@descope/web-components-ui 3.20.3 → 3.20.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/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "git+https://github.com/descope/web-components-ui.git",
6
6
  "directory": "packages/web-components/web-components-ui"
7
7
  },
8
- "version": "3.20.3",
8
+ "version": "3.20.4",
9
9
  "description": "",
10
10
  "main": "dist/cjs/index.cjs.js",
11
11
  "module": "dist/index.esm.js",
@@ -57,11 +57,11 @@
57
57
  "webpack-cli": "^7.0.0",
58
58
  "webpack-dev-server": "^5.0.0",
59
59
  "webpack-subresource-integrity": "5.2.0-rc.1",
60
- "eslint-plugin-no-bare-class-import": "3.20.3",
61
- "rollup-replace-plugin": "3.20.3",
62
- "test-drivers": "3.20.3",
63
- "webpack-extract-font-loader": "3.20.3",
64
- "webpack-replace-plugin": "3.20.3"
60
+ "rollup-replace-plugin": "3.20.4",
61
+ "test-drivers": "3.20.4",
62
+ "webpack-extract-font-loader": "3.20.4",
63
+ "webpack-replace-plugin": "3.20.4",
64
+ "eslint-plugin-no-bare-class-import": "3.20.4"
65
65
  },
66
66
  "dependencies": {
67
67
  "@vaadin/checkbox": "24.3.4",
@@ -85,42 +85,42 @@
85
85
  "libphonenumber-js": "^1.11.12",
86
86
  "lodash.debounce": "4.0.8",
87
87
  "lodash.merge": "4.6.2",
88
- "@descope-ui/common": "3.20.3",
89
- "@descope-ui/descope-address-field": "3.20.3",
90
- "@descope-ui/descope-country-subdivision-city-field": "3.20.3",
91
- "@descope-ui/descope-apps-list": "3.20.3",
92
- "@descope-ui/descope-avatar": "3.20.3",
93
- "@descope-ui/descope-badge": "3.20.3",
94
- "@descope-ui/descope-button": "3.20.3",
95
- "@descope-ui/descope-collapsible-container": "3.20.3",
96
- "@descope-ui/descope-combo-box": "3.20.3",
97
- "@descope-ui/descope-enriched-text": "3.20.3",
98
- "@descope-ui/descope-icon": "3.20.3",
99
- "@descope-ui/descope-link": "3.20.3",
100
- "@descope-ui/descope-list": "3.20.3",
101
- "@descope-ui/descope-list-item": "3.20.3",
102
- "@descope-ui/descope-image": "3.20.3",
103
- "@descope-ui/descope-month-day-field-picker": "3.20.3",
104
- "@descope-ui/descope-month-day-field": "3.20.3",
105
- "@descope-ui/descope-multi-line-mappings": "3.20.3",
106
- "@descope-ui/descope-outbound-apps": "3.20.3",
107
- "@descope-ui/descope-password-strength": "3.20.3",
108
- "@descope-ui/descope-text": "3.20.3",
109
- "@descope-ui/descope-text-field": "3.20.3",
110
- "@descope-ui/descope-timer": "3.20.3",
111
- "@descope-ui/descope-autocomplete-field": "3.20.3",
112
- "@descope-ui/descope-timer-button": "3.20.3",
113
- "@descope-ui/descope-tooltip": "3.20.3",
114
- "@descope-ui/descope-multi-sso": "3.20.3",
115
- "@descope-ui/descope-trusted-devices": "3.20.3",
116
- "@descope-ui/descope-anchored": "3.20.3",
117
- "@descope-ui/descope-outbound-app-button": "3.20.3",
118
- "@descope-ui/descope-attachment": "3.20.3",
119
- "@descope-ui/descope-recovery-codes": "3.20.3",
120
- "@descope-ui/descope-multi-select-combo-box": "3.20.3",
121
- "@descope-ui/descope-ponyhot": "3.20.3",
122
- "@descope-ui/descope-user-passkeys": "3.20.3",
123
- "@descope-ui/descope-filter": "3.20.3"
88
+ "@descope-ui/descope-country-subdivision-city-field": "3.20.4",
89
+ "@descope-ui/descope-apps-list": "3.20.4",
90
+ "@descope-ui/descope-autocomplete-field": "3.20.4",
91
+ "@descope-ui/descope-avatar": "3.20.4",
92
+ "@descope-ui/descope-badge": "3.20.4",
93
+ "@descope-ui/descope-button": "3.20.4",
94
+ "@descope-ui/descope-combo-box": "3.20.4",
95
+ "@descope-ui/descope-collapsible-container": "3.20.4",
96
+ "@descope-ui/descope-enriched-text": "3.20.4",
97
+ "@descope-ui/descope-icon": "3.20.4",
98
+ "@descope-ui/descope-image": "3.20.4",
99
+ "@descope-ui/descope-link": "3.20.4",
100
+ "@descope-ui/descope-list": "3.20.4",
101
+ "@descope-ui/descope-list-item": "3.20.4",
102
+ "@descope-ui/descope-month-day-field": "3.20.4",
103
+ "@descope-ui/descope-month-day-field-picker": "3.20.4",
104
+ "@descope-ui/descope-multi-line-mappings": "3.20.4",
105
+ "@descope-ui/descope-multi-select-combo-box": "3.20.4",
106
+ "@descope-ui/descope-outbound-apps": "3.20.4",
107
+ "@descope-ui/descope-outbound-app-button": "3.20.4",
108
+ "@descope-ui/common": "3.20.4",
109
+ "@descope-ui/descope-password-strength": "3.20.4",
110
+ "@descope-ui/descope-address-field": "3.20.4",
111
+ "@descope-ui/descope-ponyhot": "3.20.4",
112
+ "@descope-ui/descope-recovery-codes": "3.20.4",
113
+ "@descope-ui/descope-text": "3.20.4",
114
+ "@descope-ui/descope-text-field": "3.20.4",
115
+ "@descope-ui/descope-timer": "3.20.4",
116
+ "@descope-ui/descope-timer-button": "3.20.4",
117
+ "@descope-ui/descope-tooltip": "3.20.4",
118
+ "@descope-ui/descope-multi-sso": "3.20.4",
119
+ "@descope-ui/descope-trusted-devices": "3.20.4",
120
+ "@descope-ui/descope-anchored": "3.20.4",
121
+ "@descope-ui/descope-attachment": "3.20.4",
122
+ "@descope-ui/descope-user-passkeys": "3.20.4",
123
+ "@descope-ui/descope-filter": "3.20.4"
124
124
  },
