@svelte-atoms/core 1.0.0-alpha.29 → 1.0.0-alpha.30
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 +852 -852
- package/dist/attachments/clickout.svelte.d.ts +1 -1
- package/dist/attachments/clickout.svelte.js +2 -2
- package/dist/components/accordion/accordion-root.svelte +61 -61
- package/dist/components/accordion/accordion-root.svelte.d.ts +1 -1
- package/dist/components/accordion/accordion.stories.svelte +145 -134
- package/dist/components/alert/alert.stories.svelte +400 -401
- package/dist/components/atom/html-atom.svelte +71 -17
- package/dist/components/avatar/avatar.stories.svelte +22 -27
- package/dist/components/badge/badge.stories.svelte +12 -17
- package/dist/components/badge/badge.svelte +19 -19
- package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -21
- package/dist/components/button/button.stories.svelte +27 -60
- package/dist/components/calendar/calendar-day.svelte +96 -96
- package/dist/components/calendar/calendar-header.svelte +29 -29
- package/dist/components/calendar/calendar-root.svelte +206 -206
- package/dist/components/calendar/calendar.stories.svelte +10 -15
- package/dist/components/card/card-body.svelte +39 -39
- package/dist/components/card/card-footer.svelte +41 -41
- package/dist/components/card/card-root.svelte +91 -91
- package/dist/components/card/card.stories.svelte +133 -145
- package/dist/components/checkbox/checkbox.stories.svelte +22 -27
- package/dist/components/checkbox/checkbox.svelte +155 -157
- package/dist/components/collapsible/collapsible.stories.svelte +172 -173
- package/dist/components/combobox/combobox-root.svelte +65 -65
- package/dist/components/combobox/compobox.stories.svelte +51 -54
- package/dist/components/container/container.stories.svelte +20 -23
- package/dist/components/datagrid/datagrid-root.svelte +59 -59
- package/dist/components/datagrid/datagrid.css +5 -5
- package/dist/components/datagrid/datagrid.stories.svelte +72 -75
- package/dist/components/date-picker/date-picker-calendar.svelte +67 -67
- package/dist/components/date-picker/date-picker-header.svelte +100 -100
- package/dist/components/date-picker/date-picker-months.svelte +142 -142
- package/dist/components/date-picker/date-picker-root.svelte +1 -1
- package/dist/components/date-picker/date-picker-years.svelte +205 -205
- package/dist/components/date-picker/date-picker.stories.svelte +11 -18
- package/dist/components/dialog/dialog-content.svelte +62 -62
- package/dist/components/dialog/dialog.stories.svelte +64 -67
- package/dist/components/drawer/attachments.svelte.js +8 -9
- package/dist/components/drawer/drawer-content.svelte +57 -42
- package/dist/components/drawer/drawer.stories.svelte +212 -224
- package/dist/components/dropdown/dropdown-root.svelte +59 -59
- package/dist/components/dropdown/dropdown.stories.svelte +80 -83
- package/dist/components/form/form.stories.svelte +96 -99
- package/dist/components/image/image.stories.svelte +20 -23
- package/dist/components/input/input.stories.svelte +35 -38
- package/dist/components/label/label.stories.svelte +15 -26
- package/dist/components/label/label.stories.svelte.d.ts +24 -4
- package/dist/components/lazy/lazy.stories.svelte +9 -16
- package/dist/components/lazy/lazy.svelte +28 -28
- package/dist/components/link/link.stories.svelte +15 -26
- package/dist/components/link/link.stories.svelte.d.ts +24 -4
- package/dist/components/menu/menu-list.svelte +40 -40
- package/dist/components/menu/menu.stories.svelte +33 -36
- package/dist/components/popover/bond.svelte.js +31 -25
- package/dist/components/popover/popover-arrow.svelte +111 -111
- package/dist/components/popover/popover-content.svelte +175 -178
- package/dist/components/popover/popover-indicator.svelte +44 -43
- package/dist/components/popover/popover-root.svelte +48 -48
- package/dist/components/popover/popover.stories.svelte +49 -52
- package/dist/components/qr-code/qr-code.stories.svelte +4 -13
- package/dist/components/qr-code/qr-code.svelte +75 -75
- package/dist/components/radio/radio-group.stories.svelte +41 -50
- package/dist/components/radio/radio.stories.svelte +17 -26
- package/dist/components/radio/radio.svelte +109 -109
- package/dist/components/root/root.svelte +121 -121
- package/dist/components/root/root.svelte.d.ts +1 -1
- package/dist/components/scrollable/scrollable.stories.svelte +116 -126
- package/dist/components/sidebar/sidebar-content.svelte +13 -2
- package/dist/components/sidebar/sidebar-root.svelte +10 -12
- package/dist/components/sidebar/sidebar.stories.svelte +8 -19
- package/dist/components/sidebar/types.d.ts +1 -0
- package/dist/components/tabs/tab/bond.svelte.d.ts +4 -1
- package/dist/components/tabs/tab/bond.svelte.js +4 -1
- package/dist/components/tabs/tabs.stories.svelte +56 -59
- package/dist/components/tooltip/tooltip-trigger.svelte +39 -37
- package/dist/components/tooltip/tooltip.stories.svelte +32 -35
- package/dist/components/tree/tree.stories.svelte +142 -134
- package/dist/context/preset.svelte.d.ts +3 -3
- package/dist/utils/function.d.ts +2 -0
- package/dist/utils/function.js +6 -0
- package/package.json +6 -9
- package/dist/actions/animation.svelte.d.ts +0 -6
- package/dist/actions/animation.svelte.js +0 -14
- package/dist/actions/clickout.svelte.d.ts +0 -2
- package/dist/actions/clickout.svelte.js +0 -15
- package/dist/actions/popover.svelte.d.ts +0 -19
- package/dist/actions/popover.svelte.js +0 -81
- package/dist/actions/portal.svelte.d.ts +0 -8
- package/dist/actions/portal.svelte.js +0 -32
- package/dist/attachments/gsap.svelte.d.ts +0 -2
- package/dist/attachments/gsap.svelte.js +0 -26
|
@@ -1,205 +1,205 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { animate } from 'motion';
|
|
3
|
-
import { getYear, setYear } from 'date-fns';
|
|
4
|
-
import { cn } from '../../utils';
|
|
5
|
-
import { DatePickerBond } from './bond.svelte';
|
|
6
|
-
import type { DatePickerYearsProps } from './types';
|
|
7
|
-
import { HtmlAtom } from '../atom';
|
|
8
|
-
import { Icon } from '../icon';
|
|
9
|
-
|
|
10
|
-
const datePicker = DatePickerBond.get();
|
|
11
|
-
|
|
12
|
-
const pivote = $derived(datePicker?.state.props.pivote ?? new Date());
|
|
13
|
-
|
|
14
|
-
let pivoteYear = $derived(pivote.getFullYear());
|
|
15
|
-
|
|
16
|
-
const currentYear = $derived(getYear(pivote));
|
|
17
|
-
|
|
18
|
-
// Generate array of years to display (12 years: current ±5)
|
|
19
|
-
const yearsGrid = $derived.by(() => {
|
|
20
|
-
const years = [];
|
|
21
|
-
const startYear = pivoteYear - 5;
|
|
22
|
-
for (let i = 0; i < 12; i++) {
|
|
23
|
-
years.push(startYear + i);
|
|
24
|
-
}
|
|
25
|
-
return years;
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
let {
|
|
29
|
-
class: klass = '',
|
|
30
|
-
preset = 'datepicker.years',
|
|
31
|
-
children,
|
|
32
|
-
...restProps
|
|
33
|
-
}: DatePickerYearsProps = $props();
|
|
34
|
-
|
|
35
|
-
let scrollTimeout: NodeJS.Timeout | undefined = undefined;
|
|
36
|
-
|
|
37
|
-
function enter(node: HTMLElement) {
|
|
38
|
-
animate(
|
|
39
|
-
node,
|
|
40
|
-
{
|
|
41
|
-
scale: [0.8, 1]
|
|
42
|
-
},
|
|
43
|
-
{ duration: 100 / 1000, ease: 'circOut' }
|
|
44
|
-
);
|
|
45
|
-
return {
|
|
46
|
-
duration: 100
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function exit(node: HTMLElement) {
|
|
51
|
-
animate(
|
|
52
|
-
node,
|
|
53
|
-
{
|
|
54
|
-
scale: 0.8
|
|
55
|
-
},
|
|
56
|
-
{ duration: 100 / 1000, ease: 'circOut' }
|
|
57
|
-
);
|
|
58
|
-
return {
|
|
59
|
-
duration: 100
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function handlePreviousYear() {
|
|
64
|
-
pivoteYear = pivoteYear - 1;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function handleNextYear() {
|
|
68
|
-
pivoteYear = pivoteYear + 1;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function handleYearSelect(year: number) {
|
|
72
|
-
if (!datePicker?.state.props.pivote) return;
|
|
73
|
-
const current = datePicker.state.props.pivote;
|
|
74
|
-
datePicker.state.props.pivote = setYear(current, year);
|
|
75
|
-
|
|
76
|
-
datePicker.state.closeYearsPicker();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function handleWheel(event: WheelEvent) {
|
|
80
|
-
event.preventDefault();
|
|
81
|
-
|
|
82
|
-
// Clear any existing timeout
|
|
83
|
-
if (scrollTimeout) {
|
|
84
|
-
clearTimeout(scrollTimeout);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Debounce the scroll event to avoid rapid year changes
|
|
88
|
-
scrollTimeout = setTimeout(() => {
|
|
89
|
-
const direction = event.deltaY > 0 ? 1 : -1; // Positive = scroll down = next year
|
|
90
|
-
pivoteYear = pivoteYear + direction;
|
|
91
|
-
}, 50);
|
|
92
|
-
}
|
|
93
|
-
</script>
|
|
94
|
-
|
|
95
|
-
{#if datePicker.state.isYearsPickerOpen}
|
|
96
|
-
<HtmlAtom
|
|
97
|
-
class={['absolute inset-0 z-2 flex flex-col gap-2 bg-inherit opacity-0', '$preset', klass]}
|
|
98
|
-
enter={(node) => {
|
|
99
|
-
animate(
|
|
100
|
-
node,
|
|
101
|
-
{
|
|
102
|
-
opacity: [0, 1]
|
|
103
|
-
},
|
|
104
|
-
{ duration: 100 / 1000, ease: 'anticipate' }
|
|
105
|
-
);
|
|
106
|
-
return {
|
|
107
|
-
duration: 100
|
|
108
|
-
};
|
|
109
|
-
}}
|
|
110
|
-
exit={(node) => {
|
|
111
|
-
animate(
|
|
112
|
-
node,
|
|
113
|
-
{
|
|
114
|
-
opacity: 0
|
|
115
|
-
},
|
|
116
|
-
{ duration: 100 / 1000, ease: 'anticipate' }
|
|
117
|
-
);
|
|
118
|
-
return {
|
|
119
|
-
duration: 100
|
|
120
|
-
};
|
|
121
|
-
}}
|
|
122
|
-
onwheel={handleWheel}
|
|
123
|
-
{preset}
|
|
124
|
-
{...restProps}
|
|
125
|
-
>
|
|
126
|
-
<HtmlAtom class="flex flex-1 flex-col" {enter} {exit}>
|
|
127
|
-
<!-- Navigation Bar -->
|
|
128
|
-
<nav
|
|
129
|
-
class="border-border text-foreground flex h-12 items-center justify-between gap-2 border-b px-2 py-2"
|
|
130
|
-
>
|
|
131
|
-
<!-- Previous Year Button -->
|
|
132
|
-
<button
|
|
133
|
-
type="button"
|
|
134
|
-
class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
|
|
135
|
-
onclick={handlePreviousYear}
|
|
136
|
-
aria-label="Previous year"
|
|
137
|
-
>
|
|
138
|
-
<Icon class="size-5">
|
|
139
|
-
<svg
|
|
140
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
141
|
-
class="size-full"
|
|
142
|
-
viewBox="0 0 24 24"
|
|
143
|
-
fill="none"
|
|
144
|
-
stroke="currentColor"
|
|
145
|
-
stroke-width="2"
|
|
146
|
-
stroke-linecap="round"
|
|
147
|
-
stroke-linejoin="round"
|
|
148
|
-
>
|
|
149
|
-
<path d="M15 18l-6-6 6-6" />
|
|
150
|
-
</svg>
|
|
151
|
-
</Icon>
|
|
152
|
-
</button>
|
|
153
|
-
|
|
154
|
-
<!-- Year Display -->
|
|
155
|
-
<div class="flex-1">
|
|
156
|
-
<!-- {currentYear} -->
|
|
157
|
-
</div>
|
|
158
|
-
|
|
159
|
-
<!-- Next Year Button -->
|
|
160
|
-
<button
|
|
161
|
-
type="button"
|
|
162
|
-
class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
|
|
163
|
-
onclick={handleNextYear}
|
|
164
|
-
aria-label="Next year"
|
|
165
|
-
>
|
|
166
|
-
<Icon class="size-5">
|
|
167
|
-
<svg
|
|
168
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
169
|
-
class="size-full"
|
|
170
|
-
viewBox="0 0 24 24"
|
|
171
|
-
fill="none"
|
|
172
|
-
stroke="currentColor"
|
|
173
|
-
stroke-width="2"
|
|
174
|
-
stroke-linecap="round"
|
|
175
|
-
stroke-linejoin="round"
|
|
176
|
-
>
|
|
177
|
-
<path d="M9 18l6-6-6-6" />
|
|
178
|
-
</svg>
|
|
179
|
-
</Icon>
|
|
180
|
-
</button>
|
|
181
|
-
</nav>
|
|
182
|
-
|
|
183
|
-
<!-- Years Grid -->
|
|
184
|
-
<div class="grid flex-1 grid-cols-4 gap-1 px-2 py-2">
|
|
185
|
-
{#each yearsGrid as year}
|
|
186
|
-
{@const isSelected = year === pivote.getFullYear()}
|
|
187
|
-
{@const isCurrent = year === currentYear}
|
|
188
|
-
<button
|
|
189
|
-
type="button"
|
|
190
|
-
class={cn(
|
|
191
|
-
'hover:bg-foreground/10 active:bg-foreground/20 rounded-md px-3 py-2 text-sm transition-colors',
|
|
192
|
-
isSelected && 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
193
|
-
isCurrent && !isSelected && 'ring-foreground/20 ring-1'
|
|
194
|
-
)}
|
|
195
|
-
onclick={() => handleYearSelect(year)}
|
|
196
|
-
aria-label="Select year {year}"
|
|
197
|
-
aria-current={isSelected ? 'date' : undefined}
|
|
198
|
-
>
|
|
199
|
-
{year}
|
|
200
|
-
</button>
|
|
201
|
-
{/each}
|
|
202
|
-
</div>
|
|
203
|
-
</HtmlAtom>
|
|
204
|
-
</HtmlAtom>
|
|
205
|
-
{/if}
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { animate } from 'motion';
|
|
3
|
+
import { getYear, setYear } from 'date-fns';
|
|
4
|
+
import { cn } from '../../utils';
|
|
5
|
+
import { DatePickerBond } from './bond.svelte';
|
|
6
|
+
import type { DatePickerYearsProps } from './types';
|
|
7
|
+
import { HtmlAtom } from '../atom';
|
|
8
|
+
import { Icon } from '../icon';
|
|
9
|
+
|
|
10
|
+
const datePicker = DatePickerBond.get();
|
|
11
|
+
|
|
12
|
+
const pivote = $derived(datePicker?.state.props.pivote ?? new Date());
|
|
13
|
+
|
|
14
|
+
let pivoteYear = $derived(pivote.getFullYear());
|
|
15
|
+
|
|
16
|
+
const currentYear = $derived(getYear(pivote));
|
|
17
|
+
|
|
18
|
+
// Generate array of years to display (12 years: current ±5)
|
|
19
|
+
const yearsGrid = $derived.by(() => {
|
|
20
|
+
const years = [];
|
|
21
|
+
const startYear = pivoteYear - 5;
|
|
22
|
+
for (let i = 0; i < 12; i++) {
|
|
23
|
+
years.push(startYear + i);
|
|
24
|
+
}
|
|
25
|
+
return years;
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
class: klass = '',
|
|
30
|
+
preset = 'datepicker.years',
|
|
31
|
+
children,
|
|
32
|
+
...restProps
|
|
33
|
+
}: DatePickerYearsProps = $props();
|
|
34
|
+
|
|
35
|
+
let scrollTimeout: NodeJS.Timeout | undefined = undefined;
|
|
36
|
+
|
|
37
|
+
function enter(node: HTMLElement) {
|
|
38
|
+
animate(
|
|
39
|
+
node,
|
|
40
|
+
{
|
|
41
|
+
scale: [0.8, 1]
|
|
42
|
+
},
|
|
43
|
+
{ duration: 100 / 1000, ease: 'circOut' }
|
|
44
|
+
);
|
|
45
|
+
return {
|
|
46
|
+
duration: 100
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function exit(node: HTMLElement) {
|
|
51
|
+
animate(
|
|
52
|
+
node,
|
|
53
|
+
{
|
|
54
|
+
scale: 0.8
|
|
55
|
+
},
|
|
56
|
+
{ duration: 100 / 1000, ease: 'circOut' }
|
|
57
|
+
);
|
|
58
|
+
return {
|
|
59
|
+
duration: 100
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function handlePreviousYear() {
|
|
64
|
+
pivoteYear = pivoteYear - 1;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function handleNextYear() {
|
|
68
|
+
pivoteYear = pivoteYear + 1;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function handleYearSelect(year: number) {
|
|
72
|
+
if (!datePicker?.state.props.pivote) return;
|
|
73
|
+
const current = datePicker.state.props.pivote;
|
|
74
|
+
datePicker.state.props.pivote = setYear(current, year);
|
|
75
|
+
|
|
76
|
+
datePicker.state.closeYearsPicker();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function handleWheel(event: WheelEvent) {
|
|
80
|
+
event.preventDefault();
|
|
81
|
+
|
|
82
|
+
// Clear any existing timeout
|
|
83
|
+
if (scrollTimeout) {
|
|
84
|
+
clearTimeout(scrollTimeout);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Debounce the scroll event to avoid rapid year changes
|
|
88
|
+
scrollTimeout = setTimeout(() => {
|
|
89
|
+
const direction = event.deltaY > 0 ? 1 : -1; // Positive = scroll down = next year
|
|
90
|
+
pivoteYear = pivoteYear + direction;
|
|
91
|
+
}, 50);
|
|
92
|
+
}
|
|
93
|
+
</script>
|
|
94
|
+
|
|
95
|
+
{#if datePicker.state.isYearsPickerOpen}
|
|
96
|
+
<HtmlAtom
|
|
97
|
+
class={['absolute inset-0 z-2 flex flex-col gap-2 bg-inherit opacity-0', '$preset', klass]}
|
|
98
|
+
enter={(node) => {
|
|
99
|
+
animate(
|
|
100
|
+
node,
|
|
101
|
+
{
|
|
102
|
+
opacity: [0, 1]
|
|
103
|
+
},
|
|
104
|
+
{ duration: 100 / 1000, ease: 'anticipate' }
|
|
105
|
+
);
|
|
106
|
+
return {
|
|
107
|
+
duration: 100
|
|
108
|
+
};
|
|
109
|
+
}}
|
|
110
|
+
exit={(node) => {
|
|
111
|
+
animate(
|
|
112
|
+
node,
|
|
113
|
+
{
|
|
114
|
+
opacity: 0
|
|
115
|
+
},
|
|
116
|
+
{ duration: 100 / 1000, ease: 'anticipate' }
|
|
117
|
+
);
|
|
118
|
+
return {
|
|
119
|
+
duration: 100
|
|
120
|
+
};
|
|
121
|
+
}}
|
|
122
|
+
onwheel={handleWheel}
|
|
123
|
+
{preset}
|
|
124
|
+
{...restProps}
|
|
125
|
+
>
|
|
126
|
+
<HtmlAtom class="flex flex-1 flex-col" {enter} {exit}>
|
|
127
|
+
<!-- Navigation Bar -->
|
|
128
|
+
<nav
|
|
129
|
+
class="border-border text-foreground flex h-12 items-center justify-between gap-2 border-b px-2 py-2"
|
|
130
|
+
>
|
|
131
|
+
<!-- Previous Year Button -->
|
|
132
|
+
<button
|
|
133
|
+
type="button"
|
|
134
|
+
class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
|
|
135
|
+
onclick={handlePreviousYear}
|
|
136
|
+
aria-label="Previous year"
|
|
137
|
+
>
|
|
138
|
+
<Icon class="size-5">
|
|
139
|
+
<svg
|
|
140
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
141
|
+
class="size-full"
|
|
142
|
+
viewBox="0 0 24 24"
|
|
143
|
+
fill="none"
|
|
144
|
+
stroke="currentColor"
|
|
145
|
+
stroke-width="2"
|
|
146
|
+
stroke-linecap="round"
|
|
147
|
+
stroke-linejoin="round"
|
|
148
|
+
>
|
|
149
|
+
<path d="M15 18l-6-6 6-6" />
|
|
150
|
+
</svg>
|
|
151
|
+
</Icon>
|
|
152
|
+
</button>
|
|
153
|
+
|
|
154
|
+
<!-- Year Display -->
|
|
155
|
+
<div class="flex-1">
|
|
156
|
+
<!-- {currentYear} -->
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<!-- Next Year Button -->
|
|
160
|
+
<button
|
|
161
|
+
type="button"
|
|
162
|
+
class="hover:bg-foreground/10 active:bg-foreground/20 flex size-8 cursor-pointer items-center justify-center rounded-md transition-colors"
|
|
163
|
+
onclick={handleNextYear}
|
|
164
|
+
aria-label="Next year"
|
|
165
|
+
>
|
|
166
|
+
<Icon class="size-5">
|
|
167
|
+
<svg
|
|
168
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
169
|
+
class="size-full"
|
|
170
|
+
viewBox="0 0 24 24"
|
|
171
|
+
fill="none"
|
|
172
|
+
stroke="currentColor"
|
|
173
|
+
stroke-width="2"
|
|
174
|
+
stroke-linecap="round"
|
|
175
|
+
stroke-linejoin="round"
|
|
176
|
+
>
|
|
177
|
+
<path d="M9 18l6-6-6-6" />
|
|
178
|
+
</svg>
|
|
179
|
+
</Icon>
|
|
180
|
+
</button>
|
|
181
|
+
</nav>
|
|
182
|
+
|
|
183
|
+
<!-- Years Grid -->
|
|
184
|
+
<div class="grid flex-1 grid-cols-4 gap-1 px-2 py-2">
|
|
185
|
+
{#each yearsGrid as year}
|
|
186
|
+
{@const isSelected = year === pivote.getFullYear()}
|
|
187
|
+
{@const isCurrent = year === currentYear}
|
|
188
|
+
<button
|
|
189
|
+
type="button"
|
|
190
|
+
class={cn(
|
|
191
|
+
'hover:bg-foreground/10 active:bg-foreground/20 rounded-md px-3 py-2 text-sm transition-colors',
|
|
192
|
+
isSelected && 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
193
|
+
isCurrent && !isSelected && 'ring-foreground/20 ring-1'
|
|
194
|
+
)}
|
|
195
|
+
onclick={() => handleYearSelect(year)}
|
|
196
|
+
aria-label="Select year {year}"
|
|
197
|
+
aria-current={isSelected ? 'date' : undefined}
|
|
198
|
+
>
|
|
199
|
+
{year}
|
|
200
|
+
</button>
|
|
201
|
+
{/each}
|
|
202
|
+
</div>
|
|
203
|
+
</HtmlAtom>
|
|
204
|
+
</HtmlAtom>
|
|
205
|
+
{/if}
|
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
</script>
|
|
8
8
|
|
|
9
9
|
<script lang="ts">
|
|
10
|
-
import { Root } from '../root';
|
|
11
10
|
import { DatePicker as ADatePicker } from '.';
|
|
12
11
|
import { Button } from '../button';
|
|
13
12
|
import { addDays, subDays } from 'date-fns';
|
|
@@ -20,23 +19,17 @@
|
|
|
20
19
|
|
|
21
20
|
<Story name="Date Picker">
|
|
22
21
|
{#snippet children({ args })}
|
|
23
|
-
<Root>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{:else}
|
|
31
|
-
<div>Open Date Picker</div>
|
|
32
|
-
{/if}
|
|
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}
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</div>
|
|
39
|
-
{/snippet}
|
|
40
|
-
</Root>
|
|
30
|
+
<ADatePicker.Indicator class="ml-auto" />
|
|
31
|
+
</ADatePicker.Trigger>
|
|
32
|
+
<ADatePicker.Calendar />
|
|
33
|
+
</ADatePicker.Root>
|
|
41
34
|
{/snippet}
|
|
42
35
|
</Story>
|
|
@@ -1,62 +1,62 @@
|
|
|
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
|
-
import { HtmlAtom, type Base } from '../atom';
|
|
5
|
-
import { DialogBond } from './bond.svelte';
|
|
6
|
-
import type { DialogContentProps } from './types';
|
|
7
|
-
|
|
8
|
-
const bond = DialogBond.get();
|
|
9
|
-
|
|
10
|
-
let {
|
|
11
|
-
class: klass = '',
|
|
12
|
-
children = undefined,
|
|
13
|
-
onmount = undefined,
|
|
14
|
-
ondestroy = undefined,
|
|
15
|
-
animate = _animate,
|
|
16
|
-
enter = undefined,
|
|
17
|
-
exit = undefined,
|
|
18
|
-
initial = undefined,
|
|
19
|
-
...restProps
|
|
20
|
-
}: DialogContentProps<E, B> = $props();
|
|
21
|
-
|
|
22
|
-
const dialogProps = $derived({
|
|
23
|
-
...bond?.content({}),
|
|
24
|
-
...restProps
|
|
25
|
-
});
|
|
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
|
-
</script>
|
|
44
|
-
|
|
45
|
-
<HtmlAtom
|
|
46
|
-
preset="dialog.content"
|
|
47
|
-
class={[
|
|
48
|
-
'bg-card text-foreground border-border flex h-fit w-full max-w-[90svw] flex-col rounded-md border py-4 shadow-sm',
|
|
49
|
-
'$preset',
|
|
50
|
-
klass
|
|
51
|
-
]}
|
|
52
|
-
{bond}
|
|
53
|
-
enter={enter?.bind(bond.state)}
|
|
54
|
-
exit={exit?.bind(bond.state)}
|
|
55
|
-
initial={initial?.bind(bond.state)}
|
|
56
|
-
animate={animate?.bind(bond.state)}
|
|
57
|
-
onmount={onmount?.bind(bond.state)}
|
|
58
|
-
ondestroy={ondestroy?.bind(bond.state)}
|
|
59
|
-
{...dialogProps}
|
|
60
|
-
>
|
|
61
|
-
{@render children?.({ dialog: bond })}
|
|
62
|
-
</HtmlAtom>
|
|
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
|
+
import { HtmlAtom, type Base } from '../atom';
|
|
5
|
+
import { DialogBond } from './bond.svelte';
|
|
6
|
+
import type { DialogContentProps } from './types';
|
|
7
|
+
|
|
8
|
+
const bond = DialogBond.get();
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
class: klass = '',
|
|
12
|
+
children = undefined,
|
|
13
|
+
onmount = undefined,
|
|
14
|
+
ondestroy = undefined,
|
|
15
|
+
animate = _animate,
|
|
16
|
+
enter = undefined,
|
|
17
|
+
exit = undefined,
|
|
18
|
+
initial = undefined,
|
|
19
|
+
...restProps
|
|
20
|
+
}: DialogContentProps<E, B> = $props();
|
|
21
|
+
|
|
22
|
+
const dialogProps = $derived({
|
|
23
|
+
...bond?.content({}),
|
|
24
|
+
...restProps
|
|
25
|
+
});
|
|
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
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<HtmlAtom
|
|
46
|
+
preset="dialog.content"
|
|
47
|
+
class={[
|
|
48
|
+
'bg-card text-foreground border-border flex h-fit w-full max-w-[90svw] flex-col rounded-md border py-4 shadow-sm',
|
|
49
|
+
'$preset',
|
|
50
|
+
klass
|
|
51
|
+
]}
|
|
52
|
+
{bond}
|
|
53
|
+
enter={enter?.bind(bond.state)}
|
|
54
|
+
exit={exit?.bind(bond.state)}
|
|
55
|
+
initial={initial?.bind(bond.state)}
|
|
56
|
+
animate={animate?.bind(bond.state)}
|
|
57
|
+
onmount={onmount?.bind(bond.state)}
|
|
58
|
+
ondestroy={ondestroy?.bind(bond.state)}
|
|
59
|
+
{...dialogProps}
|
|
60
|
+
>
|
|
61
|
+
{@render children?.({ dialog: bond })}
|
|
62
|
+
</HtmlAtom>
|