CascadeSelect.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.
Copy
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.
CascadeSelect.CascadeSelectView# interface · packages/mixins-ui/src/cascadeSelect.ts:455
interface CascadeSelectView < ParentMessage > {
readonly model: Model
readonly config: Config
readonly onMessage : ( message: Message ) => NoInfer < ParentMessage >
readonly label: string
readonly placeholder?: string | undefined
readonly separator?: string | undefined
readonly layout?: 'columns' | 'drill' | undefined
readonly expandOn?: 'click' | 'hover' | undefined
readonly levels?: ReadonlyArray < string > | undefined
readonly clearable?: boolean | undefined
readonly clearLabel?: string | undefined
readonly backLabel?: string | undefined
readonly name?: string | undefined
readonly disabled?: boolean | undefined
readonly invalid?: boolean | undefined
readonly direction?: 'ltr' | 'rtl' | undefined
readonly anchor?: AnchorConfig | undefined
readonly style?: NamedStyle < typeof CascadeSelectSlots> | undefined
readonly mixins?: MixinList < ParentMessage > | undefined
} CascadeSelect.Config# interface · packages/mixins-ui/src/cascadeSelect.ts:122
interface Config {
readonly nodes: ReadonlyArray < Node >
readonly parents?: boolean | undefined
readonly loop?: boolean | undefined
readonly closeOnSelect?: boolean | undefined
} The options and the choices update and the view agree on.
CascadeSelect.FocusTrigger# const · packages/mixins-ui/src/cascadeSelect.ts:193
const FocusTrigger: Command . CommandDefinitionWithArgs <
'CascadeSelect.FocusTrigger' ,
{ id: Schema . String },
Effect . Effect <{ readonly _tag: 'CompletedFocusTrigger' }, never , never >
> Focuses the trigger once the closed popup is drawn away.
CascadeSelect.init# function · packages/mixins-ui/src/cascadeSelect.ts:132
function init ( options: {
readonly id: string
readonly value?: ReadonlyArray < string > | undefined
}) : Model CascadeSelect.labelsOf# function · packages/mixins-ui/src/cascadeSelect.ts:181
function labelsOf (
nodes: ReadonlyArray < Node >,
path: ReadonlyArray < string >,
) : Option . None < string []> | Option . Some < string []> The labels along the value, for the trigger, or none for a path that names no node.
CascadeSelect.Message# const · packages/mixins-ui/src/cascadeSelect.ts:99
const Message: MessageUnion <{
readonly Opened: {}
readonly Closed: {}
readonly Pressed: { readonly key: Schema . String }
readonly Highlighted: { readonly path: Schema . $Array < Schema . String > }
readonly Picked: { readonly path: Schema . $Array < Schema . String > }
readonly Entered: { readonly path: Schema . $Array < Schema . String > }
readonly Left: {}
readonly Cleared: {}
readonly Placed: { readonly cramped: Schema . Boolean }
readonly CompletedFocusTrigger: {}
readonly CompletedRevealItem: {}
}> CascadeSelect.Model# const · packages/mixins-ui/src/cascadeSelect.ts:86
const Model: Schema . Struct <{
readonly id: Schema . String
readonly open: Schema . Boolean
readonly value: Schema . Option < Schema . $Array < Schema . String >>
readonly highlighted: Schema . $Array < Schema . String >
readonly cramped: Schema . Boolean
}> CascadeSelect.Node# interface · packages/mixins-ui/src/cascadeSelect.ts:79
interface Node {
readonly id: string
readonly label: string
readonly children?: ReadonlyArray < Node > | undefined
readonly disabled?: boolean | undefined
} An option and the options under it.
CascadeSelect.PlaceCascade# const · packages/mixins-ui/src/cascadeSelect.ts:224
const PlaceCascade: Mount . MountDefinitionWithArgs <
'CascadeSelect.Place' ,
{
buttonId: Schema . String
anchor: Schema . Struct <{
readonly placement: Schema . optional <
Schema . Literals <
readonly [
'top' ,
'right' ,
'bottom' ,
'left' ,
'top-start' ,
'top-end' ,
'right-start' ,
'right-end' ,
'bottom-start' ,
'bottom-end' ,
'left-start' ,
'left-end' ,
]
>
>
readonly gap: Schema . optional < Schema . Number >
readonly offset: Schema . optional < Schema . Number >
readonly padding: Schema . optional <
Schema . Union <
readonly [
Schema . Number ,
Schema . Struct <{
readonly top: Schema . optionalKey < Schema . Number >
readonly right: Schema . optionalKey < Schema . Number >
readonly bottom: Schema . optionalKey < Schema . Number >
readonly left: Schema . optionalKey < Schema . Number >
}>,
]
>
>
readonly portal: Schema . optional < Schema . Boolean >
readonly isPlacementLocked: Schema . optional < Schema . Boolean >
}>
levels: Schema . Number
},
{ readonly _tag: 'Placed' ; readonly cramped: boolean }
> Shows its element in the top layer and places the panel inside it under
the trigger, focusing the panel once placed: the anchor hides the panel
until its first position, and focus does not land on a hidden element.
It answers whether a column per level would fit the window.
CascadeSelect.RevealItem# const · packages/mixins-ui/src/cascadeSelect.ts:206
const RevealItem: Command . CommandDefinitionWithArgs <
'CascadeSelect.RevealItem' ,
{ elementId: Schema . String },
Effect . Effect <{ readonly _tag: 'CompletedRevealItem' }, never , never >
> Scrolls the active row into its column once drawn, as the keys move it.
CascadeSelect.triggerId# function · packages/mixins-ui/src/cascadeSelect.ts:143
function triggerId ( id: string ) : string CascadeSelect.update# function · packages/mixins-ui/src/cascadeSelect.ts:274
function update ( config: Config ) : ( model: Model , message: Message ) => Return The cascade's update for config, the options the view draws; the same
Model when nothing changes.
CascadeSelect.view# function · packages/mixins-ui/src/cascadeSelect.ts:495
function view < ParentMessage >(
options: CascadeSelectView < ParentMessage >,
h: HtmlBuilder < ParentMessage >,
) : Html