@sfxcode/nuxt-ui-formkit 1.2.3 → 1.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/module.json +1 -1
- package/dist/runtime/components/FUAutoForm.d.vue.ts +7 -8
- package/dist/runtime/components/FUAutoForm.vue +1 -1
- package/dist/runtime/components/FUAutoForm.vue.d.ts +7 -8
- package/dist/runtime/components/FUAutoFormOverlay.d.vue.ts +82 -0
- package/dist/runtime/components/FUAutoFormOverlay.vue +106 -0
- package/dist/runtime/components/FUAutoFormOverlay.vue.d.ts +82 -0
- package/dist/runtime/components/FUDataEdit.d.vue.ts +7 -7
- package/dist/runtime/components/FUDataEdit.vue +3 -2
- package/dist/runtime/components/FUDataEdit.vue.d.ts +7 -7
- package/dist/runtime/components/FUDataEditOverlay.d.vue.ts +64 -0
- package/dist/runtime/components/FUDataEditOverlay.vue +94 -0
- package/dist/runtime/components/FUDataEditOverlay.vue.d.ts +64 -0
- package/dist/runtime/components/FUDataView.d.vue.ts +7 -7
- package/dist/runtime/components/FUDataView.vue +1 -1
- package/dist/runtime/components/FUDataView.vue.d.ts +7 -7
- package/dist/runtime/components/inputs/FUCalendar.vue +5 -2
- package/dist/runtime/components/inputs/FUCheckbox.vue +3 -2
- package/dist/runtime/components/inputs/FUCheckboxGroup.vue +5 -1
- package/dist/runtime/components/inputs/FUColorPicker.vue +2 -2
- package/dist/runtime/components/inputs/FUEditor.vue +59 -55
- package/dist/runtime/components/inputs/FUFileUpload.vue +3 -2
- package/dist/runtime/components/inputs/FUInput.vue +3 -2
- package/dist/runtime/components/inputs/FUInputDate.vue +6 -2
- package/dist/runtime/components/inputs/FUInputMenu.vue +3 -2
- package/dist/runtime/components/inputs/FUInputNumber.vue +3 -2
- package/dist/runtime/components/inputs/FUInputTags.vue +3 -2
- package/dist/runtime/components/inputs/FUInputTime.vue +6 -2
- package/dist/runtime/components/inputs/FUListbox.vue +11 -6
- package/dist/runtime/components/inputs/FUPinInput.vue +9 -2
- package/dist/runtime/components/inputs/FURadioGroup.vue +5 -2
- package/dist/runtime/components/inputs/FUSelect.vue +2 -2
- package/dist/runtime/components/inputs/FUSelectMenu.vue +2 -2
- package/dist/runtime/components/inputs/FUSlider.vue +2 -2
- package/dist/runtime/components/inputs/FUSwitch.vue +3 -2
- package/dist/runtime/components/inputs/FUTextarea.vue +3 -2
- package/dist/runtime/components/output/FUOutputBoolean.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputBoolean.vue.d.ts +2 -0
- package/dist/runtime/components/output/FUOutputDate.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputDate.vue.d.ts +2 -0
- package/dist/runtime/components/output/FUOutputLink.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputLink.vue.d.ts +2 -0
- package/dist/runtime/components/output/FUOutputList.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputList.vue +2 -1
- package/dist/runtime/components/output/FUOutputList.vue.d.ts +2 -0
- package/dist/runtime/components/output/FUOutputNumber.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputNumber.vue.d.ts +2 -0
- package/dist/runtime/components/output/FUOutputText.d.vue.ts +2 -0
- package/dist/runtime/components/output/FUOutputText.vue.d.ts +2 -0
- package/dist/runtime/composables/useFormKitOverlay.d.ts +20 -0
- package/dist/runtime/composables/useFormKitOverlay.js +42 -0
- package/dist/runtime/composables/useFormKitRepeater.js +5 -5
- package/dist/runtime/composables/useFormKitSchema.d.ts +7 -24
- package/dist/runtime/formkit/definitions/output.js +6 -6
- package/dist/runtime/formkit/definitions/output.mjs +6 -6
- package/dist/runtime/formkit/definitions/repeater.js +4 -0
- package/dist/runtime/formkit/definitions/repeater.mjs +4 -0
- package/dist/runtime/formkit/index.d.ts +6 -1
- package/dist/runtime/utils/useFormKitContainerBlur.d.ts +37 -0
- package/dist/runtime/utils/useFormKitContainerBlur.js +9 -0
- package/dist/runtime/utils/useFormKitInput.d.ts +1 -0
- package/dist/runtime/utils/useFormKitInput.js +10 -2
- package/dist/runtime/utils/useFormKitOutput.d.ts +25 -0
- package/dist/runtime/utils/useFormKitOutput.js +21 -5
- package/dist/runtime/utils/useOverlayCloseResolution.d.ts +20 -0
- package/dist/runtime/utils/useOverlayCloseResolution.js +17 -0
- package/package.json +6 -6
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FormKitMultiStepSlots, FormKitStepSlots } from '@formkit/addons';
|
|
2
2
|
import type { FormKitBaseSlots, FormKitInputs } from '@formkit/inputs';
|
|
3
|
-
import type { CalendarSlots, CheckboxSlots, CheckboxGroupSlots, EditorSlots, FileUploadSlots, RadioGroupSlots, InputSlots, TextareaSlots, SelectSlots, SelectMenuSlots, InputDateSlots, InputMenuSlots, InputNumberSlots, InputTagsSlots, InputTimeSlots, ListboxSlots, SwitchSlots } from '@nuxt/ui';
|
|
3
|
+
import type { CalendarSlots, CheckboxSlots, CheckboxGroupSlots, EditorSlots, FileUploadSlots, RadioGroupSlots, InputSlots, TextareaSlots, SelectSlots, SelectMenuSlots, InputDateSlots, InputMenuSlots, InputNumberSlots, InputTagsSlots, InputTimeSlots, ListboxSlots, PinInputSlots, SwitchSlots } from '@nuxt/ui';
|
|
4
4
|
export * from './createNuxtUiFormkitConfig.js';
|
|
5
5
|
export * from './definitions/index.js';
|
|
6
6
|
export * from './plugins/index.js';
|
|
@@ -58,6 +58,9 @@ declare module '@formkit/inputs' {
|
|
|
58
58
|
nuxtUIRadioGroup: {
|
|
59
59
|
type: 'nuxtUIRadioGroup';
|
|
60
60
|
};
|
|
61
|
+
nuxtUIRepeater: {
|
|
62
|
+
type: 'nuxtUIRepeater';
|
|
63
|
+
};
|
|
61
64
|
nuxtUISelect: {
|
|
62
65
|
type: 'nuxtUISelect';
|
|
63
66
|
};
|
|
@@ -109,7 +112,9 @@ declare module '@formkit/inputs' {
|
|
|
109
112
|
nuxtUIInputTime: MergeSlots<FormKitBaseSlots<Props>, InputTimeSlots>;
|
|
110
113
|
nuxtUIListbox: MergeSlots<FormKitBaseSlots<Props>, ListboxSlots>;
|
|
111
114
|
nuxtUIMultiStep: MergeSlots<FormKitBaseSlots<Props>, FormKitMultiStepSlots<Props>>;
|
|
115
|
+
nuxtUIPinInput: MergeSlots<FormKitBaseSlots<Props>, PinInputSlots>;
|
|
112
116
|
nuxtUIRadioGroup: MergeSlots<FormKitBaseSlots<Props>, RadioGroupSlots>;
|
|
117
|
+
nuxtUIRepeater: FormKitBaseSlots<Props>;
|
|
113
118
|
nuxtUISelect: MergeSlots<FormKitBaseSlots<Props>, SelectSlots>;
|
|
114
119
|
nuxtUISelectMenu: MergeSlots<FormKitBaseSlots<Props>, SelectMenuSlots>;
|
|
115
120
|
nuxtUIStep: MergeSlots<FormKitBaseSlots<Props>, FormKitStepSlots<Props>>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
/**
|
|
3
|
+
* For an input whose real focusable sub-elements live inside one container
|
|
4
|
+
* - a Reka UI `DateField`'s day/month/year segments, a checkbox/radio
|
|
5
|
+
* group's individual items, a listbox's options - `context.handlers.blur`
|
|
6
|
+
* must only fire once focus has genuinely left the whole container, not
|
|
7
|
+
* just moved between its own children. Native `blur` doesn't bubble, so a
|
|
8
|
+
* plain `@blur` on the container never sees a child's blur at all; this
|
|
9
|
+
* binds to `focusout` (which does bubble) instead, and uses
|
|
10
|
+
* `relatedTarget` to tell "moved to a sibling inside" apart from "left
|
|
11
|
+
* entirely."
|
|
12
|
+
*
|
|
13
|
+
* Discovered while wiring `FUInputDate`/`FUInputTime`: Nuxt UI's own
|
|
14
|
+
* `InputDate.vue`/`InputTime.vue` bind `@blur` on their internal
|
|
15
|
+
* `DateField.Root`, assuming Reka UI aggregates blur across segments the
|
|
16
|
+
* same way - it doesn't (`DateField.Root` doesn't declare `blur` as its own
|
|
17
|
+
* emit, so that binding is a native fallthrough on a never-focused
|
|
18
|
+
* container div, and silently never fires). This helper is what actually
|
|
19
|
+
* fixes it, bound to `@focusout` on the outer `<UInputDate>`/`<UInputTime>`
|
|
20
|
+
* component instead.
|
|
21
|
+
*
|
|
22
|
+
* Uses `event.currentTarget` (the element the listener is actually attached
|
|
23
|
+
* to) as the container, rather than a template ref to the component's own
|
|
24
|
+
* `$el` - `UInputDate`/`UInputTime` render a multi-root template (a
|
|
25
|
+
* `createReusableTemplate`-style definition block plus the real
|
|
26
|
+
* `DateField.Root`), so `$el` resolves to that definition block's own
|
|
27
|
+
* placeholder node, not the visible container (confirmed empirically).
|
|
28
|
+
* `currentTarget` has no such ambiguity: it's always the exact node the
|
|
29
|
+
* `focusout` listener is bound to.
|
|
30
|
+
*
|
|
31
|
+
* Returns a plain `(event: Event) => void`, not `(event: FocusEvent) =>
|
|
32
|
+
* void` - some Nuxt UI components (e.g. `UPinInput`) type their own `blur`
|
|
33
|
+
* emit as generic `Event`, and a stricter parameter type isn't assignable
|
|
34
|
+
* to a listener bound there. It's genuinely a `FocusEvent` at runtime
|
|
35
|
+
* (`focusout` always is), so it's cast internally.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createContainerBlurHandler(context: FormKitFrameworkContext): (event: Event) => void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function createContainerBlurHandler(context) {
|
|
2
|
+
return (event) => {
|
|
3
|
+
const focusEvent = event;
|
|
4
|
+
const container = focusEvent.currentTarget;
|
|
5
|
+
const related = focusEvent.relatedTarget;
|
|
6
|
+
if (!container || !related || !container.contains(related))
|
|
7
|
+
context.handlers.blur(focusEvent);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { computed } from "vue";
|
|
1
|
+
import { computed, onBeforeUnmount, ref } from "vue";
|
|
2
2
|
export function useFormKitInput(context) {
|
|
3
|
+
const ui = ref(context?.node?.props?.ui);
|
|
4
|
+
const uiReceipt = context?.node?.on?.("prop:ui", ({ payload }) => {
|
|
5
|
+
ui.value = payload;
|
|
6
|
+
});
|
|
7
|
+
onBeforeUnmount(() => {
|
|
8
|
+
if (uiReceipt !== void 0)
|
|
9
|
+
context?.node?.off?.(uiReceipt);
|
|
10
|
+
});
|
|
3
11
|
const isInvalid = computed(() => {
|
|
4
12
|
return context?.state?.validationVisible && !context?.state?.valid;
|
|
5
13
|
});
|
|
@@ -38,5 +46,5 @@ export function useFormKitInput(context) {
|
|
|
38
46
|
}
|
|
39
47
|
return [];
|
|
40
48
|
});
|
|
41
|
-
return { isInvalid, validSlotNames, styleClass, color, handleBlur, handleChange, handleInput, handleSelect, modelValue, items };
|
|
49
|
+
return { isInvalid, validSlotNames, styleClass, color, handleBlur, handleChange, handleInput, handleSelect, modelValue, items, ui };
|
|
42
50
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
export interface FormKitOutputUi {
|
|
3
|
+
/** Merged into `containerClass` - Output components have no themeable Nuxt UI root to forward to. */
|
|
4
|
+
root?: string;
|
|
5
|
+
/** Merged into `iconClass`, applied to every `FUIcon` an Output component renders. */
|
|
6
|
+
icon?: string;
|
|
7
|
+
/** Forwarded unmodified to `UBadge`'s own `:ui` prop (`FUOutputList`'s badge display mode only). */
|
|
8
|
+
badge?: Record<string, unknown>;
|
|
9
|
+
}
|
|
2
10
|
export declare function useFormKitOutput(context: FormKitFrameworkContext): {
|
|
3
11
|
colorClass: import("vue").ComputedRef<string>;
|
|
4
12
|
sizeClass: import("vue").ComputedRef<string>;
|
|
@@ -7,4 +15,21 @@ export declare function useFormKitOutput(context: FormKitFrameworkContext): {
|
|
|
7
15
|
iconClass: import("vue").ComputedRef<string>;
|
|
8
16
|
leadingIconName: import("vue").ComputedRef<string | null>;
|
|
9
17
|
trailingIconName: import("vue").ComputedRef<string | null>;
|
|
18
|
+
ui: import("vue").Ref<{
|
|
19
|
+
root?: string
|
|
20
|
+
/** Merged into `iconClass`, applied to every `FUIcon` an Output component renders. */
|
|
21
|
+
| undefined;
|
|
22
|
+
icon?: string
|
|
23
|
+
/** Forwarded unmodified to `UBadge`'s own `:ui` prop (`FUOutputList`'s badge display mode only). */
|
|
24
|
+
| undefined;
|
|
25
|
+
badge?: Record<string, unknown> | undefined;
|
|
26
|
+
} | undefined, FormKitOutputUi | {
|
|
27
|
+
root?: string
|
|
28
|
+
/** Merged into `iconClass`, applied to every `FUIcon` an Output component renders. */
|
|
29
|
+
| undefined;
|
|
30
|
+
icon?: string
|
|
31
|
+
/** Forwarded unmodified to `UBadge`'s own `:ui` prop (`FUOutputList`'s badge display mode only). */
|
|
32
|
+
| undefined;
|
|
33
|
+
badge?: Record<string, unknown> | undefined;
|
|
34
|
+
} | undefined>;
|
|
10
35
|
};
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import { computed } from "vue";
|
|
1
|
+
import { computed, onBeforeUnmount, ref } from "vue";
|
|
2
2
|
export function useFormKitOutput(context) {
|
|
3
|
+
const ui = ref(context?.node?.props?.ui);
|
|
4
|
+
const uiReceipt = context?.node?.on?.("prop:ui", ({ payload }) => {
|
|
5
|
+
ui.value = payload;
|
|
6
|
+
});
|
|
7
|
+
onBeforeUnmount(() => {
|
|
8
|
+
if (uiReceipt !== void 0)
|
|
9
|
+
context?.node?.off?.(uiReceipt);
|
|
10
|
+
});
|
|
3
11
|
const colorClass = computed(() => {
|
|
4
12
|
const color = context.color ?? "neutral";
|
|
5
13
|
const colorMap = {
|
|
@@ -41,6 +49,7 @@ export function useFormKitOutput(context) {
|
|
|
41
49
|
colorClass.value,
|
|
42
50
|
sizeClass.value,
|
|
43
51
|
variantClass.value,
|
|
52
|
+
ui.value?.root,
|
|
44
53
|
context?.attrs?.class
|
|
45
54
|
].filter(Boolean).join(" ");
|
|
46
55
|
});
|
|
@@ -53,13 +62,19 @@ export function useFormKitOutput(context) {
|
|
|
53
62
|
lg: "h-6 w-6",
|
|
54
63
|
xl: "h-7 w-7"
|
|
55
64
|
};
|
|
56
|
-
return iconSizeMap[size] || iconSizeMap.md;
|
|
65
|
+
return [iconSizeMap[size] || iconSizeMap.md, ui.value?.icon].filter(Boolean).join(" ");
|
|
57
66
|
});
|
|
58
67
|
const leadingIconName = computed(() => {
|
|
59
|
-
|
|
68
|
+
const leadingIcon = context.leadingIcon;
|
|
69
|
+
const leading = context.leading;
|
|
70
|
+
const icon = context.icon;
|
|
71
|
+
return leadingIcon || leading && icon || null;
|
|
60
72
|
});
|
|
61
73
|
const trailingIconName = computed(() => {
|
|
62
|
-
|
|
74
|
+
const trailingIcon = context.trailingIcon;
|
|
75
|
+
const trailing = context.trailing;
|
|
76
|
+
const icon = context.icon;
|
|
77
|
+
return trailingIcon || trailing && icon || null;
|
|
63
78
|
});
|
|
64
79
|
return {
|
|
65
80
|
colorClass,
|
|
@@ -68,6 +83,7 @@ export function useFormKitOutput(context) {
|
|
|
68
83
|
containerClass,
|
|
69
84
|
iconClass,
|
|
70
85
|
leadingIconName,
|
|
71
|
-
trailingIconName
|
|
86
|
+
trailingIconName,
|
|
87
|
+
ui
|
|
72
88
|
};
|
|
73
89
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Shared by `FUDataEditOverlay.vue`/`FUAutoFormOverlay.vue`: both need to
|
|
4
|
+
* resolve their `useOverlay` `close` emit exactly once per open cycle, from
|
|
5
|
+
* whichever of several sources fires first - an explicit Save/Cancel button,
|
|
6
|
+
* or `UModal`/`USlideover`'s own Esc/backdrop dismissal, which only ever
|
|
7
|
+
* surfaces as their `open` v-model transitioning to `false` with no
|
|
8
|
+
* dedicated event of its own.
|
|
9
|
+
*
|
|
10
|
+
* `useOverlay` reuses the same wrapper instance across sequential `edit()`/
|
|
11
|
+
* `auto()` calls (its registered `id` is fixed at `.create()` time, not
|
|
12
|
+
* per-`open()` call), so "has this open cycle already resolved" has to reset
|
|
13
|
+
* on every reopen, not just be set once ever - otherwise a *later* call's
|
|
14
|
+
* Esc/backdrop dismissal would see the flag still `true` from a previous
|
|
15
|
+
* cycle's Save/Cancel and silently no-op, leaving that later promise pending
|
|
16
|
+
* forever.
|
|
17
|
+
*/
|
|
18
|
+
export declare function useOverlayCloseResolution(open: Ref<boolean>, emit: (event: 'close', value: unknown) => void): {
|
|
19
|
+
resolveOnce: (value: unknown) => void;
|
|
20
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { watch } from "vue";
|
|
2
|
+
export function useOverlayCloseResolution(open, emit) {
|
|
3
|
+
let hasResolved = false;
|
|
4
|
+
function resolveOnce(value) {
|
|
5
|
+
if (hasResolved)
|
|
6
|
+
return;
|
|
7
|
+
hasResolved = true;
|
|
8
|
+
emit("close", value);
|
|
9
|
+
}
|
|
10
|
+
watch(open, (isOpen) => {
|
|
11
|
+
if (isOpen)
|
|
12
|
+
hasResolved = false;
|
|
13
|
+
else
|
|
14
|
+
resolveOnce(null);
|
|
15
|
+
});
|
|
16
|
+
return { resolveOnce };
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sfxcode/nuxt-ui-formkit",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "FormKit integration for Nuxt UI - Seamlessly connect FormKit form handling with Nuxt UI components",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Tom",
|
|
@@ -97,12 +97,12 @@
|
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
99
|
"@codemirror/lang-json": "^6.0.2",
|
|
100
|
-
"@codemirror/state": "^6.7.
|
|
100
|
+
"@codemirror/state": "^6.7.1",
|
|
101
101
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
102
|
-
"@codemirror/view": "^6.43.
|
|
102
|
+
"@codemirror/view": "^6.43.6",
|
|
103
103
|
"@iconify-json/heroicons": "^1.2.3",
|
|
104
104
|
"@iconify-json/lucide": "^1.2.116",
|
|
105
|
-
"@iconify-json/simple-icons": "^1.2.
|
|
105
|
+
"@iconify-json/simple-icons": "^1.2.89",
|
|
106
106
|
"@nuxt/devtools": "4.0.0-alpha.7",
|
|
107
107
|
"@nuxt/eslint-config": "^1.16.0",
|
|
108
108
|
"@nuxt/module-builder": "^1.0.2",
|
|
@@ -122,10 +122,10 @@
|
|
|
122
122
|
"unbuild": "^3.6.1",
|
|
123
123
|
"valibot": "^1.4.2",
|
|
124
124
|
"vitepress": "2.0.0-alpha.17",
|
|
125
|
-
"vitest": "^4.1.
|
|
125
|
+
"vitest": "^4.1.10",
|
|
126
126
|
"vue": "^3.5.39",
|
|
127
127
|
"vue-i18n": "^11.4.6",
|
|
128
|
-
"vue-tsc": "^3.3.
|
|
128
|
+
"vue-tsc": "^3.3.7",
|
|
129
129
|
"zod": "^4.4.3"
|
|
130
130
|
},
|
|
131
131
|
"packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499"
|