svelora 3.0.5 → 3.0.7
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/dist/BentoGrid/BentoCard.svelte +45 -0
- package/dist/BentoGrid/BentoCard.svelte.d.ts +4 -0
- package/dist/BentoGrid/BentoGrid.svelte +9 -0
- package/dist/BentoGrid/BentoGrid.svelte.d.ts +4 -0
- package/dist/BentoGrid/bento-grid.types.d.ts +47 -0
- package/dist/BentoGrid/bento-grid.types.js +1 -0
- package/dist/BentoGrid/bento-grid.variants.d.ts +30 -0
- package/dist/BentoGrid/bento-grid.variants.js +16 -0
- package/dist/BentoGrid/index.d.ts +5 -0
- package/dist/BentoGrid/index.js +5 -0
- package/dist/Chart/Chart.svelte +47 -0
- package/dist/Chart/Chart.svelte.d.ts +4 -0
- package/dist/Chart/chart.types.d.ts +20 -0
- package/dist/Chart/chart.types.js +1 -0
- package/dist/Chart/chart.variants.d.ts +3 -0
- package/dist/Chart/chart.variants.js +4 -0
- package/dist/Chart/index.d.ts +4 -0
- package/dist/Chart/index.js +4 -0
- package/dist/Chat/ChatBubble.svelte +30 -0
- package/dist/Chat/ChatBubble.svelte.d.ts +4 -0
- package/dist/Chat/ChatInput.svelte +50 -0
- package/dist/Chat/ChatInput.svelte.d.ts +4 -0
- package/dist/Chat/ChatMessage.svelte +15 -0
- package/dist/Chat/ChatMessage.svelte.d.ts +4 -0
- package/dist/Chat/chat.types.d.ts +63 -0
- package/dist/Chat/chat.types.js +1 -0
- package/dist/Chat/chat.variants.d.ts +117 -0
- package/dist/Chat/chat.variants.js +47 -0
- package/dist/Chat/index.d.ts +6 -0
- package/dist/Chat/index.js +6 -0
- package/dist/ColorPicker/ColorPicker.svelte +109 -0
- package/dist/ColorPicker/ColorPicker.svelte.d.ts +4 -0
- package/dist/ColorPicker/color-picker.types.d.ts +26 -0
- package/dist/ColorPicker/color-picker.types.js +1 -0
- package/dist/ColorPicker/color-picker.variants.d.ts +69 -0
- package/dist/ColorPicker/color-picker.variants.js +13 -0
- package/dist/ColorPicker/index.d.ts +4 -0
- package/dist/ColorPicker/index.js +4 -0
- package/dist/DateRangePicker/DateRangePicker.svelte +59 -0
- package/dist/DateRangePicker/DateRangePicker.svelte.d.ts +4 -0
- package/dist/DateRangePicker/date-range-picker.types.d.ts +34 -0
- package/dist/DateRangePicker/date-range-picker.types.js +1 -0
- package/dist/DateRangePicker/date-range-picker.variants.d.ts +39 -0
- package/dist/DateRangePicker/date-range-picker.variants.js +20 -0
- package/dist/DateRangePicker/index.d.ts +4 -0
- package/dist/DateRangePicker/index.js +4 -0
- package/dist/Fonts/fonts.js +3 -1
- package/dist/Link/Link.context-harness.svelte +8 -0
- package/dist/Link/Link.context-harness.svelte.d.ts +7 -0
- package/dist/Link/Link.svelte +57 -30
- package/dist/Link/index.d.ts +2 -0
- package/dist/Link/index.js +1 -0
- package/dist/Link/location-context.d.ts +4 -0
- package/dist/Link/location-context.js +1 -0
- package/dist/List/List.svelte +14 -0
- package/dist/List/List.svelte.d.ts +4 -0
- package/dist/List/ListItem.svelte +64 -0
- package/dist/List/ListItem.svelte.d.ts +4 -0
- package/dist/List/index.d.ts +5 -0
- package/dist/List/index.js +5 -0
- package/dist/List/list.types.d.ts +62 -0
- package/dist/List/list.types.js +1 -0
- package/dist/List/list.variants.d.ts +99 -0
- package/dist/List/list.variants.js +42 -0
- package/dist/Marquee/Marquee.svelte +50 -0
- package/dist/Marquee/Marquee.svelte.d.ts +4 -0
- package/dist/Marquee/index.d.ts +4 -0
- package/dist/Marquee/index.js +4 -0
- package/dist/Marquee/marquee.types.d.ts +38 -0
- package/dist/Marquee/marquee.types.js +1 -0
- package/dist/Marquee/marquee.variants.d.ts +78 -0
- package/dist/Marquee/marquee.variants.js +28 -0
- package/dist/Menu/Menu.svelte +134 -0
- package/dist/Menu/Menu.svelte.d.ts +4 -0
- package/dist/Menu/index.d.ts +4 -0
- package/dist/Menu/index.js +4 -0
- package/dist/Menu/menu.types.d.ts +82 -0
- package/dist/Menu/menu.types.js +1 -0
- package/dist/Menu/menu.variants.d.ts +46 -0
- package/dist/Menu/menu.variants.js +32 -0
- package/dist/NumberTicker/NumberTicker.svelte +59 -0
- package/dist/NumberTicker/NumberTicker.svelte.d.ts +4 -0
- package/dist/NumberTicker/index.d.ts +4 -0
- package/dist/NumberTicker/index.js +4 -0
- package/dist/NumberTicker/number-ticker.types.d.ts +26 -0
- package/dist/NumberTicker/number-ticker.types.js +1 -0
- package/dist/NumberTicker/number-ticker.variants.d.ts +27 -0
- package/dist/NumberTicker/number-ticker.variants.js +6 -0
- package/dist/PasswordInput/PasswordInput.svelte +74 -0
- package/dist/PasswordInput/PasswordInput.svelte.d.ts +4 -0
- package/dist/PasswordInput/index.d.ts +4 -0
- package/dist/PasswordInput/index.js +4 -0
- package/dist/PasswordInput/password-input.types.d.ts +18 -0
- package/dist/PasswordInput/password-input.types.js +1 -0
- package/dist/PasswordInput/password-input.variants.d.ts +57 -0
- package/dist/PasswordInput/password-input.variants.js +11 -0
- package/dist/Prose/Prose.svelte +13 -0
- package/dist/Prose/Prose.svelte.d.ts +4 -0
- package/dist/Prose/index.d.ts +4 -0
- package/dist/Prose/index.js +4 -0
- package/dist/Prose/prose.types.d.ts +22 -0
- package/dist/Prose/prose.types.js +1 -0
- package/dist/Prose/prose.variants.d.ts +45 -0
- package/dist/Prose/prose.variants.js +45 -0
- package/dist/Rating/Rating.svelte +93 -0
- package/dist/Rating/Rating.svelte.d.ts +4 -0
- package/dist/Rating/index.d.ts +4 -0
- package/dist/Rating/index.js +4 -0
- package/dist/Rating/rating.types.d.ts +59 -0
- package/dist/Rating/rating.types.js +1 -0
- package/dist/Rating/rating.variants.d.ts +93 -0
- package/dist/Rating/rating.variants.js +32 -0
- package/dist/Resizable/Resizable.svelte +9 -0
- package/dist/Resizable/Resizable.svelte.d.ts +4 -0
- package/dist/Resizable/index.d.ts +4 -0
- package/dist/Resizable/index.js +4 -0
- package/dist/Resizable/resizable.types.d.ts +18 -0
- package/dist/Resizable/resizable.types.js +1 -0
- package/dist/Resizable/resizable.variants.d.ts +48 -0
- package/dist/Resizable/resizable.variants.js +17 -0
- package/dist/ScrollArea/ScrollArea.svelte +54 -0
- package/dist/ScrollArea/ScrollArea.svelte.d.ts +4 -0
- package/dist/ScrollArea/index.d.ts +4 -0
- package/dist/ScrollArea/index.js +4 -0
- package/dist/ScrollArea/scroll-area.types.d.ts +27 -0
- package/dist/ScrollArea/scroll-area.types.js +1 -0
- package/dist/ScrollArea/scroll-area.variants.d.ts +45 -0
- package/dist/ScrollArea/scroll-area.variants.js +27 -0
- package/dist/SelectMenu/SelectMenu.svelte +46 -14
- package/dist/Sidebar/Sidebar.svelte +30 -0
- package/dist/Sidebar/Sidebar.svelte.d.ts +4 -0
- package/dist/Sidebar/index.d.ts +4 -0
- package/dist/Sidebar/index.js +4 -0
- package/dist/Sidebar/sidebar.types.d.ts +31 -0
- package/dist/Sidebar/sidebar.types.js +1 -0
- package/dist/Sidebar/sidebar.variants.d.ts +69 -0
- package/dist/Sidebar/sidebar.variants.js +23 -0
- package/dist/Spotlight/Spotlight.svelte +31 -0
- package/dist/Spotlight/Spotlight.svelte.d.ts +4 -0
- package/dist/Spotlight/index.d.ts +4 -0
- package/dist/Spotlight/index.js +4 -0
- package/dist/Spotlight/spotlight.types.d.ts +22 -0
- package/dist/Spotlight/spotlight.types.js +1 -0
- package/dist/Spotlight/spotlight.variants.d.ts +39 -0
- package/dist/Spotlight/spotlight.variants.js +8 -0
- package/dist/Stepper/Stepper.svelte +12 -9
- package/dist/TagsInput/TagsInput.svelte +100 -0
- package/dist/TagsInput/TagsInput.svelte.d.ts +4 -0
- package/dist/TagsInput/index.d.ts +4 -0
- package/dist/TagsInput/index.js +4 -0
- package/dist/TagsInput/tags-input.types.d.ts +32 -0
- package/dist/TagsInput/tags-input.types.js +1 -0
- package/dist/TagsInput/tags-input.variants.d.ts +45 -0
- package/dist/TagsInput/tags-input.variants.js +22 -0
- package/dist/TreeView/TreeView.svelte +95 -0
- package/dist/TreeView/TreeView.svelte.d.ts +4 -0
- package/dist/TreeView/index.d.ts +4 -0
- package/dist/TreeView/index.js +4 -0
- package/dist/TreeView/tree-view.types.d.ts +68 -0
- package/dist/TreeView/tree-view.types.js +1 -0
- package/dist/TreeView/tree-view.variants.d.ts +69 -0
- package/dist/TreeView/tree-view.variants.js +30 -0
- package/dist/docs/navigation.js +162 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/index.js +9 -0
- package/dist/hooks/useDebouncedState.svelte.d.ts +30 -0
- package/dist/hooks/useDebouncedState.svelte.js +45 -0
- package/dist/hooks/useEventListener.svelte.d.ts +30 -0
- package/dist/hooks/useEventListener.svelte.js +16 -0
- package/dist/hooks/useFocusTrap.svelte.d.ts +42 -0
- package/dist/hooks/useFocusTrap.svelte.js +87 -0
- package/dist/hooks/useIntersectionObserver.svelte.d.ts +30 -0
- package/dist/hooks/useIntersectionObserver.svelte.js +46 -0
- package/dist/hooks/useLocalStorage.svelte.d.ts +39 -0
- package/dist/hooks/useLocalStorage.svelte.js +73 -0
- package/dist/hooks/useResizeObserver.svelte.d.ts +50 -0
- package/dist/hooks/useResizeObserver.svelte.js +71 -0
- package/dist/hooks/useScrollLock.svelte.d.ts +28 -0
- package/dist/hooks/useScrollLock.svelte.js +79 -0
- package/dist/hooks/useThrottle.svelte.d.ts +37 -0
- package/dist/hooks/useThrottle.svelte.js +72 -0
- package/dist/hooks/useTimers.svelte.d.ts +62 -0
- package/dist/hooks/useTimers.svelte.js +90 -0
- package/dist/hooks/utils.d.ts +1 -0
- package/dist/hooks/utils.js +3 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +18 -0
- package/dist/mcp/svelora-docs.data.json +59 -5
- package/package.json +8 -6
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">import { twMerge } from "tailwind-merge";
|
|
2
|
+
import { Popover } from "../Popover/index.js";
|
|
3
|
+
import { Input } from "../Input/index.js";
|
|
4
|
+
import Icon from "../Icon/Icon.svelte";
|
|
5
|
+
import { colorPickerVariants } from "./color-picker.variants.js";
|
|
6
|
+
let { value = $bindable("#000000"), placeholder = "Select color", swatches = [
|
|
7
|
+
"#ef4444",
|
|
8
|
+
"#f97316",
|
|
9
|
+
"#f59e0b",
|
|
10
|
+
"#eab308",
|
|
11
|
+
"#84cc16",
|
|
12
|
+
"#22c55e",
|
|
13
|
+
"#10b981",
|
|
14
|
+
"#14b8a6",
|
|
15
|
+
"#06b6d4",
|
|
16
|
+
"#0ea5e9",
|
|
17
|
+
"#3b82f6",
|
|
18
|
+
"#6366f1",
|
|
19
|
+
"#8b5cf6",
|
|
20
|
+
"#a855f7",
|
|
21
|
+
"#d946ef",
|
|
22
|
+
"#ec4899",
|
|
23
|
+
"#f43f5e",
|
|
24
|
+
"#ffffff",
|
|
25
|
+
"#94a3b8",
|
|
26
|
+
"#000000"
|
|
27
|
+
], disabled = false, class: className, ...restProps } = $props();
|
|
28
|
+
const styles = $derived(colorPickerVariants());
|
|
29
|
+
// Validate hex
|
|
30
|
+
let hexInput = $state(value);
|
|
31
|
+
$effect(() => {
|
|
32
|
+
hexInput = value;
|
|
33
|
+
});
|
|
34
|
+
function handleHexInput(e) {
|
|
35
|
+
const target = e.target;
|
|
36
|
+
let val = target.value;
|
|
37
|
+
if (!val.startsWith("#")) {
|
|
38
|
+
val = "#" + val;
|
|
39
|
+
}
|
|
40
|
+
hexInput = val;
|
|
41
|
+
// Basic hex validation regex (3, 4, 6, or 8 digits)
|
|
42
|
+
if (/^#([A-Fa-f0-9]{3,4}){1,2}$/.test(val)) {
|
|
43
|
+
value = val;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function setSwatch(swatch) {
|
|
47
|
+
value = swatch;
|
|
48
|
+
hexInput = swatch;
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<div class={twMerge(styles.base(), className)} {...restProps}>
|
|
53
|
+
<Popover>
|
|
54
|
+
{#snippet children({ open })}
|
|
55
|
+
<div
|
|
56
|
+
class={styles.trigger()}
|
|
57
|
+
aria-disabled={disabled}
|
|
58
|
+
>
|
|
59
|
+
<div
|
|
60
|
+
class={styles.colorIndicator()}
|
|
61
|
+
style="background-color: {value || '#000'};"
|
|
62
|
+
></div>
|
|
63
|
+
<span class="truncate flex-1 text-left text-on-surface">
|
|
64
|
+
{value || placeholder}
|
|
65
|
+
</span>
|
|
66
|
+
<Icon name="lucide:chevron-down" class="text-on-surface-variant w-4 h-4" />
|
|
67
|
+
</div>
|
|
68
|
+
{/snippet}
|
|
69
|
+
|
|
70
|
+
{#snippet content()}
|
|
71
|
+
<div class={styles.content()}>
|
|
72
|
+
<div class={styles.hexInputWrapper()}>
|
|
73
|
+
<span class="text-sm font-medium">Hex</span>
|
|
74
|
+
<Input
|
|
75
|
+
value={hexInput}
|
|
76
|
+
oninput={handleHexInput}
|
|
77
|
+
class="h-8 font-mono text-xs"
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class={styles.swatchGrid()}>
|
|
82
|
+
{#each swatches as swatch}
|
|
83
|
+
<button
|
|
84
|
+
type="button"
|
|
85
|
+
class={styles.swatch()}
|
|
86
|
+
style="background-color: {swatch};"
|
|
87
|
+
title={swatch}
|
|
88
|
+
aria-label={`Select color ${swatch}`}
|
|
89
|
+
onclick={() => setSwatch(swatch)}
|
|
90
|
+
></button>
|
|
91
|
+
{/each}
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="pt-2 border-t border-outline-variant flex flex-col gap-1">
|
|
95
|
+
<span class="text-xs text-on-surface-variant mb-1">Custom Color</span>
|
|
96
|
+
<!-- Native color picker wrapper -->
|
|
97
|
+
<label class="cursor-pointer relative overflow-hidden rounded-md border border-outline-variant w-full h-8 flex items-center justify-center bg-surface-container hover:bg-surface-container-high transition-colors">
|
|
98
|
+
<span class="text-xs font-medium z-10 pointer-events-none mix-blend-difference text-white">Pick Custom</span>
|
|
99
|
+
<input
|
|
100
|
+
type="color"
|
|
101
|
+
bind:value
|
|
102
|
+
class="absolute inset-0 opacity-0 w-full h-full cursor-pointer scale-150"
|
|
103
|
+
/>
|
|
104
|
+
</label>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
{/snippet}
|
|
108
|
+
</Popover>
|
|
109
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
export interface ColorPickerProps extends Omit<HTMLAttributes<HTMLDivElement>, 'value'> {
|
|
3
|
+
/**
|
|
4
|
+
* The bound color value (Hex format).
|
|
5
|
+
* @default '#000000'
|
|
6
|
+
*/
|
|
7
|
+
value?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Placeholder text when no color is selected.
|
|
10
|
+
* @default 'Select color'
|
|
11
|
+
*/
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Array of predefined color swatches.
|
|
15
|
+
*/
|
|
16
|
+
swatches?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* Whether the color picker is disabled.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Additional CSS classes.
|
|
24
|
+
*/
|
|
25
|
+
class?: string;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type VariantProps } from 'tailwind-variants';
|
|
2
|
+
export declare const colorPickerVariants: import("tailwind-variants").TVReturnType<{
|
|
3
|
+
[key: string]: {
|
|
4
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
5
|
+
base?: import("tailwind-merge").ClassNameValue;
|
|
6
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
7
|
+
trigger?: import("tailwind-merge").ClassNameValue;
|
|
8
|
+
colorIndicator?: import("tailwind-merge").ClassNameValue;
|
|
9
|
+
swatchGrid?: import("tailwind-merge").ClassNameValue;
|
|
10
|
+
swatch?: import("tailwind-merge").ClassNameValue;
|
|
11
|
+
nativeInput?: import("tailwind-merge").ClassNameValue;
|
|
12
|
+
hexInputWrapper?: import("tailwind-merge").ClassNameValue;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
[x: string]: {
|
|
17
|
+
[x: string]: import("tailwind-merge").ClassNameValue | {
|
|
18
|
+
base?: import("tailwind-merge").ClassNameValue;
|
|
19
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
20
|
+
trigger?: import("tailwind-merge").ClassNameValue;
|
|
21
|
+
colorIndicator?: import("tailwind-merge").ClassNameValue;
|
|
22
|
+
swatchGrid?: import("tailwind-merge").ClassNameValue;
|
|
23
|
+
swatch?: import("tailwind-merge").ClassNameValue;
|
|
24
|
+
nativeInput?: import("tailwind-merge").ClassNameValue;
|
|
25
|
+
hexInputWrapper?: import("tailwind-merge").ClassNameValue;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
} | {}, {
|
|
29
|
+
base: string;
|
|
30
|
+
trigger: string;
|
|
31
|
+
colorIndicator: string;
|
|
32
|
+
content: string;
|
|
33
|
+
swatchGrid: string;
|
|
34
|
+
swatch: string;
|
|
35
|
+
nativeInput: string;
|
|
36
|
+
hexInputWrapper: string;
|
|
37
|
+
}, undefined, {
|
|
38
|
+
[key: string]: {
|
|
39
|
+
[key: string]: import("tailwind-merge").ClassNameValue | {
|
|
40
|
+
base?: import("tailwind-merge").ClassNameValue;
|
|
41
|
+
content?: import("tailwind-merge").ClassNameValue;
|
|
42
|
+
trigger?: import("tailwind-merge").ClassNameValue;
|
|
43
|
+
colorIndicator?: import("tailwind-merge").ClassNameValue;
|
|
44
|
+
swatchGrid?: import("tailwind-merge").ClassNameValue;
|
|
45
|
+
swatch?: import("tailwind-merge").ClassNameValue;
|
|
46
|
+
nativeInput?: import("tailwind-merge").ClassNameValue;
|
|
47
|
+
hexInputWrapper?: import("tailwind-merge").ClassNameValue;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
} | {}, {
|
|
51
|
+
base: string;
|
|
52
|
+
trigger: string;
|
|
53
|
+
colorIndicator: string;
|
|
54
|
+
content: string;
|
|
55
|
+
swatchGrid: string;
|
|
56
|
+
swatch: string;
|
|
57
|
+
nativeInput: string;
|
|
58
|
+
hexInputWrapper: string;
|
|
59
|
+
}, import("tailwind-variants").TVReturnType<unknown, {
|
|
60
|
+
base: string;
|
|
61
|
+
trigger: string;
|
|
62
|
+
colorIndicator: string;
|
|
63
|
+
content: string;
|
|
64
|
+
swatchGrid: string;
|
|
65
|
+
swatch: string;
|
|
66
|
+
nativeInput: string;
|
|
67
|
+
hexInputWrapper: string;
|
|
68
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
69
|
+
export type ColorPickerVariantProps = VariantProps<typeof colorPickerVariants>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const colorPickerVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
base: 'relative inline-flex',
|
|
5
|
+
trigger: 'flex items-center gap-2 px-3 py-2 border border-outline-variant rounded-md bg-surface text-sm w-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
|
|
6
|
+
colorIndicator: 'w-5 h-5 rounded border border-outline/50 shrink-0',
|
|
7
|
+
content: 'w-64 p-3 flex flex-col gap-3 bg-surface border border-outline-variant rounded-md shadow-md',
|
|
8
|
+
swatchGrid: 'grid grid-cols-6 gap-2',
|
|
9
|
+
swatch: 'w-6 h-6 rounded border border-outline/50 cursor-pointer hover:scale-110 transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary',
|
|
10
|
+
nativeInput: 'w-full h-8 cursor-pointer rounded overflow-hidden',
|
|
11
|
+
hexInputWrapper: 'flex items-center gap-2'
|
|
12
|
+
}
|
|
13
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<script lang="ts">import { twMerge } from "tailwind-merge";
|
|
2
|
+
import { DateFormatter } from "@internationalized/date";
|
|
3
|
+
import Icon from "../Icon/Icon.svelte";
|
|
4
|
+
import Popover from "../Popover/Popover.svelte";
|
|
5
|
+
import Calendar from "../Calendar/Calendar.svelte";
|
|
6
|
+
import { dateRangePickerVariants } from "./date-range-picker.variants.js";
|
|
7
|
+
let { value = $bindable({
|
|
8
|
+
start: undefined,
|
|
9
|
+
end: undefined
|
|
10
|
+
}), placeholder = "Select date range", numberOfMonths = 2, disabled = false, class: className, onchange, ...restProps } = $props();
|
|
11
|
+
let styles = $derived(dateRangePickerVariants({ disabled }));
|
|
12
|
+
// Internal state for popover
|
|
13
|
+
let open = $state(false);
|
|
14
|
+
// Formatter for displaying dates
|
|
15
|
+
const df = new DateFormatter("en-US", { dateStyle: "medium" });
|
|
16
|
+
let displayText = $derived.by(() => {
|
|
17
|
+
if (value.start) {
|
|
18
|
+
if (value.end) {
|
|
19
|
+
return `${df.format(value.start.toDate("UTC"))} - ${df.format(value.end.toDate("UTC"))}`;
|
|
20
|
+
}
|
|
21
|
+
return df.format(value.start.toDate("UTC"));
|
|
22
|
+
}
|
|
23
|
+
return placeholder;
|
|
24
|
+
});
|
|
25
|
+
function handleDateChange(v) {
|
|
26
|
+
// Range calendar passes an object with start/end
|
|
27
|
+
const rangeValue = v;
|
|
28
|
+
value = rangeValue;
|
|
29
|
+
onchange?.(rangeValue);
|
|
30
|
+
}
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<Popover bind:open>
|
|
34
|
+
{#snippet children({ open })}
|
|
35
|
+
<button
|
|
36
|
+
type="button"
|
|
37
|
+
class={twMerge(styles.trigger() as string, className, !value.start && 'text-surface-500')}
|
|
38
|
+
{disabled}
|
|
39
|
+
{...restProps}
|
|
40
|
+
>
|
|
41
|
+
<div class="flex items-center gap-2 overflow-hidden">
|
|
42
|
+
<Icon name="lucide:calendar" class={styles.icon() as string} />
|
|
43
|
+
<span class={styles.triggerText() as string}>{displayText}</span>
|
|
44
|
+
</div>
|
|
45
|
+
<Icon name="lucide:chevron-down" class={styles.icon() as string} />
|
|
46
|
+
</button>
|
|
47
|
+
{/snippet}
|
|
48
|
+
|
|
49
|
+
{#snippet content()}
|
|
50
|
+
<div class={styles.popoverContent() as string}>
|
|
51
|
+
<Calendar
|
|
52
|
+
range={true}
|
|
53
|
+
value={value as any}
|
|
54
|
+
{numberOfMonths}
|
|
55
|
+
onValueChange={handleDateChange}
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
{/snippet}
|
|
59
|
+
</Popover>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { DateValue } from '@internationalized/date';
|
|
3
|
+
export interface DateRange {
|
|
4
|
+
start: DateValue | undefined;
|
|
5
|
+
end: DateValue | undefined;
|
|
6
|
+
}
|
|
7
|
+
export interface DateRangePickerProps extends Omit<HTMLAttributes<HTMLButtonElement>, 'value' | 'onchange'> {
|
|
8
|
+
/**
|
|
9
|
+
* The selected date range.
|
|
10
|
+
*/
|
|
11
|
+
value?: DateRange;
|
|
12
|
+
/**
|
|
13
|
+
* Placeholder text when no dates are selected.
|
|
14
|
+
* @default 'Select date range'
|
|
15
|
+
*/
|
|
16
|
+
placeholder?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Number of months to display side-by-side.
|
|
19
|
+
* @default 2
|
|
20
|
+
*/
|
|
21
|
+
numberOfMonths?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Whether the picker is disabled.
|
|
24
|
+
*/
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Additional CSS classes for the trigger button.
|
|
28
|
+
*/
|
|
29
|
+
class?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Event fired when the date range changes.
|
|
32
|
+
*/
|
|
33
|
+
onchange?: (value: DateRange) => void;
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type VariantProps } from 'tailwind-variants';
|
|
2
|
+
export declare const dateRangePickerVariants: import("tailwind-variants").TVReturnType<{
|
|
3
|
+
disabled: {
|
|
4
|
+
true: {
|
|
5
|
+
trigger: string;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
}, {
|
|
9
|
+
trigger: string;
|
|
10
|
+
triggerText: string;
|
|
11
|
+
icon: string;
|
|
12
|
+
popoverContent: string;
|
|
13
|
+
calendarWrapper: string;
|
|
14
|
+
}, undefined, {
|
|
15
|
+
disabled: {
|
|
16
|
+
true: {
|
|
17
|
+
trigger: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}, {
|
|
21
|
+
trigger: string;
|
|
22
|
+
triggerText: string;
|
|
23
|
+
icon: string;
|
|
24
|
+
popoverContent: string;
|
|
25
|
+
calendarWrapper: string;
|
|
26
|
+
}, import("tailwind-variants").TVReturnType<{
|
|
27
|
+
disabled: {
|
|
28
|
+
true: {
|
|
29
|
+
trigger: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
}, {
|
|
33
|
+
trigger: string;
|
|
34
|
+
triggerText: string;
|
|
35
|
+
icon: string;
|
|
36
|
+
popoverContent: string;
|
|
37
|
+
calendarWrapper: string;
|
|
38
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
39
|
+
export type DateRangePickerVariantProps = VariantProps<typeof dateRangePickerVariants>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const dateRangePickerVariants = tv({
|
|
3
|
+
slots: {
|
|
4
|
+
trigger: 'flex w-full items-center justify-between gap-2 px-3 py-2 text-sm text-left border border-outline-variant bg-surface-50 dark:bg-surface-900 rounded-md hover:bg-surface-100 dark:hover:bg-surface-800 focus:outline-none focus:ring-2 focus:ring-primary transition-colors',
|
|
5
|
+
triggerText: 'truncate flex-1',
|
|
6
|
+
icon: 'w-4 h-4 shrink-0 text-surface-500',
|
|
7
|
+
popoverContent: 'w-auto p-3 bg-surface-50 dark:bg-surface-900 border border-outline-variant rounded-md shadow-md',
|
|
8
|
+
calendarWrapper: 'flex flex-col sm:flex-row gap-4'
|
|
9
|
+
},
|
|
10
|
+
variants: {
|
|
11
|
+
disabled: {
|
|
12
|
+
true: {
|
|
13
|
+
trigger: 'opacity-50 cursor-not-allowed pointer-events-none'
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
disabled: false
|
|
19
|
+
}
|
|
20
|
+
});
|
package/dist/Fonts/fonts.js
CHANGED
|
@@ -70,7 +70,9 @@ export function buildGoogleFontsUrl(fonts, display = 'swap') {
|
|
|
70
70
|
.filter((family, index, source) => family.length > 0 && source.indexOf(family) === index);
|
|
71
71
|
if (families.length === 0)
|
|
72
72
|
return '';
|
|
73
|
-
const familyParams = families
|
|
73
|
+
const familyParams = families
|
|
74
|
+
.map((f) => `family=${encodeURIComponent(f).replaceAll('%2B', '+')}`)
|
|
75
|
+
.join('&');
|
|
74
76
|
return `https://fonts.googleapis.com/css2?${familyParams}&display=${display}`;
|
|
75
77
|
}
|
|
76
78
|
export function buildFontFamily(font) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script lang="ts">import { setContext } from "svelte";
|
|
2
|
+
import Link from "./Link.svelte";
|
|
3
|
+
import { LINK_LOCATION_CONTEXT_KEY } from "./location-context.js";
|
|
4
|
+
let { url } = $props();
|
|
5
|
+
setContext(LINK_LOCATION_CONTEXT_KEY, { currentUrl: () => url });
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<Link href="/from-context" />
|
package/dist/Link/Link.svelte
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
<script lang="ts" module>const
|
|
2
|
-
let
|
|
1
|
+
<script lang="ts" module>const locationSubscribers = new Set();
|
|
2
|
+
let stopLocationTracking;
|
|
3
|
+
let lastKnownHref = "";
|
|
3
4
|
function parseUrl(url, baseUrl) {
|
|
4
5
|
try {
|
|
5
6
|
const parsed = new URL(url, baseUrl.origin);
|
|
@@ -35,60 +36,86 @@ function isPathnameMatch(linkPath, currentPath, exactMatch) {
|
|
|
35
36
|
const current = currentPath.replace(/\/$/, "") || "/";
|
|
36
37
|
return link === "/" ? current === "/" : current === link || current.startsWith(`${link}/`);
|
|
37
38
|
}
|
|
38
|
-
function
|
|
39
|
+
function dispatchLocationChange() {
|
|
39
40
|
if (typeof window === "undefined") {
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
+
for (const callback of locationSubscribers) {
|
|
44
|
+
callback();
|
|
45
|
+
}
|
|
43
46
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
47
|
+
function syncLocation(force = false) {
|
|
48
|
+
if (typeof window === "undefined") {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const href = window.location.href;
|
|
52
|
+
if (!force && href === lastKnownHref) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
lastKnownHref = href;
|
|
56
|
+
dispatchLocationChange();
|
|
53
57
|
}
|
|
54
|
-
function
|
|
55
|
-
if (typeof window === "undefined"
|
|
58
|
+
function scheduleLocationSync() {
|
|
59
|
+
if (typeof window === "undefined") {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
queueMicrotask(() => syncLocation());
|
|
63
|
+
window.setTimeout(() => syncLocation(), 0);
|
|
64
|
+
window.requestAnimationFrame(() => syncLocation());
|
|
65
|
+
}
|
|
66
|
+
function ensureLocationTracking() {
|
|
67
|
+
if (typeof window === "undefined" || stopLocationTracking) {
|
|
56
68
|
return;
|
|
57
69
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
lastKnownHref = window.location.href;
|
|
71
|
+
const handleImmediateLocationChange = () => syncLocation();
|
|
72
|
+
const handleDeferredLocationChange = () => scheduleLocationSync();
|
|
73
|
+
const intervalId = window.setInterval(() => syncLocation(), 125);
|
|
74
|
+
window.addEventListener("popstate", handleImmediateLocationChange);
|
|
75
|
+
window.addEventListener("hashchange", handleImmediateLocationChange);
|
|
76
|
+
document.addEventListener("click", handleDeferredLocationChange, true);
|
|
77
|
+
stopLocationTracking = () => {
|
|
78
|
+
window.clearInterval(intervalId);
|
|
79
|
+
window.removeEventListener("popstate", handleImmediateLocationChange);
|
|
80
|
+
window.removeEventListener("hashchange", handleImmediateLocationChange);
|
|
81
|
+
document.removeEventListener("click", handleDeferredLocationChange, true);
|
|
82
|
+
stopLocationTracking = undefined;
|
|
83
|
+
};
|
|
61
84
|
}
|
|
62
85
|
function subscribeToLocation(callback) {
|
|
63
86
|
if (typeof window === "undefined") {
|
|
64
87
|
return () => undefined;
|
|
65
88
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
window.addEventListener("popstate", handleLocationChange);
|
|
70
|
-
window.addEventListener("hashchange", handleLocationChange);
|
|
71
|
-
window.addEventListener(navigationEvent, handleLocationChange);
|
|
89
|
+
ensureLocationTracking();
|
|
90
|
+
locationSubscribers.add(callback);
|
|
91
|
+
callback();
|
|
72
92
|
return () => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
93
|
+
locationSubscribers.delete(callback);
|
|
94
|
+
if (locationSubscribers.size === 0) {
|
|
95
|
+
stopLocationTracking?.();
|
|
96
|
+
}
|
|
76
97
|
};
|
|
77
98
|
}
|
|
78
99
|
export {};
|
|
79
100
|
</script>
|
|
80
101
|
|
|
81
|
-
<script lang="ts">import { onMount } from "svelte";
|
|
102
|
+
<script lang="ts">import { getContext, onMount } from "svelte";
|
|
82
103
|
import { twMerge } from "tailwind-merge";
|
|
83
104
|
import { getComponentConfig } from "../config.js";
|
|
105
|
+
import { LINK_LOCATION_CONTEXT_KEY } from "./location-context.js";
|
|
84
106
|
import { linkDefaults, linkVariants } from "./link.variants.js";
|
|
85
107
|
const config = getComponentConfig("link", linkDefaults);
|
|
86
108
|
let { ref = $bindable(null), href, type, active, exact = false, exactQuery = false, exactHash = false, activeClass, inactiveClass, disabled = false, raw = false, external, children, class: className, ui, target, rel, onclick, ...restProps } = $props();
|
|
87
109
|
const isLink = $derived(!!href);
|
|
88
|
-
|
|
110
|
+
const locationContext = getContext(LINK_LOCATION_CONTEXT_KEY);
|
|
111
|
+
let observedUrl = $state(undefined);
|
|
112
|
+
const currentUrl = $derived.by(() => locationContext?.currentUrl() ?? observedUrl);
|
|
89
113
|
onMount(() => {
|
|
114
|
+
if (locationContext) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
90
117
|
return subscribeToLocation(() => {
|
|
91
|
-
|
|
118
|
+
observedUrl = new URL(window.location.href);
|
|
92
119
|
});
|
|
93
120
|
});
|
|
94
121
|
const isExternal = $derived(isLink && (external ?? (href.startsWith("http://") || href.startsWith("https://") || href.startsWith("//"))));
|
package/dist/Link/index.d.ts
CHANGED
package/dist/Link/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const LINK_LOCATION_CONTEXT_KEY = Symbol('svelora:link-location');
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<script lang="ts">import { twMerge } from "tailwind-merge";
|
|
2
|
+
import { setContext } from "svelte";
|
|
3
|
+
import { listVariants } from "./list.variants.js";
|
|
4
|
+
let { variant = "default", class: className, children, ...restProps } = $props();
|
|
5
|
+
let styles = $derived(listVariants({ variant }));
|
|
6
|
+
// Pass the variant down to children if needed, or just let them style themselves
|
|
7
|
+
// Since the variant affects the parent 'base', but 'bordered' also affects 'item',
|
|
8
|
+
// we should provide the list context so ListItems know the current variant.
|
|
9
|
+
setContext("list-variant", () => variant);
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<ul class={twMerge(styles.base(), className)} {...restProps}>
|
|
13
|
+
{@render children?.()}
|
|
14
|
+
</ul>
|