@nuxt/ui 4.0.0-alpha.2 → 4.0.0-beta.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/.nuxt/ui/prose/img.ts +1 -1
- package/README.md +1 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +3 -3
- package/dist/runtime/components/ChatMessages.vue +4 -4
- package/dist/runtime/components/CheckboxGroup.d.vue.ts +3 -3
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +3 -3
- package/dist/runtime/components/DashboardGroup.d.vue.ts +1 -1
- package/dist/runtime/components/DashboardGroup.vue.d.ts +1 -1
- package/dist/runtime/components/Form.vue +101 -76
- package/dist/runtime/components/FormField.vue +9 -3
- package/dist/runtime/components/InputMenu.vue +1 -1
- package/dist/runtime/components/InputTags.vue +2 -2
- package/dist/runtime/components/Tabs.vue +2 -2
- package/dist/runtime/components/Tree.d.vue.ts +19 -23
- package/dist/runtime/components/Tree.vue +25 -12
- package/dist/runtime/components/Tree.vue.d.ts +19 -23
- package/dist/runtime/composables/useFormField.js +0 -4
- package/dist/runtime/locale/pt.js +2 -2
- package/dist/runtime/types/form.d.ts +3 -5
- package/dist/runtime/types/tv.d.ts +9 -2
- package/dist/runtime/utils/form.d.ts +0 -6
- package/dist/runtime/utils/form.js +0 -60
- package/dist/shared/{ui.Bs5uUhtm.mjs → ui.DGJZ-1aX.mjs} +1 -1
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +11 -11
package/.nuxt/ui/prose/img.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"slots": {
|
|
3
|
-
"base": "rounded-md",
|
|
3
|
+
"base": "rounded-md w-full",
|
|
4
4
|
"overlay": "fixed inset-0 bg-default/75 backdrop-blur-sm will-change-opacity",
|
|
5
5
|
"content": "fixed inset-0 flex items-center justify-center cursor-zoom-out focus:outline-none p-4 sm:p-8"
|
|
6
6
|
},
|
package/README.md
CHANGED
|
@@ -31,6 +31,7 @@ Kickstart your project with one of our ready-to-use Nuxt UI templates or follow
|
|
|
31
31
|
- [Dashboard](https://github.com/nuxt-ui-templates/dashboard) — A dashboard template with multi-column layout.
|
|
32
32
|
- [Chat](https://github.com/nuxt-ui-templates/chat) — An AI chatbot template with GitHub authentication and persistent chat history powered by Vercel AI SDK.
|
|
33
33
|
- [Portfolio](https://github.com/nuxt-ui-templates/portfolio) — A sleek portfolio template to showcase your work, skills and blog powered by Nuxt Content.
|
|
34
|
+
- [Changelog](https://github.com/nuxt-ui-templates/changelog) — A changelog template to display your repository releases notes from GitHub powered by Nuxt MDC.
|
|
34
35
|
|
|
35
36
|
## Installation
|
|
36
37
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defu } from 'defu';
|
|
2
2
|
import { defineNuxtModule, createResolver, addPlugin, hasNuxtModule, addComponentsDir, addImportsDir, installModule } from '@nuxt/kit';
|
|
3
|
-
import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.
|
|
3
|
+
import { d as defaultOptions, r as resolveColors, a as getDefaultUiConfig, b as addTemplates } from './shared/ui.DGJZ-1aX.mjs';
|
|
4
4
|
import '../dist/runtime/utils/index.js';
|
|
5
5
|
import 'node:url';
|
|
6
6
|
import 'scule';
|
|
@@ -8,7 +8,7 @@ import 'knitwork';
|
|
|
8
8
|
import 'tailwindcss/colors';
|
|
9
9
|
|
|
10
10
|
const name = "@nuxt/ui";
|
|
11
|
-
const version = "4.0.0-
|
|
11
|
+
const version = "4.0.0-beta.0";
|
|
12
12
|
|
|
13
13
|
const module = defineNuxtModule({
|
|
14
14
|
meta: {
|
|
@@ -30,7 +30,7 @@ const module = defineNuxtModule({
|
|
|
30
30
|
nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, getDefaultUiConfig(options.theme.colors));
|
|
31
31
|
nuxt.options.app.rootAttrs = nuxt.options.app.rootAttrs || {};
|
|
32
32
|
nuxt.options.app.rootAttrs.class = [nuxt.options.app.rootAttrs.class, "isolate"].filter(Boolean).join(" ");
|
|
33
|
-
nuxt.hook("vite:
|
|
33
|
+
nuxt.hook("vite:extend", async ({ config }) => {
|
|
34
34
|
const plugin = await import('@tailwindcss/vite').then((r) => r.default);
|
|
35
35
|
config.plugins ||= [];
|
|
36
36
|
config.plugins.push(plugin());
|
|
@@ -180,13 +180,13 @@ onMounted(() => {
|
|
|
180
180
|
:compact="compact"
|
|
181
181
|
>
|
|
182
182
|
<template #content>
|
|
183
|
-
<
|
|
184
|
-
<
|
|
183
|
+
<slot name="indicator">
|
|
184
|
+
<div :class="ui.indicator({ class: props.ui?.indicator })">
|
|
185
185
|
<span />
|
|
186
186
|
<span />
|
|
187
187
|
<span />
|
|
188
|
-
</
|
|
189
|
-
</
|
|
188
|
+
</div>
|
|
189
|
+
</slot>
|
|
190
190
|
</template>
|
|
191
191
|
</UChatMessage>
|
|
192
192
|
|
|
@@ -58,7 +58,7 @@ export interface CheckboxGroupProps<T extends CheckboxGroupItem[] = CheckboxGrou
|
|
|
58
58
|
class?: any;
|
|
59
59
|
ui?: CheckboxGroup['slots'] & CheckboxProps['ui'];
|
|
60
60
|
}
|
|
61
|
-
export type CheckboxGroupEmits = CheckboxGroupRootEmits & {
|
|
61
|
+
export type CheckboxGroupEmits<T extends CheckboxGroupItem[] = CheckboxGroupItem[]> = CheckboxGroupRootEmits<T[number]> & {
|
|
62
62
|
change: [event: Event];
|
|
63
63
|
};
|
|
64
64
|
type SlotProps<T extends CheckboxGroupItem> = (props: {
|
|
@@ -74,12 +74,12 @@ export interface CheckboxGroupSlots<T extends CheckboxGroupItem[] = CheckboxGrou
|
|
|
74
74
|
declare const _default: <T extends CheckboxGroupItem[], VK extends GetItemKeys<T> = "value">(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
75
75
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
76
76
|
readonly onChange?: ((event: Event) => any) | undefined;
|
|
77
|
-
readonly "onUpdate:modelValue"?: ((value:
|
|
77
|
+
readonly "onUpdate:modelValue"?: ((value: T[number][]) => any) | undefined;
|
|
78
78
|
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onChange" | "onUpdate:modelValue"> & CheckboxGroupProps<T, VK> & {}> & import("vue").PublicProps;
|
|
79
79
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
80
80
|
attrs: any;
|
|
81
81
|
slots: CheckboxGroupSlots<T>;
|
|
82
|
-
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value:
|
|
82
|
+
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: T[number][]) => void);
|
|
83
83
|
}>) => import("vue").VNode & {
|
|
84
84
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
85
85
|
};
|
|
@@ -58,7 +58,7 @@ export interface CheckboxGroupProps<T extends CheckboxGroupItem[] = CheckboxGrou
|
|
|
58
58
|
class?: any;
|
|
59
59
|
ui?: CheckboxGroup['slots'] & CheckboxProps['ui'];
|
|
60
60
|
}
|
|
61
|
-
export type CheckboxGroupEmits = CheckboxGroupRootEmits & {
|
|
61
|
+
export type CheckboxGroupEmits<T extends CheckboxGroupItem[] = CheckboxGroupItem[]> = CheckboxGroupRootEmits<T[number]> & {
|
|
62
62
|
change: [event: Event];
|
|
63
63
|
};
|
|
64
64
|
type SlotProps<T extends CheckboxGroupItem> = (props: {
|
|
@@ -74,12 +74,12 @@ export interface CheckboxGroupSlots<T extends CheckboxGroupItem[] = CheckboxGrou
|
|
|
74
74
|
declare const _default: <T extends CheckboxGroupItem[], VK extends GetItemKeys<T> = "value">(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
75
75
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
76
76
|
readonly onChange?: ((event: Event) => any) | undefined;
|
|
77
|
-
readonly "onUpdate:modelValue"?: ((value:
|
|
77
|
+
readonly "onUpdate:modelValue"?: ((value: T[number][]) => any) | undefined;
|
|
78
78
|
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onChange" | "onUpdate:modelValue"> & CheckboxGroupProps<T, VK> & {}> & import("vue").PublicProps;
|
|
79
79
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
80
80
|
attrs: any;
|
|
81
81
|
slots: CheckboxGroupSlots<T>;
|
|
82
|
-
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value:
|
|
82
|
+
emit: ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: T[number][]) => void);
|
|
83
83
|
}>) => import("vue").VNode & {
|
|
84
84
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
85
85
|
};
|
|
@@ -12,9 +12,9 @@ export interface DashboardGroupSlots {
|
|
|
12
12
|
}
|
|
13
13
|
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<DashboardGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DashboardGroupProps> & Readonly<{}>, {
|
|
14
14
|
storage: "cookie" | "local";
|
|
15
|
-
unit: "%" | "rem" | "px";
|
|
16
15
|
storageKey: string;
|
|
17
16
|
persistent: boolean;
|
|
17
|
+
unit: "%" | "rem" | "px";
|
|
18
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardGroupSlots>;
|
|
19
19
|
export default _default;
|
|
20
20
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -12,9 +12,9 @@ export interface DashboardGroupSlots {
|
|
|
12
12
|
}
|
|
13
13
|
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<DashboardGroupProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<DashboardGroupProps> & Readonly<{}>, {
|
|
14
14
|
storage: "cookie" | "local";
|
|
15
|
-
unit: "%" | "rem" | "px";
|
|
16
15
|
storageKey: string;
|
|
17
16
|
persistent: boolean;
|
|
17
|
+
unit: "%" | "rem" | "px";
|
|
18
18
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, DashboardGroupSlots>;
|
|
19
19
|
export default _default;
|
|
20
20
|
type __VLS_WithSlots<T, S> = T & {
|
|
@@ -112,35 +112,20 @@ async function getErrors() {
|
|
|
112
112
|
}
|
|
113
113
|
async function _validate(opts = { silent: false, nested: false, transform: false }) {
|
|
114
114
|
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
115
|
+
let nestedResults = [];
|
|
116
|
+
let nestedErrors = [];
|
|
117
|
+
if (!names && opts.nested) {
|
|
118
|
+
const validations = Array.from(nestedForms.value.values()).map(
|
|
119
|
+
(form) => validateNestedForm(form, opts)
|
|
120
|
+
);
|
|
121
|
+
const results = await Promise.all(validations);
|
|
122
|
+
nestedErrors = results.filter((r) => r.error).flatMap((r) => r.error.errors.map((e) => addFormPath(e, r.name)));
|
|
123
|
+
nestedResults = results.filter((r) => r.output !== void 0);
|
|
124
124
|
}
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const nestedErrors = nestedResults.flatMap((result) => {
|
|
128
|
-
if (!result.error) return [];
|
|
129
|
-
return result.error.errors.map((e) => ({ ...e, name: result.name ? [result.name, e.name].join(".") : e.name }));
|
|
130
|
-
});
|
|
131
|
-
const nestedOutputs = nestedResults.filter((c) => c.output !== void 0);
|
|
132
|
-
const allErrors = [await getErrors(), nestedErrors].flat();
|
|
125
|
+
const currentErrors = await getErrors();
|
|
126
|
+
const allErrors = [...currentErrors, ...nestedErrors];
|
|
133
127
|
if (names) {
|
|
134
|
-
|
|
135
|
-
const patterns = names.map((name) => inputs.value?.[name]?.pattern).filter(Boolean);
|
|
136
|
-
const isErrorForPath = (error) => {
|
|
137
|
-
if (!error.name) return false;
|
|
138
|
-
if (namesSet.has(error.name)) return true;
|
|
139
|
-
return patterns.some((pattern) => pattern.test(error.name));
|
|
140
|
-
};
|
|
141
|
-
const otherErrors = errors.value.filter((error) => !isErrorForPath(error));
|
|
142
|
-
const pathErrors = allErrors.filter(isErrorForPath);
|
|
143
|
-
errors.value = otherErrors.concat(pathErrors);
|
|
128
|
+
errors.value = filterErrorsByNames(allErrors, names);
|
|
144
129
|
} else {
|
|
145
130
|
errors.value = allErrors;
|
|
146
131
|
}
|
|
@@ -149,9 +134,12 @@ async function _validate(opts = { silent: false, nested: false, transform: false
|
|
|
149
134
|
throw new FormValidationException(formId, errors.value);
|
|
150
135
|
}
|
|
151
136
|
if (opts.transform) {
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
|
|
137
|
+
nestedResults.forEach((result) => {
|
|
138
|
+
if (result.name) {
|
|
139
|
+
setAtPath(transformedState.value, result.name, result.output);
|
|
140
|
+
} else {
|
|
141
|
+
Object.assign(transformedState.value, result.output);
|
|
142
|
+
}
|
|
155
143
|
});
|
|
156
144
|
return transformedState.value ?? state.value;
|
|
157
145
|
}
|
|
@@ -184,68 +172,105 @@ provide(formOptionsInjectionKey, computed(() => ({
|
|
|
184
172
|
disabled: disabled.value,
|
|
185
173
|
validateOnInputDelay: props.validateOnInputDelay
|
|
186
174
|
})));
|
|
175
|
+
async function validateNestedForm(form, opts) {
|
|
176
|
+
try {
|
|
177
|
+
const result = await form.validate({ ...opts, silent: false });
|
|
178
|
+
return { name: form.name, output: result };
|
|
179
|
+
} catch (error) {
|
|
180
|
+
if (!(error instanceof FormValidationException)) throw error;
|
|
181
|
+
return { name: form.name, error };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function addFormPath(error, formPath) {
|
|
185
|
+
if (!formPath || !error.name) return error;
|
|
186
|
+
return { ...error, name: formPath + "." + error.name };
|
|
187
|
+
}
|
|
188
|
+
function stripFormPath(error, formPath) {
|
|
189
|
+
const prefix = formPath + ".";
|
|
190
|
+
const name = error?.name?.startsWith(prefix) ? error.name.substring(prefix.length) : error.name;
|
|
191
|
+
return { ...error, name };
|
|
192
|
+
}
|
|
193
|
+
function filterFormErrors(errors2, formPath) {
|
|
194
|
+
if (!formPath) return errors2;
|
|
195
|
+
return errors2.filter((e) => e?.name?.startsWith(formPath + ".")).map((e) => stripFormPath(e, formPath));
|
|
196
|
+
}
|
|
197
|
+
function getFormErrors(form) {
|
|
198
|
+
return form.api.getErrors().map(
|
|
199
|
+
(e) => form.name ? { ...e, name: form.name + "." + e.name } : e
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function matchesTarget(target, path) {
|
|
203
|
+
if (!target || !path) return true;
|
|
204
|
+
if (target instanceof RegExp) return target.test(path);
|
|
205
|
+
return path === target || typeof target === "string" && target.startsWith(path + ".");
|
|
206
|
+
}
|
|
207
|
+
function getNestedTarget(target, formPath) {
|
|
208
|
+
if (!target || target instanceof RegExp) return target;
|
|
209
|
+
if (formPath === target) return void 0;
|
|
210
|
+
if (typeof target === "string" && target.startsWith(formPath + ".")) {
|
|
211
|
+
return target.substring(formPath.length + 1);
|
|
212
|
+
}
|
|
213
|
+
return target;
|
|
214
|
+
}
|
|
215
|
+
function filterErrorsByNames(allErrors, names) {
|
|
216
|
+
const nameSet = new Set(names);
|
|
217
|
+
const patterns = names.map((name) => inputs.value?.[name]?.pattern).filter(Boolean);
|
|
218
|
+
const matchesNames = (error) => {
|
|
219
|
+
if (!error.name) return false;
|
|
220
|
+
if (nameSet.has(error.name)) return true;
|
|
221
|
+
return patterns.some((pattern) => pattern.test(error.name));
|
|
222
|
+
};
|
|
223
|
+
const keepErrors = errors.value.filter((error) => !matchesNames(error));
|
|
224
|
+
const newErrors = allErrors.filter(matchesNames);
|
|
225
|
+
return [...keepErrors, ...newErrors];
|
|
226
|
+
}
|
|
227
|
+
function filterErrorsByTarget(currentErrors, target) {
|
|
228
|
+
return currentErrors.filter(
|
|
229
|
+
(err) => target instanceof RegExp ? !(err.name && target.test(err.name)) : !err.name || err.name !== target
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
function isLocalError(error) {
|
|
233
|
+
return !error.name || !!inputs.value[error.name];
|
|
234
|
+
}
|
|
187
235
|
const api = {
|
|
188
236
|
validate: _validate,
|
|
189
237
|
errors,
|
|
190
238
|
setErrors(errs, name) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
formErrors = errors.value.filter(
|
|
194
|
-
(err) => name instanceof RegExp ? !(err.name && name.test(err.name)) : err.name !== name
|
|
195
|
-
).concat(formErrors);
|
|
196
|
-
}
|
|
239
|
+
const localErrors = resolveErrorIds(errs.filter(isLocalError));
|
|
240
|
+
const nestedErrors = [];
|
|
197
241
|
for (const form of nestedForms.value.values()) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
...e,
|
|
203
|
-
name: e?.name.split(form.name + `.`)[1]
|
|
204
|
-
}];
|
|
205
|
-
}
|
|
206
|
-
return [];
|
|
207
|
-
});
|
|
208
|
-
const nameMatch = name instanceof RegExp ? form.name && name.test(form.name.toString()) : form.name !== name;
|
|
209
|
-
if (nameMatch || !form.name) {
|
|
210
|
-
form.api.setErrors(errors2, name);
|
|
211
|
-
formErrors = formErrors.concat(form.api.getErrors().map((e) => ({ ...e, name: form.name ? [form.name, e.name].join(".") : e.name })));
|
|
242
|
+
if (matchesTarget(name, form.name)) {
|
|
243
|
+
const formErrors = filterFormErrors(errs, form.name);
|
|
244
|
+
form.api.setErrors(formErrors, getNestedTarget(name, form.name || ""));
|
|
245
|
+
nestedErrors.push(...getFormErrors(form));
|
|
212
246
|
}
|
|
213
247
|
}
|
|
214
|
-
|
|
248
|
+
if (name) {
|
|
249
|
+
const keepErrors = filterErrorsByTarget(errors.value, name);
|
|
250
|
+
errors.value = [...keepErrors, ...localErrors, ...nestedErrors];
|
|
251
|
+
} else {
|
|
252
|
+
errors.value = [...localErrors, ...nestedErrors];
|
|
253
|
+
}
|
|
215
254
|
},
|
|
216
255
|
async submit() {
|
|
217
256
|
await onSubmitWrapper(new Event("submit"));
|
|
218
257
|
},
|
|
219
258
|
getErrors(name) {
|
|
220
|
-
if (name)
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
259
|
+
if (!name) return errors.value;
|
|
260
|
+
return errors.value.filter(
|
|
261
|
+
(err) => name instanceof RegExp ? err.name && name.test(err.name) : err.name === name
|
|
262
|
+
);
|
|
224
263
|
},
|
|
225
264
|
clear(name) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
return err.name && !!inputs.value[err.name] && (name instanceof RegExp ? !(err.name && name.test(err.name)) : err.name !== name);
|
|
231
|
-
}
|
|
232
|
-
);
|
|
233
|
-
}
|
|
265
|
+
const localErrors = name ? errors.value.filter(
|
|
266
|
+
(err) => isLocalError(err) && (name instanceof RegExp ? !(err.name && name.test(err.name)) : err.name !== name)
|
|
267
|
+
) : [];
|
|
268
|
+
const nestedErrors = [];
|
|
234
269
|
for (const form of nestedForms.value.values()) {
|
|
235
|
-
if (
|
|
236
|
-
|
|
237
|
-
else if (typeof name === "string" && name?.startsWith(form.name + `.`)) {
|
|
238
|
-
const nestedName = name?.split(`${form.name}.`)[1];
|
|
239
|
-
form.api.clear(nestedName);
|
|
240
|
-
}
|
|
241
|
-
formErrors = formErrors.concat(
|
|
242
|
-
form.api.getErrors().map((e) => ({
|
|
243
|
-
...e,
|
|
244
|
-
name: form.name ? [form.name, e.name].join(".") : e.name
|
|
245
|
-
}))
|
|
246
|
-
);
|
|
270
|
+
if (matchesTarget(name, form.name)) form.api.clear();
|
|
271
|
+
nestedErrors.push(...getFormErrors(form));
|
|
247
272
|
}
|
|
248
|
-
errors.value =
|
|
273
|
+
errors.value = [...localErrors, ...nestedErrors];
|
|
249
274
|
},
|
|
250
275
|
disabled,
|
|
251
276
|
loading,
|
|
@@ -3,10 +3,10 @@ import theme from "#build/ui/form-field";
|
|
|
3
3
|
</script>
|
|
4
4
|
|
|
5
5
|
<script setup>
|
|
6
|
-
import { computed, ref, inject, provide, useId } from "vue";
|
|
6
|
+
import { computed, ref, inject, provide, useId, watch } from "vue";
|
|
7
7
|
import { Primitive, Label } from "reka-ui";
|
|
8
8
|
import { useAppConfig } from "#imports";
|
|
9
|
-
import { formFieldInjectionKey, inputIdInjectionKey, formErrorsInjectionKey } from "../composables/useFormField";
|
|
9
|
+
import { formFieldInjectionKey, inputIdInjectionKey, formErrorsInjectionKey, formInputsInjectionKey } from "../composables/useFormField";
|
|
10
10
|
import { tv } from "../utils/tv";
|
|
11
11
|
const props = defineProps({
|
|
12
12
|
as: { type: null, required: false },
|
|
@@ -31,9 +31,15 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.formField ||
|
|
|
31
31
|
required: props.required
|
|
32
32
|
}));
|
|
33
33
|
const formErrors = inject(formErrorsInjectionKey, null);
|
|
34
|
-
const error = computed(() => props.error || formErrors?.value?.find((error2) => error2.name
|
|
34
|
+
const error = computed(() => props.error || formErrors?.value?.find((error2) => error2.name === props.name || props.errorPattern && error2.name?.match(props.errorPattern))?.message);
|
|
35
35
|
const id = ref(useId());
|
|
36
36
|
const ariaId = id.value;
|
|
37
|
+
const formInputs = inject(formInputsInjectionKey, void 0);
|
|
38
|
+
watch(id, () => {
|
|
39
|
+
if (formInputs && props.name) {
|
|
40
|
+
formInputs.value[props.name] = { id: id.value, pattern: props.errorPattern };
|
|
41
|
+
}
|
|
42
|
+
}, { immediate: true });
|
|
37
43
|
provide(inputIdInjectionKey, id);
|
|
38
44
|
provide(formFieldInjectionKey, computed(() => ({
|
|
39
45
|
error: error.value,
|
|
@@ -259,7 +259,7 @@ defineExpose({
|
|
|
259
259
|
@focus="onFocus"
|
|
260
260
|
@remove-tag="onRemoveTag"
|
|
261
261
|
>
|
|
262
|
-
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="item" :class="ui.tagsItem({ class: [props.ui?.tagsItem, isInputItem(item) && item.ui?.tagsItem] })">
|
|
262
|
+
<TagsInputItem v-for="(item, index) in tags" :key="index" :value="isInputItem(item) ? item : String(item)" :class="ui.tagsItem({ class: [props.ui?.tagsItem, isInputItem(item) && item.ui?.tagsItem] })">
|
|
263
263
|
<TagsInputItemText :class="ui.tagsItemText({ class: [props.ui?.tagsItemText, isInputItem(item) && item.ui?.tagsItemText] })">
|
|
264
264
|
<slot name="tags-item-text" :item="item" :index="index">
|
|
265
265
|
{{ displayValue(item) }}
|
|
@@ -112,8 +112,6 @@ defineExpose({
|
|
|
112
112
|
:name="name"
|
|
113
113
|
:disabled="disabled"
|
|
114
114
|
@update:model-value="onUpdate"
|
|
115
|
-
@blur="onBlur"
|
|
116
|
-
@focus="onFocus"
|
|
117
115
|
>
|
|
118
116
|
<TagsInputItem
|
|
119
117
|
v-for="(item, index) in tags"
|
|
@@ -141,6 +139,8 @@ defineExpose({
|
|
|
141
139
|
:placeholder="placeholder"
|
|
142
140
|
:max-length="maxLength"
|
|
143
141
|
:class="ui.input({ class: props.ui?.input })"
|
|
142
|
+
@blur="onBlur"
|
|
143
|
+
@focus="onFocus"
|
|
144
144
|
/>
|
|
145
145
|
|
|
146
146
|
<slot />
|
|
@@ -62,7 +62,7 @@ defineExpose({
|
|
|
62
62
|
v-for="(item, index) of items"
|
|
63
63
|
:key="index"
|
|
64
64
|
:ref="(el) => triggersRef[index] = el"
|
|
65
|
-
:value="item.value
|
|
65
|
+
:value="item.value ?? String(index)"
|
|
66
66
|
:disabled="item.disabled"
|
|
67
67
|
:class="ui.trigger({ class: [props.ui?.trigger, item.ui?.trigger] })"
|
|
68
68
|
>
|
|
@@ -91,7 +91,7 @@ defineExpose({
|
|
|
91
91
|
</TabsList>
|
|
92
92
|
|
|
93
93
|
<template v-if="!!content">
|
|
94
|
-
<TabsContent v-for="(item, index) of items" :key="index" :value="item.value
|
|
94
|
+
<TabsContent v-for="(item, index) of items" :key="index" :value="item.value ?? String(index)" :class="ui.content({ class: [props.ui?.content, item.ui?.content, item.class] })">
|
|
95
95
|
<slot :name="item.slot || 'content'" :item="item" :index="index">
|
|
96
96
|
{{ item.content }}
|
|
97
97
|
</slot>
|
|
@@ -2,7 +2,7 @@ import type { TreeRootProps, TreeRootEmits } from 'reka-ui';
|
|
|
2
2
|
import type { AppConfig } from '@nuxt/schema';
|
|
3
3
|
import theme from '#build/ui/tree';
|
|
4
4
|
import type { IconProps } from '../types';
|
|
5
|
-
import type { DynamicSlots, GetItemKeys
|
|
5
|
+
import type { DynamicSlots, GetItemKeys } from '../types/utils';
|
|
6
6
|
import type { ComponentConfig } from '../types/tv';
|
|
7
7
|
type Tree = ComponentConfig<typeof theme, AppConfig, 'tree'>;
|
|
8
8
|
export type TreeItem = {
|
|
@@ -17,7 +17,6 @@ export type TreeItem = {
|
|
|
17
17
|
trailingIcon?: IconProps['name'];
|
|
18
18
|
defaultExpanded?: boolean;
|
|
19
19
|
disabled?: boolean;
|
|
20
|
-
value?: string;
|
|
21
20
|
slot?: string;
|
|
22
21
|
children?: TreeItem[];
|
|
23
22
|
onToggle?(e: Event): void;
|
|
@@ -26,7 +25,7 @@ export type TreeItem = {
|
|
|
26
25
|
ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
|
|
27
26
|
[key: string]: any;
|
|
28
27
|
};
|
|
29
|
-
export interface TreeProps<T extends TreeItem[] = TreeItem[],
|
|
28
|
+
export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
|
|
30
29
|
/**
|
|
31
30
|
* The element or component this component should render as.
|
|
32
31
|
* @defaultValue 'ul'
|
|
@@ -40,11 +39,8 @@ export interface TreeProps<T extends TreeItem[] = TreeItem[], VK extends GetItem
|
|
|
40
39
|
* @defaultValue 'md'
|
|
41
40
|
*/
|
|
42
41
|
size?: Tree['variants']['size'];
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
* @defaultValue 'value'
|
|
46
|
-
*/
|
|
47
|
-
valueKey?: VK;
|
|
42
|
+
/** This function is passed the index of each item and should return a unique key for that item */
|
|
43
|
+
getKey?: (val: T[number]) => string;
|
|
48
44
|
/**
|
|
49
45
|
* The key used to get the label from the item.
|
|
50
46
|
* @defaultValue 'label'
|
|
@@ -70,15 +66,15 @@ export interface TreeProps<T extends TreeItem[] = TreeItem[], VK extends GetItem
|
|
|
70
66
|
collapsedIcon?: IconProps['name'];
|
|
71
67
|
items?: T;
|
|
72
68
|
/** The controlled value of the Tree. Can be bind as `v-model`. */
|
|
73
|
-
modelValue?:
|
|
69
|
+
modelValue?: M extends true ? T[number][] : T[number];
|
|
74
70
|
/** The value of the Tree when initially rendered. Use when you do not need to control the state of the Tree. */
|
|
75
|
-
defaultValue?:
|
|
71
|
+
defaultValue?: M extends true ? T[number][] : T[number];
|
|
76
72
|
/** Whether multiple options can be selected or not. */
|
|
77
73
|
multiple?: M & boolean;
|
|
78
74
|
class?: any;
|
|
79
75
|
ui?: Tree['slots'];
|
|
80
76
|
}
|
|
81
|
-
export type TreeEmits<
|
|
77
|
+
export type TreeEmits<T extends TreeItem[] = TreeItem[], M extends boolean = false> = TreeRootEmits<T[number], M>;
|
|
82
78
|
type SlotProps<T extends TreeItem> = (props: {
|
|
83
79
|
item: T;
|
|
84
80
|
index: number;
|
|
@@ -86,27 +82,27 @@ type SlotProps<T extends TreeItem> = (props: {
|
|
|
86
82
|
expanded: boolean;
|
|
87
83
|
selected: boolean;
|
|
88
84
|
}) => any;
|
|
89
|
-
export type TreeSlots<
|
|
90
|
-
'item-wrapper': SlotProps<T>;
|
|
91
|
-
'item': SlotProps<T>;
|
|
92
|
-
'item-leading': SlotProps<T>;
|
|
93
|
-
'item-label': SlotProps<T>;
|
|
94
|
-
'item-trailing': SlotProps<T>;
|
|
95
|
-
} & DynamicSlots<T, undefined, {
|
|
85
|
+
export type TreeSlots<T extends TreeItem[] = TreeItem[]> = {
|
|
86
|
+
'item-wrapper': SlotProps<T[number]>;
|
|
87
|
+
'item': SlotProps<T[number]>;
|
|
88
|
+
'item-leading': SlotProps<T[number]>;
|
|
89
|
+
'item-label': SlotProps<T[number]>;
|
|
90
|
+
'item-trailing': SlotProps<T[number]>;
|
|
91
|
+
} & DynamicSlots<T[number], undefined, {
|
|
96
92
|
index: number;
|
|
97
93
|
level: number;
|
|
98
94
|
expanded: boolean;
|
|
99
95
|
selected: boolean;
|
|
100
96
|
}>;
|
|
101
|
-
declare const _default: <T extends TreeItem[],
|
|
97
|
+
declare const _default: <T extends TreeItem[], M extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
102
98
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
103
|
-
readonly "onUpdate:modelValue"?: ((
|
|
99
|
+
readonly "onUpdate:modelValue"?: ((val: M extends true ? T[number][] : T[number]) => any) | undefined;
|
|
104
100
|
readonly "onUpdate:expanded"?: ((val: string[]) => any) | undefined;
|
|
105
|
-
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue" | "onUpdate:expanded"> & TreeProps<T,
|
|
101
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue" | "onUpdate:expanded"> & TreeProps<T, M> & {}> & import("vue").PublicProps;
|
|
106
102
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
107
103
|
attrs: any;
|
|
108
|
-
slots: TreeSlots<T
|
|
109
|
-
emit: ((evt: "update:modelValue",
|
|
104
|
+
slots: TreeSlots<T>;
|
|
105
|
+
emit: ((evt: "update:modelValue", val: M extends true ? T[number][] : T[number]) => void) & ((evt: "update:expanded", val: string[]) => void);
|
|
110
106
|
}>) => import("vue").VNode & {
|
|
111
107
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
112
108
|
};
|
|
@@ -15,7 +15,7 @@ const props = defineProps({
|
|
|
15
15
|
as: { type: null, required: false },
|
|
16
16
|
color: { type: null, required: false },
|
|
17
17
|
size: { type: null, required: false },
|
|
18
|
-
|
|
18
|
+
getKey: { type: Function, required: false },
|
|
19
19
|
labelKey: { type: null, required: false, default: "label" },
|
|
20
20
|
trailingIcon: { type: [String, Object], required: false },
|
|
21
21
|
expandedIcon: { type: [String, Object], required: false },
|
|
@@ -33,10 +33,10 @@ const props = defineProps({
|
|
|
33
33
|
disabled: { type: Boolean, required: false },
|
|
34
34
|
bubbleSelect: { type: Boolean, required: false }
|
|
35
35
|
});
|
|
36
|
-
const emits = defineEmits(["update:
|
|
36
|
+
const emits = defineEmits(["update:modelValue", "update:expanded"]);
|
|
37
37
|
const slots = defineSlots();
|
|
38
38
|
const appConfig = useAppConfig();
|
|
39
|
-
const rootProps = useForwardPropsEmits(reactivePick(props, "as", "
|
|
39
|
+
const rootProps = useForwardPropsEmits(reactivePick(props, "as", "items", "multiple", "expanded", "disabled", "propagateSelect", "bubbleSelect"), emits);
|
|
40
40
|
const [DefineTreeTemplate, ReuseTreeTemplate] = createReusableTemplate();
|
|
41
41
|
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.tree || {} })({
|
|
42
42
|
color: props.color,
|
|
@@ -45,11 +45,11 @@ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.tree || {} })
|
|
|
45
45
|
function getItemLabel(item) {
|
|
46
46
|
return get(item, props.labelKey);
|
|
47
47
|
}
|
|
48
|
-
function
|
|
49
|
-
return
|
|
48
|
+
function getItemKey(item) {
|
|
49
|
+
return props.getKey ? props.getKey(item) || getItemLabel(item) : getItemLabel(item);
|
|
50
50
|
}
|
|
51
51
|
function getDefaultOpenedItems(item) {
|
|
52
|
-
const currentItem = item.defaultExpanded ?
|
|
52
|
+
const currentItem = item.defaultExpanded ? getItemKey(item) : null;
|
|
53
53
|
const childItems = item.children?.flatMap((child) => getDefaultOpenedItems(child)) ?? [];
|
|
54
54
|
return [currentItem, ...childItems].filter(Boolean);
|
|
55
55
|
}
|
|
@@ -72,7 +72,8 @@ const defaultExpanded = computed(
|
|
|
72
72
|
>
|
|
73
73
|
<slot
|
|
74
74
|
:name="item.slot ? `${item.slot}-wrapper` : 'item-wrapper'"
|
|
75
|
-
v-bind="{
|
|
75
|
+
v-bind="{ index, level, expanded: isExpanded, selected: isSelected }"
|
|
76
|
+
:item="item"
|
|
76
77
|
>
|
|
77
78
|
<button
|
|
78
79
|
type="button"
|
|
@@ -80,8 +81,16 @@ const defaultExpanded = computed(
|
|
|
80
81
|
:data-expanded="isExpanded"
|
|
81
82
|
:class="ui.link({ class: [props.ui?.link, item.ui?.link, item.class], selected: isSelected, disabled: item.disabled || disabled })"
|
|
82
83
|
>
|
|
83
|
-
<slot
|
|
84
|
-
|
|
84
|
+
<slot
|
|
85
|
+
:name="item.slot || 'item'"
|
|
86
|
+
v-bind="{ index, level, expanded: isExpanded, selected: isSelected }"
|
|
87
|
+
:item="item"
|
|
88
|
+
>
|
|
89
|
+
<slot
|
|
90
|
+
:name="item.slot ? `${item.slot}-leading` : 'item-leading'"
|
|
91
|
+
v-bind="{ index, level, expanded: isExpanded, selected: isSelected }"
|
|
92
|
+
:item="item"
|
|
93
|
+
>
|
|
85
94
|
<UIcon
|
|
86
95
|
v-if="item.icon"
|
|
87
96
|
:name="item.icon"
|
|
@@ -100,7 +109,8 @@ const defaultExpanded = computed(
|
|
|
100
109
|
>
|
|
101
110
|
<slot
|
|
102
111
|
:name="item.slot ? `${item.slot}-label` : 'item-label'"
|
|
103
|
-
v-bind="{
|
|
112
|
+
v-bind="{ index, level, expanded: isExpanded, selected: isSelected }"
|
|
113
|
+
:item="item"
|
|
104
114
|
>
|
|
105
115
|
{{ getItemLabel(item) }}
|
|
106
116
|
</slot>
|
|
@@ -112,7 +122,8 @@ const defaultExpanded = computed(
|
|
|
112
122
|
>
|
|
113
123
|
<slot
|
|
114
124
|
:name="item.slot ? `${item.slot}-trailing` : 'item-trailing'"
|
|
115
|
-
v-bind="{
|
|
125
|
+
v-bind="{ index, level, expanded: isExpanded, selected: isSelected }"
|
|
126
|
+
:item="item"
|
|
116
127
|
>
|
|
117
128
|
<UIcon
|
|
118
129
|
v-if="item.trailingIcon"
|
|
@@ -142,8 +153,10 @@ const defaultExpanded = computed(
|
|
|
142
153
|
|
|
143
154
|
<TreeRoot
|
|
144
155
|
v-bind="{ ...rootProps, ...$attrs }"
|
|
156
|
+
:model-value="modelValue"
|
|
157
|
+
:default-value="defaultValue"
|
|
145
158
|
:class="ui.root({ class: [props.ui?.root, props.class] })"
|
|
146
|
-
:get-key="
|
|
159
|
+
:get-key="getItemKey"
|
|
147
160
|
:default-expanded="defaultExpanded"
|
|
148
161
|
:selection-behavior="selectionBehavior"
|
|
149
162
|
>
|
|
@@ -2,7 +2,7 @@ import type { TreeRootProps, TreeRootEmits } from 'reka-ui';
|
|
|
2
2
|
import type { AppConfig } from '@nuxt/schema';
|
|
3
3
|
import theme from '#build/ui/tree';
|
|
4
4
|
import type { IconProps } from '../types';
|
|
5
|
-
import type { DynamicSlots, GetItemKeys
|
|
5
|
+
import type { DynamicSlots, GetItemKeys } from '../types/utils';
|
|
6
6
|
import type { ComponentConfig } from '../types/tv';
|
|
7
7
|
type Tree = ComponentConfig<typeof theme, AppConfig, 'tree'>;
|
|
8
8
|
export type TreeItem = {
|
|
@@ -17,7 +17,6 @@ export type TreeItem = {
|
|
|
17
17
|
trailingIcon?: IconProps['name'];
|
|
18
18
|
defaultExpanded?: boolean;
|
|
19
19
|
disabled?: boolean;
|
|
20
|
-
value?: string;
|
|
21
20
|
slot?: string;
|
|
22
21
|
children?: TreeItem[];
|
|
23
22
|
onToggle?(e: Event): void;
|
|
@@ -26,7 +25,7 @@ export type TreeItem = {
|
|
|
26
25
|
ui?: Pick<Tree['slots'], 'item' | 'itemWithChildren' | 'link' | 'linkLeadingIcon' | 'linkLabel' | 'linkTrailing' | 'linkTrailingIcon' | 'listWithChildren'>;
|
|
27
26
|
[key: string]: any;
|
|
28
27
|
};
|
|
29
|
-
export interface TreeProps<T extends TreeItem[] = TreeItem[],
|
|
28
|
+
export interface TreeProps<T extends TreeItem[] = TreeItem[], M extends boolean = false> extends Pick<TreeRootProps<T>, 'expanded' | 'defaultExpanded' | 'selectionBehavior' | 'propagateSelect' | 'disabled' | 'bubbleSelect'> {
|
|
30
29
|
/**
|
|
31
30
|
* The element or component this component should render as.
|
|
32
31
|
* @defaultValue 'ul'
|
|
@@ -40,11 +39,8 @@ export interface TreeProps<T extends TreeItem[] = TreeItem[], VK extends GetItem
|
|
|
40
39
|
* @defaultValue 'md'
|
|
41
40
|
*/
|
|
42
41
|
size?: Tree['variants']['size'];
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
* @defaultValue 'value'
|
|
46
|
-
*/
|
|
47
|
-
valueKey?: VK;
|
|
42
|
+
/** This function is passed the index of each item and should return a unique key for that item */
|
|
43
|
+
getKey?: (val: T[number]) => string;
|
|
48
44
|
/**
|
|
49
45
|
* The key used to get the label from the item.
|
|
50
46
|
* @defaultValue 'label'
|
|
@@ -70,15 +66,15 @@ export interface TreeProps<T extends TreeItem[] = TreeItem[], VK extends GetItem
|
|
|
70
66
|
collapsedIcon?: IconProps['name'];
|
|
71
67
|
items?: T;
|
|
72
68
|
/** The controlled value of the Tree. Can be bind as `v-model`. */
|
|
73
|
-
modelValue?:
|
|
69
|
+
modelValue?: M extends true ? T[number][] : T[number];
|
|
74
70
|
/** The value of the Tree when initially rendered. Use when you do not need to control the state of the Tree. */
|
|
75
|
-
defaultValue?:
|
|
71
|
+
defaultValue?: M extends true ? T[number][] : T[number];
|
|
76
72
|
/** Whether multiple options can be selected or not. */
|
|
77
73
|
multiple?: M & boolean;
|
|
78
74
|
class?: any;
|
|
79
75
|
ui?: Tree['slots'];
|
|
80
76
|
}
|
|
81
|
-
export type TreeEmits<
|
|
77
|
+
export type TreeEmits<T extends TreeItem[] = TreeItem[], M extends boolean = false> = TreeRootEmits<T[number], M>;
|
|
82
78
|
type SlotProps<T extends TreeItem> = (props: {
|
|
83
79
|
item: T;
|
|
84
80
|
index: number;
|
|
@@ -86,27 +82,27 @@ type SlotProps<T extends TreeItem> = (props: {
|
|
|
86
82
|
expanded: boolean;
|
|
87
83
|
selected: boolean;
|
|
88
84
|
}) => any;
|
|
89
|
-
export type TreeSlots<
|
|
90
|
-
'item-wrapper': SlotProps<T>;
|
|
91
|
-
'item': SlotProps<T>;
|
|
92
|
-
'item-leading': SlotProps<T>;
|
|
93
|
-
'item-label': SlotProps<T>;
|
|
94
|
-
'item-trailing': SlotProps<T>;
|
|
95
|
-
} & DynamicSlots<T, undefined, {
|
|
85
|
+
export type TreeSlots<T extends TreeItem[] = TreeItem[]> = {
|
|
86
|
+
'item-wrapper': SlotProps<T[number]>;
|
|
87
|
+
'item': SlotProps<T[number]>;
|
|
88
|
+
'item-leading': SlotProps<T[number]>;
|
|
89
|
+
'item-label': SlotProps<T[number]>;
|
|
90
|
+
'item-trailing': SlotProps<T[number]>;
|
|
91
|
+
} & DynamicSlots<T[number], undefined, {
|
|
96
92
|
index: number;
|
|
97
93
|
level: number;
|
|
98
94
|
expanded: boolean;
|
|
99
95
|
selected: boolean;
|
|
100
96
|
}>;
|
|
101
|
-
declare const _default: <T extends TreeItem[],
|
|
97
|
+
declare const _default: <T extends TreeItem[], M extends boolean = false>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
102
98
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
103
|
-
readonly "onUpdate:modelValue"?: ((
|
|
99
|
+
readonly "onUpdate:modelValue"?: ((val: M extends true ? T[number][] : T[number]) => any) | undefined;
|
|
104
100
|
readonly "onUpdate:expanded"?: ((val: string[]) => any) | undefined;
|
|
105
|
-
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue" | "onUpdate:expanded"> & TreeProps<T,
|
|
101
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:modelValue" | "onUpdate:expanded"> & TreeProps<T, M> & {}> & import("vue").PublicProps;
|
|
106
102
|
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
107
103
|
attrs: any;
|
|
108
|
-
slots: TreeSlots<T
|
|
109
|
-
emit: ((evt: "update:modelValue",
|
|
104
|
+
slots: TreeSlots<T>;
|
|
105
|
+
emit: ((evt: "update:modelValue", val: M extends true ? T[number][] : T[number]) => void) & ((evt: "update:expanded", val: string[]) => void);
|
|
110
106
|
}>) => import("vue").VNode & {
|
|
111
107
|
__ctx?: Awaited<typeof __VLS_setup>;
|
|
112
108
|
};
|
|
@@ -12,7 +12,6 @@ export function useFormField(props, opts) {
|
|
|
12
12
|
const formOptions = inject(formOptionsInjectionKey, void 0);
|
|
13
13
|
const formBus = inject(formBusInjectionKey, void 0);
|
|
14
14
|
const formField = inject(formFieldInjectionKey, void 0);
|
|
15
|
-
const formInputs = inject(formInputsInjectionKey, void 0);
|
|
16
15
|
const inputId = inject(inputIdInjectionKey, void 0);
|
|
17
16
|
provide(formFieldInjectionKey, void 0);
|
|
18
17
|
if (formField && inputId) {
|
|
@@ -21,9 +20,6 @@ export function useFormField(props, opts) {
|
|
|
21
20
|
} else if (props?.id) {
|
|
22
21
|
inputId.value = props?.id;
|
|
23
22
|
}
|
|
24
|
-
if (formInputs && formField.value.name && inputId.value) {
|
|
25
|
-
formInputs.value[formField.value.name] = { id: inputId.value, pattern: formField.value.errorPattern };
|
|
26
|
-
}
|
|
27
23
|
}
|
|
28
24
|
function emitFormEvent(type, name, eager) {
|
|
29
25
|
if (formBus && formField && name) {
|
|
@@ -27,7 +27,7 @@ export default defineLocale({
|
|
|
27
27
|
prev: "Anterior"
|
|
28
28
|
},
|
|
29
29
|
chatPrompt: {
|
|
30
|
-
placeholder: "Escreva sua mensagem aqui..."
|
|
30
|
+
placeholder: "Escreva a sua mensagem aqui..."
|
|
31
31
|
},
|
|
32
32
|
chatPromptSubmit: {
|
|
33
33
|
label: "Enviar"
|
|
@@ -114,7 +114,7 @@ export default defineLocale({
|
|
|
114
114
|
create: 'Criar "{label}"',
|
|
115
115
|
noData: "Sem dados",
|
|
116
116
|
noMatch: "Nenhum dado correspondente",
|
|
117
|
-
search: "
|
|
117
|
+
search: "Pesquisar..."
|
|
118
118
|
},
|
|
119
119
|
slideover: {
|
|
120
120
|
close: "Fechar"
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
2
|
import type { ComputedRef, DeepReadonly, Ref } from 'vue';
|
|
3
|
-
import type { Schema as JoiSchema } from 'joi';
|
|
4
|
-
import type { ObjectSchema as YupObjectSchema } from 'yup';
|
|
5
3
|
import type { GetObjectField } from './utils';
|
|
6
4
|
import type { Struct as SuperstructSchema } from 'superstruct';
|
|
7
5
|
export interface Form<S extends FormSchema> {
|
|
@@ -23,9 +21,9 @@ export interface Form<S extends FormSchema> {
|
|
|
23
21
|
touchedFields: ReadonlySet<DeepReadonly<keyof FormData<S, false>>>;
|
|
24
22
|
blurredFields: ReadonlySet<DeepReadonly<keyof FormData<S, false>>>;
|
|
25
23
|
}
|
|
26
|
-
export type FormSchema<I extends object = object, O extends object = I> =
|
|
27
|
-
export type InferInput<Schema> = Schema extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Schema> : Schema extends
|
|
28
|
-
export type InferOutput<Schema> = Schema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Schema> : Schema extends
|
|
24
|
+
export type FormSchema<I extends object = object, O extends object = I> = SuperstructSchema<any, any> | StandardSchemaV1<I, O>;
|
|
25
|
+
export type InferInput<Schema> = Schema extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Schema> : Schema extends SuperstructSchema<infer I, any> ? I : Schema extends StandardSchemaV1 ? StandardSchemaV1.InferInput<Schema> : never;
|
|
26
|
+
export type InferOutput<Schema> = Schema extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<Schema> : Schema extends SuperstructSchema<infer O, any> ? O : never;
|
|
29
27
|
export type FormData<S extends FormSchema, T extends boolean = true> = T extends true ? InferOutput<S> : InferInput<S>;
|
|
30
28
|
export type FormInputEvents = 'input' | 'blur' | 'change' | 'focus';
|
|
31
29
|
export interface FormError<P extends string = string> {
|
|
@@ -4,11 +4,18 @@ import type { ClassValue, TVVariants, TVCompoundVariants, TVDefaultVariants } fr
|
|
|
4
4
|
*/
|
|
5
5
|
export type TVConfig<T extends Record<string, any>> = {
|
|
6
6
|
[P in keyof T]?: {
|
|
7
|
-
[K in keyof T[P] as K extends 'base' | 'slots' | 'variants' | '
|
|
7
|
+
[K in keyof T[P] as K extends 'base' | 'slots' | 'variants' | 'defaultVariants' ? K : never]?: K extends 'base' ? ClassValue : K extends 'slots' ? {
|
|
8
8
|
[S in keyof T[P]['slots']]?: ClassValue;
|
|
9
|
-
} : K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue,
|
|
9
|
+
} : K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, WidenVariantsValues<T[P]['variants']>> : K extends 'defaultVariants' ? TVDefaultVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], object, undefined> : never;
|
|
10
|
+
};
|
|
11
|
+
} & {
|
|
12
|
+
[P in keyof T]?: {
|
|
13
|
+
compoundVariants?: TVCompoundVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], ClassValue, object, undefined>;
|
|
10
14
|
};
|
|
11
15
|
};
|
|
16
|
+
type WidenVariantsValues<V extends Record<string, any> | undefined> = V extends Record<string, any> ? V & {
|
|
17
|
+
[K in keyof V]: V[K] extends Record<string, any> ? V[K] & Record<string & {}, any> : V[K];
|
|
18
|
+
} : V;
|
|
12
19
|
/**
|
|
13
20
|
* Utility type to flatten intersection types for better IDE hover information.
|
|
14
21
|
* @template T The type to flatten.
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
-
import type { ValidationError as JoiError, Schema as JoiSchema } from 'joi';
|
|
3
|
-
import type { ObjectSchema as YupObjectSchema, ValidationError as YupError } from 'yup';
|
|
4
2
|
import type { Struct } from 'superstruct';
|
|
5
3
|
import type { FormSchema, ValidateReturnSchema } from '../types/form';
|
|
6
|
-
export declare function isYupSchema(schema: any): schema is YupObjectSchema<any>;
|
|
7
|
-
export declare function isYupError(error: any): error is YupError;
|
|
8
4
|
export declare function isSuperStructSchema(schema: any): schema is Struct<any, any>;
|
|
9
|
-
export declare function isJoiSchema(schema: any): schema is JoiSchema;
|
|
10
|
-
export declare function isJoiError(error: any): error is JoiError;
|
|
11
5
|
export declare function isStandardSchema(schema: any): schema is StandardSchemaV1;
|
|
12
6
|
export declare function validateStandardSchema(state: any, schema: StandardSchemaV1): Promise<ValidateReturnSchema<typeof state>>;
|
|
13
7
|
export declare function validateSchema<T extends object>(state: T, schema: FormSchema<T>): Promise<ValidateReturnSchema<typeof state>>;
|
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
export function isYupSchema(schema) {
|
|
2
|
-
return schema.validate && schema.__isYupSchema__;
|
|
3
|
-
}
|
|
4
|
-
export function isYupError(error) {
|
|
5
|
-
return error.inner !== void 0;
|
|
6
|
-
}
|
|
7
1
|
export function isSuperStructSchema(schema) {
|
|
8
2
|
return "schema" in schema && typeof schema.coercer === "function" && typeof schema.validator === "function" && typeof schema.refiner === "function";
|
|
9
3
|
}
|
|
10
|
-
export function isJoiSchema(schema) {
|
|
11
|
-
return schema.validateAsync !== void 0 && schema.id !== void 0;
|
|
12
|
-
}
|
|
13
|
-
export function isJoiError(error) {
|
|
14
|
-
return error.isJoi === true;
|
|
15
|
-
}
|
|
16
4
|
export function isStandardSchema(schema) {
|
|
17
5
|
return "~standard" in schema;
|
|
18
6
|
}
|
|
@@ -32,28 +20,6 @@ export async function validateStandardSchema(state, schema) {
|
|
|
32
20
|
result: result.value
|
|
33
21
|
};
|
|
34
22
|
}
|
|
35
|
-
async function validateYupSchema(state, schema) {
|
|
36
|
-
try {
|
|
37
|
-
const result = await schema.validate(state, { abortEarly: false });
|
|
38
|
-
return {
|
|
39
|
-
errors: null,
|
|
40
|
-
result
|
|
41
|
-
};
|
|
42
|
-
} catch (error) {
|
|
43
|
-
if (isYupError(error)) {
|
|
44
|
-
const errors = error.inner.map((issue) => ({
|
|
45
|
-
name: issue.path ?? "",
|
|
46
|
-
message: issue.message
|
|
47
|
-
}));
|
|
48
|
-
return {
|
|
49
|
-
errors,
|
|
50
|
-
result: null
|
|
51
|
-
};
|
|
52
|
-
} else {
|
|
53
|
-
throw error;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
23
|
async function validateSuperstructSchema(state, schema) {
|
|
58
24
|
const [err, result] = schema.validate(state);
|
|
59
25
|
if (err) {
|
|
@@ -71,35 +37,9 @@ async function validateSuperstructSchema(state, schema) {
|
|
|
71
37
|
result
|
|
72
38
|
};
|
|
73
39
|
}
|
|
74
|
-
async function validateJoiSchema(state, schema) {
|
|
75
|
-
try {
|
|
76
|
-
const result = await schema.validateAsync(state, { abortEarly: false });
|
|
77
|
-
return {
|
|
78
|
-
errors: null,
|
|
79
|
-
result
|
|
80
|
-
};
|
|
81
|
-
} catch (error) {
|
|
82
|
-
if (isJoiError(error)) {
|
|
83
|
-
const errors = error.details.map((issue) => ({
|
|
84
|
-
name: issue.path.join("."),
|
|
85
|
-
message: issue.message
|
|
86
|
-
}));
|
|
87
|
-
return {
|
|
88
|
-
errors,
|
|
89
|
-
result: null
|
|
90
|
-
};
|
|
91
|
-
} else {
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
40
|
export function validateSchema(state, schema) {
|
|
97
41
|
if (isStandardSchema(schema)) {
|
|
98
42
|
return validateStandardSchema(state, schema);
|
|
99
|
-
} else if (isJoiSchema(schema)) {
|
|
100
|
-
return validateJoiSchema(state, schema);
|
|
101
|
-
} else if (isYupSchema(schema)) {
|
|
102
|
-
return validateYupSchema(state, schema);
|
|
103
43
|
} else if (isSuperStructSchema(schema)) {
|
|
104
44
|
return validateSuperstructSchema(state, schema);
|
|
105
45
|
} else {
|
|
@@ -6082,7 +6082,7 @@ const icon = {
|
|
|
6082
6082
|
|
|
6083
6083
|
const img = {
|
|
6084
6084
|
slots: {
|
|
6085
|
-
base: "rounded-md",
|
|
6085
|
+
base: "rounded-md w-full",
|
|
6086
6086
|
overlay: "fixed inset-0 bg-default/75 backdrop-blur-sm will-change-opacity",
|
|
6087
6087
|
content: "fixed inset-0 flex items-center justify-center cursor-zoom-out focus:outline-none p-4 sm:p-8"
|
|
6088
6088
|
},
|
package/dist/unplugin.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { join, normalize } from 'pathe';
|
|
|
3
3
|
import { createUnplugin } from 'unplugin';
|
|
4
4
|
import { defu } from 'defu';
|
|
5
5
|
import tailwind from '@tailwindcss/vite';
|
|
6
|
-
import { g as getTemplates, d as defaultOptions, r as resolveColors, a as getDefaultUiConfig } from './shared/ui.
|
|
6
|
+
import { g as getTemplates, d as defaultOptions, r as resolveColors, a as getDefaultUiConfig } from './shared/ui.DGJZ-1aX.mjs';
|
|
7
7
|
import MagicString from 'magic-string';
|
|
8
8
|
import { genSafeVariableName } from 'knitwork';
|
|
9
9
|
import { resolvePathSync } from 'mlly';
|
package/dist/vite.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt/ui",
|
|
3
3
|
"description": "A UI Library for Modern Web Apps, powered by Vue & Tailwind CSS.",
|
|
4
|
-
"version": "4.0.0-
|
|
5
|
-
"packageManager": "pnpm@10.
|
|
4
|
+
"version": "4.0.0-beta.0",
|
|
5
|
+
"packageManager": "pnpm@10.17.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/nuxt/ui.git"
|
|
@@ -108,10 +108,10 @@
|
|
|
108
108
|
"typecheck": "vue-tsc --noEmit && nuxt typecheck playgrounds/nuxt && nuxt typecheck docs && cd playgrounds/vue && vue-tsc --noEmit",
|
|
109
109
|
"test": "vitest",
|
|
110
110
|
"test:vue": "vitest -c vitest.vue.config.ts",
|
|
111
|
-
"release": "release-it --preRelease=
|
|
111
|
+
"release": "release-it --preRelease=beta"
|
|
112
112
|
},
|
|
113
113
|
"dependencies": {
|
|
114
|
-
"@ai-sdk/vue": "^2.0.
|
|
114
|
+
"@ai-sdk/vue": "^2.0.48",
|
|
115
115
|
"@iconify/vue": "^5.0.0",
|
|
116
116
|
"@internationalized/date": "^3.9.0",
|
|
117
117
|
"@internationalized/number": "^3.6.5",
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
"@tailwindcss/postcss": "^4.1.13",
|
|
125
125
|
"@tailwindcss/vite": "^4.1.13",
|
|
126
126
|
"@tanstack/vue-table": "^8.21.3",
|
|
127
|
-
"@unhead/vue": "^2.0.
|
|
127
|
+
"@unhead/vue": "^2.0.17",
|
|
128
128
|
"@vueuse/core": "^13.9.0",
|
|
129
129
|
"@vueuse/integrations": "^13.9.0",
|
|
130
130
|
"colortranslator": "^5.0.0",
|
|
@@ -153,34 +153,34 @@
|
|
|
153
153
|
"tinyglobby": "^0.2.15",
|
|
154
154
|
"unplugin": "^2.3.10",
|
|
155
155
|
"unplugin-auto-import": "^20.1.0",
|
|
156
|
-
"unplugin-vue-components": "^29.
|
|
156
|
+
"unplugin-vue-components": "^29.1.0",
|
|
157
157
|
"vaul-vue": "0.4.1",
|
|
158
158
|
"vue-component-type-helpers": "^3.0.7"
|
|
159
159
|
},
|
|
160
160
|
"devDependencies": {
|
|
161
|
-
"@nuxt/content": "^3.7.
|
|
161
|
+
"@nuxt/content": "^3.7.1",
|
|
162
162
|
"@nuxt/eslint-config": "^1.9.0",
|
|
163
163
|
"@nuxt/module-builder": "^1.0.2",
|
|
164
164
|
"@nuxt/test-utils": "^3.19.2",
|
|
165
165
|
"@release-it/conventional-changelog": "^10.0.1",
|
|
166
166
|
"@vue/test-utils": "^2.4.6",
|
|
167
167
|
"embla-carousel": "^8.6.0",
|
|
168
|
-
"eslint": "^9.
|
|
168
|
+
"eslint": "^9.36.0",
|
|
169
169
|
"happy-dom": "^18.0.1",
|
|
170
170
|
"nuxt": "^4.0.3",
|
|
171
|
-
"release-it": "^19.0.
|
|
171
|
+
"release-it": "^19.0.5",
|
|
172
172
|
"vitest": "^3.2.4",
|
|
173
173
|
"vitest-environment-nuxt": "^1.0.1",
|
|
174
174
|
"vue-tsc": "^3.0.7"
|
|
175
175
|
},
|
|
176
176
|
"peerDependencies": {
|
|
177
177
|
"@inertiajs/vue3": "^2.0.7",
|
|
178
|
-
"joi": "^
|
|
178
|
+
"joi": "^18.0.0",
|
|
179
179
|
"superstruct": "^2.0.0",
|
|
180
180
|
"typescript": "^5.6.3",
|
|
181
181
|
"valibot": "^1.0.0",
|
|
182
182
|
"vue-router": "^4.5.0",
|
|
183
|
-
"yup": "^1.
|
|
183
|
+
"yup": "^1.7.0",
|
|
184
184
|
"zod": "^3.24.0 || ^4.0.0"
|
|
185
185
|
},
|
|
186
186
|
"peerDependenciesMeta": {
|