 9dacac780c
			
		
	
	
	
	
	9dacac780c* Remove QueryF from Select in preparation for v5 changes, as there is no longer the ability to leverage a query within ComponentHTML. Add the npm-check-updates package to dev dependencies. * switch to variants * Complete switch to Halogen 5 * switch examples to v5 * switch to extensible state, no comonad * now that state can be embedded, take as an argument * cleanup * switch to handling messages, which addresses lingering concerns with extensibility in the components * uncomment * cleanup * add default.nix file containing mkdocs * update dependencies * fix infinite recursion (compiler bug?) * eta-expand instead of removing helper * remove unused css * Add type synonyms for simple cases * rename RunQuery to AsAction * allow external initialization, merge state fields * simplify examples * Simplify a little more * formatting * add finalizer to default spec * extensible actions * update item counts on attempted highlight * cleanup * polish up CSS for examples to test behavior * switch to void
		
			
				
	
	
		
			82 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			82 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| module Components.Dropdown where
 | |
| 
 | |
| import Prelude
 | |
| 
 | |
| import Data.Const (Const)
 | |
| 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
 | |
|   }
 | |
| 
 | |
| input :: Input -> S.Input State 
 | |
| input { items, buttonLabel } =
 | |
|   { inputType: S.Toggle
 | |
|   , search: Nothing
 | |
|   , debounceTime: Nothing
 | |
|   , getItemCount: length <<< _.items
 | |
|   , items
 | |
|   , buttonLabel
 | |
|   , selection: Nothing
 | |
|   }
 | |
| 
 | |
| spec :: S.Spec State (Const Void) Void () Message Aff
 | |
| spec = S.defaultSpec { render = render, handleMessage = handleMessage }
 | |
|   where
 | |
|   handleMessage = 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 st = 
 | |
|     HH.div 
 | |
|       [ class_ "Dropdown" ]
 | |
|       [ renderToggle, renderContainer ]
 | |
|     where
 | |
|     renderToggle =
 | |
|       HH.button
 | |
|         ( SS.setToggleProps st [ 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 ]
 | |
| 
 |