@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,32 +1,46 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Stack>
|
|
3
|
-
<span v-if="label" class="
|
|
4
|
-
{{ label }}<span v-if="required" aria-hidden="true"> *</span>
|
|
2
|
+
<Stack class="w-full" :class="texts[text]">
|
|
3
|
+
<span v-if="label" class="font-normal">
|
|
4
|
+
{{ label }}<span v-if="required" aria-hidden="true" class="text-destructive"> *</span>
|
|
5
5
|
</span>
|
|
6
6
|
|
|
7
7
|
<Stack
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
gap="3"
|
|
11
|
-
class="relative min-h-32 rounded-ui border border-input border-dashed p-5 text-center transition-colors"
|
|
8
|
+
gap="0"
|
|
9
|
+
class="relative rounded-ui"
|
|
12
10
|
:class="[variants[state], interactionVariants[interaction]]"
|
|
13
11
|
@dragenter.prevent="isOver = true"
|
|
14
12
|
@dragover.prevent="isOver = true"
|
|
15
13
|
@dragleave="leave"
|
|
16
14
|
@drop.prevent="drop"
|
|
17
15
|
>
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
<slot v-if="modelValue" name="file" :file="modelValue" :remove="remove" :disabled="disabled">
|
|
17
|
+
<Stack direction="horizontal" align="center" justify="between" gap="0">
|
|
18
|
+
<span class="min-w-0 flex-1 p-3">
|
|
19
|
+
<span class="block truncate px-1">{{
|
|
20
|
+
"name" in modelValue ? modelValue.name : "File selected"
|
|
21
|
+
}}</span>
|
|
22
|
+
</span>
|
|
23
|
+
|
|
24
|
+
<Button
|
|
25
|
+
size="icon"
|
|
26
|
+
variant="secondary"
|
|
27
|
+
:text="text"
|
|
28
|
+
:icon-prefix="CloseIcon"
|
|
29
|
+
aria-label="Remove file"
|
|
30
|
+
:disabled="disabled"
|
|
31
|
+
@click="remove"
|
|
32
|
+
/>
|
|
33
|
+
</Stack>
|
|
34
|
+
</slot>
|
|
35
|
+
<slot v-else name="empty" :browse="browse" :disabled="disabled" :dragging="isOver">
|
|
36
|
+
<Stack align="center" gap="3" padding="5" class="text-center">
|
|
37
|
+
<Icon :is="UploadIcon" :size="24" />
|
|
38
|
+
|
|
39
|
+
<span class="text-sm opacity-60"> Drag and drop a file here </span>
|
|
40
|
+
|
|
41
|
+
<Button label="Browse files" variant="outline" :disabled="disabled" @click="browse" />
|
|
42
|
+
</Stack>
|
|
43
|
+
</slot>
|
|
30
44
|
|
|
31
45
|
<input
|
|
32
46
|
ref="input"
|
|
@@ -38,25 +52,47 @@
|
|
|
38
52
|
:disabled="disabled"
|
|
39
53
|
@change="change"
|
|
40
54
|
/>
|
|
55
|
+
|
|
56
|
+
<span
|
|
57
|
+
aria-hidden="true"
|
|
58
|
+
class="pointer-events-none absolute inset-0 rounded-ui ring-1 ring-input ring-inset"
|
|
59
|
+
/>
|
|
41
60
|
</Stack>
|
|
42
61
|
|
|
43
|
-
<span v-if="description" class="
|
|
62
|
+
<span v-if="description" class="opacity-60">{{ description }}</span>
|
|
44
63
|
</Stack>
|
|
45
64
|
</template>
|
|
46
65
|
|
|
47
66
|
<script setup lang="ts">
|
|
67
|
+
import UploadIcon from "~icons/hugeicons/file-upload";
|
|
68
|
+
import CloseIcon from "~icons/hugeicons/multiplication-sign";
|
|
48
69
|
import { computed, ref, useTemplateRef } from "vue";
|
|
49
70
|
import type { ControlInteraction } from "../../components/control.ts";
|
|
50
|
-
import type { UploadProps, UploadState } from "../../components/upload";
|
|
71
|
+
import type { UploadProps, UploadState, UploadText } from "../../components/upload";
|
|
51
72
|
import Button from "./button.vue";
|
|
73
|
+
import Icon from "./icon.vue";
|
|
52
74
|
import Stack from "./stack.vue";
|
|
53
75
|
|
|
54
|
-
const {
|
|
76
|
+
const {
|
|
77
|
+
modelValue,
|
|
78
|
+
label,
|
|
79
|
+
description,
|
|
80
|
+
text = "sm",
|
|
81
|
+
accept,
|
|
82
|
+
name,
|
|
83
|
+
required = false,
|
|
84
|
+
disabled = false,
|
|
85
|
+
} = defineProps<UploadProps>();
|
|
55
86
|
|
|
56
87
|
const emit = defineEmits<{
|
|
57
88
|
"update:modelValue": [value?: Blob | File];
|
|
58
89
|
}>();
|
|
59
90
|
|
|
91
|
+
defineSlots<{
|
|
92
|
+
empty?: (props: { browse: () => void; disabled: boolean; dragging: boolean }) => unknown;
|
|
93
|
+
file?: (props: { file: Blob | File; remove: () => void; disabled: boolean }) => unknown;
|
|
94
|
+
}>();
|
|
95
|
+
|
|
60
96
|
const input = useTemplateRef("input");
|
|
61
97
|
|
|
62
98
|
const isOver = ref(false);
|
|
@@ -71,10 +107,21 @@ const interactionVariants: Record<ControlInteraction, string> = {
|
|
|
71
107
|
};
|
|
72
108
|
|
|
73
109
|
const variants: Record<UploadState, string> = {
|
|
74
|
-
idle: "bg-
|
|
110
|
+
idle: "bg-secondary",
|
|
75
111
|
over: "bg-accent",
|
|
76
112
|
};
|
|
77
113
|
|
|
114
|
+
const texts: Record<UploadText, string> = {
|
|
115
|
+
sm: "text-sm",
|
|
116
|
+
md: "text-base",
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
function browse() {
|
|
120
|
+
if (!disabled) {
|
|
121
|
+
input.value?.click();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
78
125
|
function change() {
|
|
79
126
|
const file = input.value?.files?.item(0);
|
|
80
127
|
|
|
@@ -105,6 +152,10 @@ function leave(event: DragEvent) {
|
|
|
105
152
|
}
|
|
106
153
|
|
|
107
154
|
function remove() {
|
|
155
|
+
if (disabled) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
108
159
|
if (input.value) {
|
|
109
160
|
input.value.value = "";
|
|
110
161
|
}
|
package/dist/vue/index.d.ts
CHANGED
|
@@ -8,11 +8,15 @@ export { default as Counter } from "./components/counter.vue";
|
|
|
8
8
|
export { default as Dialog } from "./components/dialog.vue";
|
|
9
9
|
export { default as Field } from "./components/field.vue";
|
|
10
10
|
export { default as Heading } from "./components/heading.vue";
|
|
11
|
+
export { default as Shell } from "./components/shell.vue";
|
|
11
12
|
export { default as Icon } from "./components/icon.vue";
|
|
12
13
|
export { default as Input } from "./components/input.vue";
|
|
13
14
|
export { default as Link } from "./components/link.vue";
|
|
15
|
+
export { default as Entry } from "./components/entry.vue";
|
|
16
|
+
export { default as Notification } from "./components/notification.vue";
|
|
14
17
|
export { default as Navigate } from "./components/navigate.vue";
|
|
15
18
|
export { default as Popover } from "./components/popover.vue";
|
|
19
|
+
export { default as Pagination } from "./components/pagination.vue";
|
|
16
20
|
export { default as Progress } from "./components/progress.vue";
|
|
17
21
|
export { default as Radio } from "./components/radio.vue";
|
|
18
22
|
export { default as Range } from "./components/range.vue";
|
|
@@ -23,5 +27,6 @@ export { default as Sheet } from "./components/sheet.vue";
|
|
|
23
27
|
export { default as Stack } from "./components/stack.vue";
|
|
24
28
|
export { default as Switch } from "./components/switch.vue";
|
|
25
29
|
export { default as Upload } from "./components/upload.vue";
|
|
30
|
+
export { default as Textarea } from "./components/textarea.vue";
|
|
26
31
|
export { useFocusTrap } from "./utilities/use-focus-trap";
|
|
27
32
|
export { useScrollLock } from "./utilities/use-scroll-lock";
|
package/dist/vue/index.js
CHANGED
|
@@ -10,11 +10,15 @@ import Counter from "./components/counter.vue";
|
|
|
10
10
|
import Dialog from "./components/dialog.vue";
|
|
11
11
|
import Field from "./components/field.vue";
|
|
12
12
|
import Heading from "./components/heading.vue";
|
|
13
|
+
import Shell from "./components/shell.vue";
|
|
13
14
|
import Icon from "./components/icon.vue";
|
|
14
15
|
import Input from "./components/input.vue";
|
|
15
16
|
import Link from "./components/link.vue";
|
|
17
|
+
import Entry from "./components/entry.vue";
|
|
18
|
+
import Notification from "./components/notification.vue";
|
|
16
19
|
import Navigate from "./components/navigate.vue";
|
|
17
20
|
import Popover from "./components/popover.vue";
|
|
21
|
+
import Pagination from "./components/pagination.vue";
|
|
18
22
|
import Progress from "./components/progress.vue";
|
|
19
23
|
import Radio from "./components/radio.vue";
|
|
20
24
|
import Range from "./components/range.vue";
|
|
@@ -25,4 +29,5 @@ import Sheet from "./components/sheet.vue";
|
|
|
25
29
|
import Stack from "./components/stack.vue";
|
|
26
30
|
import Switch from "./components/switch.vue";
|
|
27
31
|
import Upload from "./components/upload.vue";
|
|
28
|
-
|
|
32
|
+
import Textarea from "./components/textarea.vue";
|
|
33
|
+
export { Breadcrumb, Button, Card, Checkbox, Collection, Container, Counter, Dialog, Entry, Field, Heading, Icon, Input, Link, Navigate, Notification, Pagination, Popover, Progress, Radio, Range, Rating, Select, Separator, Sheet, Shell, Stack, Switch, Textarea, Upload, useFocusTrap, useScrollLock };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type InputHTMLAttributes } from "vue";
|
|
2
|
+
export declare function useControlAttributes(): {
|
|
3
|
+
rootAttributes: Readonly<import("vue").Ref<{
|
|
4
|
+
class: import("vue").ClassValue;
|
|
5
|
+
style: import("vue").StyleValue;
|
|
6
|
+
}, {
|
|
7
|
+
class: import("vue").ClassValue;
|
|
8
|
+
style: import("vue").StyleValue;
|
|
9
|
+
}>>;
|
|
10
|
+
controlAttributes: Readonly<import("vue").Ref<InputHTMLAttributes, InputHTMLAttributes>>;
|
|
11
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { toRef, useAttrs } from "vue";
|
|
2
|
+
//#region src/vue/utilities/use-control-attributes.ts
|
|
3
|
+
function useControlAttributes() {
|
|
4
|
+
const attributes = useAttrs();
|
|
5
|
+
return {
|
|
6
|
+
rootAttributes: toRef(() => ({
|
|
7
|
+
class: attributes.class,
|
|
8
|
+
style: attributes.style
|
|
9
|
+
})),
|
|
10
|
+
controlAttributes: toRef(() => Object.fromEntries(Object.entries(attributes).filter(([key]) => key !== "class" && key !== "style")))
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useControlAttributes };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type MaybeRefOrGetter, type Ref } from "vue";
|
|
2
|
+
export declare function useModalDialog(element: Ref<HTMLDialogElement | null>, modelValue: MaybeRefOrGetter<boolean | undefined>, update: (value: boolean) => void, dismissible: MaybeRefOrGetter<boolean>): {
|
|
3
|
+
isOpen: import("vue").ComputedRef<boolean>;
|
|
4
|
+
open: () => void;
|
|
5
|
+
close: () => void;
|
|
6
|
+
toggle: () => void;
|
|
7
|
+
dismiss: (event: Event) => void;
|
|
8
|
+
handleClose: () => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useScrollLock } from "./use-scroll-lock.js";
|
|
2
|
+
import { computed, ref, toValue, watchEffect } from "vue";
|
|
3
|
+
//#region src/vue/utilities/use-modal-dialog.ts
|
|
4
|
+
function useModalDialog(element, modelValue, update, dismissible) {
|
|
5
|
+
function open() {
|
|
6
|
+
internalOpen.value = true;
|
|
7
|
+
update(true);
|
|
8
|
+
}
|
|
9
|
+
function close() {
|
|
10
|
+
internalOpen.value = false;
|
|
11
|
+
element.value?.close();
|
|
12
|
+
update(false);
|
|
13
|
+
}
|
|
14
|
+
function toggle() {
|
|
15
|
+
if (isOpen.value) close();
|
|
16
|
+
else open();
|
|
17
|
+
}
|
|
18
|
+
function dismiss(event) {
|
|
19
|
+
if (!toValue(dismissible)) {
|
|
20
|
+
event.preventDefault();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
close();
|
|
24
|
+
}
|
|
25
|
+
function handleClose() {
|
|
26
|
+
if (element.value?.open) return;
|
|
27
|
+
internalOpen.value = false;
|
|
28
|
+
if (isOpen.value) update(false);
|
|
29
|
+
}
|
|
30
|
+
const internalOpen = ref(false);
|
|
31
|
+
const isOpen = computed(() => toValue(modelValue) ?? internalOpen.value);
|
|
32
|
+
useScrollLock(isOpen);
|
|
33
|
+
watchEffect(() => {
|
|
34
|
+
if (!element.value?.isConnected) return;
|
|
35
|
+
if (isOpen.value && !element.value.open) element.value.showModal();
|
|
36
|
+
else if (!isOpen.value && element.value.open) element.value.close();
|
|
37
|
+
}, { flush: "post" });
|
|
38
|
+
return {
|
|
39
|
+
isOpen,
|
|
40
|
+
open,
|
|
41
|
+
close,
|
|
42
|
+
toggle,
|
|
43
|
+
dismiss,
|
|
44
|
+
handleClose
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
export { useModalDialog };
|