You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/soma/components/dropdown-menu/README.md

11 KiB

DropdownMenu

A menu of actions triggered by a button. Supports submenus, checkbox items, radio groups, keyboard navigation, and typeahead.

Anatomy

<DropdownMenu.Provider bind:open>
	<DropdownMenu.Trigger>Actions</DropdownMenu.Trigger>

	<DropdownMenu.Content>
		<DropdownMenu.Item>Cut</DropdownMenu.Item>
		<DropdownMenu.Item>Copy</DropdownMenu.Item>
		<DropdownMenu.Separator />

		<DropdownMenu.CheckboxItem bind:checked>Show Toolbar</DropdownMenu.CheckboxItem>

		<DropdownMenu.RadioGroup bind:value>
			<DropdownMenu.RadioItem value="light">Light</DropdownMenu.RadioItem>
			<DropdownMenu.RadioItem value="dark">Dark</DropdownMenu.RadioItem>
		</DropdownMenu.RadioGroup>

		<DropdownMenu.Sub bind:open={subOpen}>
			<DropdownMenu.SubTrigger>More</DropdownMenu.SubTrigger>
			<DropdownMenu.SubContent>
				<DropdownMenu.Item>Submenu Item</DropdownMenu.Item>
			</DropdownMenu.SubContent>
		</DropdownMenu.Sub>
	</DropdownMenu.Content>
</DropdownMenu.Provider>

Parts

Part Element Description
Provider none Root context. Manages open state.
Trigger <button> Opens the menu on click or keyboard.
Content <div> Menu container. Focus scope, dismissal, floating integrated.
Arrow <div> Floating arrow pointing toward the trigger.
Item <div> Action item. Selectable via click or keyboard.
Group <div> Groups related items with an optional heading.
GroupHeading <div> Label for a group, linked via aria-labelledby.
Separator <div> Visual separator between items or groups.
CheckboxItem <div> Toggleable item with checked/unchecked state.
CheckboxGroup none Optional parent. Binds value: string[] and flips checked state of child CheckboxItems by their value.
RadioGroup <div> Group of mutually exclusive radio items.
RadioItem <div> Radio option within a RadioGroup.
Sub none Submenu context. Manages submenu open state.
SubTrigger <div> Opens a submenu on hover or keyboard.
SubContent <div> Submenu container. Positioned relative to SubTrigger.

ARIA

Part Attribute Value
Trigger aria-haspopup menu
Trigger aria-expanded true | false
Trigger aria-controls ID of Content
Content role menu
Content aria-orientation vertical
Item role menuitem
CheckboxItem role menuitemcheckbox
CheckboxItem aria-checked true | false
RadioGroup role group
RadioItem role menuitemradio
RadioItem aria-checked true | false
Group role group
Group aria-labelledby ID of GroupHeading
Separator role separator
Separator aria-orientation horizontal
SubTrigger role menuitem
SubTrigger aria-haspopup menu
SubTrigger aria-expanded true | false
SubTrigger aria-controls ID of SubContent
SubContent role menu
SubContent aria-orientation vertical

Data Attributes

Part Attribute Values
Trigger data-dropdown-menu-trigger Always present
Trigger data-state open | closed
Content data-dropdown-menu-content Always present
Content data-state open | closed
Content data-side top | right | bottom | left
Content data-align start | center | end
Content data-starting-style Present during open animation
Content data-ending-style Present during close animation
Item data-dropdown-menu-item Always present
Item data-disabled Present when disabled
Item data-text-value Text content for typeahead
CheckboxItem data-dropdown-menu-checkbox-item Always present
CheckboxItem data-state checked | unchecked
CheckboxItem data-disabled Present when disabled
RadioItem data-dropdown-menu-radio-item Always present
RadioItem data-state checked | unchecked
RadioItem data-disabled Present when disabled
SubTrigger data-dropdown-menu-sub-trigger Always present
SubTrigger data-state open | closed
SubTrigger data-disabled Present when disabled
SubContent data-dropdown-menu-sub-content Always present
SubContent data-state open | closed
Separator data-dropdown-menu-separator Always present

