@nuxt/ui 4.0.0-alpha.1 → 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/content/content-navigation.ts +2 -1
- package/.nuxt/ui/marquee.ts +1 -1
- package/.nuxt/ui/progress.ts +3 -3
- package/.nuxt/ui/prose/code-tree.ts +1 -1
- package/.nuxt/ui/prose/img.ts +1 -1
- package/.nuxt/ui/tree.ts +1 -1
- package/README.md +14 -1
- package/dist/module.d.mts +6 -6
- package/dist/module.json +2 -2
- package/dist/module.mjs +8 -6
- package/dist/runtime/components/Accordion.d.vue.ts +79 -0
- package/dist/runtime/components/Accordion.vue +3 -3
- package/dist/runtime/components/Accordion.vue.d.ts +2 -2
- package/dist/runtime/components/Alert.d.vue.ts +81 -0
- package/dist/runtime/components/App.d.vue.ts +25 -0
- package/dist/runtime/components/AuthForm.d.vue.ts +128 -0
- package/dist/runtime/components/AuthForm.vue.d.ts +39 -1
- package/dist/runtime/components/Avatar.d.vue.ts +41 -0
- package/dist/runtime/components/AvatarGroup.d.vue.ts +31 -0
- package/dist/runtime/components/Badge.d.vue.ts +43 -0
- package/dist/runtime/components/Banner.d.vue.ts +72 -0
- package/dist/runtime/components/Banner.vue +1 -1
- package/dist/runtime/components/BlogPost.d.vue.ts +60 -0
- package/dist/runtime/components/BlogPosts.d.vue.ts +31 -0
- package/dist/runtime/components/Breadcrumb.d.vue.ts +67 -0
- package/dist/runtime/components/Breadcrumb.vue +1 -1
- package/dist/runtime/components/Breadcrumb.vue.d.ts +2 -2
- package/dist/runtime/components/Button.d.vue.ts +44 -0
- package/dist/runtime/components/Calendar.d.vue.ts +112 -0
- package/dist/runtime/components/Card.d.vue.ts +29 -0
- package/dist/runtime/components/Carousel.d.vue.ts +127 -0
- package/dist/runtime/components/Carousel.vue.d.ts +10 -10
- package/dist/runtime/components/ChangelogVersion.d.vue.ts +59 -0
- package/dist/runtime/components/ChangelogVersions.d.vue.ts +78 -0
- package/dist/runtime/components/ChangelogVersions.vue +2 -2
- package/dist/runtime/components/ChatMessage.d.vue.ts +67 -0
- package/dist/runtime/components/ChatMessages.d.vue.ts +83 -0
- package/dist/runtime/components/ChatMessages.vue +6 -6
- package/dist/runtime/components/ChatPalette.d.vue.ts +24 -0
- package/dist/runtime/components/ChatPrompt.d.vue.ts +61 -0
- package/dist/runtime/components/ChatPrompt.vue +2 -2
- package/dist/runtime/components/ChatPromptSubmit.d.vue.ts +100 -0
- package/dist/runtime/components/Checkbox.d.vue.ts +74 -0
- package/dist/runtime/components/CheckboxGroup.d.vue.ts +89 -0
- package/dist/runtime/components/CheckboxGroup.vue +8 -8
- package/dist/runtime/components/CheckboxGroup.vue.d.ts +20 -16
- package/dist/runtime/components/Chip.d.vue.ts +57 -0
- package/dist/runtime/components/Collapsible.d.vue.ts +35 -0
- package/dist/runtime/components/ColorPicker.d.vue.ts +48 -0
- package/dist/runtime/components/CommandPalette.d.vue.ts +193 -0
- package/dist/runtime/components/CommandPalette.vue +5 -4
- package/dist/runtime/components/CommandPalette.vue.d.ts +2 -1
- package/dist/runtime/components/Container.d.vue.ts +18 -0
- package/dist/runtime/components/ContextMenu.d.vue.ts +110 -0
- package/dist/runtime/components/ContextMenu.vue +2 -2
- package/dist/runtime/components/ContextMenu.vue.d.ts +2 -2
- package/dist/runtime/components/ContextMenuContent.d.vue.ts +50 -0
- package/dist/runtime/components/ContextMenuContent.vue +2 -2
- package/dist/runtime/components/ContextMenuContent.vue.d.ts +2 -2
- package/dist/runtime/components/DashboardGroup.d.vue.ts +24 -0
- package/dist/runtime/components/DashboardGroup.vue.d.ts +1 -1
- package/dist/runtime/components/DashboardNavbar.d.vue.ts +52 -0
- package/dist/runtime/components/DashboardPanel.d.vue.ts +30 -0
- package/dist/runtime/components/DashboardResizeHandle.d.vue.ts +18 -0
- package/dist/runtime/components/DashboardSearch.d.vue.ts +91 -0
- package/dist/runtime/components/DashboardSearch.vue +2 -2
- package/dist/runtime/components/DashboardSearchButton.d.vue.ts +59 -0
- package/dist/runtime/components/DashboardSearchButton.vue +2 -2
- package/dist/runtime/components/DashboardSidebar.d.vue.ts +75 -0
- package/dist/runtime/components/DashboardSidebarCollapse.d.vue.ts +19 -0
- package/dist/runtime/components/DashboardSidebarToggle.d.vue.ts +19 -0
- package/dist/runtime/components/DashboardToolbar.d.vue.ts +25 -0
- package/dist/runtime/components/Drawer.d.vue.ts +84 -0
- package/dist/runtime/components/DropdownMenu.d.vue.ts +120 -0
- package/dist/runtime/components/DropdownMenu.vue +2 -2
- package/dist/runtime/components/DropdownMenu.vue.d.ts +2 -2
- package/dist/runtime/components/DropdownMenuContent.d.vue.ts +56 -0
- package/dist/runtime/components/DropdownMenuContent.vue +2 -2
- package/dist/runtime/components/DropdownMenuContent.vue.d.ts +2 -2
- package/dist/runtime/components/Error.d.vue.ts +47 -0
- package/dist/runtime/components/FieldGroup.d.vue.ts +34 -0
- package/dist/runtime/components/FileUpload.d.vue.ts +166 -0
- package/dist/runtime/components/FileUpload.vue +1 -0
- package/dist/runtime/components/Footer.d.vue.ts +29 -0
- package/dist/runtime/components/FooterColumns.d.vue.ts +57 -0
- package/dist/runtime/components/Form.d.vue.ts +114 -0
- package/dist/runtime/components/Form.vue +144 -60
- package/dist/runtime/components/Form.vue.d.ts +54 -11
- package/dist/runtime/components/FormField.d.vue.ts +61 -0
- package/dist/runtime/components/FormField.vue +9 -3
- package/dist/runtime/components/Header.d.vue.ts +68 -0
- package/dist/runtime/components/Icon.d.vue.ts +8 -0
- package/dist/runtime/components/Input.d.vue.ts +74 -0
- package/dist/runtime/components/Input.vue.d.ts +4 -3
- package/dist/runtime/components/InputMenu.d.vue.ts +330 -0
- package/dist/runtime/components/InputMenu.vue +2 -2
- package/dist/runtime/components/InputMenu.vue.d.ts +4 -4
- package/dist/runtime/components/InputNumber.d.vue.ts +188 -0
- package/dist/runtime/components/InputNumber.vue +2 -2
- package/dist/runtime/components/InputNumber.vue.d.ts +0 -2
- package/dist/runtime/components/InputTags.d.vue.ts +186 -0
- package/dist/runtime/components/InputTags.vue +2 -2
- package/dist/runtime/components/Kbd.d.vue.ts +38 -0
- package/dist/runtime/components/Link.d.vue.ts +91 -0
- package/dist/runtime/components/LinkBase.d.vue.ts +25 -0
- package/dist/runtime/components/Main.d.vue.ts +20 -0
- package/dist/runtime/components/Marquee.d.vue.ts +32 -0
- package/dist/runtime/components/Marquee.vue +1 -1
- package/dist/runtime/components/Modal.d.vue.ts +107 -0
- package/dist/runtime/components/NavigationMenu.d.vue.ts +171 -0
- package/dist/runtime/components/NavigationMenu.vue.d.ts +2 -2
- package/dist/runtime/components/OverlayProvider.d.vue.ts +2 -0
- package/dist/runtime/components/Page.d.vue.ts +25 -0
- package/dist/runtime/components/PageAnchors.d.vue.ts +47 -0
- package/dist/runtime/components/PageAside.d.vue.ts +27 -0
- package/dist/runtime/components/PageBody.d.vue.ts +18 -0
- package/dist/runtime/components/PageCTA.d.vue.ts +56 -0
- package/dist/runtime/components/PageCard.d.vue.ts +72 -0
- package/dist/runtime/components/PageColumns.d.vue.ts +18 -0
- package/dist/runtime/components/PageFeature.d.vue.ts +44 -0
- package/dist/runtime/components/PageGrid.d.vue.ts +18 -0
- package/dist/runtime/components/PageHeader.d.vue.ts +36 -0
- package/dist/runtime/components/PageHero.d.vue.ts +53 -0
- package/dist/runtime/components/PageLinks.d.vue.ts +49 -0
- package/dist/runtime/components/PageList.d.vue.ts +21 -0
- package/dist/runtime/components/PageLogos.d.vue.ts +33 -0
- package/dist/runtime/components/PageSection.d.vue.ts +68 -0
- package/dist/runtime/components/Pagination.d.vue.ts +118 -0
- package/dist/runtime/components/PinInput.d.vue.ts +60 -0
- package/dist/runtime/components/Popover.d.vue.ts +71 -0
- package/dist/runtime/components/PricingPlan.d.vue.ts +112 -0
- package/dist/runtime/components/PricingPlans.d.vue.ts +44 -0
- package/dist/runtime/components/PricingTable.d.vue.ts +105 -0
- package/dist/runtime/components/Progress.d.vue.ts +66 -0
- package/dist/runtime/components/Progress.vue +2 -3
- package/dist/runtime/components/RadioGroup.d.vue.ts +99 -0
- package/dist/runtime/components/RadioGroup.vue +13 -11
- package/dist/runtime/components/RadioGroup.vue.d.ts +17 -13
- package/dist/runtime/components/Select.d.vue.ts +254 -0
- package/dist/runtime/components/Select.vue +3 -3
- package/dist/runtime/components/Select.vue.d.ts +5 -5
- package/dist/runtime/components/SelectMenu.d.vue.ts +303 -0
- package/dist/runtime/components/SelectMenu.vue.d.ts +4 -4
- package/dist/runtime/components/Separator.d.vue.ts +54 -0
- package/dist/runtime/components/Skeleton.d.vue.ts +17 -0
- package/dist/runtime/components/Slideover.d.vue.ts +108 -0
- package/dist/runtime/components/Slider.d.vue.ts +57 -0
- package/dist/runtime/components/Stepper.d.vue.ts +87 -0
- package/dist/runtime/components/Switch.d.vue.ts +71 -0
- package/dist/runtime/components/Table.d.vue.ts +201 -0
- package/dist/runtime/components/Table.vue.d.ts +26 -26
- package/dist/runtime/components/Tabs.d.vue.ts +99 -0
- package/dist/runtime/components/Tabs.vue +12 -5
- package/dist/runtime/components/Tabs.vue.d.ts +2 -2
- package/dist/runtime/components/Textarea.d.vue.ts +74 -0
- package/dist/runtime/components/Timeline.d.vue.ts +71 -0
- package/dist/runtime/components/Toast.d.vue.ts +165 -0
- package/dist/runtime/components/Toaster.d.vue.ts +44 -0
- package/dist/runtime/components/Tooltip.d.vue.ts +57 -0
- package/dist/runtime/components/Tree.d.vue.ts +112 -0
- package/dist/runtime/components/Tree.vue +88 -47
- package/dist/runtime/components/Tree.vue.d.ts +20 -24
- package/dist/runtime/components/User.d.vue.ts +47 -0
- package/dist/runtime/components/color-mode/ColorModeAvatar.d.vue.ts +7 -0
- package/dist/runtime/components/color-mode/ColorModeButton.d.vue.ts +23 -0
- package/dist/runtime/components/color-mode/ColorModeImage.d.vue.ts +6 -0
- package/dist/runtime/components/color-mode/ColorModeSelect.d.vue.ts +5 -0
- package/dist/runtime/components/color-mode/ColorModeSwitch.d.vue.ts +5 -0
- package/dist/runtime/components/content/ContentNavigation.d.vue.ts +102 -0
- package/dist/runtime/components/content/ContentNavigation.vue +5 -4
- package/dist/runtime/components/content/ContentNavigation.vue.d.ts +2 -2
- package/dist/runtime/components/content/ContentSearch.d.vue.ts +114 -0
- package/dist/runtime/components/content/ContentSearch.vue +2 -2
- package/dist/runtime/components/content/ContentSearchButton.d.vue.ts +59 -0
- package/dist/runtime/components/content/ContentSearchButton.vue +2 -2
- package/dist/runtime/components/content/ContentSurround.d.vue.ts +59 -0
- package/dist/runtime/components/content/ContentToc.d.vue.ts +88 -0
- package/dist/runtime/components/locale/LocaleSelect.d.vue.ts +15 -0
- package/dist/runtime/components/prose/A.d.vue.ts +15 -0
- package/dist/runtime/components/prose/Accordion.d.vue.ts +16 -0
- package/dist/runtime/components/prose/AccordionItem.d.vue.ts +15 -0
- package/dist/runtime/components/prose/Badge.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Blockquote.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Callout.d.vue.ts +26 -0
- package/dist/runtime/components/prose/Card.d.vue.ts +29 -0
- package/dist/runtime/components/prose/CardGroup.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Code.d.vue.ts +22 -0
- package/dist/runtime/components/prose/CodeCollapse.d.vue.ts +47 -0
- package/dist/runtime/components/prose/CodeGroup.d.vue.ts +37 -0
- package/dist/runtime/components/prose/CodeIcon.d.vue.ts +7 -0
- package/dist/runtime/components/prose/CodePreview.d.vue.ts +19 -0
- package/dist/runtime/components/prose/CodeTree.d.vue.ts +28 -0
- package/dist/runtime/components/prose/CodeTree.vue +38 -31
- package/dist/runtime/components/prose/Collapsible.d.vue.ts +39 -0
- package/dist/runtime/components/prose/Em.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Field.d.vue.ts +39 -0
- package/dist/runtime/components/prose/FieldGroup.d.vue.ts +18 -0
- package/dist/runtime/components/prose/H1.d.vue.ts +19 -0
- package/dist/runtime/components/prose/H2.d.vue.ts +19 -0
- package/dist/runtime/components/prose/H3.d.vue.ts +19 -0
- package/dist/runtime/components/prose/H4.d.vue.ts +19 -0
- package/dist/runtime/components/prose/Hr.d.vue.ts +5 -0
- package/dist/runtime/components/prose/Icon.d.vue.ts +6 -0
- package/dist/runtime/components/prose/Img.d.vue.ts +21 -0
- package/dist/runtime/components/prose/Kbd.d.vue.ts +6 -0
- package/dist/runtime/components/prose/Li.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Ol.d.vue.ts +13 -0
- package/dist/runtime/components/prose/P.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Pre.d.vue.ts +26 -0
- package/dist/runtime/components/prose/Script.d.vue.ts +5 -0
- package/dist/runtime/components/prose/Steps.d.vue.ts +22 -0
- package/dist/runtime/components/prose/Strong.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Table.d.vue.ts +18 -0
- package/dist/runtime/components/prose/Tabs.d.vue.ts +36 -0
- package/dist/runtime/components/prose/TabsItem.d.vue.ts +15 -0
- package/dist/runtime/components/prose/Tbody.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Td.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Th.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Thead.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Tr.d.vue.ts +13 -0
- package/dist/runtime/components/prose/Ul.d.vue.ts +13 -0
- package/dist/runtime/components/prose/callout/Caution.d.vue.ts +14 -0
- package/dist/runtime/components/prose/callout/Note.d.vue.ts +14 -0
- package/dist/runtime/components/prose/callout/Tip.d.vue.ts +14 -0
- package/dist/runtime/components/prose/callout/Warning.d.vue.ts +14 -0
- package/dist/runtime/composables/useFormField.d.ts +1 -0
- package/dist/runtime/composables/useFormField.js +1 -4
- package/dist/runtime/inertia/components/Link.d.vue.ts +63 -0
- package/dist/runtime/inertia/components/LinkBase.d.vue.ts +25 -0
- package/dist/runtime/locale/de_ch.d.ts +3 -0
- package/dist/runtime/locale/de_ch.js +129 -0
- package/dist/runtime/locale/id.js +1 -1
- package/dist/runtime/locale/index.d.ts +2 -0
- package/dist/runtime/locale/index.js +2 -0
- package/dist/runtime/locale/ka.d.ts +3 -0
- package/dist/runtime/locale/ka.js +132 -0
- package/dist/runtime/locale/pt.js +2 -2
- package/dist/runtime/types/form.d.ts +12 -13
- package/dist/runtime/types/form.js +1 -3
- package/dist/runtime/types/index.d.ts +1 -0
- package/dist/runtime/types/index.js +1 -0
- package/dist/runtime/types/tv.d.ts +9 -2
- package/dist/runtime/types/utils.d.ts +7 -3
- package/dist/runtime/utils/form.d.ts +2 -6
- package/dist/runtime/utils/form.js +28 -60
- package/dist/runtime/utils/fuse.d.ts +2 -1
- package/dist/runtime/utils/index.d.ts +3 -3
- package/dist/runtime/utils/index.js +6 -3
- package/dist/runtime/vue/components/Icon.d.vue.ts +6 -0
- package/dist/runtime/vue/components/Link.d.vue.ts +93 -0
- package/dist/runtime/vue/components/color-mode/ColorModeButton.d.vue.ts +16 -0
- package/dist/runtime/vue/components/color-mode/ColorModeSelect.d.vue.ts +5 -0
- package/dist/runtime/vue/components/color-mode/ColorModeSwitch.d.vue.ts +5 -0
- package/dist/shared/{ui.BEZXPd3d.mjs → ui.DGJZ-1aX.mjs} +18 -13
- package/dist/unplugin.mjs +1 -1
- package/dist/vite.mjs +1 -1
- package/package.json +27 -40
|
@@ -6,22 +6,23 @@ import theme from "#build/ui/form";
|
|
|
6
6
|
import { provide, inject, nextTick, ref, onUnmounted, onMounted, computed, useId, readonly, reactive } from "vue";
|
|
7
7
|
import { useEventBus } from "@vueuse/core";
|
|
8
8
|
import { useAppConfig } from "#imports";
|
|
9
|
-
import { formOptionsInjectionKey, formInputsInjectionKey, formBusInjectionKey, formLoadingInjectionKey, formErrorsInjectionKey } from "../composables/useFormField";
|
|
9
|
+
import { formOptionsInjectionKey, formInputsInjectionKey, formBusInjectionKey, formLoadingInjectionKey, formErrorsInjectionKey, formStateInjectionKey } from "../composables/useFormField";
|
|
10
10
|
import { tv } from "../utils/tv";
|
|
11
|
-
import { validateSchema } from "../utils/form";
|
|
11
|
+
import { validateSchema, getAtPath, setAtPath } from "../utils/form";
|
|
12
12
|
import { FormValidationException } from "../types/form";
|
|
13
13
|
const props = defineProps({
|
|
14
14
|
id: { type: [String, Number], required: false },
|
|
15
15
|
schema: { type: null, required: false },
|
|
16
|
-
state: { type:
|
|
16
|
+
state: { type: null, required: false },
|
|
17
17
|
validate: { type: Function, required: false },
|
|
18
18
|
validateOn: { type: Array, required: false, default() {
|
|
19
19
|
return ["input", "blur", "change"];
|
|
20
20
|
} },
|
|
21
21
|
disabled: { type: Boolean, required: false },
|
|
22
|
+
name: { type: null, required: false },
|
|
22
23
|
validateOnInputDelay: { type: Number, required: false, default: 300 },
|
|
23
24
|
transform: { type: null, required: false, default: () => true },
|
|
24
|
-
|
|
25
|
+
nested: { type: null, required: false },
|
|
25
26
|
loadingAuto: { type: Boolean, required: false, default: true },
|
|
26
27
|
class: { type: null, required: false },
|
|
27
28
|
onSubmit: { type: Function, required: false }
|
|
@@ -32,16 +33,37 @@ const appConfig = useAppConfig();
|
|
|
32
33
|
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.ui?.form || {} }));
|
|
33
34
|
const formId = props.id ?? useId();
|
|
34
35
|
const bus = useEventBus(`form-${formId}`);
|
|
35
|
-
const
|
|
36
|
+
const isNested = props.nested?.toString() === "" || props.nested === true;
|
|
37
|
+
const parentBus = isNested && inject(
|
|
36
38
|
formBusInjectionKey,
|
|
37
39
|
void 0
|
|
38
40
|
);
|
|
41
|
+
const parentState = isNested ? inject(formStateInjectionKey, void 0) : void 0;
|
|
42
|
+
const state = computed(() => {
|
|
43
|
+
if (parentState?.value) {
|
|
44
|
+
return props.name ? getAtPath(parentState.value, props.name) : parentState.value;
|
|
45
|
+
}
|
|
46
|
+
return props.state;
|
|
47
|
+
});
|
|
39
48
|
provide(formBusInjectionKey, bus);
|
|
49
|
+
provide(formStateInjectionKey, state);
|
|
40
50
|
const nestedForms = ref(/* @__PURE__ */ new Map());
|
|
51
|
+
onMounted(async () => {
|
|
52
|
+
if (parentBus) {
|
|
53
|
+
await nextTick();
|
|
54
|
+
parentBus.emit({ type: "attach", validate: _validate, formId, name: props.name, api });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
onUnmounted(() => {
|
|
58
|
+
bus.reset();
|
|
59
|
+
if (parentBus) {
|
|
60
|
+
parentBus.emit({ type: "detach", formId });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
41
63
|
onMounted(async () => {
|
|
42
64
|
bus.on(async (event) => {
|
|
43
65
|
if (event.type === "attach") {
|
|
44
|
-
nestedForms.value.set(event.formId, { validate: event.validate });
|
|
66
|
+
nestedForms.value.set(event.formId, { validate: event.validate, name: event.name, api: event.api });
|
|
45
67
|
} else if (event.type === "detach") {
|
|
46
68
|
nestedForms.value.delete(event.formId);
|
|
47
69
|
} else if (props.validateOn?.includes(event.type) && !loading.value) {
|
|
@@ -62,20 +84,6 @@ onMounted(async () => {
|
|
|
62
84
|
}
|
|
63
85
|
});
|
|
64
86
|
});
|
|
65
|
-
onUnmounted(() => {
|
|
66
|
-
bus.reset();
|
|
67
|
-
});
|
|
68
|
-
onMounted(async () => {
|
|
69
|
-
if (parentBus) {
|
|
70
|
-
await nextTick();
|
|
71
|
-
parentBus.emit({ type: "attach", validate: _validate, formId });
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
onUnmounted(() => {
|
|
75
|
-
if (parentBus) {
|
|
76
|
-
parentBus.emit({ type: "detach", formId });
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
87
|
const errors = ref([]);
|
|
80
88
|
provide(formErrorsInjectionKey, errors);
|
|
81
89
|
const inputs = ref({});
|
|
@@ -91,9 +99,9 @@ function resolveErrorIds(errs) {
|
|
|
91
99
|
}
|
|
92
100
|
const transformedState = ref(null);
|
|
93
101
|
async function getErrors() {
|
|
94
|
-
let errs = props.validate ? await props.validate(
|
|
102
|
+
let errs = props.validate ? await props.validate(state.value) ?? [] : [];
|
|
95
103
|
if (props.schema) {
|
|
96
|
-
const { errors: errors2, result } = await validateSchema(
|
|
104
|
+
const { errors: errors2, result } = await validateSchema(state.value, props.schema);
|
|
97
105
|
if (errors2) {
|
|
98
106
|
errs = errs.concat(errors2);
|
|
99
107
|
} else {
|
|
@@ -102,38 +110,40 @@ async function getErrors() {
|
|
|
102
110
|
}
|
|
103
111
|
return resolveErrorIds(errs);
|
|
104
112
|
}
|
|
105
|
-
async function _validate(opts = { silent: false, nested:
|
|
113
|
+
async function _validate(opts = { silent: false, nested: false, transform: false }) {
|
|
106
114
|
const names = opts.name && !Array.isArray(opts.name) ? [opts.name] : opts.name;
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
+
}
|
|
125
|
+
const currentErrors = await getErrors();
|
|
126
|
+
const allErrors = [...currentErrors, ...nestedErrors];
|
|
115
127
|
if (names) {
|
|
116
|
-
|
|
117
|
-
const pattern = inputs.value?.[name]?.pattern;
|
|
118
|
-
return name === error.name || pattern && error.name?.match(pattern);
|
|
119
|
-
}));
|
|
120
|
-
const pathErrors = (await getErrors()).filter((error) => names.some((name) => {
|
|
121
|
-
const pattern = inputs.value?.[name]?.pattern;
|
|
122
|
-
return name === error.name || pattern && error.name?.match(pattern);
|
|
123
|
-
}));
|
|
124
|
-
errors.value = otherErrors.concat(pathErrors);
|
|
128
|
+
errors.value = filterErrorsByNames(allErrors, names);
|
|
125
129
|
} else {
|
|
126
|
-
errors.value =
|
|
130
|
+
errors.value = allErrors;
|
|
127
131
|
}
|
|
128
|
-
|
|
129
|
-
if (errors.value.length + childErrors.length > 0) {
|
|
132
|
+
if (errors.value?.length) {
|
|
130
133
|
if (opts.silent) return false;
|
|
131
|
-
throw new FormValidationException(formId, errors.value
|
|
134
|
+
throw new FormValidationException(formId, errors.value);
|
|
132
135
|
}
|
|
133
136
|
if (opts.transform) {
|
|
134
|
-
|
|
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
|
+
}
|
|
143
|
+
});
|
|
144
|
+
return transformedState.value ?? state.value;
|
|
135
145
|
}
|
|
136
|
-
return
|
|
146
|
+
return state.value;
|
|
137
147
|
}
|
|
138
148
|
const loading = ref(false);
|
|
139
149
|
provide(formLoadingInjectionKey, readonly(loading));
|
|
@@ -150,8 +160,7 @@ async function onSubmitWrapper(payload) {
|
|
|
150
160
|
}
|
|
151
161
|
const errorEvent = {
|
|
152
162
|
...event,
|
|
153
|
-
errors: error.errors
|
|
154
|
-
children: error.children
|
|
163
|
+
errors: error.errors
|
|
155
164
|
};
|
|
156
165
|
emits("error", errorEvent);
|
|
157
166
|
} finally {
|
|
@@ -163,31 +172,105 @@ provide(formOptionsInjectionKey, computed(() => ({
|
|
|
163
172
|
disabled: disabled.value,
|
|
164
173
|
validateOnInputDelay: props.validateOnInputDelay
|
|
165
174
|
})));
|
|
166
|
-
|
|
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
|
+
}
|
|
235
|
+
const api = {
|
|
167
236
|
validate: _validate,
|
|
168
237
|
errors,
|
|
169
238
|
setErrors(errs, name) {
|
|
239
|
+
const localErrors = resolveErrorIds(errs.filter(isLocalError));
|
|
240
|
+
const nestedErrors = [];
|
|
241
|
+
for (const form of nestedForms.value.values()) {
|
|
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));
|
|
246
|
+
}
|
|
247
|
+
}
|
|
170
248
|
if (name) {
|
|
171
|
-
|
|
249
|
+
const keepErrors = filterErrorsByTarget(errors.value, name);
|
|
250
|
+
errors.value = [...keepErrors, ...localErrors, ...nestedErrors];
|
|
172
251
|
} else {
|
|
173
|
-
errors.value =
|
|
252
|
+
errors.value = [...localErrors, ...nestedErrors];
|
|
174
253
|
}
|
|
175
254
|
},
|
|
176
255
|
async submit() {
|
|
177
256
|
await onSubmitWrapper(new Event("submit"));
|
|
178
257
|
},
|
|
179
258
|
getErrors(name) {
|
|
180
|
-
if (name)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
+
);
|
|
184
263
|
},
|
|
185
264
|
clear(name) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
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 = [];
|
|
269
|
+
for (const form of nestedForms.value.values()) {
|
|
270
|
+
if (matchesTarget(name, form.name)) form.api.clear();
|
|
271
|
+
nestedErrors.push(...getFormErrors(form));
|
|
190
272
|
}
|
|
273
|
+
errors.value = [...localErrors, ...nestedErrors];
|
|
191
274
|
},
|
|
192
275
|
disabled,
|
|
193
276
|
loading,
|
|
@@ -195,7 +278,8 @@ defineExpose({
|
|
|
195
278
|
dirtyFields: readonly(dirtyFields),
|
|
196
279
|
blurredFields: readonly(blurredFields),
|
|
197
280
|
touchedFields: readonly(touchedFields)
|
|
198
|
-
}
|
|
281
|
+
};
|
|
282
|
+
defineExpose(api);
|
|
199
283
|
</script>
|
|
200
284
|
|
|
201
285
|
<template>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { FormSchema, FormError, FormInputEvents, FormErrorEvent, FormSubmitEvent,
|
|
2
|
-
export
|
|
1
|
+
import type { FormSchema, FormError, FormInputEvents, FormErrorEvent, FormSubmitEvent, FormErrorWithId, InferInput, FormData } from '../types/form';
|
|
2
|
+
export type FormProps<S extends FormSchema, T extends boolean = true, N extends boolean = false> = {
|
|
3
3
|
id?: string | number;
|
|
4
4
|
/** Schema to validate the form state. Supports Standard Schema objects, Yup, Joi, and Superstructs. */
|
|
5
5
|
schema?: S;
|
|
6
6
|
/** An object representing the current state of the form. */
|
|
7
|
-
state
|
|
7
|
+
state?: N extends false ? Partial<InferInput<S>> : never;
|
|
8
8
|
/**
|
|
9
9
|
* Custom validation function to validate the form state.
|
|
10
10
|
* @param state - The current state of the form.
|
|
@@ -19,21 +19,26 @@ export interface FormProps<S extends FormSchema, T extends boolean = true> {
|
|
|
19
19
|
validateOn?: FormInputEvents[];
|
|
20
20
|
/** Disable all inputs inside the form. */
|
|
21
21
|
disabled?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Path of the form's state within it's parent form.
|
|
24
|
+
* Used for nesting forms. Only available if `nested` is true.
|
|
25
|
+
*/
|
|
26
|
+
name?: N extends true ? string : never;
|
|
22
27
|
/**
|
|
23
28
|
* Delay in milliseconds before validating the form on input events.
|
|
24
29
|
* @defaultValue `300`
|
|
25
30
|
*/
|
|
26
31
|
validateOnInputDelay?: number;
|
|
27
32
|
/**
|
|
28
|
-
* If true, schema transformations
|
|
33
|
+
* If true, applies schema transformations on submit.
|
|
29
34
|
* @defaultValue `true`
|
|
30
35
|
*/
|
|
31
36
|
transform?: T;
|
|
32
37
|
/**
|
|
33
|
-
* If true, this form will attach to its parent Form
|
|
34
|
-
* @defaultValue `
|
|
38
|
+
* If true, this form will attach to its parent Form and validate at the same time.
|
|
39
|
+
* @defaultValue `false`
|
|
35
40
|
*/
|
|
36
|
-
|
|
41
|
+
nested?: N;
|
|
37
42
|
/**
|
|
38
43
|
* When `true`, all form elements will be disabled on `@submit` event.
|
|
39
44
|
* This will cause any focused input elements to lose their focus state.
|
|
@@ -42,7 +47,7 @@ export interface FormProps<S extends FormSchema, T extends boolean = true> {
|
|
|
42
47
|
loadingAuto?: boolean;
|
|
43
48
|
class?: any;
|
|
44
49
|
onSubmit?: ((event: FormSubmitEvent<FormData<S, T>>) => void | Promise<void>) | (() => void | Promise<void>);
|
|
45
|
-
}
|
|
50
|
+
};
|
|
46
51
|
export interface FormEmits<S extends FormSchema, T extends boolean = true> {
|
|
47
52
|
submit: [event: FormSubmitEvent<FormData<S, T>>];
|
|
48
53
|
error: [event: FormErrorEvent];
|
|
@@ -53,12 +58,50 @@ export interface FormSlots {
|
|
|
53
58
|
loading: boolean;
|
|
54
59
|
}): any;
|
|
55
60
|
}
|
|
56
|
-
declare const _default: <S extends FormSchema, T extends boolean = true>(__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<{
|
|
61
|
+
declare const _default: <S extends FormSchema, T extends boolean = true, N 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<{
|
|
57
62
|
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
58
63
|
readonly onError?: ((event: FormErrorEvent) => any) | undefined;
|
|
59
64
|
readonly onSubmit?: ((event: FormSubmitEvent<FormData<S, T>>) => any) | undefined;
|
|
60
|
-
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onSubmit" | "onError"> & FormProps<S, T> & {}> & import("vue").PublicProps;
|
|
61
|
-
expose(exposed: import("vue").ShallowUnwrapRef<
|
|
65
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onSubmit" | "onError"> & FormProps<S, T, N> & {}> & import("vue").PublicProps;
|
|
66
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{
|
|
67
|
+
validate: {
|
|
68
|
+
<T_1 extends boolean>(opts: {
|
|
69
|
+
name?: keyof InferInput<S> | (keyof InferInput<S>)[] | undefined;
|
|
70
|
+
silent?: false | undefined;
|
|
71
|
+
nested?: boolean;
|
|
72
|
+
transform?: T_1 | undefined;
|
|
73
|
+
}): Promise<FormData<S, T_1>>;
|
|
74
|
+
<T_1 extends boolean>(opts: {
|
|
75
|
+
name?: keyof InferInput<S> | (keyof InferInput<S>)[] | undefined;
|
|
76
|
+
silent?: true | undefined;
|
|
77
|
+
nested?: boolean;
|
|
78
|
+
transform?: T_1 | undefined;
|
|
79
|
+
}): Promise<FormData<S, T_1> | false>;
|
|
80
|
+
};
|
|
81
|
+
errors: import("vue").Ref<{
|
|
82
|
+
id?: string | undefined;
|
|
83
|
+
name?: string | undefined;
|
|
84
|
+
message: string;
|
|
85
|
+
}[], FormErrorWithId[] | {
|
|
86
|
+
id?: string | undefined;
|
|
87
|
+
name?: string | undefined;
|
|
88
|
+
message: string;
|
|
89
|
+
}[]>;
|
|
90
|
+
setErrors(errs: FormError[], name?: keyof InferInput<S> | string | RegExp): void;
|
|
91
|
+
submit(): Promise<void>;
|
|
92
|
+
getErrors(name?: keyof InferInput<S> | string | RegExp): {
|
|
93
|
+
id?: string | undefined;
|
|
94
|
+
name?: string | undefined;
|
|
95
|
+
message: string;
|
|
96
|
+
}[];
|
|
97
|
+
clear(name?: keyof InferInput<S> | string | RegExp): void;
|
|
98
|
+
disabled: import("vue").ComputedRef<boolean>;
|
|
99
|
+
loading: import("vue").Ref<boolean, boolean>;
|
|
100
|
+
dirty: import("vue").ComputedRef<boolean>;
|
|
101
|
+
dirtyFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
|
|
102
|
+
blurredFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
|
|
103
|
+
touchedFields: ReadonlySet<import("vue").DeepReadonly<import("@vue/reactivity").UnwrapRefSimple<keyof InferInput<S>>>>;
|
|
104
|
+
}>): void;
|
|
62
105
|
attrs: any;
|
|
63
106
|
slots: FormSlots;
|
|
64
107
|
emit: ((evt: "error", event: FormErrorEvent) => void) & ((evt: "submit", event: FormSubmitEvent<FormData<S, T>>) => void);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/ui/form-field';
|
|
3
|
+
import type { ComponentConfig } from '../types/tv';
|
|
4
|
+
type FormField = ComponentConfig<typeof theme, AppConfig, 'formField'>;
|
|
5
|
+
export interface FormFieldProps {
|
|
6
|
+
/**
|
|
7
|
+
* The element or component this component should render as.
|
|
8
|
+
* @defaultValue 'div'
|
|
9
|
+
*/
|
|
10
|
+
as?: any;
|
|
11
|
+
/** The name of the FormField. Also used to match form errors. */
|
|
12
|
+
name?: string;
|
|
13
|
+
/** A regular expression to match form error names. */
|
|
14
|
+
errorPattern?: RegExp;
|
|
15
|
+
label?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
help?: string;
|
|
18
|
+
error?: boolean | string;
|
|
19
|
+
hint?: string;
|
|
20
|
+
/**
|
|
21
|
+
* @defaultValue 'md'
|
|
22
|
+
*/
|
|
23
|
+
size?: FormField['variants']['size'];
|
|
24
|
+
required?: boolean;
|
|
25
|
+
/** If true, validation on input will be active immediately instead of waiting for a blur event. */
|
|
26
|
+
eagerValidation?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Delay in milliseconds before validating the form on input events.
|
|
29
|
+
* @defaultValue `300`
|
|
30
|
+
*/
|
|
31
|
+
validateOnInputDelay?: number;
|
|
32
|
+
class?: any;
|
|
33
|
+
ui?: FormField['slots'];
|
|
34
|
+
}
|
|
35
|
+
export interface FormFieldSlots {
|
|
36
|
+
label(props: {
|
|
37
|
+
label?: string;
|
|
38
|
+
}): any;
|
|
39
|
+
hint(props: {
|
|
40
|
+
hint?: string;
|
|
41
|
+
}): any;
|
|
42
|
+
description(props: {
|
|
43
|
+
description?: string;
|
|
44
|
+
}): any;
|
|
45
|
+
help(props: {
|
|
46
|
+
help?: string;
|
|
47
|
+
}): any;
|
|
48
|
+
error(props: {
|
|
49
|
+
error?: boolean | string;
|
|
50
|
+
}): any;
|
|
51
|
+
default(props: {
|
|
52
|
+
error?: boolean | string;
|
|
53
|
+
}): any;
|
|
54
|
+
}
|
|
55
|
+
declare const _default: __VLS_WithSlots<import("vue").DefineComponent<FormFieldProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<FormFieldProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, FormFieldSlots>;
|
|
56
|
+
export default _default;
|
|
57
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
58
|
+
new (): {
|
|
59
|
+
$slots: S;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
@@ -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,
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
2
|
+
import theme from '#build/ui/header';
|
|
3
|
+
import type { ButtonProps, DrawerProps, ModalProps, SlideoverProps } from '../types';
|
|
4
|
+
import type { ComponentConfig } from '../types/tv';
|
|
5
|
+
type Header = ComponentConfig<typeof theme, AppConfig, 'header'>;
|
|
6
|
+
type HeaderMode = 'modal' | 'slideover' | 'drawer';
|
|
7
|
+
type HeaderMenu<T> = T extends 'modal' ? ModalProps : T extends 'slideover' ? SlideoverProps : T extends 'drawer' ? DrawerProps : never;
|
|
8
|
+
export interface HeaderProps<T extends HeaderMode = HeaderMode> {
|
|
9
|
+
/**
|
|
10
|
+
* The element or component this component should render as.
|
|
11
|
+
* @defaultValue 'header'
|
|
12
|
+
*/
|
|
13
|
+
as?: any;
|
|
14
|
+
title?: string;
|
|
15
|
+
to?: string;
|
|
16
|
+
/**
|
|
17
|
+
* The mode of the header menu.
|
|
18
|
+
* @defaultValue 'modal'
|
|
19
|
+
*/
|
|
20
|
+
mode?: T;
|
|
21
|
+
/**
|
|
22
|
+
* The props for the header menu component.
|
|
23
|
+
*/
|
|
24
|
+
menu?: HeaderMenu<T>;
|
|
25
|
+
/**
|
|
26
|
+
* Customize the toggle button to open the header menu displayed when the `content` slot is used.
|
|
27
|
+
* `{ color: 'neutral', variant: 'ghost' }`{lang="ts-type"}
|
|
28
|
+
*/
|
|
29
|
+
toggle?: boolean | Partial<ButtonProps>;
|
|
30
|
+
/**
|
|
31
|
+
* The side to render the toggle button on.
|
|
32
|
+
* @defaultValue 'right'
|
|
33
|
+
*/
|
|
34
|
+
toggleSide?: 'left' | 'right';
|
|
35
|
+
class?: any;
|
|
36
|
+
ui?: Header['slots'];
|
|
37
|
+
}
|
|
38
|
+
export interface HeaderSlots {
|
|
39
|
+
title(props?: {}): any;
|
|
40
|
+
left(props?: {}): any;
|
|
41
|
+
default(props?: {}): any;
|
|
42
|
+
right(props?: {}): any;
|
|
43
|
+
toggle(props: {
|
|
44
|
+
open: boolean;
|
|
45
|
+
toggle: () => void;
|
|
46
|
+
}): any;
|
|
47
|
+
top(props?: {}): any;
|
|
48
|
+
bottom(props?: {}): any;
|
|
49
|
+
body(props?: {}): any;
|
|
50
|
+
content(props?: {}): any;
|
|
51
|
+
}
|
|
52
|
+
declare const _default: <T extends HeaderMode>(__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<{
|
|
53
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
54
|
+
readonly "onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
55
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onUpdate:open"> & (HeaderProps<T> & {
|
|
56
|
+
open?: boolean;
|
|
57
|
+
}) & {}> & import("vue").PublicProps;
|
|
58
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
59
|
+
attrs: any;
|
|
60
|
+
slots: HeaderSlots;
|
|
61
|
+
emit: (evt: "update:open", value: boolean) => void;
|
|
62
|
+
}>) => import("vue").VNode & {
|
|
63
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
64
|
+
};
|
|
65
|
+
export default _default;
|
|
66
|
+
type __VLS_PrettifyLocal<T> = {
|
|
67
|
+
[K in keyof T as K]: T[K];
|
|
68
|
+
} & {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface IconProps {
|
|
2
|
+
name: string | object;
|
|
3
|
+
mode?: 'svg' | 'css';
|
|
4
|
+
size?: string | number;
|
|
5
|
+
customize?: (content: string, name?: string, prefix?: string, provider?: string) => string;
|
|
6
|
+
}
|
|
7
|
+
declare const _default: import("vue").DefineComponent<IconProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<IconProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { InputHTMLAttributes } from 'vue';
|
|
2
|
+
import type { AppConfig } from '@nuxt/schema';
|
|
3
|
+
import theme from '#build/ui/input';
|
|
4
|
+
import type { UseComponentIconsProps } from '../composables/useComponentIcons';
|
|
5
|
+
import type { ModelModifiers } from '../types/input';
|
|
6
|
+
import type { AcceptableValue } from '../types/utils';
|
|
7
|
+
import type { ComponentConfig } from '../types/tv';
|
|
8
|
+
type Input = ComponentConfig<typeof theme, AppConfig, 'input'>;
|
|
9
|
+
export type InputValue = AcceptableValue;
|
|
10
|
+
export interface InputProps<T extends InputValue = InputValue> extends UseComponentIconsProps {
|
|
11
|
+
/**
|
|
12
|
+
* The element or component this component should render as.
|
|
13
|
+
* @defaultValue 'div'
|
|
14
|
+
*/
|
|
15
|
+
as?: any;
|
|
16
|
+
id?: string;
|
|
17
|
+
name?: string;
|
|
18
|
+
type?: InputHTMLAttributes['type'];
|
|
19
|
+
/** The placeholder text when the input is empty. */
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
/**
|
|
22
|
+
* @defaultValue 'primary'
|
|
23
|
+
*/
|
|
24
|
+
color?: Input['variants']['color'];
|
|
25
|
+
/**
|
|
26
|
+
* @defaultValue 'outline'
|
|
27
|
+
*/
|
|
28
|
+
variant?: Input['variants']['variant'];
|
|
29
|
+
/**
|
|
30
|
+
* @defaultValue 'md'
|
|
31
|
+
*/
|
|
32
|
+
size?: Input['variants']['size'];
|
|
33
|
+
required?: boolean;
|
|
34
|
+
autocomplete?: InputHTMLAttributes['autocomplete'];
|
|
35
|
+
autofocus?: boolean;
|
|
36
|
+
autofocusDelay?: number;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
/** Highlight the ring color like a focus state. */
|
|
39
|
+
highlight?: boolean;
|
|
40
|
+
modelValue?: T;
|
|
41
|
+
defaultValue?: T;
|
|
42
|
+
modelModifiers?: ModelModifiers;
|
|
43
|
+
class?: any;
|
|
44
|
+
ui?: Input['slots'];
|
|
45
|
+
}
|
|
46
|
+
export interface InputEmits<T extends InputValue = InputValue> {
|
|
47
|
+
'update:modelValue': [value: T];
|
|
48
|
+
'blur': [event: FocusEvent];
|
|
49
|
+
'change': [event: Event];
|
|
50
|
+
}
|
|
51
|
+
export interface InputSlots {
|
|
52
|
+
leading(props?: {}): any;
|
|
53
|
+
default(props?: {}): any;
|
|
54
|
+
trailing(props?: {}): any;
|
|
55
|
+
}
|
|
56
|
+
declare const _default: <T extends InputValue>(__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<{
|
|
57
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{
|
|
58
|
+
readonly onBlur?: ((event: FocusEvent) => any) | undefined;
|
|
59
|
+
readonly onChange?: ((event: Event) => any) | undefined;
|
|
60
|
+
readonly "onUpdate:modelValue"?: ((value: T) => any) | undefined;
|
|
61
|
+
} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, "onBlur" | "onChange" | "onUpdate:modelValue"> & InputProps<T> & {}> & import("vue").PublicProps;
|
|
62
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{
|
|
63
|
+
inputRef: import("vue").Ref<HTMLInputElement | null, HTMLInputElement | null>;
|
|
64
|
+
}>): void;
|
|
65
|
+
attrs: any;
|
|
66
|
+
slots: InputSlots;
|
|
67
|
+
emit: ((evt: "blur", event: FocusEvent) => void) & ((evt: "change", event: Event) => void) & ((evt: "update:modelValue", value: T) => void);
|
|
68
|
+
}>) => import("vue").VNode & {
|
|
69
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
70
|
+
};
|
|
71
|
+
export default _default;
|
|
72
|
+
type __VLS_PrettifyLocal<T> = {
|
|
73
|
+
[K in keyof T as K]: T[K];
|
|
74
|
+
} & {};
|