@svelte-atoms/core 1.0.0-alpha.27 → 1.0.0-alpha.28

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 (163) hide show
  1. package/README.md +856 -645
  2. package/dist/components/accordion/accordion-root.svelte +61 -61
  3. package/dist/components/accordion/item/accordion-item-body.svelte +42 -42
  4. package/dist/components/accordion/item/accordion-item-header.svelte +50 -50
  5. package/dist/components/accordion/item/accordion-item-indicator.svelte +50 -50
  6. package/dist/components/accordion/item/accordion-item-root.svelte +65 -65
  7. package/dist/components/alert/alert-actions.svelte +2 -1
  8. package/dist/components/alert/alert-close-button.svelte +18 -20
  9. package/dist/components/alert/alert-content.svelte +2 -1
  10. package/dist/components/alert/alert-description.svelte +2 -1
  11. package/dist/components/alert/alert-icon.svelte +2 -1
  12. package/dist/components/alert/alert-root.svelte +3 -2
  13. package/dist/components/alert/alert-title.svelte +2 -1
  14. package/dist/components/alert/alert.stories.svelte +401 -40
  15. package/dist/components/alert/alert.stories.svelte.d.ts +2 -5
  16. package/dist/components/atom/html-atom.svelte +205 -201
  17. package/dist/components/atom/snippet-renderer.svelte +5 -0
  18. package/dist/components/atom/snippet-renderer.svelte.d.ts +5 -0
  19. package/dist/components/avatar/avatar.stories.svelte.d.ts +1 -1
  20. package/dist/components/badge/badge.stories.svelte.d.ts +1 -1
  21. package/dist/components/breadcrumb/breadcrumb.stories.svelte.d.ts +1 -1
  22. package/dist/components/button/button.stories.svelte +60 -57
  23. package/dist/components/calendar/atoms.d.ts +5 -0
  24. package/dist/components/calendar/atoms.js +5 -0
  25. package/dist/components/calendar/bond.svelte.d.ts +72 -0
  26. package/dist/components/calendar/bond.svelte.js +132 -0
  27. package/dist/components/calendar/calendar-body.svelte +107 -0
  28. package/dist/components/calendar/calendar-body.svelte.d.ts +8 -0
  29. package/dist/components/calendar/calendar-day.svelte +97 -0
  30. package/dist/components/calendar/calendar-day.svelte.d.ts +4 -0
  31. package/dist/components/calendar/calendar-header.svelte +33 -0
  32. package/dist/components/calendar/calendar-header.svelte.d.ts +7 -0
  33. package/dist/components/calendar/calendar-root.svelte +208 -0
  34. package/dist/components/calendar/calendar-root.svelte.d.ts +8 -0
  35. package/dist/components/calendar/calendar-week-day.svelte +34 -0
  36. package/dist/components/calendar/calendar-week-day.svelte.d.ts +9 -0
  37. package/dist/components/calendar/calendar.css +26 -0
  38. package/dist/components/calendar/calendar.stories.svelte +36 -0
  39. package/dist/components/calendar/calendar.stories.svelte.d.ts +6 -0
  40. package/dist/components/calendar/index.d.ts +4 -0
  41. package/dist/components/calendar/index.js +4 -0
  42. package/dist/components/calendar/runes.svelte.d.ts +3 -0
  43. package/dist/components/calendar/runes.svelte.js +25 -0
  44. package/dist/components/calendar/types.d.ts +62 -0
  45. package/dist/components/calendar/types.js +1 -0
  46. package/dist/components/card/card-body.svelte +39 -39
  47. package/dist/components/card/card-description.svelte +41 -41
  48. package/dist/components/card/card-footer.svelte +41 -41
  49. package/dist/components/card/card-header.svelte +41 -41
  50. package/dist/components/card/card-media.svelte +41 -41
  51. package/dist/components/card/card-root.svelte +91 -91
  52. package/dist/components/card/card-subtitle.svelte +41 -41
  53. package/dist/components/card/card-title.svelte +45 -45
  54. package/dist/components/collapsible/collapsible-body.svelte +39 -39
  55. package/dist/components/collapsible/collapsible-header.svelte +39 -39
  56. package/dist/components/collapsible/collapsible-indicator.svelte +50 -50
  57. package/dist/components/collapsible/collapsible-root.svelte +66 -66
  58. package/dist/components/combobox/combobox-root.svelte +65 -65
  59. package/dist/components/container/container.stories.svelte.d.ts +1 -1
  60. package/dist/components/contextmenu/contextmenu-trigger.svelte.d.ts +1 -1
  61. package/dist/components/datagrid/bond.svelte.d.ts +2 -2
  62. package/dist/components/datagrid/datagrid-body.svelte +37 -37
  63. package/dist/components/datagrid/datagrid-checkbox.svelte +101 -101
  64. package/dist/components/datagrid/datagrid-footer.svelte +34 -34
  65. package/dist/components/datagrid/datagrid-header.svelte +49 -49
  66. package/dist/components/datagrid/datagrid-root.svelte +59 -59
  67. package/dist/components/datagrid/td/datagrid-td.svelte +66 -66
  68. package/dist/components/datagrid/th/datagrid-th.svelte +106 -106
  69. package/dist/components/datagrid/tr/datagrid-tr.svelte +88 -88
  70. package/dist/components/date-picker/atoms.d.ts +7 -0
  71. package/dist/components/date-picker/atoms.js +7 -0
  72. package/dist/components/date-picker/bond.svelte.d.ts +67 -0
  73. package/dist/components/date-picker/bond.svelte.js +174 -0
  74. package/dist/components/date-picker/date-picker-calendar.svelte +42 -0
  75. package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +7 -0
  76. package/dist/components/date-picker/date-picker-header.svelte +105 -0
  77. package/dist/components/date-picker/date-picker-header.svelte.d.ts +7 -0
  78. package/dist/components/date-picker/date-picker-months.svelte +150 -0
  79. package/dist/components/date-picker/date-picker-months.svelte.d.ts +7 -0
  80. package/dist/components/date-picker/date-picker-root.svelte +94 -0
  81. package/dist/components/date-picker/date-picker-root.svelte.d.ts +17 -0
  82. package/dist/components/date-picker/date-picker-years.svelte +214 -0
  83. package/dist/components/date-picker/date-picker-years.svelte.d.ts +7 -0
  84. package/dist/components/date-picker/date-picker.stories.svelte +51 -0
  85. package/dist/components/date-picker/date-picker.stories.svelte.d.ts +3 -0
  86. package/dist/components/date-picker/index.d.ts +3 -0
  87. package/dist/components/date-picker/index.js +3 -0
  88. package/dist/components/date-picker/types.d.ts +1 -0
  89. package/dist/components/date-picker/types.js +1 -0
  90. package/dist/components/dialog/dialog-body.svelte +39 -39
  91. package/dist/components/dialog/dialog-close-button.svelte +58 -58
  92. package/dist/components/dialog/dialog-content.svelte +62 -62
  93. package/dist/components/dialog/dialog-description.svelte +40 -40
  94. package/dist/components/dialog/dialog-footer.svelte +39 -39
  95. package/dist/components/dialog/dialog-header.svelte +39 -39
  96. package/dist/components/dialog/dialog-root.svelte +110 -110
  97. package/dist/components/dialog/dialog-title.svelte +41 -41
  98. package/dist/components/drawer/drawer-backdrop.svelte +38 -38
  99. package/dist/components/drawer/drawer-body.svelte +42 -42
  100. package/dist/components/drawer/drawer-content.svelte +42 -42
  101. package/dist/components/drawer/drawer-description.svelte +44 -44
  102. package/dist/components/drawer/drawer-footer.svelte +41 -41
  103. package/dist/components/drawer/drawer-header.svelte +43 -43
  104. package/dist/components/drawer/drawer-root.svelte +93 -93
  105. package/dist/components/drawer/drawer-title.svelte +44 -44
  106. package/dist/components/dropdown/dropdown-query.svelte +54 -54
  107. package/dist/components/dropdown/dropdown-root.svelte +59 -59
  108. package/dist/components/dropdown/dropdown-trigger.svelte +41 -41
  109. package/dist/components/dropdown/dropdown-value.svelte +60 -60
  110. package/dist/components/element/html-element.svelte +85 -85
  111. package/dist/components/form/bond.svelte.d.ts +1 -1
  112. package/dist/components/form/field/field-control.svelte +48 -48
  113. package/dist/components/form/field/field-label.svelte +24 -24
  114. package/dist/components/form/field/field-root.svelte +59 -59
  115. package/dist/components/icon/icon.svelte +44 -44
  116. package/dist/components/image/image.stories.svelte.d.ts +1 -1
  117. package/dist/components/index.d.ts +3 -0
  118. package/dist/components/index.js +3 -0
  119. package/dist/components/input/input-control.svelte +103 -103
  120. package/dist/components/label/label.svelte +25 -25
  121. package/dist/components/popover/popover-arrow.svelte +111 -111
  122. package/dist/components/popover/popover-content.svelte +46 -7
  123. package/dist/components/popover/popover-root.svelte +48 -49
  124. package/dist/components/popover/popover.stories.svelte +52 -67
  125. package/dist/components/portal/portal-root.svelte +83 -83
  126. package/dist/components/portal/teleport.svelte +50 -50
  127. package/dist/components/qr-code/index.d.ts +1 -0
  128. package/dist/components/qr-code/index.js +1 -0
  129. package/dist/components/qr-code/qr-code.stories.svelte +24 -0
  130. package/dist/components/qr-code/qr-code.stories.svelte.d.ts +26 -0
  131. package/dist/components/qr-code/qr-code.svelte +25 -0
  132. package/dist/components/qr-code/qr-code.svelte.d.ts +6 -0
  133. package/dist/components/radio/radio.svelte +109 -109
  134. package/dist/components/radio/types.svelte.d.ts +1 -1
  135. package/dist/components/scrollable/scrollable-container.svelte +82 -82
  136. package/dist/components/scrollable/scrollable-content.svelte +41 -41
  137. package/dist/components/scrollable/scrollable-root.svelte +100 -100
  138. package/dist/components/scrollable/scrollable-thumb.svelte +75 -75
  139. package/dist/components/scrollable/scrollable-track.svelte +59 -59
  140. package/dist/components/scrollable/scrollable.stories.svelte.d.ts +1 -1
  141. package/dist/components/tabs/tab/tab-body.svelte +52 -52
  142. package/dist/components/tabs/tab/tab-description.svelte +41 -41
  143. package/dist/components/tabs/tab/tab-header.svelte +71 -71
  144. package/dist/components/tabs/tab/tab-root.svelte +86 -86
  145. package/dist/components/toast/toast-description.svelte +38 -38
  146. package/dist/components/toast/toast-root.svelte +61 -61
  147. package/dist/components/toast/toast-title.svelte +35 -35
  148. package/dist/components/tree/tree-body.svelte +39 -39
  149. package/dist/components/tree/tree-header.svelte +54 -54
  150. package/dist/components/tree/tree-indicator.svelte +40 -40
  151. package/dist/components/tree/tree-root.svelte +65 -65
  152. package/dist/components/virtual/virtual-root.svelte +239 -239
  153. package/dist/context/preset.svelte.d.ts +1 -1
  154. package/dist/icons/icon-arrow-down.svelte.d.ts +1 -1
  155. package/dist/icons/icon-checkmark.svelte.d.ts +1 -1
  156. package/dist/icons/icon-close.svelte.d.ts +1 -1
  157. package/dist/icons/icon-more-vert.svelte.d.ts +1 -1
  158. package/dist/runes/container.svelte.d.ts +2 -2
  159. package/dist/shared/bond.svelte.d.ts +1 -1
  160. package/dist/utils/state.d.ts +1 -1
  161. package/dist/utils/state.js +2 -1
  162. package/llm/variants.md +1261 -712
  163. package/package.json +464 -437
