@svelte-atoms/core 1.0.0-alpha.30 → 1.0.0-alpha.32

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.
Files changed (221) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -739
  3. package/dist/attachments/index.d.ts +1 -0
  4. package/dist/attachments/index.js +1 -0
  5. package/dist/components/accordion/accordion-root.svelte +65 -61
  6. package/dist/components/accordion/accordion.stories.svelte +70 -145
  7. package/dist/components/accordion/item/accordion-item-body.svelte +6 -4
  8. package/dist/components/accordion/item/accordion-item-header.svelte +2 -1
  9. package/dist/components/accordion/item/accordion-item-indicator.svelte +2 -1
  10. package/dist/components/accordion/item/accordion-item-root.svelte +2 -1
  11. package/dist/components/accordion/item/bond.svelte.d.ts +2 -0
  12. package/dist/components/accordion/item/index.d.ts +3 -0
  13. package/dist/components/accordion/item/index.js +3 -0
  14. package/dist/components/accordion/item/motion.svelte.d.ts +15 -0
  15. package/dist/components/accordion/item/motion.svelte.js +30 -0
  16. package/dist/components/accordion/item/types.d.ts +7 -24
  17. package/dist/components/alert/alert-close-button.svelte +32 -36
  18. package/dist/components/alert/alert-description.svelte +1 -1
  19. package/dist/components/alert/alert-description.svelte.d.ts +3 -6
  20. package/dist/components/alert/alert-root.svelte +3 -38
  21. package/dist/components/alert/alert-root.svelte.d.ts +2 -2
  22. package/dist/components/alert/alert.stories.svelte +400 -400
  23. package/dist/components/alert/bond.svelte.d.ts +0 -13
  24. package/dist/components/alert/bond.svelte.js +0 -32
  25. package/dist/components/alert/types.d.ts +8 -32
  26. package/dist/components/atom/html-atom.svelte +93 -261
  27. package/dist/components/atom/types.d.ts +3 -2
  28. package/dist/components/atom/utils.d.ts +37 -0
  29. package/dist/components/atom/utils.js +208 -0
  30. package/dist/components/avatar/avatar.stories.svelte +22 -22
  31. package/dist/components/badge/badge.stories.svelte +12 -12
  32. package/dist/components/badge/badge.svelte +19 -19
  33. package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
  34. package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
  35. package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
  36. package/dist/components/button/button.stories.svelte +27 -27
  37. package/dist/components/calendar/calendar-day.svelte +9 -4
  38. package/dist/components/calendar/calendar.stories.svelte +26 -26
  39. package/dist/components/card/card-body.svelte +39 -39
  40. package/dist/components/card/card-footer.svelte +41 -41
  41. package/dist/components/card/card-root.svelte +91 -91
  42. package/dist/components/card/card.stories.svelte +133 -133
  43. package/dist/components/checkbox/checkbox.stories.svelte +22 -22
  44. package/dist/components/checkbox/checkbox.svelte +159 -155
  45. package/dist/components/collapsible/bond.svelte.js +2 -1
  46. package/dist/components/collapsible/collapsible-body.svelte +3 -2
  47. package/dist/components/collapsible/collapsible.stories.svelte +172 -172
  48. package/dist/components/collapsible/motion.svelte.d.ts +6 -0
  49. package/dist/components/collapsible/motion.svelte.js +15 -0
  50. package/dist/components/combobox/atoms.d.ts +3 -3
  51. package/dist/components/combobox/atoms.js +3 -3
  52. package/dist/components/combobox/bond.svelte.d.ts +6 -6
  53. package/dist/components/combobox/bond.svelte.js +3 -26
  54. package/dist/components/combobox/combobox-control.svelte +52 -52
  55. package/dist/components/combobox/{compobox-item.svelte → combobox-item.svelte} +62 -68
  56. package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
  57. package/dist/components/combobox/combobox-root.svelte +65 -65
  58. package/dist/components/combobox/combobox.stories.svelte +50 -0
  59. package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
  60. package/dist/components/combobox/index.d.ts +1 -0
  61. package/dist/components/container/container.stories.svelte +20 -20
  62. package/dist/components/container/container.svelte.d.ts +1 -1
  63. package/dist/components/datagrid/datagrid.stories.svelte +72 -72
  64. package/dist/components/datagrid/tr/bond.svelte.d.ts +4 -2
  65. package/dist/components/datagrid/tr/bond.svelte.js +9 -7
  66. package/dist/components/datagrid/tr/datagrid-tr.svelte +9 -7
  67. package/dist/components/date-picker/bond.svelte.d.ts +15 -5
  68. package/dist/components/date-picker/bond.svelte.js +5 -11
  69. package/dist/components/date-picker/date-picker-calendar.svelte +2 -2
  70. package/dist/components/date-picker/date-picker-root.svelte +95 -95
  71. package/dist/components/date-picker/date-picker.stories.svelte +35 -35
  72. package/dist/components/dialog/bond.svelte.d.ts +13 -3
  73. package/dist/components/dialog/bond.svelte.js +52 -6
  74. package/dist/components/dialog/dialog-content.svelte +2 -20
  75. package/dist/components/dialog/dialog-root.svelte +3 -22
  76. package/dist/components/dialog/dialog.stories.svelte +64 -64
  77. package/dist/components/dialog/motion.svelte.d.ts +13 -0
  78. package/dist/components/dialog/motion.svelte.js +44 -0
  79. package/dist/components/drawer/attachments.svelte.d.ts +1 -1
  80. package/dist/components/drawer/attachments.svelte.js +1 -3
  81. package/dist/components/drawer/bond.svelte.d.ts +30 -9
  82. package/dist/components/drawer/bond.svelte.js +80 -24
  83. package/dist/components/drawer/drawer-content.svelte +49 -57
  84. package/dist/components/drawer/drawer-root.svelte +5 -4
  85. package/dist/components/drawer/drawer.stories.svelte +141 -212
  86. package/dist/components/drawer/index.d.ts +2 -0
  87. package/dist/components/drawer/index.js +2 -0
  88. package/dist/components/drawer/motion.d.ts +15 -0
  89. package/dist/components/drawer/motion.js +28 -0
  90. package/dist/components/dropdown/atoms.d.ts +1 -1
  91. package/dist/components/dropdown/atoms.js +1 -1
  92. package/dist/components/dropdown/bond.svelte.d.ts +22 -19
  93. package/dist/components/dropdown/bond.svelte.js +29 -53
  94. package/dist/components/dropdown/dropdown-root.svelte +7 -1
  95. package/dist/components/dropdown/dropdown-values.svelte +17 -17
  96. package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
  97. package/dist/components/dropdown/dropdown.stories.svelte +13 -10
  98. package/dist/components/dropdown/index.d.ts +2 -0
  99. package/dist/components/dropdown/index.js +1 -0
  100. package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
  101. package/dist/components/dropdown/item/attachments.svelte.js +2 -2
  102. package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
  103. package/dist/components/dropdown/item/controller.svelte.js +82 -0
  104. package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
  105. package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
  106. package/dist/components/dropdown/item/index.d.ts +3 -0
  107. package/dist/components/dropdown/item/index.js +3 -0
  108. package/dist/components/dropdown/item/types.d.ts +29 -0
  109. package/dist/components/dropdown/item/types.js +1 -0
  110. package/dist/components/form/form.stories.svelte +96 -96
  111. package/dist/components/image/image.stories.svelte +20 -20
  112. package/dist/components/input/input.stories.svelte +35 -35
  113. package/dist/components/label/label.stories.svelte +15 -15
  114. package/dist/components/lazy/lazy.stories.svelte +28 -28
  115. package/dist/components/link/link.stories.svelte +15 -15
  116. package/dist/components/list/list-item.svelte +2 -2
  117. package/dist/components/menu/atoms.d.ts +9 -3
  118. package/dist/components/menu/atoms.js +9 -3
  119. package/dist/components/menu/bond.svelte.d.ts +54 -0
  120. package/dist/components/menu/bond.svelte.js +132 -0
  121. package/dist/components/menu/index.d.ts +3 -1
  122. package/dist/components/menu/index.js +2 -1
  123. package/dist/components/menu/item/controller.svelte.d.ts +26 -0
  124. package/dist/components/menu/item/controller.svelte.js +69 -0
  125. package/dist/components/menu/item/index.d.ts +2 -0
  126. package/dist/components/menu/item/index.js +2 -0
  127. package/dist/components/menu/item/menu-item.svelte +103 -0
  128. package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
  129. package/dist/components/menu/item/types.d.ts +62 -0
  130. package/dist/components/menu/item/types.js +1 -0
  131. package/dist/components/menu/{menu-list.svelte → menu-content.svelte} +40 -40
  132. package/dist/components/menu/{menu-list.svelte.d.ts → menu-content.svelte.d.ts} +3 -3
  133. package/dist/components/menu/menu-root.svelte +15 -0
  134. package/dist/components/menu/menu-root.svelte.d.ts +8 -0
  135. package/dist/components/menu/menu.stories.svelte +5 -5
  136. package/dist/components/menu/types.d.ts +0 -7
  137. package/dist/components/popover/bond.svelte.d.ts +18 -8
  138. package/dist/components/popover/bond.svelte.js +76 -40
  139. package/dist/components/popover/motion.d.ts +6 -0
  140. package/dist/components/popover/motion.js +56 -0
  141. package/dist/components/popover/popover-arrow.svelte +111 -111
  142. package/dist/components/popover/popover-content.svelte +137 -175
  143. package/dist/components/popover/popover-indicator.svelte +44 -44
  144. package/dist/components/popover/popover-root.svelte +48 -48
  145. package/dist/components/popover/popover.stories.svelte +37 -49
  146. package/dist/components/popover/types.d.ts +9 -7
  147. package/dist/components/portal/active-portal.svelte +12 -5
  148. package/dist/components/portal/active-portal.svelte.d.ts +2 -9
  149. package/dist/components/portal/portal-root.svelte +1 -8
  150. package/dist/components/portal/portal-root.svelte.d.ts +4 -6
  151. package/dist/components/portal/teleport.svelte +1 -2
  152. package/dist/components/portal/teleport.svelte.d.ts +3 -4
  153. package/dist/components/qr-code/qr-code.stories.svelte +18 -18
  154. package/dist/components/radio/radio-group.stories.svelte +41 -41
  155. package/dist/components/radio/radio.stories.svelte +17 -17
  156. package/dist/components/radio/radio.svelte +109 -109
  157. package/dist/components/radio/types.d.ts +98 -0
  158. package/dist/components/radio/types.js +2 -0
  159. package/dist/components/root/index.d.ts +1 -0
  160. package/dist/components/root/index.js +1 -0
  161. package/dist/components/root/l0-portal.svelte +8 -0
  162. package/dist/components/{radio/types.svelte.d.ts → root/l0-portal.svelte.d.ts} +3 -3
  163. package/dist/components/root/l1-portal.svelte +7 -0
  164. package/dist/components/root/l1-portal.svelte.d.ts +26 -0
  165. package/dist/components/root/root.css +119 -119
  166. package/dist/components/root/root.svelte +26 -44
  167. package/dist/components/root/root.svelte.d.ts +2 -6
  168. package/dist/components/root/toasts-portal.svelte +7 -0
  169. package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
  170. package/dist/components/root/types.d.ts +17 -0
  171. package/dist/components/scrollable/scrollable-root.svelte.d.ts +2 -2
  172. package/dist/components/scrollable/scrollable.stories.svelte +116 -116
  173. package/dist/components/sidebar/index.d.ts +2 -0
  174. package/dist/components/sidebar/index.js +2 -0
  175. package/dist/components/sidebar/motion.svelte.d.ts +11 -0
  176. package/dist/components/sidebar/motion.svelte.js +16 -0
  177. package/dist/components/sidebar/sidebar-content.svelte +40 -50
  178. package/dist/components/sidebar/sidebar-root.svelte +39 -39
  179. package/dist/components/sidebar/sidebar.stories.svelte +43 -43
  180. package/dist/components/sidebar/types.d.ts +2 -12
  181. package/dist/components/tabs/tabs.stories.svelte +56 -56
  182. package/dist/components/textarea/atoms.d.ts +1 -0
  183. package/dist/components/textarea/atoms.js +1 -0
  184. package/dist/components/textarea/textarea-input.svelte +4 -1
  185. package/dist/components/textarea/textarea-root.svelte +2 -2
  186. package/dist/components/textarea/textarea-root.svelte.d.ts +2 -0
  187. package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
  188. package/dist/components/tooltip/tooltip-trigger.svelte.d.ts +1 -0
  189. package/dist/components/tooltip/tooltip.stories.svelte +32 -32
  190. package/dist/components/tree/index.d.ts +1 -0
  191. package/dist/components/tree/index.js +1 -0
  192. package/dist/components/tree/motion.svelte.d.ts +6 -0
  193. package/dist/components/tree/motion.svelte.js +14 -0
  194. package/dist/components/tree/tree-body.svelte +4 -3
  195. package/dist/components/tree/tree.stories.svelte +142 -142
  196. package/dist/context/preset.svelte.d.ts +3 -1
  197. package/dist/icons/icon-copy.svelte +6 -0
  198. package/dist/icons/icon-copy.svelte.d.ts +26 -0
  199. package/dist/utils/dom.svelte.d.ts +2 -0
  200. package/dist/utils/dom.svelte.js +21 -0
  201. package/dist/utils/function.d.ts +1 -1
  202. package/dist/utils/promise.svelte.d.ts +5 -0
  203. package/dist/utils/promise.svelte.js +20 -0
  204. package/package.json +4 -3
  205. package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
  206. package/dist/components/combobox/compobox.stories.svelte +0 -51
  207. package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
  208. package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
  209. package/dist/components/dropdown/item/bond.svelte.js +0 -99
  210. package/dist/components/menu/menu-item.svelte +0 -51
  211. package/dist/components/menu/menu-item.svelte.d.ts +0 -36
  212. package/dist/components/radio/types.svelte +0 -0
  213. package/llm/composition.md +0 -395
  214. package/llm/crafting.md +0 -838
  215. package/llm/motion.md +0 -970
  216. package/llm/philosophy.md +0 -23
  217. package/llm/preset-variant-integration.md +0 -516
  218. package/llm/preset.md +0 -383
  219. package/llm/styling.md +0 -216
  220. package/llm/usage.md +0 -46
  221. package/llm/variants.md +0 -1259
