FormInput.purs 2.3 KB
Newer Older
arturo's avatar
arturo committed
1 2 3 4 5 6
module Gargantext.Components.Bootstrap.FormInput (formInput) where

import Gargantext.Prelude

import Data.Foldable (elem, intercalate)
import Effect (Effect)
7
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..), Sizing(..))
arturo's avatar
arturo committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce)

type Props =
  ( callback    :: String -> Effect Unit
  , value       :: String
  | Options
  )

type Options =
  ( status      :: ComponentStatus
  , className   :: String
  , type        :: String
  , placeholder :: String
24
  , size        :: Sizing
arturo's avatar
arturo committed
25 26 27 28 29 30 31 32
  )

options :: Record Options
options =
  { status      : Enabled
  , className   : ""
  , type        : "text"
  , placeholder : ""
33
  , size        : MediumSize
arturo's avatar
arturo committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
  }

-- | Structural Component for the Bootstrap input
-- |
-- | https://getbootstrap.com/docs/4.1/components/forms/
formInput :: forall r. R2.OptLeaf Options Props r
formInput = R2.optLeaf component options

componentName :: String
componentName = "b-form-input"

bootstrapName :: String
bootstrapName = "form-control"

component :: R.Component Props
component = R.hooksComponent componentName cpt where
  cpt props@{ callback
            , status
            } _ = do
    -- Computed
    className <- pure $ intercalate " "
      -- provided custom className
      [ props.className
      -- BEM classNames
      , componentName
      , componentName <> "--" <> show status
      -- Bootstrap specific classNames
      , bootstrapName
62
      , bootstrapName <> "-" <> show props.size
arturo's avatar
arturo committed
63 64 65 66 67 68 69 70 71 72 73 74 75 76
      ]

    change <- pure $ onChange status callback
    -- Render
    pure $

      H.input
      { className
      , on: { change }
      , disabled: elem status [ Disabled ]
      , readOnly: elem status [ Idled ]
      , placeholder: props.placeholder
      , type: props.type
      , autoComplete: "off"
77
      , value: props.value
arturo's avatar
arturo committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
      }

-- | * Change event will effectively be triggered according to the
-- | component status props
-- | * Also directly returns the newly input value
-- | (usage not so different from `targetValue` of ReactBasic)
onChange :: forall event.
     ComponentStatus
  -> (String -> Effect Unit)
  -> event
  -> Effect Unit
onChange status callback event = do
  if   status == Enabled
  then callback $ (unsafeCoerce event).target.value
  else pure unit