@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.
@@ -2,6 +2,7 @@
2
2
 
3
3
  var merge = require('lodash.merge');
4
4
  var Color = require('color');
5
+ var DOMPurify = require('dompurify');
5
6
  var MarkdownIt = require('markdown-it');
6
7
  require('lodash.debounce');
7
8
  var hljs = require('highlight.js');
@@ -2633,8 +2634,11 @@ const createImgEle = (src) => {
2633
2634
  };
2634
2635
 
2635
2636
  const createSvgEle = (text) => {
2637
+ // we want to purify the SVG to avoid XSS attacks
2638
+ const clean = DOMPurify.sanitize(text, { USE_PROFILES: { svg: true, svgFilters: true } });
2639
+
2636
2640
  const parser = new DOMParser();
2637
- const ele = parser.parseFromString(text, 'image/svg+xml').querySelector('svg');
2641
+ const ele = parser.parseFromString(clean, 'image/svg+xml').querySelector('svg');
2638
2642
  return ele;
2639
2643
  };
2640
2644
 
@@ -2670,7 +2674,7 @@ const componentName$V = getComponentName('icon');
2670
2674
 
2671
2675
  class RawIcon extends createBaseClass({ componentName: componentName$V, baseSelector: 'slot' }) {
2672
2676
  static get observedAttributes() {
2673
- return ['src', 'fill-color'];
2677
+ return ['src'];
2674
2678
  }
2675
2679
 
2676
2680
  #icon;
@@ -2695,36 +2699,23 @@ class RawIcon extends createBaseClass({ componentName: componentName$V, baseSele
2695
2699
  `;
2696
2700
  }
2697
2701
 
2698
- get fillColor() {
2699
- return this.getAttribute('fill-color') === 'true';
2700
- }
2701
-
2702
2702
  get src() {
2703
2703
  return this.getAttribute('src');
2704
2704
  }
2705
2705
 
2706
2706
  // in order to fill an SVG with `currentColor` override all of its `fill` and `path` nodes
2707
2707
  // with the value from the `st-fill` attribute
2708
- updateFillColor() {
2709
- if (this.#icon && this.fillColor) {
2710
- const fillCssVar = (selector) => {
2711
- this.querySelectorAll(selector).forEach((ele) =>
2712
- ele.setAttribute(
2713
- 'fill',
2714
- `var(${IconClass.cssVarList.fill}, ${ele.getAttribute('fill') || "''"})`
2715
- )
2716
- );
2717
- };
2718
-
2719
- fillCssVar('*[fill]');
2720
- fillCssVar('path');
2721
- }
2722
- }
2723
-
2724
- resetIcon() {
2725
- if (!this.#icon) return;
2726
- this.innerHTML = '';
2727
- this.appendChild(this.#icon.cloneNode(true));
2708
+ // eslint-disable-next-line class-methods-use-this
2709
+ updateFillColor(node) {
2710
+ // set fill to root node and all its relevant selectors
2711
+ const elementsToReplace = [node, ...node.querySelectorAll('*[fill]')];
2712
+
2713
+ elementsToReplace.forEach((ele) => {
2714
+ ele.setAttribute(
2715
+ 'fill',
2716
+ `var(${IconClass.cssVarList.fill}, ${ele.getAttribute('fill') || "''"})`
2717
+ );
2718
+ });
2728
2719
  }
2729
2720
 
2730
2721
  attributeChangedCallback(attrName, oldValue, newValue) {
@@ -2734,13 +2725,13 @@ class RawIcon extends createBaseClass({ componentName: componentName$V, baseSele
2734
2725
 
2735
2726
  if (attrName === 'src') {
2736
2727
  createIcon(this.src).then((res) => {
2737
- this.#icon = res;
2738
- this.resetIcon();
2739
- this.updateFillColor();
2728
+ this.innerHTML = '';
2729
+ if (res) {
2730
+ const clonedNode = res.cloneNode(true);
2731
+ this.updateFillColor(clonedNode);
2732
+ this.appendChild(clonedNode);
2733
+ }
2740
2734
  });
2741
- } else if (attrName === 'fill-color') {
2742
- this.resetIcon();
2743
- this.updateFillColor();
2744
2735
  }
2745
2736
  }
2746
2737
  }
@@ -2965,7 +2956,6 @@ const button = {
2965
2956
  [compVars$6.outlineColor]: 'transparent',
2966
2957
 
2967
2958
  [compVars$6.iconSize]: '1.5em',
2968
- [compVars$6.iconColor]: 'currentColor',
2969
2959
 
2970
2960
  size: {
2971
2961
  xs: { [compVars$6.fontSize]: '12px' },
@@ -13214,7 +13204,7 @@ const componentName$3 = getComponentName('list');
13214
13204
 
13215
13205
  class RawList extends createBaseClass({ componentName: componentName$3, baseSelector: '.wrapper' }) {
13216
13206
  static get observedAttributes() {
13217
- return ['variant'];
13207
+ return ['variant', 'readonly'];
13218
13208
  }
13219
13209
 
13220
13210
  constructor() {
@@ -13297,6 +13287,18 @@ class RawList extends createBaseClass({ componentName: componentName$3, baseSele
13297
13287
  observeChildren(this, () => {
13298
13288
  this.#handleEmptyState();
13299
13289
  this.#handleItemsVariant();
13290
+ this.#handleReadOnly();
13291
+ });
13292
+ }
13293
+
13294
+ get isReadOnly() {
13295
+ return this.getAttribute('readonly') === 'true';
13296
+ }
13297
+
13298
+ #handleReadOnly() {
13299
+ this.items.forEach((item) => {
13300
+ if (this.isReadOnly) item.setAttribute('inert', '');
13301
+ else item.removeAttribute('inert');
13300
13302
  });
13301
13303
  }
13302
13304
 
@@ -13307,6 +13309,8 @@ class RawList extends createBaseClass({ componentName: componentName$3, baseSele
13307
13309
 
13308
13310
  if (name === 'variant') {
13309
13311
  this.#handleItemsVariant();
13312
+ } else if (name === 'readonly') {
13313
+ this.#handleReadOnly();
13310
13314
  }
13311
13315
  }
13312
13316
  }
@@ -13520,16 +13524,51 @@ const createDynamicDataMixin =
13520
13524
  super.init?.();
13521
13525
 
13522
13526
  if (rerenderAttrsList.length) {
13523
- observeAttributes(this, () => this.#renderItems(), { includeAttrs: rerenderAttrsList });
13527
+ observeAttributes(
13528
+ this,
13529
+ (attrs) => {
13530
+ if (attrs.includes('data')) this.#handleDataAttr();
13531
+ if (attrs.some((attr) => attr !== 'data')) this.#renderItems();
13532
+ },
13533
+ { includeAttrs: [...rerenderAttrsList, 'data'] }
13534
+ );
13524
13535
  } else {
13525
13536
  this.#renderItems();
13526
13537
  }
13527
13538
  }
13539
+
13540
+ #handleDataAttr() {
13541
+ const dataAttr = this.getAttribute('data');
13542
+
13543
+ if (!dataAttr) return;
13544
+
13545
+ try {
13546
+ this.#data = JSON.parse(dataAttr);
13547
+ } catch (e) {
13548
+ // eslint-disable-next-line no-console
13549
+ console.warn('Invalid JSON data', dataAttr);
13550
+ }
13551
+ }
13552
+
13553
+ attributeChangedCallback(name, oldValue, newValue) {
13554
+ super.attributeChangedCallback?.(name, oldValue, newValue);
13555
+
13556
+ if (newValue === oldValue) return;
13557
+
13558
+ if (name === 'data') {
13559
+ try {
13560
+ this.data = JSON.parse(newValue);
13561
+ } catch (e) {
13562
+ // eslint-disable-next-line no-console
13563
+ console.warn('Invalid JSON data', newValue);
13564
+ }
13565
+ }
13566
+ }
13528
13567
  };
13529
13568
 
13530
13569
  const componentName$2 = getComponentName('apps-list');
13531
13570
 
13532
- const limitAbbreviation = (str, limit = 3) =>
13571
+ const limitAbbreviation = (str, limit = 2) =>
13533
13572
  str
13534
13573
  .trim()
13535
13574
  .split(' ')
@@ -13538,12 +13577,11 @@ const limitAbbreviation = (str, limit = 3) =>
13538
13577
  .join('');
13539
13578
 
13540
13579
  const itemRenderer = ({ name, icon, url }, _, ref) => `
13541
- <a href="${url}" target="_blank" title="${url}">
13580
+ <a ${url ? `href="${url}" title="${url}"` : ''} target="_blank">
13542
13581
  <descope-list-item>
13543
13582
  <descope-avatar
13544
- img="${icon}"
13545
- display-name="${name}"
13546
- abbr=${limitAbbreviation(name)}
13583
+ ${icon ? `img="${icon}"` : ''}
13584
+ ${name ? `display-name="${name}" abbr=${limitAbbreviation(name)}` : ''}
13547
13585
  size=${ref.size}
13548
13586
  ></descope-avatar>
13549
13587
  <descope-text
@@ -13589,7 +13627,7 @@ const AppsListClass = compose(
13589
13627
  createProxy({
13590
13628
  slots: ['empty-state'],
13591
13629
  wrappedEleName: 'descope-list',
13592
- excludeAttrsSync: ['tabindex', 'class'],
13630
+ excludeAttrsSync: ['tabindex', 'class', 'empty'],
13593
13631
  componentName: componentName$2,
13594
13632
  style: () => `
13595
13633
  :host {