@descope/web-components-ui 1.0.279 → 1.0.281
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/cjs/index.cjs.js +2344 -2099
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +3075 -2446
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/1000.js +1 -1
- package/dist/umd/1438.js +2 -2
- package/dist/umd/{9558.js → 1621.js} +117 -117
- package/dist/umd/2066.js +1 -1
- package/dist/umd/3280.js +197 -0
- package/dist/umd/3280.js.LICENSE.txt +29 -0
- package/dist/umd/{6542.js → 3951.js} +6 -6
- package/dist/umd/{6542.js.LICENSE.txt → 3951.js.LICENSE.txt} +0 -6
- package/dist/umd/422.js +1 -1
- package/dist/umd/4447.js +1 -1
- package/dist/umd/5806.js +1 -1
- package/dist/umd/6770.js +1 -1
- package/dist/umd/6977.js +2 -0
- package/dist/umd/6977.js.LICENSE.txt +5 -0
- package/dist/umd/7056.js +1 -1
- package/dist/umd/7262.js +1 -1
- package/dist/umd/7531.js +2 -2
- package/dist/umd/7583.js +2 -2
- package/dist/umd/8725.js +1 -1
- package/dist/umd/9092.js +2 -2
- package/dist/umd/9437.js +1 -1
- package/dist/umd/descope-combo-box-index-js.js +1 -1
- package/dist/umd/descope-notification-descope-notification-card-index-js.js +1 -1
- package/dist/umd/descope-notification-index-js.js +1 -1
- package/dist/umd/index.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-descope-mapping-item-index-js.js +1 -0
- package/dist/umd/mapping-fields-descope-mappings-field-descope-mappings-field-internal-index-js.js +1 -0
- package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -0
- package/package.json +4 -1
- package/src/components/descope-combo-box/ComboBoxClass.js +4 -0
- package/src/components/descope-text-field/textFieldMappings.js +7 -1
- package/src/components/mapping-fields/descope-mappings-field/MappingsFieldClass.js +159 -0
- package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/MappingItem.js +158 -0
- package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/index.js +3 -0
- package/src/components/mapping-fields/descope-mappings-field/descope-mappings-field-internal/MappingsFieldInternal.js +232 -0
- package/src/components/mapping-fields/descope-mappings-field/descope-mappings-field-internal/index.js +3 -0
- package/src/components/mapping-fields/descope-mappings-field/index.js +14 -0
- package/src/components/phone-fields/CountryCodes.js +1209 -1206
- package/src/index.cjs.js +1 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/mixins/inputValidationMixin.js +8 -0
- package/src/mixins/proxyInputMixin.js +48 -6
- package/src/theme/components/index.js +2 -0
- package/src/theme/components/inputWrapper.js +2 -0
- package/src/theme/components/mappingsField.js +25 -0
- package/src/theme/components/textField.js +1 -0
- /package/dist/umd/{9558.js.LICENSE.txt → 1621.js.LICENSE.txt} +0 -0
package/src/components/mapping-fields/descope-mappings-field/descope-mapping-item/MappingItem.js
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
import { createBaseInputClass } from '../../../../baseClasses/createBaseInputClass';
|
2
|
+
import { forwardAttrs, getComponentName } from '../../../../helpers/componentHelpers';
|
3
|
+
|
4
|
+
export const componentName = getComponentName('mapping-item');
|
5
|
+
|
6
|
+
const inputAttrs = ['size', 'bordered', 'readonly', 'full-width', 'disabled'];
|
7
|
+
|
8
|
+
const BaseInputClass = createBaseInputClass({ componentName, baseSelector: 'div' });
|
9
|
+
|
10
|
+
class MappingItem extends BaseInputClass {
|
11
|
+
static get observedAttributes() {
|
12
|
+
return [].concat(BaseInputClass.observedAttributes || [], inputAttrs, [
|
13
|
+
'separator',
|
14
|
+
'options',
|
15
|
+
'invalid',
|
16
|
+
'disabled',
|
17
|
+
]);
|
18
|
+
}
|
19
|
+
|
20
|
+
get separator() {
|
21
|
+
return this.getAttribute('separator') || 'map to';
|
22
|
+
}
|
23
|
+
|
24
|
+
get value() {
|
25
|
+
const attributeValue = this.attributeInput.value;
|
26
|
+
const inputValue = this.valueInput.value;
|
27
|
+
if (attributeValue && inputValue) {
|
28
|
+
return { [attributeValue]: inputValue };
|
29
|
+
}
|
30
|
+
return null;
|
31
|
+
}
|
32
|
+
|
33
|
+
set value(mapping) {
|
34
|
+
if (Object.entries(mapping).length !== 1) {
|
35
|
+
// eslint-disable-next-line no-console
|
36
|
+
console.error(
|
37
|
+
'descope-mapping item expected expects only one key-value pair in the value but received: ',
|
38
|
+
mapping
|
39
|
+
);
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
const [attribute, value] = Object.entries(mapping)[0];
|
43
|
+
this.valueInput.value = value;
|
44
|
+
this.attributeInput.value = attribute;
|
45
|
+
// The event needs to be dispatched to trigger the validation if setting the value externally
|
46
|
+
this.dispatchEvent(new InputEvent('input', { bubbles: true, composed: true }));
|
47
|
+
}
|
48
|
+
|
49
|
+
constructor() {
|
50
|
+
super();
|
51
|
+
|
52
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
53
|
+
<style>
|
54
|
+
.wrapper {
|
55
|
+
display: flex;
|
56
|
+
}
|
57
|
+
.separator {
|
58
|
+
text-align: center;
|
59
|
+
flex-shrink: 0;
|
60
|
+
}
|
61
|
+
</style>
|
62
|
+
<div class="wrapper" part="wrapper">
|
63
|
+
<descope-text-field required="true"></descope-text-field>
|
64
|
+
<div class="separator" part="separator">${this.separator}</div>
|
65
|
+
<descope-combo-box
|
66
|
+
item-label-path="data-name"
|
67
|
+
item-value-path="data-id"
|
68
|
+
required="true"
|
69
|
+
>
|
70
|
+
</descope-combo-box>
|
71
|
+
<descope-button variant="link" mode="primary">
|
72
|
+
<vaadin-icon icon="vaadin:minus"></vaadin-icon>
|
73
|
+
</descope-button>
|
74
|
+
</div>
|
75
|
+
`;
|
76
|
+
this.valueInput = this.shadowRoot.querySelector('descope-text-field');
|
77
|
+
this.attributeInput = this.shadowRoot.querySelector('descope-combo-box');
|
78
|
+
this.inputs = [this.valueInput, this.attributeInput];
|
79
|
+
this.removeButton = this.shadowRoot.querySelector('descope-button');
|
80
|
+
|
81
|
+
forwardAttrs(this, this.valueInput, {
|
82
|
+
includeAttrs: inputAttrs,
|
83
|
+
});
|
84
|
+
forwardAttrs(this, this.attributeInput, {
|
85
|
+
includeAttrs: [...inputAttrs, 'options'],
|
86
|
+
mapAttrs: { options: 'data' },
|
87
|
+
});
|
88
|
+
forwardAttrs(this, this.removeButton, {
|
89
|
+
includeAttrs: ['disabled'],
|
90
|
+
});
|
91
|
+
}
|
92
|
+
|
93
|
+
initRemoveButton() {
|
94
|
+
this.removeButton.addEventListener('click', () =>
|
95
|
+
this.dispatchEvent(new CustomEvent('mapping-item-removed'))
|
96
|
+
);
|
97
|
+
}
|
98
|
+
|
99
|
+
init() {
|
100
|
+
super.init?.();
|
101
|
+
this.initRemoveButton();
|
102
|
+
}
|
103
|
+
|
104
|
+
getValidity() {
|
105
|
+
const attributeValue = this.attributeInput.value;
|
106
|
+
const inputValue = this.valueInput.value;
|
107
|
+
if (!attributeValue || !inputValue) {
|
108
|
+
return { badInput: true };
|
109
|
+
}
|
110
|
+
return {};
|
111
|
+
}
|
112
|
+
|
113
|
+
reportValidity() {
|
114
|
+
this.inputs.forEach((input) => input.reportValidity());
|
115
|
+
}
|
116
|
+
|
117
|
+
focus() {
|
118
|
+
const focusedElement =
|
119
|
+
this.checkValidity() || !this.valueInput.checkValidity()
|
120
|
+
? this.valueInput
|
121
|
+
: this.attributeInput;
|
122
|
+
focusedElement.focus();
|
123
|
+
}
|
124
|
+
|
125
|
+
handleSeparatorChange() {
|
126
|
+
this.shadowRoot.querySelector('.separator').textContent = this.separator;
|
127
|
+
}
|
128
|
+
|
129
|
+
#handleInvalidMapping(invalid) {
|
130
|
+
if (invalid === 'true') {
|
131
|
+
const inputValue = this.valueInput.value;
|
132
|
+
if (!inputValue) {
|
133
|
+
this.valueInput.setAttribute('invalid', 'true');
|
134
|
+
this.valueInput.setAttribute('error-message', this.defaultErrorMsgValueMissing);
|
135
|
+
}
|
136
|
+
|
137
|
+
const attributeValue = this.attributeInput.value;
|
138
|
+
if (!attributeValue) {
|
139
|
+
this.attributeInput.setAttribute('invalid', 'true');
|
140
|
+
this.attributeInput.setAttribute('error-message', this.defaultErrorMsgValueMissing);
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
146
|
+
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
147
|
+
|
148
|
+
if (attrName === 'separator') {
|
149
|
+
this.handleSeparatorChange();
|
150
|
+
}
|
151
|
+
|
152
|
+
if (attrName === 'invalid') {
|
153
|
+
this.#handleInvalidMapping(newValue);
|
154
|
+
}
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
export default MappingItem;
|
@@ -0,0 +1,232 @@
|
|
1
|
+
import { createBaseInputClass } from '../../../../baseClasses/createBaseInputClass';
|
2
|
+
import { getComponentName, forwardAttrs } from '../../../../helpers/componentHelpers';
|
3
|
+
|
4
|
+
export const componentName = getComponentName('mappings-field-internal');
|
5
|
+
|
6
|
+
const BaseInputClass = createBaseInputClass({ componentName, baseSelector: 'div' });
|
7
|
+
|
8
|
+
class MappingsFieldInternal extends BaseInputClass {
|
9
|
+
#errorItem;
|
10
|
+
|
11
|
+
static get observedAttributes() {
|
12
|
+
return [].concat(BaseInputClass.observedAttributes || [], [
|
13
|
+
'label-value',
|
14
|
+
'label-attr',
|
15
|
+
'button-label',
|
16
|
+
'invalid',
|
17
|
+
'readonly',
|
18
|
+
'disabled',
|
19
|
+
]);
|
20
|
+
}
|
21
|
+
|
22
|
+
// eslint-disable-next-line class-methods-use-this
|
23
|
+
isValidDataType(data) {
|
24
|
+
try {
|
25
|
+
return data.every(
|
26
|
+
(obj) =>
|
27
|
+
typeof obj === 'object' &&
|
28
|
+
!Array.isArray(obj) &&
|
29
|
+
Object.getOwnPropertyNames(obj).length === 1 &&
|
30
|
+
typeof obj[Object.keys(obj)[0]] === 'string' &&
|
31
|
+
obj[Object.keys(obj)[0]].trim() !== ''
|
32
|
+
);
|
33
|
+
} catch (e) {
|
34
|
+
return false;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
get labelValue() {
|
39
|
+
return this.getAttribute('label-value') || 'Value';
|
40
|
+
}
|
41
|
+
|
42
|
+
get labelAttr() {
|
43
|
+
return this.getAttribute('label-attr') || 'Attribute';
|
44
|
+
}
|
45
|
+
|
46
|
+
get buttonLabel() {
|
47
|
+
return this.getAttribute('button-label') || 'Add mapping';
|
48
|
+
}
|
49
|
+
|
50
|
+
get options() {
|
51
|
+
return this.getAttribute('options') || [];
|
52
|
+
}
|
53
|
+
|
54
|
+
addNewMappingItem() {
|
55
|
+
const newMappingItem = document.createElement('descope-mapping-item');
|
56
|
+
newMappingItem.setAttribute('bordered', 'true');
|
57
|
+
this.mappingsContainerEle.appendChild(newMappingItem);
|
58
|
+
forwardAttrs(this, newMappingItem, {
|
59
|
+
includeAttrs: ['size', 'full-width', 'separator', 'options', 'disabled'],
|
60
|
+
});
|
61
|
+
// This needs to be done with the timeout, otherwise the validation is performed
|
62
|
+
// before the new item is added and thus returns a wrong result
|
63
|
+
setTimeout(() => {
|
64
|
+
this.setCustomValidity('');
|
65
|
+
newMappingItem.addEventListener('mapping-item-removed', (e) => {
|
66
|
+
// If the removed item was the one that was invalid, we need to reset the invalid indication for the internal
|
67
|
+
if (newMappingItem === this.#errorItem) {
|
68
|
+
this.resetInvalidIndication();
|
69
|
+
this.#errorItem = undefined;
|
70
|
+
}
|
71
|
+
newMappingItem.remove();
|
72
|
+
this.setCustomValidity('');
|
73
|
+
e.stopPropagation();
|
74
|
+
});
|
75
|
+
}, 0);
|
76
|
+
return newMappingItem;
|
77
|
+
}
|
78
|
+
|
79
|
+
get items() {
|
80
|
+
return Array.from(this.mappingsContainerEle.querySelectorAll('descope-mapping-item'));
|
81
|
+
}
|
82
|
+
|
83
|
+
get value() {
|
84
|
+
return this.items.reduce((acc, item) => {
|
85
|
+
if (!item.value) {
|
86
|
+
return acc;
|
87
|
+
}
|
88
|
+
|
89
|
+
return [...acc, item.value];
|
90
|
+
}, []);
|
91
|
+
}
|
92
|
+
|
93
|
+
set value(mappings) {
|
94
|
+
if (!this.isValidDataType(mappings)) {
|
95
|
+
// eslint-disable-next-line no-console
|
96
|
+
console.error(
|
97
|
+
'received invalid value to set - should be an array of objects with one key-value pair'
|
98
|
+
);
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
102
|
+
const currentItems = this.items;
|
103
|
+
|
104
|
+
// Remove extra mapping items we don't need
|
105
|
+
if (currentItems.length > mappings.length) {
|
106
|
+
for (let i = mappings.length; i < currentItems.length; i++) {
|
107
|
+
this.mappingsContainerEle.removeChild(currentItems[i]);
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
// Add or update items
|
112
|
+
mappings.forEach((mapping, index) => {
|
113
|
+
const mappingItem = currentItems[index];
|
114
|
+
if (mappingItem) {
|
115
|
+
// Set existing item value
|
116
|
+
mappingItem.value = mapping;
|
117
|
+
} else {
|
118
|
+
// Add new item
|
119
|
+
const newMappingItem = this.addNewMappingItem();
|
120
|
+
// Setting the new item value needs to be done with the timeout,
|
121
|
+
// otherwise the value is not set correctly
|
122
|
+
setTimeout(() => {
|
123
|
+
newMappingItem.value = mapping;
|
124
|
+
}, 0);
|
125
|
+
}
|
126
|
+
});
|
127
|
+
}
|
128
|
+
|
129
|
+
constructor() {
|
130
|
+
super();
|
131
|
+
|
132
|
+
this.innerHTML = `
|
133
|
+
<div class="labels-container" part="labels"></div>
|
134
|
+
<div class="mappings-container"></div>
|
135
|
+
<div class="button-container"></div>
|
136
|
+
`;
|
137
|
+
|
138
|
+
this.labelsEle = this.querySelector('.labels-container');
|
139
|
+
this.mappingsContainerEle = this.querySelector('.mappings-container');
|
140
|
+
this.buttonContainer = this.querySelector('.button-container');
|
141
|
+
}
|
142
|
+
|
143
|
+
initLabels() {
|
144
|
+
this.labelsEle.innerHTML = `
|
145
|
+
<descope-text variant="body2" part="value-label">${this.labelValue}</descope-text>
|
146
|
+
<descope-text variant="body2" part="attr-label">${this.labelAttr}</descope-text>
|
147
|
+
`;
|
148
|
+
}
|
149
|
+
|
150
|
+
initAddButton() {
|
151
|
+
this.buttonContainer.innerHTML = `
|
152
|
+
<descope-button variant="link" mode="primary" disabled="${this.isDisabled}">
|
153
|
+
<vaadin-icon icon="vaadin:plus"></vaadin-icon>
|
154
|
+
${this.buttonLabel}
|
155
|
+
</descope-button>
|
156
|
+
`;
|
157
|
+
const button = this.querySelector('descope-button');
|
158
|
+
button.onclick = () => {
|
159
|
+
this.addNewMappingItem();
|
160
|
+
};
|
161
|
+
forwardAttrs(this, button, {
|
162
|
+
includeAttrs: ['disabled'],
|
163
|
+
});
|
164
|
+
}
|
165
|
+
|
166
|
+
init() {
|
167
|
+
// This event listener needs to be placed before the super.init() call
|
168
|
+
this.addEventListener('focus', (e) => {
|
169
|
+
// we want to ignore focus events we are dispatching
|
170
|
+
if (e.isTrusted) {
|
171
|
+
const focusedElement =
|
172
|
+
this.#errorItem || this.items[0] || this.querySelector('descope-button');
|
173
|
+
focusedElement.focus();
|
174
|
+
}
|
175
|
+
});
|
176
|
+
|
177
|
+
super.init?.();
|
178
|
+
this.initLabels();
|
179
|
+
this.initAddButton();
|
180
|
+
|
181
|
+
// This event listener is responsible for removing the invalid attribute
|
182
|
+
// from the internal once the invalid item turns valid
|
183
|
+
this.addEventListener('input', () => {
|
184
|
+
const isErrorItemMounted = this.mappingsContainerEle.contains(this.#errorItem);
|
185
|
+
if (isErrorItemMounted && this.#errorItem?.checkValidity()) {
|
186
|
+
// Item has changed, it was invalid before and now it's valid
|
187
|
+
this.resetInvalidIndication();
|
188
|
+
this.#errorItem.removeAttribute('invalid');
|
189
|
+
this.#errorItem = undefined;
|
190
|
+
}
|
191
|
+
});
|
192
|
+
}
|
193
|
+
|
194
|
+
resetInvalidIndication() {
|
195
|
+
this.removeAttribute('invalid');
|
196
|
+
}
|
197
|
+
|
198
|
+
getValidity() {
|
199
|
+
const errorItem = this.items.find((item) => !item.checkValidity());
|
200
|
+
if (errorItem) {
|
201
|
+
return errorItem.validity;
|
202
|
+
}
|
203
|
+
|
204
|
+
return {};
|
205
|
+
}
|
206
|
+
|
207
|
+
#handleInvalidMappings(isInvalid) {
|
208
|
+
if (isInvalid) {
|
209
|
+
this.#errorItem = this.items.find((item) => !item.checkValidity());
|
210
|
+
this.#errorItem?.reportValidity();
|
211
|
+
this.#errorItem?.setAttribute('invalid', 'true');
|
212
|
+
}
|
213
|
+
}
|
214
|
+
|
215
|
+
attributeChangedCallback(attrName, oldValue, newValue) {
|
216
|
+
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
217
|
+
if (attrName === 'label-value' || attrName === 'label-attr') {
|
218
|
+
this.initLabels();
|
219
|
+
}
|
220
|
+
if (attrName === 'button-label') {
|
221
|
+
this.initAddButton();
|
222
|
+
}
|
223
|
+
if (attrName === 'invalid') {
|
224
|
+
this.#handleInvalidMappings(newValue === 'true');
|
225
|
+
}
|
226
|
+
if (attrName === 'readonly') {
|
227
|
+
this.toggleAttribute('inert', newValue === 'true');
|
228
|
+
}
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
export default MappingsFieldInternal;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import '@vaadin/custom-field';
|
2
|
+
import '@vaadin/icon';
|
3
|
+
import '@vaadin/icons';
|
4
|
+
import { componentName, MappingsFieldClass } from './MappingsFieldClass';
|
5
|
+
import '../../descope-text';
|
6
|
+
import '../../descope-button';
|
7
|
+
import '../../descope-text-field';
|
8
|
+
import '../../descope-combo-box';
|
9
|
+
import './descope-mappings-field-internal';
|
10
|
+
import './descope-mapping-item';
|
11
|
+
|
12
|
+
customElements.define(componentName, MappingsFieldClass);
|
13
|
+
|
14
|
+
export { MappingsFieldClass };
|