@human-kit/svelte-components 1.0.0-alpha.1 → 1.0.0-alpha.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/FOCUS_STATE_CONTRACT.md +51 -0
- package/dist/FOCUS_STATE_REVIEW_TEMPLATE.md +70 -0
- package/dist/calendar/README.md +66 -0
- package/dist/calendar/TODO.md +23 -0
- package/dist/calendar/body-cell/calendar-body-cell.svelte +230 -0
- package/dist/calendar/body-cell/calendar-body-cell.svelte.d.ts +9 -0
- package/dist/calendar/grid/calendar-grid-month-scope.svelte +16 -0
- package/dist/calendar/grid/calendar-grid-month-scope.svelte.d.ts +8 -0
- package/dist/calendar/grid/calendar-grid.svelte +45 -0
- package/dist/calendar/grid/calendar-grid.svelte.d.ts +8 -0
- package/dist/calendar/grid/month-scope.d.ts +2 -0
- package/dist/calendar/grid/month-scope.js +8 -0
- package/dist/calendar/grid-body/calendar-grid-body-custom-test.svelte +13 -0
- package/dist/calendar/grid-body/calendar-grid-body-custom-test.svelte.d.ts +18 -0
- package/dist/calendar/grid-body/calendar-grid-body.svelte +36 -0
- package/dist/calendar/grid-body/calendar-grid-body.svelte.d.ts +8 -0
- package/dist/calendar/grid-header/calendar-grid-header-custom-test.svelte +13 -0
- package/dist/calendar/grid-header/calendar-grid-header-custom-test.svelte.d.ts +18 -0
- package/dist/calendar/grid-header/calendar-grid-header.svelte +31 -0
- package/dist/calendar/grid-header/calendar-grid-header.svelte.d.ts +8 -0
- package/dist/calendar/header-cell/calendar-header-cell-test.svelte +11 -0
- package/dist/calendar/header-cell/calendar-header-cell-test.svelte.d.ts +18 -0
- package/dist/calendar/header-cell/calendar-header-cell.svelte +16 -0
- package/dist/calendar/header-cell/calendar-header-cell.svelte.d.ts +8 -0
- package/dist/calendar/heading/calendar-heading.svelte +17 -0
- package/dist/calendar/heading/calendar-heading.svelte.d.ts +5 -0
- package/dist/calendar/index.d.ts +13 -0
- package/dist/calendar/index.js +13 -0
- package/dist/calendar/index.parts.d.ts +9 -0
- package/dist/calendar/index.parts.js +9 -0
- package/dist/calendar/root/calendar-root-bind-value-test.svelte +14 -0
- package/dist/calendar/root/calendar-root-bind-value-test.svelte.d.ts +3 -0
- package/dist/calendar/root/calendar-root-controlled-clear-test.svelte +20 -0
- package/dist/calendar/root/calendar-root-controlled-clear-test.svelte.d.ts +3 -0
- package/dist/calendar/root/calendar-root-test.svelte +71 -0
- package/dist/calendar/root/calendar-root-test.svelte.d.ts +13 -0
- package/dist/calendar/root/calendar-root.svelte +143 -0
- package/dist/calendar/root/calendar-root.svelte.d.ts +31 -0
- package/dist/calendar/root/context.d.ts +66 -0
- package/dist/calendar/root/context.js +727 -0
- package/dist/calendar/root/date-utils.d.ts +17 -0
- package/dist/calendar/root/date-utils.js +94 -0
- package/dist/calendar/trigger-next/calendar-trigger-next.svelte +38 -0
- package/dist/calendar/trigger-next/calendar-trigger-next.svelte.d.ts +8 -0
- package/dist/calendar/trigger-previous/calendar-trigger-previous.svelte +38 -0
- package/dist/calendar/trigger-previous/calendar-trigger-previous.svelte.d.ts +8 -0
- package/dist/combobox/README.md +40 -0
- package/dist/combobox/TODO.md +28 -175
- package/dist/combobox/button/README.md +15 -0
- package/dist/combobox/button/combobox-button.svelte +2 -0
- package/dist/combobox/input/README.md +16 -0
- package/dist/combobox/item/README.md +27 -0
- package/dist/combobox/item-indicator/README.md +15 -0
- package/dist/combobox/list/README.md +27 -0
- package/dist/combobox/popover/README.md +13 -0
- package/dist/combobox/root/README.md +44 -0
- package/dist/combobox/root/combobox.svelte +30 -0
- package/dist/combobox/tag/README.md +37 -0
- package/dist/combobox/tag-remove/README.md +14 -0
- package/dist/combobox/tags/README.md +23 -0
- package/dist/datepicker/README.md +100 -0
- package/dist/datepicker/TODO.md +28 -0
- package/dist/datepicker/calendar/date-picker-calendar-unsafe-props-test.svelte +60 -0
- package/dist/datepicker/calendar/date-picker-calendar-unsafe-props-test.svelte.d.ts +3 -0
- package/dist/datepicker/calendar/date-picker-calendar.svelte +65 -0
- package/dist/datepicker/calendar/date-picker-calendar.svelte.d.ts +10 -0
- package/dist/datepicker/index.d.ts +18 -0
- package/dist/datepicker/index.js +18 -0
- package/dist/datepicker/index.parts.d.ts +14 -0
- package/dist/datepicker/index.parts.js +14 -0
- package/dist/datepicker/input/date-picker-input.svelte +108 -0
- package/dist/datepicker/input/date-picker-input.svelte.d.ts +11 -0
- package/dist/datepicker/internal/strict-props.d.ts +2 -0
- package/dist/datepicker/internal/strict-props.js +28 -0
- package/dist/datepicker/popover/date-picker-popover-handler-test.svelte +57 -0
- package/dist/datepicker/popover/date-picker-popover-handler-test.svelte.d.ts +3 -0
- package/dist/datepicker/popover/date-picker-popover-unsafe-props-test.svelte +45 -0
- package/dist/datepicker/popover/date-picker-popover-unsafe-props-test.svelte.d.ts +18 -0
- package/dist/datepicker/popover/date-picker-popover.svelte +87 -0
- package/dist/datepicker/popover/date-picker-popover.svelte.d.ts +7 -0
- package/dist/datepicker/root/context.d.ts +43 -0
- package/dist/datepicker/root/context.js +15 -0
- package/dist/datepicker/root/date-picker-bindable-empty-test.svelte +24 -0
- package/dist/datepicker/root/date-picker-bindable-empty-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-bindable-test.svelte +41 -0
- package/dist/datepicker/root/date-picker-bindable-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-empty-test.svelte +47 -0
- package/dist/datepicker/root/date-picker-empty-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-locale-typing-test.svelte +47 -0
- package/dist/datepicker/root/date-picker-locale-typing-test.svelte.d.ts +3 -0
- package/dist/datepicker/root/date-picker-open-cancel-test.svelte +54 -0
- package/dist/datepicker/root/date-picker-open-cancel-test.svelte.d.ts +8 -0
- package/dist/datepicker/root/date-picker-root.svelte +495 -0
- package/dist/datepicker/root/date-picker-root.svelte.d.ts +24 -0
- package/dist/datepicker/root/date-picker-test.svelte +86 -0
- package/dist/datepicker/root/date-picker-test.svelte.d.ts +13 -0
- package/dist/datepicker/root/date-utils.d.ts +17 -0
- package/dist/datepicker/root/date-utils.js +138 -0
- package/dist/datepicker/root/draft-evaluation.d.ts +13 -0
- package/dist/datepicker/root/draft-evaluation.js +56 -0
- package/dist/datepicker/root/focus-controller.d.ts +3 -0
- package/dist/datepicker/root/focus-controller.js +15 -0
- package/dist/datepicker/root/open-change.d.ts +5 -0
- package/dist/datepicker/root/open-change.js +13 -0
- package/dist/datepicker/root/open-controller.d.ts +7 -0
- package/dist/datepicker/root/open-controller.js +15 -0
- package/dist/datepicker/root/segment-controller.d.ts +8 -0
- package/dist/datepicker/root/segment-controller.js +53 -0
- package/dist/datepicker/root/segment-state.d.ts +18 -0
- package/dist/datepicker/root/segment-state.js +134 -0
- package/dist/datepicker/root/value-commit.d.ts +4 -0
- package/dist/datepicker/root/value-commit.js +8 -0
- package/dist/datepicker/segment/date-picker-segment.svelte +319 -0
- package/dist/datepicker/segment/date-picker-segment.svelte.d.ts +9 -0
- package/dist/datepicker/trigger/date-picker-trigger.svelte +110 -0
- package/dist/datepicker/trigger/date-picker-trigger.svelte.d.ts +9 -0
- package/dist/dialog/README.md +35 -0
- package/dist/dialog/content/README.md +16 -0
- package/dist/dialog/content/dialog-content.svelte +6 -6
- package/dist/dialog/overlay/README.md +13 -0
- package/dist/dialog/portal/README.md +12 -0
- package/dist/dialog/root/README.md +53 -0
- package/dist/dialog/root/context.d.ts +2 -1
- package/dist/dialog/root/dialog-root.svelte +9 -2
- package/dist/dialog/trigger/README.md +12 -0
- package/dist/dialog/trigger/dialog-trigger-multi-button-test.svelte +19 -0
- package/dist/dialog/trigger/dialog-trigger-multi-button-test.svelte.d.ts +18 -0
- package/dist/dialog/trigger/dialog-trigger.svelte +18 -6
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/listbox/README.md +26 -0
- package/dist/listbox/item/README.md +24 -0
- package/dist/listbox/root/README.md +40 -0
- package/dist/listbox/root/listbox.svelte +44 -0
- package/dist/locale-provider/context.d.ts +8 -0
- package/dist/locale-provider/context.js +18 -0
- package/dist/locale-provider/index.d.ts +4 -0
- package/dist/locale-provider/index.js +4 -0
- package/dist/locale-provider/locale-provider-initial-value-test.svelte +15 -0
- package/dist/locale-provider/locale-provider-initial-value-test.svelte.d.ts +7 -0
- package/dist/locale-provider/locale-provider-test.svelte +20 -0
- package/dist/locale-provider/locale-provider-test.svelte.d.ts +6 -0
- package/dist/locale-provider/locale-provider-value-probe.svelte +22 -0
- package/dist/locale-provider/locale-provider-value-probe.svelte.d.ts +6 -0
- package/dist/locale-provider/locale-provider.svelte +23 -0
- package/dist/locale-provider/locale-provider.svelte.d.ts +8 -0
- package/dist/popover/README.md +42 -0
- package/dist/popover/content/README.md +25 -0
- package/dist/popover/content/popover-content-standalone-test.svelte +28 -0
- package/dist/popover/content/popover-content-standalone-test.svelte.d.ts +6 -0
- package/dist/popover/content/popover-content-test.svelte +2 -1
- package/dist/popover/content/popover-content-test.svelte.d.ts +2 -1
- package/dist/popover/content/popover-content.svelte +91 -18
- package/dist/popover/content/popover-content.svelte.d.ts +5 -1
- package/dist/popover/index.d.ts +1 -1
- package/dist/popover/index.js +1 -3
- package/dist/popover/root/README.md +25 -0
- package/dist/popover/root/context.d.ts +16 -7
- package/dist/popover/root/context.js +0 -2
- package/dist/popover/root/focus-state.d.ts +4 -0
- package/dist/popover/root/focus-state.js +33 -0
- package/dist/popover/root/popover-root.svelte +90 -17
- package/dist/popover/root/popover-root.svelte.d.ts +2 -1
- package/dist/popover/root/popover-test.svelte +2 -1
- package/dist/popover/root/popover-test.svelte.d.ts +2 -1
- package/dist/popover/trigger/README.md +23 -0
- package/dist/popover/trigger/popover-trigger-button.svelte +10 -7
- package/dist/popover/trigger/popover-trigger-button.svelte.d.ts +2 -3
- package/dist/popover/trigger/popover-trigger-multi-button-test.svelte +16 -0
- package/dist/popover/trigger/popover-trigger-multi-button-test.svelte.d.ts +18 -0
- package/dist/popover/trigger/popover-trigger.svelte +19 -7
- package/dist/portal/portal.svelte +3 -1
- package/dist/primitives/click-outside.d.ts +1 -1
- package/dist/primitives/click-outside.js +1 -1
- package/dist/primitives/focus-trap.d.ts +7 -2
- package/dist/primitives/focus-trap.js +40 -6
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.js +1 -0
- package/dist/primitives/input-modality.d.ts +7 -0
- package/dist/primitives/input-modality.js +116 -0
- package/dist/test-utils/focus-contract.d.ts +3 -0
- package/dist/test-utils/focus-contract.js +26 -0
- package/dist/utils/date-only.d.ts +11 -0
- package/dist/utils/date-only.js +53 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/package.json +16 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Dialog } from '../../dialog';
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<Dialog.Root>
|
|
6
|
+
<Dialog.Trigger>
|
|
7
|
+
<div>
|
|
8
|
+
<button type="button">First Dialog Trigger</button>
|
|
9
|
+
<button type="button">Second Dialog Trigger</button>
|
|
10
|
+
</div>
|
|
11
|
+
</Dialog.Trigger>
|
|
12
|
+
|
|
13
|
+
<Dialog.Portal>
|
|
14
|
+
<Dialog.Overlay />
|
|
15
|
+
<Dialog.Content>
|
|
16
|
+
<p>Dialog body</p>
|
|
17
|
+
</Dialog.Content>
|
|
18
|
+
</Dialog.Portal>
|
|
19
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const DialogTriggerMultiButtonTest: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type DialogTriggerMultiButtonTest = InstanceType<typeof DialogTriggerMultiButtonTest>;
|
|
18
|
+
export default DialogTriggerMultiButtonTest;
|
|
@@ -24,16 +24,25 @@
|
|
|
24
24
|
const dialogCtx = ctx;
|
|
25
25
|
|
|
26
26
|
let wrapperRef: HTMLElement | null = $state(null);
|
|
27
|
+
let activeTrigger: HTMLElement | null = null;
|
|
28
|
+
|
|
29
|
+
function setActiveTrigger(button: HTMLElement) {
|
|
30
|
+
if (activeTrigger && activeTrigger !== button) {
|
|
31
|
+
activeTrigger.setAttribute('aria-expanded', 'false');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
activeTrigger = button;
|
|
35
|
+
dialogCtx.setTriggerRef(button);
|
|
36
|
+
button.setAttribute('aria-haspopup', 'dialog');
|
|
37
|
+
button.setAttribute('aria-expanded', String(dialogCtx.isOpen));
|
|
38
|
+
}
|
|
27
39
|
|
|
28
40
|
function handleClick(event: MouseEvent) {
|
|
29
41
|
const target = event.target as HTMLElement;
|
|
30
42
|
const button = target.closest('button, [role="button"]') as HTMLElement | null;
|
|
31
43
|
|
|
32
44
|
if (button && wrapperRef?.contains(button)) {
|
|
33
|
-
|
|
34
|
-
if (!dialogCtx.triggerRef) {
|
|
35
|
-
dialogCtx.setTriggerRef(button);
|
|
36
|
-
}
|
|
45
|
+
setActiveTrigger(button);
|
|
37
46
|
dialogCtx.toggle();
|
|
38
47
|
}
|
|
39
48
|
}
|
|
@@ -43,8 +52,7 @@
|
|
|
43
52
|
// Find and set up the trigger button
|
|
44
53
|
const firstButton = wrapperRef.querySelector('button, [role="button"]') as HTMLElement | null;
|
|
45
54
|
if (firstButton) {
|
|
46
|
-
|
|
47
|
-
firstButton.setAttribute('aria-haspopup', 'dialog');
|
|
55
|
+
setActiveTrigger(firstButton);
|
|
48
56
|
}
|
|
49
57
|
}
|
|
50
58
|
|
|
@@ -59,6 +67,10 @@
|
|
|
59
67
|
|
|
60
68
|
$effect(() => {
|
|
61
69
|
if (dialogCtx.triggerRef) {
|
|
70
|
+
if (activeTrigger !== dialogCtx.triggerRef) {
|
|
71
|
+
activeTrigger = dialogCtx.triggerRef;
|
|
72
|
+
}
|
|
73
|
+
dialogCtx.triggerRef.setAttribute('aria-haspopup', 'dialog');
|
|
62
74
|
dialogCtx.triggerRef.setAttribute('aria-expanded', String(dialogCtx.isOpen));
|
|
63
75
|
}
|
|
64
76
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
export { ComboBox } from './combobox/index.ts';
|
|
2
|
+
export { Calendar } from './calendar/index.ts';
|
|
3
|
+
export { DatePicker } from './datepicker/index.ts';
|
|
2
4
|
export { Dialog } from './dialog/index.ts';
|
|
3
5
|
export { ListBox } from './listbox/index.ts';
|
|
4
6
|
export { Popover } from './popover/index.ts';
|
|
5
7
|
export { default as Input } from './input/index.ts';
|
|
6
8
|
export { default as Label } from './label/index.ts';
|
|
9
|
+
export { default as LocaleProvider } from './locale-provider/index.ts';
|
|
7
10
|
export { Portal } from './portal/index.ts';
|
|
11
|
+
export * from './locale-provider/index.ts';
|
|
8
12
|
export * from './combobox/index.ts';
|
|
13
|
+
export * from './calendar/index.ts';
|
|
14
|
+
export * from './datepicker/index.ts';
|
|
9
15
|
export * from './dialog/index.ts';
|
|
10
16
|
export * from './listbox/index.ts';
|
|
11
17
|
export * from './popover/index.ts';
|
|
12
18
|
export * from './primitives/index.ts';
|
|
13
19
|
export { cn } from './utils/index.ts';
|
|
20
|
+
export * from './utils/index.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
// Main library entry point
|
|
2
2
|
// Components (namespace exports)
|
|
3
3
|
export { ComboBox } from './combobox/index.ts';
|
|
4
|
+
export { Calendar } from './calendar/index.ts';
|
|
5
|
+
export { DatePicker } from './datepicker/index.ts';
|
|
4
6
|
export { Dialog } from './dialog/index.ts';
|
|
5
7
|
export { ListBox } from './listbox/index.ts';
|
|
6
8
|
export { Popover } from './popover/index.ts';
|
|
7
9
|
// Simple components
|
|
8
10
|
export { default as Input } from './input/index.ts';
|
|
9
11
|
export { default as Label } from './label/index.ts';
|
|
12
|
+
export { default as LocaleProvider } from './locale-provider/index.ts';
|
|
10
13
|
export { Portal } from './portal/index.ts';
|
|
14
|
+
export * from './locale-provider/index.ts';
|
|
11
15
|
// Re-export named exports from components
|
|
12
16
|
export * from './combobox/index.ts';
|
|
17
|
+
export * from './calendar/index.ts';
|
|
18
|
+
export * from './datepicker/index.ts';
|
|
13
19
|
export * from './dialog/index.ts';
|
|
14
20
|
export * from './listbox/index.ts';
|
|
15
21
|
export * from './popover/index.ts';
|
|
@@ -17,3 +23,4 @@ export * from './popover/index.ts';
|
|
|
17
23
|
export * from './primitives/index.ts';
|
|
18
24
|
// Utilities
|
|
19
25
|
export { cn } from './utils/index.ts';
|
|
26
|
+
export * from './utils/index.ts';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# ListBox
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
`ListBox` is a headless selectable list primitive with keyboard navigation, single and multiple selection, and controlled or uncontrolled state.
|
|
6
|
+
|
|
7
|
+
## Usage guidelines
|
|
8
|
+
|
|
9
|
+
- Use `ListBox.Root` as the container for selection state and keyboard interactions.
|
|
10
|
+
- Render each option with `ListBox.Item`.
|
|
11
|
+
- Use `value` and `onChange` for controlled selection.
|
|
12
|
+
- Use `defaultValue` for uncontrolled initial selection.
|
|
13
|
+
- Provide `aria-label` when there is no visible label.
|
|
14
|
+
|
|
15
|
+
## Anatomy
|
|
16
|
+
|
|
17
|
+
Import the component and compose its parts:
|
|
18
|
+
|
|
19
|
+
```svelte
|
|
20
|
+
<ListBox.Root aria-label="Options">
|
|
21
|
+
<ListBox.Item id="1">Option 1</ListBox.Item>
|
|
22
|
+
</ListBox.Root>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `ListBox.Root`
|
|
26
|
+
- `ListBox.Item`
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# ListBox Item
|
|
2
|
+
|
|
3
|
+
## API reference
|
|
4
|
+
|
|
5
|
+
### ListBox.Item
|
|
6
|
+
|
|
7
|
+
Name: `ListBox.Item`
|
|
8
|
+
Description: Selectable option element with built-in selected, focused, hovered, and disabled states.
|
|
9
|
+
|
|
10
|
+
| Prop | Type | Default | Description |
|
|
11
|
+
| ---------------------- | -------------------------------- | -------------------- | -------------------------------------------------------- |
|
|
12
|
+
| `id` | `string \| number` | `required` | Unique id for option registration and selection. |
|
|
13
|
+
| `textValue` | `string` | `content text` | String used for text resolution and typeahead. |
|
|
14
|
+
| `disabled` | `boolean` | `false` | Disables item interaction. |
|
|
15
|
+
| `class` | `string` | `''` | CSS class names for the item. |
|
|
16
|
+
| `children` | `Snippet` | `undefined` | Rendered item content. |
|
|
17
|
+
| `customId` | `string` | `listbox-item-${id}` | Overrides generated DOM id. |
|
|
18
|
+
| `disableFocusHandling` | `boolean` | `false` | Disables internal DOM focus behavior. |
|
|
19
|
+
| `isFocusedOverride` | `boolean` | `undefined` | Forces focused state from parent composition. |
|
|
20
|
+
| `onItemSelect` | `(id, label) => void` | `undefined` | Custom selection callback override. |
|
|
21
|
+
| `onResolvedTextValue` | `(label: string) => void` | `undefined` | Called when item text value is resolved. |
|
|
22
|
+
| `scrollOnFocus` | `boolean` | `false` | Scrolls item into view when focused. |
|
|
23
|
+
| `isParentDisabled` | `boolean` | `false` | Additional disabled state inherited from parent wrapper. |
|
|
24
|
+
| `...restProps` | `HTMLAttributes<HTMLDivElement>` | `-` | Additional option attributes. |
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# ListBox Root
|
|
2
|
+
|
|
3
|
+
## API reference
|
|
4
|
+
|
|
5
|
+
### ListBox.Root
|
|
6
|
+
|
|
7
|
+
Name: `ListBox.Root`
|
|
8
|
+
Description: Main listbox state container that manages registration, selection, focus, and keyboard navigation.
|
|
9
|
+
|
|
10
|
+
| Prop | Type | Default | Description |
|
|
11
|
+
| ------------------- | ---------------------------------------- | --------------------- | ------------------------------------------------------------ |
|
|
12
|
+
| `selectionBehavior` | `'toggle' \| 'replace'` | `'toggle'` | Selection behavior for already selected options. |
|
|
13
|
+
| `emptyPlaceholder` | `string \| Snippet` | `'No items selected'` | Fallback content when no options are available. |
|
|
14
|
+
| `items` | `Iterable<T>` | `undefined` | Dynamic source collection for rendering. |
|
|
15
|
+
| `disabledIds` | `Iterable<string \| number>` | `undefined` | Option ids that should be disabled. |
|
|
16
|
+
| `selectionMode` | `'single' \| 'multiple'` | `'single'` | Selection mode for the listbox. |
|
|
17
|
+
| `value` | `Iterable<string \| number>` | `undefined` | Controlled selection values. |
|
|
18
|
+
| `defaultValue` | `Iterable<string \| number>` | `undefined` | Initial uncontrolled selection values. |
|
|
19
|
+
| `children` | `Snippet \| Snippet<[T]>` | `undefined` | Static or dynamic option rendering. |
|
|
20
|
+
| `class` | `string` | `''` | CSS class names for the root element. |
|
|
21
|
+
| `id` | `string` | `undefined` | DOM id for the listbox element. |
|
|
22
|
+
| `aria-label` | `string` | `undefined` | Accessible label for the listbox. |
|
|
23
|
+
| `onChange` | `(value: Set<string \| number>) => void` | `undefined` | Called when selection changes. |
|
|
24
|
+
| `context` | `ListBoxContext` | `bindable` | Exposes context via `bind:context` for advanced composition. |
|
|
25
|
+
| `element` | `HTMLElement` | `bindable` | Exposes root element via `bind:element`. |
|
|
26
|
+
|
|
27
|
+
### Context utilities
|
|
28
|
+
|
|
29
|
+
Name: `context.ts` helpers
|
|
30
|
+
Description: Low-level APIs for creating and consuming listbox state outside visual composition.
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Description |
|
|
33
|
+
| ----------------------------------------------- | ------------------------------------------------- | ----------- | ------------------------------------------------------------ |
|
|
34
|
+
| `createListBoxContext(options)` | `(CreateListBoxContextOptions) => ListBoxContext` | `{}` | Creates a listbox context with selection and focus behavior. |
|
|
35
|
+
| `useListBoxContext()` | `() => ListBoxContext` | `-` | Returns context and throws outside `ListBox.Root`. |
|
|
36
|
+
| `CreateListBoxContextOptions.selectionMode` | `'single' \| 'multiple'` | `'single'` | Initial selection mode. |
|
|
37
|
+
| `CreateListBoxContextOptions.selectionBehavior` | `'toggle' \| 'replace'` | `'toggle'` | Initial selection behavior. |
|
|
38
|
+
| `CreateListBoxContextOptions.disabledIds` | `Iterable<string \| number>` | `undefined` | Initial disabled ids. |
|
|
39
|
+
| `CreateListBoxContextOptions.initialSelection` | `Set<string \| number>` | `new Set()` | Initial uncontrolled selection set. |
|
|
40
|
+
| `CreateListBoxContextOptions.onSelectionChange` | `(selection) => void` | `undefined` | Callback for selection updates. |
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends object = object">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import { createListBoxContext, type ListBoxContext } from './context';
|
|
4
|
+
import {
|
|
5
|
+
shouldShowFocusVisible,
|
|
6
|
+
trackInteractionModality
|
|
7
|
+
} from '../../primitives/input-modality';
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
10
|
* Props for the ListBox component.
|
|
@@ -114,6 +118,40 @@
|
|
|
114
118
|
|
|
115
119
|
const itemsArray = $derived(items ? Array.from(items) : []);
|
|
116
120
|
const hasItems = $derived(itemsArray.length > 0 || itemCount > 0);
|
|
121
|
+
|
|
122
|
+
let focusWithin = $state(false);
|
|
123
|
+
let focusVisible = $state(false);
|
|
124
|
+
|
|
125
|
+
function syncFocusWithin() {
|
|
126
|
+
focusWithin =
|
|
127
|
+
!!listboxElement &&
|
|
128
|
+
!!document.activeElement &&
|
|
129
|
+
listboxElement.contains(document.activeElement);
|
|
130
|
+
if (!focusWithin) {
|
|
131
|
+
focusVisible = false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function handleFocusIn(event: FocusEvent) {
|
|
136
|
+
focusWithin = true;
|
|
137
|
+
focusVisible = shouldShowFocusVisible(event.target as HTMLElement | null);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function handleFocusOut() {
|
|
141
|
+
queueMicrotask(syncFocusWithin);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function handleMouseDown(event: MouseEvent) {
|
|
145
|
+
trackInteractionModality(event, event.target as HTMLElement | null);
|
|
146
|
+
focusVisible = false;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function handleKeyDown(event: KeyboardEvent) {
|
|
150
|
+
trackInteractionModality(event, event.target as HTMLElement | null);
|
|
151
|
+
if (focusWithin) {
|
|
152
|
+
focusVisible = true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
117
155
|
</script>
|
|
118
156
|
|
|
119
157
|
<div
|
|
@@ -124,7 +162,13 @@
|
|
|
124
162
|
aria-label={ariaLabel}
|
|
125
163
|
class={className}
|
|
126
164
|
tabindex="0"
|
|
165
|
+
data-focus-within={focusWithin || undefined}
|
|
166
|
+
data-focus-visible={focusVisible || undefined}
|
|
127
167
|
use:keyboardAction
|
|
168
|
+
onfocusin={handleFocusIn}
|
|
169
|
+
onfocusout={handleFocusOut}
|
|
170
|
+
onmousedown={handleMouseDown}
|
|
171
|
+
onkeydown={handleKeyDown}
|
|
128
172
|
>
|
|
129
173
|
{#if items && children}
|
|
130
174
|
{#each itemsArray as item (item)}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Readable } from 'svelte/store';
|
|
2
|
+
export type LocaleContext = {
|
|
3
|
+
locale: Readable<string | undefined>;
|
|
4
|
+
};
|
|
5
|
+
export declare function setLocaleContext(context: LocaleContext): void;
|
|
6
|
+
export declare function getLocaleContext(): LocaleContext | undefined;
|
|
7
|
+
export declare function useLocaleContext(): LocaleContext;
|
|
8
|
+
export declare function useLocaleContextOptional(): LocaleContext | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getContext, setContext } from 'svelte';
|
|
2
|
+
const KEY = Symbol('locale-provider');
|
|
3
|
+
export function setLocaleContext(context) {
|
|
4
|
+
setContext(KEY, context);
|
|
5
|
+
}
|
|
6
|
+
export function getLocaleContext() {
|
|
7
|
+
return getContext(KEY);
|
|
8
|
+
}
|
|
9
|
+
export function useLocaleContext() {
|
|
10
|
+
const context = getLocaleContext();
|
|
11
|
+
if (!context) {
|
|
12
|
+
throw new Error('LocaleProvider must wrap component tree when using useLocaleContext.');
|
|
13
|
+
}
|
|
14
|
+
return context;
|
|
15
|
+
}
|
|
16
|
+
export function useLocaleContextOptional() {
|
|
17
|
+
return getLocaleContext();
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { LocaleProvider } from '../index';
|
|
3
|
+
import LocaleProviderValueProbe from './locale-provider-value-probe.svelte';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
locale?: string;
|
|
7
|
+
onValue?: (value: string | undefined) => void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
let { locale = 'es-ES', onValue }: Props = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<LocaleProvider {locale}>
|
|
14
|
+
<LocaleProviderValueProbe {onValue} />
|
|
15
|
+
</LocaleProvider>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
locale?: string;
|
|
3
|
+
onValue?: (value: string | undefined) => void;
|
|
4
|
+
};
|
|
5
|
+
declare const LocaleProviderInitialValueTest: import("svelte").Component<Props, {}, "">;
|
|
6
|
+
type LocaleProviderInitialValueTest = ReturnType<typeof LocaleProviderInitialValueTest>;
|
|
7
|
+
export default LocaleProviderInitialValueTest;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { LocaleProvider } from '../index';
|
|
3
|
+
import Calendar from '../calendar';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
locale?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
let { locale = 'es-ES' }: Props = $props();
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<LocaleProvider {locale}>
|
|
13
|
+
<Calendar.Root defaultValue="2026-02-10" aria-label="Locale provider test calendar">
|
|
14
|
+
<Calendar.Heading />
|
|
15
|
+
<Calendar.Grid>
|
|
16
|
+
<Calendar.GridHeader />
|
|
17
|
+
<Calendar.GridBody />
|
|
18
|
+
</Calendar.Grid>
|
|
19
|
+
</Calendar.Root>
|
|
20
|
+
</LocaleProvider>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { useLocaleContext } from './context';
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
onValue?: (value: string | undefined) => void;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
let { onValue }: Props = $props();
|
|
9
|
+
|
|
10
|
+
const { locale } = useLocaleContext();
|
|
11
|
+
const unsubscribe = locale.subscribe((value) => {
|
|
12
|
+
onValue?.(value);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
$effect(() => {
|
|
16
|
+
return () => {
|
|
17
|
+
unsubscribe();
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div data-testid="locale-value-probe"></div>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
onValue?: (value: string | undefined) => void;
|
|
3
|
+
};
|
|
4
|
+
declare const LocaleProviderValueProbe: import("svelte").Component<Props, {}, "">;
|
|
5
|
+
type LocaleProviderValueProbe = ReturnType<typeof LocaleProviderValueProbe>;
|
|
6
|
+
export default LocaleProviderValueProbe;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { writable } from 'svelte/store';
|
|
4
|
+
import { setLocaleContext } from './context';
|
|
5
|
+
|
|
6
|
+
type LocaleProviderProps = {
|
|
7
|
+
locale?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let props: LocaleProviderProps = $props();
|
|
12
|
+
|
|
13
|
+
const localeStore = writable<string | undefined>(props.locale);
|
|
14
|
+
setLocaleContext({ locale: localeStore });
|
|
15
|
+
|
|
16
|
+
$effect(() => {
|
|
17
|
+
localeStore.set(props.locale);
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
{#if props.children}
|
|
22
|
+
{@render props.children()}
|
|
23
|
+
{/if}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type LocaleProviderProps = {
|
|
3
|
+
locale?: string;
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
};
|
|
6
|
+
declare const LocaleProvider: import("svelte").Component<LocaleProviderProps, {}, "">;
|
|
7
|
+
type LocaleProvider = ReturnType<typeof LocaleProvider>;
|
|
8
|
+
export default LocaleProvider;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Popover
|
|
2
|
+
|
|
3
|
+
## Description
|
|
4
|
+
|
|
5
|
+
`Popover` renders floating content anchored to a trigger element. It supports modal and non-modal interaction patterns, outside interaction handling, and configurable positioning.
|
|
6
|
+
|
|
7
|
+
## Usage guidelines
|
|
8
|
+
|
|
9
|
+
- Use `Popover.Root` to share open state and trigger reference.
|
|
10
|
+
- Use `Popover.Trigger` when you want to auto-wire an existing button in children.
|
|
11
|
+
- Use `Popover.TriggerButton` when you want a pre-wired trigger button component.
|
|
12
|
+
- Use `Popover.Content` inside `Popover.Root`, or in standalone mode with `open`, `triggerRef`, and `onOpenChange`.
|
|
13
|
+
- Configure `isNonModal`, `shouldCloseOnInteractOutside`, and `shouldCloseOnBlur` to match your interaction model.
|
|
14
|
+
|
|
15
|
+
## onOpenChange details
|
|
16
|
+
|
|
17
|
+
`Popover.Root` and standalone `Popover.Content` use:
|
|
18
|
+
|
|
19
|
+
- `onOpenChange(open, details)`
|
|
20
|
+
- `details.reason`: `trigger-press | imperative-action | none | escape-key | outside-press | focus-out | close-press`
|
|
21
|
+
- `details.event?`: native event that triggered the change when available
|
|
22
|
+
- `details.cancel()`: prevents the open-state transition
|
|
23
|
+
- `details.isCanceled`: reflects cancellation state inside the callback
|
|
24
|
+
|
|
25
|
+
## Anatomy
|
|
26
|
+
|
|
27
|
+
Import the component and compose its parts:
|
|
28
|
+
|
|
29
|
+
```svelte
|
|
30
|
+
<Popover.Root>
|
|
31
|
+
<Popover.Trigger>
|
|
32
|
+
<button>Open</button>
|
|
33
|
+
</Popover.Trigger>
|
|
34
|
+
<Popover.Content>
|
|
35
|
+
<div>Content</div>
|
|
36
|
+
</Popover.Content>
|
|
37
|
+
</Popover.Root>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- `Popover.Root`
|
|
41
|
+
- `Popover.Trigger` or `Popover.TriggerButton`
|
|
42
|
+
- `Popover.Content`
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Popover Content
|
|
2
|
+
|
|
3
|
+
## API reference
|
|
4
|
+
|
|
5
|
+
### Popover.Content
|
|
6
|
+
|
|
7
|
+
Name: `Popover.Content`
|
|
8
|
+
Description: Floating panel rendered in a portal. Supports context mode (`Popover.Root`) and standalone controlled mode.
|
|
9
|
+
|
|
10
|
+
| Prop | Type | Default | Description |
|
|
11
|
+
| ------------------------------ | -------------------------------- | ----------- | ------------------------------------------------------------------------------ |
|
|
12
|
+
| `offset` | `number` | `8` | Main-axis offset from the anchor element. |
|
|
13
|
+
| `placement` | `ExtendedPlacement` | `'bottom'` | Preferred floating placement. |
|
|
14
|
+
| `shouldFlip` | `boolean` | `true` | Enables automatic fallback placement when space is limited. |
|
|
15
|
+
| `boundaryElement` | `Element \| null` | `null` | Optional boundary element for positioning constraints. |
|
|
16
|
+
| `children` | `Snippet` | `undefined` | Rendered popover panel content. |
|
|
17
|
+
| `class` | `string` | `''` | CSS class names for the panel element. |
|
|
18
|
+
| `isNonModal` | `boolean` | `false` | Disables modal behaviors (focus trap, scroll lock, outside aria hiding). |
|
|
19
|
+
| `shouldCloseOnInteractOutside` | `boolean` | `true` | Closes when interacting outside the panel. |
|
|
20
|
+
| `shouldCloseOnEscape` | `boolean` | `true` | Closes on Escape key press. |
|
|
21
|
+
| `shouldCloseOnBlur` | `boolean` | `undefined` | Closes on focus leaving trigger/content. Defaults to `true` in non-modal mode. |
|
|
22
|
+
| `open` | `boolean` | `undefined` | Controlled open state in standalone mode. |
|
|
23
|
+
| `triggerRef` | `HTMLElement \| null` | `null` | Trigger reference in standalone mode. |
|
|
24
|
+
| `onOpenChange` | `(open: boolean) => void` | `undefined` | Open-state callback in standalone mode. |
|
|
25
|
+
| `...restProps` | `HTMLAttributes<HTMLDivElement>` | `-` | Additional panel attributes. |
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Popover } from '../index';
|
|
3
|
+
import type { PopoverOpenChangeDetails } from '../root/context';
|
|
4
|
+
|
|
5
|
+
type Props = {
|
|
6
|
+
preventClose?: boolean;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
let { preventClose = true }: Props = $props();
|
|
10
|
+
|
|
11
|
+
let open = $state(true);
|
|
12
|
+
let triggerRef = $state<HTMLElement | null>(null);
|
|
13
|
+
|
|
14
|
+
function handleOpenChange(nextOpen: boolean, details: PopoverOpenChangeDetails) {
|
|
15
|
+
if (!nextOpen && preventClose) {
|
|
16
|
+
details.cancel();
|
|
17
|
+
}
|
|
18
|
+
if (!details.isCanceled) {
|
|
19
|
+
open = nextOpen;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<button bind:this={triggerRef} type="button">Standalone Trigger</button>
|
|
25
|
+
|
|
26
|
+
<Popover.Content {open} {triggerRef} onOpenChange={handleOpenChange}>
|
|
27
|
+
<div>Standalone content</div>
|
|
28
|
+
</Popover.Content>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Popover } from '../index';
|
|
3
|
+
import type { PopoverOpenChangeDetails } from '../root/context';
|
|
3
4
|
|
|
4
5
|
type Props = {
|
|
5
6
|
open?: boolean;
|
|
@@ -8,7 +9,7 @@
|
|
|
8
9
|
shouldCloseOnInteractOutside?: boolean;
|
|
9
10
|
shouldCloseOnEscape?: boolean;
|
|
10
11
|
shouldCloseOnBlur?: boolean;
|
|
11
|
-
onOpenChange?: (open: boolean) => void;
|
|
12
|
+
onOpenChange?: (open: boolean, details: PopoverOpenChangeDetails) => void;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
let {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PopoverOpenChangeDetails } from '../root/context';
|
|
1
2
|
type Props = {
|
|
2
3
|
open?: boolean;
|
|
3
4
|
defaultOpen?: boolean;
|
|
@@ -5,7 +6,7 @@ type Props = {
|
|
|
5
6
|
shouldCloseOnInteractOutside?: boolean;
|
|
6
7
|
shouldCloseOnEscape?: boolean;
|
|
7
8
|
shouldCloseOnBlur?: boolean;
|
|
8
|
-
onOpenChange?: (open: boolean) => void;
|
|
9
|
+
onOpenChange?: (open: boolean, details: PopoverOpenChangeDetails) => void;
|
|
9
10
|
};
|
|
10
11
|
declare const PopoverContentTest: import("svelte").Component<Props, {}, "">;
|
|
11
12
|
type PopoverContentTest = ReturnType<typeof PopoverContentTest>;
|