compote-ui 0.3.0 → 0.5.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/dist/components/button/button.svelte +16 -0
- package/dist/components/button/{Button.svelte.d.ts → button.svelte.d.ts} +3 -2
- package/dist/components/button/button.variants.d.ts +46 -0
- package/dist/components/button/button.variants.js +20 -0
- package/dist/components/carousel/carousel.svelte +120 -0
- package/dist/components/carousel/carousel.svelte.d.ts +19 -0
- package/dist/components/checkbox/{Checkbox-group.svelte → checkbox-group.svelte} +1 -1
- package/dist/components/checkbox/{Checkbox.svelte → checkbox.svelte} +6 -2
- package/dist/components/combobox/{Combobox.svelte → combobox.svelte} +21 -24
- package/dist/components/combobox/types.d.ts +1 -1
- package/dist/components/dialog/alert-dialog.svelte +73 -0
- package/dist/components/dialog/alert-dialog.svelte.d.ts +13 -0
- package/dist/components/dialog/dialog.svelte +68 -0
- package/dist/components/dialog/dialog.svelte.d.ts +14 -0
- package/dist/components/field/field-error-text.svelte +11 -0
- package/dist/components/field/field-error-text.svelte.d.ts +4 -0
- package/dist/components/field/field-helper-text.svelte +11 -0
- package/dist/components/field/field-helper-text.svelte.d.ts +4 -0
- package/dist/components/field/field-input.svelte +38 -0
- package/dist/components/field/field-input.svelte.d.ts +4 -0
- package/dist/components/field/field-label.svelte +18 -0
- package/dist/components/field/field-label.svelte.d.ts +4 -0
- package/dist/components/field/field-textarea.svelte +16 -0
- package/dist/components/field/field-textarea.svelte.d.ts +4 -0
- package/dist/components/field/field.svelte +11 -0
- package/dist/components/field/field.svelte.d.ts +5 -0
- package/dist/components/field/index.d.ts +7 -0
- package/dist/components/field/index.js +6 -0
- package/dist/components/field/types.d.ts +22 -0
- package/dist/components/field/types.js +1 -0
- package/dist/components/file-upload/basic-document.svelte +89 -0
- package/dist/components/file-upload/basic-document.svelte.d.ts +4 -0
- package/dist/components/file-upload/basic.svelte +50 -0
- package/dist/components/file-upload/basic.svelte.d.ts +18 -0
- package/dist/components/file-upload/dropzone.svelte +26 -0
- package/dist/components/file-upload/dropzone.svelte.d.ts +4 -0
- package/dist/components/file-upload/files-list.svelte +97 -0
- package/dist/components/file-upload/files-list.svelte.d.ts +18 -0
- package/dist/components/file-upload/icons.d.ts +3 -0
- package/dist/components/file-upload/icons.js +39 -0
- package/dist/components/file-upload/types.d.ts +6 -0
- package/dist/components/file-upload/types.js +1 -0
- package/dist/components/file-upload/utils.d.ts +13 -0
- package/dist/components/file-upload/utils.js +18 -0
- package/dist/components/image-cropper/image-cropper.svelte +109 -0
- package/dist/components/image-cropper/image-cropper.svelte.d.ts +5 -0
- package/dist/components/image-cropper/types.d.ts +16 -0
- package/dist/components/image-cropper/types.js +1 -0
- package/dist/components/listbox/listbox.svelte +116 -0
- package/dist/components/listbox/listbox.svelte.d.ts +27 -0
- package/dist/components/listbox/types.d.ts +16 -0
- package/dist/components/listbox/types.js +1 -0
- package/dist/components/menu/index.d.ts +14 -0
- package/dist/components/menu/index.js +14 -0
- package/dist/components/menu/menu-checkbox-item.svelte +31 -0
- package/dist/components/menu/menu-checkbox-item.svelte.d.ts +12 -0
- package/dist/components/menu/menu-content.svelte +23 -0
- package/dist/components/menu/menu-content.svelte.d.ts +8 -0
- package/dist/components/menu/menu-context-trigger.svelte +20 -0
- package/dist/components/menu/menu-context-trigger.svelte.d.ts +8 -0
- package/dist/components/menu/menu-indicator.svelte +19 -0
- package/dist/components/menu/menu-indicator.svelte.d.ts +9 -0
- package/dist/components/menu/menu-item-group-label.svelte +17 -0
- package/dist/components/menu/menu-item-group-label.svelte.d.ts +9 -0
- package/dist/components/menu/menu-item-group.svelte +14 -0
- package/dist/components/menu/menu-item-group.svelte.d.ts +9 -0
- package/dist/components/menu/menu-item-indicator.svelte +14 -0
- package/dist/components/menu/menu-item-indicator.svelte.d.ts +9 -0
- package/dist/components/menu/menu-item.svelte +20 -0
- package/dist/components/menu/menu-item.svelte.d.ts +9 -0
- package/dist/components/menu/menu-radio-item-group.svelte +14 -0
- package/dist/components/menu/menu-radio-item-group.svelte.d.ts +9 -0
- package/dist/components/menu/menu-radio-item.svelte +28 -0
- package/dist/components/menu/menu-radio-item.svelte.d.ts +10 -0
- package/dist/components/menu/menu-separator.svelte +11 -0
- package/dist/components/menu/menu-separator.svelte.d.ts +7 -0
- package/dist/components/menu/menu-trigger-item.svelte +20 -0
- package/dist/components/menu/menu-trigger-item.svelte.d.ts +9 -0
- package/dist/components/menu/menu-trigger.svelte +19 -0
- package/dist/components/menu/menu-trigger.svelte.d.ts +12 -0
- package/dist/components/menu/menu.svelte +12 -0
- package/dist/components/menu/menu.svelte.d.ts +4 -0
- package/dist/components/number-input/number-input.svelte +67 -0
- package/dist/components/number-input/number-input.svelte.d.ts +5 -0
- package/dist/components/number-input/types.d.ts +7 -0
- package/dist/components/number-input/types.js +1 -0
- package/dist/components/select/select.svelte +93 -0
- package/dist/components/select/select.svelte.d.ts +26 -0
- package/dist/components/select/types.d.ts +13 -0
- package/dist/components/select/types.js +1 -0
- package/dist/components/splitter/splitter.svelte +60 -0
- package/dist/components/splitter/splitter.svelte.d.ts +5 -0
- package/dist/components/splitter/types.d.ts +9 -0
- package/dist/components/splitter/types.js +1 -0
- package/dist/components/switch/index.d.ts +2 -0
- package/dist/components/switch/index.js +1 -0
- package/dist/components/switch/switch.svelte +40 -0
- package/dist/components/switch/switch.svelte.d.ts +8 -0
- package/dist/components/switch/types.d.ts +5 -0
- package/dist/components/switch/types.js +1 -0
- package/dist/components/tabs/index.d.ts +4 -0
- package/dist/components/tabs/index.js +3 -0
- package/dist/components/tabs/tab-content.svelte +18 -0
- package/dist/components/tabs/tab-content.svelte.d.ts +7 -0
- package/dist/components/tabs/tab-trigger.svelte +18 -0
- package/dist/components/tabs/tab-trigger.svelte.d.ts +7 -0
- package/dist/components/tabs/tabs.svelte +39 -0
- package/dist/components/tabs/tabs.svelte.d.ts +5 -0
- package/dist/components/tabs/types.d.ts +8 -0
- package/dist/components/tabs/types.js +1 -0
- package/dist/components/tree-view/tree-view.svelte +210 -0
- package/dist/components/tree-view/tree-view.svelte.d.ts +26 -0
- package/dist/components/tree-view/types.d.ts +12 -0
- package/dist/components/tree-view/types.js +1 -0
- package/dist/icons/PhArrowLeft.svelte +18 -0
- package/dist/icons/PhArrowLeft.svelte.d.ts +5 -0
- package/dist/icons/PhArrowRight.svelte +18 -0
- package/dist/icons/PhArrowRight.svelte.d.ts +5 -0
- package/dist/icons/PhArrowsInSimple.svelte +17 -0
- package/dist/icons/PhArrowsInSimple.svelte.d.ts +5 -0
- package/dist/icons/PhCaretDown.svelte +2 -1
- package/dist/icons/PhCaretRight.svelte +17 -0
- package/dist/icons/PhCaretRight.svelte.d.ts +5 -0
- package/dist/icons/PhCaretUp.svelte +18 -0
- package/dist/icons/PhCaretUp.svelte.d.ts +5 -0
- package/dist/icons/PhCheck.svelte +2 -1
- package/dist/icons/PhFile.svelte +19 -0
- package/dist/icons/PhFile.svelte.d.ts +5 -0
- package/dist/icons/PhFileArchive.svelte +18 -0
- package/dist/icons/PhFileArchive.svelte.d.ts +5 -0
- package/dist/icons/PhFileText.svelte +18 -0
- package/dist/icons/PhFileText.svelte.d.ts +5 -0
- package/dist/icons/PhHeadphones.svelte +17 -0
- package/dist/icons/PhHeadphones.svelte.d.ts +5 -0
- package/dist/icons/PhImage.svelte +18 -0
- package/dist/icons/PhImage.svelte.d.ts +5 -0
- package/dist/icons/PhListMagnifyingGlass.svelte +17 -0
- package/dist/icons/PhListMagnifyingGlass.svelte.d.ts +5 -0
- package/dist/icons/PhMagnifyingGlass.svelte +17 -0
- package/dist/icons/PhMagnifyingGlass.svelte.d.ts +5 -0
- package/dist/icons/PhMicrosoftExcelLogo.svelte +17 -0
- package/dist/icons/PhMicrosoftExcelLogo.svelte.d.ts +5 -0
- package/dist/icons/PhStar.svelte +18 -0
- package/dist/icons/PhStar.svelte.d.ts +5 -0
- package/dist/icons/PhUploadSimple.svelte +18 -0
- package/dist/icons/PhUploadSimple.svelte.d.ts +5 -0
- package/dist/icons/PhUser.svelte +18 -0
- package/dist/icons/PhUser.svelte.d.ts +5 -0
- package/dist/icons/PhVideoCamera.svelte +17 -0
- package/dist/icons/PhVideoCamera.svelte.d.ts +5 -0
- package/dist/index.d.ts +17 -4
- package/dist/index.js +17 -4
- package/dist/open-props/props.colors-oklch-hues.css +14 -0
- package/dist/open-props/props.colors-oklch.css +19 -0
- package/dist/open-props/props.gray-oklch.css +18 -0
- package/dist/theme.css +17 -5
- package/package.json +4 -3
- package/dist/components/button/Button.svelte +0 -33
- package/dist/gray-oklch.min.css +0 -1
- package/dist/green-hsl.min.css +0 -1
- package/dist/props.colors-oklch-hues.css +0 -14
- package/dist/props.colors-oklch.css +0 -19
- package/dist/props.gray-oklch.css +0 -18
- /package/dist/components/checkbox/{Checkbox-group.svelte.d.ts → checkbox-group.svelte.d.ts} +0 -0
- /package/dist/components/checkbox/{Checkbox.svelte.d.ts → checkbox.svelte.d.ts} +0 -0
- /package/dist/components/combobox/{Combobox.svelte.d.ts → combobox.svelte.d.ts} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
import { button, type ButtonVariant, type ButtonSize } from './button.variants';
|
|
4
|
+
|
|
5
|
+
type Props = Omit<HTMLButtonAttributes, 'class'> & {
|
|
6
|
+
variant?: ButtonVariant;
|
|
7
|
+
size?: ButtonSize;
|
|
8
|
+
class?: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
let { variant, size, class: className, children, ...rest }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<button class={button({ variant, size, class: className })} {...rest}>
|
|
15
|
+
{@render children?.()}
|
|
16
|
+
</button>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
2
|
+
import { type ButtonVariant, type ButtonSize } from './button.variants';
|
|
2
3
|
type Props = Omit<HTMLButtonAttributes, 'class'> & {
|
|
3
|
-
variant?:
|
|
4
|
-
size?:
|
|
4
|
+
variant?: ButtonVariant;
|
|
5
|
+
size?: ButtonSize;
|
|
5
6
|
class?: string;
|
|
6
7
|
};
|
|
7
8
|
declare const Button: import("svelte").Component<Props, {}, "">;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type VariantProps } from 'tailwind-variants';
|
|
2
|
+
export declare const button: import("tailwind-variants").TVReturnType<{
|
|
3
|
+
variant: {
|
|
4
|
+
default: string;
|
|
5
|
+
outline: string;
|
|
6
|
+
ghost: string;
|
|
7
|
+
};
|
|
8
|
+
size: {
|
|
9
|
+
sm: string;
|
|
10
|
+
default: string;
|
|
11
|
+
lg: string;
|
|
12
|
+
icon: string;
|
|
13
|
+
'icon-sm': string;
|
|
14
|
+
'icon-lg': string;
|
|
15
|
+
};
|
|
16
|
+
}, undefined, "focus-visible:outline-ring inline-flex cursor-pointer items-center justify-center rounded bg-transparent text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50", {
|
|
17
|
+
variant: {
|
|
18
|
+
default: string;
|
|
19
|
+
outline: string;
|
|
20
|
+
ghost: string;
|
|
21
|
+
};
|
|
22
|
+
size: {
|
|
23
|
+
sm: string;
|
|
24
|
+
default: string;
|
|
25
|
+
lg: string;
|
|
26
|
+
icon: string;
|
|
27
|
+
'icon-sm': string;
|
|
28
|
+
'icon-lg': string;
|
|
29
|
+
};
|
|
30
|
+
}, undefined, import("tailwind-variants").TVReturnType<{
|
|
31
|
+
variant: {
|
|
32
|
+
default: string;
|
|
33
|
+
outline: string;
|
|
34
|
+
ghost: string;
|
|
35
|
+
};
|
|
36
|
+
size: {
|
|
37
|
+
sm: string;
|
|
38
|
+
default: string;
|
|
39
|
+
lg: string;
|
|
40
|
+
icon: string;
|
|
41
|
+
'icon-sm': string;
|
|
42
|
+
'icon-lg': string;
|
|
43
|
+
};
|
|
44
|
+
}, undefined, "focus-visible:outline-ring inline-flex cursor-pointer items-center justify-center rounded bg-transparent text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50", unknown, unknown, undefined>>;
|
|
45
|
+
export type ButtonVariant = VariantProps<typeof button>['variant'];
|
|
46
|
+
export type ButtonSize = VariantProps<typeof button>['size'];
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { tv } from 'tailwind-variants';
|
|
2
|
+
export const button = tv({
|
|
3
|
+
base: 'focus-visible:outline-ring inline-flex cursor-pointer items-center justify-center rounded bg-transparent text-sm font-medium transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
|
4
|
+
variants: {
|
|
5
|
+
variant: {
|
|
6
|
+
default: 'bg-primary text-white hover:bg-primary/90 active:bg-primary/80',
|
|
7
|
+
outline: 'border text-ink hover:bg-surface-2',
|
|
8
|
+
ghost: 'text-ink hover:bg-surface-2'
|
|
9
|
+
},
|
|
10
|
+
size: {
|
|
11
|
+
sm: 'h-8 gap-1.5 px-2',
|
|
12
|
+
default: 'h-9 gap-2 px-3',
|
|
13
|
+
lg: 'h-10 gap-2.5 px-4',
|
|
14
|
+
icon: 'size-9',
|
|
15
|
+
'icon-sm': 'size-8',
|
|
16
|
+
'icon-lg': 'size-10'
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
defaultVariants: { variant: 'default', size: 'default' }
|
|
20
|
+
});
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PhArrowLeft from '../../icons/PhArrowLeft.svelte';
|
|
3
|
+
import PhArrowRight from '../../icons/PhArrowRight.svelte';
|
|
4
|
+
import PhCheck from '../../icons/PhCheck.svelte';
|
|
5
|
+
import PhImage from '../../icons/PhImage.svelte';
|
|
6
|
+
import PhStar from '../../icons/PhStar.svelte';
|
|
7
|
+
import { Carousel } from '@ark-ui/svelte/carousel';
|
|
8
|
+
import type { CarouselRootProps } from '@ark-ui/svelte/carousel';
|
|
9
|
+
|
|
10
|
+
interface ImageItem {
|
|
11
|
+
id?: string | number;
|
|
12
|
+
src: string;
|
|
13
|
+
alt?: string;
|
|
14
|
+
is_primary?: boolean;
|
|
15
|
+
position?: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Props extends Omit<CarouselRootProps, 'slideCount'> {
|
|
19
|
+
images: ImageItem[];
|
|
20
|
+
indicator?: boolean;
|
|
21
|
+
selectable?: boolean;
|
|
22
|
+
selectedIds?: (string | number)[];
|
|
23
|
+
onSetStar?: (id: string | number) => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
let {
|
|
27
|
+
images,
|
|
28
|
+
indicator = false,
|
|
29
|
+
selectable = false,
|
|
30
|
+
selectedIds = $bindable([]),
|
|
31
|
+
onSetStar,
|
|
32
|
+
...rootProps
|
|
33
|
+
}: Props = $props();
|
|
34
|
+
|
|
35
|
+
function toggleSelect(id: string | number) {
|
|
36
|
+
if (selectedIds.includes(id)) {
|
|
37
|
+
selectedIds = selectedIds.filter((i) => i !== id);
|
|
38
|
+
} else {
|
|
39
|
+
selectedIds = [...selectedIds, id];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
</script>
|
|
43
|
+
|
|
44
|
+
{#if images.length === 0}
|
|
45
|
+
<div
|
|
46
|
+
class="flex flex-col items-center justify-center gap-3 rounded-lg border-2 border-dashed py-12 text-center text-ink-dim"
|
|
47
|
+
>
|
|
48
|
+
<PhImage class="size-10 opacity-40" />
|
|
49
|
+
<p class="text-sm">No images yet.</p>
|
|
50
|
+
</div>
|
|
51
|
+
{:else}
|
|
52
|
+
<Carousel.Root slideCount={images.length} {...rootProps}>
|
|
53
|
+
<Carousel.Control class="flex items-center gap-2">
|
|
54
|
+
<Carousel.PrevTrigger
|
|
55
|
+
class="inline-flex size-9 items-center justify-center rounded-md border bg-surface-1 shadow-sm hover:bg-surface-2 active:bg-surface-3 disabled:opacity-50"
|
|
56
|
+
>
|
|
57
|
+
<PhArrowLeft class="size-4" />
|
|
58
|
+
</Carousel.PrevTrigger>
|
|
59
|
+
<Carousel.ItemGroup class="flex flex-1 overflow-hidden rounded-lg">
|
|
60
|
+
{#each images as image, index (image.id ?? index)}
|
|
61
|
+
{@const key = image.id ?? index}
|
|
62
|
+
{@const isSelected = selectable && selectedIds.includes(key)}
|
|
63
|
+
<Carousel.Item {index} class="min-w-0 flex-[0_0_100%]">
|
|
64
|
+
<div class="group/slide relative">
|
|
65
|
+
<img
|
|
66
|
+
src={image.src}
|
|
67
|
+
alt={image.alt ?? ''}
|
|
68
|
+
class="aspect-square w-full rounded-lg bg-surface-2 object-contain"
|
|
69
|
+
/>
|
|
70
|
+
{#if onSetStar && image.id != null}
|
|
71
|
+
<button
|
|
72
|
+
class="absolute top-2 left-2 z-10 transition-opacity {image.is_primary
|
|
73
|
+
? 'opacity-100'
|
|
74
|
+
: 'opacity-0 group-hover/slide:opacity-100'}"
|
|
75
|
+
title={image.is_primary ? 'Primary image' : 'Set as primary'}
|
|
76
|
+
onclick={() => onSetStar(image.id!)}
|
|
77
|
+
>
|
|
78
|
+
<PhStar
|
|
79
|
+
class="size-5 drop-shadow {image.is_primary
|
|
80
|
+
? 'fill-yellow-400 text-yellow-400'
|
|
81
|
+
: 'text-white/70 hover:text-yellow-300'}"
|
|
82
|
+
/>
|
|
83
|
+
</button>
|
|
84
|
+
{/if}
|
|
85
|
+
{#if selectable}
|
|
86
|
+
<button
|
|
87
|
+
class="absolute top-2 right-2 z-10 flex size-6 items-center justify-center rounded-full border-2 transition-all {isSelected
|
|
88
|
+
? 'border-primary bg-primary text-white opacity-100'
|
|
89
|
+
: 'border-white/80 bg-black/40 opacity-0 group-hover/slide:opacity-100'}"
|
|
90
|
+
onclick={() => toggleSelect(key)}
|
|
91
|
+
>
|
|
92
|
+
{#if isSelected}
|
|
93
|
+
<PhCheck class="size-3.5" />
|
|
94
|
+
{/if}
|
|
95
|
+
</button>
|
|
96
|
+
{/if}
|
|
97
|
+
</div>
|
|
98
|
+
</Carousel.Item>
|
|
99
|
+
{/each}
|
|
100
|
+
</Carousel.ItemGroup>
|
|
101
|
+
<Carousel.NextTrigger
|
|
102
|
+
class="inline-flex size-9 items-center justify-center rounded-md border bg-surface-1 shadow-sm hover:bg-surface-2 active:bg-surface-3 disabled:opacity-50"
|
|
103
|
+
>
|
|
104
|
+
<PhArrowRight class="size-4" />
|
|
105
|
+
</Carousel.NextTrigger>
|
|
106
|
+
</Carousel.Control>
|
|
107
|
+
{#if indicator}
|
|
108
|
+
<Carousel.IndicatorGroup class="mt-2 flex justify-center gap-2">
|
|
109
|
+
{#each images as image, index (index)}
|
|
110
|
+
<Carousel.Indicator
|
|
111
|
+
{index}
|
|
112
|
+
class="h-15 w-15 cursor-pointer overflow-hidden rounded-sm border-2 border-transparent opacity-60 transition-all data-current:border-primary data-current:opacity-100"
|
|
113
|
+
>
|
|
114
|
+
<img src={image.src} alt={image.alt ?? ''} class="h-full w-full object-cover" />
|
|
115
|
+
</Carousel.Indicator>
|
|
116
|
+
{/each}
|
|
117
|
+
</Carousel.IndicatorGroup>
|
|
118
|
+
{/if}
|
|
119
|
+
</Carousel.Root>
|
|
120
|
+
{/if}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Carousel } from '@ark-ui/svelte/carousel';
|
|
2
|
+
import type { CarouselRootProps } from '@ark-ui/svelte/carousel';
|
|
3
|
+
interface ImageItem {
|
|
4
|
+
id?: string | number;
|
|
5
|
+
src: string;
|
|
6
|
+
alt?: string;
|
|
7
|
+
is_primary?: boolean;
|
|
8
|
+
position?: number;
|
|
9
|
+
}
|
|
10
|
+
interface Props extends Omit<CarouselRootProps, 'slideCount'> {
|
|
11
|
+
images: ImageItem[];
|
|
12
|
+
indicator?: boolean;
|
|
13
|
+
selectable?: boolean;
|
|
14
|
+
selectedIds?: (string | number)[];
|
|
15
|
+
onSetStar?: (id: string | number) => void;
|
|
16
|
+
}
|
|
17
|
+
declare const Carousel: import("svelte").Component<Props, {}, "selectedIds">;
|
|
18
|
+
type Carousel = ReturnType<typeof Carousel>;
|
|
19
|
+
export default Carousel;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends string | number">
|
|
2
2
|
import { Checkbox } from '@ark-ui/svelte/checkbox';
|
|
3
3
|
import type { CheckboxGroupProps } from './checkbox-group.types';
|
|
4
|
-
import CheckboxItem from './
|
|
4
|
+
import CheckboxItem from './checkbox.svelte';
|
|
5
5
|
|
|
6
6
|
let {
|
|
7
7
|
items,
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Checkbox } from '@ark-ui/svelte/checkbox';
|
|
3
3
|
import type { CheckboxProps as Props } from './checkbox.types.js';
|
|
4
4
|
import PhCheck from '../../icons/PhCheck.svelte';
|
|
5
|
+
import PhMinus from '../../icons/PhMinus.svelte';
|
|
5
6
|
|
|
6
7
|
let { checked = $bindable(), label, children, ...rest }: Props = $props();
|
|
7
8
|
</script>
|
|
@@ -14,10 +15,13 @@
|
|
|
14
15
|
<Checkbox.Control
|
|
15
16
|
class="{children
|
|
16
17
|
? 'mt-0.5'
|
|
17
|
-
: ''} flex size-5 shrink-0 items-center justify-center rounded-sm border
|
|
18
|
+
: ''} data-focus-visible:outline-ring flex size-5 shrink-0 items-center justify-center rounded-sm border bg-transparent transition-colors hover:border-primary/50 data-disabled:pointer-events-none data-disabled:opacity-50 data-focus-visible:outline-2 data-focus-visible:outline-offset-2 data-invalid:border-danger data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary"
|
|
18
19
|
>
|
|
19
20
|
<Checkbox.Indicator>
|
|
20
|
-
<PhCheck class="size-3.5 text-
|
|
21
|
+
<PhCheck class="size-3.5 text-white" />
|
|
22
|
+
</Checkbox.Indicator>
|
|
23
|
+
<Checkbox.Indicator indeterminate>
|
|
24
|
+
<PhMinus class="size-3.5 text-white" />
|
|
21
25
|
</Checkbox.Indicator>
|
|
22
26
|
</Checkbox.Control>
|
|
23
27
|
{#if label}
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
placeholder,
|
|
17
17
|
layout = 'vertical',
|
|
18
18
|
name,
|
|
19
|
-
|
|
19
|
+
readOnly,
|
|
20
20
|
multiple,
|
|
21
|
+
loading = false,
|
|
21
22
|
...restProps
|
|
22
23
|
}: ComboboxProps<T> = $props();
|
|
23
24
|
|
|
@@ -91,21 +92,22 @@
|
|
|
91
92
|
onInputValueChange={handleInputChange}
|
|
92
93
|
openOnClick
|
|
93
94
|
{multiple}
|
|
94
|
-
readOnly
|
|
95
|
+
{readOnly}
|
|
95
96
|
{...restProps}
|
|
96
97
|
class={cn(layout === 'horizontal' ? 'flex items-center gap-1.5' : 'grid gap-1.5')}
|
|
97
98
|
>
|
|
98
99
|
{#if label}
|
|
99
|
-
<Combobox.Label>
|
|
100
|
+
<Combobox.Label class="text-sm">
|
|
100
101
|
{label}
|
|
101
|
-
<Field.RequiredIndicator />
|
|
102
|
+
<Field.RequiredIndicator class="text-danger" />
|
|
102
103
|
</Combobox.Label>
|
|
103
104
|
{/if}
|
|
104
105
|
|
|
105
106
|
<Combobox.Control
|
|
106
107
|
class={cn(
|
|
107
108
|
'rounded-ark flex min-h-9 items-center gap-1 border px-3 shadow-sm',
|
|
108
|
-
'focus-within:ring-1 focus-within:ring-
|
|
109
|
+
'focus-within:ring-1 focus-within:ring-primary',
|
|
110
|
+
'data-invalid:border-danger data-invalid:focus-within:ring-danger',
|
|
109
111
|
multiple && 'flex-wrap py-1'
|
|
110
112
|
)}
|
|
111
113
|
>
|
|
@@ -114,21 +116,8 @@
|
|
|
114
116
|
{#each value as v (v)}
|
|
115
117
|
{@const item = items.find((i) => i.value === v)}
|
|
116
118
|
{#if item}
|
|
117
|
-
<span
|
|
118
|
-
class="inline-flex items-center gap-1 rounded bg-(--ark-hover-bg) px-2 py-0.5 text-xs"
|
|
119
|
-
>
|
|
119
|
+
<span class="inline-flex items-center gap-1 rounded bg-surface-2 px-2 py-0.5 text-xs">
|
|
120
120
|
{item.label}
|
|
121
|
-
{#if !readonly}
|
|
122
|
-
<button
|
|
123
|
-
type="button"
|
|
124
|
-
onclick={() => {
|
|
125
|
-
value = (value as (number | string)[]).filter((x) => x !== v);
|
|
126
|
-
}}
|
|
127
|
-
class="hover:text-(--ark-error)"
|
|
128
|
-
>
|
|
129
|
-
<PhX class="size-3" />
|
|
130
|
-
</button>
|
|
131
|
-
{/if}
|
|
132
121
|
</span>
|
|
133
122
|
{/if}
|
|
134
123
|
{/each}
|
|
@@ -138,7 +127,7 @@
|
|
|
138
127
|
placeholder={placeholder ?? 'Search...'}
|
|
139
128
|
class="flex-1 bg-transparent text-sm outline-none placeholder:text-ink-dim disabled:cursor-not-allowed disabled:opacity-50"
|
|
140
129
|
/>
|
|
141
|
-
{#if
|
|
130
|
+
{#if !readOnly}
|
|
142
131
|
<Combobox.ClearTrigger class="text-ink-dim transition-colors hover:text-ink">
|
|
143
132
|
<PhX class="size-4" />
|
|
144
133
|
</Combobox.ClearTrigger>
|
|
@@ -153,11 +142,19 @@
|
|
|
153
142
|
<Combobox.Content
|
|
154
143
|
class="data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 z-50 max-h-60 min-w-(--reference-width) overflow-auto rounded-md border bg-surface-1 p-1 shadow-md"
|
|
155
144
|
>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
145
|
+
{#if loading}
|
|
146
|
+
<div class="flex items-center justify-center py-4">
|
|
147
|
+
<span
|
|
148
|
+
class="size-5 animate-spin rounded-full border-2 border-surface-3 border-t-ink-dim"
|
|
149
|
+
></span>
|
|
150
|
+
</div>
|
|
151
|
+
{:else}
|
|
152
|
+
<Combobox.Empty class="py-2 text-center text-sm text-ink-dim">
|
|
153
|
+
No results found
|
|
154
|
+
</Combobox.Empty>
|
|
155
|
+
{/if}
|
|
159
156
|
|
|
160
|
-
{#each collection.items as item (item.value)}
|
|
157
|
+
{#each loading ? [] : collection.items as item (item.value)}
|
|
161
158
|
<Combobox.Item
|
|
162
159
|
{item}
|
|
163
160
|
class="relative flex cursor-default items-center rounded-sm py-1.5 pr-8 pl-2 text-sm select-none data-disabled:pointer-events-none data-disabled:opacity-50 data-highlighted:bg-surface-2 data-[state=checked]:bg-surface-2"
|
|
@@ -9,8 +9,8 @@ export interface ComboboxProps<T extends ComboboxItem> extends Omit<ComboboxRoot
|
|
|
9
9
|
items: T[];
|
|
10
10
|
label?: string;
|
|
11
11
|
placeholder?: string;
|
|
12
|
-
readonly?: boolean;
|
|
13
12
|
name?: string;
|
|
14
13
|
multiple?: boolean;
|
|
15
14
|
layout?: 'vertical' | 'horizontal';
|
|
15
|
+
loading?: boolean;
|
|
16
16
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import PhX from '../../icons/PhX.svelte';
|
|
3
|
+
import { Dialog } from '@ark-ui/svelte/dialog';
|
|
4
|
+
import { Portal } from '@ark-ui/svelte/portal';
|
|
5
|
+
|
|
6
|
+
type Variant = 'default' | 'destructive';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
open: boolean;
|
|
10
|
+
title: string;
|
|
11
|
+
description?: string | string[];
|
|
12
|
+
confirmLabel?: string;
|
|
13
|
+
cancelLabel?: string;
|
|
14
|
+
onConfirm?: () => void;
|
|
15
|
+
variant?: Variant;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
open = $bindable(),
|
|
20
|
+
title,
|
|
21
|
+
description,
|
|
22
|
+
confirmLabel = 'Confirm',
|
|
23
|
+
cancelLabel = 'Cancel',
|
|
24
|
+
onConfirm,
|
|
25
|
+
variant = 'default'
|
|
26
|
+
}: Props = $props();
|
|
27
|
+
|
|
28
|
+
const confirmClass = $derived(
|
|
29
|
+
variant === 'destructive'
|
|
30
|
+
? 'inline-flex h-9 items-center justify-center rounded-md bg-red-600 px-4 text-sm font-medium text-white shadow-sm transition-colors hover:bg-red-700 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary'
|
|
31
|
+
: 'inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 text-sm font-medium text-white shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary'
|
|
32
|
+
);
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<Dialog.Root role="alertdialog" bind:open>
|
|
36
|
+
<Portal>
|
|
37
|
+
<Dialog.Backdrop
|
|
38
|
+
class="data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 fixed inset-0 z-50 bg-black/50"
|
|
39
|
+
/>
|
|
40
|
+
<Dialog.Positioner class="fixed inset-0 z-50 flex items-center justify-center">
|
|
41
|
+
<Dialog.Content
|
|
42
|
+
class="data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 relative w-full max-w-md rounded-lg border bg-surface-1 p-6 shadow-xl"
|
|
43
|
+
>
|
|
44
|
+
<Dialog.Title class="text-lg leading-none font-semibold tracking-tight">
|
|
45
|
+
{title}
|
|
46
|
+
</Dialog.Title>
|
|
47
|
+
{#if description}
|
|
48
|
+
<Dialog.Description class="mt-2 text-sm text-ink-dim">
|
|
49
|
+
{#each Array.isArray(description) ? description : [description] as line, i (i)}
|
|
50
|
+
<span class="block">{line}</span>
|
|
51
|
+
{/each}
|
|
52
|
+
</Dialog.Description>
|
|
53
|
+
{/if}
|
|
54
|
+
<div class="mt-6 flex justify-end gap-3">
|
|
55
|
+
<Dialog.CloseTrigger
|
|
56
|
+
class="inline-flex h-9 items-center justify-center rounded-md border bg-surface-1 px-4 text-sm font-medium shadow-sm transition-colors hover:bg-surface-2 hover:text-ink focus-visible:ring-1 focus-visible:ring-primary focus-visible:outline-none"
|
|
57
|
+
>
|
|
58
|
+
{cancelLabel}
|
|
59
|
+
</Dialog.CloseTrigger>
|
|
60
|
+
<button type="button" class={confirmClass} onclick={onConfirm}>
|
|
61
|
+
{confirmLabel}
|
|
62
|
+
</button>
|
|
63
|
+
</div>
|
|
64
|
+
<Dialog.CloseTrigger
|
|
65
|
+
class="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:outline-none"
|
|
66
|
+
>
|
|
67
|
+
<PhX class="h-4 w-4" />
|
|
68
|
+
<span class="sr-only">Close</span>
|
|
69
|
+
</Dialog.CloseTrigger>
|
|
70
|
+
</Dialog.Content>
|
|
71
|
+
</Dialog.Positioner>
|
|
72
|
+
</Portal>
|
|
73
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Variant = 'default' | 'destructive';
|
|
2
|
+
type Props = {
|
|
3
|
+
open: boolean;
|
|
4
|
+
title: string;
|
|
5
|
+
description?: string | string[];
|
|
6
|
+
confirmLabel?: string;
|
|
7
|
+
cancelLabel?: string;
|
|
8
|
+
onConfirm?: () => void;
|
|
9
|
+
variant?: Variant;
|
|
10
|
+
};
|
|
11
|
+
declare const AlertDialog: import("svelte").Component<Props, {}, "open">;
|
|
12
|
+
type AlertDialog = ReturnType<typeof AlertDialog>;
|
|
13
|
+
export default AlertDialog;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { Dialog } from '@ark-ui/svelte/dialog';
|
|
4
|
+
import { Portal } from '@ark-ui/svelte/portal';
|
|
5
|
+
import { cn } from 'tailwind-variants';
|
|
6
|
+
import PhX from '../../icons/PhX.svelte';
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
open: boolean;
|
|
10
|
+
title: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
children: Snippet;
|
|
13
|
+
footer?: Snippet;
|
|
14
|
+
onClose?: () => void;
|
|
15
|
+
contentClass?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
open = $bindable(),
|
|
20
|
+
title,
|
|
21
|
+
description,
|
|
22
|
+
children,
|
|
23
|
+
footer,
|
|
24
|
+
onClose,
|
|
25
|
+
contentClass
|
|
26
|
+
}: Props = $props();
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<Dialog.Root bind:open lazyMount unmountOnExit>
|
|
30
|
+
<Portal>
|
|
31
|
+
<Dialog.Backdrop
|
|
32
|
+
class="data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 fixed inset-0 z-50 bg-black/50"
|
|
33
|
+
/>
|
|
34
|
+
<Dialog.Positioner class="fixed inset-0 z-50 flex items-center justify-center p-4">
|
|
35
|
+
<Dialog.Content
|
|
36
|
+
class={cn(
|
|
37
|
+
'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 relative w-full max-w-2xl rounded-lg border bg-surface-1 p-6 shadow-xl',
|
|
38
|
+
contentClass
|
|
39
|
+
)}
|
|
40
|
+
>
|
|
41
|
+
<Dialog.Title class="text-lg font-semibold">{title}</Dialog.Title>
|
|
42
|
+
{#if description}
|
|
43
|
+
<Dialog.Description class="mt-1 text-sm text-ink-dim">
|
|
44
|
+
{description}
|
|
45
|
+
</Dialog.Description>
|
|
46
|
+
{/if}
|
|
47
|
+
|
|
48
|
+
<div class="mt-4">
|
|
49
|
+
{@render children()}
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
{#if footer}
|
|
53
|
+
<div class="mt-4 flex justify-end gap-3">
|
|
54
|
+
{@render footer()}
|
|
55
|
+
</div>
|
|
56
|
+
{/if}
|
|
57
|
+
|
|
58
|
+
<Dialog.CloseTrigger
|
|
59
|
+
class="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2 focus-visible:outline-none active:opacity-50"
|
|
60
|
+
onclick={onClose}
|
|
61
|
+
>
|
|
62
|
+
<PhX class="size-4" />
|
|
63
|
+
<span class="sr-only">Close</span>
|
|
64
|
+
</Dialog.CloseTrigger>
|
|
65
|
+
</Dialog.Content>
|
|
66
|
+
</Dialog.Positioner>
|
|
67
|
+
</Portal>
|
|
68
|
+
</Dialog.Root>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import { Dialog } from '@ark-ui/svelte/dialog';
|
|
3
|
+
interface Props {
|
|
4
|
+
open: boolean;
|
|
5
|
+
title: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
children: Snippet;
|
|
8
|
+
footer?: Snippet;
|
|
9
|
+
onClose?: () => void;
|
|
10
|
+
contentClass?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const Dialog: import("svelte").Component<Props, {}, "open">;
|
|
13
|
+
type Dialog = ReturnType<typeof Dialog>;
|
|
14
|
+
export default Dialog;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
3
|
+
import type { FieldErrorTextProps } from './types';
|
|
4
|
+
import { cn } from 'tailwind-variants';
|
|
5
|
+
|
|
6
|
+
let { class: className, children, ...rest }: FieldErrorTextProps = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Field.ErrorText {...rest} class={cn('text-xs font-medium text-danger', className)}>
|
|
10
|
+
{@render children?.()}
|
|
11
|
+
</Field.ErrorText>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
3
|
+
import type { FieldHelperTextProps } from './types';
|
|
4
|
+
import { cn } from 'tailwind-variants';
|
|
5
|
+
|
|
6
|
+
let { class: className, children, ...rest }: FieldHelperTextProps = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Field.HelperText {...rest} class={cn('text-xs text-ink-dim', className)}>
|
|
10
|
+
{@render children?.()}
|
|
11
|
+
</Field.HelperText>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
3
|
+
import type { FieldInputProps } from './types';
|
|
4
|
+
import { cn } from 'tailwind-variants';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
class: className,
|
|
8
|
+
value = $bindable(),
|
|
9
|
+
startIcon,
|
|
10
|
+
endIcon,
|
|
11
|
+
...rest
|
|
12
|
+
}: FieldInputProps = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<div class="relative w-full">
|
|
16
|
+
{#if startIcon}
|
|
17
|
+
<div
|
|
18
|
+
class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2.5 text-ink-dim"
|
|
19
|
+
>
|
|
20
|
+
{@render startIcon()}
|
|
21
|
+
</div>
|
|
22
|
+
{/if}
|
|
23
|
+
<Field.Input
|
|
24
|
+
{...rest}
|
|
25
|
+
bind:value
|
|
26
|
+
class={cn(
|
|
27
|
+
'flex h-9 w-full rounded-md border bg-surface-1 px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-ink-dim focus-visible:ring-1 focus-visible:ring-primary focus-visible:outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-invalid:border-danger data-invalid:focus-visible:ring-danger data-readonly:cursor-default data-readonly:opacity-70',
|
|
28
|
+
startIcon && 'pl-9',
|
|
29
|
+
endIcon && 'pr-9',
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
/>
|
|
33
|
+
{#if endIcon}
|
|
34
|
+
<div class="absolute inset-y-0 right-0 flex items-center pr-2.5">
|
|
35
|
+
{@render endIcon()}
|
|
36
|
+
</div>
|
|
37
|
+
{/if}
|
|
38
|
+
</div>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Field } from '@ark-ui/svelte/field';
|
|
3
|
+
import type { FieldLabelProps } from './types';
|
|
4
|
+
import { cn } from 'tailwind-variants';
|
|
5
|
+
|
|
6
|
+
let { class: className, children, ...rest }: FieldLabelProps = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Field.Label
|
|
10
|
+
{...rest}
|
|
11
|
+
class={cn(
|
|
12
|
+
'text-sm leading-none font-medium data-disabled:cursor-not-allowed data-disabled:opacity-70',
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
>
|
|
16
|
+
{@render children?.()}
|
|
17
|
+
<Field.RequiredIndicator class="ml-1 text-danger" />
|
|
18
|
+
</Field.Label>
|