Commit 13080243 authored by Przemyslaw Kaminski's avatar Przemyslaw Kaminski

[toestand] state rewrite in inputwithautocomplete

parent 871130cb
...@@ -40,7 +40,8 @@ sizeButtonCpt :: R.Component Props ...@@ -40,7 +40,8 @@ sizeButtonCpt :: R.Component Props
sizeButtonCpt = here.component "nodeSearchControl" cpt sizeButtonCpt = here.component "nodeSearchControl" cpt
where where
cpt { graph, multiSelectEnabled, selectedNodeIds } _ = do cpt { graph, multiSelectEnabled, selectedNodeIds } _ = do
search@(search' /\ setSearch) <- R.useState' "" search <- T.useBox ""
search' <- T.useLive T.unequal search
multiSelectEnabled' <- T.useLive T.unequal multiSelectEnabled multiSelectEnabled' <- T.useLive T.unequal multiSelectEnabled
pure $ pure $
...@@ -49,7 +50,7 @@ sizeButtonCpt = here.component "nodeSearchControl" cpt ...@@ -49,7 +50,7 @@ sizeButtonCpt = here.component "nodeSearchControl" cpt
[ inputWithAutocomplete { autocompleteSearch: autocompleteSearch graph [ inputWithAutocomplete { autocompleteSearch: autocompleteSearch graph
, onAutocompleteClick: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds , onAutocompleteClick: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds
, onEnterPress: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds , onEnterPress: \s -> triggerSearch graph s multiSelectEnabled' selectedNodeIds
, state: search } , state: search } []
, H.div { className: "btn input-group-addon" , H.div { className: "btn input-group-addon"
, on: { click: \_ -> triggerSearch graph search' multiSelectEnabled' selectedNodeIds } , on: { click: \_ -> triggerSearch graph search' multiSelectEnabled' selectedNodeIds }
} }
......
...@@ -10,9 +10,11 @@ import Effect (Effect) ...@@ -10,9 +10,11 @@ import Effect (Effect)
import Effect.Timer (setTimeout) import Effect.Timer (setTimeout)
import Reactix as R import Reactix as R
import Reactix.DOM.HTML as H import Reactix.DOM.HTML as H
import Toestand as T
import Gargantext.Utils.Reactix as R2 import Gargantext.Utils.Reactix as R2
here :: R2.Here
here = R2.here "Gargantext.Components.InputWithAutocomplete" here = R2.here "Gargantext.Components.InputWithAutocomplete"
...@@ -23,23 +25,29 @@ type Props = ...@@ -23,23 +25,29 @@ type Props =
autocompleteSearch :: String -> Completions autocompleteSearch :: String -> Completions
, onAutocompleteClick :: String -> Effect Unit , onAutocompleteClick :: String -> Effect Unit
, onEnterPress :: String -> Effect Unit , onEnterPress :: String -> Effect Unit
, state :: R.State String , state :: T.Box String
) )
inputWithAutocomplete :: Record Props -> R.Element inputWithAutocomplete :: R2.Component Props
inputWithAutocomplete props = R.createElement inputWithAutocompleteCpt props [] inputWithAutocomplete = R.createElement inputWithAutocompleteCpt
inputWithAutocompleteCpt :: R.Component Props inputWithAutocompleteCpt :: R.Component Props
inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
where where
cpt props@{autocompleteSearch, onAutocompleteClick, onEnterPress, state: state@(state' /\ setState)} _ = do cpt props@{ autocompleteSearch
, onAutocompleteClick
, onEnterPress
, state } _ = do
state' <- T.useLive T.unequal state
inputRef <- R.useRef null inputRef <- R.useRef null
completions <- R.useState' $ autocompleteSearch state' completions <- T.useBox $ autocompleteSearch state'
let onFocus completions e = T.write_ (autocompleteSearch state') completions
pure $ pure $
H.span { className: "input-with-autocomplete" } H.span { className: "input-with-autocomplete" }
[ [
completionsCpt completions completionsCpt { completions, onAutocompleteClick, state } []
, H.input { type: "text" , H.input { type: "text"
, ref: inputRef , ref: inputRef
, className: "form-control" , className: "form-control"
...@@ -48,7 +56,7 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt ...@@ -48,7 +56,7 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
, focus: onFocus completions , focus: onFocus completions
, input: onInput completions , input: onInput completions
, change: onInput completions , change: onInput completions
, keyUp: onInputKeyUp inputRef completions } } , keyUp: onInputKeyUp inputRef } }
] ]
where where
...@@ -59,22 +67,20 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt ...@@ -59,22 +67,20 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
-- handles automatic autocomplete search, otherwise I'd have to hide it -- handles automatic autocomplete search, otherwise I'd have to hide it
-- in various different places (i.e. carefully handle all possible -- in various different places (i.e. carefully handle all possible
-- events where blur happens and autocomplete should hide). -- events where blur happens and autocomplete should hide).
onBlur (_ /\ setCompletions) e = setTimeout 100 $ do onBlur completions e = setTimeout 100 $ do
setCompletions $ const [] T.write_ [] completions
onFocus (_ /\ setCompletions) e = setCompletions $ const $ autocompleteSearch state'
onInput (_ /\ setCompletions) e = do onInput completions e = do
let val = R.unsafeEventValue e let val = R.unsafeEventValue e
setState $ const val T.write_ val state
setCompletions $ const $ autocompleteSearch val T.write_ (autocompleteSearch val) completions
onInputKeyUp :: R.Ref (Nullable DOM.Element) -> R.State Completions -> DE.KeyboardEvent -> Effect Unit onInputKeyUp :: R.Ref (Nullable DOM.Element) -> DE.KeyboardEvent -> Effect Unit
onInputKeyUp inputRef (_ /\ setCompletions) e = do onInputKeyUp inputRef e = do
if DE.key e == "Enter" then do if DE.key e == "Enter" then do
let val = R.unsafeEventValue e let val = R.unsafeEventValue e
let mInput = toMaybe $ R.readRef inputRef let mInput = toMaybe $ R.readRef inputRef
setState $ const val T.write_ val state
onEnterPress val onEnterPress val
case mInput of case mInput of
Nothing -> pure unit Nothing -> pure unit
...@@ -82,19 +88,32 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt ...@@ -82,19 +88,32 @@ inputWithAutocompleteCpt = here.component "inputWithAutocomplete" cpt
else else
pure $ unit pure $ unit
completionsCpt :: R.State Completions -> R.Element type CompletionsProps =
completionsCpt (completions /\ setCompletions) = ( completions :: T.Box Completions
H.div { className } , onAutocompleteClick :: String -> Effect Unit
, state :: T.Box String
)
completionsCpt :: R2.Component CompletionsProps
completionsCpt = R.createElement completionsCptCpt
completionsCptCpt :: R.Component CompletionsProps
completionsCptCpt = here.component "completionsCpt" cpt
where
cpt { completions, onAutocompleteClick, state } _ = do
completions' <- T.useLive T.unequal completions
let className = "completions " <> (if completions' == [] then "d-none" else "")
pure $ H.div { className }
[ [
H.div { className: "list-group" } (cCpt <$> completions) H.div { className: "list-group" } (cCpt <$> completions')
] ]
where where
className = "completions " <> (if completions == [] then "d-none" else "")
cCpt c = cCpt c =
H.button { type: "button" H.button { type: "button"
, className: "list-group-item" , className: "list-group-item"
, on: { click: onClick c } } [ H.text c ] , on: { click: onClick c } } [ H.text c ]
onClick c _ = do onClick c _ = do
setState $ const c T.write_ c state
onAutocompleteClick c onAutocompleteClick c
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment