@descope/web-components-ui 1.0.239 → 1.0.241
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/cjs/index.cjs.js +1455 -897
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1437 -879
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/1000.js +1 -1
- package/dist/umd/1438.js +374 -0
- package/dist/umd/1438.js.LICENSE.txt +5 -0
- package/dist/umd/1940.js +303 -0
- package/dist/umd/{849.js → 4595.js} +5 -5
- package/dist/umd/63.js +2 -0
- package/dist/umd/63.js.LICENSE.txt +5 -0
- package/dist/umd/6687.js +9 -0
- package/dist/umd/6687.js.LICENSE.txt +5 -0
- package/dist/umd/7583.js +113 -0
- package/dist/umd/{5977.js.LICENSE.txt → 7583.js.LICENSE.txt} +0 -6
- package/dist/umd/8866.js +183 -0
- package/dist/umd/8866.js.LICENSE.txt +11 -0
- package/dist/umd/9558.js +1 -1
- package/dist/umd/descope-combo-box-index-js.js +1 -1
- package/dist/umd/descope-grid-index-js.js +1 -1
- package/dist/umd/descope-modal-index-js.js +1 -1
- package/dist/umd/descope-multi-select-combo-box-index-js.js +1 -0
- package/dist/umd/index.js +1 -1
- package/dist/umd/phone-fields-descope-phone-field-index-js.js +1 -1
- package/dist/umd/phone-fields-descope-phone-input-box-field-index-js.js +1 -1
- package/package.json +2 -1
- package/src/components/descope-multi-select-combo-box/MultiSelectComboBoxClass.js +515 -0
- package/src/components/descope-multi-select-combo-box/index.js +6 -0
- package/src/mixins/inputValidationMixin.js +13 -6
- package/src/theme/components/index.js +2 -0
- package/src/theme/components/inputWrapper.js +4 -4
- package/src/theme/components/multiSelectComboBox.js +57 -0
- package/dist/umd/1932.js +0 -310
- package/dist/umd/5977.js +0 -294
- /package/dist/umd/{1932.js.LICENSE.txt → 1940.js.LICENSE.txt} +0 -0
- /package/dist/umd/{849.js.LICENSE.txt → 4595.js.LICENSE.txt} +0 -0
@@ -0,0 +1,515 @@
|
|
1
|
+
import { compose } from '../../helpers';
|
2
|
+
import {
|
3
|
+
forwardAttrs,
|
4
|
+
getComponentName,
|
5
|
+
observeAttributes,
|
6
|
+
observeChildren,
|
7
|
+
} from '../../helpers/componentHelpers';
|
8
|
+
import {
|
9
|
+
resetInputLabelPosition,
|
10
|
+
resetInputCursor,
|
11
|
+
resetInputPlaceholder,
|
12
|
+
resetInputReadonlyStyle,
|
13
|
+
useHostExternalPadding,
|
14
|
+
} from '../../helpers/themeHelpers/resetHelpers';
|
15
|
+
import {
|
16
|
+
createStyleMixin,
|
17
|
+
draggableMixin,
|
18
|
+
createProxy,
|
19
|
+
componentNameValidationMixin,
|
20
|
+
portalMixin,
|
21
|
+
proxyInputMixin,
|
22
|
+
} from '../../mixins';
|
23
|
+
|
24
|
+
export const componentName = getComponentName('multi-select-combo-box');
|
25
|
+
|
26
|
+
const MultiSelectComboBoxMixin = (superclass) =>
|
27
|
+
class MultiSelectComboBoxMixinClass extends superclass {
|
28
|
+
// eslint-disable-next-line class-methods-use-this
|
29
|
+
#renderItem = ({ displayName, value, label }) => {
|
30
|
+
return `<span data-name="${label}" data-id="${value}">${displayName || label}</span>`;
|
31
|
+
};
|
32
|
+
|
33
|
+
#data;
|
34
|
+
|
35
|
+
get defaultValues() {
|
36
|
+
const defaultValuesAttr = this.getAttribute('default-values');
|
37
|
+
if (defaultValuesAttr) {
|
38
|
+
try {
|
39
|
+
const defaultValues = JSON.parse(defaultValuesAttr);
|
40
|
+
if (this.isValidDataType(defaultValues)) {
|
41
|
+
return defaultValues;
|
42
|
+
}
|
43
|
+
} catch (e) {
|
44
|
+
// eslint-disable-next-line no-console
|
45
|
+
console.error('could not parse data string from attribute "default-values" -', e.message);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
return [];
|
49
|
+
}
|
50
|
+
|
51
|
+
get renderItem() {
|
52
|
+
return this.#renderItem;
|
53
|
+
}
|
54
|
+
|
55
|
+
set renderItem(renderFn) {
|
56
|
+
this.#renderItem = renderFn;
|
57
|
+
this.renderItems();
|
58
|
+
}
|
59
|
+
|
60
|
+
get data() {
|
61
|
+
if (this.#data) return this.#data;
|
62
|
+
|
63
|
+
const dataAttr = this.getAttribute('data');
|
64
|
+
|
65
|
+
if (dataAttr) {
|
66
|
+
try {
|
67
|
+
const data = JSON.parse(dataAttr);
|
68
|
+
if (this.isValidDataType(data)) {
|
69
|
+
return data;
|
70
|
+
}
|
71
|
+
} catch (e) {
|
72
|
+
// eslint-disable-next-line no-console
|
73
|
+
console.error('could not parse data string from attribute "data" -', e.message);
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
return [];
|
78
|
+
}
|
79
|
+
|
80
|
+
set data(data) {
|
81
|
+
if (this.isValidDataType(data)) {
|
82
|
+
this.#data = data;
|
83
|
+
this.renderItems();
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
get allowCustomValue() {
|
88
|
+
return this.getAttribute('allow-custom-value') === 'true';
|
89
|
+
}
|
90
|
+
|
91
|
+
get minItemsSelection() {
|
92
|
+
return parseInt(this.getAttribute('min-items-selection'), 10) || 0;
|
93
|
+
}
|
94
|
+
|
95
|
+
get maxItemsSelection() {
|
96
|
+
return parseInt(this.getAttribute('max-items-selection'), 10) || 0;
|
97
|
+
}
|
98
|
+
|
99
|
+
// eslint-disable-next-line class-methods-use-this
|
100
|
+
isValidDataType(data) {
|
101
|
+
const isValid = Array.isArray(data);
|
102
|
+
if (!isValid) {
|
103
|
+
// eslint-disable-next-line no-console
|
104
|
+
console.error('data and default-values must be an array, received:', data);
|
105
|
+
}
|
106
|
+
|
107
|
+
return isValid;
|
108
|
+
}
|
109
|
+
|
110
|
+
getItemsTemplate() {
|
111
|
+
return this.data?.reduce?.((acc, item) => acc + (this.renderItem?.(item || {}) || ''), '');
|
112
|
+
}
|
113
|
+
|
114
|
+
renderItems() {
|
115
|
+
const template = this.getItemsTemplate();
|
116
|
+
if (template) this.innerHTML = template;
|
117
|
+
}
|
118
|
+
|
119
|
+
handleSelectedItems() {
|
120
|
+
const currentSelected =
|
121
|
+
this.baseElement.selectedItems?.map((item) => item.getAttribute('data-id')) || [];
|
122
|
+
|
123
|
+
this.baseElement.selectedItems = [];
|
124
|
+
|
125
|
+
// if previously selected item ID exists in current children, set it as selected
|
126
|
+
if (currentSelected.length > 0) {
|
127
|
+
this.value = currentSelected;
|
128
|
+
}
|
129
|
+
|
130
|
+
// otherwise, if default value is specified, set default value as selected item
|
131
|
+
if (this.value.length === 0) {
|
132
|
+
this.setDefaultValues();
|
133
|
+
}
|
134
|
+
}
|
135
|
+
|
136
|
+
// eslint-disable-next-line class-methods-use-this
|
137
|
+
customValueTransformFn(val) {
|
138
|
+
return val;
|
139
|
+
}
|
140
|
+
|
141
|
+
// We want to override Vaadin's Combo Box value setter. This is needed since Vaadin couples between the
|
142
|
+
// field that it searches the value, and the finaly display value of the input.
|
143
|
+
// We provide a custom transform function to override that behavior.
|
144
|
+
setComboBoxDescriptor() {
|
145
|
+
const valueDescriptor = Object.getOwnPropertyDescriptor(
|
146
|
+
this.inputElement.constructor.prototype,
|
147
|
+
'value'
|
148
|
+
);
|
149
|
+
|
150
|
+
const comboBox = this;
|
151
|
+
|
152
|
+
Object.defineProperties(this.inputElement, {
|
153
|
+
value: {
|
154
|
+
...valueDescriptor,
|
155
|
+
set(val) {
|
156
|
+
const transformedValue = comboBox.customValueTransformFn(val) || '';
|
157
|
+
|
158
|
+
if (transformedValue === this.value) {
|
159
|
+
return;
|
160
|
+
}
|
161
|
+
|
162
|
+
valueDescriptor.set.call(this, transformedValue);
|
163
|
+
},
|
164
|
+
},
|
165
|
+
});
|
166
|
+
}
|
167
|
+
|
168
|
+
// vaadin api is to set props on their combo box node,
|
169
|
+
// in order to avoid it, we are passing the children of this component
|
170
|
+
// to the items & renderer props, so it will be used as the combo box items
|
171
|
+
#onChildrenChange() {
|
172
|
+
const items = Array.from(this.children);
|
173
|
+
|
174
|
+
// we want the data-name attribute to be accessible as an object attribute
|
175
|
+
if (items.length) {
|
176
|
+
this.removeAttribute('has-no-options');
|
177
|
+
|
178
|
+
items.forEach((node) => {
|
179
|
+
Object.defineProperty(node, 'data-name', {
|
180
|
+
value: node.getAttribute('data-name'),
|
181
|
+
configurable: true,
|
182
|
+
writable: true,
|
183
|
+
});
|
184
|
+
Object.defineProperty(node, 'data-id', {
|
185
|
+
value: node.getAttribute('data-id'),
|
186
|
+
configurable: true,
|
187
|
+
writable: true,
|
188
|
+
});
|
189
|
+
});
|
190
|
+
|
191
|
+
this.baseElement.items = items;
|
192
|
+
|
193
|
+
setTimeout(() => {
|
194
|
+
// set timeout to ensure this runs after customValueTransformFn had the chance to be overriden
|
195
|
+
this.handleSelectedItems();
|
196
|
+
}, 0);
|
197
|
+
} else {
|
198
|
+
this.baseElement.items = [];
|
199
|
+
this.setAttribute('has-no-options', '');
|
200
|
+
}
|
201
|
+
|
202
|
+
// use vaadin combobox custom renderer to render options as HTML
|
203
|
+
// and not via default renderer, which renders only the data-name's value
|
204
|
+
// in its own HTML template
|
205
|
+
this.baseElement.renderer = (root, combo, model) => {
|
206
|
+
// eslint-disable-next-line no-param-reassign
|
207
|
+
root.innerHTML = model.item.outerHTML;
|
208
|
+
};
|
209
|
+
}
|
210
|
+
|
211
|
+
// the default vaadin behavior is to attach the overlay to the body when opened
|
212
|
+
// we do not want that because it's difficult to style the overlay in this way
|
213
|
+
// so we override it to open inside the shadow DOM
|
214
|
+
#overrideOverlaySettings() {
|
215
|
+
const overlay = this.baseElement.shadowRoot
|
216
|
+
.querySelector('vaadin-multi-select-combo-box-internal')
|
217
|
+
.shadowRoot.querySelector('vaadin-multi-select-combo-box-overlay');
|
218
|
+
overlay._attachOverlay = () => {
|
219
|
+
overlay.bringToFront();
|
220
|
+
};
|
221
|
+
overlay._detachOverlay = () => {};
|
222
|
+
overlay._enterModalState = () => {};
|
223
|
+
}
|
224
|
+
|
225
|
+
#handleCustomValues() {
|
226
|
+
if (this.allowCustomValue) {
|
227
|
+
this.baseElement.addEventListener('custom-value-set', (e) => {
|
228
|
+
const newItemHtml = this.#renderItem({
|
229
|
+
label: e.detail,
|
230
|
+
displayName: e.detail,
|
231
|
+
value: e.detail,
|
232
|
+
});
|
233
|
+
this.innerHTML += newItemHtml;
|
234
|
+
// The value needs to be set with a timeout because it needs to execute after
|
235
|
+
// the custom value is added to items by the children change observer
|
236
|
+
setTimeout(() => {
|
237
|
+
this.value = [...this.value, e.detail];
|
238
|
+
}, 0);
|
239
|
+
});
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
setGetValidity() {
|
244
|
+
// eslint-disable-next-line func-names
|
245
|
+
this.getValidity = function () {
|
246
|
+
if (this.isRequired && !this.value.length) {
|
247
|
+
return {
|
248
|
+
valueMissing: true,
|
249
|
+
};
|
250
|
+
}
|
251
|
+
// If the field is not required, no minimum selection can be set
|
252
|
+
if (
|
253
|
+
this.isRequired &&
|
254
|
+
this.minItemsSelection &&
|
255
|
+
this.value.length < this.minItemsSelection
|
256
|
+
) {
|
257
|
+
return {
|
258
|
+
rangeUnderflow: true,
|
259
|
+
};
|
260
|
+
}
|
261
|
+
if (this.maxItemsSelection && this.value.length > this.maxItemsSelection) {
|
262
|
+
return {
|
263
|
+
rangeOverflow: true,
|
264
|
+
};
|
265
|
+
}
|
266
|
+
return {};
|
267
|
+
};
|
268
|
+
}
|
269
|
+
|
270
|
+
init() {
|
271
|
+
super.init?.();
|
272
|
+
|
273
|
+
this.setGetValidity();
|
274
|
+
|
275
|
+
this.setComboBoxDescriptor();
|
276
|
+
|
277
|
+
this.#overrideOverlaySettings();
|
278
|
+
|
279
|
+
this.#handleCustomValues();
|
280
|
+
|
281
|
+
this.renderItems();
|
282
|
+
|
283
|
+
observeAttributes(this, this.renderItems.bind(this), { includeAttrs: ['data'] });
|
284
|
+
|
285
|
+
observeChildren(this, this.#onChildrenChange.bind(this));
|
286
|
+
|
287
|
+
// Note: we need to forward the `placeholder` because the vaadin component observes it and
|
288
|
+
// tries to override it, causing us to lose the user set placeholder.
|
289
|
+
forwardAttrs(this, this.baseElement, { includeAttrs: ['placeholder'] });
|
290
|
+
|
291
|
+
this.setDefaultValues();
|
292
|
+
}
|
293
|
+
|
294
|
+
setDefaultValues() {
|
295
|
+
this.value = this.defaultValues;
|
296
|
+
}
|
297
|
+
|
298
|
+
set value(vals) {
|
299
|
+
if (vals && vals.length > 0) {
|
300
|
+
const children = this.baseElement.items?.filter((item) => vals.includes(item['data-id']));
|
301
|
+
|
302
|
+
if (children?.length > 0) {
|
303
|
+
this.baseElement.selectedItems = children;
|
304
|
+
}
|
305
|
+
} else {
|
306
|
+
this.baseElement.selectedItems = [];
|
307
|
+
}
|
308
|
+
}
|
309
|
+
|
310
|
+
get value() {
|
311
|
+
return this.baseElement.selectedItems.map((elem) => elem.getAttribute('data-id')) || [];
|
312
|
+
}
|
313
|
+
};
|
314
|
+
|
315
|
+
const {
|
316
|
+
host,
|
317
|
+
inputField,
|
318
|
+
inputElement,
|
319
|
+
placeholder,
|
320
|
+
toggle,
|
321
|
+
label,
|
322
|
+
requiredIndicator,
|
323
|
+
helperText,
|
324
|
+
errorMessage,
|
325
|
+
chip,
|
326
|
+
chipLabel,
|
327
|
+
overflowChipFirstBorder,
|
328
|
+
overflowChipSecondBorder,
|
329
|
+
} = {
|
330
|
+
host: { selector: () => ':host' },
|
331
|
+
inputField: { selector: '::part(input-field)' },
|
332
|
+
inputElement: { selector: 'input' },
|
333
|
+
placeholder: { selector: '> input:placeholder-shown' },
|
334
|
+
toggle: { selector: '::part(toggle-button)' },
|
335
|
+
label: { selector: '::part(label)' },
|
336
|
+
requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
|
337
|
+
helperText: { selector: '::part(helper-text)' },
|
338
|
+
errorMessage: { selector: '::part(error-message)' },
|
339
|
+
chip: { selector: 'vaadin-multi-select-combo-box-chip' },
|
340
|
+
chipLabel: { selector: 'vaadin-multi-select-combo-box-chip::part(label)' },
|
341
|
+
overflowChipFirstBorder: {
|
342
|
+
selector: "vaadin-multi-select-combo-box-chip[slot='overflow']::before",
|
343
|
+
},
|
344
|
+
overflowChipSecondBorder: {
|
345
|
+
selector: "vaadin-multi-select-combo-box-chip[slot='overflow']::after",
|
346
|
+
},
|
347
|
+
};
|
348
|
+
|
349
|
+
export const MultiSelectComboBoxClass = compose(
|
350
|
+
createStyleMixin({
|
351
|
+
mappings: {
|
352
|
+
hostWidth: { ...host, property: 'width' },
|
353
|
+
hostDirection: { ...host, property: 'direction' },
|
354
|
+
// we apply font-size also on the host so we can set its width with em
|
355
|
+
fontSize: [{}, host],
|
356
|
+
chipFontSize: { ...chipLabel, property: 'font-size' },
|
357
|
+
fontFamily: [label, placeholder, inputField, helperText, errorMessage, chipLabel],
|
358
|
+
labelTextColor: [
|
359
|
+
{ ...label, property: 'color' },
|
360
|
+
{ ...requiredIndicator, property: 'color' },
|
361
|
+
],
|
362
|
+
errorMessageTextColor: { ...errorMessage, property: 'color' },
|
363
|
+
inputHeight: { ...inputField, property: 'min-height' },
|
364
|
+
inputBackgroundColor: { ...inputField, property: 'background-color' },
|
365
|
+
inputBorderColor: { ...inputField, property: 'border-color' },
|
366
|
+
inputBorderWidth: { ...inputField, property: 'border-width' },
|
367
|
+
inputBorderStyle: { ...inputField, property: 'border-style' },
|
368
|
+
inputBorderRadius: { ...inputField, property: 'border-radius' },
|
369
|
+
labelRequiredIndicator: { ...requiredIndicator, property: 'content' },
|
370
|
+
inputValueTextColor: { ...inputField, property: 'color' },
|
371
|
+
inputPlaceholderTextColor: { ...placeholder, property: 'color' },
|
372
|
+
inputDropdownButtonCursor: { ...toggle, property: 'cursor' },
|
373
|
+
inputDropdownButtonColor: { ...toggle, property: 'color' },
|
374
|
+
inputDropdownButtonSize: { ...toggle, property: 'font-size' },
|
375
|
+
inputDropdownButtonOffset: [
|
376
|
+
{ ...toggle, property: 'margin-right' },
|
377
|
+
{ ...toggle, property: 'margin-left' },
|
378
|
+
],
|
379
|
+
inputOutlineColor: { ...inputField, property: 'outline-color' },
|
380
|
+
inputOutlineWidth: { ...inputField, property: 'outline-width' },
|
381
|
+
inputOutlineStyle: { ...inputField, property: 'outline-style' },
|
382
|
+
inputOutlineOffset: { ...inputField, property: 'outline-offset' },
|
383
|
+
inputHorizontalPadding: [
|
384
|
+
{ ...inputElement, property: 'padding-left' },
|
385
|
+
{ ...inputElement, property: 'padding-right' },
|
386
|
+
{ ...inputField, property: 'padding-inline-start' },
|
387
|
+
],
|
388
|
+
inputVerticalPadding: [
|
389
|
+
{ ...inputField, property: 'padding-top' },
|
390
|
+
{ ...inputField, property: 'padding-bottom' },
|
391
|
+
],
|
392
|
+
chipTextColor: { ...chipLabel, property: 'color' },
|
393
|
+
chipBackgroundColor: [
|
394
|
+
{ ...chip, property: 'background-color' },
|
395
|
+
{ ...overflowChipFirstBorder, property: 'border-color' },
|
396
|
+
{ ...overflowChipSecondBorder, property: 'border-color' },
|
397
|
+
],
|
398
|
+
|
399
|
+
// we need to use the variables from the portal mixin
|
400
|
+
// so we need to use an arrow function on the selector
|
401
|
+
// for that to work, because ComboBox is not available
|
402
|
+
// at this time.
|
403
|
+
overlayBackground: {
|
404
|
+
property: () => MultiSelectComboBoxClass.cssVarList.overlay.backgroundColor,
|
405
|
+
},
|
406
|
+
overlayBorder: { property: () => MultiSelectComboBoxClass.cssVarList.overlay.border },
|
407
|
+
overlayFontSize: { property: () => MultiSelectComboBoxClass.cssVarList.overlay.fontSize },
|
408
|
+
overlayFontFamily: { property: () => MultiSelectComboBoxClass.cssVarList.overlay.fontFamily },
|
409
|
+
overlayCursor: { property: () => MultiSelectComboBoxClass.cssVarList.overlay.cursor },
|
410
|
+
overlayItemBoxShadow: {
|
411
|
+
property: () => MultiSelectComboBoxClass.cssVarList.overlay.itemBoxShadow,
|
412
|
+
},
|
413
|
+
overlayItemPaddingInlineStart: {
|
414
|
+
property: () => MultiSelectComboBoxClass.cssVarList.overlay.itemPaddingInlineStart,
|
415
|
+
},
|
416
|
+
overlayItemPaddingInlineEnd: {
|
417
|
+
property: () => MultiSelectComboBoxClass.cssVarList.overlay.itemPaddingInlineEnd,
|
418
|
+
},
|
419
|
+
},
|
420
|
+
}),
|
421
|
+
draggableMixin,
|
422
|
+
portalMixin({
|
423
|
+
name: 'overlay',
|
424
|
+
selector: 'vaadin-multi-select-combo-box-internal',
|
425
|
+
mappings: {
|
426
|
+
backgroundColor: { selector: 'vaadin-multi-select-combo-box-scroller' },
|
427
|
+
minHeight: { selector: 'vaadin-multi-select-combo-box-overlay' },
|
428
|
+
margin: { selector: 'vaadin-multi-select-combo-box-overlay' },
|
429
|
+
cursor: { selector: 'vaadin-multi-select-combo-box-item' },
|
430
|
+
fontFamily: { selector: 'vaadin-multi-select-combo-box-item' },
|
431
|
+
fontSize: { selector: 'vaadin-multi-select-combo-box-item' },
|
432
|
+
itemBoxShadow: { selector: 'vaadin-multi-select-combo-box-item', property: 'box-shadow' },
|
433
|
+
itemPaddingInlineStart: {
|
434
|
+
selector: 'vaadin-multi-select-combo-box-item',
|
435
|
+
property: 'padding-inline-start',
|
436
|
+
},
|
437
|
+
itemPaddingInlineEnd: {
|
438
|
+
selector: 'vaadin-multi-select-combo-box-item',
|
439
|
+
property: 'padding-inline-end',
|
440
|
+
},
|
441
|
+
},
|
442
|
+
forward: {
|
443
|
+
include: false,
|
444
|
+
attributes: ['size'],
|
445
|
+
},
|
446
|
+
}),
|
447
|
+
proxyInputMixin({ proxyProps: ['selectionStart'], inputEvent: 'selected-items-changed' }),
|
448
|
+
componentNameValidationMixin,
|
449
|
+
MultiSelectComboBoxMixin
|
450
|
+
)(
|
451
|
+
createProxy({
|
452
|
+
slots: ['', 'prefix'],
|
453
|
+
wrappedEleName: 'vaadin-multi-select-combo-box',
|
454
|
+
style: () => `
|
455
|
+
:host {
|
456
|
+
display: inline-flex;
|
457
|
+
box-sizing: border-box;
|
458
|
+
-webkit-mask-image: none;
|
459
|
+
}
|
460
|
+
${useHostExternalPadding(MultiSelectComboBoxClass.cssVarList)}
|
461
|
+
${resetInputReadonlyStyle('vaadin-multi-select-combo-box')}
|
462
|
+
${resetInputPlaceholder('vaadin-multi-select-combo-box')}
|
463
|
+
${resetInputCursor('vaadin-multi-select-combo-box')}
|
464
|
+
|
465
|
+
vaadin-multi-select-combo-box {
|
466
|
+
padding: 0;
|
467
|
+
width: 100%;
|
468
|
+
}
|
469
|
+
vaadin-multi-select-combo-box::before {
|
470
|
+
height: initial;
|
471
|
+
}
|
472
|
+
vaadin-multi-select-combo-box [slot="input"] {
|
473
|
+
-webkit-mask-image: none;
|
474
|
+
min-height: 0;
|
475
|
+
align-self: center;
|
476
|
+
box-sizing: border-box;
|
477
|
+
}
|
478
|
+
|
479
|
+
::part(input-field) {
|
480
|
+
padding: 0;
|
481
|
+
box-shadow: none;
|
482
|
+
}
|
483
|
+
${resetInputLabelPosition('vaadin-multi-select-combo-box')}
|
484
|
+
:host([has-label]) vaadin-multi-select-combo-box-chip::part(label) {
|
485
|
+
display: block;
|
486
|
+
}
|
487
|
+
|
488
|
+
vaadin-multi-select-combo-box vaadin-multi-select-combo-box-chip[slot='overflow']::before,
|
489
|
+
vaadin-multi-select-combo-box vaadin-multi-select-combo-box-chip[slot='overflow']::after {
|
490
|
+
left: -4px;
|
491
|
+
right: -4px;
|
492
|
+
border-left-width: 0;
|
493
|
+
border-inline-start-style: solid;
|
494
|
+
border-inline-start-width: 2px;
|
495
|
+
}
|
496
|
+
vaadin-multi-select-combo-box vaadin-multi-select-combo-box-chip[slot='overflow']::after {
|
497
|
+
left: -8px;
|
498
|
+
right: -8px;
|
499
|
+
}
|
500
|
+
|
501
|
+
:host([has-no-options][allow-custom-value='true']) ::part(toggle-button) {
|
502
|
+
display: none;
|
503
|
+
}
|
504
|
+
`,
|
505
|
+
// Note: we exclude `size` to avoid overriding Vaadin's ComboBox property
|
506
|
+
// with the same name. Including it will cause Vaadin to calculate NaN size,
|
507
|
+
// and reset items to an empty array, and opening the list box with no items
|
508
|
+
// to display.
|
509
|
+
// Note: we exclude `placeholder` because the vaadin component observes it and
|
510
|
+
// tries to override it, causing us to lose the user set placeholder.
|
511
|
+
excludeAttrsSync: ['tabindex', 'size', 'data', 'placeholder'],
|
512
|
+
componentName,
|
513
|
+
includeForwardProps: ['items', 'renderer', 'selectedItems'],
|
514
|
+
})
|
515
|
+
);
|
@@ -44,6 +44,14 @@ export const inputValidationMixin = (superclass) =>
|
|
44
44
|
return `Maximum length is ${this.getAttribute('maxlength')}. `;
|
45
45
|
}
|
46
46
|
|
47
|
+
get defaultErrorMsgRangeUnderflow() {
|
48
|
+
return `At least ${this.minItemsSelection} items are required.`;
|
49
|
+
}
|
50
|
+
|
51
|
+
get defaultErrorMsgRangeOverflow() {
|
52
|
+
return `At most ${this.maxItemsSelection} items are allowed.`;
|
53
|
+
}
|
54
|
+
|
47
55
|
getErrorMessage(flags) {
|
48
56
|
const {
|
49
57
|
valueMissing,
|
@@ -62,12 +70,7 @@ export const inputValidationMixin = (superclass) =>
|
|
62
70
|
return (
|
63
71
|
this.getAttribute(errorAttributes.valueMissing) || this.defaultErrorMsgValueMissing
|
64
72
|
);
|
65
|
-
case patternMismatch ||
|
66
|
-
typeMismatch ||
|
67
|
-
stepMismatch ||
|
68
|
-
rangeOverflow ||
|
69
|
-
rangeUnderflow ||
|
70
|
-
badInput:
|
73
|
+
case patternMismatch || typeMismatch || stepMismatch || badInput:
|
71
74
|
return (
|
72
75
|
this.getAttribute(errorAttributes.patternMismatch) ||
|
73
76
|
this.defaultErrorMsgPatternMismatch
|
@@ -76,6 +79,10 @@ export const inputValidationMixin = (superclass) =>
|
|
76
79
|
return this.getAttribute(errorAttributes.tooShort) || this.defaultErrorMsgTooShort;
|
77
80
|
case tooLong:
|
78
81
|
return this.getAttribute(errorAttributes.tooLong) || this.defaultErrorMsgTooLong;
|
82
|
+
case rangeUnderflow:
|
83
|
+
return this.defaultErrorMsgRangeUnderflow;
|
84
|
+
case rangeOverflow:
|
85
|
+
return this.defaultErrorMsgRangeOverflow;
|
79
86
|
case customError:
|
80
87
|
return this.validationMessage;
|
81
88
|
default:
|
@@ -26,6 +26,7 @@ import * as buttonSelectionGroup from './buttonSelectionGroup/buttonSelectionGro
|
|
26
26
|
import * as modal from './modal';
|
27
27
|
import * as grid from './grid';
|
28
28
|
import * as notificationCard from './notificationCard';
|
29
|
+
import * as multiSelectComboBox from './multiSelectComboBox';
|
29
30
|
import * as badge from './badge';
|
30
31
|
|
31
32
|
const components = {
|
@@ -58,6 +59,7 @@ const components = {
|
|
58
59
|
modal,
|
59
60
|
grid,
|
60
61
|
notificationCard,
|
62
|
+
multiSelectComboBox,
|
61
63
|
badge,
|
62
64
|
};
|
63
65
|
|
@@ -35,10 +35,10 @@ const [theme, refs, vars] = createHelperVars(
|
|
35
35
|
direction: globalRefs.direction,
|
36
36
|
|
37
37
|
size: {
|
38
|
-
xs: { fontSize: '12px' },
|
39
|
-
sm: { fontSize: '14px' },
|
40
|
-
md: { fontSize: '16px' },
|
41
|
-
lg: { fontSize: '18px' },
|
38
|
+
xs: { fontSize: '12px', chipFontSize: '10px' },
|
39
|
+
sm: { fontSize: '14px', chipFontSize: '12px' },
|
40
|
+
md: { fontSize: '16px', chipFontSize: '14px' },
|
41
|
+
lg: { fontSize: '18px', chipFontSize: '16px' },
|
42
42
|
},
|
43
43
|
|
44
44
|
_fullWidth: {
|
@@ -0,0 +1,57 @@
|
|
1
|
+
import globals from '../globals';
|
2
|
+
import { MultiSelectComboBoxClass } from '../../components/descope-multi-select-combo-box/MultiSelectComboBoxClass';
|
3
|
+
import { getThemeRefs } from '../../helpers/themeHelpers';
|
4
|
+
import { refs } from './inputWrapper';
|
5
|
+
|
6
|
+
const globalRefs = getThemeRefs(globals);
|
7
|
+
const vars = MultiSelectComboBoxClass.cssVarList;
|
8
|
+
|
9
|
+
export const multiSelectComboBox = {
|
10
|
+
[vars.hostWidth]: refs.width,
|
11
|
+
[vars.hostDirection]: refs.direction,
|
12
|
+
[vars.fontSize]: refs.fontSize,
|
13
|
+
[vars.fontFamily]: refs.fontFamily,
|
14
|
+
[vars.labelTextColor]: refs.labelTextColor,
|
15
|
+
[vars.errorMessageTextColor]: refs.errorMessageTextColor,
|
16
|
+
[vars.inputBorderColor]: refs.borderColor,
|
17
|
+
[vars.inputBorderWidth]: refs.borderWidth,
|
18
|
+
[vars.inputBorderStyle]: refs.borderStyle,
|
19
|
+
[vars.inputBorderRadius]: refs.borderRadius,
|
20
|
+
[vars.inputOutlineColor]: refs.outlineColor,
|
21
|
+
[vars.inputOutlineOffset]: refs.outlineOffset,
|
22
|
+
[vars.inputOutlineWidth]: refs.outlineWidth,
|
23
|
+
[vars.inputOutlineStyle]: refs.outlineStyle,
|
24
|
+
[vars.labelRequiredIndicator]: refs.requiredIndicator,
|
25
|
+
[vars.inputValueTextColor]: refs.valueTextColor,
|
26
|
+
[vars.inputPlaceholderTextColor]: refs.placeholderTextColor,
|
27
|
+
[vars.inputBackgroundColor]: refs.backgroundColor,
|
28
|
+
[vars.inputHorizontalPadding]: refs.horizontalPadding,
|
29
|
+
[vars.inputVerticalPadding]: refs.verticalPadding,
|
30
|
+
[vars.inputHeight]: refs.inputHeight,
|
31
|
+
[vars.inputDropdownButtonColor]: globalRefs.colors.surface.contrast,
|
32
|
+
[vars.inputDropdownButtonCursor]: 'pointer',
|
33
|
+
[vars.inputDropdownButtonSize]: refs.toggleButtonSize,
|
34
|
+
[vars.inputDropdownButtonOffset]: globalRefs.spacing.xs,
|
35
|
+
[vars.overlayItemPaddingInlineStart]: globalRefs.spacing.xs,
|
36
|
+
[vars.overlayItemPaddingInlineEnd]: globalRefs.spacing.lg,
|
37
|
+
[vars.chipFontSize]: refs.chipFontSize,
|
38
|
+
[vars.chipTextColor]: refs.valueTextColor,
|
39
|
+
[vars.chipBackgroundColor]: globalRefs.colors.surface.main,
|
40
|
+
|
41
|
+
_readonly: {
|
42
|
+
[vars.inputDropdownButtonCursor]: 'default',
|
43
|
+
},
|
44
|
+
|
45
|
+
// Overlay theme exposed via the component:
|
46
|
+
[vars.overlayFontSize]: refs.fontSize,
|
47
|
+
[vars.overlayFontFamily]: refs.fontFamily,
|
48
|
+
[vars.overlayCursor]: 'pointer',
|
49
|
+
[vars.overlayItemBoxShadow]: 'none',
|
50
|
+
|
51
|
+
// Overlay direct theme:
|
52
|
+
[vars.overlay.minHeight]: '400px',
|
53
|
+
[vars.overlay.margin]: '0',
|
54
|
+
};
|
55
|
+
|
56
|
+
export default multiSelectComboBox;
|
57
|
+
export { vars };
|