Select.Primitives.Container
- Package
- purescript-halogen-select
- Repository
- citizennet/purescript-halogen-select
The Container primitive contains an array of items that can be selected. As you provide the render functions, this array of items could be anything from a dropdown list to a calendar grid. The primitive provides keyboard and click behaviors for highlighting and selecting items and will be used in nearly every selection component you write.
#ContainerQuery Source
data ContainerQuery o item a
The query type for the Container
primitive. This primitive handles selections
and keyboard navigation.
Arguments:
o
: The type of the parent query to embed. This is usually the component thatmounts the search primitive, but it could also be the query type of some higher component.
item
: Your custom item type, used by your renderers.
Constructors:
Highlight
: Change the highlighted item to the next, previous, or a specific index.Select
: Select an item at the specified indexKey
: Capture key events for arrow navigation, Escape to close, and Enter to select.Mouse
: Capture mouse events to close the menu or select an itemBlur
: Trigger the DOM blur eventVisibility
: Set the visibility by toggling, setting to on, or setting to off.ReplaceItems
: Replace the array of items.Raise
: Embed a parent query that can be returned to the parent for evaluation.ContainerReceiver
: Update the component on newInput
when the parent re-renders.
Constructors
Highlight Target a
Select Int a
Key KeyboardEvent a
Mouse MouseState a
Blur a
Visibility VisibilityStatus a
ReplaceItems (Array item) a
Raise (o Unit) a
ContainerReceiver (ContainerInput o item) a
#VisibilityStatus Source
data VisibilityStatus
Possible visibility statuses for the container's Visibility
query.
On
: Set the container to be visible (use this to "open" the container)
Off
: Set the container to be visible (use this to "close" the container)
Toggle
: Toggle between "open" and "closed".
Constructors
#ContainerState Source
type ContainerState item = { highlightedIndex :: Maybe Int, items :: Array item, lastIndex :: Int, mouseDown :: Boolean, open :: Boolean }
The internal state of the Container
primitive
items
: An array of items held within theContainer
open
: Whether theContainer
is visiblehighlightedIndex
: The index of the highlighted item, if one existslastIndex
: The index of the last item in theContainer
mouseDown
: Whether the mouse is clicked or not
#ContainerInput Source
type ContainerInput o item = { items :: Array item, render :: ContainerState item -> ComponentHTML (ContainerQuery o item) }
The input type of the Container
primitive
items
: The initial value ofitems
in theContainerState
render
: Therender
function for theContainer
primitive
#Message Source
data Message o item
Messages emitted by the container primitive to notify the parent of important events.
ItemSelected
: An item has been selected in the container. This does not indicate the item has been removed; if you would like the item to also be removed from the container, make sure to queryReplaceItems
from the parent.Emit
: A parent query has been triggered and should be evaluated by the parent. Typically:
eval (HandleContainer (Emit q) next) = eval q *> pure next
Constructors
ItemSelected item
Emit (o Unit)
#component Source
component :: forall m eff item o. MonadAff (dom :: DOM | eff) m => Component HTML (ContainerQuery o item) (ContainerInput o item) (Message o item) m
The primitive handles state and transformations but defers all rendering to the parent. The render function can be written using our helper functions to ensure the right events are included.
#getToggleProps Source
getToggleProps :: forall f e item o. (ContainerQuery o item Unit -> Unit -> f Unit) -> Array (IProp (onBlur :: FocusEvent, onClick :: MouseEvent, onKeyDown :: KeyboardEvent, onMouseDown :: MouseEvent, onMouseUp :: MouseEvent, tabIndex :: Int | e) f) -> Array (IProp (onBlur :: FocusEvent, onClick :: MouseEvent, onKeyDown :: KeyboardEvent, onMouseDown :: MouseEvent, onMouseUp :: MouseEvent, tabIndex :: Int | e) f)
Attach properties to a DOM node that will maintain focus and capture key and click events for the container. If you are using the search primitive, this helper is unnecessary.
Note: This function will overwrite any properties of the same name that are already set. Use it directly on the list of properties for the node that will serve as the toggle.
Note: The toggle is not rendered within the container component. Instead, you should define a query on the parent that routes events to the relevant container, and provide that query as the first argument to this function.
-- ToContainer is a parent query you have defined that, in eval, sends queries to the container.
span (getToggleProps ToContainer [ class_ $ ClassName "my-class" ]) [ text "Button" ]
#getChildProps Source
getChildProps :: forall e item o. Array (IProp (onBlur :: FocusEvent, tabIndex :: Int | e) (ContainerQuery o item)) -> Array (IProp (onBlur :: FocusEvent, tabIndex :: Int | e) (ContainerQuery o item))
A helper to embed your own HTML and queries inside the container's render function. It will ensure that your events do not inadvertently steal focus or trigger a blur on the container. Useful to embed buttons and other arbitrary HTML within the container.
To embed your own queries, remember to use the Raise
query from the container to wrap
them. This will ensure they are re-raised to the parent.
Use directly on the properties for the element you are embedding:
button (getChildProps [ onClick $ input_ $ Raise $ action $ MyQuery "Do something" ]) [ text "Button" ]
Note: This will overwrite any properties of the same name.
#getContainerProps Source
getContainerProps :: forall e item o. Array (IProp (onBlur :: FocusEvent, onMouseDown :: MouseEvent, onMouseUp :: MouseEvent, tabIndex :: Int | e) (ContainerQuery o item)) -> Array (IProp (onBlur :: FocusEvent, onMouseDown :: MouseEvent, onMouseUp :: MouseEvent, tabIndex :: Int | e) (ContainerQuery o item))
Attach properties to the HTML element that encloses the container. This makes sure you can select items without blurring the container, unless you want to. It is used in conjunction with the getItemProps helper, which you should attach to each item in the container.
div (getContainerProps [ class_ (ClassName "my-class") ]) [ ... further html ... ]
Note: This function will overwrite any properties of the same name that are already set.
#getItemProps Source
getItemProps :: forall e item o. Int -> Array (IProp (onBlur :: FocusEvent, onClick :: MouseEvent, onKeyDown :: KeyboardEvent, onMouseOver :: MouseEvent, tabIndex :: Int | e) (ContainerQuery o item)) -> Array (IProp (onBlur :: FocusEvent, onClick :: MouseEvent, onKeyDown :: KeyboardEvent, onMouseOver :: MouseEvent, tabIndex :: Int | e) (ContainerQuery o item))
Attach events to an item in the container to support selection, highlighting, and key
events (like Enter to select). Used in conjunction with getContainerProps
.
This function requires an index. It's usually easiest to provide a renderer that uses
mapWithIndex
to ensure indexes are provided properly.
renderItems arrayOfItems = renderItem `mapWithIndex` arrayOfItems
renderItem index item = li (getItemProps index [ class_ (ClassName "item-class") ]) [ text item ]
You should provide CSS to highlight items without requiring hovers, so that arrow keys can properly maintain highlights. To do that, use the container's state to check if the item being rendered has the same index as the highlight, and if so, apply your class:
-- in renderItem...
if state.highlightedIndex == Just index then "highlight-class" else "no-highlight-class"
Note: This function will overwrite any properties of the same name that are already set.