@revojs/ui 0.2.11 → 0.2.13
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.d.ts +1 -0
- package/dist/components/card.d.ts +8 -2
- package/dist/components/collection.d.ts +3 -0
- package/dist/components/container.d.ts +2 -3
- package/dist/components/dialog.d.ts +3 -3
- package/dist/components/entry.d.ts +6 -0
- package/dist/components/entry.js +1 -0
- package/dist/components/field.d.ts +4 -0
- package/dist/components/input.d.ts +3 -0
- package/dist/components/notification.d.ts +9 -0
- package/dist/components/notification.js +1 -0
- package/dist/components/pagination.d.ts +8 -0
- package/dist/components/pagination.js +1 -0
- package/dist/components/popover.d.ts +9 -1
- package/dist/components/select.d.ts +8 -5
- package/dist/components/sheet.d.ts +3 -3
- package/dist/components/shell.d.ts +6 -0
- package/dist/components/shell.js +1 -0
- package/dist/components/textarea.d.ts +13 -0
- package/dist/components/textarea.js +1 -0
- package/dist/components/upload.d.ts +2 -0
- package/dist/index.d.ts +5 -0
- package/dist/module/index.d.ts +16 -0
- package/dist/module/index.js +32 -0
- package/dist/style.css +16 -0
- package/dist/vue/components/breadcrumb.vue +6 -1
- package/dist/vue/components/button.vue +34 -13
- package/dist/vue/components/card.vue +27 -14
- package/dist/vue/components/checkbox.vue +18 -4
- package/dist/vue/components/collection.vue +22 -7
- package/dist/vue/components/container.vue +11 -2
- package/dist/vue/components/counter.vue +7 -4
- package/dist/vue/components/dialog.vue +53 -36
- package/dist/vue/components/entry.vue +52 -0
- package/dist/vue/components/field.vue +44 -9
- package/dist/vue/components/input.vue +33 -6
- package/dist/vue/components/link.vue +1 -1
- package/dist/vue/components/navigate.vue +1 -0
- package/dist/vue/components/notification.vue +58 -0
- package/dist/vue/components/pagination.vue +24 -0
- package/dist/vue/components/popover.vue +46 -18
- package/dist/vue/components/progress.vue +2 -2
- package/dist/vue/components/radio.vue +19 -5
- package/dist/vue/components/range.vue +1 -1
- package/dist/vue/components/rating.vue +2 -2
- package/dist/vue/components/select.vue +116 -35
- package/dist/vue/components/separator.vue +2 -2
- package/dist/vue/components/sheet.vue +56 -22
- package/dist/vue/components/shell.vue +38 -0
- package/dist/vue/components/switch.vue +21 -7
- package/dist/vue/components/textarea.vue +49 -0
- package/dist/vue/components/upload.vue +74 -23
- package/dist/vue/index.d.ts +5 -0
- package/dist/vue/index.js +6 -1
- package/dist/vue/utilities/use-control-attributes.d.ts +11 -0
- package/dist/vue/utilities/use-control-attributes.js +14 -0
- package/dist/vue/utilities/use-modal-dialog.d.ts +9 -0
- package/dist/vue/utilities/use-modal-dialog.js +48 -0
- package/package.json +1 -1
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import type { StackProps } from "./stack";
|
|
1
2
|
export interface CardProps {
|
|
2
3
|
label?: string;
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
labelId?: string;
|
|
5
|
+
bodyPadding?: StackProps["padding"];
|
|
6
|
+
bodyGap?: StackProps["gap"];
|
|
7
|
+
bodyDirection?: StackProps["direction"];
|
|
8
|
+
bodyAlign?: StackProps["align"];
|
|
9
|
+
bodyJustify?: StackProps["justify"];
|
|
10
|
+
bodyWrap?: StackProps["wrap"];
|
|
5
11
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { StackProps } from "./stack";
|
|
1
2
|
export type CollectionColumns = 1 | 2 | 3 | 4;
|
|
2
3
|
export interface CollectionProps<T = unknown> {
|
|
3
4
|
items?: Array<T>;
|
|
4
5
|
columns?: CollectionColumns;
|
|
6
|
+
gap?: StackProps["gap"];
|
|
7
|
+
itemKey?: keyof T | ((item: T, index: number) => string | number);
|
|
5
8
|
emptyLabel?: string;
|
|
6
9
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { StackProps } from "./stack";
|
|
2
2
|
export type ContainerSize = "3xl" | "5xl" | "7xl";
|
|
3
|
-
export interface ContainerProps {
|
|
3
|
+
export interface ContainerProps extends StackProps {
|
|
4
4
|
size?: ContainerSize;
|
|
5
|
-
padding?: StackGap;
|
|
6
5
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { IconComponent } from "./icon";
|
|
2
|
+
export type InputText = "sm" | "md";
|
|
2
3
|
export interface InputProps {
|
|
3
4
|
modelValue?: string | number;
|
|
4
5
|
type?: string;
|
|
6
|
+
text?: InputText;
|
|
5
7
|
iconPrefix?: IconComponent;
|
|
6
8
|
iconSuffix?: IconComponent;
|
|
7
9
|
placeholder?: string;
|
|
@@ -10,4 +12,5 @@ export interface InputProps {
|
|
|
10
12
|
required?: boolean;
|
|
11
13
|
readonly?: boolean;
|
|
12
14
|
disabled?: boolean;
|
|
15
|
+
invalid?: boolean;
|
|
13
16
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IconComponent } from "./icon";
|
|
2
|
+
export type NotificationVariant = "error" | "attention" | "success" | "info";
|
|
3
|
+
export interface NotificationProps {
|
|
4
|
+
label?: string;
|
|
5
|
+
subtext?: string;
|
|
6
|
+
icon?: IconComponent;
|
|
7
|
+
variant?: NotificationVariant;
|
|
8
|
+
announce?: boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import type { ButtonLayout } from "./button";
|
|
1
|
+
import type { ButtonLayout, ButtonVariant } from "./button";
|
|
2
|
+
import type { StackProps } from "./stack";
|
|
2
3
|
export interface PopoverProps {
|
|
3
4
|
modelValue?: boolean;
|
|
4
5
|
triggerLabel?: string;
|
|
5
6
|
triggerClass?: string;
|
|
6
7
|
triggerLayout?: ButtonLayout;
|
|
8
|
+
triggerVariant?: ButtonVariant;
|
|
7
9
|
contentClass?: string;
|
|
10
|
+
contentPadding?: StackProps["padding"];
|
|
11
|
+
contentGap?: StackProps["gap"];
|
|
12
|
+
contentDirection?: StackProps["direction"];
|
|
13
|
+
contentAlign?: StackProps["align"];
|
|
14
|
+
contentJustify?: StackProps["justify"];
|
|
15
|
+
contentWrap?: StackProps["wrap"];
|
|
8
16
|
matchTriggerWidth?: boolean;
|
|
9
17
|
disabled?: boolean;
|
|
10
18
|
}
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
export type SelectValue = string | number;
|
|
2
2
|
export type SelectValueState = "placeholder" | "selected";
|
|
3
|
-
export interface SelectOption {
|
|
3
|
+
export interface SelectOption<Value extends SelectValue = SelectValue> {
|
|
4
4
|
label: string;
|
|
5
|
-
value:
|
|
5
|
+
value: Value;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}
|
|
8
|
-
export interface SelectProps {
|
|
9
|
-
modelValue?:
|
|
10
|
-
options: Array<SelectOption
|
|
8
|
+
export interface SelectProps<Value extends SelectValue = SelectValue> {
|
|
9
|
+
modelValue?: Value;
|
|
10
|
+
options: Array<SelectOption<Value>>;
|
|
11
11
|
label?: string;
|
|
12
12
|
placeholder?: string;
|
|
13
13
|
emptyLabel?: string;
|
|
14
14
|
name?: string;
|
|
15
15
|
required?: boolean;
|
|
16
16
|
disabled?: boolean;
|
|
17
|
+
searchable?: boolean;
|
|
18
|
+
invalid?: boolean;
|
|
19
|
+
requiredLabel?: string;
|
|
17
20
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { CardProps } from "./card";
|
|
1
2
|
export type SheetSide = "top" | "right" | "bottom" | "left";
|
|
2
|
-
export interface SheetProps {
|
|
3
|
+
export interface SheetProps extends CardProps {
|
|
3
4
|
modelValue?: boolean;
|
|
4
5
|
side?: SheetSide;
|
|
5
|
-
title?: string;
|
|
6
|
-
description?: string;
|
|
7
6
|
closeLabel?: string;
|
|
7
|
+
dismissible?: boolean;
|
|
8
8
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TextareaText = "sm" | "md";
|
|
2
|
+
export type TextareaResize = "none" | "vertical" | "horizontal" | "both";
|
|
3
|
+
export type TextareaVariant = "default" | "plain";
|
|
4
|
+
export interface TextareaProps {
|
|
5
|
+
modelValue?: string;
|
|
6
|
+
text?: TextareaText;
|
|
7
|
+
resize?: TextareaResize;
|
|
8
|
+
variant?: TextareaVariant;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
readonly?: boolean;
|
|
11
|
+
required?: boolean;
|
|
12
|
+
invalid?: boolean;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export type UploadState = "idle" | "over";
|
|
2
|
+
export type UploadText = "sm" | "md";
|
|
2
3
|
export interface UploadProps {
|
|
3
4
|
modelValue?: Blob | File;
|
|
4
5
|
label?: string;
|
|
5
6
|
description?: string;
|
|
7
|
+
text?: UploadText;
|
|
6
8
|
accept?: string;
|
|
7
9
|
name?: string;
|
|
8
10
|
required?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,11 +9,15 @@ export type * from "./components/counter";
|
|
|
9
9
|
export type * from "./components/dialog";
|
|
10
10
|
export type * from "./components/field";
|
|
11
11
|
export type * from "./components/heading";
|
|
12
|
+
export type * from "./components/shell";
|
|
12
13
|
export type * from "./components/icon";
|
|
13
14
|
export type * from "./components/input";
|
|
14
15
|
export type * from "./components/link";
|
|
16
|
+
export type * from "./components/entry";
|
|
17
|
+
export type * from "./components/notification";
|
|
15
18
|
export type * from "./components/navigate";
|
|
16
19
|
export type * from "./components/popover";
|
|
20
|
+
export type * from "./components/pagination";
|
|
17
21
|
export type * from "./components/progress";
|
|
18
22
|
export type * from "./components/radio";
|
|
19
23
|
export type * from "./components/range";
|
|
@@ -24,3 +28,4 @@ export type * from "./components/sheet";
|
|
|
24
28
|
export type * from "./components/stack";
|
|
25
29
|
export type * from "./components/switch";
|
|
26
30
|
export type * from "./components/upload";
|
|
31
|
+
export type * from "./components/textarea";
|
package/dist/module/index.d.ts
CHANGED
|
@@ -13,15 +13,31 @@ export interface UiTheme {
|
|
|
13
13
|
popover: TailwindColor;
|
|
14
14
|
popoverForeground: TailwindColor;
|
|
15
15
|
primary: TailwindColor;
|
|
16
|
+
primaryHover: TailwindColor;
|
|
17
|
+
primaryActive: TailwindColor;
|
|
16
18
|
primaryForeground: TailwindColor;
|
|
17
19
|
secondary: TailwindColor;
|
|
20
|
+
secondaryHover: TailwindColor;
|
|
21
|
+
secondaryActive: TailwindColor;
|
|
18
22
|
secondaryForeground: TailwindColor;
|
|
19
23
|
muted: TailwindColor;
|
|
20
24
|
mutedForeground: TailwindColor;
|
|
21
25
|
accent: TailwindColor;
|
|
22
26
|
accentForeground: TailwindColor;
|
|
27
|
+
ghostHover: TailwindColor;
|
|
28
|
+
ghostActive: TailwindColor;
|
|
23
29
|
destructive: TailwindColor;
|
|
30
|
+
destructiveHover: TailwindColor;
|
|
31
|
+
destructiveActive: TailwindColor;
|
|
24
32
|
destructiveForeground: TailwindColor;
|
|
33
|
+
attention: TailwindColor;
|
|
34
|
+
attentionHover: TailwindColor;
|
|
35
|
+
attentionActive: TailwindColor;
|
|
36
|
+
attentionForeground: TailwindColor;
|
|
37
|
+
success: TailwindColor;
|
|
38
|
+
successHover: TailwindColor;
|
|
39
|
+
successActive: TailwindColor;
|
|
40
|
+
successForeground: TailwindColor;
|
|
25
41
|
border: TailwindColor;
|
|
26
42
|
input: TailwindColor;
|
|
27
43
|
ring: TailwindColor;
|
package/dist/module/index.js
CHANGED
|
@@ -37,15 +37,31 @@ var module_default = defineModule({
|
|
|
37
37
|
popover: "white",
|
|
38
38
|
popoverForeground: "zinc-950",
|
|
39
39
|
primary: "zinc-950",
|
|
40
|
+
primaryHover: "zinc-900",
|
|
41
|
+
primaryActive: "zinc-800",
|
|
40
42
|
primaryForeground: "white",
|
|
41
43
|
secondary: "zinc-100",
|
|
44
|
+
secondaryHover: "zinc-200",
|
|
45
|
+
secondaryActive: "zinc-300",
|
|
42
46
|
secondaryForeground: "zinc-900",
|
|
43
47
|
muted: "zinc-100",
|
|
44
48
|
mutedForeground: "zinc-500",
|
|
45
49
|
accent: "zinc-100",
|
|
46
50
|
accentForeground: "zinc-900",
|
|
51
|
+
ghostHover: "zinc-100",
|
|
52
|
+
ghostActive: "zinc-200",
|
|
47
53
|
destructive: "red-500",
|
|
54
|
+
destructiveHover: "red-600",
|
|
55
|
+
destructiveActive: "red-700",
|
|
48
56
|
destructiveForeground: "zinc-50",
|
|
57
|
+
attention: "yellow-700",
|
|
58
|
+
attentionHover: "yellow-800",
|
|
59
|
+
attentionActive: "yellow-900",
|
|
60
|
+
attentionForeground: "white",
|
|
61
|
+
success: "green-700",
|
|
62
|
+
successHover: "green-800",
|
|
63
|
+
successActive: "green-900",
|
|
64
|
+
successForeground: "white",
|
|
49
65
|
border: "zinc-200",
|
|
50
66
|
input: "zinc-200",
|
|
51
67
|
ring: "zinc-400"
|
|
@@ -58,15 +74,31 @@ var module_default = defineModule({
|
|
|
58
74
|
popover: "zinc-950",
|
|
59
75
|
popoverForeground: "zinc-50",
|
|
60
76
|
primary: "white",
|
|
77
|
+
primaryHover: "zinc-100",
|
|
78
|
+
primaryActive: "zinc-200",
|
|
61
79
|
primaryForeground: "zinc-950",
|
|
62
80
|
secondary: "zinc-900",
|
|
81
|
+
secondaryHover: "zinc-800",
|
|
82
|
+
secondaryActive: "zinc-700",
|
|
63
83
|
secondaryForeground: "zinc-50",
|
|
64
84
|
muted: "zinc-900",
|
|
65
85
|
mutedForeground: "zinc-400",
|
|
66
86
|
accent: "zinc-900",
|
|
67
87
|
accentForeground: "zinc-50",
|
|
88
|
+
ghostHover: "zinc-900",
|
|
89
|
+
ghostActive: "zinc-800",
|
|
68
90
|
destructive: "red-500",
|
|
91
|
+
destructiveHover: "red-600",
|
|
92
|
+
destructiveActive: "red-700",
|
|
69
93
|
destructiveForeground: "zinc-50",
|
|
94
|
+
attention: "yellow-400",
|
|
95
|
+
attentionHover: "yellow-500",
|
|
96
|
+
attentionActive: "yellow-600",
|
|
97
|
+
attentionForeground: "zinc-950",
|
|
98
|
+
success: "green-400",
|
|
99
|
+
successHover: "green-500",
|
|
100
|
+
successActive: "green-600",
|
|
101
|
+
successForeground: "zinc-950",
|
|
70
102
|
border: "zinc-700",
|
|
71
103
|
input: "zinc-700",
|
|
72
104
|
ring: "zinc-700"
|
package/dist/style.css
CHANGED
|
@@ -10,15 +10,31 @@
|
|
|
10
10
|
--color-popover: var(--ui-popover);
|
|
11
11
|
--color-popover-foreground: var(--ui-popover-foreground);
|
|
12
12
|
--color-primary: var(--ui-primary);
|
|
13
|
+
--color-primary-hover: var(--ui-primary-hover);
|
|
14
|
+
--color-primary-active: var(--ui-primary-active);
|
|
13
15
|
--color-primary-foreground: var(--ui-primary-foreground);
|
|
14
16
|
--color-secondary: var(--ui-secondary);
|
|
17
|
+
--color-secondary-hover: var(--ui-secondary-hover);
|
|
18
|
+
--color-secondary-active: var(--ui-secondary-active);
|
|
15
19
|
--color-secondary-foreground: var(--ui-secondary-foreground);
|
|
16
20
|
--color-muted: var(--ui-muted);
|
|
17
21
|
--color-muted-foreground: var(--ui-muted-foreground);
|
|
18
22
|
--color-accent: var(--ui-accent);
|
|
19
23
|
--color-accent-foreground: var(--ui-accent-foreground);
|
|
24
|
+
--color-ghost-hover: var(--ui-ghost-hover);
|
|
25
|
+
--color-ghost-active: var(--ui-ghost-active);
|
|
20
26
|
--color-destructive: var(--ui-destructive);
|
|
27
|
+
--color-destructive-hover: var(--ui-destructive-hover);
|
|
28
|
+
--color-destructive-active: var(--ui-destructive-active);
|
|
21
29
|
--color-destructive-foreground: var(--ui-destructive-foreground);
|
|
30
|
+
--color-attention: var(--ui-attention);
|
|
31
|
+
--color-attention-hover: var(--ui-attention-hover);
|
|
32
|
+
--color-attention-active: var(--ui-attention-active);
|
|
33
|
+
--color-attention-foreground: var(--ui-attention-foreground);
|
|
34
|
+
--color-success: var(--ui-success);
|
|
35
|
+
--color-success-hover: var(--ui-success-hover);
|
|
36
|
+
--color-success-active: var(--ui-success-active);
|
|
37
|
+
--color-success-foreground: var(--ui-success-foreground);
|
|
22
38
|
--color-border: var(--ui-border);
|
|
23
39
|
--color-input: var(--ui-input);
|
|
24
40
|
--color-ring: var(--ui-ring);
|
|
@@ -11,7 +11,12 @@
|
|
|
11
11
|
>
|
|
12
12
|
<span v-if="index" aria-hidden="true" class="opacity-40"> / </span>
|
|
13
13
|
|
|
14
|
-
<Link
|
|
14
|
+
<Link
|
|
15
|
+
:href="href"
|
|
16
|
+
:label="label"
|
|
17
|
+
:variant="index === routes.length - 1 ? 'primary' : 'muted'"
|
|
18
|
+
:aria-current="index === routes.length - 1 ? 'page' : undefined"
|
|
19
|
+
/>
|
|
15
20
|
</Stack>
|
|
16
21
|
</Stack>
|
|
17
22
|
</nav>
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="is"
|
|
4
|
-
class="inline-flex cursor-pointer items-center justify-center gap-1 rounded-ui
|
|
4
|
+
class="inline-flex shrink-0 cursor-pointer items-center justify-center gap-1 truncate rounded-ui font-[inherit] no-underline outline-ring select-none focus-visible:outline-2 focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 aria-disabled:cursor-not-allowed aria-disabled:opacity-50"
|
|
5
5
|
:class="[fonts[font], layouts[layout], sizes[size], texts[text], variants[variant]]"
|
|
6
|
-
:type="attributes.type ?? 'button'"
|
|
7
|
-
:disabled="disabled"
|
|
6
|
+
:type="is === 'a' ? undefined : (attributes.type ?? 'button')"
|
|
7
|
+
:disabled="is === 'a' ? undefined : disabled || loading"
|
|
8
|
+
:aria-disabled="disabled || loading || undefined"
|
|
9
|
+
:aria-busy="loading || undefined"
|
|
10
|
+
@click="click"
|
|
8
11
|
>
|
|
9
|
-
<
|
|
12
|
+
<span
|
|
13
|
+
v-if="loading"
|
|
14
|
+
aria-hidden="true"
|
|
15
|
+
class="size-5 shrink-0 animate-spin rounded-full border-2 border-current border-r-transparent"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<Icon v-else-if="iconPrefix" :is="iconPrefix" :size="iconSize[text]" />
|
|
10
19
|
|
|
11
20
|
<slot>
|
|
12
21
|
<span v-if="label" class="truncate px-1" :class="labelLayouts[layout]">{{ label }}</span>
|
|
@@ -33,12 +42,13 @@ const {
|
|
|
33
42
|
iconPrefix,
|
|
34
43
|
iconSuffix,
|
|
35
44
|
label,
|
|
36
|
-
font = "
|
|
45
|
+
font = "semibold",
|
|
37
46
|
layout = "center",
|
|
38
47
|
size = "default",
|
|
39
48
|
text = "sm",
|
|
40
49
|
variant = "primary",
|
|
41
50
|
disabled = false,
|
|
51
|
+
loading = false,
|
|
42
52
|
} = defineProps<
|
|
43
53
|
Omit<ButtonProps, "type"> & {
|
|
44
54
|
is?: string | Component;
|
|
@@ -47,6 +57,18 @@ const {
|
|
|
47
57
|
|
|
48
58
|
const attributes = useAttrs();
|
|
49
59
|
|
|
60
|
+
const emit = defineEmits<{ click: [event: MouseEvent] }>();
|
|
61
|
+
|
|
62
|
+
function click(event: MouseEvent) {
|
|
63
|
+
if (disabled || loading) {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
event.stopImmediatePropagation();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
emit("click", event);
|
|
70
|
+
}
|
|
71
|
+
|
|
50
72
|
const fonts: Record<ButtonFont, string> = {
|
|
51
73
|
normal: "font-normal",
|
|
52
74
|
medium: "font-medium",
|
|
@@ -66,8 +88,8 @@ const labelLayouts: Record<ButtonLayout, string> = {
|
|
|
66
88
|
};
|
|
67
89
|
|
|
68
90
|
const sizes: Record<ButtonSize, string> = {
|
|
69
|
-
default: "
|
|
70
|
-
icon: "
|
|
91
|
+
default: "p-3",
|
|
92
|
+
icon: "p-3",
|
|
71
93
|
};
|
|
72
94
|
|
|
73
95
|
const texts: Record<ButtonText, string> = {
|
|
@@ -81,12 +103,11 @@ const iconSize: Record<ButtonText, number> = {
|
|
|
81
103
|
};
|
|
82
104
|
|
|
83
105
|
const variants: Record<ButtonVariant, string> = {
|
|
84
|
-
primary: "
|
|
85
|
-
secondary: "
|
|
106
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary-hover active:bg-primary-active",
|
|
107
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary-hover active:bg-secondary-active",
|
|
86
108
|
outline:
|
|
87
|
-
"
|
|
88
|
-
ghost: "
|
|
89
|
-
destructive:
|
|
90
|
-
"border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/90 active:bg-destructive/80",
|
|
109
|
+
"bg-secondary text-secondary-foreground ring-1 ring-border ring-inset hover:bg-secondary-hover active:bg-secondary-active",
|
|
110
|
+
ghost: "bg-transparent text-foreground hover:bg-ghost-hover active:bg-ghost-active",
|
|
111
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive-hover active:bg-destructive-active",
|
|
91
112
|
};
|
|
92
113
|
</script>
|
|
@@ -1,33 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Stack is="section" gap="0" class="rounded-ui border border-border bg-card text-card-foreground
|
|
2
|
+
<Stack is="section" gap="0" class="w-full rounded-ui border border-border bg-card text-card-foreground">
|
|
3
3
|
<Stack
|
|
4
|
-
v-if="label ||
|
|
4
|
+
v-if="label || $slots.header || $slots.actions"
|
|
5
5
|
is="header"
|
|
6
6
|
direction="horizontal"
|
|
7
7
|
align="center"
|
|
8
8
|
justify="between"
|
|
9
|
-
class="border-b border-border
|
|
9
|
+
class="shrink-0 border-b border-border"
|
|
10
10
|
>
|
|
11
11
|
<slot name="header">
|
|
12
|
-
<
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<h3 v-if="title" class="text-lg font-semibold leading-none">{{ title }}</h3>
|
|
16
|
-
|
|
17
|
-
<p v-if="description" class="text-sm opacity-70">{{ description }}</p>
|
|
18
|
-
</Stack>
|
|
12
|
+
<span v-if="label" :id="labelId" class="min-w-0 flex-1 px-5 py-3 text-sm/5 font-normal">
|
|
13
|
+
{{ label }}
|
|
14
|
+
</span>
|
|
19
15
|
</slot>
|
|
20
16
|
|
|
21
|
-
<Stack v-if="$slots.actions" direction="horizontal" align="center" class="shrink-0">
|
|
17
|
+
<Stack v-if="$slots.actions" direction="horizontal" align="center" class="ml-auto shrink-0">
|
|
22
18
|
<slot name="actions" />
|
|
23
19
|
</Stack>
|
|
24
20
|
</Stack>
|
|
25
21
|
|
|
26
|
-
<Stack
|
|
22
|
+
<Stack
|
|
23
|
+
:gap="bodyGap"
|
|
24
|
+
:padding="bodyPadding"
|
|
25
|
+
:direction="bodyDirection"
|
|
26
|
+
:align="bodyAlign"
|
|
27
|
+
:justify="bodyJustify"
|
|
28
|
+
:wrap="bodyWrap"
|
|
29
|
+
class="min-h-0 flex-1"
|
|
30
|
+
>
|
|
27
31
|
<slot />
|
|
28
32
|
</Stack>
|
|
29
33
|
|
|
30
|
-
<Stack v-if="$slots.footer" is="footer" direction="horizontal" align="center"
|
|
34
|
+
<Stack v-if="$slots.footer" is="footer" direction="horizontal" align="center" class="shrink-0 px-5 pb-5">
|
|
31
35
|
<slot name="footer" />
|
|
32
36
|
</Stack>
|
|
33
37
|
</Stack>
|
|
@@ -37,5 +41,14 @@
|
|
|
37
41
|
import type { CardProps } from "../../components/card";
|
|
38
42
|
import Stack from "./stack.vue";
|
|
39
43
|
|
|
40
|
-
const {
|
|
44
|
+
const {
|
|
45
|
+
label,
|
|
46
|
+
labelId,
|
|
47
|
+
bodyPadding = "5",
|
|
48
|
+
bodyGap = "5",
|
|
49
|
+
bodyDirection,
|
|
50
|
+
bodyAlign,
|
|
51
|
+
bodyJustify,
|
|
52
|
+
bodyWrap,
|
|
53
|
+
} = defineProps<CardProps>();
|
|
41
54
|
</script>
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Stack
|
|
2
|
+
<Stack
|
|
3
|
+
is="label"
|
|
4
|
+
direction="horizontal"
|
|
5
|
+
align="start"
|
|
6
|
+
gap="3"
|
|
7
|
+
class="group"
|
|
8
|
+
:class="interactionVariants[interaction]"
|
|
9
|
+
>
|
|
3
10
|
<input
|
|
4
11
|
class="peer sr-only"
|
|
5
12
|
type="checkbox"
|
|
@@ -12,8 +19,15 @@
|
|
|
12
19
|
|
|
13
20
|
<span
|
|
14
21
|
aria-hidden="true"
|
|
15
|
-
class="mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-ui border
|
|
16
|
-
:class="
|
|
22
|
+
class="mt-0.5 flex size-5 shrink-0 items-center justify-center rounded-ui border peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ring"
|
|
23
|
+
:class="[
|
|
24
|
+
modelValue ? 'border-transparent bg-primary' : 'border-input bg-background',
|
|
25
|
+
disabled
|
|
26
|
+
? ''
|
|
27
|
+
: modelValue
|
|
28
|
+
? 'group-hover:bg-primary-hover group-active:bg-primary-active'
|
|
29
|
+
: 'group-hover:bg-secondary-hover group-active:bg-secondary-active',
|
|
30
|
+
]"
|
|
17
31
|
>
|
|
18
32
|
<span
|
|
19
33
|
v-if="modelValue"
|
|
@@ -22,7 +36,7 @@
|
|
|
22
36
|
</span>
|
|
23
37
|
|
|
24
38
|
<Stack is="span" v-if="label || description || $slots.default" gap="0">
|
|
25
|
-
<span class="text-sm font-
|
|
39
|
+
<span class="text-sm font-normal"
|
|
26
40
|
><slot>{{ label }}</slot></span
|
|
27
41
|
>
|
|
28
42
|
<span v-if="description" class="text-sm opacity-60">{{ description }}</span>
|
|
@@ -5,17 +5,22 @@
|
|
|
5
5
|
class="w-full divide-y divide-border overflow-hidden rounded-ui border border-border bg-card"
|
|
6
6
|
>
|
|
7
7
|
<template v-if="items.length">
|
|
8
|
-
<div
|
|
8
|
+
<div
|
|
9
|
+
v-for="(item, index) in items"
|
|
10
|
+
:key="typeof itemKey === 'function' ? itemKey(item, index) : itemKey ? String(item[itemKey]) : index"
|
|
11
|
+
>
|
|
9
12
|
<slot :item="item" :index="index" />
|
|
10
13
|
</div>
|
|
11
14
|
</template>
|
|
12
|
-
<
|
|
13
|
-
<
|
|
15
|
+
<slot v-else name="empty">
|
|
16
|
+
<Stack align="center" padding="5">
|
|
17
|
+
<Icon :is="SearchIcon" class="text-2xl" />
|
|
14
18
|
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
<span>{{ emptyLabel }}</span>
|
|
20
|
+
</Stack>
|
|
21
|
+
</slot>
|
|
17
22
|
</Stack>
|
|
18
|
-
<div v-else class="grid
|
|
23
|
+
<div v-else class="grid" :class="[columnsClass[columns], gaps[gap]]">
|
|
19
24
|
<slot />
|
|
20
25
|
</div>
|
|
21
26
|
</template>
|
|
@@ -23,13 +28,15 @@
|
|
|
23
28
|
<script setup generic="T" lang="ts">
|
|
24
29
|
import SearchIcon from "~icons/hugeicons/search-01";
|
|
25
30
|
import type { CollectionColumns, CollectionProps } from "../../components/collection";
|
|
31
|
+
import type { StackGap } from "../../components/stack";
|
|
26
32
|
import Icon from "./icon.vue";
|
|
27
33
|
import Stack from "./stack.vue";
|
|
28
34
|
|
|
29
|
-
const { items, columns = 1, emptyLabel = "Nothing found" } = defineProps<CollectionProps<T>>();
|
|
35
|
+
const { items, columns = 1, gap = "5", itemKey, emptyLabel = "Nothing found" } = defineProps<CollectionProps<T>>();
|
|
30
36
|
|
|
31
37
|
defineSlots<{
|
|
32
38
|
default: (() => unknown) & ((props: { item: T; index: number }) => unknown);
|
|
39
|
+
empty?: () => unknown;
|
|
33
40
|
}>();
|
|
34
41
|
|
|
35
42
|
const columnsClass: Record<CollectionColumns, string> = {
|
|
@@ -38,4 +45,12 @@ const columnsClass: Record<CollectionColumns, string> = {
|
|
|
38
45
|
3: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-3",
|
|
39
46
|
4: "grid-cols-1 sm:grid-cols-2 lg:grid-cols-4",
|
|
40
47
|
};
|
|
48
|
+
|
|
49
|
+
const gaps: Record<StackGap, string> = {
|
|
50
|
+
"0": "gap-0",
|
|
51
|
+
"1": "gap-1",
|
|
52
|
+
"3": "gap-3",
|
|
53
|
+
"5": "gap-5",
|
|
54
|
+
"7": "gap-7",
|
|
55
|
+
};
|
|
41
56
|
</script>
|