@@ -12,13 +12,11 @@ export type DatePickerBondElements = PopoverDomElements & {
12
12
  };
13
13
  export declare class DatePickerBond<Props extends DatePickerBondProps = DatePickerBondProps, State extends DatePickerBondState<Props> = DatePickerBondState<Props>> extends PopoverBond<Props, State, DatePickerBondElements> {
14
14
  #private;
15
- static CONTEXT_KEY: string;
16
15
  constructor(state: State);
17
16
  get calendar(): CalendarBond<CalendarBondProps, import("..").CalendarBondState<CalendarBondProps>> | undefined;
18
17
  setCalendar(calendar: CalendarBond): void;
19
18
  share(): this;
20
19
  trigger(): {
21
- [x: symbol]: (node: HTMLInputElement) => void;
22
20
  id: string;
23
21
  role: string;
24
22
  'aria-expanded': boolean;
@@ -29,19 +27,31 @@ export declare class DatePickerBond<Props extends DatePickerBondProps = DatePick
29
27
  disabled: boolean;
30
28
  readonly: boolean;
31
29
  tabindex: number;
30
+ 'aria-haspopup': string;
31
+ 'data-kind': string;
32
+ onclick: (ev: PointerEvent) => void;
33
+ onkeydown: (ev: KeyboardEvent) => void;
32
34
  };
33
35
  content(): {
34
- [x: symbol]: (node: HTMLElement) => void;
35
36
  id: string;
36
37
  role: string;
37
38
  'aria-label': string;
39
+ 'aria-modal': boolean;
40
+ 'aria-labelledby': string;
41
+ inert: boolean | undefined;
42
+ tabindex: number;
43
+ 'data-atom': string;
44
+ 'data-kind': string;
45
+ 'data-active': boolean;
46
+ onkeydown: ((ev: KeyboardEvent) => void) | undefined;
38
47
  };
39
- clearButton(props?: Record<string, unknown>): {
40
- onclick: (ev: Event) => void;
48
+ clearButton(): {
49
+ [x: symbol]: (node: HTMLElement) => void;
41
50
  id: string;
42
51
  type: string;
43
52
  'aria-label': string;
44
53
  tabindex: number;
54
+ onclick: (ev: Event) => void;
45
55
  };
46
56
  static get(): DatePickerBond;
47
57
  static set(bond: DatePickerBond): DatePickerBond;
@@ -2,7 +2,6 @@ import { PopoverBond, PopoverState } from '../popover/bond.svelte';
2
2
  import { getContext, setContext } from 'svelte';
3
3
  import { createAttachmentKey } from 'svelte/attachments';
4
4
  export class DatePickerBond extends PopoverBond {
5
- static CONTEXT_KEY = '@atoms/context/date-picker';
6
5
  #calendarBond;
7
6
  constructor(state) {
8
7
  super(state);
@@ -20,6 +19,7 @@ export class DatePickerBond extends PopoverBond {
20
19
  const isDisabled = this.state.props.disabled ?? false;
21
20
  const placeholder = this.state.props.placeholder ?? 'Select a date';
22
21
  return {
22
+ ...super.trigger(),
23
23
  id: `date-picker-input-${this.id}`,
24
24
  role: 'combobox',
25
25
  'aria-expanded': this.state.props.open ?? false,
@@ -29,30 +29,24 @@ export class DatePickerBond extends PopoverBond {
29
29
  placeholder,
30
30
  disabled: isDisabled,
31
31
  readonly: true,
32
- tabindex: isDisabled ? -1 : 0,
33
- [createAttachmentKey()]: (node) => {
34
- this.elements.trigger = node;
35
- }
32
+ tabindex: isDisabled ? -1 : 0
36
33
  };
37
34
  }
38
35
  content() {
39
36
  return {
37
+ ...super.content(),
40
38
  id: `date-picker-calendar-${this.id}`,
41
39
  role: 'dialog',
42
- 'aria-label': 'Choose date',
43
- [createAttachmentKey()]: (node) => {
44
- this.elements.content = node;
45
- }
40
+ 'aria-label': 'Choose date'
46
41
  };
47
42
  }
48
- clearButton(props = {}) {
43
+ clearButton() {
49
44
  const hasValue = this.state.hasValue;
50
45
  return {
51
46
  id: `date-picker-clear-${this.id}`,
52
47
  type: 'button',
53
48
  'aria-label': 'Clear date',
54
49
  tabindex: hasValue ? 0 : -1,
55
- ...props,
56
50
  onclick: (ev) => {
57
51
  ev.preventDefault();
58
52
  ev.stopPropagation();
@@ -52,11 +52,11 @@
52
52
  {...calendarProps}
53
53
  >
54
54
  <HtmlAtom base={Header} class="col-span-full" />
55
- <HtmlAtom base={Weekdays} />
55
+ <HtmlAtom base={Weekdays} class="border-0" />
56
56
 
57
57
  <HtmlAtom base={Body}>
58
58
  {#snippet children({ day }: { day: CalendarDayType })}
59
- <HtmlAtom base={Day} {day} class="flex items-center justify-center">
59
+ <HtmlAtom base={Day} {day} class="flex items-center justify-center border-0">
60
60
  <span class="value">{day.dayOfMonth}</span>
61
61
  </HtmlAtom>
62
62
  {/snippet}
@@ -1,95 +1,95 @@
1
- <script lang="ts">
2
- import { startOfDay } from 'date-fns';
3
- import { defineProperty, defineState } from '../../utils';
4
- import { Root } from '../popover/atoms';
5
- import type { CalendarRange } from '../calendar/types';
6
- import { DatePickerBond, DatePickerBondState, type DatePickerBondProps } from './bond.svelte';
7
- import type { DatePickerRootProps } from './types';
8
-
9
- let {
10
- open = $bindable(false),
11
- value = $bindable(undefined),
12
- range = $bindable([undefined, undefined]),
13
- pivote = $bindable(new Date()),
14
- start = $bindable(startOfDay(new Date())),
15
- end = $bindable(undefined),
16
- min = undefined,
17
- max = undefined,
18
- type = 'single',
19
- offset = 1,
20
- factory = _factory,
21
- children,
22
- ...restProps
23
- }: DatePickerRootProps = $props();
24
-
25
- const seed = {};
26
-
27
- const bondProps = defineState<DatePickerBondProps>(
28
- [
29
- defineProperty(
30
- 'open',
31
- () => open,
32
- (v) => {
33
- open = v;
34
- }
35
- ),
36
- defineProperty(
37
- 'range',
38
- () => range,
39
- (v: CalendarRange) => {
40
- range = v;
41
- value = v[0];
42
- }
43
- ),
44
- defineProperty(
45
- 'value',
46
- () => range?.[0],
47
- (v) => {
48
- range[0] = v;
49
- }
50
- ),
51
- defineProperty(
52
- 'pivote',
53
- () => pivote,
54
- (v: Date) => (pivote = v)
55
- ),
56
- defineProperty(
57
- 'start',
58
- () => range[0],
59
- (v: Date) => {
60
- range[0] = v;
61
- }
62
- ),
63
- defineProperty(
64
- 'end',
65
- () => range[1],
66
- (v: Date | undefined) => {
67
- range[1] = v;
68
- }
69
- ),
70
- defineProperty(
71
- 'min',
72
- () => min,
73
- (v: Date | undefined) => (min = v)
74
- ),
75
- defineProperty(
76
- 'max',
77
- () => max,
78
- (v: Date | undefined) => (max = v)
79
- ),
80
- defineProperty('type', () => type ?? 'single')
81
- ],
82
- () => seed
83
- );
84
-
85
- const bond = factory().share();
86
-
87
- function _factory() {
88
- const bondState = new DatePickerBondState(() => bondProps);
89
- return new DatePickerBond(bondState);
90
- }
91
- </script>
92
-
93
- <Root bind:open extend={bondProps} {offset} {...restProps}>
94
- {@render children?.({ datePicker: bond })}
95
- </Root>
1
+ <script lang="ts">
2
+ import { startOfDay } from 'date-fns';
3
+ import { defineProperty, defineState } from '../../utils';
4
+ import { Root } from '../popover/atoms';
5
+ import type { CalendarRange } from '../calendar/types';
6
+ import { DatePickerBond, DatePickerBondState, type DatePickerBondProps } from './bond.svelte';
7
+ import type { DatePickerRootProps } from './types';
8
+
9
+ let {
10
+ open = $bindable(false),
11
+ value = $bindable(undefined),
12
+ range = $bindable([undefined, undefined]),
13
+ pivote = $bindable(new Date()),
14
+ start = $bindable(startOfDay(new Date())),
15
+ end = $bindable(undefined),
16
+ min = undefined,
17
+ max = undefined,
18
+ type = 'single',
19
+ offset = 1,
20
+ factory = _factory,
21
+ children,
22
+ ...restProps
23
+ }: DatePickerRootProps = $props();
24
+
25
+ const seed = {};
26
+
27
+ const bondProps = defineState<DatePickerBondProps>(
28
+ [
29
+ defineProperty(
30
+ 'open',
31
+ () => open,
32
+ (v) => {
33
+ open = v;
34
+ }
35
+ ),
36
+ defineProperty(
37
+ 'range',
38
+ () => range,
39
+ (v: CalendarRange) => {
40
+ range = v;
41
+ value = v[0];
42
+ }
43
+ ),
44
+ defineProperty(
45
+ 'value',
46
+ () => range?.[0],
47
+ (v) => {
48
+ range[0] = v;
49
+ }
50
+ ),
51
+ defineProperty(
52
+ 'pivote',
53
+ () => pivote,
54
+ (v: Date) => (pivote = v)
55
+ ),
56
+ defineProperty(
57
+ 'start',
58
+ () => range[0],
59
+ (v: Date) => {
60
+ range[0] = v;
61
+ }
62
+ ),
63
+ defineProperty(
64
+ 'end',
65
+ () => range[1],
66
+ (v: Date | undefined) => {
67
+ range[1] = v;
68
+ }
69
+ ),
70
+ defineProperty(
71
+ 'min',
72
+ () => min,
73
+ (v: Date | undefined) => (min = v)
74
+ ),
75
+ defineProperty(
76
+ 'max',
77
+ () => max,
78
+ (v: Date | undefined) => (max = v)
79
+ ),
80
+ defineProperty('type', () => type ?? 'single')
81
+ ],
82
+ () => seed
83
+ );
84
+
85
+ const bond = factory().share();
86
+
87
+ function _factory() {
88
+ const bondState = new DatePickerBondState(() => bondProps);
89
+ return new DatePickerBond(bondState);
90
+ }
91
+ </script>
92
+
93
+ <Root bind:open extend={bondProps} {offset} {...restProps}>
94
+ {@render children?.({ datePicker: bond })}
95
+ </Root>
@@ -1,35 +1,35 @@
1
- <script module>
2
- import { defineMeta } from '@storybook/addon-svelte-csf';
3
-
4
- const { Story } = defineMeta({
5
- title: 'Atoms/Date Picker'
6
- });
7
- </script>
8
-
9
- <script lang="ts">
10
- import { DatePicker as ADatePicker } from '.';
11
- import { Button } from '../button';
12
- import { addDays, subDays } from 'date-fns';
13
-
14
- let value: Date | undefined = $state(undefined);
15
-
16
- let min = $state(subDays(new Date(), 5));
17
- let max = $state(addDays(new Date(), 15));
18
- </script>
19
-
20
- <Story name="Date Picker">
21
- {#snippet children({ args })}
22
- <ADatePicker.Root bind:value {min} {max}>
23
- <ADatePicker.Trigger base={Button} class="w-sm gap-4">
24
- {#if value}
25
- <div>{value.toDateString()}</div>
26
- {:else}
27
- <div>Open Date Picker</div>
28
- {/if}
29
-
30
- <ADatePicker.Indicator class="ml-auto" />
31
- </ADatePicker.Trigger>
32
- <ADatePicker.Calendar />
33
- </ADatePicker.Root>
34
- {/snippet}
35
- </Story>
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+
4
+ const { Story } = defineMeta({
5
+ title: 'Atoms/Date Picker'
6
+ });
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { DatePicker as ADatePicker } from '.';
11
+ import { Button } from '../button';
12
+ import { addDays, subDays } from 'date-fns';
13
+
14
+ let value: Date | undefined = $state(undefined);
15
+
16
+ let min = $state(subDays(new Date(), 5));
17
+ let max = $state(addDays(new Date(), 15));
18
+ </script>
19
+
20
+ <Story name="Date Picker">
21
+ {#snippet children({ args })}
22
+ <ADatePicker.Root bind:value {min} {max}>
23
+ <ADatePicker.Trigger base={Button} class="w-sm gap-4">
24
+ {#if value}
25
+ <div>{value.toDateString()}</div>
26
+ {:else}
27
+ <div>Open Date Picker</div>
28
+ {/if}
29
+
30
+ <ADatePicker.Indicator class="ml-auto" />
31
+ </ADatePicker.Trigger>
32
+ <ADatePicker.Calendar />
33
+ </ADatePicker.Root>
34
+ {/snippet}
35
+ </Story>
@@ -16,26 +16,33 @@ export declare class DialogBond<State extends DialogBondState<DialogBondProps> =
16
16
  static CONTEXT_KEY: string;
17
17
  constructor(s: State);
18
18
  share(): this;
19
- root(props: Record<string, unknown>): {
19
+ root(): {
20
+ [x: symbol]: (node: HTMLDialogElement) => void;
20
21
  id: string;
21
22
  role: string;
22
23
  'aria-modal': boolean;
23
24
  'aria-labelledby': string;
24
25
  'aria-describedby': string;
25
- 'aria-opened': boolean;
26
- 'aria-disabled': boolean;
26
+ inert: string | undefined;
27
27
  'data-kind': string;
28
+ 'data-open': boolean;
29
+ onclick: (ev: MouseEvent) => void;
30
+ onkeydown: (ev: KeyboardEvent) => void;
28
31
  };
29
32
  content(props: Record<string, unknown>): {
30
33
  id: string;
34
+ role: string;
31
35
  'data-kind': string;
32
36
  };
33
37
  header(props: Record<string, unknown>): {
34
38
  id: string;
39
+ role: string;
35
40
  'data-kind': string;
36
41
  };
37
42
  title(props: Record<string, unknown>): {
38
43
  id: string;
44
+ role: string;
45
+ 'aria-level': number;
39
46
  'data-kind': string;
40
47
  };
41
48
  description(props: Record<string, unknown>): {
@@ -44,10 +51,13 @@ export declare class DialogBond<State extends DialogBondState<DialogBondProps> =
44
51
  };
45
52
  body(props: Record<string, unknown>): {
46
53
  id: string;
54
+ role: string;
55
+ 'aria-live': string;
47
56
  'data-kind': string;
48
57
  };
49
58
  footer(props: Record<string, unknown>): {
50
59
  id: string;
60
+ role: string;
51
61
  'data-kind': string;
52
62
  };
53
63
  static get(): DialogBond | undefined;
@@ -1,6 +1,6 @@
1
1
  import { createAttachmentKey } from 'svelte/attachments';
2
2
  import { getContext, setContext } from 'svelte';
3
- import { getElementId } from '../../utils/dom.svelte';
3
+ import { focusTrap, getElementId } from '../../utils/dom.svelte';
4
4
  import { Bond, BondState } from '../../shared/bond.svelte';
5
5
  const DIALOG_ELEMENTS_KIND = {
6
6
  root: 'dialog-root',
@@ -19,24 +19,63 @@ export class DialogBond extends Bond {
19
19
  share() {
20
20
  return DialogBond.set(this);
21
21
  }
22
- root(props) {
22
+ root() {
23
23
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.root);
24
24
  const titleId = getElementId(this.id, DIALOG_ELEMENTS_KIND.title);
25
25
  const descriptionId = getElementId(this.id, DIALOG_ELEMENTS_KIND.description);
26
- const idOpened = this.state.props.open ?? false;
26
+ const isOpen = this.state.props.open ?? false;
27
27
  const isDisabled = this.state.props.disabled ?? false;
28
+ // Focus trap handler
29
+ const focusManager = (ev) => {
30
+ focusTrap(ev);
31
+ };
32
+ let previousActiveElement = null;
28
33
  return {
29
34
  id,
30
35
  role: 'dialog',
31
36
  'aria-modal': true,
32
37
  'aria-labelledby': titleId,
33
38
  'aria-describedby': descriptionId,
34
- 'aria-opened': idOpened,
35
- 'aria-disabled': isDisabled,
39
+ inert: !isOpen ? '' : undefined,
36
40
  'data-kind': DIALOG_ELEMENTS_KIND.root,
37
- ...props,
41
+ 'data-open': isOpen,
42
+ onclick: (ev) => {
43
+ // Close on backdrop click (clicking outside content)
44
+ if (ev.target === ev.currentTarget && !isDisabled) {
45
+ this.state.close();
46
+ }
47
+ },
48
+ onkeydown: (ev) => {
49
+ // Close on Escape key
50
+ if (ev.key === 'Escape') {
51
+ ev.preventDefault();
52
+ this.state.close();
53
+ }
54
+ focusManager(ev);
55
+ },
38
56
  [createAttachmentKey()]: (node) => {
39
57
  this.elements.root = node;
58
+ if (this.state.props.open) {
59
+ // Store current focus
60
+ previousActiveElement = document.activeElement;
61
+ // Focus first focusable element or dialog itself
62
+ setTimeout(() => {
63
+ const firstFocusable = node.querySelector('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])');
64
+ if (firstFocusable) {
65
+ firstFocusable.focus();
66
+ }
67
+ else {
68
+ node.focus();
69
+ }
70
+ }, 0);
71
+ }
72
+ else {
73
+ console.log('restoring focus to', previousActiveElement);
74
+ // Restore focus to previous element
75
+ if (previousActiveElement instanceof HTMLElement) {
76
+ previousActiveElement.focus();
77
+ }
78
+ }
40
79
  }
41
80
  };
42
81
  }
@@ -44,6 +83,7 @@ export class DialogBond extends Bond {
44
83
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.content);
45
84
  return {
46
85
  id,
86
+ role: 'document',
47
87
  'data-kind': DIALOG_ELEMENTS_KIND.content,
48
88
  ...props,
49
89
  [createAttachmentKey()]: (node) => {
@@ -55,6 +95,7 @@ export class DialogBond extends Bond {
55
95
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.header);
56
96
  return {
57
97
  id,
98
+ role: 'banner',
58
99
  'data-kind': DIALOG_ELEMENTS_KIND.header,
59
100
  ...props,
60
101
  [createAttachmentKey()]: (node) => {
@@ -66,6 +107,8 @@ export class DialogBond extends Bond {
66
107
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.title);
67
108
  return {
68
109
  id,
110
+ role: 'heading',
111
+ 'aria-level': 2,
69
112
  'data-kind': DIALOG_ELEMENTS_KIND.title,
70
113
  ...props,
71
114
  [createAttachmentKey()]: (node) => {
@@ -88,6 +131,8 @@ export class DialogBond extends Bond {
88
131
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.body);
89
132
  return {
90
133
  id,
134
+ role: 'region',
135
+ 'aria-live': 'polite',
91
136
  'data-kind': DIALOG_ELEMENTS_KIND.body,
92
137
  ...props,
93
138
  [createAttachmentKey()]: (node) => {
@@ -99,6 +144,7 @@ export class DialogBond extends Bond {
99
144
  const id = getElementId(this.id, DIALOG_ELEMENTS_KIND.footer);
100
145
  return {
101
146
  id,
147
+ role: 'contentinfo',
102
148
  'data-kind': DIALOG_ELEMENTS_KIND.footer,
103
149
  ...props,
104
150
  [createAttachmentKey()]: (node) => {
@@ -1,9 +1,8 @@
1
1
  <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import { animate as motion } from 'motion';
3
- import { DURATION } from '../../shared';
4
2
  import { HtmlAtom, type Base } from '../atom';
5
3
  import { DialogBond } from './bond.svelte';
6
4
  import type { DialogContentProps } from './types';
5
+ import { animateDialogContent } from './motion.svelte';
7
6
 
8
7
  const bond = DialogBond.get();
9
8
 
@@ -12,7 +11,7 @@
12
11
  children = undefined,
13
12
  onmount = undefined,
14
13
  ondestroy = undefined,
15
- animate = _animate,
14
+ animate = animateDialogContent(),
16
15
  enter = undefined,
17
16
  exit = undefined,
18
17
  initial = undefined,
@@ -23,23 +22,6 @@
23
22
  ...bond?.content({}),
24
23
  ...restProps
25
24
  });
26
-
27
- const open = $derived(bond?.state?.props?.open ?? false);
28
-
29
- function _animate(node: HTMLElement) {
30
- if (open) {
31
- bond?.elements.root?.show?.();
32
- }
33
-
34
- motion(
35
- node,
36
- { scale: 0.9 + 0.1 * +open, opacity: +open },
37
- {
38
- duration: DURATION.normal / 1000,
39
- ease: 'anticipate'
40
- }
41
- );
42
- }
43
25
  </script>
44
26
 
45
27
  <HtmlAtom
@@ -1,11 +1,10 @@
1
1
  <script lang="ts" generics="E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import { animate as motion } from 'motion';
3
2
  import { Teleport, ActivePortal } from '../portal';
4
3
  import { defineProperty, defineState } from '../../utils';
5
4
  import type { Base } from '../atom';
6
- import { DURATION } from '../../shared';
7
5
  import { DialogBond, DialogBondState, type DialogBondProps } from './bond.svelte';
8
6
  import type { DialogProps } from './types';
7
+ import { animateDialogRoot } from './motion.svelte';
9
8
 
10
9
  let {
11
10
  class: klass = '',
@@ -16,7 +15,7 @@
16
15
  factory = _factory,
17
16
  onmount = undefined,
18
17
  ondestroy = undefined,
19
- animate = _animate,
18
+ animate = animateDialogRoot(),
20
19
  enter = undefined,
21
20
  exit = undefined,
22
21
  initial = undefined,
@@ -39,7 +38,7 @@
39
38
  const bond = _factory(bondProps).share();
40
39
 
41
40
  const rootProps = $derived({
42
- ...bond?.root({}),
41
+ ...bond?.root(),
43
42
  ...restProps
44
43
  });
45
44
 
@@ -48,24 +47,6 @@
48
47
  return new DialogBond(bondState);
49
48
  }
50
49
 
51
- function _animate(node: HTMLDialogElement) {
52
- motion(
53
- node,
54
- {
55
- opacity: +open
56
- },
57
- {
58
- duration: DURATION.normal / 1000,
59
- ease: 'anticipate',
60
- onComplete: () => {
61
- if (!open) {
62
- node?.close?.();
63
- }
64
- }
65
- }
66
- );
67
- }
68
-
69
50
  function onclickDialogElement(ev: MouseEvent) {
70
51
  if (bond?.elements?.content?.contains(ev.target)) {
71
52
  return;