|
|
5 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| dropdown-menu-arrow.svelte | 5 months ago | |
| dropdown-menu-checkbox-group.svelte | 5 months ago | |
| dropdown-menu-checkbox-item.svelte | 5 months ago | |
| dropdown-menu-content.svelte | 5 months ago | |
| dropdown-menu-group-heading.svelte | 5 months ago | |
| dropdown-menu-group.svelte | 5 months ago | |
| dropdown-menu-item.svelte | 5 months ago | |
| dropdown-menu-radio-group.svelte | 5 months ago | |
| dropdown-menu-radio-item.svelte | 5 months ago | |
| dropdown-menu-separator.svelte | 5 months ago | |
| dropdown-menu-sub-content.svelte | 5 months ago | |
| dropdown-menu-sub-trigger.svelte | 5 months ago | |
| dropdown-menu-sub.svelte | 5 months ago | |
| dropdown-menu-trigger.svelte | 5 months ago | |
| dropdown-menu.css | 5 months ago | |
| dropdown-menu.svelte | 5 months ago | |
| index.ts | 5 months ago | |
| types.ts | 5 months ago | |
README.md
<DropdownMenu> — eidos
Anchored menu opened by a button trigger. Compound API mirrors Radix DropdownMenu / Bits UI / Ark UI — full surface: Items, Groups (with GroupHeading), Separators, optional CheckboxItem / RadioItem (with RadioGroup or CheckboxGroup binding), nested Sub-menus and an optional Arrow pointer.
Usage
<script lang="ts">
import { DropdownMenu } from '$uix/eidos/components/dropdown-menu';
let open = $state(false);
let notifications = $state(true);
let theme = $state<'light' | 'dark'>('light');
</script>
<DropdownMenu bind:open>
<DropdownMenu.Trigger>Open menu</DropdownMenu.Trigger>
<DropdownMenu.Content side="bottom" align="start">
<DropdownMenu.Group>
<DropdownMenu.GroupHeading>Account</DropdownMenu.GroupHeading>
<DropdownMenu.Item onSelect={() => goto('/profile')}>Profile</DropdownMenu.Item>
<DropdownMenu.Item onSelect={() => goto('/settings')}>Settings</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.CheckboxItem bind:checked={notifications}>
Show notifications
</DropdownMenu.CheckboxItem>
<DropdownMenu.Separator />
<DropdownMenu.RadioGroup bind:value={theme}>
<DropdownMenu.RadioItem value="light">Light</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="dark">Dark</DropdownMenu.RadioItem>
</DropdownMenu.RadioGroup>
<DropdownMenu.Separator />
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger>More options</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Item>Nested item</DropdownMenu.Item>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
</DropdownMenu.Content>
</DropdownMenu>
Parts
15 in total. All pass-through wrappers over soma — eidos adds no evaluative props at this level; visual treatment is uniform across items because the menu is itself the "variant" within an app's UI.
| Part | Notes |
|---|---|
DropdownMenu (root) |
Provider; bind:open |
Trigger |
Toggle button — bring your own visual via children |
Content |
Floating panel — soma owns positioning (side / align / collisions) |
Arrow |
Optional anchor pointer |
Item |
role=menuitem; fires commit-select on activation |
Group / GroupHeading |
Semantic grouping with aria-labelledby |
Separator |
role=separator, horizontal 1px divider |
CheckboxItem |
role=menuitemcheckbox; bind:checked |
CheckboxGroup |
Binds an array; child CheckboxItems use value to participate |
RadioGroup / RadioItem |
role=menuitemradio inside role=group |
Sub / SubTrigger / SubContent |
Nested fly-out menu |
Baseline
WAI-ARIA APG Menu Button: https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/
Soma owns:
- Floating positioning (
side,align,sideOffset,avoidCollisions) - Keyboard navigation (arrows, typeahead, Home/End, Enter/Space, Escape)
- Focus trap inside the open Content, return-on-close to Trigger
- Modal / dismissal behaviour (overlay click, outside interact)
- Sub-menu cross-axis navigation (ArrowRight opens, ArrowLeft closes)
Comparativa
| Lib | Sub-menus | CheckboxItem / RadioItem | CheckboxGroup | Arrow | Modal toggle |
|---|---|---|---|---|---|
| Radix Primitives | ✓ | ✓ | — | ✓ | ✓ |
| Bits UI | ✓ | ✓ | ✓ | ✓ | ✓ |
| Ark UI | ✓ | ✓ | — | — | ✓ |
| Chakra v3 | ✓ | ✓ | — | — | — |
| Radix Themes | ✓ | ✓ | — | — | — |
| shadcn/ui | inherits Radix | ✓ | — | inherits | ✓ |
| Eidos (this) | ✓ | ✓ | ✓ (Bits pattern) | ✓ | ✓ |
Full parity with the strongest reference (Bits UI). CheckboxGroup is Bits' addition that Radix lacks — useful for "menu of toggleable chips" without per-item state bookkeeping.
Decisiones
- No
variant/color/sizeat the menu level. Menus are the visual variant of "list of actions" within an app; introducing multiple visual flavors creates noise. If a consumer wants a colored destructive item they passdata-coloron the<DropdownMenu.Item>directly (the morfo accepts it). - Pass-through wrappers for every part. Visual treatment is in the
CSS recipe via
[data-dropdown-menu-*]selectors — keeping wrappers thin makes context-menu and menubar trivial to derive (just different triggers). - SubContent reads identical to Content. Same panel chrome, same item rows. The contrast between root and sub is visual hierarchy (positioning, chevron affordance), not different styling.
- Indicator via
::beforepseudo. Checkbox/Radio items reserve a leading affordance slot; soma's CheckboxItem doesn't ship an indicator child by default (unlike Bits') because the visual cue viadata-state="checked"+ pseudo is more compact.
Gaps
| Gap | Disposición | Detalle |
|---|---|---|
Per-item data-color cascade (destructive item visual) |
implementar próximo turno | Add a cascade [data-dropdown-menu-item][data-color='risk'] for the canonical destructive item pattern. |
Right-aligned Shortcut slot (⌘K text) |
diferir | Add an ItemShortcut part if the user requests; common pattern from shadcn. |
RadioGroupHeading separate from GroupHeading |
diferir | Not in soma morfo; only one heading semantics today. |
Animation on data-state='closed' exit |
diferir | Right now closed instantly sets opacity 0. Add a fade-out keyframe when Presence is wired. |
Reference
- Radix UI Primitives: https://www.radix-ui.com/primitives/docs/components/dropdown-menu
- Bits UI: https://bits-ui.com/docs/components/dropdown-menu
- Ark UI: https://ark-ui.com/docs/components/menu
- Chakra v3: https://chakra-ui.com/docs/components/menu
- Radix Themes: https://www.radix-ui.com/themes/docs/components/dropdown-menu
- shadcn/ui: https://ui.shadcn.com/docs/components/dropdown-menu