Unboxed.purs 2.03 KB
Newer Older
arturo's avatar
arturo committed
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 82
module Gargantext.Hooks.StateRecord.Unboxed
  ( useStateRecord
  , useStateRecord'
  ) where

import Gargantext.Prelude

import Data.Eq (class EqRecord)
import Effect (Effect)
import Gargantext.Hooks.StateRecord.Behaviors (TwoWayBinding, binder, setter)
import Gargantext.Utils.Reactix as R2
import Prim.RowList (class RowToList)
import Reactix as R
import Toestand as T

type Methods r a =
  -- | Every provided props will be available within the `formFields` proxy
  ( state         ::        Record r
  , stateBox      :: T.Box (Record r)
  -- | When binded with a form input, any form fields can be handled by
  -- | providing this function
  , setStateKey   :: String -> a -> Effect Unit
  -- | API method proposing a two way data binding (such as "v-model" of
  -- | VueJS)
  , bindStateKey  :: String -> Record (TwoWayBinding a)
  )

-- | Hooks inspired from this article
-- |
-- | https://blog.logrocket.com/forms-in-react-in-2020/
-- |
-- | ```purescript
-- |
-- |  r <- useStateRecord defaultValues
-- |
-- | ...
-- |
-- | B.formInput
-- |   { value: r.state.prop
-- |   , callback: r.setStateKey "prop"
-- |   }
-- |
-- | ...
-- |
-- | -- `bindStateKey` will add both `value: ...` and `callback: ...`
-- | B.formInput $
-- |   { ... } `merge` r.bindStateKey "prop"
-- |
useStateRecord :: forall a r l.
     RowToList r l
  => EqRecord l r
  => Record r
  -> R.Hooks (Record (Methods r a))
useStateRecord = T.useBox >=> main

-- | Variant where `stateBox :: Box (Record r)` is already instanciated and
-- | provided
useStateRecord' :: forall a r l.
     T.ReadWrite (T.Box (Record r)) (Record r)
  => RowToList r l
  => EqRecord l r
  => T.Box (Record r)
  -> R.Hooks (Record (Methods r a))
useStateRecord' = main


main :: forall a r l.
     T.ReadWrite (T.Box (Record r)) (Record r)
  => RowToList r l
  => EqRecord l r
  => T.Box (Record r)
  -> R.Hooks (Record (Methods r a))
main stateBox = do

  state <- R2.useLive' stateBox

  pure
    { state
    , stateBox
    , setStateKey : (_ # stateBox # setter)
    , bindStateKey: (_ # stateBox # binder $ state)
    }