@descope/web-components-ui 1.0.369 → 1.0.371

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/index.esm.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import '@vaadin/button';
2
2
  import 'element-internals-polyfill';
3
+ import DOMPurify from 'dompurify';
3
4
  import '@vaadin/checkbox';
4
5
  import '@vaadin/text-field';
5
6
  import '@vaadin/email-field';
@@ -1412,8 +1413,11 @@ const createImgEle = (src) => {
1412
1413
  };
1413
1414
 
1414
1415
  const createSvgEle = (text) => {
1416
+ // we want to purify the SVG to avoid XSS attacks
1417
+ const clean = DOMPurify.sanitize(text, { USE_PROFILES: { svg: true, svgFilters: true } });
1418
+
1415
1419
  const parser = new DOMParser();
1416
- const ele = parser.parseFromString(text, 'image/svg+xml').querySelector('svg');
1420
+ const ele = parser.parseFromString(clean, 'image/svg+xml').querySelector('svg');
1417
1421
  return ele;
1418
1422
  };
1419
1423
 
@@ -1449,7 +1453,7 @@ const componentName$_ = getComponentName('icon');
1449
1453
 
1450
1454
  class RawIcon extends createBaseClass({ componentName: componentName$_, baseSelector: 'slot' }) {
1451
1455
  static get observedAttributes() {
1452
- return ['src', 'fill-color'];
1456
+ return ['src'];
1453
1457
  }
1454
1458
 
1455
1459
  #icon;
@@ -1474,36 +1478,23 @@ class RawIcon extends createBaseClass({ componentName: componentName$_, baseSele
1474
1478
  `;
1475
1479
  }
1476
1480
 
1477
- get fillColor() {
1478
- return this.getAttribute('fill-color') === 'true';
1479
- }
1480
-
1481
1481
  get src() {
1482
1482
  return this.getAttribute('src');
1483
1483
  }
1484
1484
 
1485
1485
  // in order to fill an SVG with `currentColor` override all of its `fill` and `path` nodes
1486
1486
  // with the value from the `st-fill` attribute
1487
- updateFillColor() {
1488
- if (this.#icon && this.fillColor) {
1489
- const fillCssVar = (selector) => {
1490
- this.querySelectorAll(selector).forEach((ele) =>
1491
- ele.setAttribute(
1492
- 'fill',
1493
- `var(${IconClass.cssVarList.fill}, ${ele.getAttribute('fill') || "''"})`
1494
- )
1495
- );
1496
- };
1497
-
1498
- fillCssVar('*[fill]');
1499
- fillCssVar('path');
1500
- }
1501
- }
1502
-
1503
- resetIcon() {
1504
- if (!this.#icon) return;
1505
- this.innerHTML = '';
1506
- this.appendChild(this.#icon.cloneNode(true));
1487
+ // eslint-disable-next-line class-methods-use-this
1488
+ updateFillColor(node) {
1489
+ // set fill to root node and all its relevant selectors
1490
+ const elementsToReplace = [node, ...node.querySelectorAll('*[fill]')];
1491
+
1492
+ elementsToReplace.forEach((ele) => {
1493
+ ele.setAttribute(
1494
+ 'fill',
1495
+ `var(${IconClass.cssVarList.fill}, ${ele.getAttribute('fill') || "''"})`
1496
+ );
1497
+ });
1507
1498
  }
1508
1499
 
1509
1500
  attributeChangedCallback(attrName, oldValue, newValue) {
@@ -1513,13 +1504,13 @@ class RawIcon extends createBaseClass({ componentName: componentName$_, baseSele
1513
1504
 
1514
1505
  if (attrName === 'src') {
1515
1506
  createIcon(this.src).then((res) => {
1516
- this.#icon = res;
1517
- this.resetIcon();
1518
- this.updateFillColor();
1507
+ this.innerHTML = '';
1508
+ if (res) {
1509
+ const clonedNode = res.cloneNode(true);
1510
+ this.updateFillColor(clonedNode);
1511
+ this.appendChild(clonedNode);
1512
+ }
1519
1513
  });
1520
- } else if (attrName === 'fill-color') {
1521
- this.resetIcon();
1522
- this.updateFillColor();
1523
1514
  }
1524
1515
  }
1525
1516
  }
@@ -11954,7 +11945,7 @@ const componentName$2 = getComponentName('list');
11954
11945
 
11955
11946
  class RawList extends createBaseClass({ componentName: componentName$2, baseSelector: '.wrapper' }) {
11956
11947
  static get observedAttributes() {
11957
- return ['variant'];
11948
+ return ['variant', 'readonly'];
11958
11949
  }
11959
11950
 
11960
11951
  constructor() {
@@ -12037,6 +12028,18 @@ class RawList extends createBaseClass({ componentName: componentName$2, baseSele
12037
12028
  observeChildren(this, () => {
12038
12029
  this.#handleEmptyState();
12039
12030
  this.#handleItemsVariant();
12031
+ this.#handleReadOnly();
12032
+ });
12033
+ }
12034
+
12035
+ get isReadOnly() {
12036
+ return this.getAttribute('readonly') === 'true';
12037
+ }
12038
+
12039
+ #handleReadOnly() {
12040
+ this.items.forEach((item) => {
12041
+ if (this.isReadOnly) item.setAttribute('inert', '');
12042
+ else item.removeAttribute('inert');
12040
12043
  });
12041
12044
  }
12042
12045
 
@@ -12047,6 +12050,8 @@ class RawList extends createBaseClass({ componentName: componentName$2, baseSele
12047
12050
 
12048
12051
  if (name === 'variant') {
12049
12052
  this.#handleItemsVariant();
12053
+ } else if (name === 'readonly') {
12054
+ this.#handleReadOnly();
12050
12055
  }
12051
12056
  }
12052
12057
  }
@@ -12164,16 +12169,51 @@ const createDynamicDataMixin =
12164
12169
  super.init?.();
12165
12170
 
12166
12171
  if (rerenderAttrsList.length) {
12167
- observeAttributes(this, () => this.#renderItems(), { includeAttrs: rerenderAttrsList });
12172
+ observeAttributes(
12173
+ this,
12174
+ (attrs) => {
12175
+ if (attrs.includes('data')) this.#handleDataAttr();
12176
+ if (attrs.some((attr) => attr !== 'data')) this.#renderItems();
12177
+ },
12178
+ { includeAttrs: [...rerenderAttrsList, 'data'] }
12179
+ );
12168
12180
  } else {
12169
12181
  this.#renderItems();
12170
12182
  }
12171
12183
  }
12184
+
12185
+ #handleDataAttr() {
12186
+ const dataAttr = this.getAttribute('data');
12187
+
12188
+ if (!dataAttr) return;
12189
+
12190
+ try {
12191
+ this.#data = JSON.parse(dataAttr);
12192
+ } catch (e) {
12193
+ // eslint-disable-next-line no-console
12194
+ console.warn('Invalid JSON data', dataAttr);
12195
+ }
12196
+ }
12197
+
12198
+ attributeChangedCallback(name, oldValue, newValue) {
12199
+ super.attributeChangedCallback?.(name, oldValue, newValue);
12200
+
12201
+ if (newValue === oldValue) return;
12202
+
12203
+ if (name === 'data') {
12204
+ try {
12205
+ this.data = JSON.parse(newValue);
12206
+ } catch (e) {
12207
+ // eslint-disable-next-line no-console
12208
+ console.warn('Invalid JSON data', newValue);
12209
+ }
12210
+ }
12211
+ }
12172
12212
  };
12173
12213
 
12174
12214
  const componentName$1 = getComponentName('apps-list');
12175
12215
 
12176
- const limitAbbreviation = (str, limit = 3) =>
12216
+ const limitAbbreviation = (str, limit = 2) =>
12177
12217
  str
12178
12218
  .trim()
12179
12219
  .split(' ')
@@ -12182,12 +12222,11 @@ const limitAbbreviation = (str, limit = 3) =>
12182
12222
  .join('');
12183
12223
 
12184
12224
  const itemRenderer = ({ name, icon, url }, _, ref) => `
12185
- <a href="${url}" target="_blank" title="${url}">
12225
+ <a ${url ? `href="${url}" title="${url}"` : ''} target="_blank">
12186
12226
  <descope-list-item>
12187
12227
  <descope-avatar
12188
- img="${icon}"
12189
- display-name="${name}"
12190
- abbr=${limitAbbreviation(name)}
12228
+ ${icon ? `img="${icon}"` : ''}
12229
+ ${name ? `display-name="${name}" abbr=${limitAbbreviation(name)}` : ''}
12191
12230
  size=${ref.size}
12192
12231
  ></descope-avatar>
12193
12232
  <descope-text
@@ -12233,7 +12272,7 @@ const AppsListClass = compose(
12233
12272
  createProxy({
12234
12273
  slots: ['empty-state'],
12235
12274
  wrappedEleName: 'descope-list',
12236
- excludeAttrsSync: ['tabindex', 'class'],
12275
+ excludeAttrsSync: ['tabindex', 'class', 'empty'],
12237
12276
  componentName: componentName$1,
12238
12277
  style: () => `
12239
12278
  :host {
@@ -12739,7 +12778,6 @@ const button = {
12739
12778
  [compVars$6.outlineColor]: 'transparent',
12740
12779
 
12741
12780
  [compVars$6.iconSize]: '1.5em',
12742
- [compVars$6.iconColor]: 'currentColor',
12743
12781
 
12744
12782
  size: {
12745
12783
  xs: { [compVars$6.fontSize]: '12px' },