1
Fork 0
purescript-halogen-select/examples/Components/Dropdown.purs
2021-03-31 18:40:06 -07:00

85 lines
2.3 KiB
Text

module Components.Dropdown where
import Prelude
import Effect.Aff (Aff)
import Data.Array ((!!), mapWithIndex, length)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Monoid (guard)
import Halogen as H
import Halogen.HTML as HH
import Internal.CSS (class_, classes_, whenElem)
import Select as S
import Select.Setters as SS
type Slot =
H.Slot S.Query' Message
type State =
( items :: Array String
, selection :: Maybe String
, buttonLabel :: String
)
data Message
= SelectionChanged (Maybe String) (Maybe String)
-- it is unnecessary to export your own input type, but doing so helps if you
-- would like to set some sensible defaults behind the scenes.
type Input =
{ items :: Array String
, buttonLabel :: String
}
component :: H.Component S.Query' Input Message Aff
component = S.component input $ S.defaultSpec
{ render = render
, handleEvent = handleEvent
}
where
input :: Input -> S.Input State
input { items, buttonLabel } =
{ inputType: S.Toggle
, search: Nothing
, debounceTime: Nothing
, getItemCount: length <<< _.items
, items
, buttonLabel
, selection: Nothing
}
handleEvent :: S.Event -> H.HalogenM (S.State State) S.Action' () Message Aff Unit
handleEvent = case _ of
S.Selected ix -> do
st <- H.get
let selection = st.items !! ix
H.modify_ _ { selection = selection, visibility = S.Off }
H.raise $ SelectionChanged st.selection selection
_ -> pure unit
render :: S.State State -> H.ComponentHTML S.Action' () Aff
render st =
HH.div
[ class_ "Dropdown" ]
[ renderToggle, renderContainer ]
where
renderToggle =
HH.button
( SS.setToggleProps [ class_ "Dropdown__toggle" ] )
[ HH.text (fromMaybe st.buttonLabel st.selection) ]
renderContainer = whenElem (st.visibility == S.On) \_ ->
HH.div
( SS.setContainerProps [ class_ "Dropdown__container" ] )
( renderItem `mapWithIndex` st.items )
where
renderItem index item =
HH.div
( SS.setItemProps index
[ classes_
[ "Dropdown__item"
, "Dropdown__item--highlighted" # guard (st.highlightedIndex == Just index)
]
]
)
[ HH.text item ]