@descope-ui/descope-combo-box 2.2.54 → 2.2.56
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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [2.2.56](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.55...web-components-ui-2.2.56) (2026-02-24)
|
|
6
|
+
|
|
7
|
+
## [2.2.55](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.54...web-components-ui-2.2.55) (2026-02-23)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* combo-box `require-match` ([#885](https://github.com/descope/web-components-ui/issues/885)) ([3cbbb50](https://github.com/descope/web-components-ui/commit/3cbbb5089d9f4ff7c6e8b48005664fc26fdca157))
|
|
13
|
+
|
|
5
14
|
## [2.2.54](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.53...web-components-ui-2.2.54) (2026-02-23)
|
|
6
15
|
|
|
7
16
|
## [2.2.53](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.52...web-components-ui-2.2.53) (2026-02-23)
|
|
@@ -482,3 +482,91 @@ test.describe('custom error message', () => {
|
|
|
482
482
|
});
|
|
483
483
|
});
|
|
484
484
|
});
|
|
485
|
+
|
|
486
|
+
test.describe('require-match', () => {
|
|
487
|
+
test('should validate pattern', async ({ page }) => {
|
|
488
|
+
await page.goto(
|
|
489
|
+
getStoryUrl(storyName, {
|
|
490
|
+
'require-match': 'true',
|
|
491
|
+
}),
|
|
492
|
+
);
|
|
493
|
+
const componentLocator = page.locator(componentName);
|
|
494
|
+
const component = createComboBoxTestDriver(componentLocator);
|
|
495
|
+
|
|
496
|
+
await component.insertValue('xyz');
|
|
497
|
+
await component.blur();
|
|
498
|
+
|
|
499
|
+
const displayValue = await component.getDisplayValue();
|
|
500
|
+
expect(displayValue).toBe('xyz');
|
|
501
|
+
|
|
502
|
+
const actualValue = await componentLocator.evaluate(
|
|
503
|
+
(node: HTMLElement & { value: string }) => node.value,
|
|
504
|
+
);
|
|
505
|
+
expect(actualValue).toBe('');
|
|
506
|
+
|
|
507
|
+
await page.getByRole('button').getByText('Submit').click();
|
|
508
|
+
|
|
509
|
+
expect(await component.checkValidity()).toBe(false);
|
|
510
|
+
|
|
511
|
+
expect(
|
|
512
|
+
await component.screenshot({ delay: 1000, animations: 'disabled' }),
|
|
513
|
+
).toMatchSnapshot();
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
test('should have custom error message for require match', async ({ page }) => {
|
|
517
|
+
await page.goto(
|
|
518
|
+
getStoryUrl(storyName, {
|
|
519
|
+
'require-match': 'true',
|
|
520
|
+
'data-errormessage-pattern-mismatch': 'Custom error message',
|
|
521
|
+
}),
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
const component = createComboBoxTestDriver(page.locator(componentName));
|
|
525
|
+
|
|
526
|
+
await page.getByRole('button').getByText('Submit').click();
|
|
527
|
+
|
|
528
|
+
expect(
|
|
529
|
+
await component.screenshot({ delay: 1000, animations: 'disabled' })
|
|
530
|
+
).toMatchSnapshot();
|
|
531
|
+
});
|
|
532
|
+
|
|
533
|
+
test('should not clear filter on blur', async ({ page }) => {
|
|
534
|
+
await page.goto(
|
|
535
|
+
getStoryUrl(storyName, {
|
|
536
|
+
'require-match': 'true',
|
|
537
|
+
'data-pattern-mismatch-missing': 'Custom error message',
|
|
538
|
+
}),
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
const component = createComboBoxTestDriver(page.locator(componentName));
|
|
542
|
+
|
|
543
|
+
await component.insertValue('xyz');
|
|
544
|
+
await component.blur();
|
|
545
|
+
|
|
546
|
+
expect(
|
|
547
|
+
await component.screenshot({ delay: 1000, animations: 'disabled' })
|
|
548
|
+
).toMatchSnapshot();
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
test('should not override allow-custom-value', async ({ page }) => {
|
|
552
|
+
await page.goto(
|
|
553
|
+
getStoryUrl(storyName, {
|
|
554
|
+
'require-match': 'true',
|
|
555
|
+
'allow-cuzstom-value': 'true',
|
|
556
|
+
'data-pattern-mismatch-missing': 'Custom error message',
|
|
557
|
+
}),
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
const component = createComboBoxTestDriver(page.locator(componentName));
|
|
561
|
+
|
|
562
|
+
await component.insertValue('allowed custom value');
|
|
563
|
+
await component.blur();
|
|
564
|
+
|
|
565
|
+
await page.getByRole('button').getByText('Submit').click();
|
|
566
|
+
|
|
567
|
+
expect(
|
|
568
|
+
await component.screenshot({ delay: 1000, animations: 'disabled' })
|
|
569
|
+
).toMatchSnapshot();
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@descope-ui/descope-combo-box",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.56",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"import": "./src/component/index.js"
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@playwright/test": "1.58.1",
|
|
17
|
-
"e2e-utils": "2.2.
|
|
18
|
-
"test-drivers": "2.2.
|
|
17
|
+
"e2e-utils": "2.2.56",
|
|
18
|
+
"test-drivers": "2.2.56"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@vaadin/combo-box": "24.3.4",
|
|
22
|
-
"@descope-ui/common": "2.2.
|
|
23
|
-
"@descope-ui/theme-globals": "2.2.
|
|
24
|
-
"@descope-ui/theme-input-wrapper": "2.2.
|
|
22
|
+
"@descope-ui/common": "2.2.56",
|
|
23
|
+
"@descope-ui/theme-globals": "2.2.56",
|
|
24
|
+
"@descope-ui/theme-input-wrapper": "2.2.56"
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
|
27
27
|
"link-workspace-packages": false
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
draggableMixin,
|
|
18
18
|
createProxy,
|
|
19
19
|
componentNameValidationMixin,
|
|
20
|
+
inputOverrideValidConstraintsMixin,
|
|
20
21
|
portalMixin,
|
|
21
22
|
proxyInputMixin,
|
|
22
23
|
} from '@descope-ui/common/components-mixins';
|
|
@@ -26,7 +27,7 @@ export const componentName = getComponentName('combo-box');
|
|
|
26
27
|
const ComboBoxMixin = (superclass) =>
|
|
27
28
|
class ComboBoxMixinClass extends superclass {
|
|
28
29
|
static get observedAttributes() {
|
|
29
|
-
return ['label-type'];
|
|
30
|
+
return ['label-type', 'require-match'];
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
// eslint-disable-next-line class-methods-use-this
|
|
@@ -98,6 +99,10 @@ const ComboBoxMixin = (superclass) =>
|
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
102
|
+
get requireMatch() {
|
|
103
|
+
return this.getAttribute('require-match') === 'true' && !this.allowCustomValue;
|
|
104
|
+
}
|
|
105
|
+
|
|
101
106
|
// eslint-disable-next-line class-methods-use-this
|
|
102
107
|
isValidDataType(data) {
|
|
103
108
|
const isValid = Array.isArray(data);
|
|
@@ -250,16 +255,27 @@ const ComboBoxMixin = (superclass) =>
|
|
|
250
255
|
}
|
|
251
256
|
}
|
|
252
257
|
|
|
258
|
+
isValueMatch() {
|
|
259
|
+
return this.baseElement.items.some(val => val.getAttribute('data-id') === this.baseElement.querySelector('input').value);
|
|
260
|
+
}
|
|
261
|
+
|
|
253
262
|
init() {
|
|
254
263
|
super.init?.();
|
|
255
264
|
|
|
256
265
|
// eslint-disable-next-line func-names
|
|
257
266
|
this.getValidity = function () {
|
|
267
|
+
if (this.requireMatch && !this.isValueMatch()) {
|
|
268
|
+
return {
|
|
269
|
+
patternMismatch: true,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
258
273
|
if (!this.value && this.isRequired) {
|
|
259
274
|
return {
|
|
260
275
|
valueMissing: true,
|
|
261
276
|
};
|
|
262
277
|
}
|
|
278
|
+
|
|
263
279
|
return {};
|
|
264
280
|
};
|
|
265
281
|
|
|
@@ -311,6 +327,10 @@ const ComboBoxMixin = (superclass) =>
|
|
|
311
327
|
}
|
|
312
328
|
}
|
|
313
329
|
|
|
330
|
+
handleRequireMatchChange(shouldValidate) {
|
|
331
|
+
this.baseElement.allowCustomValue = shouldValidate || this.allowCustomValue;
|
|
332
|
+
}
|
|
333
|
+
|
|
314
334
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
|
315
335
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
|
316
336
|
|
|
@@ -321,6 +341,8 @@ const ComboBoxMixin = (superclass) =>
|
|
|
321
341
|
} else {
|
|
322
342
|
this.removeEventListener('click', this.onLabelClick);
|
|
323
343
|
}
|
|
344
|
+
} else if (attrName === 'require-match') {
|
|
345
|
+
this.handleRequireMatchChange(newValue === 'true');
|
|
324
346
|
}
|
|
325
347
|
}
|
|
326
348
|
}
|
|
@@ -618,6 +640,7 @@ export const ComboBoxClass = compose(
|
|
|
618
640
|
proxyProps: ['selectionStart'],
|
|
619
641
|
inputEvent: 'value-changed',
|
|
620
642
|
}),
|
|
643
|
+
inputOverrideValidConstraintsMixin,
|
|
621
644
|
componentNameValidationMixin,
|
|
622
645
|
ComboBoxMixin,
|
|
623
646
|
)(
|
|
@@ -41,9 +41,11 @@ const Template = ({
|
|
|
41
41
|
loading,
|
|
42
42
|
'default-value': defaultValue,
|
|
43
43
|
'data-errormessage-value-missing': customErrorMissingValue,
|
|
44
|
+
'data-errormessage-pattern-mismatch': customErrorPatternMismatch,
|
|
44
45
|
'label-type': labelType,
|
|
45
46
|
'hide-toggle-button': hideToggleButton,
|
|
46
47
|
'allow-custom-value': allowCustomValue,
|
|
48
|
+
'require-match': patternValidation,
|
|
47
49
|
errorMsgIcon,
|
|
48
50
|
}) => {
|
|
49
51
|
let serializedData;
|
|
@@ -71,10 +73,12 @@ const Template = ({
|
|
|
71
73
|
disabled="${disabled || false}"
|
|
72
74
|
loading="${loading || false}"
|
|
73
75
|
data-errormessage-value-missing="${customErrorMissingValue || ''}"
|
|
76
|
+
data-errormessage-pattern-mismatch="${customErrorPatternMismatch || ''}"
|
|
74
77
|
st-host-direction="${direction ?? ''}"
|
|
75
78
|
label-type="${labelType || ''}"
|
|
76
79
|
hide-toggle-button="${hideToggleButton || false}"
|
|
77
80
|
allow-custom-value="${allowCustomValue || false}"
|
|
81
|
+
require-match="${patternValidation || false}"
|
|
78
82
|
${errorMsgIcon ? errorMessageIconAttrs : ''}
|
|
79
83
|
>
|
|
80
84
|
<span data-name="ItemName1" data-id="itemId1">Trojan War Heroes' Valor</span>
|
|
@@ -163,6 +167,10 @@ export default {
|
|
|
163
167
|
name: 'Override the default renderer function',
|
|
164
168
|
control: { type: 'boolean' },
|
|
165
169
|
},
|
|
170
|
+
'require-match': {
|
|
171
|
+
name: 'Require Match',
|
|
172
|
+
control: { type: 'boolean' },
|
|
173
|
+
},
|
|
166
174
|
},
|
|
167
175
|
};
|
|
168
176
|
|
|
@@ -180,4 +188,5 @@ Default.args = {
|
|
|
180
188
|
],
|
|
181
189
|
itemsSource: 'children',
|
|
182
190
|
'data-errormessage-value-missing': 'Please fill out this field.',
|
|
191
|
+
'data-errormessage-pattern-mismatch': ''
|
|
183
192
|
};
|