@narrative.io/jsonforms-provider-protocols 3.0.0-beta.3 → 3.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/projection.d.ts.map +1 -1
- package/dist/core/projection.js.map +1 -1
- package/dist/core/transforms.d.ts.map +1 -1
- package/dist/core/transforms.js +3 -1
- package/dist/core/transforms.js.map +1 -1
- package/dist/jsonforms-provider-protocols.css +2 -2
- package/dist/vue/components/ProviderAutocomplete.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderAutocomplete.vue.js +8 -5
- package/dist/vue/components/ProviderAutocomplete.vue.js.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue.js +1 -1
- package/dist/vue/components/ProviderMultiSelect.vue2.js +8 -5
- package/dist/vue/components/ProviderMultiSelect.vue2.js.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.d.ts.map +1 -1
- package/dist/vue/components/ProviderSelect.vue.js +1 -1
- package/dist/vue/components/ProviderSelect.vue2.js +8 -5
- package/dist/vue/components/ProviderSelect.vue2.js.map +1 -1
- package/dist/vue/composables/useDerive.d.ts +1 -1
- package/dist/vue/composables/useDerive.d.ts.map +1 -1
- package/dist/vue/composables/useDerive.js +5 -1
- package/dist/vue/composables/useDerive.js.map +1 -1
- package/dist/vue/composables/useProjection.d.ts.map +1 -1
- package/dist/vue/composables/useProjection.js +1 -3
- package/dist/vue/composables/useProjection.js.map +1 -1
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +10 -2
- package/dist/vue/index.js.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfBoolean.vue.js +14 -3
- package/dist/vue/primevue/JfBoolean.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnum.vue.js +10 -5
- package/dist/vue/primevue/JfEnum.vue.js.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfEnumArray.vue.js +10 -5
- package/dist/vue/primevue/JfEnumArray.vue.js.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfNumber.vue.js +11 -6
- package/dist/vue/primevue/JfNumber.vue.js.map +1 -1
- package/dist/vue/primevue/JfText.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfText.vue.js +11 -6
- package/dist/vue/primevue/JfText.vue.js.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.d.ts.map +1 -1
- package/dist/vue/primevue/JfTextArea.vue.js +10 -5
- package/dist/vue/primevue/JfTextArea.vue.js.map +1 -1
- package/dist/vue/primevue/index.d.ts.map +1 -1
- package/dist/vue/primevue/index.js +93 -16
- package/dist/vue/primevue/index.js.map +1 -1
- package/dist/vue/utils/autoSelect.js.map +1 -1
- package/package.json +1 -1
- package/src/core/projection.ts +5 -5
- package/src/core/transforms.ts +33 -6
- package/src/vue/components/ProviderAutocomplete.vue +8 -5
- package/src/vue/components/ProviderMultiSelect.vue +12 -7
- package/src/vue/components/ProviderSelect.vue +9 -6
- package/src/vue/composables/useDerive.ts +16 -3
- package/src/vue/composables/useProjection.ts +6 -12
- package/src/vue/index.ts +10 -4
- package/src/vue/primevue/JfBoolean.vue +8 -3
- package/src/vue/primevue/JfEnum.vue +11 -8
- package/src/vue/primevue/JfEnumArray.vue +15 -12
- package/src/vue/primevue/JfNumber.vue +11 -8
- package/src/vue/primevue/JfText.vue +11 -8
- package/src/vue/primevue/JfTextArea.vue +10 -7
- package/src/vue/primevue/index.ts +104 -23
- package/src/vue/styles.css +26 -1
- package/src/vue/utils/autoSelect.ts +2 -2
|
@@ -53,7 +53,12 @@ import MultiSelect from "primevue/multiselect";
|
|
|
53
53
|
const instance = getCurrentInstance()!;
|
|
54
54
|
const props = instance.props as unknown as ControlProps;
|
|
55
55
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
56
|
-
const {
|
|
56
|
+
const {
|
|
57
|
+
projectedData,
|
|
58
|
+
handleProjectedChange: handleChange,
|
|
59
|
+
projectedErrors,
|
|
60
|
+
projectedLabel,
|
|
61
|
+
} = useProjection(control, rawHandleChange);
|
|
57
62
|
|
|
58
63
|
type Opt = { label: string; value: unknown };
|
|
59
64
|
const toOptions = (schema?: JsonSchema): Opt[] => {
|
|
@@ -145,14 +150,16 @@ watch(
|
|
|
145
150
|
control.value.uischema?.options?.autoSelectSingle === true,
|
|
146
151
|
isLoading,
|
|
147
152
|
items,
|
|
148
|
-
currentValue: Array.isArray(projectedData.value)
|
|
153
|
+
currentValue: Array.isArray(projectedData.value)
|
|
154
|
+
? projectedData.value
|
|
155
|
+
: [],
|
|
149
156
|
});
|
|
150
157
|
|
|
151
158
|
if (valueToSelect !== null) {
|
|
152
159
|
handleChange(control.value.path, valueToSelect);
|
|
153
160
|
}
|
|
154
161
|
},
|
|
155
|
-
{ immediate: true }
|
|
162
|
+
{ immediate: true },
|
|
156
163
|
);
|
|
157
164
|
|
|
158
165
|
const placeholder = computed<string | undefined>(() => {
|
|
@@ -190,17 +197,15 @@ const model = computed<unknown[]>({
|
|
|
190
197
|
</script>
|
|
191
198
|
|
|
192
199
|
<template>
|
|
193
|
-
<div class="
|
|
194
|
-
<label v-if="projectedLabel" class="
|
|
195
|
-
|
|
196
|
-
}}</label>
|
|
197
|
-
<div v-if="control.description" class="text-color-secondary text-left">
|
|
200
|
+
<div class="jf-control">
|
|
201
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
202
|
+
<div v-if="control.description" class="jf-description">
|
|
198
203
|
{{ control.description }}
|
|
199
204
|
</div>
|
|
200
205
|
|
|
201
206
|
<MultiSelect
|
|
202
207
|
v-model="model"
|
|
203
|
-
:class="['w-full', { 'p-invalid': showErrors }]"
|
|
208
|
+
:class="['w-full!', { 'p-invalid': showErrors }]"
|
|
204
209
|
:options="options"
|
|
205
210
|
option-label="label"
|
|
206
211
|
option-value="value"
|
|
@@ -214,8 +219,6 @@ const model = computed<unknown[]>({
|
|
|
214
219
|
<small v-if="error" class="p-error" role="alert"
|
|
215
220
|
>Failed to load: {{ error }}</small
|
|
216
221
|
>
|
|
217
|
-
<small v-else-if="showErrors" class="p-error">{{
|
|
218
|
-
projectedErrors
|
|
219
|
-
}}</small>
|
|
222
|
+
<small v-else-if="showErrors" class="p-error">{{ projectedErrors }}</small>
|
|
220
223
|
</div>
|
|
221
224
|
</template>
|
|
@@ -50,7 +50,12 @@ import InputNumber from "primevue/inputnumber";
|
|
|
50
50
|
const instance = getCurrentInstance()!;
|
|
51
51
|
const props = instance.props as unknown as ControlProps;
|
|
52
52
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
53
|
-
const {
|
|
53
|
+
const {
|
|
54
|
+
projectedData,
|
|
55
|
+
handleProjectedChange: handleChange,
|
|
56
|
+
projectedErrors,
|
|
57
|
+
projectedLabel,
|
|
58
|
+
} = useProjection(control, rawHandleChange);
|
|
54
59
|
|
|
55
60
|
const options = computed(
|
|
56
61
|
() =>
|
|
@@ -110,16 +115,14 @@ const onNumber = (val: number | null) => {
|
|
|
110
115
|
</script>
|
|
111
116
|
|
|
112
117
|
<template>
|
|
113
|
-
<div class="
|
|
114
|
-
<label v-if="projectedLabel" class="
|
|
115
|
-
|
|
116
|
-
}}</label>
|
|
117
|
-
<div v-if="control.description" class="text-color-secondary text-left">
|
|
118
|
+
<div class="jf-control">
|
|
119
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
120
|
+
<div v-if="control.description" class="jf-description">
|
|
118
121
|
{{ control.description }}
|
|
119
122
|
</div>
|
|
120
123
|
<InputNumber
|
|
121
|
-
:class="['w-full', { 'p-invalid': showErrors }]"
|
|
122
|
-
:input-class="['w-full', { 'p-invalid': showErrors }]"
|
|
124
|
+
:class="['w-full!', { 'p-invalid': showErrors }]"
|
|
125
|
+
:input-class="['w-full!', { 'p-invalid': showErrors }]"
|
|
123
126
|
:use-grouping="useGrouping"
|
|
124
127
|
:mode="mode"
|
|
125
128
|
:currency="currency"
|
|
@@ -52,7 +52,12 @@ import AutoComplete from "primevue/autocomplete";
|
|
|
52
52
|
const instance = getCurrentInstance()!;
|
|
53
53
|
const props = instance.props as unknown as ControlProps;
|
|
54
54
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
55
|
-
const {
|
|
55
|
+
const {
|
|
56
|
+
projectedData,
|
|
57
|
+
handleProjectedChange: handleChange,
|
|
58
|
+
projectedErrors,
|
|
59
|
+
projectedLabel,
|
|
60
|
+
} = useProjection(control, rawHandleChange);
|
|
56
61
|
|
|
57
62
|
// Provider support for autocomplete functionality
|
|
58
63
|
const binding = computed(() => {
|
|
@@ -150,16 +155,14 @@ const onSelect = (event: { value?: { value?: unknown } | unknown }) => {
|
|
|
150
155
|
</script>
|
|
151
156
|
|
|
152
157
|
<template>
|
|
153
|
-
<div class="
|
|
154
|
-
<label v-if="projectedLabel" class="
|
|
155
|
-
|
|
156
|
-
}}</label>
|
|
157
|
-
<div v-if="control.description" class="text-color-secondary text-left">
|
|
158
|
+
<div class="jf-control">
|
|
159
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
160
|
+
<div v-if="control.description" class="jf-description">
|
|
158
161
|
{{ control.description }}
|
|
159
162
|
</div>
|
|
160
163
|
<AutoComplete
|
|
161
164
|
v-if="isAutocomplete"
|
|
162
|
-
:class="['w-full', { 'p-invalid': showErrors }]"
|
|
165
|
+
:class="['w-full!', { 'p-invalid': showErrors }]"
|
|
163
166
|
:model-value="projectedData ?? ''"
|
|
164
167
|
:suggestions="items"
|
|
165
168
|
option-label="label"
|
|
@@ -173,7 +176,7 @@ const onSelect = (event: { value?: { value?: unknown } | unknown }) => {
|
|
|
173
176
|
/>
|
|
174
177
|
<InputText
|
|
175
178
|
v-else
|
|
176
|
-
:class="['w-full', { 'p-invalid': showErrors }]"
|
|
179
|
+
:class="['w-full!', { 'p-invalid': showErrors }]"
|
|
177
180
|
:model-value="(projectedData as string) ?? ''"
|
|
178
181
|
:disabled="!control.enabled"
|
|
179
182
|
:aria-invalid="showErrors || undefined"
|
|
@@ -49,7 +49,12 @@ import Textarea from "primevue/textarea";
|
|
|
49
49
|
const instance = getCurrentInstance()!;
|
|
50
50
|
const props = instance.props as unknown as ControlProps;
|
|
51
51
|
const { control, handleChange: rawHandleChange } = useJsonFormsControl(props);
|
|
52
|
-
const {
|
|
52
|
+
const {
|
|
53
|
+
projectedData,
|
|
54
|
+
handleProjectedChange: handleChange,
|
|
55
|
+
projectedErrors,
|
|
56
|
+
projectedLabel,
|
|
57
|
+
} = useProjection(control, rawHandleChange);
|
|
53
58
|
|
|
54
59
|
const placeholder = computed<string | undefined>(
|
|
55
60
|
() =>
|
|
@@ -79,15 +84,13 @@ function onBlur() {
|
|
|
79
84
|
</script>
|
|
80
85
|
|
|
81
86
|
<template>
|
|
82
|
-
<div class="
|
|
83
|
-
<label v-if="projectedLabel" class="
|
|
84
|
-
|
|
85
|
-
}}</label>
|
|
86
|
-
<div v-if="control.description" class="text-color-secondary text-left">
|
|
87
|
+
<div class="jf-control">
|
|
88
|
+
<label v-if="projectedLabel" class="jf-label">{{ projectedLabel }}</label>
|
|
89
|
+
<div v-if="control.description" class="jf-description">
|
|
87
90
|
{{ control.description }}
|
|
88
91
|
</div>
|
|
89
92
|
<Textarea
|
|
90
|
-
:class="['w-full', { 'p-invalid': showErrors }]"
|
|
93
|
+
:class="['w-full!', { 'p-invalid': showErrors }]"
|
|
91
94
|
:model-value="(projectedData as string) ?? ''"
|
|
92
95
|
:disabled="!control.enabled"
|
|
93
96
|
:aria-invalid="showErrors || undefined"
|
|
@@ -19,13 +19,38 @@ const injectLayoutStyles = () => {
|
|
|
19
19
|
display: flex;
|
|
20
20
|
flex-direction: column;
|
|
21
21
|
align-items: flex-start;
|
|
22
|
-
gap:
|
|
22
|
+
gap: 24px;
|
|
23
23
|
width: 100%;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
.vertical-layout-item {
|
|
27
27
|
width: 100%;
|
|
28
28
|
}
|
|
29
|
+
|
|
30
|
+
/* Form control wrapper */
|
|
31
|
+
.jf-control {
|
|
32
|
+
display: flex;
|
|
33
|
+
flex-direction: column;
|
|
34
|
+
gap: 12px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Form control label typography */
|
|
38
|
+
.jf-label {
|
|
39
|
+
font-weight: 600;
|
|
40
|
+
font-size: 14px;
|
|
41
|
+
line-height: 14px;
|
|
42
|
+
color: #031553;
|
|
43
|
+
text-align: left;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Form control description typography */
|
|
47
|
+
.jf-description {
|
|
48
|
+
font-weight: 400;
|
|
49
|
+
font-size: 14px;
|
|
50
|
+
line-height: 14px;
|
|
51
|
+
color: #415290;
|
|
52
|
+
text-align: left;
|
|
53
|
+
}
|
|
29
54
|
`;
|
|
30
55
|
document.head.appendChild(style);
|
|
31
56
|
}
|
|
@@ -102,47 +127,103 @@ export function registerPrimevueRenderers(jsonformsCore: any): unknown[] {
|
|
|
102
127
|
|
|
103
128
|
// Projection-aware schema check: when options.projection is set,
|
|
104
129
|
// resolve the projected schema and test against it instead of the original
|
|
105
|
-
|
|
106
|
-
const projectedSchemaMatches =
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
130
|
+
|
|
131
|
+
const projectedSchemaMatches =
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
|
+
(check: (schema: any) => boolean) =>
|
|
134
|
+
(uischema: unknown, schema: unknown): boolean => {
|
|
135
|
+
const ui = uischema as {
|
|
136
|
+
type?: string;
|
|
137
|
+
scope?: string;
|
|
138
|
+
options?: { projection?: string };
|
|
139
|
+
};
|
|
140
|
+
const projection = ui?.options?.projection;
|
|
141
|
+
if (!projection || ui?.type !== "Control" || !ui?.scope) return false;
|
|
142
|
+
|
|
143
|
+
const propertySchema = resolveScopeSchema(
|
|
144
|
+
ui.scope,
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
146
|
+
schema as Record<string, any>,
|
|
147
|
+
);
|
|
148
|
+
if (!propertySchema) return false;
|
|
149
|
+
|
|
150
|
+
return check(getProjectedSchema(propertySchema, projection));
|
|
151
|
+
};
|
|
118
152
|
|
|
119
153
|
const isMultilineProjection = (uischema: unknown, schema: unknown) => {
|
|
120
154
|
const ui = uischema as { options?: { multi?: boolean } };
|
|
121
|
-
return
|
|
122
|
-
|
|
155
|
+
return (
|
|
156
|
+
ui?.options?.multi === true &&
|
|
157
|
+
projectedSchemaMatches((s) => s?.type === "string")(uischema, schema)
|
|
158
|
+
);
|
|
123
159
|
};
|
|
124
160
|
|
|
125
161
|
const renderers = [
|
|
126
162
|
// Multiline text has higher priority than regular text
|
|
127
|
-
{ tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)), renderer: JfTextArea },
|
|
128
|
-
{ tester: rankWith(PRIME + 3, or(isStringControl, projectedSchemaMatches((s) => s?.type === "string"))), renderer: JfText },
|
|
129
163
|
{
|
|
130
|
-
tester: rankWith(PRIME +
|
|
164
|
+
tester: rankWith(PRIME + 4, or(isMultilineString, isMultilineProjection)),
|
|
165
|
+
renderer: JfTextArea,
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
tester: rankWith(
|
|
169
|
+
PRIME + 3,
|
|
170
|
+
or(
|
|
171
|
+
isStringControl,
|
|
172
|
+
projectedSchemaMatches((s) => s?.type === "string"),
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
renderer: JfText,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
tester: rankWith(
|
|
179
|
+
PRIME + 6,
|
|
180
|
+
or(
|
|
181
|
+
isIntegerControl,
|
|
182
|
+
projectedSchemaMatches((s) => s?.type === "integer"),
|
|
183
|
+
),
|
|
184
|
+
),
|
|
131
185
|
renderer: JfNumber,
|
|
132
186
|
},
|
|
133
187
|
{
|
|
134
|
-
tester: rankWith(
|
|
188
|
+
tester: rankWith(
|
|
189
|
+
PRIME + 4,
|
|
190
|
+
or(
|
|
191
|
+
isNumberControl,
|
|
192
|
+
projectedSchemaMatches((s) => s?.type === "number"),
|
|
193
|
+
),
|
|
194
|
+
),
|
|
135
195
|
renderer: JfNumber,
|
|
136
196
|
},
|
|
137
197
|
{
|
|
138
|
-
tester: rankWith(
|
|
198
|
+
tester: rankWith(
|
|
199
|
+
PRIME + 7,
|
|
200
|
+
or(
|
|
201
|
+
and(isControl, schemaMatches(isScalarEnum)),
|
|
202
|
+
and(isControl, projectedSchemaMatches(isScalarEnum)),
|
|
203
|
+
),
|
|
204
|
+
),
|
|
139
205
|
renderer: JfEnum,
|
|
140
206
|
},
|
|
141
207
|
{
|
|
142
|
-
tester: rankWith(
|
|
208
|
+
tester: rankWith(
|
|
209
|
+
PRIME + 8,
|
|
210
|
+
or(
|
|
211
|
+
and(isControl, schemaMatches(isEnumArray)),
|
|
212
|
+
and(isControl, projectedSchemaMatches(isEnumArray)),
|
|
213
|
+
),
|
|
214
|
+
),
|
|
143
215
|
renderer: JfEnumArray,
|
|
144
216
|
},
|
|
145
|
-
{
|
|
217
|
+
{
|
|
218
|
+
tester: rankWith(
|
|
219
|
+
PRIME + 3,
|
|
220
|
+
or(
|
|
221
|
+
isBooleanControl,
|
|
222
|
+
projectedSchemaMatches((s) => s?.type === "boolean"),
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
renderer: JfBoolean,
|
|
226
|
+
},
|
|
146
227
|
];
|
|
147
228
|
|
|
148
229
|
// Update the exported array
|
package/src/vue/styles.css
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
display: flex;
|
|
6
6
|
flex-direction: column;
|
|
7
7
|
align-items: flex-start;
|
|
8
|
-
gap:
|
|
8
|
+
gap: 24px;
|
|
9
9
|
width: 100%;
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -14,6 +14,31 @@
|
|
|
14
14
|
width: 100%;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/* Form control wrapper */
|
|
18
|
+
.jf-control {
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
gap: 12px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Form control label typography */
|
|
25
|
+
.jf-label {
|
|
26
|
+
font-weight: 600;
|
|
27
|
+
font-size: 14px;
|
|
28
|
+
line-height: 14px;
|
|
29
|
+
color: #031553;
|
|
30
|
+
text-align: left;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* Form control description typography */
|
|
34
|
+
.jf-description {
|
|
35
|
+
font-weight: 400;
|
|
36
|
+
font-size: 14px;
|
|
37
|
+
line-height: 14px;
|
|
38
|
+
color: #415290;
|
|
39
|
+
text-align: left;
|
|
40
|
+
}
|
|
41
|
+
|
|
17
42
|
/* PrimeVue dropdown text alignment fix */
|
|
18
43
|
.p-dropdown-label {
|
|
19
44
|
text-align: left !important;
|
|
@@ -57,7 +57,7 @@ export interface AutoSelectMultiParams {
|
|
|
57
57
|
* - Current value is empty array OR current selection is not in the current options
|
|
58
58
|
*/
|
|
59
59
|
export function shouldAutoSelectMulti(
|
|
60
|
-
params: AutoSelectMultiParams
|
|
60
|
+
params: AutoSelectMultiParams,
|
|
61
61
|
): unknown[] | null {
|
|
62
62
|
const { autoSelectSingle, isLoading, items, currentValue } = params;
|
|
63
63
|
|
|
@@ -73,7 +73,7 @@ export function shouldAutoSelectMulti(
|
|
|
73
73
|
const currentArray = Array.isArray(currentValue) ? currentValue : [];
|
|
74
74
|
const isValueEmpty = currentArray.length === 0;
|
|
75
75
|
const hasValidSelection = currentArray.some((val) =>
|
|
76
|
-
items.some((item) => item.value === val)
|
|
76
|
+
items.some((item) => item.value === val),
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
if (isValueEmpty || !hasValidSelection) {
|