@sfxcode/nuxt-ui-formkit 1.2.3 → 1.2.4
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/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.vue +2 -1
- 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/inputs/FUCalendar.vue +3 -0
- package/dist/runtime/components/inputs/FUCheckbox.vue +2 -1
- package/dist/runtime/components/inputs/FUCheckboxGroup.vue +3 -0
- package/dist/runtime/components/inputs/FUEditor.vue +58 -54
- package/dist/runtime/components/inputs/FUFileUpload.vue +2 -1
- package/dist/runtime/components/inputs/FUInput.vue +2 -1
- package/dist/runtime/components/inputs/FUInputDate.vue +5 -1
- package/dist/runtime/components/inputs/FUInputMenu.vue +2 -1
- package/dist/runtime/components/inputs/FUInputNumber.vue +2 -1
- package/dist/runtime/components/inputs/FUInputTags.vue +2 -1
- package/dist/runtime/components/inputs/FUInputTime.vue +5 -1
- package/dist/runtime/components/inputs/FUListbox.vue +4 -0
- package/dist/runtime/components/inputs/FUPinInput.vue +8 -1
- package/dist/runtime/components/inputs/FURadioGroup.vue +3 -0
- package/dist/runtime/components/inputs/FUSwitch.vue +2 -1
- package/dist/runtime/components/inputs/FUTextarea.vue +2 -1
- package/dist/runtime/composables/useFormKitOverlay.d.ts +20 -0
- package/dist/runtime/composables/useFormKitOverlay.js +42 -0
- package/dist/runtime/utils/useFormKitContainerBlur.d.ts +37 -0
- package/dist/runtime/utils/useFormKitContainerBlur.js +9 -0
- package/dist/runtime/utils/useOverlayCloseResolution.d.ts +20 -0
- package/dist/runtime/utils/useOverlayCloseResolution.js +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ FormKit Nuxt UI bridges the gap between [FormKit](https://formkit.com/)'s powerf
|
|
|
75
75
|
- `useFormKitMultiStep` - Multi-step tab-item mapping and navigation bridging
|
|
76
76
|
- `useFormKitForm` - Submit/reset/error-management wrapper for a form's imperative APIs, callable from outside the form
|
|
77
77
|
- `useFormKitAutoForm` - Schema inference from data value shapes, Valibot, or Zod schemas (`inferFormSchema`/`inferFormSchemaFromValibot`/`inferFormSchemaFromZod`)
|
|
78
|
+
- `useFormKitOverlay` - Promise-based modal/slideover forms: `await overlay.edit({ data, schema, title })` (or `.auto(...)` for a schema-free version), resolving to the saved data or `null` on cancel
|
|
78
79
|
- `colorConverter` - Color format conversion utilities
|
|
79
80
|
- `durationConverter` - Duration format conversion utilities
|
|
80
81
|
|
package/dist/module.json
CHANGED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
import type { AutoFormOverrides, ValibotLikeSchema, ZodLikeSchema } from '../composables/useFormKitAutoForm.js';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
id: {
|
|
5
|
+
type: StringConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
data: {
|
|
9
|
+
type: ObjectConstructor;
|
|
10
|
+
default: null;
|
|
11
|
+
};
|
|
12
|
+
valibotSchema: {
|
|
13
|
+
type: PropType<ValibotLikeSchema>;
|
|
14
|
+
default: undefined;
|
|
15
|
+
};
|
|
16
|
+
zodSchema: {
|
|
17
|
+
type: PropType<ZodLikeSchema>;
|
|
18
|
+
default: undefined;
|
|
19
|
+
};
|
|
20
|
+
overrides: {
|
|
21
|
+
type: PropType<AutoFormOverrides>;
|
|
22
|
+
default: undefined;
|
|
23
|
+
};
|
|
24
|
+
title: {
|
|
25
|
+
type: StringConstructor;
|
|
26
|
+
default: undefined;
|
|
27
|
+
};
|
|
28
|
+
as: {
|
|
29
|
+
type: PropType<"modal" | "slideover">;
|
|
30
|
+
default: string;
|
|
31
|
+
};
|
|
32
|
+
open: {
|
|
33
|
+
type: PropType<boolean>;
|
|
34
|
+
};
|
|
35
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
36
|
+
close: (value: unknown) => any;
|
|
37
|
+
"update:open": (value: boolean) => any;
|
|
38
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
39
|
+
id: {
|
|
40
|
+
type: StringConstructor;
|
|
41
|
+
required: true;
|
|
42
|
+
};
|
|
43
|
+
data: {
|
|
44
|
+
type: ObjectConstructor;
|
|
45
|
+
default: null;
|
|
46
|
+
};
|
|
47
|
+
valibotSchema: {
|
|
48
|
+
type: PropType<ValibotLikeSchema>;
|
|
49
|
+
default: undefined;
|
|
50
|
+
};
|
|
51
|
+
zodSchema: {
|
|
52
|
+
type: PropType<ZodLikeSchema>;
|
|
53
|
+
default: undefined;
|
|
54
|
+
};
|
|
55
|
+
overrides: {
|
|
56
|
+
type: PropType<AutoFormOverrides>;
|
|
57
|
+
default: undefined;
|
|
58
|
+
};
|
|
59
|
+
title: {
|
|
60
|
+
type: StringConstructor;
|
|
61
|
+
default: undefined;
|
|
62
|
+
};
|
|
63
|
+
as: {
|
|
64
|
+
type: PropType<"modal" | "slideover">;
|
|
65
|
+
default: string;
|
|
66
|
+
};
|
|
67
|
+
open: {
|
|
68
|
+
type: PropType<boolean>;
|
|
69
|
+
};
|
|
70
|
+
}>> & Readonly<{
|
|
71
|
+
onClose?: ((value: unknown) => any) | undefined;
|
|
72
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
73
|
+
}>, {
|
|
74
|
+
data: Record<string, any>;
|
|
75
|
+
title: string;
|
|
76
|
+
overrides: AutoFormOverrides;
|
|
77
|
+
valibotSchema: ValibotLikeSchema;
|
|
78
|
+
zodSchema: ZodLikeSchema;
|
|
79
|
+
as: "modal" | "slideover";
|
|
80
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
81
|
+
declare const _default: typeof __VLS_export;
|
|
82
|
+
export default _default;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useOverlayCloseResolution } from "../utils/useOverlayCloseResolution";
|
|
3
|
+
import FUAutoForm from "./FUAutoForm.vue";
|
|
4
|
+
defineProps({
|
|
5
|
+
id: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
data: {
|
|
10
|
+
type: Object,
|
|
11
|
+
default: null
|
|
12
|
+
},
|
|
13
|
+
valibotSchema: {
|
|
14
|
+
type: Object,
|
|
15
|
+
default: void 0
|
|
16
|
+
},
|
|
17
|
+
zodSchema: {
|
|
18
|
+
type: Object,
|
|
19
|
+
default: void 0
|
|
20
|
+
},
|
|
21
|
+
overrides: {
|
|
22
|
+
type: Object,
|
|
23
|
+
default: void 0
|
|
24
|
+
},
|
|
25
|
+
title: {
|
|
26
|
+
type: String,
|
|
27
|
+
default: void 0
|
|
28
|
+
},
|
|
29
|
+
as: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: "modal"
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
const emit = defineEmits(["close"]);
|
|
35
|
+
const open = defineModel("open", { type: Boolean, ...{ default: false } });
|
|
36
|
+
const { resolveOnce } = useOverlayCloseResolution(open, emit);
|
|
37
|
+
function handleSaved(savedData) {
|
|
38
|
+
resolveOnce(savedData);
|
|
39
|
+
}
|
|
40
|
+
function handleCancel() {
|
|
41
|
+
resolveOnce(null);
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<UModal
|
|
47
|
+
v-if="as === 'modal'"
|
|
48
|
+
v-model:open="open"
|
|
49
|
+
:title="title"
|
|
50
|
+
>
|
|
51
|
+
<template #body>
|
|
52
|
+
<FUAutoForm
|
|
53
|
+
:id="id"
|
|
54
|
+
:data="data"
|
|
55
|
+
:valibot-schema="valibotSchema"
|
|
56
|
+
:zod-schema="zodSchema"
|
|
57
|
+
:overrides="overrides"
|
|
58
|
+
@data-saved="handleSaved"
|
|
59
|
+
>
|
|
60
|
+
<template #submit>
|
|
61
|
+
<UButton
|
|
62
|
+
type="submit"
|
|
63
|
+
label="Save"
|
|
64
|
+
/>
|
|
65
|
+
<UButton
|
|
66
|
+
type="button"
|
|
67
|
+
label="Cancel"
|
|
68
|
+
color="neutral"
|
|
69
|
+
variant="outline"
|
|
70
|
+
@click="handleCancel"
|
|
71
|
+
/>
|
|
72
|
+
</template>
|
|
73
|
+
</FUAutoForm>
|
|
74
|
+
</template>
|
|
75
|
+
</UModal>
|
|
76
|
+
<USlideover
|
|
77
|
+
v-else
|
|
78
|
+
v-model:open="open"
|
|
79
|
+
:title="title"
|
|
80
|
+
>
|
|
81
|
+
<template #body>
|
|
82
|
+
<FUAutoForm
|
|
83
|
+
:id="id"
|
|
84
|
+
:data="data"
|
|
85
|
+
:valibot-schema="valibotSchema"
|
|
86
|
+
:zod-schema="zodSchema"
|
|
87
|
+
:overrides="overrides"
|
|
88
|
+
@data-saved="handleSaved"
|
|
89
|
+
>
|
|
90
|
+
<template #submit>
|
|
91
|
+
<UButton
|
|
92
|
+
type="submit"
|
|
93
|
+
label="Save"
|
|
94
|
+
/>
|
|
95
|
+
<UButton
|
|
96
|
+
type="button"
|
|
97
|
+
label="Cancel"
|
|
98
|
+
color="neutral"
|
|
99
|
+
variant="outline"
|
|
100
|
+
@click="handleCancel"
|
|
101
|
+
/>
|
|
102
|
+
</template>
|
|
103
|
+
</FUAutoForm>
|
|
104
|
+
</template>
|
|
105
|
+
</USlideover>
|
|
106
|
+
</template>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { PropType } from 'vue';
|
|
2
|
+
import type { AutoFormOverrides, ValibotLikeSchema, ZodLikeSchema } from '../composables/useFormKitAutoForm.js';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
id: {
|
|
5
|
+
type: StringConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
data: {
|
|
9
|
+
type: ObjectConstructor;
|
|
10
|
+
default: null;
|
|
11
|
+
};
|
|
12
|
+
valibotSchema: {
|
|
13
|
+
type: PropType<ValibotLikeSchema>;
|
|
14
|
+
default: undefined;
|
|
15
|
+
};
|
|
16
|
+
zodSchema: {
|
|
17
|
+
type: PropType<ZodLikeSchema>;
|
|
18
|
+
default: undefined;
|
|
19
|
+
};
|
|
20
|
+
overrides: {
|
|
21
|
+
type: PropType<AutoFormOverrides>;
|
|
22
|
+
default: undefined;
|
|
23
|
+
};
|
|
24
|
+
title: {
|
|
25
|
+
type: StringConstructor;
|
|
26
|
+
default: undefined;
|
|
27
|
+
};
|
|
28
|
+
as: {
|
|
29
|
+
type: PropType<"modal" | "slideover">;
|
|
30
|
+
default: string;
|
|
31
|
+
};
|
|
32
|
+
open: {
|
|
33
|
+
type: PropType<boolean>;
|
|
34
|
+
};
|
|
35
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
36
|
+
close: (value: unknown) => any;
|
|
37
|
+
"update:open": (value: boolean) => any;
|
|
38
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
39
|
+
id: {
|
|
40
|
+
type: StringConstructor;
|
|
41
|
+
required: true;
|
|
42
|
+
};
|
|
43
|
+
data: {
|
|
44
|
+
type: ObjectConstructor;
|
|
45
|
+
default: null;
|
|
46
|
+
};
|
|
47
|
+
valibotSchema: {
|
|
48
|
+
type: PropType<ValibotLikeSchema>;
|
|
49
|
+
default: undefined;
|
|
50
|
+
};
|
|
51
|
+
zodSchema: {
|
|
52
|
+
type: PropType<ZodLikeSchema>;
|
|
53
|
+
default: undefined;
|
|
54
|
+
};
|
|
55
|
+
overrides: {
|
|
56
|
+
type: PropType<AutoFormOverrides>;
|
|
57
|
+
default: undefined;
|
|
58
|
+
};
|
|
59
|
+
title: {
|
|
60
|
+
type: StringConstructor;
|
|
61
|
+
default: undefined;
|
|
62
|
+
};
|
|
63
|
+
as: {
|
|
64
|
+
type: PropType<"modal" | "slideover">;
|
|
65
|
+
default: string;
|
|
66
|
+
};
|
|
67
|
+
open: {
|
|
68
|
+
type: PropType<boolean>;
|
|
69
|
+
};
|
|
70
|
+
}>> & Readonly<{
|
|
71
|
+
onClose?: ((value: unknown) => any) | undefined;
|
|
72
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
73
|
+
}>, {
|
|
74
|
+
data: Record<string, any>;
|
|
75
|
+
title: string;
|
|
76
|
+
overrides: AutoFormOverrides;
|
|
77
|
+
valibotSchema: ValibotLikeSchema;
|
|
78
|
+
zodSchema: ZodLikeSchema;
|
|
79
|
+
as: "modal" | "slideover";
|
|
80
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
81
|
+
declare const _default: typeof __VLS_export;
|
|
82
|
+
export default _default;
|
|
@@ -95,7 +95,8 @@ if (props.data) {
|
|
|
95
95
|
formData.value = props.data;
|
|
96
96
|
}
|
|
97
97
|
function handleSave() {
|
|
98
|
-
|
|
98
|
+
const { slots: _slots, ...data } = formData.value ?? {};
|
|
99
|
+
emit("dataSaved", data);
|
|
99
100
|
}
|
|
100
101
|
function handleReset() {
|
|
101
102
|
reset(props.id);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { FormKitSchemaDefinition } from '@formkit/core';
|
|
2
|
+
import type { PropType } from 'vue';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
id: {
|
|
5
|
+
type: StringConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
data: {
|
|
9
|
+
type: ObjectConstructor;
|
|
10
|
+
default: null;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
14
|
+
default: null;
|
|
15
|
+
};
|
|
16
|
+
title: {
|
|
17
|
+
type: StringConstructor;
|
|
18
|
+
default: undefined;
|
|
19
|
+
};
|
|
20
|
+
as: {
|
|
21
|
+
type: PropType<"modal" | "slideover">;
|
|
22
|
+
default: string;
|
|
23
|
+
};
|
|
24
|
+
open: {
|
|
25
|
+
type: PropType<boolean>;
|
|
26
|
+
};
|
|
27
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
28
|
+
close: (value: unknown) => any;
|
|
29
|
+
"update:open": (value: boolean) => any;
|
|
30
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
31
|
+
id: {
|
|
32
|
+
type: StringConstructor;
|
|
33
|
+
required: true;
|
|
34
|
+
};
|
|
35
|
+
data: {
|
|
36
|
+
type: ObjectConstructor;
|
|
37
|
+
default: null;
|
|
38
|
+
};
|
|
39
|
+
schema: {
|
|
40
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
41
|
+
default: null;
|
|
42
|
+
};
|
|
43
|
+
title: {
|
|
44
|
+
type: StringConstructor;
|
|
45
|
+
default: undefined;
|
|
46
|
+
};
|
|
47
|
+
as: {
|
|
48
|
+
type: PropType<"modal" | "slideover">;
|
|
49
|
+
default: string;
|
|
50
|
+
};
|
|
51
|
+
open: {
|
|
52
|
+
type: PropType<boolean>;
|
|
53
|
+
};
|
|
54
|
+
}>> & Readonly<{
|
|
55
|
+
onClose?: ((value: unknown) => any) | undefined;
|
|
56
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
57
|
+
}>, {
|
|
58
|
+
schema: FormKitSchemaDefinition;
|
|
59
|
+
data: Record<string, any>;
|
|
60
|
+
title: string;
|
|
61
|
+
as: "modal" | "slideover";
|
|
62
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
63
|
+
declare const _default: typeof __VLS_export;
|
|
64
|
+
export default _default;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useOverlayCloseResolution } from "../utils/useOverlayCloseResolution";
|
|
3
|
+
import FUDataEdit from "./FUDataEdit.vue";
|
|
4
|
+
defineProps({
|
|
5
|
+
id: {
|
|
6
|
+
type: String,
|
|
7
|
+
required: true
|
|
8
|
+
},
|
|
9
|
+
data: {
|
|
10
|
+
type: Object,
|
|
11
|
+
default: null
|
|
12
|
+
},
|
|
13
|
+
schema: {
|
|
14
|
+
type: Object,
|
|
15
|
+
default: null
|
|
16
|
+
},
|
|
17
|
+
title: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: void 0
|
|
20
|
+
},
|
|
21
|
+
as: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: "modal"
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const emit = defineEmits(["close"]);
|
|
27
|
+
const open = defineModel("open", { type: Boolean, ...{ default: false } });
|
|
28
|
+
const { resolveOnce } = useOverlayCloseResolution(open, emit);
|
|
29
|
+
function handleSaved(savedData) {
|
|
30
|
+
resolveOnce(savedData);
|
|
31
|
+
}
|
|
32
|
+
function handleCancel() {
|
|
33
|
+
resolveOnce(null);
|
|
34
|
+
}
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<UModal
|
|
39
|
+
v-if="as === 'modal'"
|
|
40
|
+
v-model:open="open"
|
|
41
|
+
:title="title"
|
|
42
|
+
>
|
|
43
|
+
<template #body>
|
|
44
|
+
<FUDataEdit
|
|
45
|
+
:id="id"
|
|
46
|
+
:data="data"
|
|
47
|
+
:schema="schema"
|
|
48
|
+
@data-saved="handleSaved"
|
|
49
|
+
>
|
|
50
|
+
<template #submit>
|
|
51
|
+
<UButton
|
|
52
|
+
type="submit"
|
|
53
|
+
label="Save"
|
|
54
|
+
/>
|
|
55
|
+
<UButton
|
|
56
|
+
type="button"
|
|
57
|
+
label="Cancel"
|
|
58
|
+
color="neutral"
|
|
59
|
+
variant="outline"
|
|
60
|
+
@click="handleCancel"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
63
|
+
</FUDataEdit>
|
|
64
|
+
</template>
|
|
65
|
+
</UModal>
|
|
66
|
+
<USlideover
|
|
67
|
+
v-else
|
|
68
|
+
v-model:open="open"
|
|
69
|
+
:title="title"
|
|
70
|
+
>
|
|
71
|
+
<template #body>
|
|
72
|
+
<FUDataEdit
|
|
73
|
+
:id="id"
|
|
74
|
+
:data="data"
|
|
75
|
+
:schema="schema"
|
|
76
|
+
@data-saved="handleSaved"
|
|
77
|
+
>
|
|
78
|
+
<template #submit>
|
|
79
|
+
<UButton
|
|
80
|
+
type="submit"
|
|
81
|
+
label="Save"
|
|
82
|
+
/>
|
|
83
|
+
<UButton
|
|
84
|
+
type="button"
|
|
85
|
+
label="Cancel"
|
|
86
|
+
color="neutral"
|
|
87
|
+
variant="outline"
|
|
88
|
+
@click="handleCancel"
|
|
89
|
+
/>
|
|
90
|
+
</template>
|
|
91
|
+
</FUDataEdit>
|
|
92
|
+
</template>
|
|
93
|
+
</USlideover>
|
|
94
|
+
</template>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { FormKitSchemaDefinition } from '@formkit/core';
|
|
2
|
+
import type { PropType } from 'vue';
|
|
3
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
+
id: {
|
|
5
|
+
type: StringConstructor;
|
|
6
|
+
required: true;
|
|
7
|
+
};
|
|
8
|
+
data: {
|
|
9
|
+
type: ObjectConstructor;
|
|
10
|
+
default: null;
|
|
11
|
+
};
|
|
12
|
+
schema: {
|
|
13
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
14
|
+
default: null;
|
|
15
|
+
};
|
|
16
|
+
title: {
|
|
17
|
+
type: StringConstructor;
|
|
18
|
+
default: undefined;
|
|
19
|
+
};
|
|
20
|
+
as: {
|
|
21
|
+
type: PropType<"modal" | "slideover">;
|
|
22
|
+
default: string;
|
|
23
|
+
};
|
|
24
|
+
open: {
|
|
25
|
+
type: PropType<boolean>;
|
|
26
|
+
};
|
|
27
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
28
|
+
close: (value: unknown) => any;
|
|
29
|
+
"update:open": (value: boolean) => any;
|
|
30
|
+
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
31
|
+
id: {
|
|
32
|
+
type: StringConstructor;
|
|
33
|
+
required: true;
|
|
34
|
+
};
|
|
35
|
+
data: {
|
|
36
|
+
type: ObjectConstructor;
|
|
37
|
+
default: null;
|
|
38
|
+
};
|
|
39
|
+
schema: {
|
|
40
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
41
|
+
default: null;
|
|
42
|
+
};
|
|
43
|
+
title: {
|
|
44
|
+
type: StringConstructor;
|
|
45
|
+
default: undefined;
|
|
46
|
+
};
|
|
47
|
+
as: {
|
|
48
|
+
type: PropType<"modal" | "slideover">;
|
|
49
|
+
default: string;
|
|
50
|
+
};
|
|
51
|
+
open: {
|
|
52
|
+
type: PropType<boolean>;
|
|
53
|
+
};
|
|
54
|
+
}>> & Readonly<{
|
|
55
|
+
onClose?: ((value: unknown) => any) | undefined;
|
|
56
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
57
|
+
}>, {
|
|
58
|
+
schema: FormKitSchemaDefinition;
|
|
59
|
+
data: Record<string, any>;
|
|
60
|
+
title: string;
|
|
61
|
+
as: "modal" | "slideover";
|
|
62
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
63
|
+
declare const _default: typeof __VLS_export;
|
|
64
|
+
export default _default;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
4
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
4
5
|
import { toDateValue, toDateValueOrRangeOrArray, fromDateValueOrRangeOrArray } from "../../utils/dateValueConversion";
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
context: {
|
|
@@ -9,6 +10,7 @@ const props = defineProps({
|
|
|
9
10
|
}
|
|
10
11
|
});
|
|
11
12
|
const { handleInput, styleClass, color, validSlotNames } = useFormKitInput(props.context);
|
|
13
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
12
14
|
const conversionOptions = computed(() => ({ timeZone: props.context.timeZone }));
|
|
13
15
|
const modelValue = computed({
|
|
14
16
|
get: () => toDateValueOrRangeOrArray(props.context._value, conversionOptions.value),
|
|
@@ -46,6 +48,7 @@ const maxValue = computed(() => toDateValue(props.context.maxValue, conversionOp
|
|
|
46
48
|
:is-date-unavailable="context.isDateUnavailable"
|
|
47
49
|
:ui="context.ui"
|
|
48
50
|
@update:model-value="handleInput"
|
|
51
|
+
@focusout="handleContainerBlur"
|
|
49
52
|
>
|
|
50
53
|
<template
|
|
51
54
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, styleClass, modelValue, color, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, styleClass, modelValue, color, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -31,6 +31,7 @@ const { handleInput, handleChange, styleClass, modelValue, color, validSlotNames
|
|
|
31
31
|
:ui="context.ui"
|
|
32
32
|
@change="handleChange"
|
|
33
33
|
@update:model-value="handleInput"
|
|
34
|
+
@blur="handleBlur"
|
|
34
35
|
>
|
|
35
36
|
<template
|
|
36
37
|
v-for="slotName in validSlotNames"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
context: {
|
|
5
6
|
type: Object,
|
|
@@ -7,6 +8,7 @@ const props = defineProps({
|
|
|
7
8
|
}
|
|
8
9
|
});
|
|
9
10
|
const { handleInput, handleChange, styleClass, color, modelValue, items, validSlotNames } = useFormKitInput(props.context);
|
|
11
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
10
12
|
</script>
|
|
11
13
|
|
|
12
14
|
<template>
|
|
@@ -31,6 +33,7 @@ const { handleInput, handleChange, styleClass, color, modelValue, items, validSl
|
|
|
31
33
|
:name="context.name"
|
|
32
34
|
@change="handleChange"
|
|
33
35
|
@update:model-value="handleInput"
|
|
36
|
+
@focusout="handleContainerBlur"
|
|
34
37
|
>
|
|
35
38
|
<template
|
|
36
39
|
v-for="slotName in validSlotNames"
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
3
4
|
const DEFAULT_EDITOR_TOOLBAR_ITEMS = [
|
|
4
5
|
[
|
|
5
6
|
{ kind: "undo", icon: "i-lucide-undo", tooltip: { text: "Undo" } },
|
|
@@ -61,61 +62,64 @@ const props = defineProps({
|
|
|
61
62
|
}
|
|
62
63
|
});
|
|
63
64
|
const { handleInput, styleClass, modelValue } = useFormKitInput(props.context);
|
|
65
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
64
66
|
</script>
|
|
65
67
|
|
|
66
68
|
<template>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
69
|
+
<div @focusout="handleContainerBlur">
|
|
70
|
+
<UEditor
|
|
71
|
+
:id="context.id"
|
|
72
|
+
v-model="modelValue"
|
|
73
|
+
v-bind="{ ...context?.attrs }"
|
|
74
|
+
:class="styleClass"
|
|
75
|
+
:editable="!context?.disabled"
|
|
76
|
+
:style="context?.attrs.style"
|
|
77
|
+
:content-type="context.contentType"
|
|
78
|
+
:starter-kit="context.starterKit"
|
|
79
|
+
:placeholder="context.placeholder"
|
|
80
|
+
:markdown="context.markdown"
|
|
81
|
+
:image="context.image"
|
|
82
|
+
:mention="context.mention"
|
|
83
|
+
:handlers="context.editorHandlers"
|
|
84
|
+
:extensions="context.extensions"
|
|
85
|
+
:autofocus="context.autofocus"
|
|
86
|
+
:ui="context.ui"
|
|
87
|
+
@update:model-value="handleInput"
|
|
88
|
+
>
|
|
89
|
+
<template #default="{ editor, handlers }">
|
|
90
|
+
<UEditorToolbar
|
|
91
|
+
v-if="context.toolbar !== false"
|
|
92
|
+
:editor="editor"
|
|
93
|
+
:items="context.toolbarItems ?? DEFAULT_EDITOR_TOOLBAR_ITEMS"
|
|
94
|
+
class="border-b border-default px-2 py-1 mb-2 flex-wrap"
|
|
95
|
+
/>
|
|
96
|
+
<UEditorToolbar
|
|
97
|
+
v-if="context.bubbleToolbar !== false"
|
|
98
|
+
:editor="editor"
|
|
99
|
+
:items="context.bubbleToolbarItems ?? DEFAULT_BUBBLE_TOOLBAR_ITEMS"
|
|
100
|
+
layout="bubble"
|
|
101
|
+
:should-show="bubbleToolbarShouldShow"
|
|
102
|
+
/>
|
|
103
|
+
<UEditorDragHandle
|
|
104
|
+
v-if="context.dragHandle"
|
|
105
|
+
:editor="editor"
|
|
106
|
+
/>
|
|
107
|
+
<UEditorSuggestionMenu
|
|
108
|
+
v-if="context.suggestionMenu"
|
|
109
|
+
:editor="editor"
|
|
110
|
+
:items="context.suggestionMenuItems ?? DEFAULT_SUGGESTION_MENU_ITEMS"
|
|
111
|
+
/>
|
|
112
|
+
<UEditorMentionMenu
|
|
113
|
+
v-if="context.mentionItems?.length"
|
|
114
|
+
:editor="editor"
|
|
115
|
+
:items="context.mentionItems"
|
|
116
|
+
/>
|
|
117
|
+
<component
|
|
118
|
+
:is="context.slots.default"
|
|
119
|
+
v-if="context?.slots?.default"
|
|
120
|
+
v-bind="{ ...context, editor, handlers }"
|
|
121
|
+
/>
|
|
122
|
+
</template>
|
|
123
|
+
</UEditor>
|
|
124
|
+
</div>
|
|
121
125
|
</template>
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -41,6 +41,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, val
|
|
|
41
41
|
:ui="context.ui"
|
|
42
42
|
@change="handleChange"
|
|
43
43
|
@update:model-value="handleInput"
|
|
44
|
+
@blur="handleBlur"
|
|
44
45
|
>
|
|
45
46
|
<template
|
|
46
47
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -46,6 +46,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, val
|
|
|
46
46
|
:ui="context.ui"
|
|
47
47
|
@change="handleChange"
|
|
48
48
|
@update:model-value="handleInput"
|
|
49
|
+
@blur="handleBlur"
|
|
49
50
|
>
|
|
50
51
|
<template
|
|
51
52
|
v-for="slotName in validSlotNames"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
4
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
4
5
|
import { fromDateValueOrRange, toDateValue, toDateValueOrRange } from "../../utils/dateValueConversion";
|
|
5
6
|
const props = defineProps({
|
|
6
7
|
context: {
|
|
@@ -8,7 +9,8 @@ const props = defineProps({
|
|
|
8
9
|
required: true
|
|
9
10
|
}
|
|
10
11
|
});
|
|
11
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, validSlotNames } = useFormKitInput(props.context);
|
|
12
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, validSlotNames } = useFormKitInput(props.context);
|
|
13
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
12
14
|
const conversionOptions = computed(() => ({
|
|
13
15
|
granularity: props.context.granularity,
|
|
14
16
|
hideTimeZone: props.context.hideTimeZone,
|
|
@@ -66,6 +68,8 @@ const minValue = computed(() => toDateValue(props.context.minValue, conversionOp
|
|
|
66
68
|
:ui="context.ui"
|
|
67
69
|
@change="handleChange"
|
|
68
70
|
@update:model-value="handleInput"
|
|
71
|
+
@blur="handleBlur"
|
|
72
|
+
@focusout="handleContainerBlur"
|
|
69
73
|
>
|
|
70
74
|
<template
|
|
71
75
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, items, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, items, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -65,6 +65,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, ite
|
|
|
65
65
|
:ui="context.ui"
|
|
66
66
|
@change="handleChange"
|
|
67
67
|
@update:model-value="handleInput"
|
|
68
|
+
@blur="handleBlur"
|
|
68
69
|
>
|
|
69
70
|
<template
|
|
70
71
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -47,6 +47,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, val
|
|
|
47
47
|
:ui="context.ui"
|
|
48
48
|
@change="handleChange"
|
|
49
49
|
@update:model-value="handleInput"
|
|
50
|
+
@blur="handleBlur"
|
|
50
51
|
>
|
|
51
52
|
<template
|
|
52
53
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -49,6 +49,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, val
|
|
|
49
49
|
:ui="context.ui"
|
|
50
50
|
@change="handleChange"
|
|
51
51
|
@update:model-value="handleInput"
|
|
52
|
+
@blur="handleBlur"
|
|
52
53
|
>
|
|
53
54
|
<template
|
|
54
55
|
v-for="slotName in validSlotNames"
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
context: {
|
|
5
6
|
type: Object,
|
|
6
7
|
required: true
|
|
7
8
|
}
|
|
8
9
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
11
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
10
12
|
</script>
|
|
11
13
|
|
|
12
14
|
<template>
|
|
@@ -46,6 +48,8 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, val
|
|
|
46
48
|
:ui="context.ui"
|
|
47
49
|
@change="handleChange"
|
|
48
50
|
@update:model-value="handleInput"
|
|
51
|
+
@blur="handleBlur"
|
|
52
|
+
@focusout="handleContainerBlur"
|
|
49
53
|
>
|
|
50
54
|
<template
|
|
51
55
|
v-for="slotName in validSlotNames"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { computed, nextTick, ref, watch } from "vue";
|
|
3
3
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
4
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
context: {
|
|
6
7
|
type: Object,
|
|
@@ -8,6 +9,7 @@ const props = defineProps({
|
|
|
8
9
|
}
|
|
9
10
|
});
|
|
10
11
|
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue, items, validSlotNames } = useFormKitInput(props.context);
|
|
12
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
11
13
|
const targetItems = ref(modelValue.value || []);
|
|
12
14
|
const sourceSelection = ref([]);
|
|
13
15
|
const targetSelection = ref([]);
|
|
@@ -240,6 +242,7 @@ watch(targetItems, (newVal) => {
|
|
|
240
242
|
:ui="context.ui"
|
|
241
243
|
@change="handleChange"
|
|
242
244
|
@update:model-value="handleInput"
|
|
245
|
+
@focusout="handleContainerBlur"
|
|
243
246
|
>
|
|
244
247
|
<template
|
|
245
248
|
v-for="slotName in validSlotNames"
|
|
@@ -255,6 +258,7 @@ watch(targetItems, (newVal) => {
|
|
|
255
258
|
<div
|
|
256
259
|
v-if="context.displayMode === 'transfer'"
|
|
257
260
|
class="flex items-stretch gap-4 w-full"
|
|
261
|
+
@focusout="handleContainerBlur"
|
|
258
262
|
>
|
|
259
263
|
<div
|
|
260
264
|
ref="sourceContainerRef"
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
context: {
|
|
5
6
|
type: Object,
|
|
6
7
|
required: true
|
|
7
8
|
}
|
|
8
9
|
});
|
|
9
|
-
const { handleInput, handleChange, isInvalid, styleClass, color, modelValue } = useFormKitInput(props.context);
|
|
10
|
+
const { handleInput, handleChange, handleBlur, isInvalid, styleClass, color, modelValue } = useFormKitInput(props.context);
|
|
11
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
12
|
+
function handlePinBlur(event) {
|
|
13
|
+
handleBlur(event);
|
|
14
|
+
}
|
|
10
15
|
</script>
|
|
11
16
|
|
|
12
17
|
<template>
|
|
@@ -35,5 +40,7 @@ const { handleInput, handleChange, isInvalid, styleClass, color, modelValue } =
|
|
|
35
40
|
:ui="context.ui"
|
|
36
41
|
@change="handleChange"
|
|
37
42
|
@update:model-value="handleInput"
|
|
43
|
+
@blur="handlePinBlur"
|
|
44
|
+
@focusout="handleContainerBlur"
|
|
38
45
|
/>
|
|
39
46
|
</template>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
import { createContainerBlurHandler } from "../../utils/useFormKitContainerBlur";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
context: {
|
|
5
6
|
type: Object,
|
|
@@ -7,6 +8,7 @@ const props = defineProps({
|
|
|
7
8
|
}
|
|
8
9
|
});
|
|
9
10
|
const { handleInput, handleChange, styleClass, color, modelValue, items, validSlotNames } = useFormKitInput(props.context);
|
|
11
|
+
const handleContainerBlur = createContainerBlurHandler(props.context);
|
|
10
12
|
</script>
|
|
11
13
|
|
|
12
14
|
<template>
|
|
@@ -31,6 +33,7 @@ const { handleInput, handleChange, styleClass, color, modelValue, items, validSl
|
|
|
31
33
|
:ui="context.ui"
|
|
32
34
|
@change="handleChange"
|
|
33
35
|
@update:model-value="handleInput"
|
|
36
|
+
@focusout="handleContainerBlur"
|
|
34
37
|
>
|
|
35
38
|
<template
|
|
36
39
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, styleClass, color, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -32,6 +32,7 @@ const { handleInput, handleChange, styleClass, color, modelValue, validSlotNames
|
|
|
32
32
|
:ui="context.ui"
|
|
33
33
|
@change="handleChange"
|
|
34
34
|
@update:model-value="handleInput"
|
|
35
|
+
@blur="handleBlur"
|
|
35
36
|
>
|
|
36
37
|
<template
|
|
37
38
|
v-for="slotName in validSlotNames"
|
|
@@ -6,7 +6,7 @@ const props = defineProps({
|
|
|
6
6
|
required: true
|
|
7
7
|
}
|
|
8
8
|
});
|
|
9
|
-
const { handleInput, handleChange, styleClass, color, isInvalid, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
9
|
+
const { handleInput, handleChange, handleBlur, styleClass, color, isInvalid, modelValue, validSlotNames } = useFormKitInput(props.context);
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<template>
|
|
@@ -46,6 +46,7 @@ const { handleInput, handleChange, styleClass, color, isInvalid, modelValue, val
|
|
|
46
46
|
:ui="context.ui"
|
|
47
47
|
@change="handleChange"
|
|
48
48
|
@update:model-value="handleInput"
|
|
49
|
+
@blur="handleBlur"
|
|
49
50
|
>
|
|
50
51
|
<template
|
|
51
52
|
v-for="slotName in validSlotNames"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FormKitSchemaDefinition } from '@formkit/core';
|
|
2
|
+
import type { AutoFormOverrides, ValibotLikeSchema, ZodLikeSchema } from './useFormKitAutoForm.js';
|
|
3
|
+
export interface FormKitOverlayEditOptions {
|
|
4
|
+
data: unknown;
|
|
5
|
+
schema: FormKitSchemaDefinition;
|
|
6
|
+
title?: string;
|
|
7
|
+
as?: 'modal' | 'slideover';
|
|
8
|
+
}
|
|
9
|
+
export interface FormKitOverlayAutoOptions {
|
|
10
|
+
data?: unknown;
|
|
11
|
+
valibotSchema?: ValibotLikeSchema;
|
|
12
|
+
zodSchema?: ZodLikeSchema;
|
|
13
|
+
overrides?: AutoFormOverrides;
|
|
14
|
+
title?: string;
|
|
15
|
+
as?: 'modal' | 'slideover';
|
|
16
|
+
}
|
|
17
|
+
export declare function useFormKitOverlay(): {
|
|
18
|
+
edit: (options: FormKitOverlayEditOptions) => Promise<unknown>;
|
|
19
|
+
auto: (options: FormKitOverlayAutoOptions) => Promise<unknown>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useOverlay } from "@nuxt/ui/composables";
|
|
2
|
+
import FUAutoFormOverlay from "../components/FUAutoFormOverlay.vue";
|
|
3
|
+
import FUDataEditOverlay from "../components/FUDataEditOverlay.vue";
|
|
4
|
+
const registeredOverlays = /* @__PURE__ */ new WeakMap();
|
|
5
|
+
const registeredAutoOverlays = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
let formIdCounter = 0;
|
|
7
|
+
export function useFormKitOverlay() {
|
|
8
|
+
const overlay = useOverlay();
|
|
9
|
+
let registeredOverlay = registeredOverlays.get(overlay);
|
|
10
|
+
if (!registeredOverlay) {
|
|
11
|
+
registeredOverlay = overlay.create(FUDataEditOverlay);
|
|
12
|
+
registeredOverlays.set(overlay, registeredOverlay);
|
|
13
|
+
}
|
|
14
|
+
let registeredAutoOverlay = registeredAutoOverlays.get(overlay);
|
|
15
|
+
if (!registeredAutoOverlay) {
|
|
16
|
+
registeredAutoOverlay = overlay.create(FUAutoFormOverlay);
|
|
17
|
+
registeredAutoOverlays.set(overlay, registeredAutoOverlay);
|
|
18
|
+
}
|
|
19
|
+
function edit(options) {
|
|
20
|
+
const id = `formkit-overlay-${++formIdCounter}`;
|
|
21
|
+
return registeredOverlay.open({
|
|
22
|
+
id,
|
|
23
|
+
data: options.data,
|
|
24
|
+
schema: options.schema,
|
|
25
|
+
title: options.title,
|
|
26
|
+
as: options.as ?? "modal"
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function auto(options) {
|
|
30
|
+
const id = `formkit-autoform-overlay-${++formIdCounter}`;
|
|
31
|
+
return registeredAutoOverlay.open({
|
|
32
|
+
id,
|
|
33
|
+
data: options.data,
|
|
34
|
+
valibotSchema: options.valibotSchema,
|
|
35
|
+
zodSchema: options.zodSchema,
|
|
36
|
+
overrides: options.overrides,
|
|
37
|
+
title: options.title,
|
|
38
|
+
as: options.as ?? "modal"
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return { edit, auto };
|
|
42
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|