@sfxcode/nuxt-ui-formkit 1.1.1 → 1.2.1
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 +11 -1
- package/dist/module.json +1 -1
- package/dist/runtime/components/FUDataEdit.d.vue.ts +8 -4
- package/dist/runtime/components/FUDataEdit.vue +1 -1
- package/dist/runtime/components/FUDataEdit.vue.d.ts +8 -4
- package/dist/runtime/components/FUDataView.d.vue.ts +8 -4
- package/dist/runtime/components/FUDataView.vue +1 -1
- package/dist/runtime/components/FUDataView.vue.d.ts +8 -4
- package/dist/runtime/components/inputs/FUCalendar.d.vue.ts +48 -0
- package/dist/runtime/components/inputs/FUCalendar.vue +61 -0
- package/dist/runtime/components/inputs/FUCalendar.vue.d.ts +48 -0
- package/dist/runtime/components/inputs/FUEditor.d.vue.ts +60 -0
- package/dist/runtime/components/inputs/FUEditor.vue +121 -0
- package/dist/runtime/components/inputs/FUEditor.vue.d.ts +60 -0
- package/dist/runtime/components/inputs/FUFileUpload.d.vue.ts +39 -0
- package/dist/runtime/components/inputs/FUFileUpload.vue +56 -0
- package/dist/runtime/components/inputs/FUFileUpload.vue.d.ts +39 -0
- package/dist/runtime/components/inputs/FUInputDate.d.vue.ts +18 -5
- package/dist/runtime/components/inputs/FUInputDate.vue +24 -6
- package/dist/runtime/components/inputs/FUInputDate.vue.d.ts +18 -5
- package/dist/runtime/components/inputs/FUListbox.d.vue.ts +2 -0
- package/dist/runtime/components/inputs/FUListbox.vue +226 -6
- package/dist/runtime/components/inputs/FUListbox.vue.d.ts +2 -0
- package/dist/runtime/formkit/definitions/index.d.ts +27 -24
- package/dist/runtime/formkit/definitions/index.js +4 -1
- package/dist/runtime/formkit/definitions/index.mjs +4 -1
- package/dist/runtime/formkit/definitions/input.d.ts +3 -0
- package/dist/runtime/formkit/definitions/input.js +17 -2
- package/dist/runtime/formkit/definitions/input.mjs +17 -2
- package/dist/runtime/formkit/definitions/repeater.js +8 -1
- package/dist/runtime/formkit/definitions/repeater.mjs +8 -1
- package/dist/runtime/formkit/index.d.ts +13 -1
- package/dist/runtime/utils/dateValueConversion.d.ts +35 -0
- package/dist/runtime/utils/dateValueConversion.js +80 -0
- package/dist/runtime/utils/useFormKitInput.d.ts +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -18,10 +18,13 @@ FormKit Nuxt UI bridges the gap between [FormKit](https://formkit.com/)'s powerf
|
|
|
18
18
|
|
|
19
19
|
## Features
|
|
20
20
|
|
|
21
|
-
✨ **
|
|
21
|
+
✨ **20 Input Components** - Complete set of FormKit-wrapped Nuxt UI input components
|
|
22
|
+
- `nuxtUICalendar` - Bare date-grid picker with range/multiple selection
|
|
22
23
|
- `nuxtUICheckbox` - Single checkbox with label and description
|
|
23
24
|
- `nuxtUICheckboxGroup` - Multiple checkbox selection
|
|
24
25
|
- `nuxtUIColorPicker` - Color selection with multiple formats
|
|
26
|
+
- `nuxtUIEditor` - Tiptap-based rich text editor
|
|
27
|
+
- `nuxtUIFileUpload` - Drag/drop and click-to-browse file input
|
|
25
28
|
- `nuxtUIInput` - Text input with various types (text, email, password, etc.)
|
|
26
29
|
- `nuxtUIInputDate` - Date and time picker with range support
|
|
27
30
|
- `nuxtUIInputMenu` - Dropdown menu with searchable options
|
|
@@ -285,9 +288,12 @@ Refer to the [Nuxt UI documentation](https://ui.nuxt.com/) for component-specifi
|
|
|
285
288
|
The playground includes comprehensive examples for all components:
|
|
286
289
|
|
|
287
290
|
### Input Components
|
|
291
|
+
- [Calendar](./playground/app/pages/components/input/calendar.vue)
|
|
288
292
|
- [Checkbox](./playground/app/pages/components/input/checkbox.vue)
|
|
289
293
|
- [CheckboxGroup](./playground/app/pages/components/input/checkbox-group.vue)
|
|
290
294
|
- [ColorPicker](./playground/app/pages/components/input/color-picker.vue)
|
|
295
|
+
- [Editor](./playground/app/pages/components/input/editor.vue)
|
|
296
|
+
- [FileUpload](./playground/app/pages/components/input/file-upload.vue)
|
|
291
297
|
- [Input](./playground/app/pages/components/input/input.vue)
|
|
292
298
|
- [InputDate](./playground/app/pages/components/input/input-date.vue)
|
|
293
299
|
- [InputMenu](./playground/app/pages/components/input/input-menu.vue)
|
|
@@ -311,6 +317,10 @@ The playground includes comprehensive examples for all components:
|
|
|
311
317
|
- [OutputNumber](./playground/app/pages/components/output/number.vue)
|
|
312
318
|
- [OutputText](./playground/app/pages/components/output/text.vue)
|
|
313
319
|
|
|
320
|
+
### Repeater
|
|
321
|
+
- [Repeater](./playground/app/pages/form/repeater-sample.vue)
|
|
322
|
+
- [Drag-and-Drop Repeater](./playground/app/pages/form/repeater-drag.vue)
|
|
323
|
+
|
|
314
324
|
## Development
|
|
315
325
|
|
|
316
326
|
<details>
|
package/dist/module.json
CHANGED
|
@@ -73,9 +73,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
73
73
|
type: BooleanConstructor;
|
|
74
74
|
default: boolean;
|
|
75
75
|
};
|
|
76
|
-
modelValue:
|
|
76
|
+
modelValue: {
|
|
77
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
78
|
+
};
|
|
77
79
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
78
|
-
"update:modelValue": (value:
|
|
80
|
+
"update:modelValue": (value: FormKitSchemaDefinition | undefined) => any;
|
|
79
81
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
80
82
|
id: {
|
|
81
83
|
type: StringConstructor;
|
|
@@ -141,9 +143,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
141
143
|
type: BooleanConstructor;
|
|
142
144
|
default: boolean;
|
|
143
145
|
};
|
|
144
|
-
modelValue:
|
|
146
|
+
modelValue: {
|
|
147
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
148
|
+
};
|
|
145
149
|
}>> & Readonly<{
|
|
146
|
-
"onUpdate:modelValue"?: ((value:
|
|
150
|
+
"onUpdate:modelValue"?: ((value: FormKitSchemaDefinition | undefined) => any) | undefined;
|
|
147
151
|
}>, {
|
|
148
152
|
data: Record<string, any>;
|
|
149
153
|
id: string;
|
|
@@ -71,7 +71,7 @@ const props = defineProps({
|
|
|
71
71
|
});
|
|
72
72
|
const emit = defineEmits(["dataSaved", "onReset"]);
|
|
73
73
|
const formSchema = ref(props.schema);
|
|
74
|
-
const formData = defineModel({ type:
|
|
74
|
+
const formData = defineModel({ type: [Object, String, Array] });
|
|
75
75
|
watch(() => props.schema, (newSchema) => {
|
|
76
76
|
formSchema.value = newSchema;
|
|
77
77
|
}, { deep: true });
|
|
@@ -73,9 +73,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
73
73
|
type: BooleanConstructor;
|
|
74
74
|
default: boolean;
|
|
75
75
|
};
|
|
76
|
-
modelValue:
|
|
76
|
+
modelValue: {
|
|
77
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
78
|
+
};
|
|
77
79
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
78
|
-
"update:modelValue": (value:
|
|
80
|
+
"update:modelValue": (value: FormKitSchemaDefinition | undefined) => any;
|
|
79
81
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
80
82
|
id: {
|
|
81
83
|
type: StringConstructor;
|
|
@@ -141,9 +143,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
141
143
|
type: BooleanConstructor;
|
|
142
144
|
default: boolean;
|
|
143
145
|
};
|
|
144
|
-
modelValue:
|
|
146
|
+
modelValue: {
|
|
147
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
148
|
+
};
|
|
145
149
|
}>> & Readonly<{
|
|
146
|
-
"onUpdate:modelValue"?: ((value:
|
|
150
|
+
"onUpdate:modelValue"?: ((value: FormKitSchemaDefinition | undefined) => any) | undefined;
|
|
147
151
|
}>, {
|
|
148
152
|
data: Record<string, any>;
|
|
149
153
|
id: string;
|
|
@@ -25,9 +25,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
25
25
|
type: BooleanConstructor;
|
|
26
26
|
default: boolean;
|
|
27
27
|
};
|
|
28
|
-
modelValue:
|
|
28
|
+
modelValue: {
|
|
29
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
30
|
+
};
|
|
29
31
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
-
"update:modelValue": (value:
|
|
32
|
+
"update:modelValue": (value: FormKitSchemaDefinition | undefined) => any;
|
|
31
33
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
32
34
|
data: {
|
|
33
35
|
type: ObjectConstructor;
|
|
@@ -49,9 +51,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
49
51
|
type: BooleanConstructor;
|
|
50
52
|
default: boolean;
|
|
51
53
|
};
|
|
52
|
-
modelValue:
|
|
54
|
+
modelValue: {
|
|
55
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
56
|
+
};
|
|
53
57
|
}>> & Readonly<{
|
|
54
|
-
"onUpdate:modelValue"?: ((value:
|
|
58
|
+
"onUpdate:modelValue"?: ((value: FormKitSchemaDefinition | undefined) => any) | undefined;
|
|
55
59
|
}>, {
|
|
56
60
|
data: Record<string, any>;
|
|
57
61
|
schema: FormKitSchemaDefinition;
|
|
@@ -25,7 +25,7 @@ const props = defineProps({
|
|
|
25
25
|
}
|
|
26
26
|
});
|
|
27
27
|
const formSchema = ref(props.schema);
|
|
28
|
-
const formData = defineModel({ type:
|
|
28
|
+
const formData = defineModel({ type: [Object, String, Array] });
|
|
29
29
|
watch(() => props.schema, (newSchema) => {
|
|
30
30
|
formSchema.value = newSchema;
|
|
31
31
|
}, { deep: true });
|
|
@@ -25,9 +25,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
25
25
|
type: BooleanConstructor;
|
|
26
26
|
default: boolean;
|
|
27
27
|
};
|
|
28
|
-
modelValue:
|
|
28
|
+
modelValue: {
|
|
29
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
30
|
+
};
|
|
29
31
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
30
|
-
"update:modelValue": (value:
|
|
32
|
+
"update:modelValue": (value: FormKitSchemaDefinition | undefined) => any;
|
|
31
33
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
32
34
|
data: {
|
|
33
35
|
type: ObjectConstructor;
|
|
@@ -49,9 +51,11 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
|
|
|
49
51
|
type: BooleanConstructor;
|
|
50
52
|
default: boolean;
|
|
51
53
|
};
|
|
52
|
-
modelValue:
|
|
54
|
+
modelValue: {
|
|
55
|
+
type: PropType<FormKitSchemaDefinition>;
|
|
56
|
+
};
|
|
53
57
|
}>> & Readonly<{
|
|
54
|
-
"onUpdate:modelValue"?: ((value:
|
|
58
|
+
"onUpdate:modelValue"?: ((value: FormKitSchemaDefinition | undefined) => any) | undefined;
|
|
55
59
|
}>, {
|
|
56
60
|
data: Record<string, any>;
|
|
57
61
|
schema: FormKitSchemaDefinition;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
import type { DateValue } from '@internationalized/date';
|
|
3
|
+
import type { PropType } from 'vue';
|
|
4
|
+
import type { DateValueType } from '../../utils/dateValueConversion.js';
|
|
5
|
+
type DateLike = DateValue | Date | string;
|
|
6
|
+
export interface CalendarDateRange {
|
|
7
|
+
start: DateLike;
|
|
8
|
+
end: DateLike;
|
|
9
|
+
}
|
|
10
|
+
export interface FormKitCalendarProps {
|
|
11
|
+
type?: 'date' | 'month' | 'year';
|
|
12
|
+
color?: 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'neutral';
|
|
13
|
+
variant?: 'solid' | 'outline' | 'soft' | 'subtle';
|
|
14
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
15
|
+
range?: boolean;
|
|
16
|
+
multiple?: boolean;
|
|
17
|
+
weekNumbers?: boolean;
|
|
18
|
+
monthControls?: boolean;
|
|
19
|
+
yearControls?: boolean;
|
|
20
|
+
viewControl?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Shape of the value read from / written to the FormKit form data.
|
|
23
|
+
* `'calendar'` (default) keeps the native `@internationalized/date` `DateValue`.
|
|
24
|
+
* `'date'` converts to/from a JS `Date`. `'iso'` converts to/from an ISO 8601 string.
|
|
25
|
+
*/
|
|
26
|
+
valueType?: DateValueType;
|
|
27
|
+
/** Timezone used when converting to/from `'date'`/`'iso'`. Defaults to the local timezone. */
|
|
28
|
+
timeZone?: string;
|
|
29
|
+
defaultValue?: DateLike | DateLike[] | CalendarDateRange;
|
|
30
|
+
minValue?: DateLike;
|
|
31
|
+
maxValue?: DateLike;
|
|
32
|
+
isDateDisabled?: (date: DateValue) => boolean;
|
|
33
|
+
isDateUnavailable?: (date: DateValue) => boolean;
|
|
34
|
+
ui?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
37
|
+
context: {
|
|
38
|
+
type: PropType<FormKitFrameworkContext & FormKitCalendarProps>;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
42
|
+
context: {
|
|
43
|
+
type: PropType<FormKitFrameworkContext & FormKitCalendarProps>;
|
|
44
|
+
required: true;
|
|
45
|
+
};
|
|
46
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
47
|
+
declare const _default: typeof __VLS_export;
|
|
48
|
+
export default _default;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
4
|
+
import { toDateValue, toDateValueOrRangeOrArray, fromDateValueOrRangeOrArray } from "../../utils/dateValueConversion";
|
|
5
|
+
const props = defineProps({
|
|
6
|
+
context: {
|
|
7
|
+
type: Object,
|
|
8
|
+
required: true
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const { handleInput, styleClass, color, validSlotNames } = useFormKitInput(props.context);
|
|
12
|
+
const conversionOptions = computed(() => ({ timeZone: props.context.timeZone }));
|
|
13
|
+
const modelValue = computed({
|
|
14
|
+
get: () => toDateValueOrRangeOrArray(props.context._value, conversionOptions.value),
|
|
15
|
+
set: (value) => {
|
|
16
|
+
props.context.node.input(fromDateValueOrRangeOrArray(value, props.context.valueType ?? "calendar", props.context.timeZone));
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const defaultValue = computed(() => toDateValueOrRangeOrArray(props.context.defaultValue, conversionOptions.value));
|
|
20
|
+
const minValue = computed(() => toDateValue(props.context.minValue, conversionOptions.value));
|
|
21
|
+
const maxValue = computed(() => toDateValue(props.context.maxValue, conversionOptions.value));
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<template>
|
|
25
|
+
<UCalendar
|
|
26
|
+
:id="context.id"
|
|
27
|
+
v-model="modelValue"
|
|
28
|
+
v-bind="{ ...context?.attrs }"
|
|
29
|
+
:class="styleClass"
|
|
30
|
+
:disabled="!!context?.disabled"
|
|
31
|
+
:style="context?.attrs.style"
|
|
32
|
+
:type="context.type ?? 'date'"
|
|
33
|
+
:color="color"
|
|
34
|
+
:variant="context.variant"
|
|
35
|
+
:size="context.size ?? 'md'"
|
|
36
|
+
:range="context.range"
|
|
37
|
+
:multiple="context.multiple"
|
|
38
|
+
:week-numbers="context.weekNumbers"
|
|
39
|
+
:month-controls="context.monthControls"
|
|
40
|
+
:year-controls="context.yearControls"
|
|
41
|
+
:view-control="context.viewControl"
|
|
42
|
+
:default-value="defaultValue"
|
|
43
|
+
:min-value="minValue"
|
|
44
|
+
:max-value="maxValue"
|
|
45
|
+
:is-date-disabled="context.isDateDisabled"
|
|
46
|
+
:is-date-unavailable="context.isDateUnavailable"
|
|
47
|
+
:ui="context.ui"
|
|
48
|
+
@update:model-value="handleInput"
|
|
49
|
+
>
|
|
50
|
+
<template
|
|
51
|
+
v-for="slotName in validSlotNames"
|
|
52
|
+
:key="slotName"
|
|
53
|
+
#[slotName]="slotProps"
|
|
54
|
+
>
|
|
55
|
+
<component
|
|
56
|
+
:is="context?.slots[slotName]"
|
|
57
|
+
v-bind="{ ...context, ...slotProps }"
|
|
58
|
+
/>
|
|
59
|
+
</template>
|
|
60
|
+
</UCalendar>
|
|
61
|
+
</template>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
import type { DateValue } from '@internationalized/date';
|
|
3
|
+
import type { PropType } from 'vue';
|
|
4
|
+
import type { DateValueType } from '../../utils/dateValueConversion.js';
|
|
5
|
+
type DateLike = DateValue | Date | string;
|
|
6
|
+
export interface CalendarDateRange {
|
|
7
|
+
start: DateLike;
|
|
8
|
+
end: DateLike;
|
|
9
|
+
}
|
|
10
|
+
export interface FormKitCalendarProps {
|
|
11
|
+
type?: 'date' | 'month' | 'year';
|
|
12
|
+
color?: 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'neutral';
|
|
13
|
+
variant?: 'solid' | 'outline' | 'soft' | 'subtle';
|
|
14
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
15
|
+
range?: boolean;
|
|
16
|
+
multiple?: boolean;
|
|
17
|
+
weekNumbers?: boolean;
|
|
18
|
+
monthControls?: boolean;
|
|
19
|
+
yearControls?: boolean;
|
|
20
|
+
viewControl?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Shape of the value read from / written to the FormKit form data.
|
|
23
|
+
* `'calendar'` (default) keeps the native `@internationalized/date` `DateValue`.
|
|
24
|
+
* `'date'` converts to/from a JS `Date`. `'iso'` converts to/from an ISO 8601 string.
|
|
25
|
+
*/
|
|
26
|
+
valueType?: DateValueType;
|
|
27
|
+
/** Timezone used when converting to/from `'date'`/`'iso'`. Defaults to the local timezone. */
|
|
28
|
+
timeZone?: string;
|
|
29
|
+
defaultValue?: DateLike | DateLike[] | CalendarDateRange;
|
|
30
|
+
minValue?: DateLike;
|
|
31
|
+
maxValue?: DateLike;
|
|
32
|
+
isDateDisabled?: (date: DateValue) => boolean;
|
|
33
|
+
isDateUnavailable?: (date: DateValue) => boolean;
|
|
34
|
+
ui?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
37
|
+
context: {
|
|
38
|
+
type: PropType<FormKitFrameworkContext & FormKitCalendarProps>;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
42
|
+
context: {
|
|
43
|
+
type: PropType<FormKitFrameworkContext & FormKitCalendarProps>;
|
|
44
|
+
required: true;
|
|
45
|
+
};
|
|
46
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
47
|
+
declare const _default: typeof __VLS_export;
|
|
48
|
+
export default _default;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
3
|
+
import type { PropType } from 'vue';
|
|
4
|
+
export interface FormKitEditorHandler {
|
|
5
|
+
canExecute: (editor: unknown, cmd?: unknown) => boolean;
|
|
6
|
+
execute: (editor: unknown, cmd?: unknown) => unknown;
|
|
7
|
+
isActive: (editor: unknown, cmd?: unknown) => boolean;
|
|
8
|
+
isDisabled?: (editor: unknown, cmd?: unknown) => boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface FormKitEditorItem {
|
|
11
|
+
kind: string;
|
|
12
|
+
icon?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
tooltip?: Record<string, unknown>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface FormKitEditorSuggestionItem extends FormKitEditorItem {
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
export interface FormKitEditorMentionItem {
|
|
21
|
+
label: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
icon?: string;
|
|
24
|
+
avatar?: Record<string, unknown>;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface FormKitEditorProps {
|
|
29
|
+
contentType?: 'json' | 'html' | 'markdown';
|
|
30
|
+
starterKit?: Record<string, unknown>;
|
|
31
|
+
placeholder?: string | Record<string, unknown>;
|
|
32
|
+
markdown?: Record<string, unknown>;
|
|
33
|
+
image?: boolean | Record<string, unknown>;
|
|
34
|
+
mention?: boolean | Record<string, unknown>;
|
|
35
|
+
editorHandlers?: Record<string, FormKitEditorHandler>;
|
|
36
|
+
extensions?: AnyExtension[];
|
|
37
|
+
autofocus?: boolean;
|
|
38
|
+
toolbar?: boolean;
|
|
39
|
+
toolbarItems?: FormKitEditorItem[] | FormKitEditorItem[][];
|
|
40
|
+
bubbleToolbar?: boolean;
|
|
41
|
+
bubbleToolbarItems?: FormKitEditorItem[] | FormKitEditorItem[][];
|
|
42
|
+
dragHandle?: boolean;
|
|
43
|
+
suggestionMenu?: boolean;
|
|
44
|
+
suggestionMenuItems?: FormKitEditorSuggestionItem[] | FormKitEditorSuggestionItem[][];
|
|
45
|
+
mentionItems?: FormKitEditorMentionItem[];
|
|
46
|
+
ui?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
49
|
+
context: {
|
|
50
|
+
type: PropType<FormKitFrameworkContext & FormKitEditorProps>;
|
|
51
|
+
required: true;
|
|
52
|
+
};
|
|
53
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
54
|
+
context: {
|
|
55
|
+
type: PropType<FormKitFrameworkContext & FormKitEditorProps>;
|
|
56
|
+
required: true;
|
|
57
|
+
};
|
|
58
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
59
|
+
declare const _default: typeof __VLS_export;
|
|
60
|
+
export default _default;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useFormKitInput } from "../../utils/useFormKitInput";
|
|
3
|
+
const DEFAULT_EDITOR_TOOLBAR_ITEMS = [
|
|
4
|
+
[
|
|
5
|
+
{ kind: "undo", icon: "i-lucide-undo", tooltip: { text: "Undo" } },
|
|
6
|
+
{ kind: "redo", icon: "i-lucide-redo", tooltip: { text: "Redo" } }
|
|
7
|
+
],
|
|
8
|
+
[
|
|
9
|
+
{ kind: "heading", level: 1, icon: "i-lucide-heading-1", tooltip: { text: "Heading 1" } },
|
|
10
|
+
{ kind: "heading", level: 2, icon: "i-lucide-heading-2", tooltip: { text: "Heading 2" } },
|
|
11
|
+
{ kind: "heading", level: 3, icon: "i-lucide-heading-3", tooltip: { text: "Heading 3" } }
|
|
12
|
+
],
|
|
13
|
+
[
|
|
14
|
+
{ kind: "mark", mark: "bold", icon: "i-lucide-bold", tooltip: { text: "Bold" } },
|
|
15
|
+
{ kind: "mark", mark: "italic", icon: "i-lucide-italic", tooltip: { text: "Italic" } },
|
|
16
|
+
{ kind: "mark", mark: "underline", icon: "i-lucide-underline", tooltip: { text: "Underline" } },
|
|
17
|
+
{ kind: "mark", mark: "strike", icon: "i-lucide-strikethrough", tooltip: { text: "Strikethrough" } },
|
|
18
|
+
{ kind: "mark", mark: "code", icon: "i-lucide-code", tooltip: { text: "Code" } }
|
|
19
|
+
],
|
|
20
|
+
[
|
|
21
|
+
{ kind: "bulletList", icon: "i-lucide-list", tooltip: { text: "Bullet List" } },
|
|
22
|
+
{ kind: "orderedList", icon: "i-lucide-list-ordered", tooltip: { text: "Ordered List" } },
|
|
23
|
+
{ kind: "blockquote", icon: "i-lucide-quote", tooltip: { text: "Blockquote" } },
|
|
24
|
+
{ kind: "codeBlock", icon: "i-lucide-square-code", tooltip: { text: "Code Block" } },
|
|
25
|
+
{ kind: "horizontalRule", icon: "i-lucide-minus", tooltip: { text: "Horizontal Rule" } },
|
|
26
|
+
{ kind: "link", icon: "i-lucide-link", tooltip: { text: "Link" } }
|
|
27
|
+
]
|
|
28
|
+
];
|
|
29
|
+
const DEFAULT_BUBBLE_TOOLBAR_ITEMS = [
|
|
30
|
+
[
|
|
31
|
+
{ kind: "mark", mark: "bold", icon: "i-lucide-bold", tooltip: { text: "Bold" } },
|
|
32
|
+
{ kind: "mark", mark: "italic", icon: "i-lucide-italic", tooltip: { text: "Italic" } },
|
|
33
|
+
{ kind: "mark", mark: "underline", icon: "i-lucide-underline", tooltip: { text: "Underline" } },
|
|
34
|
+
{ kind: "mark", mark: "strike", icon: "i-lucide-strikethrough", tooltip: { text: "Strikethrough" } },
|
|
35
|
+
{ kind: "mark", mark: "code", icon: "i-lucide-code", tooltip: { text: "Code" } }
|
|
36
|
+
],
|
|
37
|
+
[
|
|
38
|
+
{ kind: "link", icon: "i-lucide-link", tooltip: { text: "Link" } }
|
|
39
|
+
]
|
|
40
|
+
];
|
|
41
|
+
const DEFAULT_SUGGESTION_MENU_ITEMS = [
|
|
42
|
+
[
|
|
43
|
+
{ kind: "paragraph", label: "Paragraph", icon: "i-lucide-type" },
|
|
44
|
+
{ kind: "heading", level: 1, label: "Heading 1", icon: "i-lucide-heading-1" },
|
|
45
|
+
{ kind: "heading", level: 2, label: "Heading 2", icon: "i-lucide-heading-2" },
|
|
46
|
+
{ kind: "heading", level: 3, label: "Heading 3", icon: "i-lucide-heading-3" },
|
|
47
|
+
{ kind: "bulletList", label: "Bullet List", icon: "i-lucide-list" },
|
|
48
|
+
{ kind: "orderedList", label: "Numbered List", icon: "i-lucide-list-ordered" },
|
|
49
|
+
{ kind: "blockquote", label: "Blockquote", icon: "i-lucide-text-quote" },
|
|
50
|
+
{ kind: "codeBlock", label: "Code Block", icon: "i-lucide-square-code" },
|
|
51
|
+
{ kind: "horizontalRule", label: "Horizontal Rule", icon: "i-lucide-separator-horizontal" }
|
|
52
|
+
]
|
|
53
|
+
];
|
|
54
|
+
function bubbleToolbarShouldShow({ view, state }) {
|
|
55
|
+
return view.hasFocus() && !state.selection.empty;
|
|
56
|
+
}
|
|
57
|
+
const props = defineProps({
|
|
58
|
+
context: {
|
|
59
|
+
type: Object,
|
|
60
|
+
required: true
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
const { handleInput, styleClass, modelValue } = useFormKitInput(props.context);
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<template>
|
|
67
|
+
<UEditor
|
|
68
|
+
:id="context.id"
|
|
69
|
+
v-model="modelValue"
|
|
70
|
+
v-bind="{ ...context?.attrs }"
|
|
71
|
+
:class="styleClass"
|
|
72
|
+
:editable="!context?.disabled"
|
|
73
|
+
:style="context?.attrs.style"
|
|
74
|
+
:content-type="context.contentType"
|
|
75
|
+
:starter-kit="context.starterKit"
|
|
76
|
+
:placeholder="context.placeholder"
|
|
77
|
+
:markdown="context.markdown"
|
|
78
|
+
:image="context.image"
|
|
79
|
+
:mention="context.mention"
|
|
80
|
+
:handlers="context.editorHandlers"
|
|
81
|
+
:extensions="context.extensions"
|
|
82
|
+
:autofocus="context.autofocus"
|
|
83
|
+
:ui="context.ui"
|
|
84
|
+
@update:model-value="handleInput"
|
|
85
|
+
>
|
|
86
|
+
<template #default="{ editor, handlers }">
|
|
87
|
+
<UEditorToolbar
|
|
88
|
+
v-if="context.toolbar !== false"
|
|
89
|
+
:editor="editor"
|
|
90
|
+
:items="context.toolbarItems ?? DEFAULT_EDITOR_TOOLBAR_ITEMS"
|
|
91
|
+
class="border-b border-default px-2 py-1 mb-2 flex-wrap"
|
|
92
|
+
/>
|
|
93
|
+
<UEditorToolbar
|
|
94
|
+
v-if="context.bubbleToolbar !== false"
|
|
95
|
+
:editor="editor"
|
|
96
|
+
:items="context.bubbleToolbarItems ?? DEFAULT_BUBBLE_TOOLBAR_ITEMS"
|
|
97
|
+
layout="bubble"
|
|
98
|
+
:should-show="bubbleToolbarShouldShow"
|
|
99
|
+
/>
|
|
100
|
+
<UEditorDragHandle
|
|
101
|
+
v-if="context.dragHandle"
|
|
102
|
+
:editor="editor"
|
|
103
|
+
/>
|
|
104
|
+
<UEditorSuggestionMenu
|
|
105
|
+
v-if="context.suggestionMenu"
|
|
106
|
+
:editor="editor"
|
|
107
|
+
:items="context.suggestionMenuItems ?? DEFAULT_SUGGESTION_MENU_ITEMS"
|
|
108
|
+
/>
|
|
109
|
+
<UEditorMentionMenu
|
|
110
|
+
v-if="context.mentionItems?.length"
|
|
111
|
+
:editor="editor"
|
|
112
|
+
:items="context.mentionItems"
|
|
113
|
+
/>
|
|
114
|
+
<component
|
|
115
|
+
:is="context.slots.default"
|
|
116
|
+
v-if="context?.slots?.default"
|
|
117
|
+
v-bind="{ ...context, editor, handlers }"
|
|
118
|
+
/>
|
|
119
|
+
</template>
|
|
120
|
+
</UEditor>
|
|
121
|
+
</template>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
import type { AnyExtension } from '@tiptap/core';
|
|
3
|
+
import type { PropType } from 'vue';
|
|
4
|
+
export interface FormKitEditorHandler {
|
|
5
|
+
canExecute: (editor: unknown, cmd?: unknown) => boolean;
|
|
6
|
+
execute: (editor: unknown, cmd?: unknown) => unknown;
|
|
7
|
+
isActive: (editor: unknown, cmd?: unknown) => boolean;
|
|
8
|
+
isDisabled?: (editor: unknown, cmd?: unknown) => boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface FormKitEditorItem {
|
|
11
|
+
kind: string;
|
|
12
|
+
icon?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
tooltip?: Record<string, unknown>;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
export interface FormKitEditorSuggestionItem extends FormKitEditorItem {
|
|
18
|
+
label: string;
|
|
19
|
+
}
|
|
20
|
+
export interface FormKitEditorMentionItem {
|
|
21
|
+
label: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
icon?: string;
|
|
24
|
+
avatar?: Record<string, unknown>;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface FormKitEditorProps {
|
|
29
|
+
contentType?: 'json' | 'html' | 'markdown';
|
|
30
|
+
starterKit?: Record<string, unknown>;
|
|
31
|
+
placeholder?: string | Record<string, unknown>;
|
|
32
|
+
markdown?: Record<string, unknown>;
|
|
33
|
+
image?: boolean | Record<string, unknown>;
|
|
34
|
+
mention?: boolean | Record<string, unknown>;
|
|
35
|
+
editorHandlers?: Record<string, FormKitEditorHandler>;
|
|
36
|
+
extensions?: AnyExtension[];
|
|
37
|
+
autofocus?: boolean;
|
|
38
|
+
toolbar?: boolean;
|
|
39
|
+
toolbarItems?: FormKitEditorItem[] | FormKitEditorItem[][];
|
|
40
|
+
bubbleToolbar?: boolean;
|
|
41
|
+
bubbleToolbarItems?: FormKitEditorItem[] | FormKitEditorItem[][];
|
|
42
|
+
dragHandle?: boolean;
|
|
43
|
+
suggestionMenu?: boolean;
|
|
44
|
+
suggestionMenuItems?: FormKitEditorSuggestionItem[] | FormKitEditorSuggestionItem[][];
|
|
45
|
+
mentionItems?: FormKitEditorMentionItem[];
|
|
46
|
+
ui?: Record<string, unknown>;
|
|
47
|
+
}
|
|
48
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
49
|
+
context: {
|
|
50
|
+
type: PropType<FormKitFrameworkContext & FormKitEditorProps>;
|
|
51
|
+
required: true;
|
|
52
|
+
};
|
|
53
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
54
|
+
context: {
|
|
55
|
+
type: PropType<FormKitFrameworkContext & FormKitEditorProps>;
|
|
56
|
+
required: true;
|
|
57
|
+
};
|
|
58
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
59
|
+
declare const _default: typeof __VLS_export;
|
|
60
|
+
export default _default;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { FormKitFrameworkContext } from '@formkit/core';
|
|
2
|
+
import type { PropType } from 'vue';
|
|
3
|
+
export interface FormKitFileUploadProps {
|
|
4
|
+
multiple?: boolean;
|
|
5
|
+
accept?: string;
|
|
6
|
+
icon?: string | false;
|
|
7
|
+
label?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
color?: 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'neutral';
|
|
10
|
+
variant?: 'area' | 'button';
|
|
11
|
+
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
12
|
+
layout?: 'list' | 'grid';
|
|
13
|
+
position?: 'inside' | 'outside';
|
|
14
|
+
highlight?: boolean;
|
|
15
|
+
dropzone?: boolean;
|
|
16
|
+
interactive?: boolean;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
reset?: boolean;
|
|
19
|
+
fileIcon?: string;
|
|
20
|
+
fileImage?: boolean;
|
|
21
|
+
fileDelete?: boolean | Record<string, unknown>;
|
|
22
|
+
fileDeleteIcon?: string;
|
|
23
|
+
preview?: boolean;
|
|
24
|
+
name?: string;
|
|
25
|
+
ui?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
28
|
+
context: {
|
|
29
|
+
type: PropType<FormKitFrameworkContext & FormKitFileUploadProps>;
|
|
30
|
+
required: true;
|
|
31
|
+
};
|
|
32
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
33
|
+
context: {
|
|
34
|
+
type: PropType<FormKitFrameworkContext & FormKitFileUploadProps>;
|
|
35
|
+
required: true;
|
|
36
|
+
};
|
|
37
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
38
|
+
declare const _default: typeof __VLS_export;
|
|
39
|
+
export default _default;
|