FormCheckbox.purs 2.09 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
module Gargantext.Components.Bootstrap.FormCheckbox (formCheckbox) where

import Gargantext.Prelude

import Data.Foldable (elem, intercalate)
import Effect (Effect)
import Gargantext.Components.Bootstrap.Types (ComponentStatus(..))
import Gargantext.Utils.Reactix as R2
import Reactix as R
import Reactix.DOM.HTML as H
import Unsafe.Coerce (unsafeCoerce)

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

type Options =
  ( status      :: ComponentStatus
  , className   :: String
  )

options :: Record Options
options =
  { status      : Enabled
  , className   : ""
  }

-- | Structural Component for an <input type="checkbox">
-- |
-- |    - not using "bootstrap" here, as their checkbox does not have many
-- |      feature (sizing, colour variant), and their use of checkbox/label
-- |      is far too opinionated
formCheckbox :: forall r. R2.OptLeaf Options Props r
formCheckbox = R2.optLeaf component options

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

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
      ]

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

      H.input
      { className
      , on: { change }
      , type: "checkbox"
      , disabled: elem status [ Disabled ]
      , readOnly: elem status [ Idled ]
      , value: props.value
      , checked: props.value
      }

-- | * 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
  -> (Boolean -> Effect Unit)
  -> event
  -> Effect Unit
onChange status callback event = do
  if   status == Enabled
  then callback $ (unsafeCoerce event).target.checked
  else pure unit