@descope/web-components-ui 3.16.3 → 3.17.0
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 +104 -8
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +104 -8
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/DescopeDev.js +1 -1
- package/dist/umd/DescopeDev.js.map +1 -1
- package/dist/umd/descope-hybrid-field-index-js.js +1 -1
- package/dist/umd/descope-hybrid-field-index-js.js.map +1 -1
- package/dist/umd/descope-user-attribute-index-js.js +2 -2
- package/dist/umd/descope-user-attribute-index-js.js.map +1 -1
- package/dist/umd/index.js +1 -1
- package/package.json +41 -41
- package/src/components/descope-hybrid-field/HybridFieldClass.js +11 -2
- package/src/components/descope-user-attribute/UserAttributeClass.js +91 -6
- package/src/components/descope-user-attribute/check.svg +3 -0
- package/src/components/descope-user-attribute/copy.svg +3 -0
- package/stories/descope-user-attribute.stories.js +12 -0
|
@@ -9,6 +9,8 @@ import { compose } from '../../helpers';
|
|
|
9
9
|
import { getComponentName } from '../../helpers/componentHelpers';
|
|
10
10
|
import deleteIcon from './delete.svg';
|
|
11
11
|
import editIcon from './edit.svg';
|
|
12
|
+
import copyIcon from './copy.svg';
|
|
13
|
+
import checkIcon from './check.svg';
|
|
12
14
|
|
|
13
15
|
export const componentName = getComponentName('user-attribute');
|
|
14
16
|
class RawUserAttribute extends createBaseClass({
|
|
@@ -25,6 +27,10 @@ class RawUserAttribute extends createBaseClass({
|
|
|
25
27
|
<descope-text st-text-align="auto" data-id="value-text" variant="body1" mode="primary" class="value"></descope-text>
|
|
26
28
|
<div class="btn-wrapper">
|
|
27
29
|
<descope-badge mode="default" bordered="true" size="xs"></descope-badge>
|
|
30
|
+
<descope-button size="sm" data-id="copy-btn" variant="link" mode="primary">
|
|
31
|
+
<slot name="copy-icon"></slot>
|
|
32
|
+
<descope-icon class="check-icon" src="${checkIcon}" src-dark="${checkIcon}"></descope-icon>
|
|
33
|
+
</descope-button>
|
|
28
34
|
<descope-button size="sm" data-id="delete-btn" variant="link" mode="primary">
|
|
29
35
|
<slot name="delete-icon"></slot>
|
|
30
36
|
</descope-button>
|
|
@@ -71,12 +77,29 @@ class RawUserAttribute extends createBaseClass({
|
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
slot[name="edit-icon"],
|
|
74
|
-
slot[name="delete-icon"]
|
|
80
|
+
slot[name="delete-icon"],
|
|
81
|
+
slot[name="copy-icon"] {
|
|
75
82
|
display: inline-flex;
|
|
76
83
|
flex-shrink: 0;
|
|
77
84
|
align-items: center;
|
|
78
85
|
}
|
|
79
86
|
|
|
87
|
+
descope-button[data-id="copy-btn"].hidden {
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
descope-button[data-id="copy-btn"] .check-icon {
|
|
92
|
+
display: none;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
descope-button[data-id="copy-btn"].copied slot[name="copy-icon"] {
|
|
96
|
+
display: none;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
descope-button[data-id="copy-btn"].copied .check-icon {
|
|
100
|
+
display: inline-flex;
|
|
101
|
+
}
|
|
102
|
+
|
|
80
103
|
.content-wrapper {
|
|
81
104
|
display: flex;
|
|
82
105
|
flex-grow: 1;
|
|
@@ -119,7 +142,7 @@ class RawUserAttribute extends createBaseClass({
|
|
|
119
142
|
color: var(${TextClass.cssVarList.textColor});
|
|
120
143
|
}
|
|
121
144
|
|
|
122
|
-
:host([readonly="true"]) descope-button {
|
|
145
|
+
:host([readonly="true"]) descope-button:not([data-id="copy-btn"]) {
|
|
123
146
|
visibility: hidden;
|
|
124
147
|
width: 0;
|
|
125
148
|
}
|
|
@@ -127,6 +150,7 @@ class RawUserAttribute extends createBaseClass({
|
|
|
127
150
|
this
|
|
128
151
|
);
|
|
129
152
|
|
|
153
|
+
this.copyButton = this.shadowRoot.querySelector('descope-button[data-id="copy-btn"]');
|
|
130
154
|
this.deleteButton = this.shadowRoot.querySelector('descope-button[data-id="delete-btn"]');
|
|
131
155
|
this.editButton = this.shadowRoot.querySelector('descope-button[data-id="edit-btn"]');
|
|
132
156
|
this.badge = this.shadowRoot.querySelector('descope-badge');
|
|
@@ -216,6 +240,14 @@ class RawUserAttribute extends createBaseClass({
|
|
|
216
240
|
return this.getAttribute('hide-delete') === 'true';
|
|
217
241
|
}
|
|
218
242
|
|
|
243
|
+
get isCopyEnabled() {
|
|
244
|
+
return this.getAttribute('show-copy') === 'true';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
get copyButtonLabel() {
|
|
248
|
+
return this.getAttribute('copy-button-label') || '';
|
|
249
|
+
}
|
|
250
|
+
|
|
219
251
|
init() {
|
|
220
252
|
this.onLabelChange();
|
|
221
253
|
this.onValueOrPlaceholderChange();
|
|
@@ -224,7 +256,9 @@ class RawUserAttribute extends createBaseClass({
|
|
|
224
256
|
this.onBadgeTooltipTextChange();
|
|
225
257
|
this.updateButtonLabel(this.editButton, this.editButtonLabel);
|
|
226
258
|
this.updateButtonLabel(this.deleteButton, this.deleteButtonLabel);
|
|
259
|
+
this.updateButtonLabel(this.copyButton, this.copyButtonLabel);
|
|
227
260
|
this.handleDeleteButtonVisibility();
|
|
261
|
+
this.handleCopyButtonState();
|
|
228
262
|
|
|
229
263
|
this.deleteButton.addEventListener('click', () =>
|
|
230
264
|
this.dispatchEvent(new CustomEvent('delete-clicked', { bubbles: true, composed: true }))
|
|
@@ -234,9 +268,35 @@ class RawUserAttribute extends createBaseClass({
|
|
|
234
268
|
this.dispatchEvent(new CustomEvent('edit-clicked', { bubbles: true, composed: true }))
|
|
235
269
|
);
|
|
236
270
|
|
|
271
|
+
this.copyButton.addEventListener('click', () => this.#handleCopyClick());
|
|
272
|
+
|
|
237
273
|
this.setDefaultChildren();
|
|
238
274
|
}
|
|
239
275
|
|
|
276
|
+
#handleCopyClick() {
|
|
277
|
+
// isDraggable is true only inside the page editor (craftjs sets draggable="true"
|
|
278
|
+
// for drag-and-drop); there the copy action must not run.
|
|
279
|
+
if (!this.value || this.isDraggable || !navigator.clipboard) return;
|
|
280
|
+
|
|
281
|
+
navigator.clipboard
|
|
282
|
+
.writeText(this.value)
|
|
283
|
+
.then(() => {
|
|
284
|
+
this.copyButton.classList.add('copied');
|
|
285
|
+
setTimeout(() => this.copyButton.classList.remove('copied'), 2000);
|
|
286
|
+
})
|
|
287
|
+
.catch(() => {});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
handleCopyButtonState() {
|
|
291
|
+
this.copyButton.classList.toggle('hidden', !this.isCopyEnabled);
|
|
292
|
+
|
|
293
|
+
if (this.value) {
|
|
294
|
+
this.copyButton.removeAttribute('disabled');
|
|
295
|
+
} else {
|
|
296
|
+
this.copyButton.setAttribute('disabled', 'true');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
240
300
|
#addIcon(src, slotName) {
|
|
241
301
|
const icon = document.createElement('descope-icon');
|
|
242
302
|
icon.setAttribute('src', src);
|
|
@@ -246,9 +306,19 @@ class RawUserAttribute extends createBaseClass({
|
|
|
246
306
|
}
|
|
247
307
|
|
|
248
308
|
setDefaultChildren() {
|
|
249
|
-
if (this.
|
|
250
|
-
|
|
251
|
-
|
|
309
|
+
if (!this.querySelector('[slot="delete-icon"]')) {
|
|
310
|
+
this.#addIcon(deleteIcon, 'delete-icon');
|
|
311
|
+
}
|
|
312
|
+
if (!this.querySelector('[slot="edit-icon"]')) {
|
|
313
|
+
this.#addIcon(editIcon, 'edit-icon');
|
|
314
|
+
}
|
|
315
|
+
this.setDefaultCopyIcon();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
setDefaultCopyIcon() {
|
|
319
|
+
if (this.isCopyEnabled && !this.querySelector('[slot="copy-icon"]')) {
|
|
320
|
+
this.#addIcon(copyIcon, 'copy-icon');
|
|
321
|
+
}
|
|
252
322
|
}
|
|
253
323
|
|
|
254
324
|
static get observedAttributes() {
|
|
@@ -261,7 +331,9 @@ class RawUserAttribute extends createBaseClass({
|
|
|
261
331
|
'badge-tooltip-text',
|
|
262
332
|
'edit-button-label',
|
|
263
333
|
'delete-button-label',
|
|
334
|
+
'copy-button-label',
|
|
264
335
|
'hide-delete',
|
|
336
|
+
'show-copy',
|
|
265
337
|
].concat(super.observedAttributes);
|
|
266
338
|
}
|
|
267
339
|
|
|
@@ -293,11 +365,19 @@ class RawUserAttribute extends createBaseClass({
|
|
|
293
365
|
this.updateButtonLabel(this.editButton, this.editButtonLabel);
|
|
294
366
|
} else if (name === 'delete-button-label') {
|
|
295
367
|
this.updateButtonLabel(this.deleteButton, this.deleteButtonLabel);
|
|
368
|
+
} else if (name === 'copy-button-label') {
|
|
369
|
+
this.updateButtonLabel(this.copyButton, this.copyButtonLabel);
|
|
370
|
+
} else if (name === 'show-copy') {
|
|
371
|
+
this.setDefaultCopyIcon();
|
|
296
372
|
}
|
|
297
373
|
|
|
298
374
|
if (name === 'value' || name === 'required' || name === 'hide-delete') {
|
|
299
375
|
this.handleDeleteButtonVisibility();
|
|
300
376
|
}
|
|
377
|
+
|
|
378
|
+
if (name === 'value' || name === 'show-copy') {
|
|
379
|
+
this.handleCopyButtonState();
|
|
380
|
+
}
|
|
301
381
|
}
|
|
302
382
|
}
|
|
303
383
|
|
|
@@ -326,7 +406,12 @@ export const UserAttributeClass = compose(
|
|
|
326
406
|
contentMinWidth: { ...contentWrapper, property: 'min-width' },
|
|
327
407
|
badgeMaxWidth: { ...badge, property: 'max-width' },
|
|
328
408
|
itemsGap: [{ property: 'gap' }, { ...contentWrapper, property: 'gap' }],
|
|
329
|
-
iconColor: [
|
|
409
|
+
iconColor: [
|
|
410
|
+
{ selector: () => '::slotted(*)', property: IconClass.cssVarList.fill },
|
|
411
|
+
// the copied check-icon lives in the shadow DOM (not slotted), so it
|
|
412
|
+
// needs its own mapping to follow the same icon color
|
|
413
|
+
{ selector: () => '.check-icon', property: IconClass.cssVarList.fill },
|
|
414
|
+
],
|
|
330
415
|
},
|
|
331
416
|
}),
|
|
332
417
|
draggableMixin,
|
|
@@ -29,6 +29,8 @@ const Template = ({
|
|
|
29
29
|
'edit-button-label': editButtonLabel,
|
|
30
30
|
'delete-button-label': deleteButtonLabel,
|
|
31
31
|
'hide-delete': hideDelete,
|
|
32
|
+
showCopy,
|
|
33
|
+
copyButtonLabel,
|
|
32
34
|
customIcons,
|
|
33
35
|
}) => `
|
|
34
36
|
<descope-user-attribute
|
|
@@ -42,6 +44,8 @@ const Template = ({
|
|
|
42
44
|
edit-button-label="${editButtonLabel || ''}"
|
|
43
45
|
delete-button-label="${deleteButtonLabel || ''}"
|
|
44
46
|
hide-delete="${hideDelete || 'false'}"
|
|
47
|
+
show-copy="${showCopy || 'false'}"
|
|
48
|
+
copy-button-label="${copyButtonLabel || ''}"
|
|
45
49
|
st-host-direction="${direction ?? ''}"
|
|
46
50
|
readonly="${readonly || false}"
|
|
47
51
|
>
|
|
@@ -83,6 +87,14 @@ export default {
|
|
|
83
87
|
name: 'Hide Delete',
|
|
84
88
|
control: { type: 'boolean' },
|
|
85
89
|
},
|
|
90
|
+
showCopy: {
|
|
91
|
+
name: 'Show Copy',
|
|
92
|
+
control: { type: 'boolean' },
|
|
93
|
+
},
|
|
94
|
+
copyButtonLabel: {
|
|
95
|
+
name: 'Copy Button Label',
|
|
96
|
+
control: { type: 'text' },
|
|
97
|
+
},
|
|
86
98
|
customIcons: {
|
|
87
99
|
name: 'Custom Icons',
|
|
88
100
|
control: { type: 'boolean' },
|