Mixins / foldkit-mixins-ui

CascadeSelectSlots

const · packages/mixins-ui/src/cascadeSelect.ts:39

const CascadeSelectSlots: Slots.Contract<{ readonly root: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly trigger: Slot.UnnamedSlot<Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>, readonly [Event.EventToken<"click">, Event.EventToken<"keydown">], readonly [Attr.AttrToken<"role">, Attr.AttrToken<"aria-label">, Attr.AttrToken<"aria-expanded">, Attr.AttrToken<"aria-invalid">, Attr.AttrToken<"disabled">], readonly Slot.RequirementName[], boolean>; readonly valueText: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly chevron: Slot.UnnamedSlot<Capability.Capability<"Container", readonly [Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>]>, readonly Slot.EventName[], readonly Slot.AttributeName[], readonly Slot.RequirementName[], boolean>; readonly clear: Slot.UnnamedSlot<Capability.Capability<"Interactive", readonly [Capability.Capability<"Base", readonly []>]>, readonly [Event.EventToken<"click">], readonly [Attr.AttrToken<"aria-label">], readonly Slot.RequirementName[], boolean>; readonly inp …;

A cascade select, Zag's: one value chosen as a path through nested options (a country, then a region, then a city), from a popup that shows one column per level, or one level at a time with a way back (layout: 'drill'). The value is the path of ids, root first.

trigger -> Opened -> highlighted = the value's path, or the first option
keys, pointer -> Pressed / Highlighted / Picked -> update(config) -> highlighted, value
view: highlighted -> the columns shown, the active row; value -> the trigger's text

The open popup is a tree in the APG's sense, its columns the levels: focus rests on it and aria-activedescendant names the active row. The arrows move within a level and between levels (ArrowRight into the active row's children, ArrowLeft back to its parent, swapped right to left), Home and End go to a level's ends, a letter to the next row it begins, Enter and Space choose, and Escape closes. Only an option without children can be chosen, unless the config's parents allows any. The popup is drawn in the browser's top layer, placed under its trigger by @foldkit/ui's anchor, over a backdrop. Focus leaving the panel closes it, by Tab or a press anywhere else; the backdrop takes that press, so it opens nothing beneath, the trigger included.