125
125
  "overrides": {
126
126
  "@vaadin/avatar": "24.3.4",
@@ -8,6 +8,7 @@ import {
8
8
  externalInputMixin,
9
9
  } from '../../mixins';
10
10
  import { compose } from '../../helpers';
11
+ import { asciiPattern, unicodePattern } from './emailPattern';
11
12
  import { getComponentName } from '../../helpers/componentHelpers';
12
13
  import {
13
14
  inputFloatingLabelStyle,
@@ -18,23 +19,70 @@ import {
18
19
 
19
20
  export const componentName = getComponentName('email-field');
20
21
 
21
- const defaultPattern = "^[\\w\\.\\%\\+\\-']+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$";
22
22
  const defaultAutocomplete = 'username';
23
+ const defaultInputMode = 'email';
23
24
 
24
25
  const customMixin = (superclass) =>
25
26
  class EmailFieldMixinClass extends superclass {
27
+ // On by default - `accept-unicode="false"` restores the pre-unicode field:
28
+ // native `type="email"` validation and the ASCII pattern.
29
+ //
30
+ // Read once, in `init`. Changing the attribute afterwards has no effect; it
31
+ // is static configuration, which is how every consumer sets it.
32
+ get acceptsUnicode() {
33
+ return this.getAttribute('accept-unicode') !== 'false';
34
+ }
35
+
26
36
  init() {
27
37
  super.init?.();
28
38
 
29
39
  // we need to set the pattern on the base element because vaadin-email-field is overriding it
30
- this.baseElement.setAttribute('pattern', defaultPattern);
40
+ this.baseElement.setAttribute('pattern', asciiPattern);
31
41
 
32
42
  if (!this.getAttribute('autocomplete')) {
33
43
  this.setAttribute('autocomplete', defaultAutocomplete);
34
44
  }
35
45
 
36
46
  this.createExternalInput();
47
+
48
+ [this.inputElement, this.externalInput].filter(Boolean).forEach((input) => {
49
+ input.addEventListener('change', this.stripSurroundingWhitespace);
50
+ });
51
+
52
+ if (this.acceptsUnicode) {
53
+ this.enableUnicode();
54
+ }
37
55
  }
56
+
57
+ enableUnicode() {
58
+ this.baseElement.setAttribute('pattern', unicodePattern);
59
+
60
+ // native `type="email"` validation is ASCII only and sets typeMismatch
61
+ // before `pattern` is consulted, so `text` is what lets the pattern decide.
62
+ // Through vaadin's `_setType` because `type` is a readOnly property bound
63
+ // to the inner input - assigning `input.type` is re-applied over.
64
+ this.baseElement._setType('text');
65
+
66
+ if (this.externalInput) {
67
+ this.externalInput.type = 'text';
68
+ }
69
+
70
+ // `type="text"` loses the email keyboard on mobile
71
+ if (!this.getAttribute('inputmode')) {
72
+ this.setAttribute('inputmode', defaultInputMode);
73
+ }
74
+
75
+ this.externalInput?.setAttribute('inputmode', defaultInputMode);
76
+ }
77
+
78
+ stripSurroundingWhitespace = (e) => {
79
+ const trimmed = e.target.value.trim();
80
+ if (trimmed === e.target.value) return;
81
+ this.value = trimmed;
82
+
83
+ // validity is cached and was computed against the untrimmed value
84
+ this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
85
+ };
38
86
  };
39
87
 
40
88
  export const EmailFieldClass = compose(
@@ -0,0 +1,7 @@
1
+ // Kept in its own module (with no imports) so it can be unit tested without
2
+ // pulling in the whole component / vaadin dependency chain.
3
+
4
+ export const asciiPattern = "^[\\w\\.\\%\\+\\-']+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$";
5
+
6
+ export const unicodePattern =
7
+ "^[\\p{L}\\p{M}\\p{N}._%+'\\-]+@[\\p{L}\\p{M}\\p{N}.\\-]+\\.[\\p{L}\\p{M}][\\p{L}\\p{M}\\p{N}\\-]+$";
@@ -34,6 +34,7 @@ const Template = ({
34
34
  'full-width': fullWidth,
35
35
  readonly,
36
36
  'external-input': externalInput,
37
+ 'accept-unicode': acceptUnicode,
37
38
  'data-errormessage-value-missing': customErrorMissingValue,
38
39
  'data-errormessage-pattern-mismatch': customErrorPatternMismatch,
39
40
  'label-type': labelType,
@@ -53,6 +54,7 @@ const Template = ({
53
54
  st-host-direction="${direction ?? ''}"
54
55
  label-type="${labelType || ''}"
55
56
  external-input="${externalInput || false}"
57
+ ${acceptUnicode === false ? 'accept-unicode="false"' : ''}
56
58
  ${errorMsgIcon ? errorMessageIconAttrs : ''}
57
59
  ></descope-email-field>
58
60
  `;
@@ -95,6 +97,11 @@ export default {
95
97
  'external-input': {
96
98
  control: { type: 'boolean' },
97
99
  },
100
+ 'accept-unicode': {
101
+ control: { type: 'boolean' },
102
+ description:
103
+ 'On by default. Accepts diacritics and non-Latin scripts in the local part, and unicode domains, by moving the input off native type="email" validation, which is ASCII only. Set to false to restore the ASCII-only field.',
104
+ },
98
105
  },
99
106
  };
100
107
 
@@ -102,6 +109,7 @@ export const Default = Template.bind({});
102
109
 
103
110
  Default.args = {
104
111
  size: 'md',
112
+ 'accept-unicode': true,
105
113
  bordered: true,
106
114
  validateOnBlur: false,
107
115
  'data-errormessage-value-missing': 'Please fill out this field.',