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
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import USelectMenu from "@nuxt/ui/components/SelectMenu.vue";
|
|
3
|
+
import { createReusableTemplate } from "@vueuse/core";
|
|
3
4
|
import { computed, ref, watch } from "vue";
|
|
4
5
|
import { useUiToolsLocale } from "../../../i18n/use-locale";
|
|
5
6
|
import FormFieldShell from "../../components/renderer/form-field-shell.vue";
|
|
7
|
+
import FormOptionDisplayValue from "../../components/utils/form-option-display-value.vue";
|
|
6
8
|
import FormOptionItemLabel from "../../components/utils/form-option-item-label.vue";
|
|
9
|
+
import FormOptionLeading from "../../components/utils/form-option-leading.vue";
|
|
7
10
|
import FormOptionMenuFooter from "../../components/utils/form-option-menu-footer.vue";
|
|
11
|
+
import FormOptionSuffix from "../../components/utils/form-option-suffix.vue";
|
|
8
12
|
import { useFieldControl } from "../../composables/use-field-control";
|
|
9
|
-
import {
|
|
13
|
+
import { useOptionMenu } from "../../composables/use-option-menu";
|
|
10
14
|
import { isBoolean, isNumber, isString } from "../../utils/predicate";
|
|
11
15
|
import { mergeFormUiClass } from "../../utils/ui";
|
|
12
16
|
const props = defineProps({
|
|
@@ -30,6 +34,7 @@ const {
|
|
|
30
34
|
() => props.path,
|
|
31
35
|
{ omit: ["createItem", "max", "searchable", "clearable"] }
|
|
32
36
|
);
|
|
37
|
+
const [DefineControl, ReuseControl] = createReusableTemplate();
|
|
33
38
|
const searchTerm = ref("");
|
|
34
39
|
const open = ref(false);
|
|
35
40
|
const model = computed({
|
|
@@ -51,16 +56,20 @@ const model = computed({
|
|
|
51
56
|
form.setValue(props.path, value);
|
|
52
57
|
}
|
|
53
58
|
});
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
const menu = useOptionMenu({
|
|
60
|
+
field: () => props.field,
|
|
61
|
+
loadMoreLabel: () => t("form.fields.options.loadingMore"),
|
|
62
|
+
model: () => model.value,
|
|
63
|
+
multiple: () => fieldProps.value.multiple === true,
|
|
64
|
+
options
|
|
65
|
+
});
|
|
61
66
|
const controlUi = computed(() => ({
|
|
62
67
|
...controlProps.value.ui,
|
|
63
|
-
content: mergeFormUiClass(controlProps.value.ui?.content, interactionOwnerClass.value)
|
|
68
|
+
content: mergeFormUiClass(controlProps.value.ui?.content, interactionOwnerClass.value),
|
|
69
|
+
itemDescription: mergeFormUiClass(
|
|
70
|
+
menu.renderOption.value ? "hidden" : "text-[12.5px]",
|
|
71
|
+
controlProps.value.ui?.itemDescription
|
|
72
|
+
)
|
|
64
73
|
}));
|
|
65
74
|
const createItem = computed(
|
|
66
75
|
() => options.creatable.value && fieldProps.value.createItem ? fieldProps.value.createItem : false
|
|
@@ -109,53 +118,7 @@ function isOptionValue(value) {
|
|
|
109
118
|
</script>
|
|
110
119
|
|
|
111
120
|
<template>
|
|
112
|
-
<
|
|
113
|
-
v-if="bare"
|
|
114
|
-
v-model="model"
|
|
115
|
-
v-model:search-term="searchTerm"
|
|
116
|
-
:open="open"
|
|
117
|
-
v-bind="controlProps"
|
|
118
|
-
class="w-full"
|
|
119
|
-
value-key="value"
|
|
120
|
-
label-key="label"
|
|
121
|
-
:items="items"
|
|
122
|
-
:multiple="fieldProps.multiple"
|
|
123
|
-
:placeholder="placeholder"
|
|
124
|
-
:disabled="disabled"
|
|
125
|
-
:loading="
|
|
126
|
-
validationPending || options.loading.value || options.fetching.value || options.creating.value
|
|
127
|
-
"
|
|
128
|
-
:trailing="true"
|
|
129
|
-
:search-input="searchable"
|
|
130
|
-
:ignore-filter="options.remote.value"
|
|
131
|
-
:clear="fieldProps.clearable === true"
|
|
132
|
-
:create-item="createItem"
|
|
133
|
-
:ui="controlUi"
|
|
134
|
-
@update:open="handleOpen"
|
|
135
|
-
@create="handleNativeCreate"
|
|
136
|
-
@blur="handleBlur"
|
|
137
|
-
>
|
|
138
|
-
<template #item-label="{ item }">
|
|
139
|
-
<FormOptionItemLabel :item="item" />
|
|
140
|
-
</template>
|
|
141
|
-
|
|
142
|
-
<template #content-bottom>
|
|
143
|
-
<FormOptionMenuFooter
|
|
144
|
-
:options="options"
|
|
145
|
-
:disabled="disabled"
|
|
146
|
-
:show-create="showExplicitCreate"
|
|
147
|
-
:create-label="createActionLabel"
|
|
148
|
-
@create="handleCreateAction"
|
|
149
|
-
/>
|
|
150
|
-
</template>
|
|
151
|
-
|
|
152
|
-
<template #create-item-label="{ item }">
|
|
153
|
-
{{
|
|
154
|
-
options.creating.value ? t("form.fields.options.creating") : t("form.fields.options.createNamed", { label: item })
|
|
155
|
-
}}
|
|
156
|
-
</template>
|
|
157
|
-
</USelectMenu>
|
|
158
|
-
<FormFieldShell v-else :field="field" :path="path">
|
|
121
|
+
<DefineControl>
|
|
159
122
|
<USelectMenu
|
|
160
123
|
v-model="model"
|
|
161
124
|
v-model:search-term="searchTerm"
|
|
@@ -164,7 +127,7 @@ function isOptionValue(value) {
|
|
|
164
127
|
class="w-full"
|
|
165
128
|
value-key="value"
|
|
166
129
|
label-key="label"
|
|
167
|
-
:items="items"
|
|
130
|
+
:items="menu.items.value"
|
|
168
131
|
:multiple="fieldProps.multiple"
|
|
169
132
|
:placeholder="placeholder"
|
|
170
133
|
:disabled="disabled"
|
|
@@ -181,8 +144,38 @@ function isOptionValue(value) {
|
|
|
181
144
|
@create="handleNativeCreate"
|
|
182
145
|
@blur="handleBlur"
|
|
183
146
|
>
|
|
147
|
+
<template v-if="menu.leadingOption.value" #leading="{ ui }">
|
|
148
|
+
<FormOptionLeading
|
|
149
|
+
:option="menu.leadingOption.value"
|
|
150
|
+
:icon-class="ui.leadingIcon()"
|
|
151
|
+
:avatar-size="ui.itemLeadingAvatarSize()"
|
|
152
|
+
chip-class="size-5"
|
|
153
|
+
/>
|
|
154
|
+
</template>
|
|
155
|
+
|
|
156
|
+
<template v-if="menu.customValueOption.value" #default="{ ui }">
|
|
157
|
+
<span :class="ui.value({ class: controlProps.ui?.value })" data-slot="value">
|
|
158
|
+
<FormOptionDisplayValue
|
|
159
|
+
:option="menu.customValueOption.value"
|
|
160
|
+
:render="menu.renderValue.value"
|
|
161
|
+
/>
|
|
162
|
+
</span>
|
|
163
|
+
</template>
|
|
164
|
+
|
|
165
|
+
<template #item-leading="{ item }">
|
|
166
|
+
<FormOptionLeading :option="menu.renderOption.value ? void 0 : item" />
|
|
167
|
+
</template>
|
|
168
|
+
|
|
184
169
|
<template #item-label="{ item }">
|
|
185
|
-
<FormOptionItemLabel
|
|
170
|
+
<FormOptionItemLabel
|
|
171
|
+
:option="item"
|
|
172
|
+
:selected="menu.isSelected(item)"
|
|
173
|
+
:render="menu.renderOption.value"
|
|
174
|
+
/>
|
|
175
|
+
</template>
|
|
176
|
+
|
|
177
|
+
<template #item-trailing="{ item }">
|
|
178
|
+
<FormOptionSuffix v-if="!menu.renderOption.value" :option="item" />
|
|
186
179
|
</template>
|
|
187
180
|
|
|
188
181
|
<template #content-bottom>
|
|
@@ -201,5 +194,10 @@ function isOptionValue(value) {
|
|
|
201
194
|
}}
|
|
202
195
|
</template>
|
|
203
196
|
</USelectMenu>
|
|
197
|
+
</DefineControl>
|
|
198
|
+
|
|
199
|
+
<ReuseControl v-if="bare" />
|
|
200
|
+
<FormFieldShell v-else :field="field" :path="path">
|
|
201
|
+
<ReuseControl />
|
|
204
202
|
</FormFieldShell>
|
|
205
203
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineFormFieldKind } from "../../utils/field-kind.js";
|
|
2
2
|
export const selectFieldKind = 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: "select",
|
|
@@ -1,6 +1,6 @@
|
|
|
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
|
export type FormSelectCreateItem = boolean | 'always' | {
|
|
5
5
|
position?: 'top' | 'bottom';
|
|
6
6
|
when?: 'always' | 'empty';
|
|
@@ -12,7 +12,7 @@ export interface FormSelectProps {
|
|
|
12
12
|
createItem?: FormSelectCreateItem;
|
|
13
13
|
max?: number;
|
|
14
14
|
}
|
|
15
|
-
export interface FormSelectField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'select', TValue | readonly TValue[] | null, TContext, TDeps, FormSelectProps> {
|
|
15
|
+
export interface FormSelectField<TContext = NonNullable<unknown>, TDeps = NonNullable<unknown>, TValue extends FormOptionValue = FormOptionValue, TOption extends FormOptionItem<TValue> = FormOptionItem<TValue>> extends FormStatefulFieldBase<'select', TValue | readonly TValue[] | null, TContext, TDeps, FormSelectProps>, FormOptionGrouping, FormOptionValueRenderers<TOption> {
|
|
16
16
|
options: FormAnyOptionConfig<TOption, TContext, TDeps, TValue | readonly TValue[] | null>;
|
|
17
17
|
}
|
|
18
18
|
type SelectFieldValue<TField> = FieldProps<TField> extends {
|
|
@@ -53,6 +53,12 @@ export interface FormStatefulFieldBase<TType extends FormFieldType, TValue, TCon
|
|
|
53
53
|
props?: FormFieldProps<TProps, TContext, TDeps>;
|
|
54
54
|
/** Disables the field without removing it from form state. */
|
|
55
55
|
disabled?: FormFieldCallback<boolean, TContext, TDeps, TValue>;
|
|
56
|
+
/**
|
|
57
|
+
* Why the field is disabled, shown under the control with a lock icon only while the `disabled`
|
|
58
|
+
* callback holds. Static text, or a callback receiving `{ ctx, deps, api }` that returns nothing
|
|
59
|
+
* when no reason applies.
|
|
60
|
+
*/
|
|
61
|
+
disabledReason?: FormText | FormFieldCallback<FormText | undefined, TContext, TDeps, TValue>;
|
|
56
62
|
/** Controls whether the field is rendered. Hidden fields can still be part of form state. */
|
|
57
63
|
condition?: FormFieldCallback<boolean, TContext, TDeps, TValue>;
|
|
58
64
|
/** Validation behavior for this field. */
|
|
@@ -21,6 +21,8 @@ export interface FormFieldKindDefinition<TType extends FormFieldType = FormField
|
|
|
21
21
|
/** Whether the field owns option resolution. */
|
|
22
22
|
options?: {
|
|
23
23
|
enabled: boolean;
|
|
24
|
+
/** Whether the field lists its options under headings read from a property of the options. */
|
|
25
|
+
groups?: boolean;
|
|
24
26
|
};
|
|
25
27
|
/** Whether the field owns file upload work. */
|
|
26
28
|
upload?: {
|
|
@@ -33,4 +35,4 @@ export interface FormFieldKindDefinition<TType extends FormFieldType = FormField
|
|
|
33
35
|
}
|
|
34
36
|
export type FormFieldKindState = FormFieldKindDefinition['state'];
|
|
35
37
|
export type FormFieldState = FormFieldKindState;
|
|
36
|
-
export type FormFieldCapability = 'value' | 'children' | 'label' | 'description' | 'hint' | 'layout' | 'itemLayout' | 'containerLayout' | 'options' | 'upload' | 'validation' | 'transform' | 'submit';
|
|
38
|
+
export type FormFieldCapability = 'value' | 'children' | 'label' | 'description' | 'hint' | 'layout' | 'itemLayout' | 'containerLayout' | 'options' | 'optionGroups' | 'upload' | 'validation' | 'transform' | 'submit';
|
|
@@ -54,6 +54,7 @@ export type { FormAutoCompleteField } from '../fields/auto-complete/types.js';
|
|
|
54
54
|
export type { FormButtonField } from '../fields/button/types.js';
|
|
55
55
|
export type { FormCardField } from '../fields/card/types.js';
|
|
56
56
|
export type { FormCheckboxCardField } from '../fields/checkbox-card/types.js';
|
|
57
|
+
export type { FormChoiceCardDensity, FormChoiceCardOption, FormChoiceCardOptionItem, FormChoiceCardProps, } from '../fields/choice-card/types.js';
|
|
57
58
|
export type { FormCheckboxField } from '../fields/checkbox/types.js';
|
|
58
59
|
export type { FormCheckboxGroupField } from '../fields/checkbox-group/types.js';
|
|
59
60
|
export type { FormColorPickerField } from '../fields/color-picker/types.js';
|
|
@@ -20,6 +20,12 @@ export interface FormLayoutConfig {
|
|
|
20
20
|
export interface FormItemLayout {
|
|
21
21
|
/** Column span for this field inside the owning layout grid. Replaces legacy `size`. */
|
|
22
22
|
span?: number | string;
|
|
23
|
+
/**
|
|
24
|
+
* Starts this field on a new row of the owning grid, at its first column, whatever the fields
|
|
25
|
+
* before it left free. Only the start of the column is set, so a responsive `span` still
|
|
26
|
+
* decides how wide the field is at each breakpoint.
|
|
27
|
+
*/
|
|
28
|
+
newRow?: boolean;
|
|
23
29
|
/** Fixed width used by renderers that lay fields out as columns, such as array tables. */
|
|
24
30
|
width?: number | string;
|
|
25
31
|
/** Label placement for this field. */
|
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
import type { QueryKey } from '@tanstack/vue-query';
|
|
2
|
+
import type { VNodeChild } from 'vue';
|
|
2
3
|
import type { RemoteOptionsLoader, RemoteOptionsPageRequest, RemoteOptionsPagination, RemoteOptionsResult, RemoteOptionsSearch } from '../../shared/types/remote-options.js';
|
|
3
4
|
import type { FormValue } from './/index.js';
|
|
4
5
|
import type { FormDependencies, FormFieldCallback, FormFieldCallbackParams } from './callbacks.js';
|
|
5
6
|
import type { FormQueryOptions } from './context.js';
|
|
6
7
|
import type { FormMaybePromise, FormText } from './utils.js';
|
|
8
|
+
/** Colors a `chip` option dot can take. */
|
|
9
|
+
export type FormOptionChipColor = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | 'neutral';
|
|
10
|
+
/**
|
|
11
|
+
* Picture drawn before an option label, passed to the Nuxt UI avatar. Use it for people and
|
|
12
|
+
* organisations: `text` is the fallback shown when `src` is missing or fails to load.
|
|
13
|
+
*/
|
|
14
|
+
export interface FormOptionAvatar {
|
|
15
|
+
/** Image URL. */
|
|
16
|
+
src?: string;
|
|
17
|
+
/** Accessible description of the image. Defaults to the option label. */
|
|
18
|
+
alt?: string;
|
|
19
|
+
/** Fallback text shown when there is no image, such as initials. */
|
|
20
|
+
text?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Colored dot drawn before an option label, for statuses and categories. */
|
|
23
|
+
export interface FormOptionChip {
|
|
24
|
+
/** Color of the dot. Defaults to `primary`. */
|
|
25
|
+
color?: FormOptionChipColor;
|
|
26
|
+
}
|
|
7
27
|
/**
|
|
8
28
|
* Primitive value accepted by option-based fields.
|
|
9
29
|
*/
|
|
@@ -20,6 +40,123 @@ export interface FormOption<TValue extends FormOptionValue = FormOptionValue> {
|
|
|
20
40
|
description?: FormText;
|
|
21
41
|
/** Disables the option without removing it from the list. */
|
|
22
42
|
disabled?: boolean;
|
|
43
|
+
/** Iconify icon drawn before the label. */
|
|
44
|
+
icon?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Picture drawn before the label, for people and organisations. Only one leading visual shows,
|
|
47
|
+
* in the order `icon`, `avatar`, `chip`.
|
|
48
|
+
*/
|
|
49
|
+
avatar?: FormOptionAvatar;
|
|
50
|
+
/**
|
|
51
|
+
* Colored dot drawn before the label, for statuses and categories. Only one leading visual
|
|
52
|
+
* shows, in the order `icon`, `avatar`, `chip`.
|
|
53
|
+
*/
|
|
54
|
+
chip?: FormOptionChip;
|
|
55
|
+
/**
|
|
56
|
+
* Secondary text at the end of the option, such as a code (`EUR`) or a count. It also follows
|
|
57
|
+
* the label in the closed control of a select.
|
|
58
|
+
*/
|
|
59
|
+
suffix?: FormText;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Option as the engine resolved it: the shared shape every option-based field renders from,
|
|
63
|
+
* whatever the authored option looked like (a primitive, a record, or a record with its own keys).
|
|
64
|
+
*/
|
|
65
|
+
export interface ResolvedFormOption {
|
|
66
|
+
value: FormOptionValue;
|
|
67
|
+
label: string;
|
|
68
|
+
description?: string;
|
|
69
|
+
disabled?: boolean;
|
|
70
|
+
icon?: string;
|
|
71
|
+
avatar?: FormOptionAvatar;
|
|
72
|
+
chip?: FormOptionChip;
|
|
73
|
+
/** Secondary text at the end of the option, already resolved. */
|
|
74
|
+
suffix?: string;
|
|
75
|
+
/**
|
|
76
|
+
* The option exactly as the schema or the source gave it, so render functions can read any
|
|
77
|
+
* data it carries. A primitive option is the primitive itself. The load-more row has none.
|
|
78
|
+
*/
|
|
79
|
+
item?: FormOptionItem;
|
|
80
|
+
/** Heading the option is listed under, for the fields that group their options. */
|
|
81
|
+
group?: string;
|
|
82
|
+
children?: readonly ResolvedFormOption[];
|
|
83
|
+
/** True when the option has children that load on demand. */
|
|
84
|
+
lazy?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/** What a field hands `renderOption` for each option it lists. */
|
|
87
|
+
export interface FormOptionRenderContext<TOption = FormOptionItem> {
|
|
88
|
+
/** The resolved option: label, description, icon, avatar, chip and suffix as the field reads them. */
|
|
89
|
+
option: ResolvedFormOption;
|
|
90
|
+
/** The option exactly as authored or returned by the source, with any custom data it carries. */
|
|
91
|
+
item: TOption;
|
|
92
|
+
/** True when the option is part of the field value. */
|
|
93
|
+
selected: boolean;
|
|
94
|
+
/** True when the option cannot be chosen. */
|
|
95
|
+
disabled: boolean;
|
|
96
|
+
}
|
|
97
|
+
/** What a field hands `renderValue` for the option it shows in the closed control. */
|
|
98
|
+
export interface FormOptionValueRenderContext<TOption = FormOptionItem> {
|
|
99
|
+
/** The resolved option: label, description, icon, avatar, chip and suffix as the field reads them. */
|
|
100
|
+
option: ResolvedFormOption;
|
|
101
|
+
/** The option exactly as authored or returned by the source, with any custom data it carries. */
|
|
102
|
+
item: TOption;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Content render functions of the option-based fields, declared on the field next to its
|
|
106
|
+
* `options`. A field typed with its option type (`FormSelectField<Ctx, Deps, Value, Currency>`)
|
|
107
|
+
* hands them that type. In an inline schema the option type is not inferred into the callback, so
|
|
108
|
+
* annotate the parameter with the context of your option type to read its custom data.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```ts
|
|
112
|
+
* interface Currency extends FormOption<'EUR' | 'USD'> {
|
|
113
|
+
* symbol: string
|
|
114
|
+
* }
|
|
115
|
+
*
|
|
116
|
+
* // Each currency is listed as its symbol, then its name.
|
|
117
|
+
* {
|
|
118
|
+
* type: 'select',
|
|
119
|
+
* key: 'currency',
|
|
120
|
+
* options: [{ value: 'EUR', label: 'Euro', symbol: '€' }],
|
|
121
|
+
* renderOption: ({ item, option }: FormOptionRenderContext<Currency>) =>
|
|
122
|
+
* h('span', [item.symbol, ' ', option.label]),
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export interface FormOptionRenderers<TOption = FormOptionItem> {
|
|
127
|
+
/**
|
|
128
|
+
* Replaces the content of each option in the list: label, description, leading visual and
|
|
129
|
+
* suffix. The control keeps its own selection indicator and keyboard behavior.
|
|
130
|
+
*/
|
|
131
|
+
renderOption?(context: FormOptionRenderContext<TOption>): VNodeChild;
|
|
132
|
+
}
|
|
133
|
+
/** Renderers of the fields that show the chosen option in a closed control. */
|
|
134
|
+
export interface FormOptionValueRenderers<TOption = FormOptionItem> extends FormOptionRenderers<TOption> {
|
|
135
|
+
/**
|
|
136
|
+
* Replaces how the chosen option reads in the closed control, in single selection. Multiple
|
|
137
|
+
* selection keeps its comma-separated labels.
|
|
138
|
+
*/
|
|
139
|
+
renderValue?(context: FormOptionValueRenderContext<TOption>): VNodeChild;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Option grouping of the fields that list options under headings, declared on the field next to
|
|
143
|
+
* its `options`.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* // Rows from the API, each with a `section` to list the options under.
|
|
148
|
+
* { type: 'select', options: () => queryOptions({ queryKey: ['plans'], queryFn: fetchPlans }), groupKey: 'section' }
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export interface FormOptionGrouping {
|
|
152
|
+
/**
|
|
153
|
+
* Property of the options that holds the heading they are listed under. Options written inline
|
|
154
|
+
* in the schema group by their `group` without it. The records a function, a promise or a query
|
|
155
|
+
* returns group only when this names the property, so records that already carry a `group` for
|
|
156
|
+
* another purpose are never regrouped by surprise. `false` lists every option together, even
|
|
157
|
+
* inline options that carry a `group`.
|
|
158
|
+
*/
|
|
159
|
+
groupKey?: string | false;
|
|
23
160
|
}
|
|
24
161
|
/**
|
|
25
162
|
* Authored option item accepted by option-based fields.
|
|
@@ -41,10 +41,10 @@ export interface FormPageSection<TContext = NonNullable<unknown>, TFields extend
|
|
|
41
41
|
/** Supporting copy next to the title. */
|
|
42
42
|
description?: FormText;
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
45
|
-
* without a required field is optional already; set this when its
|
|
46
|
-
* by their defaults and the user has nothing to do there. Set
|
|
47
|
-
* required when its only required fields are the cells of array rows.
|
|
44
|
+
* Marks the section optional while nothing is entered in it, and leaves it out of the sections
|
|
45
|
+
* left to complete. A section without a required field is optional already; set this when its
|
|
46
|
+
* required fields are filled by their defaults and the user has nothing to do there. Set
|
|
47
|
+
* `false` to keep a section required when its only required fields are the cells of array rows.
|
|
48
48
|
*/
|
|
49
49
|
optional?: boolean;
|
|
50
50
|
/** Grid of the section's fields, merged over the schema `layout`. */
|
|
@@ -62,6 +62,12 @@ export interface FormPageSection<TContext = NonNullable<unknown>, TFields extend
|
|
|
62
62
|
export interface FormPageNavigationConfig {
|
|
63
63
|
/** Heading above the entries, e.g. `'Création'`. Accepts a function to translate it. */
|
|
64
64
|
title?: FormText;
|
|
65
|
+
/**
|
|
66
|
+
* Shows the navigation only when the page has at least this many visible sections. Below it,
|
|
67
|
+
* the page is one focused column of content: two short sections gain nothing from a side
|
|
68
|
+
* navigation. Without it, the navigation always shows.
|
|
69
|
+
*/
|
|
70
|
+
minSections?: number;
|
|
65
71
|
}
|
|
66
72
|
/**
|
|
67
73
|
* Schema accepted by `defineFormPageSchema`: a form schema whose `sections` replace `fields`.
|
|
@@ -142,12 +148,18 @@ export interface FormPageScrollOptions {
|
|
|
142
148
|
/**
|
|
143
149
|
* Where a section stands:
|
|
144
150
|
*
|
|
145
|
-
* - `invalid`: it shows at least one validation error
|
|
151
|
+
* - `invalid`: it shows at least one validation error, which only appears once the user left the
|
|
152
|
+
* field or tried to submit, so a section nobody touched is never `invalid`
|
|
153
|
+
* - `pending`: a required field has no value yet, in a required section, or in an optional one
|
|
154
|
+
* the user started and left incomplete
|
|
146
155
|
* - `complete`: nothing required is missing and it shows no error; an optional section also
|
|
147
156
|
* needs a value, entered by the user or provided by the form input
|
|
148
|
-
* - `
|
|
157
|
+
* - `optional`: an optional section without any entered value, where there is nothing to do
|
|
158
|
+
*
|
|
159
|
+
* `invalid` and `pending` are the sections that keep the form from being submitted, and the only
|
|
160
|
+
* ones the navigation counts as left to complete.
|
|
149
161
|
*/
|
|
150
|
-
export type FormPageSectionStatus = 'invalid' | 'complete' | '
|
|
162
|
+
export type FormPageSectionStatus = 'invalid' | 'pending' | 'complete' | 'optional';
|
|
151
163
|
/**
|
|
152
164
|
* Live state of a visible section, as the page navigation and section slots receive it.
|
|
153
165
|
*/
|
|
@@ -167,7 +179,7 @@ export interface FormPageSectionState {
|
|
|
167
179
|
optional: boolean;
|
|
168
180
|
/** Number of required fields without a value, the fields of array items included. */
|
|
169
181
|
missing: number;
|
|
170
|
-
/**
|
|
182
|
+
/** Where the section stands, see `FormPageSectionStatus`. */
|
|
171
183
|
status: FormPageSectionStatus;
|
|
172
184
|
/** True when a value of the section differs from the form's baseline. */
|
|
173
185
|
dirty: boolean;
|
|
@@ -44,6 +44,8 @@ export interface FormFieldUi {
|
|
|
44
44
|
hint?: FormUiClass;
|
|
45
45
|
labelExtra?: FormUiClass;
|
|
46
46
|
help?: FormUiClass;
|
|
47
|
+
disabledReason?: FormUiClass;
|
|
48
|
+
disabledReasonIcon?: FormUiClass;
|
|
47
49
|
body?: FormUiClass;
|
|
48
50
|
content?: FormUiClass;
|
|
49
51
|
pending?: FormUiClass;
|
|
@@ -191,11 +193,27 @@ export interface FormOverlayUi {
|
|
|
191
193
|
overlay?: FormUiClass;
|
|
192
194
|
content?: FormUiClass;
|
|
193
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* How the sections of a form page are drawn:
|
|
198
|
+
*
|
|
199
|
+
* - `card`: each section is a bordered card on the gray canvas of the page (default)
|
|
200
|
+
* - `plain`: no box. A section is its heading, description, and fields on the page itself,
|
|
201
|
+
* separated from the next by spacing and a hairline
|
|
202
|
+
*/
|
|
203
|
+
export type FormPageSurface = 'card' | 'plain';
|
|
204
|
+
/**
|
|
205
|
+
* The `page` part of the form UI config: the surface of the sections and the `ui` slots of the
|
|
206
|
+
* page parts. Both follow the usual layering: app config, then schema `ui`, then the `ui` prop.
|
|
207
|
+
*/
|
|
208
|
+
export interface FormPageUiConfig extends FormUiPartConfig<FormPageUi> {
|
|
209
|
+
/** Defaults to `card`. */
|
|
210
|
+
surface?: FormPageSurface;
|
|
211
|
+
}
|
|
194
212
|
/**
|
|
195
213
|
* Slots of a form page and its parts. Data attributes carry the live state, so a slot can
|
|
196
214
|
* restyle one state: `data-active` on the current navigation entry, `data-state`
|
|
197
|
-
* (`complete`, `invalid`, `pending`) on entries
|
|
198
|
-
* sections and entries.
|
|
215
|
+
* (`complete`, `invalid`, `pending`, `optional`) on entries, indicators, and sections,
|
|
216
|
+
* `data-dirty` on modified sections and entries.
|
|
199
217
|
*
|
|
200
218
|
* Sections and the navigation stay below the pinned header: the page gives each section its
|
|
201
219
|
* `scroll-margin-top` and the navigation the `--nut-form-page-header` variable (the header's
|
|
@@ -209,6 +227,11 @@ export interface FormPageUi {
|
|
|
209
227
|
/** Grid holding the navigation and the sections. */
|
|
210
228
|
body?: FormUiClass;
|
|
211
229
|
header?: FormUiClass;
|
|
230
|
+
/**
|
|
231
|
+
* Row holding the heading and the actions. Beside a navigation it adds no box of its own; on a
|
|
232
|
+
* page without one it is the centered column the body shares, and carries the header padding.
|
|
233
|
+
*/
|
|
234
|
+
headerRow?: FormUiClass;
|
|
212
235
|
headerContent?: FormUiClass;
|
|
213
236
|
heading?: FormUiClass;
|
|
214
237
|
eyebrow?: FormUiClass;
|
|
@@ -228,9 +251,10 @@ export interface FormPageUi {
|
|
|
228
251
|
navigationIndicator?: FormUiClass;
|
|
229
252
|
/** Check of a complete section in the indicator. */
|
|
230
253
|
navigationIndicatorIcon?: FormUiClass;
|
|
231
|
-
/** Dot in the indicator of the current section while it is pending. */
|
|
254
|
+
/** Dot in the indicator of the current section while it is pending or optional. */
|
|
232
255
|
navigationIndicatorMarker?: FormUiClass;
|
|
233
256
|
navigationLabel?: FormUiClass;
|
|
257
|
+
/** The "Optional" tag of an entry whose optional section has nothing entered. */
|
|
234
258
|
navigationOptional?: FormUiClass;
|
|
235
259
|
navigationDirty?: FormUiClass;
|
|
236
260
|
/** Wrapper under the entries, whose padding insets the summary. */
|
|
@@ -246,6 +270,7 @@ export interface FormPageUi {
|
|
|
246
270
|
sectionHeader?: FormUiClass;
|
|
247
271
|
sectionTitle?: FormUiClass;
|
|
248
272
|
sectionDescription?: FormUiClass;
|
|
273
|
+
/** The "Optional" badge of an optional section with nothing entered. */
|
|
249
274
|
sectionOptional?: FormUiClass;
|
|
250
275
|
sectionActions?: FormUiClass;
|
|
251
276
|
sectionReset?: FormUiClass;
|
|
@@ -288,5 +313,5 @@ export interface FormUiConfig {
|
|
|
288
313
|
drawer?: FormUiPartConfig<FormOverlayUi>;
|
|
289
314
|
fullscreen?: FormUiPartConfig<FormOverlayUi>;
|
|
290
315
|
/** Form page rendered by `FormPage` and its parts. */
|
|
291
|
-
page?:
|
|
316
|
+
page?: FormPageUiConfig;
|
|
292
317
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { FormField, FormFieldCallbackParams } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Whether the field's authored `disabled` callback holds. Engine-driven disabling (a pending form
|
|
4
|
+
* action, options still loading) is separate: it explains itself, so it never carries a reason.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isFieldDisabledByCallback(field: FormField, params: FormFieldCallbackParams): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* The reason to show under a field while its `disabled` callback holds: the authored
|
|
9
|
+
* `disabledReason` text, or nothing when the field is enabled or the author gave no reason.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveFieldDisabledReason(field: FormField, params: FormFieldCallbackParams): string | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isFunction } from "./predicate.js";
|
|
2
|
+
import { resolveFieldText } from "./text.js";
|
|
3
|
+
export function isFieldDisabledByCallback(field, params) {
|
|
4
|
+
const disabled = Object.getOwnPropertyDescriptor(field, "disabled")?.value;
|
|
5
|
+
return isFunction(disabled) ? disabled(params) === true : false;
|
|
6
|
+
}
|
|
7
|
+
export function resolveFieldDisabledReason(field, params) {
|
|
8
|
+
if (!isFieldDisabledByCallback(field, params)) return void 0;
|
|
9
|
+
const reason = Object.getOwnPropertyDescriptor(field, "disabledReason")?.value;
|
|
10
|
+
return resolveFieldText(reason, params) || void 0;
|
|
11
|
+
}
|
|
@@ -67,6 +67,9 @@ export function fieldKindHas(kind, capability) {
|
|
|
67
67
|
if (capability === "options") {
|
|
68
68
|
return kind.options?.enabled === true;
|
|
69
69
|
}
|
|
70
|
+
if (capability === "optionGroups") {
|
|
71
|
+
return kind.options?.groups === true;
|
|
72
|
+
}
|
|
70
73
|
if (capability === "upload") {
|
|
71
74
|
return kind.upload?.enabled === true;
|
|
72
75
|
}
|