@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
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Bond } from '../../shared';
|
|
10
10
|
import SnippetRenderer from './snippet-renderer.svelte';
|
|
11
11
|
import type { Component } from 'svelte';
|
|
12
|
+
import { call } from '../../utils/function';
|
|
12
13
|
|
|
13
14
|
type Element = HTMLElementTagNameMap[E];
|
|
14
15
|
|
|
@@ -25,9 +26,20 @@
|
|
|
25
26
|
...restProps
|
|
26
27
|
}: HtmlAtomProps<E, B> & Omit<HTMLAttributes<Element>, 'children'> = $props();
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Resolve variant definition to props
|
|
31
|
+
*/
|
|
32
|
+
// Cache for resolved variants to avoid recomputation
|
|
33
|
+
// Key: JSON stringified combination of variant props
|
|
34
|
+
const variantCache = new Map<string, Record<string, any>>();
|
|
35
|
+
|
|
36
|
+
// Memoize preset resolution - only recompute when presetKey or bond changes
|
|
37
|
+
const preset = $derived.by(() => {
|
|
38
|
+
if (!presetKey) return undefined;
|
|
39
|
+
const result = getPreset(presetKey as PresetModuleName)?.apply?.(bond, [bond]);
|
|
40
|
+
// Handle deferred preset result (factory function)
|
|
41
|
+
return call(result);
|
|
42
|
+
});
|
|
31
43
|
|
|
32
44
|
const presetProps = $derived(preset?.variants);
|
|
33
45
|
|
|
@@ -45,6 +57,7 @@
|
|
|
45
57
|
});
|
|
46
58
|
|
|
47
59
|
// Merge preset variants with local variants
|
|
60
|
+
// Memoized to avoid recomputation when inputs haven't changed
|
|
48
61
|
const mergedVariants = $derived.by(() => {
|
|
49
62
|
// No variants at all
|
|
50
63
|
if (!presetProps && !localVariants) return undefined;
|
|
@@ -52,8 +65,8 @@
|
|
|
52
65
|
// Only preset variants (raw object from preset)
|
|
53
66
|
if (presetProps && !localVariants) {
|
|
54
67
|
// Convert preset variants to VariantDefinition-like structure
|
|
55
|
-
const variantDef = {
|
|
56
|
-
class: preset?.class,
|
|
68
|
+
const variantDef: VariantDefinition<any> = {
|
|
69
|
+
class: preset?.class ?? '',
|
|
57
70
|
variants: presetProps,
|
|
58
71
|
compounds: preset?.compounds ?? [],
|
|
59
72
|
defaults: preset?.defaults ?? {}
|
|
@@ -68,9 +81,9 @@
|
|
|
68
81
|
|
|
69
82
|
// Both exist - merge them
|
|
70
83
|
// When both preset and local variants exist, we need to merge the resolved props
|
|
71
|
-
const presetVariantDef = {
|
|
72
|
-
class: preset?.class,
|
|
73
|
-
variants: presetProps,
|
|
84
|
+
const presetVariantDef: VariantDefinition<any> = {
|
|
85
|
+
class: preset?.class ?? '',
|
|
86
|
+
variants: presetProps ?? {},
|
|
74
87
|
compounds: preset?.compounds ?? [],
|
|
75
88
|
defaults: preset?.defaults ?? {}
|
|
76
89
|
};
|
|
@@ -93,9 +106,31 @@
|
|
|
93
106
|
};
|
|
94
107
|
});
|
|
95
108
|
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
)
|
|
109
|
+
const presetClassString = $derived(cn(preset?.class));
|
|
110
|
+
|
|
111
|
+
const _klass = $derived.by(() => {
|
|
112
|
+
const klassStr = cn(klass ?? '');
|
|
113
|
+
// Check for $preset placeholder first
|
|
114
|
+
if (!klassStr.includes('$preset')) {
|
|
115
|
+
// No placeholder - normal merge: variants override direct class
|
|
116
|
+
return cn(klass, mergedVariants?.class ?? '');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Has placeholder - calculate position and inject preset classes
|
|
120
|
+
const parts = klassStr.split('$preset');
|
|
121
|
+
|
|
122
|
+
// Only keep the last $preset placeholder
|
|
123
|
+
const beforeLastPlaceholder = parts.slice(0, -1).join('');
|
|
124
|
+
const afterLastPlaceholder = parts[parts.length - 1];
|
|
125
|
+
|
|
126
|
+
// Merge: before + preset + variants + after
|
|
127
|
+
return cn(
|
|
128
|
+
beforeLastPlaceholder,
|
|
129
|
+
presetClassString,
|
|
130
|
+
mergedVariants?.class ?? '',
|
|
131
|
+
afterLastPlaceholder
|
|
132
|
+
);
|
|
133
|
+
});
|
|
99
134
|
|
|
100
135
|
const _base = $derived(base ?? preset?.base);
|
|
101
136
|
const _as = $derived(as ?? preset?.as);
|
|
@@ -131,9 +166,6 @@
|
|
|
131
166
|
};
|
|
132
167
|
}) as { component: Component; props: Record<string, any> };
|
|
133
168
|
|
|
134
|
-
/**
|
|
135
|
-
* Resolve variant definition to props
|
|
136
|
-
*/
|
|
137
169
|
function resolveVariants(
|
|
138
170
|
def: VariantDefinition<any>,
|
|
139
171
|
bond: Bond | null | undefined,
|
|
@@ -144,6 +176,18 @@
|
|
|
144
176
|
// Merge props with defaults
|
|
145
177
|
const finalProps = { ...defaults, ...props };
|
|
146
178
|
|
|
179
|
+
// Create cache key from final props (only variant-related props)
|
|
180
|
+
const variantKeys = variantMap ? Object.keys(variantMap) : [];
|
|
181
|
+
const relevantProps = Object.fromEntries(
|
|
182
|
+
Object.entries(finalProps).filter(([key]) => variantKeys.includes(key))
|
|
183
|
+
);
|
|
184
|
+
const cacheKey = JSON.stringify({ relevantProps, baseClass, compounds });
|
|
185
|
+
|
|
186
|
+
// Check cache
|
|
187
|
+
if (variantCache.has(cacheKey)) {
|
|
188
|
+
return variantCache.get(cacheKey)!;
|
|
189
|
+
}
|
|
190
|
+
|
|
147
191
|
const classes: ClassValue[] = [];
|
|
148
192
|
const attributes: Record<string, any> = {};
|
|
149
193
|
|
|
@@ -193,15 +237,25 @@
|
|
|
193
237
|
}
|
|
194
238
|
}
|
|
195
239
|
|
|
196
|
-
|
|
240
|
+
const result = {
|
|
197
241
|
class: classes,
|
|
198
242
|
...attributes
|
|
199
243
|
};
|
|
244
|
+
|
|
245
|
+
// Store in cache (limit cache size to prevent memory leaks)
|
|
246
|
+
if (variantCache.size > 100) {
|
|
247
|
+
// Clear oldest entry (first in Map)
|
|
248
|
+
const firstKey = variantCache.keys().next().value;
|
|
249
|
+
if (firstKey) variantCache.delete(firstKey);
|
|
250
|
+
}
|
|
251
|
+
variantCache.set(cacheKey, result);
|
|
252
|
+
|
|
253
|
+
return result;
|
|
200
254
|
}
|
|
201
255
|
</script>
|
|
202
256
|
|
|
203
257
|
<renderer.component {...renderer.props}>
|
|
204
|
-
{#snippet children(args)}
|
|
205
|
-
{@render childrenProp?.(args)}
|
|
258
|
+
{#snippet children(args: any)}
|
|
259
|
+
{@render (childrenProp as any)?.(args)}
|
|
206
260
|
{/snippet}
|
|
207
261
|
</renderer.component>
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
-
import AvatarCmp from './avatar.svelte';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/>
|
|
24
|
-
</div>
|
|
25
|
-
{/snippet}
|
|
26
|
-
</Root>
|
|
27
|
-
</Story>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import AvatarCmp from './avatar.svelte';
|
|
4
|
+
import CalendarRegularIcon from '../../icons/icon-arrow-down.svelte';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'ATOMS/Avatar'
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<Story name="Avatar">
|
|
12
|
+
<div class="flex h-full w-full items-center justify-center gap-4">
|
|
13
|
+
<AvatarCmp alt="Abdelhalim Riache" />
|
|
14
|
+
|
|
15
|
+
<AvatarCmp src={CalendarRegularIcon} alt="Abdelhalim Riache" />
|
|
16
|
+
|
|
17
|
+
<AvatarCmp
|
|
18
|
+
src="https://sevennaturalwonders.org/wp-content/uploads/2023/12/1-Mount-Fuji.jpg"
|
|
19
|
+
alt="Mount Fuji"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
</Story>
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
{#snippet children({ args })}
|
|
14
|
-
<BadgeModule>Badge</BadgeModule>
|
|
15
|
-
{/snippet}
|
|
16
|
-
</Root>
|
|
17
|
-
</Story>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import { Badge as BadgeModule } from '.';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'ATOMS/Badge'
|
|
7
|
+
});
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Story name="Badge">
|
|
11
|
+
<BadgeModule>Badge</BadgeModule>
|
|
12
|
+
</Story>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { HtmlAtom } from '../atom';
|
|
3
|
-
import type { BadgeProps } from './types';
|
|
4
|
-
|
|
5
|
-
let { class: klass = '', as = 'span', children = undefined, ...restProps }: BadgeProps = $props();
|
|
6
|
-
</script>
|
|
7
|
-
|
|
8
|
-
<HtmlAtom
|
|
9
|
-
preset="badge"
|
|
10
|
-
class={[
|
|
11
|
-
'bg-foreground/10 border-border text-foreground inline-flex h-auto items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
|
|
12
|
-
'$preset',
|
|
13
|
-
klass
|
|
14
|
-
]}
|
|
15
|
-
{as}
|
|
16
|
-
{...restProps}
|
|
17
|
-
>
|
|
18
|
-
{@render children?.()}
|
|
19
|
-
</HtmlAtom>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { HtmlAtom } from '../atom';
|
|
3
|
+
import type { BadgeProps } from './types';
|
|
4
|
+
|
|
5
|
+
let { class: klass = '', as = 'span', children = undefined, ...restProps }: BadgeProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<HtmlAtom
|
|
9
|
+
preset="badge"
|
|
10
|
+
class={[
|
|
11
|
+
'bg-foreground/10 border-border text-foreground inline-flex h-auto w-fit items-center rounded-full px-2.5 py-0.5 text-xs font-medium',
|
|
12
|
+
'$preset',
|
|
13
|
+
klass
|
|
14
|
+
]}
|
|
15
|
+
{as}
|
|
16
|
+
{...restProps}
|
|
17
|
+
>
|
|
18
|
+
{@render children?.()}
|
|
19
|
+
</HtmlAtom>
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<BreadcrumbModule.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<BreadcrumbModule.Item href="/vehicles">Vehicles</BreadcrumbModule.Item>
|
|
18
|
-
</BreadcrumbModule.Root>
|
|
19
|
-
{/snippet}
|
|
20
|
-
</Root>
|
|
21
|
-
</Story>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import { Breadcrumb as BreadcrumbModule } from '.';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'ATOMS/Breadcrumb'
|
|
7
|
+
});
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<Story name="Breadcrumb">
|
|
11
|
+
<BreadcrumbModule.Root>
|
|
12
|
+
<BreadcrumbModule.Item href="/">Home</BreadcrumbModule.Item>
|
|
13
|
+
<BreadcrumbModule.Separator>/</BreadcrumbModule.Separator>
|
|
14
|
+
<BreadcrumbModule.Item href="/vehicles">Vehicles</BreadcrumbModule.Item>
|
|
15
|
+
</BreadcrumbModule.Root>
|
|
16
|
+
</Story>
|
|
@@ -1,60 +1,27 @@
|
|
|
1
|
-
<script module>
|
|
2
|
-
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
secondary: {
|
|
30
|
-
class:
|
|
31
|
-
'bg-secondary text-secondary-foreground hover:bg-secondary/80 active:bg-secondary/90'
|
|
32
|
-
},
|
|
33
|
-
destructive: {
|
|
34
|
-
class:
|
|
35
|
-
'bg-destructive text-destructive-foreground hover:bg-destructive/80 active:bg-destructive/90'
|
|
36
|
-
},
|
|
37
|
-
outline: {
|
|
38
|
-
class:
|
|
39
|
-
'bg-transparent hover:bg-foreground/5 active:bg-foreground/10 border border-border text-foreground'
|
|
40
|
-
},
|
|
41
|
-
ghost: {
|
|
42
|
-
class:
|
|
43
|
-
'bg-transparent text-foreground hover:bg-foreground/5 active:bg-foreground/10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2'
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
compounds: [],
|
|
48
|
-
defaults: {
|
|
49
|
-
variant: 'destructive'
|
|
50
|
-
}
|
|
51
|
-
}));
|
|
52
|
-
</script>
|
|
53
|
-
|
|
54
|
-
<Story name="Button">
|
|
55
|
-
{#snippet template(args)}
|
|
56
|
-
<Root class="p-4">
|
|
57
|
-
<ButtonCmp {variants} {...args}>Clicke me</ButtonCmp>
|
|
58
|
-
</Root>
|
|
59
|
-
{/snippet}
|
|
60
|
-
</Story>
|
|
1
|
+
<script module>
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import ButtonCmp from './button.svelte';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'ATOMS/Button',
|
|
7
|
+
argTypes: {
|
|
8
|
+
variant: {
|
|
9
|
+
control: 'select',
|
|
10
|
+
options: ['primary', 'secondary', 'destructive', 'outline', 'ghost'],
|
|
11
|
+
description: 'Button variant style',
|
|
12
|
+
table: {
|
|
13
|
+
defaultValue: { summary: 'primary' }
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<script lang="ts">
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<Story name="Button">
|
|
24
|
+
{#snippet template(args)}
|
|
25
|
+
<ButtonCmp {...args}>Click me</ButtonCmp>
|
|
26
|
+
{/snippet}
|
|
27
|
+
</Story>
|
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { isBefore, isSameDay, isWithinInterval } from 'date-fns';
|
|
3
|
-
import { CalendarBond } from './bond.svelte';
|
|
4
|
-
import type { CalendarDayProps } from './types';
|
|
5
|
-
import { HtmlAtom } from '../atom';
|
|
6
|
-
|
|
7
|
-
const calendarBond = CalendarBond.get();
|
|
8
|
-
|
|
9
|
-
const selectedDateStart = $derived(calendarBond?.state.props.start);
|
|
10
|
-
const selectedDateEnd = $derived(calendarBond?.state.props.end);
|
|
11
|
-
const isRange = $derived(Array.isArray(calendarBond?.state.props.type === 'range'));
|
|
12
|
-
|
|
13
|
-
let {
|
|
14
|
-
class: klass = '',
|
|
15
|
-
preset = 'calendar.day',
|
|
16
|
-
day,
|
|
17
|
-
as = 'button',
|
|
18
|
-
children = undefined,
|
|
19
|
-
onclick = handleClick,
|
|
20
|
-
...restProps
|
|
21
|
-
}: CalendarDayProps = $props();
|
|
22
|
-
|
|
23
|
-
const dayProps = $derived({
|
|
24
|
-
...calendarBond?.day(day),
|
|
25
|
-
...restProps
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const isSelected = $derived.by(() => {
|
|
29
|
-
if (selectedDateEnd && selectedDateStart) {
|
|
30
|
-
return isWithinInterval(day.date, { end: selectedDateEnd, start: selectedDateStart });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return selectedDateStart && isSameDay(day.date, selectedDateStart);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
function handleClick() {
|
|
37
|
-
if (isRange) {
|
|
38
|
-
const start = calendarBond?.state.props.start;
|
|
39
|
-
if (!start) {
|
|
40
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (isBefore(new Date(day.date), new Date(start))) {
|
|
45
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
calendarBond?.state.selectEnd(new Date(day.date));
|
|
50
|
-
} else {
|
|
51
|
-
calendarBond?.state.selectStart(new Date(day.date));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
<HtmlAtom
|
|
57
|
-
{as}
|
|
58
|
-
{preset}
|
|
59
|
-
class={[
|
|
60
|
-
'calendar-day text-foreground border-border hover:bg-accent hover:text-accent-foreground h-12 cursor-pointer border-b border-l p-1 transition-colors',
|
|
61
|
-
day.offmonth && 'text-muted-foreground bg-muted/30',
|
|
62
|
-
day.weekend && 'bg-muted/50',
|
|
63
|
-
isSelected &&
|
|
64
|
-
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground',
|
|
65
|
-
isSelected && day.offmonth && 'bg-primary/70',
|
|
66
|
-
day.today && !isSelected && 'border-primary border-2 font-semibold',
|
|
67
|
-
day.disabled && 'pointer-events-none opacity-50',
|
|
68
|
-
klass
|
|
69
|
-
]}
|
|
70
|
-
data-disabled={day.disabled}
|
|
71
|
-
data-prec={day.fromPreviousMonth}
|
|
72
|
-
data-next={day.fromNextMonth}
|
|
73
|
-
data-offmonth={day.offmonth}
|
|
74
|
-
data-weekend={day.weekend}
|
|
75
|
-
data-today={day.today}
|
|
76
|
-
data-selected={isSelected}
|
|
77
|
-
{onclick}
|
|
78
|
-
{...dayProps}
|
|
79
|
-
>
|
|
80
|
-
{#if children}
|
|
81
|
-
{@render children({
|
|
82
|
-
calendar: calendarBond!
|
|
83
|
-
})}
|
|
84
|
-
{:else}
|
|
85
|
-
<span class="value">{day.dayOfMonth}</span>
|
|
86
|
-
{/if}
|
|
87
|
-
</HtmlAtom>
|
|
88
|
-
|
|
89
|
-
<style>
|
|
90
|
-
:global(.calendar-day):nth-child(7n + 1) {
|
|
91
|
-
border-left: none;
|
|
92
|
-
}
|
|
93
|
-
:global(.calendar-day):nth-last-child(-n + 7) {
|
|
94
|
-
border-bottom: none;
|
|
95
|
-
}
|
|
96
|
-
</style>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { isBefore, isSameDay, isWithinInterval } from 'date-fns';
|
|
3
|
+
import { CalendarBond } from './bond.svelte';
|
|
4
|
+
import type { CalendarDayProps } from './types';
|
|
5
|
+
import { HtmlAtom } from '../atom';
|
|
6
|
+
|
|
7
|
+
const calendarBond = CalendarBond.get();
|
|
8
|
+
|
|
9
|
+
const selectedDateStart = $derived(calendarBond?.state.props.start);
|
|
10
|
+
const selectedDateEnd = $derived(calendarBond?.state.props.end);
|
|
11
|
+
const isRange = $derived(Array.isArray(calendarBond?.state.props.type === 'range'));
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
class: klass = '',
|
|
15
|
+
preset = 'calendar.day',
|
|
16
|
+
day,
|
|
17
|
+
as = 'button',
|
|
18
|
+
children = undefined,
|
|
19
|
+
onclick = handleClick,
|
|
20
|
+
...restProps
|
|
21
|
+
}: CalendarDayProps = $props();
|
|
22
|
+
|
|
23
|
+
const dayProps = $derived({
|
|
24
|
+
...calendarBond?.day(day),
|
|
25
|
+
...restProps
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const isSelected = $derived.by(() => {
|
|
29
|
+
if (selectedDateEnd && selectedDateStart) {
|
|
30
|
+
return isWithinInterval(day.date, { end: selectedDateEnd, start: selectedDateStart });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return selectedDateStart && isSameDay(day.date, selectedDateStart);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
function handleClick() {
|
|
37
|
+
if (isRange) {
|
|
38
|
+
const start = calendarBond?.state.props.start;
|
|
39
|
+
if (!start) {
|
|
40
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (isBefore(new Date(day.date), new Date(start))) {
|
|
45
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
calendarBond?.state.selectEnd(new Date(day.date));
|
|
50
|
+
} else {
|
|
51
|
+
calendarBond?.state.selectStart(new Date(day.date));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<HtmlAtom
|
|
57
|
+
{as}
|
|
58
|
+
{preset}
|
|
59
|
+
class={[
|
|
60
|
+
'calendar-day text-foreground border-border hover:bg-accent hover:text-accent-foreground h-12 cursor-pointer border-b border-l p-1 transition-colors',
|
|
61
|
+
day.offmonth && 'text-muted-foreground bg-muted/30',
|
|
62
|
+
day.weekend && 'bg-muted/50',
|
|
63
|
+
isSelected &&
|
|
64
|
+
'bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground',
|
|
65
|
+
isSelected && day.offmonth && 'bg-primary/70',
|
|
66
|
+
day.today && !isSelected && 'border-primary border-2 font-semibold',
|
|
67
|
+
day.disabled && 'pointer-events-none opacity-50',
|
|
68
|
+
klass
|
|
69
|
+
]}
|
|
70
|
+
data-disabled={day.disabled}
|
|
71
|
+
data-prec={day.fromPreviousMonth}
|
|
72
|
+
data-next={day.fromNextMonth}
|
|
73
|
+
data-offmonth={day.offmonth}
|
|
74
|
+
data-weekend={day.weekend}
|
|
75
|
+
data-today={day.today}
|
|
76
|
+
data-selected={isSelected}
|
|
77
|
+
{onclick}
|
|
78
|
+
{...dayProps}
|
|
79
|
+
>
|
|
80
|
+
{#if children}
|
|
81
|
+
{@render children({
|
|
82
|
+
calendar: calendarBond!
|
|
83
|
+
})}
|
|
84
|
+
{:else}
|
|
85
|
+
<span class="value">{day.dayOfMonth}</span>
|
|
86
|
+
{/if}
|
|
87
|
+
</HtmlAtom>
|
|
88
|
+
|
|
89
|
+
<style>
|
|
90
|
+
:global(.calendar-day):nth-child(7n + 1) {
|
|
91
|
+
border-left: none;
|
|
92
|
+
}
|
|
93
|
+
:global(.calendar-day):nth-last-child(-n + 7) {
|
|
94
|
+
border-bottom: none;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { cn } from '../../utils';
|
|
3
|
-
import { HtmlAtom } from '../atom';
|
|
4
|
-
import { CalendarBond } from './bond.svelte';
|
|
5
|
-
import CalendarWeekDay from './calendar-week-day.svelte';
|
|
6
|
-
|
|
7
|
-
const calendarBond = CalendarBond.get();
|
|
8
|
-
const currentMonth = $derived(calendarBond?.state.props.currentMonth);
|
|
9
|
-
|
|
10
|
-
let { class: klass = '', preset = 'calendar.header', ...restProps } = $props();
|
|
11
|
-
|
|
12
|
-
const headerProps = $derived({
|
|
13
|
-
...calendarBond?.header(),
|
|
14
|
-
...restProps
|
|
15
|
-
});
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<HtmlAtom
|
|
19
|
-
{preset}
|
|
20
|
-
class={cn(
|
|
21
|
-
'calendar-header border-border col-span-full grid h-fit grid-cols-subgrid border-b',
|
|
22
|
-
klass
|
|
23
|
-
)}
|
|
24
|
-
{...headerProps}
|
|
25
|
-
>
|
|
26
|
-
{#each (currentMonth?.days ?? []).filter((d) => d.week == 1) as day}
|
|
27
|
-
<CalendarWeekDay isWeekend={day.weekend}>{day.name}</CalendarWeekDay>
|
|
28
|
-
{/each}
|
|
29
|
-
</HtmlAtom>
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from '../../utils';
|
|
3
|
+
import { HtmlAtom } from '../atom';
|
|
4
|
+
import { CalendarBond } from './bond.svelte';
|
|
5
|
+
import CalendarWeekDay from './calendar-week-day.svelte';
|
|
6
|
+
|
|
7
|
+
const calendarBond = CalendarBond.get();
|
|
8
|
+
const currentMonth = $derived(calendarBond?.state.props.currentMonth);
|
|
9
|
+
|
|
10
|
+
let { class: klass = '', preset = 'calendar.header', ...restProps } = $props();
|
|
11
|
+
|
|
12
|
+
const headerProps = $derived({
|
|
13
|
+
...calendarBond?.header(),
|
|
14
|
+
...restProps
|
|
15
|
+
});
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<HtmlAtom
|
|
19
|
+
{preset}
|
|
20
|
+
class={cn(
|
|
21
|
+
'calendar-header border-border col-span-full grid h-fit grid-cols-subgrid border-b',
|
|
22
|
+
klass
|
|
23
|
+
)}
|
|
24
|
+
{...headerProps}
|
|
25
|
+
>
|
|
26
|
+
{#each (currentMonth?.days ?? []).filter((d) => d.week == 1) as day}
|
|
27
|
+
<CalendarWeekDay isWeekend={day.weekend}>{day.name}</CalendarWeekDay>
|
|
28
|
+
{/each}
|
|
29
|
+
</HtmlAtom>
|