nuxt-ui-tools 1.17.1 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -0
- package/dist/runtime/form/components/page/form-page-header.d.vue.ts +3 -1
- package/dist/runtime/form/components/page/form-page-header.vue +44 -34
- package/dist/runtime/form/components/page/form-page-header.vue.d.ts +3 -1
- package/dist/runtime/form/components/page/form-page-navigation.d.vue.ts +5 -3
- package/dist/runtime/form/components/page/form-page-navigation.vue +6 -3
- package/dist/runtime/form/components/page/form-page-navigation.vue.d.ts +5 -3
- package/dist/runtime/form/components/page/form-page-section.vue +6 -5
- package/dist/runtime/form/components/page/form-page-sections.d.vue.ts +4 -3
- package/dist/runtime/form/components/page/form-page-sections.vue +7 -2
- package/dist/runtime/form/components/page/form-page-sections.vue.d.ts +4 -3
- package/dist/runtime/form/components/page/form-page.d.vue.ts +2 -0
- package/dist/runtime/form/components/page/form-page.vue +11 -2
- package/dist/runtime/form/components/page/form-page.vue.d.ts +2 -0
- package/dist/runtime/form/components/renderer/form-field-renderer.vue +6 -4
- package/dist/runtime/form/components/renderer/form-field-shell.d.vue.ts +4 -4
- package/dist/runtime/form/components/renderer/form-field-shell.vue +28 -4
- package/dist/runtime/form/components/renderer/form-field-shell.vue.d.ts +4 -4
- package/dist/runtime/form/components/root/form.vue +2 -2
- package/dist/runtime/form/components/utils/form-option-choice-label.d.vue.ts +16 -0
- package/dist/runtime/form/components/utils/form-option-choice-label.vue +37 -0
- package/dist/runtime/form/components/utils/form-option-choice-label.vue.d.ts +16 -0
- package/dist/runtime/form/components/utils/form-option-display-value.d.vue.ts +14 -0
- package/dist/runtime/form/components/utils/form-option-display-value.vue +20 -0
- package/dist/runtime/form/components/utils/form-option-display-value.vue.d.ts +14 -0
- package/dist/runtime/form/components/utils/form-option-item-label.d.vue.ts +9 -2
- package/dist/runtime/form/components/utils/form-option-item-label.vue +20 -13
- package/dist/runtime/form/components/utils/form-option-item-label.vue.d.ts +9 -2
- package/dist/runtime/form/components/utils/form-option-leading.d.vue.ts +23 -0
- package/dist/runtime/form/components/utils/form-option-leading.vue +41 -0
- package/dist/runtime/form/components/utils/form-option-leading.vue.d.ts +23 -0
- package/dist/runtime/form/components/utils/form-option-render.d.ts +11 -0
- package/dist/runtime/form/components/utils/form-option-render.js +5 -0
- package/dist/runtime/form/components/utils/form-option-suffix.d.vue.ts +8 -0
- package/dist/runtime/form/components/utils/form-option-suffix.vue +15 -0
- package/dist/runtime/form/components/utils/form-option-suffix.vue.d.ts +8 -0
- package/dist/runtime/form/components/utils/form-option-value-overlay.d.vue.ts +30 -0
- package/dist/runtime/form/components/utils/form-option-value-overlay.vue +44 -0
- package/dist/runtime/form/components/utils/form-option-value-overlay.vue.d.ts +30 -0
- package/dist/runtime/form/composables/use-choice-group-items.d.ts +27 -0
- package/dist/runtime/form/composables/use-choice-group-items.js +24 -0
- package/dist/runtime/form/composables/use-field-control.d.ts +6 -6
- package/dist/runtime/form/composables/use-field-control.js +9 -21
- package/dist/runtime/form/composables/use-field-options.js +8 -4
- package/dist/runtime/form/composables/use-form-layout.js +4 -3
- package/dist/runtime/form/composables/use-form-page.d.ts +11 -1
- package/dist/runtime/form/composables/use-form-page.js +12 -6
- package/dist/runtime/form/composables/use-form-runtime.js +1 -1
- package/dist/runtime/form/composables/use-option-menu.d.ts +20 -0
- package/dist/runtime/form/composables/use-option-menu.js +41 -0
- package/dist/runtime/form/fields/array-primitive/types.d.ts +1 -1
- package/dist/runtime/form/fields/auto-complete/component.vue +92 -51
- package/dist/runtime/form/fields/auto-complete/config.d.ts +1 -0
- package/dist/runtime/form/fields/auto-complete/config.js +1 -1
- package/dist/runtime/form/fields/auto-complete/types.d.ts +2 -2
- package/dist/runtime/form/fields/checkbox-card/component.vue +55 -29
- package/dist/runtime/form/fields/checkbox-card/config.d.ts +1 -0
- package/dist/runtime/form/fields/checkbox-card/config.js +1 -1
- package/dist/runtime/form/fields/checkbox-card/types.d.ts +3 -3
- package/dist/runtime/form/fields/checkbox-group/component.vue +18 -4
- package/dist/runtime/form/fields/checkbox-group/types.d.ts +2 -2
- package/dist/runtime/form/fields/choice-card/choice-card-label.d.vue.ts +7 -0
- package/dist/runtime/form/fields/choice-card/choice-card-label.vue +27 -1
- package/dist/runtime/form/fields/choice-card/choice-card-label.vue.d.ts +7 -0
- package/dist/runtime/form/fields/choice-card/types.d.ts +35 -1
- package/dist/runtime/form/fields/choice-card/use-choice-card.d.ts +7 -3
- package/dist/runtime/form/fields/choice-card/use-choice-card.js +37 -15
- package/dist/runtime/form/fields/choice-card/utils.d.ts +10 -0
- package/dist/runtime/form/fields/choice-card/utils.js +6 -0
- package/dist/runtime/form/fields/hierarchy/component.vue +3 -2
- package/dist/runtime/form/fields/index.d.ts +4 -0
- package/dist/runtime/form/fields/radio/component.vue +19 -2
- package/dist/runtime/form/fields/radio/types.d.ts +2 -2
- package/dist/runtime/form/fields/radio-card/component.vue +58 -28
- package/dist/runtime/form/fields/radio-card/config.d.ts +1 -0
- package/dist/runtime/form/fields/radio-card/config.js +1 -1
- package/dist/runtime/form/fields/radio-card/types.d.ts +3 -3
- package/dist/runtime/form/fields/select/component.vue +56 -58
- package/dist/runtime/form/fields/select/config.d.ts +1 -0
- package/dist/runtime/form/fields/select/config.js +1 -1
- package/dist/runtime/form/fields/select/types.d.ts +2 -2
- package/dist/runtime/form/types/field-base.d.ts +6 -0
- package/dist/runtime/form/types/field-kind.d.ts +3 -1
- package/dist/runtime/form/types/field.d.ts +1 -0
- package/dist/runtime/form/types/layout.d.ts +6 -0
- package/dist/runtime/form/types/options.d.ts +137 -0
- package/dist/runtime/form/types/page.d.ts +20 -8
- package/dist/runtime/form/types/ui.d.ts +29 -4
- package/dist/runtime/form/utils/disabled.d.ts +11 -0
- package/dist/runtime/form/utils/disabled.js +11 -0
- package/dist/runtime/form/utils/field-instance.js +3 -0
- package/dist/runtime/form/utils/options.d.ts +56 -11
- package/dist/runtime/form/utils/options.js +86 -0
- package/dist/runtime/form/utils/page-surface.d.ts +26 -0
- package/dist/runtime/form/utils/page-surface.js +28 -0
- package/dist/runtime/form/utils/page.d.ts +21 -1
- package/dist/runtime/form/utils/page.js +24 -2
- package/dist/runtime/i18n/locales/en.js +28 -8
- package/dist/runtime/i18n/locales/fr.js +28 -8
- package/dist/runtime/i18n/types.d.ts +46 -7
- package/dist/runtime/spreadsheet/components/internal/spreadsheet-import-column-row.d.vue.ts +2 -2
- package/dist/runtime/spreadsheet/components/internal/spreadsheet-import-column-row.vue.d.ts +2 -2
- package/dist/runtime/table/components/actions/row-actions.d.vue.ts +2 -0
- package/dist/runtime/table/components/actions/row-actions.vue +8 -3
- package/dist/runtime/table/components/actions/row-actions.vue.d.ts +2 -0
- package/dist/runtime/table/components/data-list/data-list-content.vue +7 -1
- package/dist/runtime/table/components/data-list/data-list-default.d.vue.ts +16 -16
- package/dist/runtime/table/components/data-list/data-list-default.vue +3 -0
- package/dist/runtime/table/components/data-list/data-list-default.vue.d.ts +16 -16
- package/dist/runtime/table/components/data-list/data-list-layout-switch.vue +7 -9
- package/dist/runtime/table/components/data-list/data-list-root.vue +5 -6
- package/dist/runtime/table/components/data-list/data-list-sort-menu.vue +3 -1
- package/dist/runtime/table/components/data-list/data-list-table.d.vue.ts +8 -1
- package/dist/runtime/table/components/data-list/data-list-table.vue +18 -1
- package/dist/runtime/table/components/data-list/data-list-table.vue.d.ts +8 -1
- package/dist/runtime/table/components/data-list/data-list-view-toggle.d.vue.ts +25 -0
- package/dist/runtime/table/components/data-list/data-list-view-toggle.vue +57 -0
- package/dist/runtime/table/components/data-list/data-list-view-toggle.vue.d.ts +25 -0
- package/dist/runtime/table/components/data-list/sort-menu-panel.vue +1 -1
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/boolean-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/date-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/date-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/number-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/number-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/option-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/option-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/filters/tags/text-filter-tag.d.vue.ts +2 -2
- package/dist/runtime/table/components/filters/tags/text-filter-tag.vue.d.ts +2 -2
- package/dist/runtime/table/components/layout/table-footer.d.vue.ts +6 -4
- package/dist/runtime/table/components/layout/table-footer.vue +80 -3
- package/dist/runtime/table/components/layout/table-footer.vue.d.ts +6 -4
- package/dist/runtime/table/components/summary/summary-content.d.ts +13 -0
- package/dist/runtime/table/components/summary/summary-content.js +5 -0
- package/dist/runtime/table/components/summary/summary-renderer.d.vue.ts +31 -0
- package/dist/runtime/table/components/summary/summary-renderer.vue +282 -0
- package/dist/runtime/table/components/summary/summary-renderer.vue.d.ts +31 -0
- package/dist/runtime/table/components/summary/summary-row.d.vue.ts +19 -0
- package/dist/runtime/table/components/summary/summary-row.vue +102 -0
- package/dist/runtime/table/components/summary/summary-row.vue.d.ts +19 -0
- package/dist/runtime/table/components/table/table-empty-state.vue +39 -9
- package/dist/runtime/table/components/table/table-renderer.vue +1 -1
- package/dist/runtime/table/components/table/table-row-actions-control.vue +10 -6
- package/dist/runtime/table/components/table/table-selection-control.d.vue.ts +5 -1
- package/dist/runtime/table/components/table/table-selection-control.vue +17 -4
- package/dist/runtime/table/components/table/table-selection-control.vue.d.ts +5 -1
- package/dist/runtime/table/components/table/table-tree-control.vue +2 -1
- package/dist/runtime/table/components/table/table-tree-header.vue +0 -1
- package/dist/runtime/table/composables/use-table-api.d.ts +2 -0
- package/dist/runtime/table/composables/use-table-api.js +8 -0
- package/dist/runtime/table/composables/use-table-columns.d.ts +2 -0
- package/dist/runtime/table/composables/use-table-controls.d.ts +6 -0
- package/dist/runtime/table/composables/use-table-controls.js +6 -3
- package/dist/runtime/table/composables/use-table-internals.d.ts +33 -0
- package/dist/runtime/table/composables/use-table-internals.js +9 -0
- package/dist/runtime/table/composables/use-table-row-labels.d.ts +16 -0
- package/dist/runtime/table/composables/use-table-row-labels.js +22 -0
- package/dist/runtime/table/composables/use-table-row-summary.d.ts +18 -0
- package/dist/runtime/table/composables/use-table-row-summary.js +41 -0
- package/dist/runtime/table/constants/mobile.d.ts +79 -0
- package/dist/runtime/table/constants/mobile.js +17 -0
- package/dist/runtime/table/constants/summary.d.ts +67 -0
- package/dist/runtime/table/constants/summary.js +31 -0
- package/dist/runtime/table/types/data-list.d.ts +58 -8
- package/dist/runtime/table/types/layout.d.ts +73 -0
- package/dist/runtime/table/types/remote-options.d.ts +4 -1
- package/dist/runtime/table/types/schema.d.ts +9 -1
- package/dist/runtime/table/types/table-api.d.ts +12 -0
- package/dist/runtime/table/utils/columns/defs.js +3 -1
- package/dist/runtime/table/utils/columns/render.d.ts +2 -0
- package/dist/runtime/table/utils/columns/render.js +2 -2
- package/dist/runtime/table/utils/data-list-ui.d.ts +1 -1
- package/dist/runtime/table/utils/data-list-ui.js +3 -1
- package/dist/runtime/table/utils/mobile-defaults.d.ts +7 -0
- package/dist/runtime/table/utils/mobile-defaults.js +25 -0
- package/dist/runtime/table/utils/remote-table-options.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,8 @@ import type { FormPageSectionState } from '../types/index.js';
|
|
|
2
2
|
import type { useFormRoot } from './use-form-root.js';
|
|
3
3
|
/**
|
|
4
4
|
* State shared by a form page and its parts: the visible sections and where each stands, the
|
|
5
|
-
* section in view, the navigation summary,
|
|
5
|
+
* section in view, the navigation summary, whether the navigation shows, the surface the
|
|
6
|
+
* sections are drawn with, and the actions a part can take on a section.
|
|
6
7
|
*/
|
|
7
8
|
export declare function useFormPage(params: {
|
|
8
9
|
root: ReturnType<typeof useFormRoot>;
|
|
@@ -19,6 +20,7 @@ export declare function useFormPage(params: {
|
|
|
19
20
|
}[]>;
|
|
20
21
|
modified: import("vue").ComputedRef<number>;
|
|
21
22
|
navigationTitle: import("vue").ComputedRef<string | undefined>;
|
|
23
|
+
navigationVisible: import("vue").ComputedRef<boolean>;
|
|
22
24
|
register: (key: string, element: HTMLElement) => () => void;
|
|
23
25
|
remaining: import("vue").ComputedRef<number>;
|
|
24
26
|
resetSection: (key: string) => Promise<void>;
|
|
@@ -42,6 +44,8 @@ export declare function useFormPage(params: {
|
|
|
42
44
|
scrollTo: (key: string, options?: import("../types/index.js").FormPageScrollOptions) => boolean;
|
|
43
45
|
sections: import("vue").ComputedRef<readonly FormPageSectionState[]>;
|
|
44
46
|
stickyOffset: import("vue").Ref<number, number>;
|
|
47
|
+
surface: import("vue").ComputedRef<import("../types/index.js").FormPageSurface>;
|
|
48
|
+
surfaceClasses: import("vue").ComputedRef<import("../utils/page-surface.js").FormPageSurfaceClasses>;
|
|
45
49
|
};
|
|
46
50
|
export declare function provideFormPage(page: ReturnType<typeof useFormPage>): {
|
|
47
51
|
active: import("vue").Ref<string | undefined, string | undefined>;
|
|
@@ -53,6 +57,7 @@ export declare function provideFormPage(page: ReturnType<typeof useFormPage>): {
|
|
|
53
57
|
}[]>;
|
|
54
58
|
modified: import("vue").ComputedRef<number>;
|
|
55
59
|
navigationTitle: import("vue").ComputedRef<string | undefined>;
|
|
60
|
+
navigationVisible: import("vue").ComputedRef<boolean>;
|
|
56
61
|
register: (key: string, element: HTMLElement) => () => void;
|
|
57
62
|
remaining: import("vue").ComputedRef<number>;
|
|
58
63
|
resetSection: (key: string) => Promise<void>;
|
|
@@ -76,6 +81,8 @@ export declare function provideFormPage(page: ReturnType<typeof useFormPage>): {
|
|
|
76
81
|
scrollTo: (key: string, options?: import("../types/index.js").FormPageScrollOptions) => boolean;
|
|
77
82
|
sections: import("vue").ComputedRef<readonly FormPageSectionState[]>;
|
|
78
83
|
stickyOffset: import("vue").Ref<number, number>;
|
|
84
|
+
surface: import("vue").ComputedRef<import("../types/index.js").FormPageSurface>;
|
|
85
|
+
surfaceClasses: import("vue").ComputedRef<import("../utils/page-surface.js").FormPageSurfaceClasses>;
|
|
79
86
|
};
|
|
80
87
|
/** The page a part renders in. Parts only work inside `FormPage`. */
|
|
81
88
|
export declare function useFormPageContext(): {
|
|
@@ -88,6 +95,7 @@ export declare function useFormPageContext(): {
|
|
|
88
95
|
}[]>;
|
|
89
96
|
modified: import("vue").ComputedRef<number>;
|
|
90
97
|
navigationTitle: import("vue").ComputedRef<string | undefined>;
|
|
98
|
+
navigationVisible: import("vue").ComputedRef<boolean>;
|
|
91
99
|
register: (key: string, element: HTMLElement) => () => void;
|
|
92
100
|
remaining: import("vue").ComputedRef<number>;
|
|
93
101
|
resetSection: (key: string) => Promise<void>;
|
|
@@ -111,4 +119,6 @@ export declare function useFormPageContext(): {
|
|
|
111
119
|
scrollTo: (key: string, options?: import("../types/index.js").FormPageScrollOptions) => boolean;
|
|
112
120
|
sections: import("vue").ComputedRef<readonly FormPageSectionState[]>;
|
|
113
121
|
stickyOffset: import("vue").Ref<number, number>;
|
|
122
|
+
surface: import("vue").ComputedRef<import("../types/index.js").FormPageSurface>;
|
|
123
|
+
surfaceClasses: import("vue").ComputedRef<import("../utils/page-surface.js").FormPageSurfaceClasses>;
|
|
114
124
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { computed, inject, provide, ref } from "vue";
|
|
2
2
|
import { getSchemaDirtyCheck } from "../utils/controls.js";
|
|
3
3
|
import {
|
|
4
|
+
getFormPageNavigationMinSections,
|
|
4
5
|
getFormPageNavigationTitle,
|
|
5
6
|
getFormPageSections,
|
|
7
|
+
isFormPageSectionBlocking,
|
|
6
8
|
isFormPageSectionVisible,
|
|
7
9
|
resolveFormPageSectionState
|
|
8
10
|
} from "../utils/page.js";
|
|
11
|
+
import { getFormPageSurfaceClasses, resolveFormPageSurface } from "../utils/page-surface.js";
|
|
9
12
|
import { cloneFormValue } from "../utils/path.js";
|
|
10
13
|
import { useFormPageScroll } from "./use-form-page-scroll.js";
|
|
11
14
|
export function useFormPage(params) {
|
|
@@ -36,11 +39,11 @@ export function useFormPage(params) {
|
|
|
36
39
|
);
|
|
37
40
|
const dirtyCheck = computed(() => getSchemaDirtyCheck(root.schema.value));
|
|
38
41
|
const navigationTitle = computed(() => getFormPageNavigationTitle(root.schema.value));
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
);
|
|
42
|
+
const navigationMinSections = computed(() => getFormPageNavigationMinSections(root.schema.value));
|
|
43
|
+
const navigationVisible = computed(() => sections.value.length >= navigationMinSections.value);
|
|
44
|
+
const surface = computed(() => resolveFormPageSurface(root.formUi.ui.value.page?.surface));
|
|
45
|
+
const surfaceClasses = computed(() => getFormPageSurfaceClasses(surface.value));
|
|
46
|
+
const remaining = computed(() => sections.value.filter(isFormPageSectionBlocking).length);
|
|
44
47
|
const modified = computed(() => sections.value.filter((section) => section.dirty).length);
|
|
45
48
|
const stickyOffset = ref(0);
|
|
46
49
|
const scroll = useFormPageScroll({ hash: params.hash, root: params.element, sections });
|
|
@@ -62,13 +65,16 @@ export function useFormPage(params) {
|
|
|
62
65
|
items,
|
|
63
66
|
modified,
|
|
64
67
|
navigationTitle,
|
|
68
|
+
navigationVisible,
|
|
65
69
|
register: scroll.register,
|
|
66
70
|
remaining,
|
|
67
71
|
resetSection,
|
|
68
72
|
root,
|
|
69
73
|
scrollTo: scroll.scrollTo,
|
|
70
74
|
sections,
|
|
71
|
-
stickyOffset
|
|
75
|
+
stickyOffset,
|
|
76
|
+
surface,
|
|
77
|
+
surfaceClasses
|
|
72
78
|
};
|
|
73
79
|
}
|
|
74
80
|
const formPageKey = Symbol("nuxt-ui-tools-form-page");
|
|
@@ -221,7 +221,7 @@ export function useFormRuntime(params) {
|
|
|
221
221
|
active: currentStepIndex.value === index,
|
|
222
222
|
index,
|
|
223
223
|
key: step.key ?? String(index + 1),
|
|
224
|
-
label: isFunction(step.title) ? String(step.title()) : String(step.title ?? step.key ??
|
|
224
|
+
label: isFunction(step.title) ? String(step.title()) : String(step.title ?? step.key ?? t("form.steps.fallback", { number: index + 1 })),
|
|
225
225
|
root: step.root
|
|
226
226
|
}))
|
|
227
227
|
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FormAutoCompleteField, FormOptionRuntimeState, FormOptionValue, FormSelectField, ResolvedFormOption } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* What the select and the auto-complete share around the options they list in a Nuxt UI menu: the
|
|
4
|
+
* menu items (grouped when the options carry headings), which option is selected, and the option
|
|
5
|
+
* the closed control shows with its leading visual and its custom value.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useOptionMenu(params: {
|
|
8
|
+
field: () => FormSelectField | FormAutoCompleteField;
|
|
9
|
+
model: () => FormOptionValue | readonly FormOptionValue[] | null | undefined;
|
|
10
|
+
multiple: () => boolean;
|
|
11
|
+
options: FormOptionRuntimeState;
|
|
12
|
+
loadMoreLabel: () => string;
|
|
13
|
+
}): {
|
|
14
|
+
customValueOption: import("vue").ComputedRef<ResolvedFormOption | undefined>;
|
|
15
|
+
isSelected: (option: ResolvedFormOption) => boolean;
|
|
16
|
+
items: import("vue").ComputedRef<import("../utils/options.js").OptionMenuItem[] | import("../utils/options.js").OptionMenuItem[][]>;
|
|
17
|
+
leadingOption: import("vue").ComputedRef<ResolvedFormOption | undefined>;
|
|
18
|
+
renderOption: import("vue").ComputedRef<((context: import("../types/index.js").FormOptionRenderContext<import("../types/index.js").FormOptionItem<FormOptionValue>>) => import("vue").VNodeChild) | undefined>;
|
|
19
|
+
renderValue: import("vue").ComputedRef<((context: import("../types/index.js").FormOptionValueRenderContext<import("../types/index.js").FormOptionItem<FormOptionValue>>) => import("vue").VNodeChild) | undefined>;
|
|
20
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { formOptionKey, resolveOptionLeading, toMenuItems } from "../utils/options.js";
|
|
3
|
+
export function useOptionMenu(params) {
|
|
4
|
+
const renderOption = computed(() => params.field().renderOption);
|
|
5
|
+
const renderValue = computed(() => params.field().renderValue);
|
|
6
|
+
const items = computed(
|
|
7
|
+
() => toMenuItems(params.options.items.value, {
|
|
8
|
+
label: params.loadMoreLabel(),
|
|
9
|
+
show: params.options.remote.value && (params.options.hasMore.value || params.options.loadingMore.value)
|
|
10
|
+
})
|
|
11
|
+
);
|
|
12
|
+
const selectedKeys = computed(() => {
|
|
13
|
+
const model = params.model();
|
|
14
|
+
const values = Array.isArray(model) ? model : [model];
|
|
15
|
+
return new Set(
|
|
16
|
+
values.filter((value) => value !== null && value !== void 0).map(formOptionKey)
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
const valueOption = computed(
|
|
20
|
+
() => params.multiple() ? void 0 : params.options.selectedItems.value[0]
|
|
21
|
+
);
|
|
22
|
+
const leadingOption = computed(() => {
|
|
23
|
+
const option = valueOption.value;
|
|
24
|
+
return option && !renderValue.value && resolveOptionLeading(option) ? option : void 0;
|
|
25
|
+
});
|
|
26
|
+
const customValueOption = computed(() => {
|
|
27
|
+
const option = valueOption.value;
|
|
28
|
+
return option && (renderValue.value || option.suffix) ? option : void 0;
|
|
29
|
+
});
|
|
30
|
+
function isSelected(option) {
|
|
31
|
+
return selectedKeys.value.has(formOptionKey(option.value));
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
customValueOption,
|
|
35
|
+
isSelected,
|
|
36
|
+
items,
|
|
37
|
+
leadingOption,
|
|
38
|
+
renderOption,
|
|
39
|
+
renderValue
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -5,7 +5,7 @@ import type { FormStatefulFieldBase } from '../../types/field-base.js';
|
|
|
5
5
|
import type { ResolveFormFieldValue } from '../../types/field-output.js';
|
|
6
6
|
import type { FormObject, FormRenderable, FormText } from '../../types/utils.js';
|
|
7
7
|
type ContainerFieldType = 'array-list' | 'array-table' | 'array-tabs' | 'array-variant' | 'array-collapse' | 'array-primitive' | 'object' | 'group' | 'input-group' | 'card' | 'column' | 'matrix' | 'info' | 'divider' | 'section' | 'button' | 'hidden';
|
|
8
|
-
type ItemFieldChrome = 'key' | 'label' | 'description' | 'hint' | 'help' | 'labelExtra' | 'layout';
|
|
8
|
+
type ItemFieldChrome = 'key' | 'label' | 'description' | 'hint' | 'help' | 'disabledReason' | 'labelExtra' | 'layout';
|
|
9
9
|
type DistributiveOmit<TValue, TKey extends PropertyKey> = TValue extends unknown ? Omit<TValue, TKey> : never;
|
|
10
10
|
export type FormArrayPrimitiveItemField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>> = DistributiveOmit<Exclude<FormField<TContext, TDeps>, {
|
|
11
11
|
type: ContainerFieldType;
|
|
@@ -4,9 +4,12 @@ import { computed, ref, watch } from "vue";
|
|
|
4
4
|
import { useUiToolsLocale } from "../../../i18n/use-locale";
|
|
5
5
|
import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
6
6
|
import FormOptionItemLabel from "../../components/utils/form-option-item-label.vue";
|
|
7
|
+
import FormOptionLeading from "../../components/utils/form-option-leading.vue";
|
|
7
8
|
import FormOptionMenuFooter from "../../components/utils/form-option-menu-footer.vue";
|
|
9
|
+
import FormOptionSuffix from "../../components/utils/form-option-suffix.vue";
|
|
10
|
+
import FormOptionValueOverlay from "../../components/utils/form-option-value-overlay.vue";
|
|
8
11
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
9
|
-
import {
|
|
12
|
+
import { useOptionMenu } from "../../composables/use-option-menu";
|
|
10
13
|
import { isBoolean, isNumber, isString } from "../../utils/predicate";
|
|
11
14
|
import { mergeFormUiClass } from "../../utils/ui";
|
|
12
15
|
const props = defineProps({
|
|
@@ -30,6 +33,7 @@ const {
|
|
|
30
33
|
{ omit: ["createItem", "clearable"] }
|
|
31
34
|
);
|
|
32
35
|
const searchTerm = ref("");
|
|
36
|
+
const open = ref(false);
|
|
33
37
|
const model = computed({
|
|
34
38
|
get: () => {
|
|
35
39
|
const value = form.getValue(props.path);
|
|
@@ -43,16 +47,27 @@ const model = computed({
|
|
|
43
47
|
},
|
|
44
48
|
set: (value) => form.setValue(props.path, value)
|
|
45
49
|
});
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const menu = useOptionMenu({
|
|
51
|
+
field: () => props.field,
|
|
52
|
+
loadMoreLabel: () => t("form.fields.options.loadingMore"),
|
|
53
|
+
model: () => model.value,
|
|
54
|
+
multiple: () => fieldProps.value.multiple === true,
|
|
55
|
+
options
|
|
56
|
+
});
|
|
57
|
+
const overlayActive = computed(
|
|
58
|
+
() => menu.customValueOption.value !== void 0 && !open.value && searchTerm.value === ""
|
|
59
|
+
);
|
|
53
60
|
const controlUi = computed(() => ({
|
|
54
61
|
...controlProps.value.ui,
|
|
55
|
-
|
|
62
|
+
base: mergeFormUiClass(
|
|
63
|
+
controlProps.value.ui?.base,
|
|
64
|
+
overlayActive.value ? "text-transparent" : void 0
|
|
65
|
+
),
|
|
66
|
+
content: mergeFormUiClass(controlProps.value.ui?.content, interactionOwnerClass.value),
|
|
67
|
+
itemDescription: mergeFormUiClass(
|
|
68
|
+
menu.renderOption.value ? "hidden" : "text-[12.5px]",
|
|
69
|
+
controlProps.value.ui?.itemDescription
|
|
70
|
+
)
|
|
56
71
|
}));
|
|
57
72
|
const createItem = computed(
|
|
58
73
|
() => options.creatable.value && fieldProps.value.createItem ? fieldProps.value.createItem : false
|
|
@@ -68,10 +83,9 @@ watch(searchTerm, (term) => {
|
|
|
68
83
|
options.setSearch(term);
|
|
69
84
|
}
|
|
70
85
|
});
|
|
71
|
-
function handleOpen(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
86
|
+
function handleOpen(next) {
|
|
87
|
+
open.value = next;
|
|
88
|
+
if (next) options.activate();
|
|
75
89
|
}
|
|
76
90
|
async function handleCreate(label) {
|
|
77
91
|
await options.create(label);
|
|
@@ -93,47 +107,74 @@ function isOptionValue(value) {
|
|
|
93
107
|
|
|
94
108
|
<template>
|
|
95
109
|
<FormFieldShell :field="field" :path="path">
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
<FormOptionValueOverlay
|
|
111
|
+
:option="menu.customValueOption.value"
|
|
112
|
+
:render="menu.renderValue.value"
|
|
113
|
+
:active="overlayActive"
|
|
114
|
+
>
|
|
115
|
+
<UInputMenu
|
|
116
|
+
v-model="model"
|
|
117
|
+
v-model:search-term="searchTerm"
|
|
118
|
+
v-bind="controlProps"
|
|
119
|
+
class="w-full"
|
|
120
|
+
value-key="value"
|
|
121
|
+
label-key="label"
|
|
122
|
+
:items="menu.items.value"
|
|
123
|
+
:multiple="fieldProps.multiple"
|
|
124
|
+
:placeholder="placeholder"
|
|
125
|
+
:disabled="disabled"
|
|
126
|
+
:loading="
|
|
108
127
|
validationPending || options.loading.value || options.fetching.value || options.creating.value
|
|
109
128
|
"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
:clear="fieldProps.clearable === true"
|
|
130
|
+
:ignore-filter="options.remote.value"
|
|
131
|
+
:create-item="createItem"
|
|
132
|
+
:ui="controlUi"
|
|
133
|
+
@update:open="handleOpen"
|
|
134
|
+
@create="handleNativeCreate"
|
|
135
|
+
@blur="handleBlur"
|
|
136
|
+
>
|
|
137
|
+
<template #create-item-label="{ item }">
|
|
138
|
+
{{
|
|
139
|
+
options.creating.value ? t("form.fields.options.creating") : t("form.fields.options.createNamed", { label: item })
|
|
140
|
+
}}
|
|
141
|
+
</template>
|
|
142
|
+
|
|
143
|
+
<template v-if="menu.leadingOption.value" #leading="{ ui }">
|
|
144
|
+
<FormOptionLeading
|
|
145
|
+
:option="menu.leadingOption.value"
|
|
146
|
+
:icon-class="ui.leadingIcon()"
|
|
147
|
+
:avatar-size="ui.itemLeadingAvatarSize()"
|
|
148
|
+
chip-class="size-5"
|
|
149
|
+
/>
|
|
150
|
+
</template>
|
|
151
|
+
|
|
152
|
+
<template #item-leading="{ item }">
|
|
153
|
+
<FormOptionLeading :option="menu.renderOption.value ? void 0 : item" />
|
|
154
|
+
</template>
|
|
155
|
+
|
|
156
|
+
<template #item-label="{ item }">
|
|
157
|
+
<FormOptionItemLabel
|
|
158
|
+
:option="item"
|
|
159
|
+
:selected="menu.isSelected(item)"
|
|
160
|
+
:render="menu.renderOption.value"
|
|
161
|
+
/>
|
|
162
|
+
</template>
|
|
123
163
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
164
|
+
<template #item-trailing="{ item }">
|
|
165
|
+
<FormOptionSuffix v-if="!menu.renderOption.value" :option="item" />
|
|
166
|
+
</template>
|
|
127
167
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
168
|
+
<template #content-bottom>
|
|
169
|
+
<FormOptionMenuFooter
|
|
170
|
+
:options="options"
|
|
171
|
+
:disabled="disabled"
|
|
172
|
+
:show-create="showExplicitCreate"
|
|
173
|
+
:create-label="createActionLabel"
|
|
174
|
+
@create="handleCreateAction"
|
|
175
|
+
/>
|
|
176
|
+
</template>
|
|
177
|
+
</UInputMenu>
|
|
178
|
+
</FormOptionValueOverlay>
|
|
138
179
|
</FormFieldShell>
|
|
139
180
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineFormFieldKind } from "../../utils/field-kind.js";
|
|
2
2
|
export const autoCompleteFieldKind = defineFormFieldKind({
|
|
3
3
|
layout: { item: true },
|
|
4
|
-
options: { enabled: true },
|
|
4
|
+
options: { enabled: true, groups: true },
|
|
5
5
|
state: "stateful",
|
|
6
6
|
transform: true,
|
|
7
7
|
type: "auto-complete",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { FormStatefulFieldBase } from '../../types/field-base.js';
|
|
2
2
|
import type { FieldOptionValue, FieldProps, FallbackNever, NullableValue } from '../../types/field-output-utils.js';
|
|
3
|
-
import type { FormAnyOptionConfig, FormOptionItem, FormOptionValue } from '../../types/options.js';
|
|
3
|
+
import type { FormAnyOptionConfig, FormOptionGrouping, FormOptionItem, FormOptionValue, FormOptionValueRenderers } from '../../types/options.js';
|
|
4
4
|
import type { FormSelectCreateItem } from '../select/types.js';
|
|
5
5
|
export interface FormAutoCompleteProps {
|
|
6
6
|
multiple?: boolean;
|
|
7
7
|
clearable?: boolean;
|
|
8
8
|
createItem?: FormSelectCreateItem;
|
|
9
9
|
}
|
|
10
|
-
export interface FormAutoCompleteField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'auto-complete', TValue | readonly TValue[] | null, TContext, TDeps, FormAutoCompleteProps> {
|
|
10
|
+
export interface FormAutoCompleteField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'auto-complete', TValue | readonly TValue[] | null, TContext, TDeps, FormAutoCompleteProps>, FormOptionGrouping, FormOptionValueRenderers<TOption> {
|
|
11
11
|
options: FormAnyOptionConfig<TOption, TContext, TDeps, TValue | readonly TValue[] | null>;
|
|
12
12
|
}
|
|
13
13
|
type AutoCompleteFieldValue<TField> = FieldProps<TField> extends {
|
|
@@ -3,10 +3,11 @@ import UCheckboxGroup from "@nuxt/ui/components/CheckboxGroup.vue";
|
|
|
3
3
|
import { computed } from "vue";
|
|
4
4
|
import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
5
5
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
6
|
-
import { formOptionKey } from "../../utils/options";
|
|
6
|
+
import { formOptionKey, groupOptions } from "../../utils/options";
|
|
7
7
|
import { isBoolean, isNumber, isString, isUndefined } from "../../utils/predicate";
|
|
8
8
|
import ChoiceCardLabel from "../choice-card/choice-card-label.vue";
|
|
9
9
|
import { CHOICE_CARD_PROPS, useChoiceCard } from "../choice-card/use-choice-card";
|
|
10
|
+
import { choiceCardGroupAttrs } from "../choice-card/utils";
|
|
10
11
|
const props = defineProps({
|
|
11
12
|
field: { type: Object, required: true },
|
|
12
13
|
path: { type: Array, required: true }
|
|
@@ -16,7 +17,11 @@ const { fieldProps, form, controlProps, disabled, handleBlur, options } = useFie
|
|
|
16
17
|
() => props.path,
|
|
17
18
|
{ omit: CHOICE_CARD_PROPS }
|
|
18
19
|
);
|
|
19
|
-
const cards = useChoiceCard({
|
|
20
|
+
const cards = useChoiceCard({
|
|
21
|
+
kind: "checkbox",
|
|
22
|
+
props: () => fieldProps.value,
|
|
23
|
+
ui: () => controlProps.value.ui
|
|
24
|
+
});
|
|
20
25
|
const optionByKey = computed(
|
|
21
26
|
() => new Map(options.items.value.map((item) => [formOptionKey(item.value), item]))
|
|
22
27
|
);
|
|
@@ -36,9 +41,20 @@ const model = computed({
|
|
|
36
41
|
const items = computed(
|
|
37
42
|
() => options.items.value.map(({ icon: _icon, ...item }) => ({
|
|
38
43
|
...item,
|
|
44
|
+
description: cards.compact.value ? void 0 : item.description,
|
|
39
45
|
value: formOptionKey(item.value)
|
|
40
46
|
}))
|
|
41
47
|
);
|
|
48
|
+
const groups = computed(() => groupOptions(items.value));
|
|
49
|
+
function selectionOf(group) {
|
|
50
|
+
return model.value.filter((key) => group.items.some((item) => item.value === key));
|
|
51
|
+
}
|
|
52
|
+
function update(group, keys) {
|
|
53
|
+
const kept = model.value.filter(
|
|
54
|
+
(key) => keys.includes(key) || !group.items.some((item) => item.value === key)
|
|
55
|
+
);
|
|
56
|
+
model.value = [...kept, ...keys.filter((key) => !kept.includes(key))];
|
|
57
|
+
}
|
|
42
58
|
function isOptionValue(value) {
|
|
43
59
|
return isString(value) || isNumber(value) || isBoolean(value);
|
|
44
60
|
}
|
|
@@ -46,32 +62,42 @@ function isOptionValue(value) {
|
|
|
46
62
|
|
|
47
63
|
<template>
|
|
48
64
|
<FormFieldShell :field="field" :path="path">
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
65
|
+
<div :class="cards.groupsClass.value">
|
|
66
|
+
<UCheckboxGroup
|
|
67
|
+
v-for="(group, index) in groups"
|
|
68
|
+
:key="group.key"
|
|
69
|
+
:model-value="selectionOf(group)"
|
|
70
|
+
v-bind="choiceCardGroupAttrs(controlProps, index)"
|
|
71
|
+
:items="group.items"
|
|
72
|
+
value-key="value"
|
|
73
|
+
label-key="label"
|
|
74
|
+
description-key="description"
|
|
75
|
+
variant="card"
|
|
76
|
+
:legend="group.heading"
|
|
77
|
+
:orientation="cards.orientation.value"
|
|
78
|
+
:indicator="cards.indicator.value"
|
|
79
|
+
:ui="cards.ui.value"
|
|
80
|
+
:style="cards.style.value"
|
|
81
|
+
:disabled="disabled"
|
|
82
|
+
@update:model-value="update(group, $event)"
|
|
83
|
+
@blur="handleBlur"
|
|
84
|
+
>
|
|
85
|
+
<template #label="{ item }">
|
|
86
|
+
<ChoiceCardLabel
|
|
87
|
+
:label="optionByKey.get(item.value)?.label ?? item.label"
|
|
88
|
+
:description="
|
|
89
|
+
cards.compact.value ? optionByKey.get(item.value)?.description : void 0
|
|
90
|
+
"
|
|
91
|
+
:icon="optionByKey.get(item.value)?.icon"
|
|
92
|
+
:value="optionByKey.get(item.value)?.value"
|
|
93
|
+
:tile="cards.tile.value"
|
|
94
|
+
:compact="cards.compact.value"
|
|
95
|
+
:mark="cards.mark.value"
|
|
96
|
+
:selected="model.includes(item.value)"
|
|
97
|
+
:ui="cards.ui.value"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
</UCheckboxGroup>
|
|
101
|
+
</div>
|
|
76
102
|
</FormFieldShell>
|
|
77
103
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineFormFieldKind } from "../../utils/field-kind.js";
|
|
2
2
|
export const checkboxCardFieldKind = defineFormFieldKind({
|
|
3
3
|
layout: { item: true },
|
|
4
|
-
options: { enabled: true },
|
|
4
|
+
options: { enabled: true, groups: true },
|
|
5
5
|
state: "stateful",
|
|
6
6
|
transform: true,
|
|
7
7
|
type: "checkbox-card",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { FormStatefulFieldBase } from '../../types/field-base.js';
|
|
2
2
|
import type { FieldOptionValue, NullableValue } from '../../types/field-output-utils.js';
|
|
3
|
-
import type { FormOptionConfig,
|
|
4
|
-
import type { FormChoiceCardProps } from '../choice-card/types.js';
|
|
5
|
-
export interface FormCheckboxCardField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends
|
|
3
|
+
import type { FormOptionConfig, FormOptionGrouping, FormOptionValue, FormOptionsSource } from '../../types/options.js';
|
|
4
|
+
import type { FormChoiceCardOptionItem, FormChoiceCardProps } from '../choice-card/types.js';
|
|
5
|
+
export interface FormCheckboxCardField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormChoiceCardOptionItem<TValue> = FormChoiceCardOptionItem<TValue>> extends FormStatefulFieldBase<'checkbox-card', readonly TValue[] | null, TContext, TDeps, FormChoiceCardProps>, FormOptionGrouping {
|
|
6
6
|
options: FormOptionConfig<TOption, TContext, TDeps, readonly TValue[] | null> | FormOptionsSource<TOption, TContext, TDeps, readonly TValue[] | null>;
|
|
7
7
|
}
|
|
8
8
|
export type CheckboxCardFieldOutput<TField> = readonly FieldOptionValue<TField>[] | NullableValue;
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import UCheckboxGroup from "@nuxt/ui/components/CheckboxGroup.vue";
|
|
3
3
|
import { computed } from "vue";
|
|
4
4
|
import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
5
|
+
import FormOptionChoiceLabel from "../../components/utils/form-option-choice-label.vue";
|
|
6
|
+
import { useChoiceGroupItems } from "../../composables/use-choice-group-items";
|
|
5
7
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
6
8
|
import { formOptionKey } from "../../utils/options";
|
|
7
9
|
import { isBoolean, isNumber, isString, isUndefined } from "../../utils/predicate";
|
|
@@ -31,9 +33,13 @@ const model = computed({
|
|
|
31
33
|
})
|
|
32
34
|
)
|
|
33
35
|
});
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
)
|
|
36
|
+
const renderOption = computed(() => props.field.renderOption);
|
|
37
|
+
const { items, optionOf } = useChoiceGroupItems({
|
|
38
|
+
custom: () => renderOption.value !== void 0,
|
|
39
|
+
options,
|
|
40
|
+
ui: () => controlProps.value.ui,
|
|
41
|
+
valueOf: (option) => formOptionKey(option.value)
|
|
42
|
+
});
|
|
37
43
|
const groupUi = computed(() => ({
|
|
38
44
|
...controlProps.value.ui,
|
|
39
45
|
fieldset: mergeFormUiClass(
|
|
@@ -65,6 +71,14 @@ function isOptionValue(value) {
|
|
|
65
71
|
:indicator="fieldProps.indicator"
|
|
66
72
|
:disabled="disabled"
|
|
67
73
|
@blur="handleBlur"
|
|
68
|
-
|
|
74
|
+
>
|
|
75
|
+
<template #label="{ item }">
|
|
76
|
+
<FormOptionChoiceLabel
|
|
77
|
+
:option="optionOf(item.value)"
|
|
78
|
+
:selected="model.includes(item.value)"
|
|
79
|
+
:render="renderOption"
|
|
80
|
+
/>
|
|
81
|
+
</template>
|
|
82
|
+
</UCheckboxGroup>
|
|
69
83
|
</FormFieldShell>
|
|
70
84
|
</template>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FormStatefulFieldBase } from '../../types/field-base.js';
|
|
2
2
|
import type { FieldOptionValue, NullableValue } from '../../types/field-output-utils.js';
|
|
3
|
-
import type { FormOptionConfig, FormOptionItem, FormOptionValue, FormOptionsSource } from '../../types/options.js';
|
|
3
|
+
import type { FormOptionConfig, FormOptionItem, FormOptionRenderers, FormOptionValue, FormOptionsSource } from '../../types/options.js';
|
|
4
4
|
export interface FormCheckboxGroupProps {
|
|
5
5
|
/**
|
|
6
6
|
* `list` (the default) lines up bare checkboxes, `card` frames each option on its own, and
|
|
@@ -10,7 +10,7 @@ export interface FormCheckboxGroupProps {
|
|
|
10
10
|
orientation?: 'horizontal' | 'vertical';
|
|
11
11
|
indicator?: 'start' | 'end' | 'hidden';
|
|
12
12
|
}
|
|
13
|
-
export interface FormCheckboxGroupField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'checkbox-group', readonly TValue[] | null, TContext, TDeps, FormCheckboxGroupProps> {
|
|
13
|
+
export interface FormCheckboxGroupField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'checkbox-group', readonly TValue[] | null, TContext, TDeps, FormCheckboxGroupProps>, FormOptionRenderers<TOption> {
|
|
14
14
|
options: FormOptionConfig<TOption, TContext, TDeps, readonly TValue[] | null> | FormOptionsSource<TOption, TContext, TDeps, readonly TValue[] | null>;
|
|
15
15
|
}
|
|
16
16
|
export type CheckboxGroupFieldOutput<TField> = readonly FieldOptionValue<TField>[] | NullableValue;
|