Keyboard

On Trigger

Key Action
ArrowDown / Enter / Space Open menu, focus first item

On Content

Key Action
ArrowDown Move to next item
ArrowUp Move to previous item
Home Move to first item
End Move to last item
Enter / Space Activate focused item
Escape Close menu
Character keys Typeahead — jump to matching item

On SubTrigger

Key Action
ArrowRight (LTR) Open submenu
Enter / Space Open submenu

On SubContent

Key Action
ArrowLeft (LTR) / Escape Close submenu, focus SubTrigger
ArrowDown / ArrowUp Navigate items within submenu

Motion

The panel uses the standard overlay state-preset: motion="slide-fade" (default) writes data-animation-style, and the recipe animates it over data-state (dropdown-menu-enter on open). The open/close sema firma (emerge) plays on the content during the hold (see Sema events).

A previous opt-in item cascade (animation="cascade-slide", the rows staggering in/out via a DomCascade) was removed on 2026-06-19 along with the rest of the parallel motion-orchestration service — see the retirement note in MOTION_SERVICE_RFC.md. Coordinated per-row motion will return as a channel of the menu's emerge.open firma, materialised by eidos — not a parallel motor.

Sema events

Event Family Verb Target Intent Sequence When
open emerge open content — pre Menu opens (handleOpen central state mutator).
close emerge close content — pre Menu closes (handleClose).
commit-select commit select item affirm post User activates an item (mouse click or keyboard).

open / close use sequence pre so the perceptual signal lands at the gesture moment, before the structural flip (the content is still in DOM, the cascade matches [data-dropdown-menu-content]). commit-select fires from MenuItem onclick and onkeydown with e.currentTarget as fallback target.

Pack: src/uix/sema/components/dropdown-menu.ts:

  • open → emerge.soft (soft chime, gain 0.08).
  • close → emerge.exit.soft (descending pitch + gain 0.05).
  • commit-select → form.commit.subtle + light tap haptic. Softer than radio-group because close-emerge + select-commit + downstream-surface fire in quick succession; spreading intensity avoids double-tap fatigue.

Usage

Basic

<script>
	import { DropdownMenu } from '$soma/components';

	let open = $state(false);
</script>

<DropdownMenu.Provider bind:open>
	<DropdownMenu.Trigger>Options</DropdownMenu.Trigger>

	<DropdownMenu.Content>
		<DropdownMenu.Item>Edit</DropdownMenu.Item>
		<DropdownMenu.Item>Duplicate</DropdownMenu.Item>
		<DropdownMenu.Separator />
		<DropdownMenu.Item>Delete</DropdownMenu.Item>
	</DropdownMenu.Content>
</DropdownMenu.Provider>

Checkbox item

<script>
	let showToolbar = $state(true);
</script>

<DropdownMenu.CheckboxItem bind:checked={showToolbar}>Show Toolbar</DropdownMenu.CheckboxItem>

Radio group

<script>
	let theme = $state('light');
</script>

<DropdownMenu.RadioGroup bind:value={theme}>
	<DropdownMenu.RadioItem value="light">Light</DropdownMenu.RadioItem>
	<DropdownMenu.RadioItem value="dark">Dark</DropdownMenu.RadioItem>
	<DropdownMenu.RadioItem value="system">System</DropdownMenu.RadioItem>
</DropdownMenu.RadioGroup>

Submenu

<DropdownMenu.Sub>
	<DropdownMenu.SubTrigger>Share</DropdownMenu.SubTrigger>
	<DropdownMenu.SubContent>
		<DropdownMenu.Item>Email</DropdownMenu.Item>
		<DropdownMenu.Item>Slack</DropdownMenu.Item>
	</DropdownMenu.SubContent>
</DropdownMenu.Sub>

Powered by TurnKey Linux.