@descope/web-components-ui 1.0.60 → 1.0.62
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.map +1 -1
- package/dist/index.esm.js +395 -185
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/442.js +1 -0
- package/dist/umd/942.js +1 -1
- package/dist/umd/descope-button-index-js.js +1 -1
- package/dist/umd/descope-checkbox-index-js.js +1 -1
- package/dist/umd/descope-combo-index-js.js +1 -1
- package/dist/umd/descope-container-index-js.js +1 -1
- package/dist/umd/descope-date-picker-index-js.js +1 -1
- package/dist/umd/descope-divider-index-js.js +1 -1
- package/dist/umd/descope-email-field-index-js.js +1 -1
- package/dist/umd/descope-link-index-js.js +1 -1
- package/dist/umd/descope-loader-linear-index-js.js +1 -1
- package/dist/umd/descope-loader-radial-index-js.js +1 -1
- package/dist/umd/descope-logo-index-js.js +1 -1
- package/dist/umd/descope-number-field-index-js.js +1 -1
- package/dist/umd/descope-passcode-descope-passcode-internal-index-js.js +1 -1
- package/dist/umd/descope-passcode-index-js.js +1 -1
- package/dist/umd/descope-password-field-index-js.js +1 -1
- package/dist/umd/descope-switch-toggle-index-js.js +1 -1
- package/dist/umd/descope-text-area-index-js.js +1 -1
- package/dist/umd/descope-text-field-index-js.js +1 -1
- package/dist/umd/descope-text-index-js.js +1 -1
- package/dist/umd/index.js +1 -1
- package/package.json +1 -1
- package/src/baseClasses/BaseInputClass.js +3 -0
- package/src/components/descope-checkbox/Checkbox.js +2 -2
- package/src/components/descope-combo/index.js +1 -1
- package/src/components/descope-container/Container.js +1 -1
- package/src/components/descope-divider/Divider.js +1 -1
- package/src/components/descope-email-field/EmailField.js +2 -2
- package/src/components/descope-link/Link.js +1 -1
- package/src/components/descope-loader-linear/LoaderLinear.js +1 -1
- package/src/components/descope-loader-radial/LoaderRadial.js +1 -1
- package/src/components/descope-logo/Logo.js +1 -1
- package/src/components/descope-number-field/NumberField.js +2 -2
- package/src/components/descope-passcode/Passcode.js +2 -2
- package/src/components/descope-passcode/descope-passcode-internal/PasscodeInternal.js +42 -70
- package/src/components/descope-password-field/PasswordField.js +2 -2
- package/src/components/descope-switch-toggle/SwitchToggle.js +2 -2
- package/src/components/descope-text/Text.js +1 -1
- package/src/components/descope-text-area/TextArea.js +2 -2
- package/src/components/descope-text-field/TextField.js +2 -2
- package/src/componentsHelpers/compose.js +3 -0
- package/src/componentsHelpers/createProxy/index.js +2 -2
- package/src/componentsHelpers/enforceNestingElementsStylesMixin.js +67 -59
- package/src/componentsHelpers/index.js +2 -6
- package/src/componentsHelpers/inputMixin.js +173 -94
- package/src/componentsHelpers/proxyInputMixin.js +152 -0
- package/src/theme/components/textField.js +1 -1
- package/dist/umd/832.js +0 -1
- /package/src/{components → baseClasses}/DescopeBaseClass.js +0 -0
@@ -1,16 +1,16 @@
|
|
1
|
+
import BaseInputClass from '../../../baseClasses/BaseInputClass';
|
1
2
|
import { getComponentName } from '../../../componentsHelpers';
|
2
3
|
import { getSanitizedCharacters, focusElement } from './helpers';
|
3
4
|
|
4
5
|
export const componentName = getComponentName('passcode-internal');
|
5
6
|
|
6
|
-
class PasscodeInternal extends
|
7
|
+
class PasscodeInternal extends BaseInputClass {
|
7
8
|
static get observedAttributes() {
|
8
9
|
return [
|
10
|
+
...BaseInputClass.observedAttributes,
|
9
11
|
'disabled',
|
10
12
|
'bordered',
|
11
|
-
'size'
|
12
|
-
'required',
|
13
|
-
'pattern'
|
13
|
+
'size'
|
14
14
|
];
|
15
15
|
}
|
16
16
|
|
@@ -18,12 +18,6 @@ class PasscodeInternal extends HTMLElement {
|
|
18
18
|
return componentName;
|
19
19
|
}
|
20
20
|
|
21
|
-
static get formAssociated() {
|
22
|
-
return true;
|
23
|
-
}
|
24
|
-
|
25
|
-
#internals
|
26
|
-
|
27
21
|
constructor() {
|
28
22
|
super();
|
29
23
|
const template = document.createElement('template');
|
@@ -47,23 +41,9 @@ class PasscodeInternal extends HTMLElement {
|
|
47
41
|
|
48
42
|
this.baseSelector = ':host > div';
|
49
43
|
|
50
|
-
this.#internals = this.attachInternals();
|
51
|
-
|
52
44
|
this.inputs = Array.from(this.querySelectorAll('descope-text-field'))
|
53
45
|
}
|
54
46
|
|
55
|
-
checkValidity() {
|
56
|
-
// we need to toggle the has-error-message so the text inside the digits will become red when there is an error
|
57
|
-
if (this.#internals.validity.valid) {
|
58
|
-
this.inputs.forEach(input => input.removeAttribute('has-error-message'))
|
59
|
-
} else {
|
60
|
-
this.inputs.forEach(input => input.setAttribute('has-error-message', 'true'))
|
61
|
-
// we need to call it so the has-error-message with have the correct format (="true")
|
62
|
-
this.oninvalid?.()
|
63
|
-
}
|
64
|
-
return this.#internals.validity.valid
|
65
|
-
}
|
66
|
-
|
67
47
|
get digits() {
|
68
48
|
return Number.parseInt(this.getAttribute('digits')) || 6
|
69
49
|
}
|
@@ -72,59 +52,54 @@ class PasscodeInternal extends HTMLElement {
|
|
72
52
|
return this.inputs.map(({ value }) => value).join('')
|
73
53
|
}
|
74
54
|
|
75
|
-
set value(val) {
|
55
|
+
set value(val) {
|
56
|
+
if(val === this.value) return;
|
76
57
|
|
77
|
-
|
78
|
-
|
58
|
+
const charArr = getSanitizedCharacters(val);
|
59
|
+
|
60
|
+
if (charArr.length) {
|
61
|
+
this.fillDigits(charArr, this.inputs[0]);
|
62
|
+
}
|
79
63
|
}
|
80
64
|
|
81
65
|
get pattern() {
|
82
66
|
return `^$|^\\d{${this.digits},}$`
|
83
67
|
}
|
84
68
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
}
|
92
|
-
|
93
|
-
get validity() {
|
94
|
-
return this.#internals.validity;
|
95
|
-
}
|
96
|
-
|
97
|
-
get validationMessage() {
|
98
|
-
return this.#internals.validationMessage;
|
99
|
-
}
|
100
|
-
|
101
|
-
reportValidity() {
|
102
|
-
this.#internals.reportValidity()
|
69
|
+
handleInputsInvalid() {
|
70
|
+
setTimeout(() => {
|
71
|
+
if (this.hasAttribute('invalid')) {
|
72
|
+
this.inputs.forEach(input => input.setAttribute('invalid', 'true'))
|
73
|
+
}
|
74
|
+
})
|
103
75
|
}
|
104
76
|
|
105
|
-
|
106
|
-
this.
|
77
|
+
handleInputsValid() {
|
78
|
+
this.inputs.forEach(input => input.removeAttribute('invalid'))
|
107
79
|
}
|
108
80
|
|
109
|
-
|
81
|
+
getValidity() {
|
110
82
|
if (this.isRequired && !this.value) {
|
111
|
-
|
83
|
+
return { valueMissing: true };
|
112
84
|
}
|
113
85
|
else if (this.pattern && !new RegExp(this.pattern).test(this.value)) {
|
114
|
-
|
86
|
+
return { patternMismatch: true };
|
115
87
|
}
|
116
88
|
else {
|
117
|
-
|
89
|
+
return {}
|
118
90
|
}
|
119
91
|
};
|
120
92
|
|
93
|
+
handleFocus() {
|
94
|
+
this.inputs[0].focus();
|
95
|
+
}
|
96
|
+
|
121
97
|
async connectedCallback() {
|
122
|
-
|
98
|
+
super.connectedCallback();
|
123
99
|
this.initInputs()
|
124
100
|
|
125
|
-
this.
|
126
|
-
|
127
|
-
}
|
101
|
+
this.addEventListener('invalid', this.handleInputsInvalid)
|
102
|
+
this.addEventListener('valid', this.handleInputsValid)
|
128
103
|
}
|
129
104
|
|
130
105
|
getInputIdx(inputEle) {
|
@@ -155,6 +130,10 @@ class PasscodeInternal extends HTMLElement {
|
|
155
130
|
!currentInput.hasAttribute('focused') && focusElement(currentInput);
|
156
131
|
};
|
157
132
|
|
133
|
+
handleBlur() {
|
134
|
+
this.handleInputsInvalid()
|
135
|
+
}
|
136
|
+
|
158
137
|
initInputs() {
|
159
138
|
this.inputs.forEach((input) => {
|
160
139
|
|
@@ -163,7 +142,7 @@ class PasscodeInternal extends HTMLElement {
|
|
163
142
|
// if not, the component is no longer focused and we should simulate blur
|
164
143
|
input.addEventListener('blur', () => {
|
165
144
|
const timerId = setTimeout(() => {
|
166
|
-
this.
|
145
|
+
this.dispatchBlur()
|
167
146
|
});
|
168
147
|
|
169
148
|
this.inputs.forEach((ele) =>
|
@@ -171,13 +150,13 @@ class PasscodeInternal extends HTMLElement {
|
|
171
150
|
);
|
172
151
|
})
|
173
152
|
|
174
|
-
input.oninput = (
|
153
|
+
input.oninput = () => {
|
175
154
|
const charArr = getSanitizedCharacters(input.value);
|
176
155
|
|
177
156
|
if (!charArr.length) input.value = ''; // if we got an invalid value we want to clear the input
|
178
157
|
else this.fillDigits(charArr, input);
|
179
158
|
|
180
|
-
this.
|
159
|
+
this.dispatchInput()
|
181
160
|
};
|
182
161
|
|
183
162
|
input.onkeydown = ({ key }) => {
|
@@ -190,27 +169,21 @@ class PasscodeInternal extends HTMLElement {
|
|
190
169
|
!prevInput.hasAttribute('focused') && setTimeout(() => {
|
191
170
|
focusElement(prevInput);
|
192
171
|
});
|
172
|
+
|
173
|
+
this.dispatchInput()
|
193
174
|
} else if (key.match(/^(\d)$/g)) { // if input is a digit
|
194
175
|
input.value = ''; // we are clearing the previous value so we can override it with the new value
|
195
176
|
}
|
196
177
|
|
197
|
-
this.setValidity()
|
198
178
|
};
|
199
179
|
})
|
200
180
|
}
|
201
181
|
|
202
|
-
attributeChangedCallback(
|
203
|
-
attrName,
|
204
|
-
oldValue,
|
205
|
-
newValue
|
206
|
-
) {
|
207
|
-
const validationRelatedAttributes = ['required', 'pattern'];
|
182
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
183
|
+
super.attributeChangedCallback(attrName, oldValue, newValue)
|
208
184
|
|
209
185
|
if (oldValue !== newValue) {
|
210
|
-
if (
|
211
|
-
this.setValidity()
|
212
|
-
}
|
213
|
-
else if (PasscodeInternal.observedAttributes.includes(attrName)) {
|
186
|
+
if (PasscodeInternal.observedAttributes.includes(attrName) && !BaseInputClass.observedAttributes.includes(attrName)) {
|
214
187
|
this.inputs.forEach((input) => input.setAttribute(attrName, newValue))
|
215
188
|
}
|
216
189
|
}
|
@@ -218,4 +191,3 @@ class PasscodeInternal extends HTMLElement {
|
|
218
191
|
}
|
219
192
|
|
220
193
|
export default PasscodeInternal;
|
221
|
-
|
@@ -3,7 +3,7 @@ import {
|
|
3
3
|
createStyleMixin,
|
4
4
|
draggableMixin,
|
5
5
|
createProxy,
|
6
|
-
|
6
|
+
proxyInputMixin,
|
7
7
|
compose,
|
8
8
|
componentNameValidationMixin
|
9
9
|
} from '../../componentsHelpers';
|
@@ -26,7 +26,7 @@ const PasswordField = compose(
|
|
26
26
|
}
|
27
27
|
}),
|
28
28
|
draggableMixin,
|
29
|
-
|
29
|
+
proxyInputMixin,
|
30
30
|
componentNameValidationMixin
|
31
31
|
)(
|
32
32
|
createProxy({
|
@@ -3,7 +3,7 @@ import {
|
|
3
3
|
createStyleMixin,
|
4
4
|
draggableMixin,
|
5
5
|
createProxy,
|
6
|
-
|
6
|
+
proxyInputMixin,
|
7
7
|
compose,
|
8
8
|
componentNameValidationMixin,
|
9
9
|
} from '../../componentsHelpers';
|
@@ -21,7 +21,7 @@ const SwitchToggle = compose(
|
|
21
21
|
}
|
22
22
|
}),
|
23
23
|
draggableMixin,
|
24
|
-
|
24
|
+
proxyInputMixin,
|
25
25
|
componentNameValidationMixin
|
26
26
|
)(
|
27
27
|
createProxy({
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
componentNameValidationMixin
|
7
7
|
} from '../../componentsHelpers';
|
8
8
|
import { matchHostStyle } from '../../componentsHelpers/createStyleMixin/helpers';
|
9
|
-
import { DescopeBaseClass } from '
|
9
|
+
import { DescopeBaseClass } from '../../baseClasses/DescopeBaseClass';
|
10
10
|
|
11
11
|
export const componentName = getComponentName('text');
|
12
12
|
|
@@ -3,7 +3,7 @@ import {
|
|
3
3
|
createStyleMixin,
|
4
4
|
draggableMixin,
|
5
5
|
createProxy,
|
6
|
-
|
6
|
+
proxyInputMixin,
|
7
7
|
compose,
|
8
8
|
componentNameValidationMixin
|
9
9
|
} from '../../componentsHelpers';
|
@@ -36,7 +36,7 @@ const TextArea = compose(
|
|
36
36
|
}
|
37
37
|
}),
|
38
38
|
draggableMixin,
|
39
|
-
|
39
|
+
proxyInputMixin,
|
40
40
|
componentNameValidationMixin
|
41
41
|
)(
|
42
42
|
createProxy({
|
@@ -3,7 +3,7 @@ import {
|
|
3
3
|
createStyleMixin,
|
4
4
|
draggableMixin,
|
5
5
|
createProxy,
|
6
|
-
|
6
|
+
proxyInputMixin,
|
7
7
|
compose,
|
8
8
|
componentNameValidationMixin
|
9
9
|
} from '../../componentsHelpers';
|
@@ -18,7 +18,7 @@ const TextField = compose(
|
|
18
18
|
mappings: textFieldMappings
|
19
19
|
}),
|
20
20
|
draggableMixin,
|
21
|
-
|
21
|
+
proxyInputMixin,
|
22
22
|
componentNameValidationMixin
|
23
23
|
)(
|
24
24
|
createProxy({
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import
|
2
|
-
import { DescopeBaseClass } from '../../
|
1
|
+
import compose from '../compose';
|
2
|
+
import { DescopeBaseClass } from '../../baseClasses/DescopeBaseClass';
|
3
3
|
import { hoverableMixin } from '../hoverableMixin';
|
4
4
|
import { syncAttrs, forwardProps } from './helpers';
|
5
5
|
|
@@ -19,65 +19,65 @@ const insertNestingLevel = (srcEle, nestingEle) => {
|
|
19
19
|
// to be under the nesting element
|
20
20
|
export const enforceNestingElementsStylesMixin =
|
21
21
|
({ nestingElementTagName, nestingElementDestSlotName, forwardAttrOptions }) =>
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
let childObserver;
|
29
|
-
|
30
|
-
const getObserver = () => childObserver;
|
31
|
-
|
32
|
-
return class EnforceNestingElementsStylesMixinClass extends superclass {
|
33
|
-
constructor() {
|
34
|
-
super();
|
35
|
-
|
36
|
-
const childObserverCallback = () => {
|
37
|
-
// we are going to change the DOM, so we need to disconnect the observer before
|
38
|
-
// and reconnect it after the child component is added
|
39
|
-
getObserver().disconnect(this.shadowRoot.host);
|
40
|
-
|
41
|
-
const isNestingElementExist = this.shadowRoot.host.querySelector(nestingElementTagName);
|
42
|
-
const hasNewChildren = this.shadowRoot.host.childNodes.length > 0;
|
43
|
-
|
44
|
-
if (!isNestingElementExist && hasNewChildren) {
|
45
|
-
// if before there were no children and now there are children - insert
|
46
|
-
insertNestingLevel(this.shadowRoot.host, getChildNodeEle());
|
47
|
-
} else if (isNestingElementExist && hasNewChildren) {
|
48
|
-
// if children existed, and they changed -
|
49
|
-
// we need to update (move) the new children into
|
50
|
-
// descope-text and remove previous children
|
51
|
-
this.shadowRoot.host.querySelector(child).remove();
|
52
|
-
insertNestingLevel(this.shadowRoot.host, getChildNodeEle());
|
53
|
-
}
|
54
|
-
else if (isNestingElementExist && !hasNewChildren) {
|
55
|
-
// if children existed and now there are none -
|
56
|
-
// we need to remove descope-text completely
|
57
|
-
this.shadowRoot.host.querySelector(child).remove();
|
58
|
-
}
|
22
|
+
(superclass) => {
|
23
|
+
const getChildNodeEle = () =>
|
24
|
+
document.createElement(nestingElementTagName, {
|
25
|
+
slot: nestingElementDestSlotName
|
26
|
+
});
|
59
27
|
|
60
|
-
|
61
|
-
this.shadowRoot.host.querySelector(nestingElementTagName) &&
|
62
|
-
forwardAttrs(
|
63
|
-
this.shadowRoot.host,
|
64
|
-
this.shadowRoot.host.querySelector(nestingElementTagName),
|
65
|
-
forwardAttrOptions
|
66
|
-
);
|
28
|
+
let childObserver;
|
67
29
|
|
68
|
-
|
69
|
-
childList: true
|
70
|
-
});
|
71
|
-
};
|
30
|
+
const getObserver = () => childObserver;
|
72
31
|
|
73
|
-
|
74
|
-
|
32
|
+
let isMutating = false;
|
33
|
+
|
34
|
+
const filterNestingElement = (node) => node.localName !== nestingElementTagName
|
35
|
+
return class EnforceNestingElementsStylesMixinClass extends superclass {
|
36
|
+
constructor() {
|
37
|
+
super();
|
38
|
+
|
39
|
+
const childObserverCallback = (mutation, observer) => {
|
40
|
+
|
41
|
+
// we are going to change the DOM, so we need to skip the upcoming mutations
|
42
|
+
if (isMutating) return;
|
43
|
+
|
44
|
+
isMutating = true
|
45
|
+
|
46
|
+
const { addedNodes, removedNodes } = mutation
|
47
|
+
|
48
|
+
const nestingElement = this.shadowRoot.host.querySelector(nestingElementTagName);
|
49
|
+
const hasNewChildren = Array.from(addedNodes)
|
50
|
+
.filter(filterNestingElement)
|
51
|
+
.length > 0;
|
52
|
+
const hasRemovedChildren = Array.from(removedNodes)
|
53
|
+
.filter(filterNestingElement)
|
54
|
+
.length > 0;
|
75
55
|
|
76
|
-
|
77
|
-
|
56
|
+
if (!nestingElement && hasNewChildren) {
|
57
|
+
// if before there were no children and now there are children - insert
|
58
|
+
this.handleNestingLevelInsertion()
|
78
59
|
|
79
|
-
|
80
|
-
|
60
|
+
} else if (nestingElement && hasNewChildren) {
|
61
|
+
// if children existed, and they changed -
|
62
|
+
// we need to update (move) the new children into
|
63
|
+
// descope-text and remove previous children
|
64
|
+
nestingElement.replaceChildren(...addedNodes)
|
65
|
+
}
|
66
|
+
else if (nestingElement && !hasNewChildren && hasRemovedChildren) {
|
67
|
+
// // if children existed and now there are none -
|
68
|
+
// // we need to remove descope-text completely
|
69
|
+
nestingElement.remove();
|
70
|
+
}
|
71
|
+
|
72
|
+
setTimeout(() => {
|
73
|
+
isMutating = false
|
74
|
+
})
|
75
|
+
};
|
76
|
+
|
77
|
+
childObserver = getChildObserver(childObserverCallback);
|
78
|
+
}
|
79
|
+
|
80
|
+
handleNestingLevelInsertion() {
|
81
81
|
insertNestingLevel(this.shadowRoot.host, getChildNodeEle());
|
82
82
|
|
83
83
|
forwardAttrs(
|
@@ -87,9 +87,17 @@ export const enforceNestingElementsStylesMixin =
|
|
87
87
|
);
|
88
88
|
}
|
89
89
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
90
|
+
connectedCallback() {
|
91
|
+
super.connectedCallback?.();
|
92
|
+
|
93
|
+
if (this.shadowRoot.host.childNodes.length > 0) {
|
94
|
+
// on the first render - we want to move all component's children to be under descope-text
|
95
|
+
this.handleNestingLevelInsertion()
|
96
|
+
}
|
97
|
+
|
98
|
+
getObserver().observe(this.shadowRoot.host, {
|
99
|
+
childList: true
|
100
|
+
});
|
101
|
+
}
|
102
|
+
};
|
94
103
|
};
|
95
|
-
};
|
@@ -3,13 +3,9 @@ import { kebabCaseJoin } from '../helpers';
|
|
3
3
|
|
4
4
|
export const getComponentName = (name) => kebabCaseJoin(DESCOPE_PREFIX, name);
|
5
5
|
|
6
|
-
export const compose =
|
7
|
-
(...fns) =>
|
8
|
-
(val) =>
|
9
|
-
fns.reduceRight((res, fn) => fn(res), val);
|
10
|
-
|
11
6
|
export { createStyleMixin } from './createStyleMixin';
|
12
7
|
export { draggableMixin } from './draggableMixin';
|
13
8
|
export { createProxy } from './createProxy';
|
14
|
-
export {
|
9
|
+
export { proxyInputMixin } from './proxyInputMixin';
|
15
10
|
export { componentNameValidationMixin } from './componentNameValidationMixin';
|
11
|
+
export { default as compose } from './compose'
|