vlite3 0.0.8 → 0.0.9
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/README.md +156 -17
- package/components/DatePicker.vue.js +9 -11
- package/components/Form/Form.vue.d.ts +2 -1
- package/components/Form/Form.vue.js +1 -1
- package/components/Form/Form.vue2.js +51 -49
- package/components/Form/composables/useFileUpload.d.ts +4 -10
- package/components/Form/composables/useFileUpload.js +29 -21
- package/components/Form/composables/useForm.js +17 -17
- package/core/config.d.ts +29 -0
- package/core/config.js +12 -0
- package/core/index.d.ts +31 -0
- package/core/index.js +15 -0
- package/index.d.ts +1 -0
- package/index.js +64 -60
- package/package.json +5 -2
- package/style.css +109 -85
- package/types/config.type.d.ts +28 -0
- package/types/index.d.ts +1 -0
package/README.md
CHANGED
|
@@ -16,23 +16,19 @@ npm install vlite3
|
|
|
16
16
|
yarn add vlite3
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## 2. Tailwind CSS Setup (Tailwind v4)
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
Import the library's base styles (for custom component styles) in your main entry file (e.g., `main.ts` or `App.vue`):
|
|
21
|
+
`vite.config.ts`
|
|
24
22
|
|
|
25
23
|
```ts
|
|
26
|
-
import '
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
### 2. Tailwind CSS Setup
|
|
30
|
-
|
|
31
|
-
This library relies on Tailwind CSS for utility classes. You must configure your project to scan the library's files so that the necessary classes are generated.
|
|
24
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
export default defineConfig({
|
|
27
|
+
plugins: [vue(), tailwindcss()],
|
|
28
|
+
})
|
|
29
|
+
```
|
|
34
30
|
|
|
35
|
-
|
|
31
|
+
`style.css`
|
|
36
32
|
|
|
37
33
|
```css
|
|
38
34
|
@import 'tailwindcss';
|
|
@@ -42,7 +38,7 @@ If you are using the new CSS-first configuration, add the source path:
|
|
|
42
38
|
@source "../node_modules/vlite3";
|
|
43
39
|
```
|
|
44
40
|
|
|
45
|
-
## Usage
|
|
41
|
+
## 3. Usage
|
|
46
42
|
|
|
47
43
|
Import components directly in your Vue files:
|
|
48
44
|
|
|
@@ -52,9 +48,152 @@ import { Button, Input } from 'vlite3'
|
|
|
52
48
|
</script>
|
|
53
49
|
|
|
54
50
|
<template>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
<div class="p-4 space-y-4">
|
|
52
|
+
<Button>Click Me</Button>
|
|
53
|
+
<Input placeholder="Type here..." />
|
|
54
|
+
</div>
|
|
59
55
|
</template>
|
|
60
56
|
```
|
|
57
|
+
|
|
58
|
+
## 🎨 Theming & Customization
|
|
59
|
+
|
|
60
|
+
vlite3 uses a semantic theming system inspired by **shadcn/ui** and compatible with **Tailwind CSS v4**. All colors are defined as CSS variables, making it easy to customize the look and feel of your application including Dark Mode support.
|
|
61
|
+
|
|
62
|
+
### Semantic Colors
|
|
63
|
+
|
|
64
|
+
You can customize these colors in your CSS by overriding the variables in `:root` or `.dark` classes (if you are using a class-based dark mode switcher).
|
|
65
|
+
|
|
66
|
+
| Variable | Class Name | Description | Recommended Usage |
|
|
67
|
+
| :------------------------- | :---------------------------- | :----------------------- | :--------------------------------------------------------- |
|
|
68
|
+
| `--background` | `bg-background` | Default page background | The main background color of your app. |
|
|
69
|
+
| `--foreground` | `text-foreground` | Default text color | The primary text color for content. |
|
|
70
|
+
| `--card` | `bg-card` | Card background | Background for cards, panels, and dialogs. |
|
|
71
|
+
| `--card-foreground` | `text-card-foreground` | Card text color | Text color inside cards. |
|
|
72
|
+
| `--card-muted` | `bg-card-muted` | Muted card background | Secondary background area within cards. |
|
|
73
|
+
| `--popover` | `bg-popover` | Popover background | Background for popovers, tooltips, and dropdowns. |
|
|
74
|
+
| `--popover-foreground` | `text-popover-foreground` | Popover text color | Text color inside popovers. |
|
|
75
|
+
| `--popover-muted` | `bg-popover-muted` | Muted popover background | Secondary area within popovers (e.g., headers). |
|
|
76
|
+
| `--primary` | `bg-primary` | Primary brand color | Used for main actions (buttons, active states). |
|
|
77
|
+
| `--primary-foreground` | `text-primary-foreground` | Primary text color | Text color for content on top of primary background. |
|
|
78
|
+
| `--secondary` | `bg-secondary` | Secondary background | Used for secondary actions or muted sections. |
|
|
79
|
+
| `--secondary-foreground` | `text-secondary-foreground` | Secondary text color | Text color for content on top of secondary background. |
|
|
80
|
+
| `--muted` | `bg-muted` | Muted background | Subtle backgrounds (e.g., table headers, disabled states). |
|
|
81
|
+
| `--muted-foreground` | `text-muted-foreground` | Muted text color | Secondary text, hints, placeholders. |
|
|
82
|
+
| `--accent` | `bg-accent` | Accent background | Used for hover states, selection highlights. |
|
|
83
|
+
| `--accent-foreground` | `text-accent-foreground` | Accent text color | Text color on accent backgrounds. |
|
|
84
|
+
| `--destructive` | `bg-destructive` | Destructive color | Used for error states and destructive actions. |
|
|
85
|
+
| `--destructive-foreground` | `text-destructive-foreground` | Destructive text color | Text color on destructive backgrounds. |
|
|
86
|
+
| `--border` | `border` | Default border color | Borders for inputs, cards, and dividers. |
|
|
87
|
+
| `--input` | `border-input` | Input border color | Borders specifically for form inputs. |
|
|
88
|
+
| `--ring` | `ring-ring` | Focus ring color | Outline color for focused elements. |
|
|
89
|
+
| `--radius` | `rounded-radius` | Border radius | Global border radius for components. |
|
|
90
|
+
|
|
91
|
+
### Extended Color Variants
|
|
92
|
+
|
|
93
|
+
For more complex components, vlite3 provides extended variants for main semantic colors (`primary`, `danger`, `warning`, `info`, `success`). These are useful for building nuanced UIs with subtle backgrounds, hover states, and accessible text.
|
|
94
|
+
|
|
95
|
+
| Base Color | Variant Variables | Usage Description |
|
|
96
|
+
| :---------- | :------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| **Primary** | `--color-primary-light`<br>`--color-primary-dark`<br>`--color-primary-fg`<br>`--color-primary-fg-light` | **Light**: Subtle background (e.g., 10% opacity).<br>**Dark**: Hover state for the main color.<br>**Fg**: Text color on top of the _main_ color.<br>**Fg-Light**: Text color on top of the _light_ variant. |
|
|
98
|
+
| **Danger** | `--color-danger-light`<br>`--color-danger-dark`<br>`--color-danger-fg`<br>`--color-danger-fg-light` | **Light**: Error backgrounds (alerts).<br>**Dark**: Hover state for destructive buttons.<br>**Fg**: Text on destructive buttons.<br>**Fg-Light**: Text on error alerts. |
|
|
99
|
+
| **Warning** | `--color-warning-light`<br>`--color-warning-dark`<br>`--color-warning-fg`<br>`--color-warning-fg-light` | **Light**: Warning backgrounds.<br>**Dark**: Active/Determined warning states.<br>**Fg**: Text on warning badges.<br>**Fg-Light**: Text on warning backgrounds. |
|
|
100
|
+
| **Success** | `--color-success-light`<br>`--color-success-dark`<br>`--color-success-fg`<br>`--color-success-fg-light` | **Light**: Success backgrounds (toasts).<br>**Dark**: Hover/Active success actions.<br>**Fg**: Text on success buttons.<br>**Fg-Light**: Text on success backgrounds. |
|
|
101
|
+
| **Info** | `--color-info-light`<br>`--color-info-dark`<br>`--color-info-fg`<br>`--color-info-fg-light` | **Light**: Info backgrounds.<br>**Dark**: Hover/Active info actions.<br>**Fg**: Text on info buttons.<br>**Fg-Light**: Text on info backgrounds. |
|
|
102
|
+
|
|
103
|
+
**Example Usage:**
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<!-- A success badge with subtle background and matching text -->
|
|
107
|
+
<div class="bg-success-light text-success-fg-light border border-success/20">
|
|
108
|
+
Operation Completed
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<!-- A danger button with hover effect -->
|
|
112
|
+
<button class="bg-danger text-danger-fg hover:bg-danger-dark">Delete</button>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Additional Colors
|
|
116
|
+
|
|
117
|
+
vlite3 also provides additional utility colors for specific feedback states:
|
|
118
|
+
|
|
119
|
+
| Variable | Class Name | Description |
|
|
120
|
+
| :---------------- | :--------------------------- | :-------------------------------------- |
|
|
121
|
+
| `--color-success` | `text-success`, `bg-success` | For success messages/badges. |
|
|
122
|
+
| `--color-warning` | `text-warning`, `bg-warning` | For warning messages/badges. |
|
|
123
|
+
| `--color-info` | `text-info`, `bg-info` | For informational messages/badges. |
|
|
124
|
+
| `--color-danger` | `text-danger`, `bg-danger` | Alias for destructive in some contexts. |
|
|
125
|
+
|
|
126
|
+
### Example Customization
|
|
127
|
+
|
|
128
|
+
To customize the theme, simply override the CSS variables in your main CSS file:
|
|
129
|
+
|
|
130
|
+
```css
|
|
131
|
+
@layer base {
|
|
132
|
+
:root {
|
|
133
|
+
--primary: #3b82f6; /* Blue-500 */
|
|
134
|
+
--primary-foreground: #ffffff;
|
|
135
|
+
--radius: 0.75rem;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.dark {
|
|
139
|
+
--primary: #60a5fa; /* Blue-400 */
|
|
140
|
+
--primary-foreground: #000000;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## ✅ Components
|
|
146
|
+
|
|
147
|
+
- **Button**
|
|
148
|
+
- **ButtonGroup**
|
|
149
|
+
- **Icon**
|
|
150
|
+
- **Label**
|
|
151
|
+
- **Badge**
|
|
152
|
+
- **Chip**
|
|
153
|
+
- **Logo**
|
|
154
|
+
- **Navbar**
|
|
155
|
+
- **SidebarMenu**
|
|
156
|
+
- **SidePanel**
|
|
157
|
+
- **Masonry Grid**
|
|
158
|
+
- **ThemeToggle**
|
|
159
|
+
|
|
160
|
+
### Inputs & Forms
|
|
161
|
+
|
|
162
|
+
- **Input**
|
|
163
|
+
- **Textarea**
|
|
164
|
+
- **CheckBox**
|
|
165
|
+
- **Switch**
|
|
166
|
+
- **ChoiceBox**
|
|
167
|
+
- **Slider**
|
|
168
|
+
- **OTPInput**
|
|
169
|
+
- **DatePicker**
|
|
170
|
+
- **ColorPicker**
|
|
171
|
+
- **FilePicker**
|
|
172
|
+
- **AvatarUploader**
|
|
173
|
+
- **IconPicker**
|
|
174
|
+
- **MultiSelect**
|
|
175
|
+
- **Form**
|
|
176
|
+
- **CustomFields**
|
|
177
|
+
|
|
178
|
+
### Data Display
|
|
179
|
+
|
|
180
|
+
- **Avatar**
|
|
181
|
+
- **Accordion**
|
|
182
|
+
- **Carousel**
|
|
183
|
+
- **DataTable**
|
|
184
|
+
- **Pagination**
|
|
185
|
+
- **Timeline**
|
|
186
|
+
- **Heatmap**
|
|
187
|
+
- **PricingPlan**
|
|
188
|
+
- **FileTree**
|
|
189
|
+
- **Workbook**
|
|
190
|
+
- **Tabes**
|
|
191
|
+
|
|
192
|
+
### Feedback & Overlays
|
|
193
|
+
|
|
194
|
+
- **Alert**
|
|
195
|
+
- **Modal**
|
|
196
|
+
- **ConfirmationModal**
|
|
197
|
+
- **ToastNotification**
|
|
198
|
+
- **Tooltip**
|
|
199
|
+
- **Dropdown**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent as v, computed as r, openBlock as
|
|
1
|
+
import { defineComponent as v, computed as r, openBlock as h, createBlock as g, unref as u, withCtx as m, createElementVNode as p, createVNode as c, renderSlot as V, mergeProps as w } from "vue";
|
|
2
2
|
import D from "./Button.vue.js";
|
|
3
3
|
import y from "./Dropdown/Dropdown.vue.js";
|
|
4
4
|
import "@iconify/vue";
|
|
@@ -21,24 +21,22 @@ const P = { class: "min-w-[300px] overflow-hidden" }, N = /* @__PURE__ */ v({
|
|
|
21
21
|
},
|
|
22
22
|
emits: ["update:modelValue", "onChange"],
|
|
23
23
|
setup(t, { emit: d }) {
|
|
24
|
-
const n = t,
|
|
24
|
+
const n = t, i = d, a = r({
|
|
25
25
|
get: () => n.modelValue ?? n.value,
|
|
26
26
|
set: (e) => {
|
|
27
|
-
|
|
27
|
+
i("update:modelValue", e), i("onChange", e);
|
|
28
28
|
}
|
|
29
|
-
}), s = (e) => e instanceof Date ? e.getHours() !== 0 || e.getMinutes() !== 0 : typeof e == "string" ? e.includes("T") || /\d{2}:\d{2}/.test(e) : !1,
|
|
29
|
+
}), s = (e) => e instanceof Date ? e.getHours() !== 0 || e.getMinutes() !== 0 : typeof e == "string" ? e.includes("T") || /\d{2}:\d{2}/.test(e) : !1, l = r(() => {
|
|
30
30
|
if (!a.value) return "";
|
|
31
31
|
try {
|
|
32
|
-
console.log("actualValue.value :>> ", a.value);
|
|
33
32
|
const e = new Date(a.value);
|
|
34
33
|
if (isNaN(e.getTime())) return String(a.value);
|
|
35
|
-
|
|
36
|
-
const i = n.mode === "dateTime" && s(a.value);
|
|
34
|
+
const o = n.mode === "dateTime" && s(a.value);
|
|
37
35
|
return e.toLocaleDateString("en-US", {
|
|
38
36
|
month: "short",
|
|
39
37
|
day: "numeric",
|
|
40
38
|
year: "numeric",
|
|
41
|
-
...
|
|
39
|
+
...o ? { hour: "2-digit", minute: "2-digit" } : {}
|
|
42
40
|
});
|
|
43
41
|
} catch {
|
|
44
42
|
return String(a.value);
|
|
@@ -46,7 +44,7 @@ const P = { class: "min-w-[300px] overflow-hidden" }, N = /* @__PURE__ */ v({
|
|
|
46
44
|
}), f = (e) => {
|
|
47
45
|
a.value = e;
|
|
48
46
|
};
|
|
49
|
-
return (e,
|
|
47
|
+
return (e, o) => (h(), g(u(y), {
|
|
50
48
|
position: "bottom-start",
|
|
51
49
|
class: "w-full",
|
|
52
50
|
teleport: t.teleport
|
|
@@ -54,10 +52,10 @@ const P = { class: "min-w-[300px] overflow-hidden" }, N = /* @__PURE__ */ v({
|
|
|
54
52
|
trigger: m(() => [
|
|
55
53
|
V(e.$slots, "default", {
|
|
56
54
|
value: a.value,
|
|
57
|
-
displayValue:
|
|
55
|
+
displayValue: l.value
|
|
58
56
|
}, () => [
|
|
59
57
|
c(D, w({
|
|
60
|
-
text:
|
|
58
|
+
text: l.value || t.placeholder || "Select date",
|
|
61
59
|
variant: t.variant || "outline",
|
|
62
60
|
size: t.size || "md",
|
|
63
61
|
icon: t.icon || "lucide:calendar"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IForm, IFormStep, IFormSubmitPayload } from './types';
|
|
2
|
-
import { InputVariant, InputSize, InputRounded, TimelineTextPosition } from '../../types';
|
|
2
|
+
import { InputVariant, InputSize, InputRounded, TimelineTextPosition, ButtonProps } from '../../types';
|
|
3
3
|
interface Props {
|
|
4
4
|
/** Schema - single array or grouped arrays */
|
|
5
5
|
schema: IForm[] | IForm[][];
|
|
@@ -23,6 +23,7 @@ interface Props {
|
|
|
23
23
|
tabs?: IFormStep[];
|
|
24
24
|
/** Submit button text */
|
|
25
25
|
submitText?: string;
|
|
26
|
+
submitProps?: ButtonProps;
|
|
26
27
|
/** Cancel button text */
|
|
27
28
|
cancelText?: string;
|
|
28
29
|
/** Show cancel button */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./Form.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import r from "../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-
|
|
4
|
+
const p = /* @__PURE__ */ r(o, [["__scopeId", "data-v-25a5775d"]]);
|
|
5
5
|
export {
|
|
6
6
|
p as default
|
|
7
7
|
};
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { defineComponent as K, computed as d, ref as O, watch as Q, openBlock as i, createElementBlock as
|
|
2
|
-
import { useForm as
|
|
1
|
+
import { defineComponent as K, computed as d, ref as O, watch as Q, openBlock as i, createElementBlock as r, withModifiers as W, normalizeClass as f, createVNode as F, createCommentVNode as u, unref as t, Fragment as X, renderList as Y, createElementVNode as U, toDisplayString as k, renderSlot as Z, createBlock as x, mergeProps as I } from "vue";
|
|
2
|
+
import { useForm as _ } from "./composables/useForm.js";
|
|
3
3
|
import D from "./FormFields.vue.js";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
const
|
|
4
|
+
import p from "../Button.vue.js";
|
|
5
|
+
import ee from "../Timeline.vue.js";
|
|
6
|
+
const te = {
|
|
7
7
|
key: 0,
|
|
8
8
|
class: "form-timeline mb-18"
|
|
9
|
-
},
|
|
9
|
+
}, ae = {
|
|
10
10
|
key: 1,
|
|
11
11
|
class: "form-fields-single"
|
|
12
|
-
},
|
|
12
|
+
}, ie = {
|
|
13
13
|
key: 2,
|
|
14
14
|
class: "form-groups space-y-6"
|
|
15
|
-
},
|
|
15
|
+
}, se = { class: "text-base font-semibold text-foreground" }, le = {
|
|
16
16
|
key: 0,
|
|
17
17
|
class: "text-sm text-muted-foreground mt-1"
|
|
18
|
-
},
|
|
18
|
+
}, ne = { class: "form-group-body p-6" }, re = {
|
|
19
19
|
key: 3,
|
|
20
20
|
class: "form-step"
|
|
21
|
-
}, oe = { class: "text-lg font-semibold text-foreground" },
|
|
21
|
+
}, oe = { class: "text-lg font-semibold text-foreground" }, ue = {
|
|
22
22
|
key: 0,
|
|
23
23
|
class: "text-sm text-muted-foreground mt-1"
|
|
24
|
-
},
|
|
24
|
+
}, ye = /* @__PURE__ */ K({
|
|
25
25
|
__name: "Form",
|
|
26
26
|
props: {
|
|
27
27
|
schema: {},
|
|
@@ -35,6 +35,7 @@ const ee = {
|
|
|
35
35
|
groupHeadingsDescription: { default: () => [] },
|
|
36
36
|
tabs: {},
|
|
37
37
|
submitText: { default: "Submit" },
|
|
38
|
+
submitProps: {},
|
|
38
39
|
cancelText: { default: "Cancel" },
|
|
39
40
|
showCancel: { type: Boolean, default: !1 },
|
|
40
41
|
isUpdate: { type: Boolean, default: !1 },
|
|
@@ -47,26 +48,26 @@ const ee = {
|
|
|
47
48
|
},
|
|
48
49
|
emits: ["onSubmit", "onCancel", "onStepChange"],
|
|
49
50
|
setup(e, { emit: M }) {
|
|
50
|
-
const s = e, m = M, h = d(() => !s.schema || s.schema.length === 0 ? !1 : Array.isArray(s.schema[0])),
|
|
51
|
+
const s = e, m = M, h = d(() => !s.schema || s.schema.length === 0 ? !1 : Array.isArray(s.schema[0])), o = d(() => s.tabs && s.tabs.length > 0 && h.value), a = O(0), P = d(() => s.tabs ? s.tabs.map((l, n) => ({
|
|
51
52
|
id: l.id?.toString() || n.toString(),
|
|
52
53
|
title: l.title,
|
|
53
54
|
icon: l.icon,
|
|
54
55
|
description: l.description,
|
|
55
56
|
status: n < a.value ? "completed" : n === a.value ? "current" : "upcoming"
|
|
56
|
-
})) : []), g = d(() => h.value ? s.schema : [s.schema]),
|
|
57
|
+
})) : []), g = d(() => h.value ? s.schema : [s.schema]), w = d(() => o.value ? g.value[a.value] || [] : []), {
|
|
57
58
|
formValues: b,
|
|
58
59
|
errors: y,
|
|
59
|
-
isSubmitting:
|
|
60
|
+
isSubmitting: N,
|
|
60
61
|
handleFieldChange: A,
|
|
61
62
|
validateField: G,
|
|
62
|
-
validateAll:
|
|
63
|
+
validateAll: de,
|
|
63
64
|
isFieldVisible: S,
|
|
64
65
|
isFieldDisabled: C,
|
|
65
66
|
isFieldReadonly: V,
|
|
66
|
-
getFieldValue:
|
|
67
|
+
getFieldValue: ce,
|
|
67
68
|
handleSubmit: $,
|
|
68
|
-
flatSchema:
|
|
69
|
-
} =
|
|
69
|
+
flatSchema: me
|
|
70
|
+
} = _({
|
|
70
71
|
schema: s.schema,
|
|
71
72
|
values: s.values,
|
|
72
73
|
isUpdate: s.isUpdate,
|
|
@@ -83,22 +84,22 @@ const ee = {
|
|
|
83
84
|
const z = (l, n) => {
|
|
84
85
|
A(l, n.value, n.data);
|
|
85
86
|
}, E = () => {
|
|
86
|
-
if (!
|
|
87
|
-
const l =
|
|
87
|
+
if (!o.value) return !0;
|
|
88
|
+
const l = w.value;
|
|
88
89
|
let n = !0;
|
|
89
90
|
for (const v of l) {
|
|
90
91
|
if (!S(v) || C(v)) continue;
|
|
91
92
|
G(v) && (n = !1);
|
|
92
93
|
}
|
|
93
94
|
return n;
|
|
94
|
-
}, L = d(() =>
|
|
95
|
+
}, L = d(() => o.value ? a.value < g.value.length - 1 : !1), R = d(() => o.value ? a.value > 0 : !1), B = d(() => o.value ? a.value === g.value.length - 1 : !0), T = () => {
|
|
95
96
|
L.value && E() && (a.value++, m("onStepChange", a.value));
|
|
96
97
|
}, j = () => {
|
|
97
|
-
|
|
98
|
+
R.value && (a.value--, m("onStepChange", a.value));
|
|
98
99
|
}, q = (l, n) => {
|
|
99
100
|
n <= a.value && (a.value = n, m("onStepChange", a.value));
|
|
100
101
|
}, H = async () => {
|
|
101
|
-
if (
|
|
102
|
+
if (o.value && !B.value) {
|
|
102
103
|
T();
|
|
103
104
|
return;
|
|
104
105
|
}
|
|
@@ -106,13 +107,13 @@ const ee = {
|
|
|
106
107
|
}, J = () => {
|
|
107
108
|
m("onCancel");
|
|
108
109
|
};
|
|
109
|
-
return (l, n) => (i(),
|
|
110
|
+
return (l, n) => (i(), r("form", {
|
|
110
111
|
class: f(["form-container", s.class]),
|
|
111
112
|
onSubmit: W(H, ["prevent"])
|
|
112
113
|
}, [
|
|
113
|
-
|
|
114
|
-
F(
|
|
115
|
-
steps:
|
|
114
|
+
o.value && P.value.length > 0 ? (i(), r("div", te, [
|
|
115
|
+
F(ee, {
|
|
116
|
+
steps: P.value,
|
|
116
117
|
activeStep: a.value,
|
|
117
118
|
direction: "horizontal",
|
|
118
119
|
textPosition: e.timelineTextPosition,
|
|
@@ -120,19 +121,19 @@ const ee = {
|
|
|
120
121
|
onStepClick: q
|
|
121
122
|
}, null, 8, ["steps", "activeStep", "textPosition"])
|
|
122
123
|
])) : u("", !0),
|
|
123
|
-
h.value ? h.value && !
|
|
124
|
-
(i(!0),
|
|
124
|
+
h.value ? h.value && !o.value ? (i(), r("div", ie, [
|
|
125
|
+
(i(!0), r(X, null, Y(g.value, (v, c) => (i(), r("div", {
|
|
125
126
|
key: c,
|
|
126
127
|
class: f(["form-group border rounded-lg overflow-hidden", e.groupClass])
|
|
127
128
|
}, [
|
|
128
|
-
e.groupsHeadings?.[c] ? (i(),
|
|
129
|
+
e.groupsHeadings?.[c] ? (i(), r("div", {
|
|
129
130
|
key: 0,
|
|
130
131
|
class: f(["form-group-header bg-muted/50 px-6 py-4 border-b", e.headerClass])
|
|
131
132
|
}, [
|
|
132
|
-
U("h3",
|
|
133
|
-
e.groupHeadingsDescription?.[c] ? (i(),
|
|
133
|
+
U("h3", se, k(e.groupsHeadings[c]), 1),
|
|
134
|
+
e.groupHeadingsDescription?.[c] ? (i(), r("p", le, k(e.groupHeadingsDescription[c]), 1)) : u("", !0)
|
|
134
135
|
], 2)) : u("", !0),
|
|
135
|
-
U("div",
|
|
136
|
+
U("div", ne, [
|
|
136
137
|
F(D, {
|
|
137
138
|
schema: v,
|
|
138
139
|
values: t(b),
|
|
@@ -149,16 +150,16 @@ const ee = {
|
|
|
149
150
|
}, null, 8, ["schema", "values", "errors", "variant", "size", "rounded", "className", "isUpdate", "isFieldVisible", "isFieldDisabled", "isFieldReadonly"])
|
|
150
151
|
])
|
|
151
152
|
], 2))), 128))
|
|
152
|
-
])) :
|
|
153
|
-
e.tabs?.[a.value] ? (i(),
|
|
153
|
+
])) : o.value ? (i(), r("div", re, [
|
|
154
|
+
e.tabs?.[a.value] ? (i(), r("div", {
|
|
154
155
|
key: 0,
|
|
155
156
|
class: f(["form-step-header mb-6", e.headerClass])
|
|
156
157
|
}, [
|
|
157
158
|
U("h2", oe, k(e.tabs[a.value].title), 1),
|
|
158
|
-
e.tabs[a.value].description ? (i(),
|
|
159
|
+
e.tabs[a.value].description ? (i(), r("p", ue, k(e.tabs[a.value].description), 1)) : u("", !0)
|
|
159
160
|
], 2)) : u("", !0),
|
|
160
161
|
F(D, {
|
|
161
|
-
schema:
|
|
162
|
+
schema: w.value,
|
|
162
163
|
values: t(b),
|
|
163
164
|
errors: t(y),
|
|
164
165
|
variant: e.variant,
|
|
@@ -171,7 +172,7 @@ const ee = {
|
|
|
171
172
|
isFieldReadonly: t(V),
|
|
172
173
|
onChange: z
|
|
173
174
|
}, null, 8, ["schema", "values", "errors", "variant", "size", "rounded", "className", "isUpdate", "isFieldVisible", "isFieldDisabled", "isFieldReadonly"])
|
|
174
|
-
])) : u("", !0) : (i(),
|
|
175
|
+
])) : u("", !0) : (i(), r("div", ae, [
|
|
175
176
|
F(D, {
|
|
176
177
|
schema: e.schema,
|
|
177
178
|
values: t(b),
|
|
@@ -190,22 +191,22 @@ const ee = {
|
|
|
190
191
|
Z(l.$slots, "default", {
|
|
191
192
|
values: t(b),
|
|
192
193
|
errors: t(y),
|
|
193
|
-
isSubmitting: t(
|
|
194
|
+
isSubmitting: t(N),
|
|
194
195
|
handleSubmit: H
|
|
195
196
|
}, void 0, !0),
|
|
196
|
-
e.footer ? (i(),
|
|
197
|
+
e.footer ? (i(), r("div", {
|
|
197
198
|
key: 4,
|
|
198
199
|
class: f(["form-footer mt-6 flex items-center justify-end gap-3", e.footerClass])
|
|
199
200
|
}, [
|
|
200
|
-
e.showCancel ? (i(), x(
|
|
201
|
+
e.showCancel ? (i(), x(p, {
|
|
201
202
|
key: 0,
|
|
202
203
|
type: "button",
|
|
203
204
|
variant: "outline",
|
|
204
205
|
text: e.cancelText,
|
|
205
|
-
disabled: e.loading || t(
|
|
206
|
+
disabled: e.loading || t(N),
|
|
206
207
|
onClick: J
|
|
207
208
|
}, null, 8, ["text", "disabled"])) : u("", !0),
|
|
208
|
-
|
|
209
|
+
o.value && R.value ? (i(), x(p, {
|
|
209
210
|
key: 1,
|
|
210
211
|
type: "button",
|
|
211
212
|
variant: "outline",
|
|
@@ -213,24 +214,25 @@ const ee = {
|
|
|
213
214
|
text: "Previous",
|
|
214
215
|
onClick: j
|
|
215
216
|
})) : u("", !0),
|
|
216
|
-
|
|
217
|
+
o.value && !B.value ? (i(), x(p, {
|
|
217
218
|
key: 2,
|
|
218
219
|
type: "button",
|
|
219
220
|
variant: "primary",
|
|
220
221
|
text: "Next",
|
|
221
222
|
iconRight: "lucide:arrow-right",
|
|
222
223
|
onClick: T
|
|
223
|
-
})) : (i(), x(
|
|
224
|
+
})) : (i(), x(p, I({
|
|
224
225
|
key: 3,
|
|
225
226
|
type: "submit",
|
|
226
227
|
variant: "primary",
|
|
227
|
-
text: e.submitText
|
|
228
|
-
|
|
229
|
-
|
|
228
|
+
text: e.submitText
|
|
229
|
+
}, e.submitProps, {
|
|
230
|
+
loading: e.loading || t(N)
|
|
231
|
+
}), null, 16, ["text", "loading"]))
|
|
230
232
|
], 2)) : u("", !0)
|
|
231
233
|
], 34));
|
|
232
234
|
}
|
|
233
235
|
});
|
|
234
236
|
export {
|
|
235
|
-
|
|
237
|
+
ye as default
|
|
236
238
|
};
|
|
@@ -5,17 +5,11 @@ export interface FileUploadResult {
|
|
|
5
5
|
fileSize?: number;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
|
-
* Composable for handling file uploads
|
|
8
|
+
* Composable for handling file uploads.
|
|
9
9
|
*
|
|
10
|
-
* This
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```ts
|
|
15
|
-
* const { handleUploadFile, loading } = useFileUpload()
|
|
16
|
-
*
|
|
17
|
-
* const url = await handleUploadFile(file, folderId)
|
|
18
|
-
* ```
|
|
10
|
+
* This composable automatically checks the global VLite configuration
|
|
11
|
+
* for a registered 'upload' service. If found, it uses that service.
|
|
12
|
+
* Otherwise, it falls back to a mock implementation.
|
|
19
13
|
*/
|
|
20
14
|
export declare function useFileUpload(): {
|
|
21
15
|
handleUploadFile: (file: File | {
|
|
@@ -1,32 +1,40 @@
|
|
|
1
|
-
import { ref as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ref as u } from "vue";
|
|
2
|
+
import { useVLiteConfig as d } from "../../../core/config.js";
|
|
3
|
+
function g() {
|
|
4
|
+
const s = u(!1), a = u(null), i = d(), c = async (r, t) => {
|
|
5
5
|
try {
|
|
6
|
-
const e =
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const e = r instanceof File ? r : r.file;
|
|
7
|
+
if (i.services?.upload)
|
|
8
|
+
try {
|
|
9
|
+
return await i.services.upload(e, t);
|
|
10
|
+
} catch (o) {
|
|
11
|
+
throw o instanceof Error ? o : new Error("External upload service failed");
|
|
12
|
+
}
|
|
13
|
+
await new Promise((o) => setTimeout(o, 800));
|
|
14
|
+
const l = Math.random().toString(36).substring(7), n = e.name.replace(/[^a-zA-Z0-9.-]/g, "_");
|
|
15
|
+
return `https://storage.googleapis.com/vlite-bucket/${l}/${n}`;
|
|
10
16
|
} catch (e) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
l.value = !1;
|
|
17
|
+
const l = e instanceof Error ? e.message : "Upload failed";
|
|
18
|
+
return console.error("[useFileUpload] Error:", e), a.value = l, null;
|
|
14
19
|
}
|
|
15
20
|
};
|
|
16
21
|
return {
|
|
17
|
-
handleUploadFile:
|
|
18
|
-
handleUploadFiles: async (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
22
|
+
handleUploadFile: c,
|
|
23
|
+
handleUploadFiles: async (r, t) => {
|
|
24
|
+
s.value = !0, a.value = null;
|
|
25
|
+
try {
|
|
26
|
+
const e = r.map((n) => c(n, t));
|
|
27
|
+
return await Promise.all(e);
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return a.value = e instanceof Error ? e.message : "One or more uploads failed", console.error("[useFileUpload] Parallel Upload Error:", e), [];
|
|
30
|
+
} finally {
|
|
31
|
+
s.value = !1;
|
|
23
32
|
}
|
|
24
|
-
return e;
|
|
25
33
|
},
|
|
26
|
-
loading:
|
|
27
|
-
error:
|
|
34
|
+
loading: s,
|
|
35
|
+
error: a
|
|
28
36
|
};
|
|
29
37
|
}
|
|
30
38
|
export {
|
|
31
|
-
|
|
39
|
+
g as useFileUpload
|
|
32
40
|
};
|