Components

Cascade select

One value chosen as a path through nested options, from a column per level or one level at a time, by the pointer or the arrows.

size
trigger
width
scheme
direction

Columns #

export const CascadeSelectStyle = forSlots(CascadeSelectSlots)(Recipes.CascadeSelect({}))

/** Folded with `CascadeSelect.update(CASCADE_PLACES)`; its Model from `CascadeSelect.init({ id })`. */
export const CASCADE_PLACES: CascadeSelect.Config = {
  nodes: [
    {
      id: 'ca',
      label: 'Canada',
      children: [
        {
          id: 'on',
          label: 'Ontario',
          children: [
            { id: 'tor', label: 'Toronto' },
            { id: 'ott', label: 'Ottawa' },
          ],
        },
        { id: 'qc', label: 'Quebec', children: [{ id: 'mtl', label: 'Montreal' }] },
      ],
    },
    {
      id: 'jp',
      label: 'Japan',
      children: [
        { id: 'kanto', label: 'Kantō', children: [{ id: 'tyo', label: 'Tokyo' }] },
        { id: 'kansai', label: 'Kansai', children: [{ id: 'osa', label: 'Osaka' }] },
      ],
    },
    { id: 'sg', label: 'Singapore' },
  ],
}

// A city chosen through its country and region: a column per level, the
// arrows within and between them, the value the path of ids.
export const cascadeSelect = <Message>(
  style: NamedStyle<typeof CascadeSelectSlots>,
  model: CascadeSelect.Model,
  onMessage: (message: CascadeSelect.Message) => Message,
  h: HtmlBuilder<Message>,
): Html =>
  CascadeSelect.view(
    {
      model,
      config: CASCADE_PLACES,
      onMessage,
      label: 'City',
      placeholder: 'Choose a city',
      levels: ['Country', 'Region', 'City'],
      clearable: true,
      style,
    },
    h,
  )

One level at a time #

// One level at a time, with a way back: a phone's width holds one column.
export const cascadeSelectDrill = <Message>(
  style: NamedStyle<typeof CascadeSelectSlots>,
  model: CascadeSelect.Model,
  onMessage: (message: CascadeSelect.Message) => Message,
  h: HtmlBuilder<Message>,
): Html =>
  CascadeSelect.view(
    { model, config: CASCADE_PLACES, onMessage, label: 'City', layout: 'drill', style },
    h,
  )

Usage

Each example above names the function that drew it, over the theme module Create a theme writes. The preview passes it the style picked above instead of its default.

The recipe ↗This code ↗