@spectral_labs/ui 1.5.2 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/context-menu/index.d.ts +3 -0
- package/dist/components/context-menu/index.d.ts.map +1 -1
- package/dist/components/context-menu/index.js +2 -0
- package/dist/components/dropdown-menu/__tests__/DropdownMenuRadioTest.svelte +90 -0
- package/dist/components/dropdown-menu/__tests__/dropdown-menu-radio-group.test.svelte.js +306 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-group.svelte +45 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-group.svelte.d.ts +5 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-group.svelte.d.ts.map +1 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-item.svelte +143 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-item.svelte.d.ts +5 -0
- package/dist/components/dropdown-menu/components/dropdown-menu-radio-item.svelte.d.ts.map +1 -0
- package/dist/components/dropdown-menu/dropdown-menu.svelte.d.ts +18 -0
- package/dist/components/dropdown-menu/dropdown-menu.svelte.d.ts.map +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.svelte.js +16 -0
- package/dist/components/dropdown-menu/index.d.ts +3 -1
- package/dist/components/dropdown-menu/index.d.ts.map +1 -1
- package/dist/components/dropdown-menu/index.js +2 -0
- package/dist/components/dropdown-menu/types.d.ts +35 -1
- package/dist/components/dropdown-menu/types.d.ts.map +1 -1
- package/dist/components/menubar/index.d.ts +3 -1
- package/dist/components/menubar/index.d.ts.map +1 -1
- package/dist/components/menubar/index.js +2 -0
- package/package.json +1 -1
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { default as CheckboxItem } from '../dropdown-menu/components/dropdown-menu-checkbox-item.svelte';
|
|
2
2
|
export { default as Item } from '../dropdown-menu/components/dropdown-menu-item.svelte';
|
|
3
3
|
export { default as Label } from '../dropdown-menu/components/dropdown-menu-label.svelte';
|
|
4
|
+
export { default as RadioGroup } from '../dropdown-menu/components/dropdown-menu-radio-group.svelte';
|
|
5
|
+
export { default as RadioItem } from '../dropdown-menu/components/dropdown-menu-radio-item.svelte';
|
|
4
6
|
export { default as Separator } from '../dropdown-menu/components/dropdown-menu-separator.svelte';
|
|
7
|
+
export type { DropdownMenuRadioGroupProps as ContextMenuRadioGroupProps, DropdownMenuRadioItemProps as ContextMenuRadioItemProps, } from '../dropdown-menu/types.js';
|
|
5
8
|
export { default as Content } from './components/context-menu-content.svelte';
|
|
6
9
|
export { default as Root } from './components/context-menu-root.svelte';
|
|
7
10
|
export { default as Trigger } from './components/context-menu-trigger.svelte';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/context-menu/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gEAAgE,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uDAAuD,CAAA;AACvF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,wDAAwD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4DAA4D,CAAA;AACjG,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0CAA0C,CAAA;AAC7E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uCAAuC,CAAA;AACvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0CAA0C,CAAA;AAC7E,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/context-menu/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gEAAgE,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uDAAuD,CAAA;AACvF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,wDAAwD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6DAA6D,CAAA;AAClG,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4DAA4D,CAAA;AACjG,YAAY,EACV,2BAA2B,IAAI,0BAA0B,EACzD,0BAA0B,IAAI,yBAAyB,GACxD,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0CAA0C,CAAA;AAC7E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uCAAuC,CAAA;AACvE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0CAA0C,CAAA;AAC7E,YAAY,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export { default as CheckboxItem } from '../dropdown-menu/components/dropdown-menu-checkbox-item.svelte';
|
|
3
3
|
export { default as Item } from '../dropdown-menu/components/dropdown-menu-item.svelte';
|
|
4
4
|
export { default as Label } from '../dropdown-menu/components/dropdown-menu-label.svelte';
|
|
5
|
+
export { default as RadioGroup } from '../dropdown-menu/components/dropdown-menu-radio-group.svelte';
|
|
6
|
+
export { default as RadioItem } from '../dropdown-menu/components/dropdown-menu-radio-item.svelte';
|
|
5
7
|
export { default as Separator } from '../dropdown-menu/components/dropdown-menu-separator.svelte';
|
|
6
8
|
export { default as Content } from './components/context-menu-content.svelte';
|
|
7
9
|
export { default as Root } from './components/context-menu-root.svelte';
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import DropdownMenuContent from '../components/dropdown-menu-content.svelte'
|
|
3
|
+
import DropdownMenuItem from '../components/dropdown-menu-item.svelte'
|
|
4
|
+
import DropdownMenuRadioGroup from '../components/dropdown-menu-radio-group.svelte'
|
|
5
|
+
import DropdownMenuRadioItem from '../components/dropdown-menu-radio-item.svelte'
|
|
6
|
+
import DropdownMenuRoot from '../components/dropdown-menu-root.svelte'
|
|
7
|
+
import DropdownMenuTrigger from '../components/dropdown-menu-trigger.svelte'
|
|
8
|
+
|
|
9
|
+
let {
|
|
10
|
+
open = $bindable(true),
|
|
11
|
+
value = $bindable('document'),
|
|
12
|
+
portalTo,
|
|
13
|
+
onValueChange,
|
|
14
|
+
closeOnSelect = undefined,
|
|
15
|
+
disabledValue = undefined,
|
|
16
|
+
textValues = undefined,
|
|
17
|
+
itemAttrs = undefined,
|
|
18
|
+
onItemClick = undefined,
|
|
19
|
+
withLeadingItem = false,
|
|
20
|
+
orphan = false,
|
|
21
|
+
groupAttrs = undefined,
|
|
22
|
+
onItemKeydown = undefined,
|
|
23
|
+
onItemSelect = undefined,
|
|
24
|
+
parentTarget = 'bibliographie',
|
|
25
|
+
}: {
|
|
26
|
+
open?: boolean
|
|
27
|
+
value?: string
|
|
28
|
+
portalTo?: HTMLElement | string
|
|
29
|
+
onValueChange?: (value: string) => void
|
|
30
|
+
closeOnSelect?: boolean
|
|
31
|
+
/** Value of the single item rendered disabled. */
|
|
32
|
+
disabledValue?: string
|
|
33
|
+
/** Per-value `textValue` overrides for typeahead. */
|
|
34
|
+
textValues?: Record<string, string>
|
|
35
|
+
/** Arbitrary HTML attributes spread onto the `placeholders` item. */
|
|
36
|
+
itemAttrs?: Record<string, unknown>
|
|
37
|
+
/** Consumer-supplied click handler on the `placeholders` item. */
|
|
38
|
+
onItemClick?: (event: MouseEvent) => void
|
|
39
|
+
/** A plain Item BEFORE the group — proves roving spans both kinds. */
|
|
40
|
+
withLeadingItem?: boolean
|
|
41
|
+
/** Renders a RadioItem with NO enclosing RadioGroup (guard-rail case). */
|
|
42
|
+
orphan?: boolean
|
|
43
|
+
/** Arbitrary HTML attributes spread onto the `role="group"` node. */
|
|
44
|
+
groupAttrs?: Record<string, unknown>
|
|
45
|
+
/** Consumer-supplied keydown handler on the `placeholders` item. */
|
|
46
|
+
onItemKeydown?: (event: KeyboardEvent) => void
|
|
47
|
+
/** Consumer-supplied `onSelect` on the `placeholders` item. */
|
|
48
|
+
onItemSelect?: (event: Event) => void
|
|
49
|
+
/** Value the PARENT-driven button assigns (see `parent-set` below). */
|
|
50
|
+
parentTarget?: string
|
|
51
|
+
} = $props()
|
|
52
|
+
|
|
53
|
+
const OPTIONS = [
|
|
54
|
+
{ value: 'document', label: 'Document' },
|
|
55
|
+
{ value: 'placeholders', label: 'Placeholders' },
|
|
56
|
+
{ value: 'bibliographie', label: 'Bibliographie' },
|
|
57
|
+
]
|
|
58
|
+
</script>
|
|
59
|
+
|
|
60
|
+
<!-- Lives OUTSIDE the menu: clicking it is the PARENT moving `value`, the
|
|
61
|
+
one path that must move the checked row without any notification. -->
|
|
62
|
+
<button data-testid="parent-set" onclick={() => (value = parentTarget)}>set from parent</button>
|
|
63
|
+
|
|
64
|
+
<DropdownMenuRoot bind:open>
|
|
65
|
+
<DropdownMenuTrigger>Affichage</DropdownMenuTrigger>
|
|
66
|
+
<DropdownMenuContent {portalTo}>
|
|
67
|
+
{#if withLeadingItem}
|
|
68
|
+
<DropdownMenuItem>Plan</DropdownMenuItem>
|
|
69
|
+
{/if}
|
|
70
|
+
{#if orphan}
|
|
71
|
+
<DropdownMenuRadioItem value="orphan">Orphan</DropdownMenuRadioItem>
|
|
72
|
+
{/if}
|
|
73
|
+
<DropdownMenuRadioGroup bind:value {onValueChange} {...groupAttrs ?? {}}>
|
|
74
|
+
{#each OPTIONS as option (option.value)}
|
|
75
|
+
<DropdownMenuRadioItem
|
|
76
|
+
value={option.value}
|
|
77
|
+
disabled={option.value === disabledValue}
|
|
78
|
+
textValue={textValues?.[option.value]}
|
|
79
|
+
{closeOnSelect}
|
|
80
|
+
onclick={option.value === 'placeholders' ? onItemClick : undefined}
|
|
81
|
+
onkeydown={option.value === 'placeholders' ? onItemKeydown : undefined}
|
|
82
|
+
onSelect={option.value === 'placeholders' ? onItemSelect : undefined}
|
|
83
|
+
{...option.value === 'placeholders' ? (itemAttrs ?? {}) : {}}
|
|
84
|
+
>
|
|
85
|
+
{option.label}
|
|
86
|
+
</DropdownMenuRadioItem>
|
|
87
|
+
{/each}
|
|
88
|
+
</DropdownMenuRadioGroup>
|
|
89
|
+
</DropdownMenuContent>
|
|
90
|
+
</DropdownMenuRoot>
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { flushSync, mount, unmount } from 'svelte';
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import DropdownMenuRadioTest from './DropdownMenuRadioTest.svelte';
|
|
4
|
+
/**
|
|
5
|
+
* `DropdownMenu.RadioGroup` / `RadioItem` — the single-choice row family.
|
|
6
|
+
*
|
|
7
|
+
* These rows exist because a menu that offers "pick exactly one of N" had no
|
|
8
|
+
* honest markup here: `CheckboxItem` announces `menuitemcheckbox`, which tells
|
|
9
|
+
* a screen-reader user the options are independent when they are not.
|
|
10
|
+
*
|
|
11
|
+
* The suite also pins the two properties this family is REQUIRED to have from
|
|
12
|
+
* birth, and which the older rows lack (spectral-ui#201): consumer HTML
|
|
13
|
+
* attributes reach the DOM node, and a consumer event handler COMPOSES with
|
|
14
|
+
* the built-in one instead of being dropped.
|
|
15
|
+
*/
|
|
16
|
+
describe('dropdown-menu radio group', () => {
|
|
17
|
+
let target;
|
|
18
|
+
let instance;
|
|
19
|
+
function setup(props = {}) {
|
|
20
|
+
target = document.createElement('div');
|
|
21
|
+
document.body.appendChild(target);
|
|
22
|
+
instance = mount(DropdownMenuRadioTest, {
|
|
23
|
+
target,
|
|
24
|
+
props: { portalTo: target, ...props },
|
|
25
|
+
});
|
|
26
|
+
flushSync();
|
|
27
|
+
return target;
|
|
28
|
+
}
|
|
29
|
+
function radios() {
|
|
30
|
+
return Array.from(target.querySelectorAll('[role="menuitemradio"]'));
|
|
31
|
+
}
|
|
32
|
+
function radio(value) {
|
|
33
|
+
const el = target.querySelector(`[role="menuitemradio"][data-value="${value}"]`);
|
|
34
|
+
if (!el)
|
|
35
|
+
throw new Error(`no radio item for value "${value}"`);
|
|
36
|
+
return el;
|
|
37
|
+
}
|
|
38
|
+
/** Same idiom as `dropdown-menu.test.svelte.ts`: drive the REAL focused
|
|
39
|
+
* element, so the Content -> collection -> focus chain is exercised rather
|
|
40
|
+
* than merely inspected. */
|
|
41
|
+
function pressKey(key) {
|
|
42
|
+
const el = document.activeElement;
|
|
43
|
+
el.dispatchEvent(new KeyboardEvent('keydown', { key, bubbles: true }));
|
|
44
|
+
flushSync();
|
|
45
|
+
}
|
|
46
|
+
function activeValue() {
|
|
47
|
+
return document.activeElement?.getAttribute('data-value') ?? null;
|
|
48
|
+
}
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
if (instance)
|
|
51
|
+
unmount(instance);
|
|
52
|
+
instance = undefined;
|
|
53
|
+
target?.remove();
|
|
54
|
+
});
|
|
55
|
+
// ── ARIA ──────────────────────────────────────────────────────────────
|
|
56
|
+
it('wraps its rows in role="group" — never role="radiogroup", invalid inside a menu', () => {
|
|
57
|
+
setup();
|
|
58
|
+
expect(target.querySelector('.sp-dropdown-menu-radio-group')?.getAttribute('role')).toBe('group');
|
|
59
|
+
// The ratified contract FORBIDS `radiogroup`: a `menu` may only own
|
|
60
|
+
// menuitem / menuitemcheckbox / menuitemradio / group / separator.
|
|
61
|
+
expect(target.querySelector('[role="radiogroup"]')).toBeNull();
|
|
62
|
+
const items = radios();
|
|
63
|
+
expect(items).toHaveLength(3);
|
|
64
|
+
expect(items.map((el) => el.getAttribute('aria-checked'))).toEqual(['true', 'false', 'false']);
|
|
65
|
+
});
|
|
66
|
+
it('reflects the selected value in data-state, for styling parity with CheckboxItem', () => {
|
|
67
|
+
setup();
|
|
68
|
+
expect(radio('document').getAttribute('data-state')).toBe('checked');
|
|
69
|
+
expect(radio('placeholders').getAttribute('data-state')).toBe('unchecked');
|
|
70
|
+
});
|
|
71
|
+
it('moves the checked row when the PARENT changes `value` after mount', () => {
|
|
72
|
+
// Mounting straight at the target value would stay green even if the group
|
|
73
|
+
// snapshotted the prop at init — the move has to happen AFTER mount, driven
|
|
74
|
+
// from outside, with the menu open.
|
|
75
|
+
const calls = [];
|
|
76
|
+
setup({ onValueChange: (v) => calls.push(v) });
|
|
77
|
+
expect(radios().map((el) => el.getAttribute('aria-checked'))).toEqual([
|
|
78
|
+
'true',
|
|
79
|
+
'false',
|
|
80
|
+
'false',
|
|
81
|
+
]);
|
|
82
|
+
target.querySelector('[data-testid="parent-set"]').click();
|
|
83
|
+
flushSync();
|
|
84
|
+
expect(radios().map((el) => el.getAttribute('aria-checked'))).toEqual([
|
|
85
|
+
'false',
|
|
86
|
+
'false',
|
|
87
|
+
'true',
|
|
88
|
+
]);
|
|
89
|
+
expect(radio('bibliographie').getAttribute('data-state')).toBe('checked');
|
|
90
|
+
// The parent moved it; the group has nothing to report back.
|
|
91
|
+
expect(calls).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
// ── Selection ─────────────────────────────────────────────────────────
|
|
94
|
+
// `closeOnSelect: false` in the selection tests below is not incidental: the
|
|
95
|
+
// default closes the menu, which unmounts the rows — a post-click assertion
|
|
96
|
+
// on `aria-checked` would then fail for the wrong reason. Closing has its
|
|
97
|
+
// own test.
|
|
98
|
+
it('selects on click and notifies once with the new value', () => {
|
|
99
|
+
const calls = [];
|
|
100
|
+
let selects = 0;
|
|
101
|
+
setup({
|
|
102
|
+
closeOnSelect: false,
|
|
103
|
+
onItemSelect: () => selects++,
|
|
104
|
+
onValueChange: (v) => calls.push(v),
|
|
105
|
+
});
|
|
106
|
+
radio('placeholders').click();
|
|
107
|
+
flushSync();
|
|
108
|
+
expect(calls).toEqual(['placeholders']);
|
|
109
|
+
expect(radio('placeholders').getAttribute('aria-checked')).toBe('true');
|
|
110
|
+
expect(radio('document').getAttribute('aria-checked')).toBe('false');
|
|
111
|
+
// Proves the `onSelect` wiring is live — without this, the `select: 0` of
|
|
112
|
+
// the disabled test below would hold no matter what the component did.
|
|
113
|
+
expect(selects).toBe(1);
|
|
114
|
+
});
|
|
115
|
+
it('does NOT re-notify when the already-selected row is chosen again', () => {
|
|
116
|
+
const calls = [];
|
|
117
|
+
setup({ onValueChange: (v) => calls.push(v) });
|
|
118
|
+
radio('document').click();
|
|
119
|
+
flushSync();
|
|
120
|
+
expect(calls).toEqual([]);
|
|
121
|
+
});
|
|
122
|
+
it('selects on Enter and on Space', () => {
|
|
123
|
+
const calls = [];
|
|
124
|
+
setup({ closeOnSelect: false, onValueChange: (v) => calls.push(v) });
|
|
125
|
+
radio('placeholders').dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
126
|
+
flushSync();
|
|
127
|
+
expect(calls).toEqual(['placeholders']);
|
|
128
|
+
radio('bibliographie').dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }));
|
|
129
|
+
flushSync();
|
|
130
|
+
expect(calls).toEqual(['placeholders', 'bibliographie']);
|
|
131
|
+
});
|
|
132
|
+
it('closes the menu after a selection, and keeps it open when closeOnSelect is false', () => {
|
|
133
|
+
setup();
|
|
134
|
+
radio('placeholders').click();
|
|
135
|
+
flushSync();
|
|
136
|
+
expect(target.querySelector('[role="menu"]')).toBeNull();
|
|
137
|
+
unmount(instance);
|
|
138
|
+
instance = undefined;
|
|
139
|
+
target.remove();
|
|
140
|
+
setup({ closeOnSelect: false });
|
|
141
|
+
radio('placeholders').click();
|
|
142
|
+
flushSync();
|
|
143
|
+
expect(target.querySelector('[role="menu"]')).toBeTruthy();
|
|
144
|
+
});
|
|
145
|
+
// ── Disabled ──────────────────────────────────────────────────────────
|
|
146
|
+
it('a disabled row is TOTALLY inert — the consumer handler does not run either', () => {
|
|
147
|
+
const counts = { click: 0, keydown: 0, select: 0, change: 0 };
|
|
148
|
+
setup({
|
|
149
|
+
disabledValue: 'placeholders',
|
|
150
|
+
onItemClick: () => counts.click++,
|
|
151
|
+
onItemKeydown: () => counts.keydown++,
|
|
152
|
+
onItemSelect: () => counts.select++,
|
|
153
|
+
onValueChange: () => counts.change++,
|
|
154
|
+
});
|
|
155
|
+
const disabled = radio('placeholders');
|
|
156
|
+
expect(disabled.getAttribute('aria-disabled')).toBe('true');
|
|
157
|
+
expect(disabled.hasAttribute('data-disabled')).toBe(true);
|
|
158
|
+
disabled.click();
|
|
159
|
+
flushSync();
|
|
160
|
+
disabled.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
161
|
+
flushSync();
|
|
162
|
+
disabled.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }));
|
|
163
|
+
flushSync();
|
|
164
|
+
// A dimmed, unselectable row that still fires an application effect is not
|
|
165
|
+
// disabled — it only LOOKS disabled.
|
|
166
|
+
expect(counts).toEqual({ click: 0, keydown: 0, select: 0, change: 0 });
|
|
167
|
+
expect(disabled.getAttribute('aria-checked')).toBe('false');
|
|
168
|
+
// ... and none of it dismissed the menu.
|
|
169
|
+
expect(target.querySelector('[role="menu"]')).toBeTruthy();
|
|
170
|
+
// `getOwnLevelMenuItems` filters on `[data-roving-focus-item]:not([data-disabled])`.
|
|
171
|
+
const rovable = target.querySelectorAll('[data-roving-focus-item]:not([data-disabled])');
|
|
172
|
+
expect(Array.from(rovable)).not.toContain(disabled);
|
|
173
|
+
});
|
|
174
|
+
// ── Keyboard: the chain, not the wiring ───────────────────────────────
|
|
175
|
+
//
|
|
176
|
+
// The `data-*` hooks below can all be present while the
|
|
177
|
+
// Content -> collection -> focus chain is broken, so these drive the real
|
|
178
|
+
// focused element instead of asserting attributes.
|
|
179
|
+
it('is reachable by ArrowDown from a plain Item, and Enter selects the FOCUSED row', () => {
|
|
180
|
+
const calls = [];
|
|
181
|
+
setup({
|
|
182
|
+
withLeadingItem: true,
|
|
183
|
+
closeOnSelect: false,
|
|
184
|
+
onValueChange: (v) => calls.push(v),
|
|
185
|
+
});
|
|
186
|
+
// Opening autofocuses the first roving row — the plain Item.
|
|
187
|
+
expect(document.activeElement?.textContent?.trim()).toBe('Plan');
|
|
188
|
+
pressKey('ArrowDown');
|
|
189
|
+
expect(document.activeElement?.getAttribute('role')).toBe('menuitemradio');
|
|
190
|
+
expect(activeValue()).toBe('document');
|
|
191
|
+
pressKey('ArrowDown');
|
|
192
|
+
expect(activeValue()).toBe('placeholders');
|
|
193
|
+
pressKey('Enter');
|
|
194
|
+
expect(calls).toEqual(['placeholders']);
|
|
195
|
+
expect(radio('placeholders').getAttribute('aria-checked')).toBe('true');
|
|
196
|
+
});
|
|
197
|
+
it('roving SKIPS a disabled row on ArrowDown', () => {
|
|
198
|
+
setup({ withLeadingItem: true, disabledValue: 'placeholders' });
|
|
199
|
+
expect(document.activeElement?.textContent?.trim()).toBe('Plan');
|
|
200
|
+
pressKey('ArrowDown');
|
|
201
|
+
expect(activeValue()).toBe('document');
|
|
202
|
+
pressKey('ArrowDown');
|
|
203
|
+
// `placeholders` is disabled — roving lands on the next enabled row.
|
|
204
|
+
expect(activeValue()).toBe('bibliographie');
|
|
205
|
+
});
|
|
206
|
+
it('typeahead focuses the matching row, and `textValue` redirects the match', () => {
|
|
207
|
+
setup({ withLeadingItem: true });
|
|
208
|
+
pressKey('b');
|
|
209
|
+
expect(activeValue()).toBe('bibliographie');
|
|
210
|
+
unmount(instance);
|
|
211
|
+
instance = undefined;
|
|
212
|
+
target.remove();
|
|
213
|
+
// With the override, `Bibliographie` no longer answers to `b` — and no
|
|
214
|
+
// other row does, so focus stays put.
|
|
215
|
+
setup({ withLeadingItem: true, textValues: { bibliographie: 'zzz' } });
|
|
216
|
+
const before = document.activeElement;
|
|
217
|
+
pressKey('b');
|
|
218
|
+
expect(document.activeElement).toBe(before);
|
|
219
|
+
// Remount before the second probe: typeahead ACCUMULATES a buffer, so a
|
|
220
|
+
// `z` typed after a failed `b` searches for "bz" and would match nothing —
|
|
221
|
+
// the test would then pass or fail for a reason unrelated to `textValue`.
|
|
222
|
+
unmount(instance);
|
|
223
|
+
instance = undefined;
|
|
224
|
+
target.remove();
|
|
225
|
+
setup({ withLeadingItem: true, textValues: { bibliographie: 'zzz' } });
|
|
226
|
+
pressKey('z');
|
|
227
|
+
expect(activeValue()).toBe('bibliographie');
|
|
228
|
+
});
|
|
229
|
+
// ── Roving focus + typeahead wiring ───────────────────────────────────
|
|
230
|
+
it('joins the roving collection alongside plain items', () => {
|
|
231
|
+
setup({ withLeadingItem: true });
|
|
232
|
+
const rovable = Array.from(target.querySelectorAll('[data-roving-focus-item]:not([data-disabled])'));
|
|
233
|
+
// Plan + the three radio rows, in document order.
|
|
234
|
+
expect(rovable).toHaveLength(4);
|
|
235
|
+
expect(rovable[0].getAttribute('role')).toBe('menuitem');
|
|
236
|
+
expect(rovable.slice(1).map((el) => el.getAttribute('role'))).toEqual([
|
|
237
|
+
'menuitemradio',
|
|
238
|
+
'menuitemradio',
|
|
239
|
+
'menuitemradio',
|
|
240
|
+
]);
|
|
241
|
+
});
|
|
242
|
+
it('exposes its label to typeahead, and lets `textValue` override it', () => {
|
|
243
|
+
setup({ textValues: { bibliographie: 'zzz' } });
|
|
244
|
+
// No override → the content's typeahead falls back to textContent.
|
|
245
|
+
expect(radio('document').getAttribute('data-text-value')).toBeNull();
|
|
246
|
+
expect(radio('document').textContent?.trim()).toBe('Document');
|
|
247
|
+
// Override → the attribute the content reads FIRST.
|
|
248
|
+
expect(radio('bibliographie').getAttribute('data-text-value')).toBe('zzz');
|
|
249
|
+
});
|
|
250
|
+
// ── The two properties #201 costs the older rows ───────────────────────
|
|
251
|
+
it('forwards consumer HTML attributes to the GROUP element', () => {
|
|
252
|
+
setup({ groupAttrs: { 'aria-label': 'Panneau', 'data-testid': 'view-group' } });
|
|
253
|
+
const group = target.querySelector('.sp-dropdown-menu-radio-group');
|
|
254
|
+
expect(group.getAttribute('aria-label')).toBe('Panneau');
|
|
255
|
+
expect(group.getAttribute('data-testid')).toBe('view-group');
|
|
256
|
+
// The role stays ours.
|
|
257
|
+
expect(group.getAttribute('role')).toBe('group');
|
|
258
|
+
});
|
|
259
|
+
it('forwards consumer HTML attributes to the row element', () => {
|
|
260
|
+
setup({ itemAttrs: { 'data-testid': 'view-placeholders', 'aria-keyshortcuts': 'p' } });
|
|
261
|
+
const el = radio('placeholders');
|
|
262
|
+
expect(el.getAttribute('data-testid')).toBe('view-placeholders');
|
|
263
|
+
expect(el.getAttribute('aria-keyshortcuts')).toBe('p');
|
|
264
|
+
});
|
|
265
|
+
it('keeps its own class alongside a consumer class', () => {
|
|
266
|
+
setup({ itemAttrs: { class: 'view-row' } });
|
|
267
|
+
const el = radio('placeholders');
|
|
268
|
+
expect(el.classList.contains('view-row')).toBe(true);
|
|
269
|
+
expect(el.classList.contains('sp-dropdown-menu-item')).toBe(true);
|
|
270
|
+
});
|
|
271
|
+
it('cOMPOSES a consumer handler with the built-in selection', () => {
|
|
272
|
+
const seen = [];
|
|
273
|
+
setup({
|
|
274
|
+
closeOnSelect: false,
|
|
275
|
+
onItemClick: () => seen.push('consumer'),
|
|
276
|
+
onValueChange: (v) => seen.push(`selected:${v}`),
|
|
277
|
+
});
|
|
278
|
+
radio('placeholders').click();
|
|
279
|
+
flushSync();
|
|
280
|
+
// Both ran, consumer first — and selection actually happened.
|
|
281
|
+
expect(seen).toEqual(['consumer', 'selected:placeholders']);
|
|
282
|
+
});
|
|
283
|
+
it('lets a consumer handler cancel the selection with preventDefault', () => {
|
|
284
|
+
const calls = [];
|
|
285
|
+
setup({
|
|
286
|
+
onItemClick: (event) => event.preventDefault(),
|
|
287
|
+
onValueChange: (v) => calls.push(v),
|
|
288
|
+
});
|
|
289
|
+
radio('placeholders').click();
|
|
290
|
+
flushSync();
|
|
291
|
+
expect(calls).toEqual([]);
|
|
292
|
+
expect(radio('placeholders').getAttribute('aria-checked')).toBe('false');
|
|
293
|
+
// A cancelled selection must not close the menu either.
|
|
294
|
+
expect(target.querySelector('[role="menu"]')).toBeTruthy();
|
|
295
|
+
});
|
|
296
|
+
// ── Guard rail ────────────────────────────────────────────────────────
|
|
297
|
+
it('throws a NAMED error when a RadioItem is used outside a RadioGroup', () => {
|
|
298
|
+
const spy = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
299
|
+
try {
|
|
300
|
+
expect(() => setup({ orphan: true })).toThrow(/RadioGroup/);
|
|
301
|
+
}
|
|
302
|
+
finally {
|
|
303
|
+
spy.mockRestore();
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { DropdownMenuRadioGroupProps } from '../types.js'
|
|
3
|
+
import { setDropdownMenuRadioGroupContext } from '../dropdown-menu.svelte.js'
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
value = $bindable(),
|
|
7
|
+
onValueChange,
|
|
8
|
+
class: className,
|
|
9
|
+
children,
|
|
10
|
+
...rest
|
|
11
|
+
}: DropdownMenuRadioGroupProps = $props()
|
|
12
|
+
|
|
13
|
+
// `role="group"`, never `radiogroup`: WAI-ARIA lets a `menu` own
|
|
14
|
+
// `menuitem` / `menuitemcheckbox` / `menuitemradio` / `group` / `separator`
|
|
15
|
+
// — a `radiogroup` inside a menu is an invalid owned element.
|
|
16
|
+
setDropdownMenuRadioGroupContext({
|
|
17
|
+
get value() {
|
|
18
|
+
return value
|
|
19
|
+
},
|
|
20
|
+
select(next) {
|
|
21
|
+
// Re-selecting the current row is a legitimate dismissal, but it is not
|
|
22
|
+
// a CHANGE: notifying here would make consumers debounce their own
|
|
23
|
+
// no-ops (the `armed` idiom in Preparo's command bar, for one).
|
|
24
|
+
if (next === value) return
|
|
25
|
+
value = next
|
|
26
|
+
onValueChange?.(next)
|
|
27
|
+
},
|
|
28
|
+
})
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<!-- `{...rest}` FIRST: a consumer names and tags the group (`aria-label`,
|
|
32
|
+
`id`, `data-testid`), never overrides the role that makes it a group. -->
|
|
33
|
+
<div {...rest} class="sp-dropdown-menu-radio-group {className ?? ''}" role="group">
|
|
34
|
+
{#if children}{@render children()}{/if}
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
/* A plain block, deliberately NOT `display: contents`: the menu content is
|
|
39
|
+
already a block that stacks its rows, so the wrapper costs no layout —
|
|
40
|
+
and `display: contents` has a history of dropping the element's
|
|
41
|
+
accessibility semantics, which is the one thing this wrapper exists for. */
|
|
42
|
+
.sp-dropdown-menu-radio-group {
|
|
43
|
+
display: block;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DropdownMenuRadioGroupProps } from '../types.js';
|
|
2
|
+
declare const DropdownMenuRadioGroup: import("svelte").Component<DropdownMenuRadioGroupProps, {}, "value">;
|
|
3
|
+
type DropdownMenuRadioGroup = ReturnType<typeof DropdownMenuRadioGroup>;
|
|
4
|
+
export default DropdownMenuRadioGroup;
|
|
5
|
+
//# sourceMappingURL=dropdown-menu-radio-group.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown-menu-radio-group.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/dropdown-menu/components/dropdown-menu-radio-group.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAA;AA0C9D,QAAA,MAAM,sBAAsB,sEAAwC,CAAC;AACrE,KAAK,sBAAsB,GAAG,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;AACxE,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { DropdownMenuRadioItemProps } from '../types.js'
|
|
3
|
+
import { getMenuContext } from '../../../internal/menu-context/index.js'
|
|
4
|
+
import { getDropdownMenuRadioGroupContext } from '../dropdown-menu.svelte.js'
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
value,
|
|
8
|
+
disabled = false,
|
|
9
|
+
textValue,
|
|
10
|
+
closeOnSelect = true,
|
|
11
|
+
onSelect,
|
|
12
|
+
class: className,
|
|
13
|
+
children,
|
|
14
|
+
// Pulled out of `rest` so the built-in behaviour can COMPOSE with them
|
|
15
|
+
// instead of being clobbered by the spread.
|
|
16
|
+
onclick,
|
|
17
|
+
onkeydown,
|
|
18
|
+
onpointerenter,
|
|
19
|
+
...rest
|
|
20
|
+
}: DropdownMenuRadioItemProps = $props()
|
|
21
|
+
|
|
22
|
+
const group = getDropdownMenuRadioGroupContext()
|
|
23
|
+
const menuCtx = getMenuContext()
|
|
24
|
+
|
|
25
|
+
const checked = $derived(group.value === value)
|
|
26
|
+
|
|
27
|
+
/** Svelte's DOM attribute handlers narrow `currentTarget` to the host
|
|
28
|
+
* element; a bare `MouseEvent` is not assignable to that. */
|
|
29
|
+
type RowEvent<E extends Event> = E & { currentTarget: EventTarget & HTMLDivElement }
|
|
30
|
+
|
|
31
|
+
function select(event: Event) {
|
|
32
|
+
if (disabled) return
|
|
33
|
+
group.select(value)
|
|
34
|
+
onSelect?.(event)
|
|
35
|
+
// Re-selecting the current row still dismisses: picking the option you
|
|
36
|
+
// already have is a legitimate way to close the menu.
|
|
37
|
+
if (closeOnSelect) menuCtx.close()
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// A disabled row is INERT, which has to include the consumer's handler:
|
|
41
|
+
// running it would let a dimmed, unselectable row still fire an application
|
|
42
|
+
// effect. Activation paths bail before anything runs.
|
|
43
|
+
function handleClick(event: RowEvent<MouseEvent>) {
|
|
44
|
+
if (disabled) return
|
|
45
|
+
onclick?.(event)
|
|
46
|
+
if (event.defaultPrevented) return
|
|
47
|
+
select(event)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function handleKeydown(event: RowEvent<KeyboardEvent>) {
|
|
51
|
+
if (disabled) return
|
|
52
|
+
onkeydown?.(event)
|
|
53
|
+
if (event.defaultPrevented) return
|
|
54
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
55
|
+
event.preventDefault()
|
|
56
|
+
select(event)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Deliberately NOT guarded on `disabled`: hovering a dimmed row must still
|
|
61
|
+
// close open sibling submenus, exactly as `Item` does.
|
|
62
|
+
function handlePointerEnter(event: RowEvent<PointerEvent>) {
|
|
63
|
+
onpointerenter?.(event)
|
|
64
|
+
if (event.defaultPrevented) return
|
|
65
|
+
// Pointer coordination: entering any row of this menu level closes open
|
|
66
|
+
// sibling submenus (unless the pointer travels through a grace area).
|
|
67
|
+
// Runs even when disabled — hovering a disabled row still closes subs.
|
|
68
|
+
menuCtx.onItemEnter(event)
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<!-- `{...rest}` FIRST: a consumer may add attributes, never override the
|
|
73
|
+
row's identity (role, checked state, roving hooks) — those come after and
|
|
74
|
+
win. -->
|
|
75
|
+
<div
|
|
76
|
+
{...rest}
|
|
77
|
+
class="sp-dropdown-menu-item radio {className ?? ''}"
|
|
78
|
+
role="menuitemradio"
|
|
79
|
+
aria-checked={checked}
|
|
80
|
+
aria-disabled={disabled || undefined}
|
|
81
|
+
tabindex={-1}
|
|
82
|
+
data-roving-focus-item
|
|
83
|
+
data-value={value}
|
|
84
|
+
data-text-value={textValue}
|
|
85
|
+
data-disabled={disabled || undefined}
|
|
86
|
+
data-state={checked ? 'checked' : 'unchecked'}
|
|
87
|
+
onpointerenter={handlePointerEnter}
|
|
88
|
+
onclick={handleClick}
|
|
89
|
+
onkeydown={handleKeydown}
|
|
90
|
+
>
|
|
91
|
+
<span class="sp-dropdown-menu-dot">
|
|
92
|
+
{#if checked}
|
|
93
|
+
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
|
94
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
95
|
+
</svg>
|
|
96
|
+
{/if}
|
|
97
|
+
</span>
|
|
98
|
+
{#if children}{@render children()}{/if}
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<style>
|
|
102
|
+
/* Same row metrics as `.checkbox` — the two families must sit on one rhythm
|
|
103
|
+
when a menu mixes them (Preparo's Affichage menu does). */
|
|
104
|
+
.sp-dropdown-menu-item.radio {
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
gap: 0.5rem;
|
|
108
|
+
padding: 0.5rem 0.75rem;
|
|
109
|
+
border-radius: var(--sp-sys-shape-corner-md, 12px);
|
|
110
|
+
font-family: var(--sp-sys-typescale-body-medium-font, inherit);
|
|
111
|
+
font-size: var(--sp-sys-typescale-body-medium-size, 0.875rem);
|
|
112
|
+
color: var(--sp-sys-color-on-surface);
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
user-select: none;
|
|
115
|
+
outline: none;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.sp-dropdown-menu-item.radio:focus-visible,
|
|
119
|
+
.sp-dropdown-menu-item.radio:hover:not([data-disabled]) {
|
|
120
|
+
background-color: color-mix(
|
|
121
|
+
in oklch,
|
|
122
|
+
var(--sp-sys-color-on-surface) calc(var(--sp-sys-state-hover-opacity, 0.08) * 100%),
|
|
123
|
+
transparent
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.sp-dropdown-menu-item.radio[data-disabled] {
|
|
128
|
+
opacity: 0.38;
|
|
129
|
+
cursor: not-allowed;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.sp-dropdown-menu-dot {
|
|
133
|
+
width: 16px;
|
|
134
|
+
height: 16px;
|
|
135
|
+
flex-shrink: 0;
|
|
136
|
+
color: var(--sp-sys-color-primary);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.sp-dropdown-menu-dot svg {
|
|
140
|
+
width: 16px;
|
|
141
|
+
height: 16px;
|
|
142
|
+
}
|
|
143
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DropdownMenuRadioItemProps } from '../types.js';
|
|
2
|
+
declare const DropdownMenuRadioItem: import("svelte").Component<DropdownMenuRadioItemProps, {}, "">;
|
|
3
|
+
type DropdownMenuRadioItem = ReturnType<typeof DropdownMenuRadioItem>;
|
|
4
|
+
export default DropdownMenuRadioItem;
|
|
5
|
+
//# sourceMappingURL=dropdown-menu-radio-item.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dropdown-menu-radio-item.svelte.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/dropdown-menu/components/dropdown-menu-radio-item.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AA2F7D,QAAA,MAAM,qBAAqB,gEAAwC,CAAC;AACpE,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACtE,eAAe,qBAAqB,CAAC"}
|
|
@@ -51,4 +51,22 @@ export interface DropdownMenuSubContext {
|
|
|
51
51
|
}
|
|
52
52
|
export declare function setDropdownMenuSubContext(state: DropdownMenuSubContext): void;
|
|
53
53
|
export declare function getDropdownMenuSubContext(): DropdownMenuSubContext;
|
|
54
|
+
/**
|
|
55
|
+
* The single-choice contract shared by a `RadioGroup` and its `RadioItem`
|
|
56
|
+
* rows. `value` is a GETTER, never a snapshot: the group owns a `$bindable`
|
|
57
|
+
* prop, and a row reading `ctx.value` while rendering must see the current
|
|
58
|
+
* selection — including one changed from OUTSIDE the menu.
|
|
59
|
+
*/
|
|
60
|
+
export interface DropdownMenuRadioGroupContext {
|
|
61
|
+
readonly value: string | undefined;
|
|
62
|
+
/** Selects `value`. A no-op — and no notification — when already selected. */
|
|
63
|
+
select: (value: string) => void;
|
|
64
|
+
}
|
|
65
|
+
export declare function setDropdownMenuRadioGroupContext(state: DropdownMenuRadioGroupContext): void;
|
|
66
|
+
/**
|
|
67
|
+
* Throws a NAMED error instead of returning `undefined`: an orphan
|
|
68
|
+
* `RadioItem` would otherwise fail later with an opaque property-access
|
|
69
|
+
* TypeError, at a point that no longer names the mistake.
|
|
70
|
+
*/
|
|
71
|
+
export declare function getDropdownMenuRadioGroupContext(): DropdownMenuRadioGroupContext;
|
|
54
72
|
//# sourceMappingURL=dropdown-menu.svelte.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dropdown-menu.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/dropdown-menu.svelte.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CAC/C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAErE;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAE1D;AAED,wBAAgB,qBAAqB;;;EAKpC;AAID,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAA;IACpC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACvD,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACxD,2DAA2D;IAC3D,0BAA0B,EAAE,MAAM,IAAI,CAAA;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACvC,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC9C;;;OAGG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAC7C;;;;OAIG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CAC9C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAE7E;AAED,wBAAgB,yBAAyB,IAAI,sBAAsB,CAElE"}
|
|
1
|
+
{"version":3,"file":"dropdown-menu.svelte.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/dropdown-menu.svelte.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;CAC/C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAErE;AAED,wBAAgB,sBAAsB,IAAI,iBAAiB,CAE1D;AAED,wBAAgB,qBAAqB;;;EAKpC;AAID,MAAM,WAAW,sBAAsB;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;IACtC;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAA;IACpC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACvD,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAA;IACxD,2DAA2D;IAC3D,0BAA0B,EAAE,MAAM,IAAI,CAAA;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAA;IACvC,YAAY,EAAE,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC9C;;;OAGG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAC7C;;;;OAIG;IACH,cAAc,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CAC9C;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAE7E;AAED,wBAAgB,yBAAyB,IAAI,sBAAsB,CAElE;AAID;;;;;GAKG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;IAClC,8EAA8E;IAC9E,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAChC;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,6BAA6B,GAAG,IAAI,CAE3F;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,IAAI,6BAA6B,CAQhF"}
|
|
@@ -20,3 +20,19 @@ export function setDropdownMenuSubContext(state) {
|
|
|
20
20
|
export function getDropdownMenuSubContext() {
|
|
21
21
|
return getContext(SUB_KEY);
|
|
22
22
|
}
|
|
23
|
+
const RADIO_GROUP_KEY = Symbol('sp-dropdown-radio-group');
|
|
24
|
+
export function setDropdownMenuRadioGroupContext(state) {
|
|
25
|
+
setContext(RADIO_GROUP_KEY, state);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Throws a NAMED error instead of returning `undefined`: an orphan
|
|
29
|
+
* `RadioItem` would otherwise fail later with an opaque property-access
|
|
30
|
+
* TypeError, at a point that no longer names the mistake.
|
|
31
|
+
*/
|
|
32
|
+
export function getDropdownMenuRadioGroupContext() {
|
|
33
|
+
const ctx = getContext(RADIO_GROUP_KEY);
|
|
34
|
+
if (!ctx) {
|
|
35
|
+
throw new Error('[spectral-ui] DropdownMenu.RadioItem must be rendered inside a DropdownMenu.RadioGroup.');
|
|
36
|
+
}
|
|
37
|
+
return ctx;
|
|
38
|
+
}
|
|
@@ -2,11 +2,13 @@ export { default as CheckboxItem } from './components/dropdown-menu-checkbox-ite
|
|
|
2
2
|
export { default as Content } from './components/dropdown-menu-content.svelte';
|
|
3
3
|
export { default as Item } from './components/dropdown-menu-item.svelte';
|
|
4
4
|
export { default as Label } from './components/dropdown-menu-label.svelte';
|
|
5
|
+
export { default as RadioGroup } from './components/dropdown-menu-radio-group.svelte';
|
|
6
|
+
export { default as RadioItem } from './components/dropdown-menu-radio-item.svelte';
|
|
5
7
|
export { default as Root } from './components/dropdown-menu-root.svelte';
|
|
6
8
|
export { default as Separator } from './components/dropdown-menu-separator.svelte';
|
|
7
9
|
export { default as SubContent } from './components/dropdown-menu-sub-content.svelte';
|
|
8
10
|
export { default as SubTrigger } from './components/dropdown-menu-sub-trigger.svelte';
|
|
9
11
|
export { default as Sub } from './components/dropdown-menu-sub.svelte';
|
|
10
12
|
export { default as Trigger } from './components/dropdown-menu-trigger.svelte';
|
|
11
|
-
export type { DropdownMenuCheckboxItemProps, DropdownMenuContentProps, DropdownMenuItemProps, DropdownMenuLabelProps, DropdownMenuProps, DropdownMenuSeparatorProps, DropdownMenuSubContentProps, DropdownMenuSubProps, DropdownMenuSubTriggerProps, DropdownMenuTriggerProps, } from './types.js';
|
|
13
|
+
export type { DropdownMenuCheckboxItemProps, DropdownMenuContentProps, DropdownMenuItemProps, DropdownMenuLabelProps, DropdownMenuProps, DropdownMenuRadioGroupProps, DropdownMenuRadioItemProps, DropdownMenuSeparatorProps, DropdownMenuSubContentProps, DropdownMenuSubProps, DropdownMenuSubTriggerProps, DropdownMenuTriggerProps, } from './types.js';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iDAAiD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2CAA2C,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,yCAAyC,CAAA;AAC1E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6CAA6C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2CAA2C,CAAA;AAC9E,YAAY,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,iDAAiD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2CAA2C,CAAA;AAC9E,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,yCAAyC,CAAA;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,8CAA8C,CAAA;AACnF,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,wCAAwC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6CAA6C,CAAA;AAClF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+CAA+C,CAAA;AACrF,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,uCAAuC,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,2CAA2C,CAAA;AAC9E,YAAY,EACV,6BAA6B,EAC7B,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,2BAA2B,EAC3B,0BAA0B,EAC1B,0BAA0B,EAC1B,2BAA2B,EAC3B,oBAAoB,EACpB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,YAAY,CAAA"}
|
|
@@ -2,6 +2,8 @@ export { default as CheckboxItem } from './components/dropdown-menu-checkbox-ite
|
|
|
2
2
|
export { default as Content } from './components/dropdown-menu-content.svelte';
|
|
3
3
|
export { default as Item } from './components/dropdown-menu-item.svelte';
|
|
4
4
|
export { default as Label } from './components/dropdown-menu-label.svelte';
|
|
5
|
+
export { default as RadioGroup } from './components/dropdown-menu-radio-group.svelte';
|
|
6
|
+
export { default as RadioItem } from './components/dropdown-menu-radio-item.svelte';
|
|
5
7
|
export { default as Root } from './components/dropdown-menu-root.svelte';
|
|
6
8
|
export { default as Separator } from './components/dropdown-menu-separator.svelte';
|
|
7
9
|
export { default as SubContent } from './components/dropdown-menu-sub-content.svelte';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
2
|
+
import type { HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
import type { Align, Side } from '../../internal/floating-layer/types.js';
|
|
4
4
|
export interface DropdownMenuProps {
|
|
5
5
|
open?: boolean;
|
|
@@ -55,6 +55,40 @@ export interface DropdownMenuCheckboxItemProps {
|
|
|
55
55
|
class?: string;
|
|
56
56
|
children?: Snippet;
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Extends the native div attributes so the real `role="group"` node can be
|
|
60
|
+
* named: several radio groups in one menu each need their own `aria-label` /
|
|
61
|
+
* `aria-labelledby`, and consumers need `id` / `data-testid` on the group
|
|
62
|
+
* itself.
|
|
63
|
+
*/
|
|
64
|
+
export interface DropdownMenuRadioGroupProps extends Omit<HTMLAttributes<HTMLDivElement>, 'class' | 'children'> {
|
|
65
|
+
/** The selected value. Bindable. */
|
|
66
|
+
value?: string;
|
|
67
|
+
/** Called whenever the selection changes. Never fired for a re-selection. */
|
|
68
|
+
onValueChange?: (value: string) => void;
|
|
69
|
+
class?: string;
|
|
70
|
+
children?: Snippet;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Extends the native div attributes: unlike the older menu rows, a consumer's
|
|
74
|
+
* `data-testid`, `aria-*` and event handlers reach the DOM node
|
|
75
|
+
* (spectral-ui#201 is not reproduced here). Consumer handlers COMPOSE with the
|
|
76
|
+
* built-in ones — they run first, and calling `preventDefault()` cancels the
|
|
77
|
+
* built-in behaviour.
|
|
78
|
+
*/
|
|
79
|
+
export interface DropdownMenuRadioItemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'class' | 'children'> {
|
|
80
|
+
/** Value identifying this row within its `RadioGroup`. */
|
|
81
|
+
value: string;
|
|
82
|
+
disabled?: boolean;
|
|
83
|
+
/** Override textContent for typeahead matching. */
|
|
84
|
+
textValue?: string;
|
|
85
|
+
/** Close the menu after selection (default true). */
|
|
86
|
+
closeOnSelect?: boolean;
|
|
87
|
+
/** Callback on selection, after the group's value has moved. */
|
|
88
|
+
onSelect?: (event: Event) => void;
|
|
89
|
+
class?: string;
|
|
90
|
+
children?: Snippet;
|
|
91
|
+
}
|
|
58
92
|
export interface DropdownMenuSubProps {
|
|
59
93
|
/** Whether the submenu is open. */
|
|
60
94
|
open?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/components/dropdown-menu/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
export { default as CheckboxItem } from '../dropdown-menu/components/dropdown-menu-checkbox-item.svelte';
|
|
2
2
|
export { default as Item } from '../dropdown-menu/components/dropdown-menu-item.svelte';
|
|
3
3
|
export { default as Label } from '../dropdown-menu/components/dropdown-menu-label.svelte';
|
|
4
|
+
export { default as RadioGroup } from '../dropdown-menu/components/dropdown-menu-radio-group.svelte';
|
|
5
|
+
export { default as RadioItem } from '../dropdown-menu/components/dropdown-menu-radio-item.svelte';
|
|
4
6
|
export { default as Separator } from '../dropdown-menu/components/dropdown-menu-separator.svelte';
|
|
5
7
|
export { default as SubContent } from '../dropdown-menu/components/dropdown-menu-sub-content.svelte';
|
|
6
8
|
export { default as SubTrigger } from '../dropdown-menu/components/dropdown-menu-sub-trigger.svelte';
|
|
7
9
|
export { default as Sub } from '../dropdown-menu/components/dropdown-menu-sub.svelte';
|
|
8
|
-
export type { DropdownMenuCheckboxItemProps as MenubarCheckboxItemProps, DropdownMenuItemProps as MenubarItemProps, DropdownMenuLabelProps as MenubarLabelProps, DropdownMenuSeparatorProps as MenubarSeparatorProps, DropdownMenuSubContentProps as MenubarSubContentProps, DropdownMenuSubProps as MenubarSubProps, DropdownMenuSubTriggerProps as MenubarSubTriggerProps, } from '../dropdown-menu/types.js';
|
|
10
|
+
export type { DropdownMenuCheckboxItemProps as MenubarCheckboxItemProps, DropdownMenuItemProps as MenubarItemProps, DropdownMenuLabelProps as MenubarLabelProps, DropdownMenuRadioGroupProps as MenubarRadioGroupProps, DropdownMenuRadioItemProps as MenubarRadioItemProps, DropdownMenuSeparatorProps as MenubarSeparatorProps, DropdownMenuSubContentProps as MenubarSubContentProps, DropdownMenuSubProps as MenubarSubProps, DropdownMenuSubTriggerProps as MenubarSubTriggerProps, } from '../dropdown-menu/types.js';
|
|
9
11
|
export { default as Content } from './components/menubar-content.svelte';
|
|
10
12
|
export { default as Menu } from './components/menubar-menu.svelte';
|
|
11
13
|
export { default as Root } from './components/menubar-root.svelte';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/menubar/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gEAAgE,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uDAAuD,CAAA;AACvF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,wDAAwD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4DAA4D,CAAA;AAEjG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,sDAAsD,CAAA;AAErF,YAAY,EACV,6BAA6B,IAAI,wBAAwB,EACzD,qBAAqB,IAAI,gBAAgB,EACzC,sBAAsB,IAAI,iBAAiB,EAC3C,0BAA0B,IAAI,qBAAqB,EACnD,2BAA2B,IAAI,sBAAsB,EACrD,oBAAoB,IAAI,eAAe,EACvC,2BAA2B,IAAI,sBAAsB,GACtD,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qCAAqC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,kCAAkC,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,kCAAkC,CAAA;AAElE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qCAAqC,CAAA;AAExE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/components/menubar/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,gEAAgE,CAAA;AACxG,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,uDAAuD,CAAA;AACvF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,wDAAwD,CAAA;AACzF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,6DAA6D,CAAA;AAClG,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4DAA4D,CAAA;AAEjG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,sDAAsD,CAAA;AAErF,YAAY,EACV,6BAA6B,IAAI,wBAAwB,EACzD,qBAAqB,IAAI,gBAAgB,EACzC,sBAAsB,IAAI,iBAAiB,EAC3C,2BAA2B,IAAI,sBAAsB,EACrD,0BAA0B,IAAI,qBAAqB,EACnD,0BAA0B,IAAI,qBAAqB,EACnD,2BAA2B,IAAI,sBAAsB,EACrD,oBAAoB,IAAI,eAAe,EACvC,2BAA2B,IAAI,sBAAsB,GACtD,MAAM,2BAA2B,CAAA;AAElC,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qCAAqC,CAAA;AACxE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,kCAAkC,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,kCAAkC,CAAA;AAElE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,qCAAqC,CAAA;AAExE,YAAY,EACV,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,YAAY,CAAA"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
export { default as CheckboxItem } from '../dropdown-menu/components/dropdown-menu-checkbox-item.svelte';
|
|
3
3
|
export { default as Item } from '../dropdown-menu/components/dropdown-menu-item.svelte';
|
|
4
4
|
export { default as Label } from '../dropdown-menu/components/dropdown-menu-label.svelte';
|
|
5
|
+
export { default as RadioGroup } from '../dropdown-menu/components/dropdown-menu-radio-group.svelte';
|
|
6
|
+
export { default as RadioItem } from '../dropdown-menu/components/dropdown-menu-radio-item.svelte';
|
|
5
7
|
export { default as Separator } from '../dropdown-menu/components/dropdown-menu-separator.svelte';
|
|
6
8
|
export { default as SubContent } from '../dropdown-menu/components/dropdown-menu-sub-content.svelte';
|
|
7
9
|
export { default as SubTrigger } from '../dropdown-menu/components/dropdown-menu-sub-trigger.svelte';
|