sv5ui-plus 4.0.0
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/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/adapters/notify.d.ts +29 -0
- package/dist/adapters/notify.js +88 -0
- package/dist/compat.d.ts +6 -0
- package/dist/compat.js +6 -0
- package/dist/components/BentoGrid/BentoCard.svelte +45 -0
- package/dist/components/BentoGrid/BentoCard.svelte.d.ts +4 -0
- package/dist/components/BentoGrid/BentoGrid.svelte +9 -0
- package/dist/components/BentoGrid/BentoGrid.svelte.d.ts +4 -0
- package/dist/components/BentoGrid/bento-grid.types.d.ts +47 -0
- package/dist/components/BentoGrid/bento-grid.types.js +1 -0
- package/dist/components/BentoGrid/bento-grid.variants.d.ts +30 -0
- package/dist/components/BentoGrid/bento-grid.variants.js +16 -0
- package/dist/components/BentoGrid/index.d.ts +5 -0
- package/dist/components/BentoGrid/index.js +5 -0
- package/dist/components/Chart/Chart.svelte +62 -0
- package/dist/components/Chart/Chart.svelte.d.ts +4 -0
- package/dist/components/Chart/chart.types.d.ts +16 -0
- package/dist/components/Chart/chart.types.js +1 -0
- package/dist/components/Chart/index.d.ts +2 -0
- package/dist/components/Chart/index.js +2 -0
- package/dist/components/Chat/ChatBubble.svelte +30 -0
- package/dist/components/Chat/ChatBubble.svelte.d.ts +4 -0
- package/dist/components/Chat/ChatInput.svelte +50 -0
- package/dist/components/Chat/ChatInput.svelte.d.ts +4 -0
- package/dist/components/Chat/ChatMessage.svelte +15 -0
- package/dist/components/Chat/ChatMessage.svelte.d.ts +4 -0
- package/dist/components/Chat/chat.types.d.ts +63 -0
- package/dist/components/Chat/chat.types.js +1 -0
- package/dist/components/Chat/chat.variants.d.ts +117 -0
- package/dist/components/Chat/chat.variants.js +47 -0
- package/dist/components/Chat/index.d.ts +6 -0
- package/dist/components/Chat/index.js +6 -0
- package/dist/components/CodeBlock/CodeBlock.svelte +66 -0
- package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +5 -0
- package/dist/components/CodeBlock/code-block.types.d.ts +15 -0
- package/dist/components/CodeBlock/code-block.types.js +1 -0
- package/dist/components/CodeBlock/code-block.variants.d.ts +288 -0
- package/dist/components/CodeBlock/code-block.variants.js +69 -0
- package/dist/components/CodeBlock/index.d.ts +2 -0
- package/dist/components/CodeBlock/index.js +1 -0
- package/dist/components/ColorPicker/ColorPicker.svelte +109 -0
- package/dist/components/ColorPicker/ColorPicker.svelte.d.ts +4 -0
- package/dist/components/ColorPicker/color-picker.types.d.ts +26 -0
- package/dist/components/ColorPicker/color-picker.types.js +1 -0
- package/dist/components/ColorPicker/color-picker.variants.d.ts +69 -0
- package/dist/components/ColorPicker/color-picker.variants.js +13 -0
- package/dist/components/ColorPicker/index.d.ts +4 -0
- package/dist/components/ColorPicker/index.js +4 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.svelte +175 -0
- package/dist/components/ConfirmDialog/ConfirmDialog.svelte.d.ts +10 -0
- package/dist/components/ConfirmDialog/confirm.d.ts +9 -0
- package/dist/components/ConfirmDialog/confirm.js +24 -0
- package/dist/components/ConfirmDialog/confirm.types.d.ts +21 -0
- package/dist/components/ConfirmDialog/confirm.types.js +1 -0
- package/dist/components/ConfirmDialog/index.d.ts +4 -0
- package/dist/components/ConfirmDialog/index.js +2 -0
- package/dist/components/Fonts/Fonts.svelte +32 -0
- package/dist/components/Fonts/Fonts.svelte.d.ts +5 -0
- package/dist/components/Fonts/fonts.d.ts +12 -0
- package/dist/components/Fonts/fonts.js +126 -0
- package/dist/components/Fonts/fonts.types.d.ts +40 -0
- package/dist/components/Fonts/fonts.types.js +1 -0
- package/dist/components/Fonts/index.d.ts +3 -0
- package/dist/components/Fonts/index.js +2 -0
- package/dist/components/List/List.svelte +14 -0
- package/dist/components/List/List.svelte.d.ts +4 -0
- package/dist/components/List/ListItem.svelte +64 -0
- package/dist/components/List/ListItem.svelte.d.ts +4 -0
- package/dist/components/List/index.d.ts +5 -0
- package/dist/components/List/index.js +5 -0
- package/dist/components/List/list.types.d.ts +62 -0
- package/dist/components/List/list.types.js +1 -0
- package/dist/components/List/list.variants.d.ts +99 -0
- package/dist/components/List/list.variants.js +42 -0
- package/dist/components/LocaleButton/LocaleButton.svelte +181 -0
- package/dist/components/LocaleButton/LocaleButton.svelte.d.ts +5 -0
- package/dist/components/LocaleButton/index.d.ts +2 -0
- package/dist/components/LocaleButton/index.js +1 -0
- package/dist/components/LocaleButton/locale-button.types.d.ts +208 -0
- package/dist/components/LocaleButton/locale-button.types.js +1 -0
- package/dist/components/LocaleButton/locale-button.variants.d.ts +245 -0
- package/dist/components/LocaleButton/locale-button.variants.js +98 -0
- package/dist/components/Marquee/Marquee.svelte +50 -0
- package/dist/components/Marquee/Marquee.svelte.d.ts +4 -0
- package/dist/components/Marquee/index.d.ts +4 -0
- package/dist/components/Marquee/index.js +4 -0
- package/dist/components/Marquee/marquee.types.d.ts +38 -0
- package/dist/components/Marquee/marquee.types.js +1 -0
- package/dist/components/Marquee/marquee.variants.d.ts +78 -0
- package/dist/components/Marquee/marquee.variants.js +28 -0
- package/dist/components/NavigationMenu/NavigationMenu.svelte +623 -0
- package/dist/components/NavigationMenu/NavigationMenu.svelte.d.ts +5 -0
- package/dist/components/NavigationMenu/index.d.ts +2 -0
- package/dist/components/NavigationMenu/index.js +1 -0
- package/dist/components/NavigationMenu/navigation-menu.types.d.ts +245 -0
- package/dist/components/NavigationMenu/navigation-menu.types.js +1 -0
- package/dist/components/NavigationMenu/navigation-menu.variants.d.ts +543 -0
- package/dist/components/NavigationMenu/navigation-menu.variants.js +287 -0
- package/dist/components/NumberTicker/NumberTicker.svelte +59 -0
- package/dist/components/NumberTicker/NumberTicker.svelte.d.ts +4 -0
- package/dist/components/NumberTicker/index.d.ts +4 -0
- package/dist/components/NumberTicker/index.js +4 -0
- package/dist/components/NumberTicker/number-ticker.types.d.ts +26 -0
- package/dist/components/NumberTicker/number-ticker.types.js +1 -0
- package/dist/components/NumberTicker/number-ticker.variants.d.ts +27 -0
- package/dist/components/NumberTicker/number-ticker.variants.js +6 -0
- package/dist/components/PasswordInput/PasswordInput.svelte +182 -0
- package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +5 -0
- package/dist/components/PasswordInput/index.d.ts +2 -0
- package/dist/components/PasswordInput/index.js +1 -0
- package/dist/components/PasswordInput/password-input.types.d.ts +111 -0
- package/dist/components/PasswordInput/password-input.types.js +1 -0
- package/dist/components/PasswordInput/password-input.variants.d.ts +273 -0
- package/dist/components/PasswordInput/password-input.variants.js +105 -0
- package/dist/components/Prose/Prose.svelte +13 -0
- package/dist/components/Prose/Prose.svelte.d.ts +4 -0
- package/dist/components/Prose/index.d.ts +4 -0
- package/dist/components/Prose/index.js +4 -0
- package/dist/components/Prose/prose.types.d.ts +22 -0
- package/dist/components/Prose/prose.types.js +1 -0
- package/dist/components/Prose/prose.variants.d.ts +45 -0
- package/dist/components/Prose/prose.variants.js +45 -0
- package/dist/components/Resizable/Resizable.svelte +9 -0
- package/dist/components/Resizable/Resizable.svelte.d.ts +4 -0
- package/dist/components/Resizable/index.d.ts +4 -0
- package/dist/components/Resizable/index.js +4 -0
- package/dist/components/Resizable/resizable.types.d.ts +18 -0
- package/dist/components/Resizable/resizable.types.js +1 -0
- package/dist/components/Resizable/resizable.variants.d.ts +48 -0
- package/dist/components/Resizable/resizable.variants.js +17 -0
- package/dist/components/ScrollArea/ScrollArea.svelte +54 -0
- package/dist/components/ScrollArea/ScrollArea.svelte.d.ts +4 -0
- package/dist/components/ScrollArea/index.d.ts +4 -0
- package/dist/components/ScrollArea/index.js +4 -0
- package/dist/components/ScrollArea/scroll-area.types.d.ts +27 -0
- package/dist/components/ScrollArea/scroll-area.types.js +1 -0
- package/dist/components/ScrollArea/scroll-area.variants.d.ts +45 -0
- package/dist/components/ScrollArea/scroll-area.variants.js +27 -0
- package/dist/components/Search/Search.svelte +94 -0
- package/dist/components/Search/Search.svelte.d.ts +4 -0
- package/dist/components/Search/index.d.ts +2 -0
- package/dist/components/Search/index.js +1 -0
- package/dist/components/Search/search.types.d.ts +40 -0
- package/dist/components/Search/search.types.js +1 -0
- package/dist/components/SortableGroup/SortableGroup.svelte +53 -0
- package/dist/components/SortableGroup/SortableGroup.svelte.d.ts +13 -0
- package/dist/components/SortableGroup/index.d.ts +1 -0
- package/dist/components/SortableGroup/index.js +1 -0
- package/dist/components/SortableList/SortableList.svelte +81 -0
- package/dist/components/SortableList/SortableList.svelte.d.ts +26 -0
- package/dist/components/SortableList/index.d.ts +2 -0
- package/dist/components/SortableList/index.js +1 -0
- package/dist/components/SortableList/sortable-list.types.d.ts +21 -0
- package/dist/components/SortableList/sortable-list.types.js +1 -0
- package/dist/components/Spotlight/Spotlight.svelte +31 -0
- package/dist/components/Spotlight/Spotlight.svelte.d.ts +4 -0
- package/dist/components/Spotlight/index.d.ts +4 -0
- package/dist/components/Spotlight/index.js +4 -0
- package/dist/components/Spotlight/spotlight.types.d.ts +22 -0
- package/dist/components/Spotlight/spotlight.types.js +1 -0
- package/dist/components/Spotlight/spotlight.variants.d.ts +39 -0
- package/dist/components/Spotlight/spotlight.variants.js +8 -0
- package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte +38 -0
- package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte.d.ts +5 -0
- package/dist/components/TableBulkActionBar/index.d.ts +2 -0
- package/dist/components/TableBulkActionBar/index.js +1 -0
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.types.d.ts +31 -0
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.types.js +1 -0
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.d.ts +52 -0
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.js +10 -0
- package/dist/components/TreeView/TreeView.svelte +95 -0
- package/dist/components/TreeView/TreeView.svelte.d.ts +4 -0
- package/dist/components/TreeView/index.d.ts +4 -0
- package/dist/components/TreeView/index.js +3 -0
- package/dist/components/TreeView/tree-view.types.d.ts +68 -0
- package/dist/components/TreeView/tree-view.types.js +1 -0
- package/dist/components/TreeView/tree-view.variants.d.ts +69 -0
- package/dist/components/TreeView/tree-view.variants.js +30 -0
- package/dist/config.d.ts +91 -0
- package/dist/config.js +124 -0
- package/dist/editor.d.ts +2 -0
- package/dist/editor.js +2 -0
- package/dist/form/resolve-form-field-name.d.ts +5 -0
- package/dist/form/resolve-form-field-name.js +11 -0
- package/dist/hooks/internal/DragDropProviderScope.svelte +29 -0
- package/dist/hooks/internal/DragDropProviderScope.svelte.d.ts +7 -0
- package/dist/hooks/internal/SortableProvider.svelte +68 -0
- package/dist/hooks/internal/SortableProvider.svelte.d.ts +30 -0
- package/dist/hooks/internal/drag-drop-context.d.ts +12 -0
- package/dist/hooks/internal/drag-drop-context.js +1 -0
- package/dist/hooks/internal/sortable-context.d.ts +26 -0
- package/dist/hooks/internal/sortable-context.js +2 -0
- package/dist/hooks/useDragDrop/index.d.ts +1 -0
- package/dist/hooks/useDragDrop/index.js +1 -0
- package/dist/hooks/useDragDrop/useDragDrop.svelte.d.ts +40 -0
- package/dist/hooks/useDragDrop/useDragDrop.svelte.js +128 -0
- package/dist/hooks/useSortable/index.d.ts +2 -0
- package/dist/hooks/useSortable/index.js +2 -0
- package/dist/hooks/useSortable/sortable-utils.d.ts +1 -0
- package/dist/hooks/useSortable/sortable-utils.js +13 -0
- package/dist/hooks/useSortable/useSortable.svelte.d.ts +60 -0
- package/dist/hooks/useSortable/useSortable.svelte.js +151 -0
- package/dist/hooks/utils.d.ts +1 -0
- package/dist/hooks/utils.js +3 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +30 -0
- package/dist/mcp/cursor.mcp.json +12 -0
- package/dist/mcp/install-template.mjs +55 -0
- package/dist/mcp/server.mjs +338 -0
- package/dist/mcp/sv5ui-plus-docs.data.json +17 -0
- package/dist/theme.css +64 -0
- package/package.json +176 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<script lang="ts">import { twMerge } from "tailwind-merge";
|
|
2
|
+
import { Popover } from "sv5ui";
|
|
3
|
+
import { Input } from "sv5ui";
|
|
4
|
+
import { Icon } from "sv5ui";
|
|
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-variants").ClassValue | {
|
|
5
|
+
base?: import("tailwind-variants").ClassValue;
|
|
6
|
+
trigger?: import("tailwind-variants").ClassValue;
|
|
7
|
+
colorIndicator?: import("tailwind-variants").ClassValue;
|
|
8
|
+
content?: import("tailwind-variants").ClassValue;
|
|
9
|
+
swatchGrid?: import("tailwind-variants").ClassValue;
|
|
10
|
+
swatch?: import("tailwind-variants").ClassValue;
|
|
11
|
+
nativeInput?: import("tailwind-variants").ClassValue;
|
|
12
|
+
hexInputWrapper?: import("tailwind-variants").ClassValue;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
[x: string]: {
|
|
17
|
+
[x: string]: import("tailwind-variants").ClassValue | {
|
|
18
|
+
base?: import("tailwind-variants").ClassValue;
|
|
19
|
+
trigger?: import("tailwind-variants").ClassValue;
|
|
20
|
+
colorIndicator?: import("tailwind-variants").ClassValue;
|
|
21
|
+
content?: import("tailwind-variants").ClassValue;
|
|
22
|
+
swatchGrid?: import("tailwind-variants").ClassValue;
|
|
23
|
+
swatch?: import("tailwind-variants").ClassValue;
|
|
24
|
+
nativeInput?: import("tailwind-variants").ClassValue;
|
|
25
|
+
hexInputWrapper?: import("tailwind-variants").ClassValue;
|
|
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-variants").ClassValue | {
|
|
40
|
+
base?: import("tailwind-variants").ClassValue;
|
|
41
|
+
trigger?: import("tailwind-variants").ClassValue;
|
|
42
|
+
colorIndicator?: import("tailwind-variants").ClassValue;
|
|
43
|
+
content?: import("tailwind-variants").ClassValue;
|
|
44
|
+
swatchGrid?: import("tailwind-variants").ClassValue;
|
|
45
|
+
swatch?: import("tailwind-variants").ClassValue;
|
|
46
|
+
nativeInput?: import("tailwind-variants").ClassValue;
|
|
47
|
+
hexInputWrapper?: import("tailwind-variants").ClassValue;
|
|
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").TVReturnTypeLike<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
|
+
}>>;
|
|
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,175 @@
|
|
|
1
|
+
<script lang="ts" module>export {};
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<script lang="ts">import { Dialog } from "bits-ui";
|
|
5
|
+
import { Button } from "sv5ui";
|
|
6
|
+
import { Input } from "sv5ui";
|
|
7
|
+
import { Textarea } from "sv5ui";
|
|
8
|
+
import { Icon } from "sv5ui";
|
|
9
|
+
let { confirmText: defaultConfirmText = "Confirm", cancelText: defaultCancelText = "Cancel" } = $props();
|
|
10
|
+
let open = $state(false);
|
|
11
|
+
let pending = $state(null);
|
|
12
|
+
let currentInputValue = $state("");
|
|
13
|
+
const iconNames = {
|
|
14
|
+
warning: "lucide:triangle-alert",
|
|
15
|
+
error: "lucide:circle-x",
|
|
16
|
+
question: "lucide:circle-help",
|
|
17
|
+
info: "lucide:info",
|
|
18
|
+
success: "lucide:circle-check"
|
|
19
|
+
};
|
|
20
|
+
const iconColors = {
|
|
21
|
+
warning: "text-warning",
|
|
22
|
+
error: "text-error",
|
|
23
|
+
question: "text-primary",
|
|
24
|
+
info: "text-info",
|
|
25
|
+
success: "text-success"
|
|
26
|
+
};
|
|
27
|
+
const dismissible = $derived(pending?.options.dismissible !== false);
|
|
28
|
+
const showCancel = $derived(pending?.options.showCancel !== false);
|
|
29
|
+
export function show(options = {}) {
|
|
30
|
+
return new Promise((resolve) => {
|
|
31
|
+
currentInputValue = options.inputValue ?? "";
|
|
32
|
+
pending = {
|
|
33
|
+
options,
|
|
34
|
+
resolve
|
|
35
|
+
};
|
|
36
|
+
open = true;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function settle(result) {
|
|
40
|
+
const current = pending;
|
|
41
|
+
pending = null;
|
|
42
|
+
open = false;
|
|
43
|
+
current?.resolve(result);
|
|
44
|
+
}
|
|
45
|
+
function handleConfirm() {
|
|
46
|
+
pending?.options.onConfirm?.(currentInputValue);
|
|
47
|
+
settle(true);
|
|
48
|
+
}
|
|
49
|
+
function handleCancel() {
|
|
50
|
+
pending?.options.onCancel?.();
|
|
51
|
+
settle(false);
|
|
52
|
+
}
|
|
53
|
+
function handleOpenChange(value) {
|
|
54
|
+
if (!value && pending) {
|
|
55
|
+
handleCancel();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
open = value;
|
|
59
|
+
}
|
|
60
|
+
const contentProps = $derived.by(() => {
|
|
61
|
+
const behavior = dismissible ? "close" : "ignore";
|
|
62
|
+
return {
|
|
63
|
+
trapFocus: true,
|
|
64
|
+
preventScroll: true,
|
|
65
|
+
escapeKeydownBehavior: behavior,
|
|
66
|
+
interactOutsideBehavior: behavior
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<Dialog.Root bind:open onOpenChange={handleOpenChange}>
|
|
72
|
+
<Dialog.Portal>
|
|
73
|
+
<Dialog.Overlay
|
|
74
|
+
class="fixed inset-0 z-50 bg-[var(--scrim-bg,rgba(0,0,0,0.3))] backdrop-blur-sm"
|
|
75
|
+
/>
|
|
76
|
+
{#if pending}
|
|
77
|
+
<Dialog.Content
|
|
78
|
+
{...contentProps}
|
|
79
|
+
class="fixed top-1/2 left-1/2 z-50 w-[min(24rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-outline-variant bg-surface p-6 text-center text-on-surface shadow-2xl focus:outline-none"
|
|
80
|
+
>
|
|
81
|
+
{#if pending.options.title}
|
|
82
|
+
<Dialog.Title class="sr-only">{pending.options.title}</Dialog.Title>
|
|
83
|
+
{/if}
|
|
84
|
+
{#if pending.options.message}
|
|
85
|
+
<Dialog.Description class="sr-only"
|
|
86
|
+
>{pending.options.message}</Dialog.Description
|
|
87
|
+
>
|
|
88
|
+
{/if}
|
|
89
|
+
|
|
90
|
+
{#if pending.options.icon}
|
|
91
|
+
{#key pending.options.icon}
|
|
92
|
+
<div class="mb-4 flex min-h-20 justify-center">
|
|
93
|
+
<Icon
|
|
94
|
+
name={iconNames[pending.options.icon]}
|
|
95
|
+
size={80}
|
|
96
|
+
class={iconColors[pending.options.icon]}
|
|
97
|
+
/>
|
|
98
|
+
</div>
|
|
99
|
+
{/key}
|
|
100
|
+
{/if}
|
|
101
|
+
|
|
102
|
+
{#if pending.options.title}
|
|
103
|
+
<h3 class="mb-2 text-lg font-semibold text-on-surface">
|
|
104
|
+
{pending.options.title}
|
|
105
|
+
</h3>
|
|
106
|
+
{/if}
|
|
107
|
+
|
|
108
|
+
{#if pending.options.message}
|
|
109
|
+
<p class="mb-6 text-sm text-on-surface-variant">
|
|
110
|
+
{pending.options.message}
|
|
111
|
+
</p>
|
|
112
|
+
{:else if !pending.options.inputPlaceholder}
|
|
113
|
+
<div class="mb-6"></div>
|
|
114
|
+
{/if}
|
|
115
|
+
|
|
116
|
+
{#if pending.options.inputPlaceholder}
|
|
117
|
+
{#if pending.options.inputChoices && pending.options.inputChoices.length > 0}
|
|
118
|
+
<div class="mb-3 flex flex-wrap justify-center gap-1">
|
|
119
|
+
{#each pending.options.inputChoices as choice (choice)}
|
|
120
|
+
<Button
|
|
121
|
+
label={choice}
|
|
122
|
+
size="xs"
|
|
123
|
+
variant={currentInputValue === choice ? 'solid' : 'outline'}
|
|
124
|
+
color={currentInputValue === choice ? 'primary' : 'surface'}
|
|
125
|
+
onclick={() => (currentInputValue = choice)}
|
|
126
|
+
/>
|
|
127
|
+
{/each}
|
|
128
|
+
</div>
|
|
129
|
+
{/if}
|
|
130
|
+
|
|
131
|
+
<div class="mb-6 text-left">
|
|
132
|
+
{#if pending.options.inputType === 'textarea'}
|
|
133
|
+
<Textarea
|
|
134
|
+
bind:value={currentInputValue}
|
|
135
|
+
placeholder={pending.options.inputPlaceholder}
|
|
136
|
+
class="w-full"
|
|
137
|
+
/>
|
|
138
|
+
{:else}
|
|
139
|
+
<Input
|
|
140
|
+
type={pending.options.inputType ?? 'text'}
|
|
141
|
+
bind:value={currentInputValue}
|
|
142
|
+
placeholder={pending.options.inputPlaceholder}
|
|
143
|
+
class="w-full"
|
|
144
|
+
onkeydown={(e) => {
|
|
145
|
+
if (e.key === 'Enter') {
|
|
146
|
+
e.preventDefault()
|
|
147
|
+
handleConfirm()
|
|
148
|
+
}
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
151
|
+
{/if}
|
|
152
|
+
</div>
|
|
153
|
+
{/if}
|
|
154
|
+
|
|
155
|
+
<div class="flex justify-center gap-2">
|
|
156
|
+
{#if showCancel}
|
|
157
|
+
<Button
|
|
158
|
+
label={pending.options.cancelText ?? defaultCancelText}
|
|
159
|
+
variant="outline"
|
|
160
|
+
class="flex-1"
|
|
161
|
+
onclick={handleCancel}
|
|
162
|
+
/>
|
|
163
|
+
{/if}
|
|
164
|
+
<Button
|
|
165
|
+
label={pending.options.confirmText ?? defaultConfirmText}
|
|
166
|
+
variant="solid"
|
|
167
|
+
color={pending.options.confirmColor ?? 'primary'}
|
|
168
|
+
class={showCancel ? 'flex-1' : 'w-full'}
|
|
169
|
+
onclick={handleConfirm}
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
</Dialog.Content>
|
|
173
|
+
{/if}
|
|
174
|
+
</Dialog.Portal>
|
|
175
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type Props = {
|
|
2
|
+
confirmText?: string;
|
|
3
|
+
cancelText?: string;
|
|
4
|
+
};
|
|
5
|
+
import type { ConfirmOptions } from './confirm.types.js';
|
|
6
|
+
declare const ConfirmDialog: import("svelte").Component<Props, {
|
|
7
|
+
show: (options?: ConfirmOptions) => Promise<boolean>;
|
|
8
|
+
}, "">;
|
|
9
|
+
type ConfirmDialog = ReturnType<typeof ConfirmDialog>;
|
|
10
|
+
export default ConfirmDialog;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ConfirmOptions } from './confirm.types.js';
|
|
2
|
+
type ShowFn = (options?: ConfirmOptions) => Promise<boolean>;
|
|
3
|
+
export declare function registerConfirmDialog(fn: ShowFn | null): void;
|
|
4
|
+
export declare const confirmDialog: {
|
|
5
|
+
show(options?: ConfirmOptions): Promise<boolean>;
|
|
6
|
+
delete(options?: ConfirmOptions): Promise<boolean>;
|
|
7
|
+
};
|
|
8
|
+
export type ConfirmDialogUtility = typeof confirmDialog;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
let showFn = null;
|
|
2
|
+
export function registerConfirmDialog(fn) {
|
|
3
|
+
showFn = fn;
|
|
4
|
+
}
|
|
5
|
+
export const confirmDialog = {
|
|
6
|
+
show(options = {}) {
|
|
7
|
+
if (!showFn) {
|
|
8
|
+
console.warn('[confirmDialog] ConfirmDialog is not registered — add <ConfirmDialog /> to your root layout.');
|
|
9
|
+
return Promise.resolve(false);
|
|
10
|
+
}
|
|
11
|
+
return showFn(options);
|
|
12
|
+
},
|
|
13
|
+
delete(options = {}) {
|
|
14
|
+
return this.show({
|
|
15
|
+
title: 'Delete this item?',
|
|
16
|
+
message: 'This action is permanent and cannot be undone.',
|
|
17
|
+
confirmText: 'Delete',
|
|
18
|
+
cancelText: 'Cancel',
|
|
19
|
+
icon: 'warning',
|
|
20
|
+
confirmColor: 'error',
|
|
21
|
+
...options
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ButtonProps } from 'sv5ui';
|
|
2
|
+
export type ConfirmIcon = 'warning' | 'error' | 'question' | 'info' | 'success';
|
|
3
|
+
export type ConfirmColor = NonNullable<ButtonProps['color']>;
|
|
4
|
+
export interface ConfirmOptions {
|
|
5
|
+
title?: string;
|
|
6
|
+
message?: string;
|
|
7
|
+
confirmText?: string;
|
|
8
|
+
cancelText?: string;
|
|
9
|
+
icon?: ConfirmIcon;
|
|
10
|
+
confirmColor?: ConfirmColor;
|
|
11
|
+
/** When false, only the confirm button is shown (alert-style). @default true */
|
|
12
|
+
showCancel?: boolean;
|
|
13
|
+
/** When false, backdrop click and Escape do not dismiss. @default true */
|
|
14
|
+
dismissible?: boolean;
|
|
15
|
+
inputPlaceholder?: string;
|
|
16
|
+
inputValue?: string;
|
|
17
|
+
inputType?: 'text' | 'password' | 'email' | 'number' | 'textarea';
|
|
18
|
+
inputChoices?: string[];
|
|
19
|
+
onConfirm?: (value?: string) => void;
|
|
20
|
+
onCancel?: () => void;
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { default as ConfirmDialog } from './ConfirmDialog.svelte';
|
|
2
|
+
export { confirmDialog, registerConfirmDialog } from './confirm.js';
|
|
3
|
+
export type { ConfirmOptions, ConfirmIcon, ConfirmColor } from './confirm.types.js';
|
|
4
|
+
export type { ConfirmDialogUtility } from './confirm.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts" module>export {};
|
|
2
|
+
</script>
|
|
3
|
+
|
|
4
|
+
<script lang="ts">import { getConfig } from "../../config.js";
|
|
5
|
+
import { buildFontVariablesCss, buildGoogleFontsUrl, buildLocalFontFaceCss, fontsDefaults, resolveFontsOptions } from "./fonts.js";
|
|
6
|
+
const globalConfig = getConfig();
|
|
7
|
+
const config = resolveFontsOptions(globalConfig.fonts);
|
|
8
|
+
let { fonts, families, display, preconnect } = $props();
|
|
9
|
+
const resolvedFamilies = $derived(families ?? fonts ?? (config === false ? [] : config.families ?? []));
|
|
10
|
+
const resolvedDisplay = $derived(display ?? (config === false ? fontsDefaults.display : config.display));
|
|
11
|
+
const resolvedPreconnect = $derived(preconnect ?? (config === false ? fontsDefaults.preconnect : config.preconnect));
|
|
12
|
+
const href = $derived(buildGoogleFontsUrl(resolvedFamilies, resolvedDisplay));
|
|
13
|
+
const localFontFaceCss = $derived(buildLocalFontFaceCss(resolvedFamilies, resolvedDisplay));
|
|
14
|
+
const variableCss = $derived(buildFontVariablesCss(resolvedFamilies));
|
|
15
|
+
const inlineCss = $derived([localFontFaceCss, variableCss].filter((value) => value.length > 0).join("\n\n"));
|
|
16
|
+
const hasFonts = $derived(href.length > 0 || inlineCss.length > 0);
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<svelte:head>
|
|
20
|
+
{#if hasFonts}
|
|
21
|
+
{#if resolvedPreconnect && href}
|
|
22
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
23
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="anonymous" />
|
|
24
|
+
{/if}
|
|
25
|
+
{#if href}
|
|
26
|
+
<link rel="stylesheet" href={href} />
|
|
27
|
+
{/if}
|
|
28
|
+
{#if inlineCss}
|
|
29
|
+
<svelte:element this={'style'}>{inlineCss}</svelte:element>
|
|
30
|
+
{/if}
|
|
31
|
+
{/if}
|
|
32
|
+
</svelte:head>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FontDefinition, GoogleFontDisplay, FontsConfig, FontsOptions } from './fonts.types.js';
|
|
2
|
+
export declare const defaultFontFamilies: FontDefinition[];
|
|
3
|
+
export declare const fontsDefaults: {
|
|
4
|
+
families: FontDefinition[];
|
|
5
|
+
display: GoogleFontDisplay;
|
|
6
|
+
preconnect: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare function buildGoogleFontsUrl(fonts: FontDefinition[], display?: GoogleFontDisplay): string;
|
|
9
|
+
export declare function buildFontFamily(font: FontDefinition): string;
|
|
10
|
+
export declare function buildLocalFontFaceCss(fonts: FontDefinition[], defaultDisplay?: GoogleFontDisplay): string;
|
|
11
|
+
export declare function buildFontVariablesCss(fonts: FontDefinition[]): string;
|
|
12
|
+
export declare function resolveFontsOptions(config?: FontsConfig): FontsOptions | false;
|