@@ -1,88 +1,88 @@
1
- <script lang="ts" generics="T, E extends HtmlElementTagName, B extends Base = Base">
2
- import { untrack } from 'svelte';
3
- import { nanoid } from 'nanoid';
4
- import { defineProperty, defineState } from '../../../utils';
5
- import { HtmlAtom, type Base } from '../../atom';
6
- import type { HtmlElementTagName } from '../../element';
7
- import { DataGridTrBond, DataGridTrBondState, type DataGridTrBondProps } from './bond.svelte';
8
- import type { DatagridTrProps } from '../types';
9
- import { getDatagridHeaderContext, type DatagridContext } from '../context';
10
-
11
- import './datagrid-tr.css';
12
-
13
- const context_header = getDatagridHeaderContext();
14
-
15
- let {
16
- class: klass = '',
17
- value = nanoid(),
18
- rows = 'auto',
19
- data = undefined,
20
- header = false,
21
- factory = _factory,
22
- children = undefined,
23
- onmount = undefined,
24
- ondestroy = undefined,
25
- animate = undefined,
26
- enter = undefined,
27
- exit = undefined,
28
- initial = undefined,
29
- onclick = undefined,
30
- ...restProps
31
- }: DatagridTrProps<T, E, B> = $props();
32
-
33
- const bondProps = defineState<DataGridTrBondProps>([
34
- defineProperty('data', () => data),
35
- defineProperty('value', () => value),
36
- defineProperty('header', () => header)
37
- ]);
38
- const bond = factory(bondProps).share();
39
-
40
- const isHeader = $derived(context_header?.derived?.data?.header ?? false);
41
- const isSelected = $derived(bond.state.isSelected);
42
-
43
- const unmount = untrack(() => {
44
- if (!isHeader) {
45
- return bond.mount();
46
- }
47
- });
48
-
49
- $effect(() => unmount);
50
-
51
- function _factory(props: typeof bondProps) {
52
- const datagridTrState = new DataGridTrBondState(() => props);
53
- return new DataGridTrBond(datagridTrState);
54
- }
55
-
56
- function onclick_(ev: Event) {
57
- onclick?.(ev, { tr: bond as unknown as DatagridContext<T> });
58
-
59
- if (!ev.defaultPrevented) {
60
- //
61
- }
62
- }
63
- </script>
64
-
65
- <HtmlAtom
66
- {bond}
67
- preset="datagrid.tr"
68
- class={[
69
- 'datagrid-tr border-border items-center border-b bg-transparent',
70
- !isHeader &&
71
- 'hover:bg-foreground/2 active:bg-foreground/4 transition-colors duration-100 last:border-b-0',
72
- isHeader && 'header-tr',
73
- isSelected && 'bg-primary/2 hover:bg-primary/4 active:bg-primary/6',
74
- '$preset',
75
- klass
76
- ]}
77
- style="--rows:{rows}"
78
- enter={enter?.bind(bond.state)}
79
- exit={exit?.bind(bond.state)}
80
- initial={initial?.bind(bond.state)}
81
- animate={animate?.bind(bond.state)}
82
- onmount={onmount?.bind(bond.state)}
83
- ondestroy={ondestroy?.bind(bond.state)}
84
- onclick={onclick_}
85
- {...bond.root(restProps)}
86
- >
87
- {@render children?.({ tr: bond as unknown as DatagridContext<T> })}
88
- </HtmlAtom>
1
+ <script lang="ts" generics="T, E extends HtmlElementTagName, B extends Base = Base">
2
+ import { untrack } from 'svelte';
3
+ import { nanoid } from 'nanoid';
4
+ import { defineProperty, defineState } from '../../../utils';
5
+ import { HtmlAtom, type Base } from '../../atom';
6
+ import type { HtmlElementTagName } from '../../element';
7
+ import { DataGridTrBond, DataGridTrBondState, type DataGridTrBondProps } from './bond.svelte';
8
+ import type { DatagridTrProps } from '../types';
9
+ import { getDatagridHeaderContext, type DatagridContext } from '../context';
10
+
11
+ import './datagrid-tr.css';
12
+
13
+ const context_header = getDatagridHeaderContext();
14
+
15
+ let {
16
+ class: klass = '',
17
+ value = nanoid(),
18
+ rows = 'auto',
19
+ data = undefined,
20
+ header = false,
21
+ factory = _factory,
22
+ children = undefined,
23
+ onmount = undefined,
24
+ ondestroy = undefined,
25
+ animate = undefined,
26
+ enter = undefined,
27
+ exit = undefined,
28
+ initial = undefined,
29
+ onclick = undefined,
30
+ ...restProps
31
+ }: DatagridTrProps<T, E, B> = $props();
32
+
33
+ const bondProps = defineState<DataGridTrBondProps>([
34
+ defineProperty('data', () => data),
35
+ defineProperty('value', () => value),
36
+ defineProperty('header', () => header)
37
+ ]);
38
+ const bond = factory(bondProps).share();
39
+
40
+ const isHeader = $derived(context_header?.derived?.data?.header ?? false);
41
+ const isSelected = $derived(bond.state.isSelected);
42
+
43
+ const unmount = untrack(() => {
44
+ if (!isHeader) {
45
+ return bond.mount();
46
+ }
47
+ });
48
+
49
+ $effect(() => unmount);
50
+
51
+ function _factory(props: typeof bondProps) {
52
+ const datagridTrState = new DataGridTrBondState(() => props);
53
+ return new DataGridTrBond(datagridTrState);
54
+ }
55
+
56
+ function onclick_(ev: Event) {
57
+ onclick?.(ev, { tr: bond as unknown as DatagridContext<T> });
58
+
59
+ if (!ev.defaultPrevented) {
60
+ //
61
+ }
62
+ }
63
+ </script>
64
+
65
+ <HtmlAtom
66
+ {bond}
67
+ preset="datagrid.tr"
68
+ class={[
69
+ 'datagrid-tr border-border items-center border-b bg-transparent',
70
+ !isHeader &&
71
+ 'hover:bg-foreground/2 active:bg-foreground/4 transition-colors duration-100 last:border-b-0',
72
+ isHeader && 'header-tr',
73
+ isSelected && 'bg-primary/2 hover:bg-primary/4 active:bg-primary/6',
74
+ '$preset',
75
+ klass
76
+ ]}
77
+ style="--rows:{rows}"
78
+ enter={enter?.bind(bond.state)}
79
+ exit={exit?.bind(bond.state)}
80
+ initial={initial?.bind(bond.state)}
81
+ animate={animate?.bind(bond.state)}
82
+ onmount={onmount?.bind(bond.state)}
83
+ ondestroy={ondestroy?.bind(bond.state)}
84
+ onclick={onclick_}
85
+ {...bond.root(restProps)}
86
+ >
87
+ {@render children?.({ tr: bond as unknown as DatagridContext<T> })}
88
+ </HtmlAtom>
@@ -0,0 +1,7 @@
1
+ export { Arrow, Indicator, Trigger } from '../popover/atoms';
2
+ export { Body, Day, Header as WeekDays, WeekDay } from '../calendar/atoms';
3
+ export { default as Root } from './date-picker-root.svelte';
4
+ export { default as Calendar } from './date-picker-calendar.svelte';
5
+ export { default as Header } from './date-picker-header.svelte';
6
+ export { default as Years } from './date-picker-years.svelte';
7
+ export { default as Months } from './date-picker-months.svelte';
@@ -0,0 +1,7 @@
1
+ export { Arrow, Indicator, Trigger } from '../popover/atoms';
2
+ export { Body, Day, Header as WeekDays, WeekDay } from '../calendar/atoms';
3
+ export { default as Root } from './date-picker-root.svelte';
4
+ export { default as Calendar } from './date-picker-calendar.svelte';
5
+ export { default as Header } from './date-picker-header.svelte';
6
+ export { default as Years } from './date-picker-years.svelte';
7
+ export { default as Months } from './date-picker-months.svelte';
@@ -0,0 +1,67 @@
1
+ import { PopoverBond, PopoverState, type PopoverDomElements, type PopoverStateProps } from '../popover/bond.svelte';
2
+ import type { CalendarBond, CalendarBondProps } from '../calendar/bond.svelte';
3
+ export type DatePickerBondProps = PopoverStateProps & CalendarBondProps & {
4
+ format?: string;
5
+ placeholder?: string;
6
+ };
7
+ export type DatePickerBondElements = PopoverDomElements & {
8
+ trigger: HTMLInputElement;
9
+ root: HTMLElement;
10
+ content: HTMLElement;
11
+ clearButton: HTMLElement;
12
+ };
13
+ export declare class DatePickerBond<Props extends DatePickerBondProps = DatePickerBondProps, State extends DatePickerBondState<Props> = DatePickerBondState<Props>> extends PopoverBond<Props, State, DatePickerBondElements> {
14
+ #private;
15
+ static CONTEXT_KEY: string;
16
+ constructor(state: State);
17
+ get calendar(): CalendarBond<CalendarBondProps, import("..").CalendarBondState<CalendarBondProps>> | undefined;
18
+ setCalendar(calendar: CalendarBond): void;
19
+ share(): this;
20
+ trigger(): {
21
+ [x: symbol]: (node: HTMLInputElement) => void;
22
+ id: string;
23
+ role: string;
24
+ 'aria-expanded': boolean;
25
+ 'aria-controls': string;
26
+ 'aria-label': string;
27
+ 'aria-disabled': boolean;
28
+ placeholder: string;
29
+ disabled: boolean;
30
+ readonly: boolean;
31
+ tabindex: number;
32
+ };
33
+ content(): {
34
+ [x: symbol]: (node: HTMLElement) => void;
35
+ id: string;
36
+ role: string;
37
+ 'aria-label': string;
38
+ };
39
+ clearButton(props?: Record<string, unknown>): {
40
+ onclick: (ev: Event) => void;
41
+ id: string;
42
+ type: string;
43
+ 'aria-label': string;
44
+ tabindex: number;
45
+ };
46
+ static get(): DatePickerBond;
47
+ static set(bond: DatePickerBond): DatePickerBond;
48
+ }
49
+ export declare class DatePickerBondState<Props extends DatePickerBondProps> extends PopoverState<Props> {
50
+ #private;
51
+ constructor(props: () => Props);
52
+ get formattedValue(): string;
53
+ get hasValue(): boolean;
54
+ get isYearsPickerOpen(): boolean;
55
+ get isMonthsPickerOpen(): boolean;
56
+ selectDate(date: Date): void;
57
+ selectStart(date: Date): void;
58
+ selectEnd(date: Date): void;
59
+ clear(): void;
60
+ private formatDate;
61
+ openYearsPicker(): void;
62
+ closeYearsPicker(): void;
63
+ toggleYearsPicker(): void;
64
+ openMonthsPicker(): void;
65
+ closeMonthsPicker(): void;
66
+ toggleMonthsPicker(): void;
67
+ }
@@ -0,0 +1,174 @@
1
+ import { PopoverBond, PopoverState } from '../popover/bond.svelte';
2
+ import { getContext, setContext } from 'svelte';
3
+ import { createAttachmentKey } from 'svelte/attachments';
4
+ export class DatePickerBond extends PopoverBond {
5
+ static CONTEXT_KEY = '@atoms/context/date-picker';
6
+ #calendarBond;
7
+ constructor(state) {
8
+ super(state);
9
+ }
10
+ get calendar() {
11
+ return this.#calendarBond;
12
+ }
13
+ setCalendar(calendar) {
14
+ this.#calendarBond = calendar;
15
+ }
16
+ share() {
17
+ return DatePickerBond.set(this);
18
+ }
19
+ trigger() {
20
+ const isDisabled = this.state.props.disabled ?? false;
21
+ const placeholder = this.state.props.placeholder ?? 'Select a date';
22
+ return {
23
+ id: `date-picker-input-${this.id}`,
24
+ role: 'combobox',
25
+ 'aria-expanded': this.state.props.open ?? false,
26
+ 'aria-controls': `date-picker-calendar-${this.id}`,
27
+ 'aria-label': 'Date picker',
28
+ 'aria-disabled': isDisabled,
29
+ placeholder,
30
+ disabled: isDisabled,
31
+ readonly: true,
32
+ tabindex: isDisabled ? -1 : 0,
33
+ [createAttachmentKey()]: (node) => {
34
+ this.elements.trigger = node;
35
+ }
36
+ };
37
+ }
38
+ content() {
39
+ return {
40
+ id: `date-picker-calendar-${this.id}`,
41
+ role: 'dialog',
42
+ 'aria-label': 'Choose date',
43
+ [createAttachmentKey()]: (node) => {
44
+ this.elements.content = node;
45
+ }
46
+ };
47
+ }
48
+ clearButton(props = {}) {
49
+ const hasValue = this.state.hasValue;
50
+ return {
51
+ id: `date-picker-clear-${this.id}`,
52
+ type: 'button',
53
+ 'aria-label': 'Clear date',
54
+ tabindex: hasValue ? 0 : -1,
55
+ ...props,
56
+ onclick: (ev) => {
57
+ ev.preventDefault();
58
+ ev.stopPropagation();
59
+ this.state.clear();
60
+ },
61
+ [createAttachmentKey()]: (node) => {
62
+ this.elements.clearButton = node;
63
+ }
64
+ };
65
+ }
66
+ static get() {
67
+ return getContext(this.CONTEXT_KEY);
68
+ }
69
+ static set(bond) {
70
+ return setContext(this.CONTEXT_KEY, bond);
71
+ }
72
+ }
73
+ export class DatePickerBondState extends PopoverState {
74
+ #isYearsPickerOpen = $state(false);
75
+ #isMonthsPickerOpen = $state(false);
76
+ constructor(props) {
77
+ super(props);
78
+ }
79
+ get formattedValue() {
80
+ if (this.props.range) {
81
+ if (!this.props.start)
82
+ return '';
83
+ if (!this.props.end)
84
+ return this.formatDate(this.props.start);
85
+ return `${this.formatDate(this.props.start)} - ${this.formatDate(this.props.end)}`;
86
+ }
87
+ return this.props.value ? this.formatDate(this.props.value) : '';
88
+ }
89
+ get hasValue() {
90
+ if (this.props.range) {
91
+ return !!(this.props.start || this.props.end);
92
+ }
93
+ return !!this.props.value;
94
+ }
95
+ get isYearsPickerOpen() {
96
+ return this.#isYearsPickerOpen;
97
+ }
98
+ get isMonthsPickerOpen() {
99
+ return this.#isMonthsPickerOpen;
100
+ }
101
+ selectDate(date) {
102
+ if (this.props.range) {
103
+ if (!this.props.start) {
104
+ this.props.start = date;
105
+ }
106
+ else if (!this.props.end) {
107
+ this.props.end = date;
108
+ this.close(); // Close after selecting range
109
+ }
110
+ else {
111
+ this.props.start = date;
112
+ this.props.end = undefined;
113
+ }
114
+ }
115
+ else {
116
+ this.props.value = date;
117
+ this.close(); // Close after selecting single date
118
+ }
119
+ }
120
+ selectStart(date) {
121
+ this.props.start = date;
122
+ }
123
+ selectEnd(date) {
124
+ this.props.end = date;
125
+ this.close();
126
+ }
127
+ clear() {
128
+ this.props.value = undefined;
129
+ this.props.start = undefined;
130
+ this.props.end = undefined;
131
+ }
132
+ formatDate(date) {
133
+ const format = this.props.format ?? 'MM/dd/yyyy';
134
+ // Basic formatting - can be enhanced with date-fns format later
135
+ if (format === 'MM/dd/yyyy') {
136
+ const month = String(date.getMonth() + 1).padStart(2, '0');
137
+ const day = String(date.getDate()).padStart(2, '0');
138
+ const year = date.getFullYear();
139
+ return `${month}/${day}/${year}`;
140
+ }
141
+ if (format === 'dd/MM/yyyy') {
142
+ const month = String(date.getMonth() + 1).padStart(2, '0');
143
+ const day = String(date.getDate()).padStart(2, '0');
144
+ const year = date.getFullYear();
145
+ return `${day}/${month}/${year}`;
146
+ }
147
+ if (format === 'yyyy-MM-dd') {
148
+ const month = String(date.getMonth() + 1).padStart(2, '0');
149
+ const day = String(date.getDate()).padStart(2, '0');
150
+ const year = date.getFullYear();
151
+ return `${year}-${month}-${day}`;
152
+ }
153
+ // Default fallback
154
+ return date.toLocaleDateString();
155
+ }
156
+ openYearsPicker() {
157
+ this.#isYearsPickerOpen = true;
158
+ }
159
+ closeYearsPicker() {
160
+ this.#isYearsPickerOpen = false;
161
+ }
162
+ toggleYearsPicker() {
163
+ this.#isYearsPickerOpen = !this.#isYearsPickerOpen;
164
+ }
165
+ openMonthsPicker() {
166
+ this.#isMonthsPickerOpen = true;
167
+ }
168
+ closeMonthsPicker() {
169
+ this.#isMonthsPickerOpen = false;
170
+ }
171
+ toggleMonthsPicker() {
172
+ this.#isMonthsPickerOpen = !this.#isMonthsPickerOpen;
173
+ }
174
+ }
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import { Content } from '../popover/atoms';
3
+ import { Root } from '../calendar/atoms';
4
+ import { DatePickerBond } from './bond.svelte';
5
+
6
+ const datePickerBond = DatePickerBond.get();
7
+ const datePickerBondProps = $derived(datePickerBond?.state.props);
8
+
9
+ let {
10
+ class: klass = '',
11
+ preset = 'datepicker.calendar',
12
+ children: datePickerChildren,
13
+ ...restProps
14
+ } = $props();
15
+
16
+ const calendarProps = $derived({
17
+ ...datePickerBond?.content(),
18
+ ...datePickerBondProps,
19
+ ...restProps
20
+ });
21
+
22
+ function handleChange(ev: CustomEvent, { range, pivote }) {
23
+ if (!datePickerBond) return;
24
+
25
+ datePickerBond.state.props.range = range;
26
+ datePickerBond.state.props.pivote = pivote;
27
+ }
28
+ </script>
29
+
30
+ <Content
31
+ class={['relative overflow-hidden p-0', klass]}
32
+ base={Root}
33
+ onchange={handleChange}
34
+ {preset}
35
+ {...calendarProps}
36
+ >
37
+ {#snippet children({ calendar })}
38
+ {@render datePickerChildren?.({
39
+ datePicker: datePickerBond
40
+ })}
41
+ {/snippet}
42
+ </Content>
@@ -0,0 +1,7 @@
1
+ declare const DatePickerCalendar: import("svelte").Component<{
2
+ class?: string;
3
+ preset?: string;
4
+ children: any;
5
+ } & Record<string, any>, {}, "">;
6
+ type DatePickerCalendar = ReturnType<typeof DatePickerCalendar>;
7
+ export default DatePickerCalendar;
@@ -0,0 +1,105 @@
1
+ <script lang="ts">
2
+ import { HtmlAtom } from '../atom';
3
+ import { DatePickerBond } from './bond.svelte';
4
+ import { CalendarBond } from '../calendar/bond.svelte';
5
+ import { Icon } from '../icon';
6
+
7
+ const datePickerBond = DatePickerBond.get();
8
+ const calendarBond = CalendarBond.get();
9
+
10
+ let { class: klass = '', preset = 'datepicker.header', children, ...restProps } = $props();
11
+
12
+ const calendarBondProps = $derived(datePickerBond?.state?.props);
13
+
14
+ const pivote = $derived(calendarBondProps?.pivote ?? new Date());
15
+
16
+ // Format month and year
17
+ const monthName = $derived(pivote.toLocaleDateString('en-US', { month: 'long' }));
18
+ const year = $derived(pivote.getFullYear());
19
+
20
+ function handlePreviousMonth() {
21
+ calendarBond?.state?.previousMonth();
22
+ }
23
+
24
+ function handleNextMonth() {
25
+ calendarBond?.state?.nextMonth();
26
+ }
27
+
28
+ function handleMonthPicker() {
29
+ if (!datePickerBond) return;
30
+ datePickerBond.state.openMonthsPicker();
31
+ }
32
+ </script>
33
+
34
+ <HtmlAtom
35
+ as="nav"
36
+ class={['border-border flex items-center justify-between gap-2 border-b p-2', '$preset', klass]}
37
+ {preset}
38
+ {...restProps}
39
+ >
40
+ {#if children}
41
+ {@render children?.({
42
+ datePicker: datePickerBond,
43
+ calendar: calendarBond,
44
+ monthName,
45
+ year,
46
+ onPrevious: handlePreviousMonth,
47
+ onNext: handleNextMonth
48
+ })}
49
+ {:else}
50
+ <!-- Previous Month Button -->
51
+ <button
52
+ type="button"
53
+ class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
54
+ onclick={handlePreviousMonth}
55
+ aria-label="Previous month"
56
+ >
57
+ <Icon class="size-5">
58
+ <svg
59
+ xmlns="http://www.w3.org/2000/svg"
60
+ class="size-full"
61
+ viewBox="0 0 24 24"
62
+ fill="none"
63
+ stroke="currentColor"
64
+ stroke-width="2"
65
+ stroke-linecap="round"
66
+ stroke-linejoin="round"
67
+ >
68
+ <path d="M15 18l-6-6 6-6" />
69
+ </svg>
70
+ </Icon>
71
+ </button>
72
+
73
+ <!-- Month and Year Display -->
74
+ <button
75
+ class="text-foreground h-full flex-1 cursor-pointer text-center text-sm font-semibold"
76
+ onclick={handleMonthPicker}
77
+ >
78
+ {monthName}
79
+ {year}
80
+ </button>
81
+
82
+ <!-- Next Month Button -->
83
+ <button
84
+ type="button"
85
+ class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
86
+ onclick={handleNextMonth}
87
+ aria-label="Next month"
88
+ >
89
+ <Icon class="size-5">
90
+ <svg
91
+ xmlns="http://www.w3.org/2000/svg"
92
+ class="size-full"
93
+ viewBox="0 0 24 24"
94
+ fill="none"
95
+ stroke="currentColor"
96
+ stroke-width="2"
97
+ stroke-linecap="round"
98
+ stroke-linejoin="round"
99
+ >
100
+ <path d="M9 18l6-6-6-6" />
101
+ </svg>
102
+ </Icon>
103
+ </button>
104
+ {/if}
105
+ </HtmlAtom>
@@ -0,0 +1,7 @@
1
+ declare const DatePickerHeader: import("svelte").Component<{
2
+ class?: string;
3
+ preset?: string;
4
+ children: any;
5
+ } & Record<string, any>, {}, "">;
6
+ type DatePickerHeader = ReturnType<typeof DatePickerHeader>;
7
+ export default DatePickerHeader;