@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.
- package/README.md +856 -645
- package/dist/components/accordion/accordion-root.svelte +61 -61
- package/dist/components/accordion/item/accordion-item-body.svelte +42 -42
- package/dist/components/accordion/item/accordion-item-header.svelte +50 -50
- package/dist/components/accordion/item/accordion-item-indicator.svelte +50 -50
- package/dist/components/accordion/item/accordion-item-root.svelte +65 -65
- package/dist/components/alert/alert-actions.svelte +2 -1
- package/dist/components/alert/alert-close-button.svelte +18 -20
- package/dist/components/alert/alert-content.svelte +2 -1
- package/dist/components/alert/alert-description.svelte +2 -1
- package/dist/components/alert/alert-icon.svelte +2 -1
- package/dist/components/alert/alert-root.svelte +3 -2
- package/dist/components/alert/alert-title.svelte +2 -1
- package/dist/components/alert/alert.stories.svelte +401 -40
- package/dist/components/alert/alert.stories.svelte.d.ts +2 -5
- package/dist/components/atom/html-atom.svelte +205 -201
- package/dist/components/atom/snippet-renderer.svelte +5 -0
- package/dist/components/atom/snippet-renderer.svelte.d.ts +5 -0
- package/dist/components/avatar/avatar.stories.svelte.d.ts +1 -1
- package/dist/components/badge/badge.stories.svelte.d.ts +1 -1
- package/dist/components/breadcrumb/breadcrumb.stories.svelte.d.ts +1 -1
- package/dist/components/button/button.stories.svelte +60 -57
- package/dist/components/calendar/atoms.d.ts +5 -0
- package/dist/components/calendar/atoms.js +5 -0
- package/dist/components/calendar/bond.svelte.d.ts +72 -0
- package/dist/components/calendar/bond.svelte.js +132 -0
- package/dist/components/calendar/calendar-body.svelte +107 -0
- package/dist/components/calendar/calendar-body.svelte.d.ts +8 -0
- package/dist/components/calendar/calendar-day.svelte +97 -0
- package/dist/components/calendar/calendar-day.svelte.d.ts +4 -0
- package/dist/components/calendar/calendar-header.svelte +33 -0
- package/dist/components/calendar/calendar-header.svelte.d.ts +7 -0
- package/dist/components/calendar/calendar-root.svelte +208 -0
- package/dist/components/calendar/calendar-root.svelte.d.ts +8 -0
- package/dist/components/calendar/calendar-week-day.svelte +34 -0
- package/dist/components/calendar/calendar-week-day.svelte.d.ts +9 -0
- package/dist/components/calendar/calendar.css +26 -0
- package/dist/components/calendar/calendar.stories.svelte +36 -0
- package/dist/components/calendar/calendar.stories.svelte.d.ts +6 -0
- package/dist/components/calendar/index.d.ts +4 -0
- package/dist/components/calendar/index.js +4 -0
- package/dist/components/calendar/runes.svelte.d.ts +3 -0
- package/dist/components/calendar/runes.svelte.js +25 -0
- package/dist/components/calendar/types.d.ts +62 -0
- package/dist/components/calendar/types.js +1 -0
- package/dist/components/card/card-body.svelte +39 -39
- package/dist/components/card/card-description.svelte +41 -41
- package/dist/components/card/card-footer.svelte +41 -41
- package/dist/components/card/card-header.svelte +41 -41
- package/dist/components/card/card-media.svelte +41 -41
- package/dist/components/card/card-root.svelte +91 -91
- package/dist/components/card/card-subtitle.svelte +41 -41
- package/dist/components/card/card-title.svelte +45 -45
- package/dist/components/collapsible/collapsible-body.svelte +39 -39
- package/dist/components/collapsible/collapsible-header.svelte +39 -39
- package/dist/components/collapsible/collapsible-indicator.svelte +50 -50
- package/dist/components/collapsible/collapsible-root.svelte +66 -66
- package/dist/components/combobox/combobox-root.svelte +65 -65
- package/dist/components/container/container.stories.svelte.d.ts +1 -1
- package/dist/components/contextmenu/contextmenu-trigger.svelte.d.ts +1 -1
- package/dist/components/datagrid/bond.svelte.d.ts +2 -2
- package/dist/components/datagrid/datagrid-body.svelte +37 -37
- package/dist/components/datagrid/datagrid-checkbox.svelte +101 -101
- package/dist/components/datagrid/datagrid-footer.svelte +34 -34
- package/dist/components/datagrid/datagrid-header.svelte +49 -49
- package/dist/components/datagrid/datagrid-root.svelte +59 -59
- package/dist/components/datagrid/td/datagrid-td.svelte +66 -66
- package/dist/components/datagrid/th/datagrid-th.svelte +106 -106
- package/dist/components/datagrid/tr/datagrid-tr.svelte +88 -88
- package/dist/components/date-picker/atoms.d.ts +7 -0
- package/dist/components/date-picker/atoms.js +7 -0
- package/dist/components/date-picker/bond.svelte.d.ts +67 -0
- package/dist/components/date-picker/bond.svelte.js +174 -0
- package/dist/components/date-picker/date-picker-calendar.svelte +42 -0
- package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +7 -0
- package/dist/components/date-picker/date-picker-header.svelte +105 -0
- package/dist/components/date-picker/date-picker-header.svelte.d.ts +7 -0
- package/dist/components/date-picker/date-picker-months.svelte +150 -0
- package/dist/components/date-picker/date-picker-months.svelte.d.ts +7 -0
- package/dist/components/date-picker/date-picker-root.svelte +94 -0
- package/dist/components/date-picker/date-picker-root.svelte.d.ts +17 -0
- package/dist/components/date-picker/date-picker-years.svelte +214 -0
- package/dist/components/date-picker/date-picker-years.svelte.d.ts +7 -0
- package/dist/components/date-picker/date-picker.stories.svelte +51 -0
- package/dist/components/date-picker/date-picker.stories.svelte.d.ts +3 -0
- package/dist/components/date-picker/index.d.ts +3 -0
- package/dist/components/date-picker/index.js +3 -0
- package/dist/components/date-picker/types.d.ts +1 -0
- package/dist/components/date-picker/types.js +1 -0
- package/dist/components/dialog/dialog-body.svelte +39 -39
- package/dist/components/dialog/dialog-close-button.svelte +58 -58
- package/dist/components/dialog/dialog-content.svelte +62 -62
- package/dist/components/dialog/dialog-description.svelte +40 -40
- package/dist/components/dialog/dialog-footer.svelte +39 -39
- package/dist/components/dialog/dialog-header.svelte +39 -39
- package/dist/components/dialog/dialog-root.svelte +110 -110
- package/dist/components/dialog/dialog-title.svelte +41 -41
- package/dist/components/drawer/drawer-backdrop.svelte +38 -38
- package/dist/components/drawer/drawer-body.svelte +42 -42
- package/dist/components/drawer/drawer-content.svelte +42 -42
- package/dist/components/drawer/drawer-description.svelte +44 -44
- package/dist/components/drawer/drawer-footer.svelte +41 -41
- package/dist/components/drawer/drawer-header.svelte +43 -43
- package/dist/components/drawer/drawer-root.svelte +93 -93
- package/dist/components/drawer/drawer-title.svelte +44 -44
- package/dist/components/dropdown/dropdown-query.svelte +54 -54
- package/dist/components/dropdown/dropdown-root.svelte +59 -59
- package/dist/components/dropdown/dropdown-trigger.svelte +41 -41
- package/dist/components/dropdown/dropdown-value.svelte +60 -60
- package/dist/components/element/html-element.svelte +85 -85
- package/dist/components/form/bond.svelte.d.ts +1 -1
- package/dist/components/form/field/field-control.svelte +48 -48
- package/dist/components/form/field/field-label.svelte +24 -24
- package/dist/components/form/field/field-root.svelte +59 -59
- package/dist/components/icon/icon.svelte +44 -44
- package/dist/components/image/image.stories.svelte.d.ts +1 -1
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +3 -0
- package/dist/components/input/input-control.svelte +103 -103
- package/dist/components/label/label.svelte +25 -25
- package/dist/components/popover/popover-arrow.svelte +111 -111
- package/dist/components/popover/popover-content.svelte +46 -7
- package/dist/components/popover/popover-root.svelte +48 -49
- package/dist/components/popover/popover.stories.svelte +52 -67
- package/dist/components/portal/portal-root.svelte +83 -83
- package/dist/components/portal/teleport.svelte +50 -50
- package/dist/components/qr-code/index.d.ts +1 -0
- package/dist/components/qr-code/index.js +1 -0
- package/dist/components/qr-code/qr-code.stories.svelte +24 -0
- package/dist/components/qr-code/qr-code.stories.svelte.d.ts +26 -0
- package/dist/components/qr-code/qr-code.svelte +25 -0
- package/dist/components/qr-code/qr-code.svelte.d.ts +6 -0
- package/dist/components/radio/radio.svelte +109 -109
- package/dist/components/radio/types.svelte.d.ts +1 -1
- package/dist/components/scrollable/scrollable-container.svelte +82 -82
- package/dist/components/scrollable/scrollable-content.svelte +41 -41
- package/dist/components/scrollable/scrollable-root.svelte +100 -100
- package/dist/components/scrollable/scrollable-thumb.svelte +75 -75
- package/dist/components/scrollable/scrollable-track.svelte +59 -59
- package/dist/components/scrollable/scrollable.stories.svelte.d.ts +1 -1
- package/dist/components/tabs/tab/tab-body.svelte +52 -52
- package/dist/components/tabs/tab/tab-description.svelte +41 -41
- package/dist/components/tabs/tab/tab-header.svelte +71 -71
- package/dist/components/tabs/tab/tab-root.svelte +86 -86
- package/dist/components/toast/toast-description.svelte +38 -38
- package/dist/components/toast/toast-root.svelte +61 -61
- package/dist/components/toast/toast-title.svelte +35 -35
- package/dist/components/tree/tree-body.svelte +39 -39
- package/dist/components/tree/tree-header.svelte +54 -54
- package/dist/components/tree/tree-indicator.svelte +40 -40
- package/dist/components/tree/tree-root.svelte +65 -65
- package/dist/components/virtual/virtual-root.svelte +239 -239
- package/dist/context/preset.svelte.d.ts +1 -1
- package/dist/icons/icon-arrow-down.svelte.d.ts +1 -1
- package/dist/icons/icon-checkmark.svelte.d.ts +1 -1
- package/dist/icons/icon-close.svelte.d.ts +1 -1
- package/dist/icons/icon-more-vert.svelte.d.ts +1 -1
- package/dist/runes/container.svelte.d.ts +2 -2
- package/dist/shared/bond.svelte.d.ts +1 -1
- package/dist/utils/state.d.ts +1 -1
- package/dist/utils/state.js +2 -1
- package/llm/variants.md +1261 -712
- 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,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>
|