@svelte-atoms/core 1.0.0-alpha.28 → 1.0.0-alpha.29
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 +1 -5
- package/dist/components/alert/alert-actions.svelte +43 -43
- package/dist/components/alert/alert-close-button.svelte +70 -70
- package/dist/components/alert/alert-content.svelte +43 -43
- package/dist/components/alert/alert-description.svelte +42 -42
- package/dist/components/alert/alert-icon.svelte +47 -47
- package/dist/components/alert/alert-root.svelte +103 -103
- package/dist/components/alert/alert-title.svelte +42 -42
- package/dist/components/alert/alert.stories.svelte +401 -401
- package/dist/components/atom/html-atom.svelte +6 -4
- package/dist/components/atom/html-atom.svelte.d.ts +1 -1
- package/dist/components/atom/snippet-renderer.svelte +5 -5
- package/dist/components/button/button.stories.svelte +60 -60
- package/dist/components/calendar/calendar-body.svelte +107 -107
- package/dist/components/calendar/calendar-day.svelte +0 -1
- package/dist/components/calendar/calendar-header.svelte +2 -6
- package/dist/components/calendar/calendar-header.svelte.d.ts +0 -1
- package/dist/components/calendar/calendar-root.svelte +0 -2
- package/dist/components/calendar/calendar-week-day.svelte +34 -34
- package/dist/components/calendar/calendar.css +26 -26
- package/dist/components/calendar/calendar.stories.svelte +0 -5
- package/dist/components/calendar/calendar.stories.svelte.d.ts +24 -4
- package/dist/components/datagrid/datagrid-root.svelte +59 -59
- package/dist/components/datagrid/datagrid.css +5 -47
- package/dist/components/datagrid/types.d.ts +1 -1
- package/dist/components/date-picker/atoms.d.ts +0 -4
- package/dist/components/date-picker/atoms.js +0 -4
- package/dist/components/date-picker/date-picker-calendar.svelte +34 -9
- package/dist/components/date-picker/date-picker-calendar.svelte.d.ts +2 -5
- package/dist/components/date-picker/date-picker-header.svelte +59 -64
- package/dist/components/date-picker/date-picker-header.svelte.d.ts +2 -5
- package/dist/components/date-picker/date-picker-months.svelte +36 -44
- package/dist/components/date-picker/date-picker-months.svelte.d.ts +2 -5
- package/dist/components/date-picker/date-picker-root.svelte +3 -2
- package/dist/components/date-picker/date-picker-root.svelte.d.ts +2 -15
- package/dist/components/date-picker/date-picker-years.svelte +88 -97
- package/dist/components/date-picker/date-picker-years.svelte.d.ts +2 -5
- package/dist/components/date-picker/date-picker.stories.svelte +6 -15
- package/dist/components/date-picker/types.d.ts +53 -1
- package/dist/components/dialog/dialog-content.svelte +62 -62
- package/dist/components/element/html-element.svelte +85 -85
- package/dist/components/element/types.d.ts +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/lazy/index.d.ts +1 -0
- package/dist/components/lazy/index.js +1 -0
- package/dist/components/lazy/lazy.stories.svelte +35 -0
- package/dist/components/lazy/lazy.stories.svelte.d.ts +19 -0
- package/dist/components/lazy/lazy.svelte +28 -0
- package/dist/components/lazy/lazy.svelte.d.ts +5 -0
- package/dist/components/lazy/types.d.ts +10 -0
- package/dist/components/lazy/types.js +1 -0
- package/dist/components/menu/menu-list.svelte +40 -39
- package/dist/components/menu/menu-list.svelte.d.ts +1 -0
- package/dist/components/popover/popover-content.svelte +178 -178
- package/dist/components/popover/popover-root.svelte +48 -48
- package/dist/components/popover/popover.stories.svelte +52 -52
- 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 +4 -1
- package/dist/components/qr-code/qr-code.svelte +65 -15
- package/dist/components/qr-code/qr-code.svelte.d.ts +2 -4
- package/dist/components/qr-code/types.d.ts +14 -0
- package/dist/components/qr-code/types.js +1 -0
- package/dist/components/sidebar/bond.svelte.d.ts +0 -5
- package/dist/components/sidebar/bond.svelte.js +1 -12
- package/dist/components/sidebar/sidebar-content.svelte +39 -39
- package/dist/components/sidebar/sidebar-content.svelte.d.ts +2 -2
- package/dist/components/sidebar/sidebar-root.svelte +41 -68
- package/dist/components/sidebar/sidebar-root.svelte.d.ts +2 -2
- package/dist/components/sidebar/sidebar.stories.svelte +54 -52
- package/dist/components/sidebar/types.d.ts +6 -6
- package/llm/variants.md +1259 -1261
- package/package.json +2 -1
|
@@ -1,33 +1,36 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import { PopoverBond } from '../popover';
|
|
4
|
-
import { Icon } from '../icon';
|
|
5
|
-
import { DatePickerBond } from './bond.svelte';
|
|
2
|
+
import { animate } from 'motion';
|
|
6
3
|
import { getYear, setYear } from 'date-fns';
|
|
7
4
|
import { cn } from '../../utils';
|
|
8
|
-
import {
|
|
5
|
+
import { DatePickerBond } from './bond.svelte';
|
|
6
|
+
import type { DatePickerYearsProps } from './types';
|
|
7
|
+
import { HtmlAtom } from '../atom';
|
|
8
|
+
import { Icon } from '../icon';
|
|
9
9
|
|
|
10
|
-
const popover = PopoverBond.get();
|
|
11
10
|
const datePicker = DatePickerBond.get();
|
|
12
|
-
const calendar = datePicker.calendar;
|
|
13
11
|
|
|
14
12
|
const pivote = $derived(datePicker?.state.props.pivote ?? new Date());
|
|
15
13
|
|
|
16
|
-
let
|
|
14
|
+
let pivoteYear = $derived(pivote.getFullYear());
|
|
17
15
|
|
|
18
16
|
const currentYear = $derived(getYear(pivote));
|
|
19
17
|
|
|
20
18
|
// Generate array of years to display (12 years: current ±5)
|
|
21
19
|
const yearsGrid = $derived.by(() => {
|
|
22
20
|
const years = [];
|
|
23
|
-
const startYear =
|
|
21
|
+
const startYear = pivoteYear - 5;
|
|
24
22
|
for (let i = 0; i < 12; i++) {
|
|
25
23
|
years.push(startYear + i);
|
|
26
24
|
}
|
|
27
25
|
return years;
|
|
28
26
|
});
|
|
29
27
|
|
|
30
|
-
let {
|
|
28
|
+
let {
|
|
29
|
+
class: klass = '',
|
|
30
|
+
preset = 'datepicker.years',
|
|
31
|
+
children,
|
|
32
|
+
...restProps
|
|
33
|
+
}: DatePickerYearsProps = $props();
|
|
31
34
|
|
|
32
35
|
let scrollTimeout: NodeJS.Timeout | undefined = undefined;
|
|
33
36
|
|
|
@@ -58,11 +61,11 @@
|
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
function handlePreviousYear() {
|
|
61
|
-
|
|
64
|
+
pivoteYear = pivoteYear - 1;
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
function handleNextYear() {
|
|
65
|
-
|
|
68
|
+
pivoteYear = pivoteYear + 1;
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
function handleYearSelect(year: number) {
|
|
@@ -84,7 +87,7 @@
|
|
|
84
87
|
// Debounce the scroll event to avoid rapid year changes
|
|
85
88
|
scrollTimeout = setTimeout(() => {
|
|
86
89
|
const direction = event.deltaY > 0 ? 1 : -1; // Positive = scroll down = next year
|
|
87
|
-
|
|
90
|
+
pivoteYear = pivoteYear + direction;
|
|
88
91
|
}, 50);
|
|
89
92
|
}
|
|
90
93
|
</script>
|
|
@@ -120,95 +123,83 @@
|
|
|
120
123
|
{preset}
|
|
121
124
|
{...restProps}
|
|
122
125
|
>
|
|
123
|
-
{
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
<HtmlAtom class="flex flex-1 flex-col" {enter} {exit}>
|
|
135
|
-
<!-- Navigation Bar -->
|
|
136
|
-
<nav
|
|
137
|
-
class="border-border text-foreground flex h-12 items-center justify-between gap-2 border-b px-2 py-2"
|
|
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"
|
|
138
137
|
>
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
</Icon>
|
|
160
|
-
</button>
|
|
161
|
-
|
|
162
|
-
<!-- Year Display -->
|
|
163
|
-
<div class="text-foreground flex-1 text-center text-sm font-semibold">
|
|
164
|
-
{currentYear}
|
|
165
|
-
</div>
|
|
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>
|
|
166
158
|
|
|
167
|
-
|
|
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}
|
|
168
188
|
<button
|
|
169
189
|
type="button"
|
|
170
|
-
class=
|
|
171
|
-
|
|
172
|
-
|
|
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}
|
|
173
198
|
>
|
|
174
|
-
|
|
175
|
-
<svg
|
|
176
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
177
|
-
class="size-full"
|
|
178
|
-
viewBox="0 0 24 24"
|
|
179
|
-
fill="none"
|
|
180
|
-
stroke="currentColor"
|
|
181
|
-
stroke-width="2"
|
|
182
|
-
stroke-linecap="round"
|
|
183
|
-
stroke-linejoin="round"
|
|
184
|
-
>
|
|
185
|
-
<path d="M9 18l6-6-6-6" />
|
|
186
|
-
</svg>
|
|
187
|
-
</Icon>
|
|
199
|
+
{year}
|
|
188
200
|
</button>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
<div class="grid flex-1 grid-cols-4 gap-1 px-2 py-2">
|
|
193
|
-
{#each yearsGrid as year}
|
|
194
|
-
{@const isSelected = year === pivote.getFullYear()}
|
|
195
|
-
{@const isCurrent = year === currentYear}
|
|
196
|
-
<button
|
|
197
|
-
type="button"
|
|
198
|
-
class={cn(
|
|
199
|
-
'hover:bg-foreground/10 active:bg-foreground/20 rounded-md px-3 py-2 text-sm transition-colors',
|
|
200
|
-
isSelected && 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
201
|
-
isCurrent && !isSelected && 'ring-foreground/20 ring-1'
|
|
202
|
-
)}
|
|
203
|
-
onclick={() => handleYearSelect(year)}
|
|
204
|
-
aria-label="Select year {year}"
|
|
205
|
-
aria-current={isSelected ? 'date' : undefined}
|
|
206
|
-
>
|
|
207
|
-
{year}
|
|
208
|
-
</button>
|
|
209
|
-
{/each}
|
|
210
|
-
</div>
|
|
211
|
-
</HtmlAtom>
|
|
212
|
-
{/if}
|
|
201
|
+
{/each}
|
|
202
|
+
</div>
|
|
203
|
+
</HtmlAtom>
|
|
213
204
|
</HtmlAtom>
|
|
214
205
|
{/if}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
preset?: string;
|
|
4
|
-
children: any;
|
|
5
|
-
} & Record<string, any>, {}, "">;
|
|
1
|
+
import type { DatePickerYearsProps } from './types';
|
|
2
|
+
declare const DatePickerYears: import("svelte").Component<DatePickerYearsProps, {}, "">;
|
|
6
3
|
type DatePickerYears = ReturnType<typeof DatePickerYears>;
|
|
7
4
|
export default DatePickerYears;
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
import { Root } from '../root';
|
|
11
11
|
import { DatePicker as ADatePicker } from '.';
|
|
12
12
|
import { Button } from '../button';
|
|
13
|
-
import { addDays,
|
|
14
|
-
import { date } from 'zod';
|
|
13
|
+
import { addDays, subDays } from 'date-fns';
|
|
15
14
|
|
|
16
15
|
let value: Date | undefined = $state(undefined);
|
|
16
|
+
|
|
17
|
+
let min = $state(subDays(new Date(), 5));
|
|
18
|
+
let max = $state(addDays(new Date(), 15));
|
|
17
19
|
</script>
|
|
18
20
|
|
|
19
21
|
<Story name="Date Picker">
|
|
@@ -21,7 +23,7 @@
|
|
|
21
23
|
<Root>
|
|
22
24
|
{#snippet children({})}
|
|
23
25
|
<div class="flex h-fit items-center justify-center">
|
|
24
|
-
<ADatePicker.Root bind:value min
|
|
26
|
+
<ADatePicker.Root bind:value {min} {max}>
|
|
25
27
|
<ADatePicker.Trigger base={Button} class="w-sm gap-4">
|
|
26
28
|
{#if value}
|
|
27
29
|
<div>{value.toDateString()}</div>
|
|
@@ -31,18 +33,7 @@
|
|
|
31
33
|
|
|
32
34
|
<ADatePicker.Indicator class="ml-auto" />
|
|
33
35
|
</ADatePicker.Trigger>
|
|
34
|
-
<ADatePicker.Calendar
|
|
35
|
-
<ADatePicker.Header class="col-span-full"></ADatePicker.Header>
|
|
36
|
-
<ADatePicker.WeekDays></ADatePicker.WeekDays>
|
|
37
|
-
<ADatePicker.Body>
|
|
38
|
-
{#snippet children({ day })}
|
|
39
|
-
<ADatePicker.Day {day} class=""></ADatePicker.Day>
|
|
40
|
-
{/snippet}
|
|
41
|
-
</ADatePicker.Body>
|
|
42
|
-
|
|
43
|
-
<ADatePicker.Years></ADatePicker.Years>
|
|
44
|
-
<ADatePicker.Months></ADatePicker.Months>
|
|
45
|
-
</ADatePicker.Calendar>
|
|
36
|
+
<ADatePicker.Calendar />
|
|
46
37
|
</ADatePicker.Root>
|
|
47
38
|
</div>
|
|
48
39
|
{/snippet}
|
|
@@ -1 +1,53 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
|
+
import type { Day, CalendarRange } from '../calendar/types';
|
|
3
|
+
import type { DatePickerBond } from './bond.svelte';
|
|
4
|
+
import type { Factory } from '../../types';
|
|
5
|
+
export interface DatePickerCalendarProps {
|
|
6
|
+
class?: string;
|
|
7
|
+
preset?: string;
|
|
8
|
+
children?: Snippet<[{
|
|
9
|
+
day: Day;
|
|
10
|
+
}]>;
|
|
11
|
+
Header?: Component;
|
|
12
|
+
Weekdays?: Component;
|
|
13
|
+
Body?: Component;
|
|
14
|
+
Day?: Component;
|
|
15
|
+
Months?: Component;
|
|
16
|
+
Years?: Component;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}
|
|
19
|
+
export interface DatePickerHeaderProps {
|
|
20
|
+
class?: string;
|
|
21
|
+
preset?: string;
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface DatePickerMonthsProps {
|
|
26
|
+
class?: string;
|
|
27
|
+
preset?: string;
|
|
28
|
+
children?: Snippet;
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
export interface DatePickerYearsProps {
|
|
32
|
+
class?: string;
|
|
33
|
+
preset?: string;
|
|
34
|
+
children?: Snippet;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
export interface DatePickerRootProps {
|
|
38
|
+
open?: boolean;
|
|
39
|
+
value?: Date;
|
|
40
|
+
range?: CalendarRange;
|
|
41
|
+
pivote?: Date;
|
|
42
|
+
start?: Date;
|
|
43
|
+
end?: Date;
|
|
44
|
+
min?: Date;
|
|
45
|
+
max?: Date;
|
|
46
|
+
type?: 'range' | 'single';
|
|
47
|
+
offset?: number;
|
|
48
|
+
factory?: Factory<DatePickerBond>;
|
|
49
|
+
children?: Snippet<[{
|
|
50
|
+
datePicker: DatePickerBond;
|
|
51
|
+
}]>;
|
|
52
|
+
[key: string]: unknown;
|
|
53
|
+
}
|
|
@@ -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>
|
|
@@ -1,85 +1,85 @@
|
|
|
1
|
-
<script lang="ts" generics="T extends HtmlElementTagName">
|
|
2
|
-
import { untrack } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
-
import { createAttachmentKey } from 'svelte/attachments';
|
|
5
|
-
import { cn, toClassValue } from '../../utils';
|
|
6
|
-
import type { ElementType, HtmlElementProps, HtmlElementTagName } from './types';
|
|
7
|
-
|
|
8
|
-
type Element = ElementType<T>;
|
|
9
|
-
|
|
10
|
-
let {
|
|
11
|
-
class: klass = '',
|
|
12
|
-
as = 'div' as T,
|
|
13
|
-
global = true,
|
|
14
|
-
initial = undefined,
|
|
15
|
-
enter = undefined,
|
|
16
|
-
exit = undefined,
|
|
17
|
-
animate = undefined,
|
|
18
|
-
onmount = undefined,
|
|
19
|
-
ondestroy = undefined,
|
|
20
|
-
children = undefined,
|
|
21
|
-
...restProps
|
|
22
|
-
}: HtmlElementProps<T> & Omit<HTMLAttributes<Element>, keyof HtmlElementProps<T>> = $props();
|
|
23
|
-
|
|
24
|
-
let node = $state<Element>();
|
|
25
|
-
|
|
26
|
-
let skipFirstAnimate = $state(!!enter);
|
|
27
|
-
|
|
28
|
-
$effect(() => {
|
|
29
|
-
if (!node) return;
|
|
30
|
-
|
|
31
|
-
const unmount = untrack(() => onmount?.(node!));
|
|
32
|
-
|
|
33
|
-
return () => {
|
|
34
|
-
if (typeof unmount === 'function') unmount(node!);
|
|
35
|
-
ondestroy?.(node!);
|
|
36
|
-
};
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
$effect(() => {
|
|
40
|
-
const fn = animate;
|
|
41
|
-
|
|
42
|
-
if (!node) return;
|
|
43
|
-
const shouldSkip = untrack(() => skipFirstAnimate);
|
|
44
|
-
|
|
45
|
-
if (shouldSkip) {
|
|
46
|
-
skipFirstAnimate = false;
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
fn?.(node);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const elementProps = $derived({
|
|
54
|
-
[createAttachmentKey()]: (n: Element) => {
|
|
55
|
-
node = n;
|
|
56
|
-
},
|
|
57
|
-
class: cn(toClassValue(klass)),
|
|
58
|
-
...restProps
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
function _enter(node: Element) {
|
|
62
|
-
initial?.(node);
|
|
63
|
-
return () => {
|
|
64
|
-
const { duration = 0, delay = 0, easing = undefined } = enter?.(node) ?? {};
|
|
65
|
-
return { duration, delay, easing };
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function _exit(node: Element) {
|
|
70
|
-
return () => {
|
|
71
|
-
const { duration = 0, delay = 0, easing = undefined } = exit?.(node) ?? {};
|
|
72
|
-
return { duration, delay, easing };
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
</script>
|
|
76
|
-
|
|
77
|
-
{#if global}
|
|
78
|
-
<svelte:element this={as} in:_enter|global out:_exit|global {...elementProps}>
|
|
79
|
-
{@render children?.()}
|
|
80
|
-
</svelte:element>
|
|
81
|
-
{:else}
|
|
82
|
-
<svelte:element this={as} in:_enter out:_exit {...elementProps}>
|
|
83
|
-
{@render children?.()}
|
|
84
|
-
</svelte:element>
|
|
85
|
-
{/if}
|
|
1
|
+
<script lang="ts" generics="T extends HtmlElementTagName">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { createAttachmentKey } from 'svelte/attachments';
|
|
5
|
+
import { cn, toClassValue } from '../../utils';
|
|
6
|
+
import type { ElementType, HtmlElementProps, HtmlElementTagName } from './types';
|
|
7
|
+
|
|
8
|
+
type Element = ElementType<T>;
|
|
9
|
+
|
|
10
|
+
let {
|
|
11
|
+
class: klass = '',
|
|
12
|
+
as = 'div' as T,
|
|
13
|
+
global = true,
|
|
14
|
+
initial = undefined,
|
|
15
|
+
enter = undefined,
|
|
16
|
+
exit = undefined,
|
|
17
|
+
animate = undefined,
|
|
18
|
+
onmount = undefined,
|
|
19
|
+
ondestroy = undefined,
|
|
20
|
+
children = undefined,
|
|
21
|
+
...restProps
|
|
22
|
+
}: HtmlElementProps<T> & Omit<HTMLAttributes<Element>, keyof HtmlElementProps<T>> = $props();
|
|
23
|
+
|
|
24
|
+
let node = $state<Element>();
|
|
25
|
+
|
|
26
|
+
let skipFirstAnimate = $state(!!enter);
|
|
27
|
+
|
|
28
|
+
$effect(() => {
|
|
29
|
+
if (!node) return;
|
|
30
|
+
|
|
31
|
+
const unmount = untrack(() => onmount?.(node!));
|
|
32
|
+
|
|
33
|
+
return () => {
|
|
34
|
+
if (typeof unmount === 'function') unmount(node!);
|
|
35
|
+
ondestroy?.(node!);
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
$effect(() => {
|
|
40
|
+
const fn = animate;
|
|
41
|
+
|
|
42
|
+
if (!node) return;
|
|
43
|
+
const shouldSkip = untrack(() => skipFirstAnimate);
|
|
44
|
+
|
|
45
|
+
if (shouldSkip) {
|
|
46
|
+
skipFirstAnimate = false;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fn?.(node);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const elementProps = $derived({
|
|
54
|
+
[createAttachmentKey()]: (n: Element) => {
|
|
55
|
+
node = n;
|
|
56
|
+
},
|
|
57
|
+
class: cn(toClassValue(klass)),
|
|
58
|
+
...restProps
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
function _enter(node: Element) {
|
|
62
|
+
initial?.(node);
|
|
63
|
+
return () => {
|
|
64
|
+
const { duration = 0, delay = 0, easing = undefined } = enter?.(node) ?? {};
|
|
65
|
+
return { duration, delay, easing };
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function _exit(node: Element) {
|
|
70
|
+
return () => {
|
|
71
|
+
const { duration = 0, delay = 0, easing = undefined } = exit?.(node) ?? {};
|
|
72
|
+
return { duration, delay, easing };
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
{#if global}
|
|
78
|
+
<svelte:element this={as} in:_enter|global out:_exit|global {...elementProps}>
|
|
79
|
+
{@render children?.()}
|
|
80
|
+
</svelte:element>
|
|
81
|
+
{:else}
|
|
82
|
+
<svelte:element this={as} in:_enter out:_exit {...elementProps}>
|
|
83
|
+
{@render children?.()}
|
|
84
|
+
</svelte:element>
|
|
85
|
+
{/if}
|
|
@@ -12,7 +12,7 @@ export interface ElementProps<T extends ElementTagName> extends Record<string, u
|
|
|
12
12
|
animate?: NodeFunction<T>;
|
|
13
13
|
onmount?: NodeFunction<T>;
|
|
14
14
|
ondestroy?: NodeFunction<T>;
|
|
15
|
-
children?: Snippet
|
|
15
|
+
children?: Snippet<unknown[]>;
|
|
16
16
|
[key: string]: unknown;
|
|
17
17
|
}
|
|
18
18
|
export type HtmlElementTagName = keyof HTMLElementTagNameMap;
|
package/dist/components/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Lazy } from './lazy.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Lazy } from './lazy.svelte';
|