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) }