@descope-ui/common 2.2.12 → 2.2.14

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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ## [2.2.14](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.13...web-components-ui-2.2.14) (2025-12-22)
6
+
7
+ ## [2.2.13](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.12...web-components-ui-2.2.13) (2025-12-21)
8
+
5
9
  ## [2.2.12](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.11...web-components-ui-2.2.12) (2025-12-18)
6
10
 
7
11
  ## [2.2.11](https://github.com/descope/web-components-ui/compare/web-components-ui-2.2.10...web-components-ui-2.2.11) (2025-12-02)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope-ui/common",
3
- "version": "2.2.12",
3
+ "version": "2.2.14",
4
4
  "dependencies": {
5
5
  "element-internals-polyfill": "^1.3.9",
6
6
  "color": "^4.2.3",
@@ -57,6 +57,9 @@ const createSyncAttrsCb =
57
57
  attrNames.forEach((attrName) => {
58
58
  const targetAttrName = mapAttrs[attrName] || attrName;
59
59
  const srcAttrVal = srcEle.getAttribute(attrName);
60
+
61
+ if (!targetEle) return;
62
+
60
63
  if (srcAttrVal !== null) {
61
64
  if (targetEle.getAttribute(targetAttrName) !== srcAttrVal) {
62
65
  targetEle.setAttribute(targetAttrName, srcAttrVal);
@@ -108,6 +111,7 @@ export const forwardProps = (src, target, props = []) => {
108
111
 
109
112
  export const injectStyle = (cssString, ref, { prepend = false } = {}) => {
110
113
  let style;
114
+
111
115
  try {
112
116
  style = new CSSStyleSheet();
113
117
  } catch (e) {
@@ -126,8 +130,10 @@ export const injectStyle = (cssString, ref, { prepend = false } = {}) => {
126
130
  _ref.adoptedStyleSheets = adoptedStyleSheets;
127
131
  }
128
132
 
129
- if(cssString && !style.cssRules[0]?.style){
130
- console.warn(`No style rules were created, make sure the CSS is valid:\n "${cssString}"`)
133
+ if (cssString && !style.cssRules[0]?.style) {
134
+ console.warn(
135
+ `No style rules were created, make sure the CSS is valid:\n "${cssString}"`,
136
+ );
131
137
  }
132
138
 
133
139
  return style;
@@ -102,7 +102,7 @@ export const createStyleMixin =
102
102
  if (this.#styleAttributes.length) {
103
103
  let classSpecifier = createClassSelectorSpecifier(
104
104
  componentName,
105
- CSS_SELECTOR_SPECIFIER_MULTIPLY
105
+ CSS_SELECTOR_SPECIFIER_MULTIPLY,
106
106
  );
107
107
  const elementId = this.getAttribute('id');
108
108
  if (elementId) {
@@ -111,11 +111,13 @@ export const createStyleMixin =
111
111
  classSpecifier += `#${CSS.escape(elementId)}`;
112
112
  }
113
113
 
114
- this.#overrideStyleEle = injectStyle(`:host(${classSpecifier}) {}`, this.#rootElement);
114
+ this.#overrideStyleEle = injectStyle(
115
+ `:host(${classSpecifier}) {}`,
116
+ this.#rootElement,
117
+ );
115
118
  }
116
119
  }
117
120
 
118
-
119
121
  #setAttrOverride(attrName, value) {
120
122
  const style = this.#overrideStyleEle.cssRules[0].style;
121
123
 
@@ -154,14 +156,16 @@ export const createStyleMixin =
154
156
  }
155
157
 
156
158
  #addClassName(className) {
157
- (this.#rootElement.classList || this.#rootElement.host.classList).add(
158
- className,
159
- );
159
+ (
160
+ this.#rootElement?.classList ||
161
+ this.#rootElement?.host?.classList ||
162
+ this.classList
163
+ ).add(className);
160
164
  }
161
165
 
162
166
  async init() {
163
167
  super.init?.();
164
- if (this.shadowRoot.isConnected) {
168
+ if (this.shadowRoot?.isConnected || !this.shadowRoot) {
165
169
  this.#rootElement =
166
170
  (await this.#getRootElement?.(this)) || this.shadowRoot;
167
171
 
@@ -3,11 +3,15 @@ export const hoverableMixin = (superclass) =>
3
3
  init() {
4
4
  super.init?.();
5
5
 
6
- this.baseElement.addEventListener('mouseover', (e) => {
6
+ (this.baseElement || this).addEventListener('mouseover', (e) => {
7
7
  this.setAttribute('hover', 'true');
8
- e.target.addEventListener('mouseleave', () => this.removeAttribute('hover'), {
9
- once: true,
10
- });
8
+ e.target.addEventListener(
9
+ 'mouseleave',
10
+ () => this.removeAttribute('hover'),
11
+ {
12
+ once: true,
13
+ },
14
+ );
11
15
  });
12
16
  }
13
17
  };
@@ -9,8 +9,6 @@ import { createCssVarsList } from './createStyleMixin/helpers';
9
9
  // when the portal name is "overlay".
10
10
  // because of that, we are adding this separator that is also used as a differentiator
11
11
  const DISPLAY_NAME_SEPARATOR = '_';
12
- const PORTAL_THEME_PREFIX = '@';
13
-
14
12
 
15
13
  const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
16
14
 
@@ -35,6 +33,7 @@ const withWaitForShadowRoot = (getRootElementFn) => async (that) => {
35
33
  setTimeout(check);
36
34
  } else {
37
35
  res(ele.shadowRoot);
36
+ return;
38
37
  }
39
38
  };
40
39
  check();
@@ -42,7 +41,12 @@ const withWaitForShadowRoot = (getRootElementFn) => async (that) => {
42
41
  };
43
42
 
44
43
  export const portalMixin =
45
- ({ name, selector, mappings = {}, forward: { attributes = [], include = true } = {} }) =>
44
+ ({
45
+ name,
46
+ selector,
47
+ mappings = {},
48
+ forward: { attributes = [], include = true } = {},
49
+ }) =>
46
50
  (superclass) => {
47
51
  const eleDisplayName = name || sanitizeSelector(selector);
48
52
 
@@ -55,8 +59,13 @@ export const portalMixin =
55
59
  return {
56
60
  ...BaseClass.cssVarList,
57
61
  [eleDisplayName]: createCssVarsList(
58
- kebabCaseJoin(superclass.componentName, DISPLAY_NAME_SEPARATOR + eleDisplayName),
59
- mappings
62
+ eleDisplayName
63
+ ? kebabCaseJoin(
64
+ superclass.componentName,
65
+ DISPLAY_NAME_SEPARATOR + eleDisplayName,
66
+ )
67
+ : superclass.componentName,
68
+ mappings,
60
69
  ),
61
70
  };
62
71
  }
@@ -66,14 +75,18 @@ export const portalMixin =
66
75
  constructor() {
67
76
  // we cannot use "this" before calling "super"
68
77
  const getRootElement = async (that) => {
69
- const baseEle = (that.shadowRoot || that).querySelector(that.baseSelector);
70
- if (!selector) {
78
+ const baseEle = (that.shadowRoot || that).querySelector(
79
+ that.baseSelector,
80
+ );
81
+ if (!selector || !that.shadowRoot) {
71
82
  return baseEle;
72
83
  }
73
84
 
74
85
  // in case we have a selector, we should first wait for the base element shadow root
75
86
  // and then look for the internal element
76
- const baseEleShadowRoot = await withWaitForShadowRoot(() => baseEle)(that);
87
+ const baseEleShadowRoot = await withWaitForShadowRoot(() => baseEle)(
88
+ that,
89
+ );
77
90
  return baseEleShadowRoot.querySelector(selector);
78
91
  };
79
92
 
@@ -81,14 +94,22 @@ export const portalMixin =
81
94
 
82
95
  super({
83
96
  getRootElement: getPortalElement,
84
- componentNameSuffix: DISPLAY_NAME_SEPARATOR + eleDisplayName,
85
- themeSection: PORTAL_THEME_PREFIX + eleDisplayName,
86
- baseSelector: ':host',
97
+ componentNameSuffix:
98
+ eleDisplayName && DISPLAY_NAME_SEPARATOR + eleDisplayName,
99
+ themeSection: eleDisplayName
100
+ ? DISPLAY_NAME_SEPARATOR + eleDisplayName
101
+ : undefined,
102
+ baseSelector: '',
87
103
  });
88
104
 
89
- this.#portalEle = getPortalElement(this).then((ele) => ele.host);
105
+ // Defer portal element lookup to init() for React compatibility
106
+ // (elements created in init() won't exist during constructor)
107
+ this.#getPortalElement = () =>
108
+ getPortalElement(this).then((ele) => ele?.host || ele);
90
109
  }
91
110
 
111
+ #getPortalElement;
112
+
92
113
  async #handleHoverAttribute() {
93
114
  const portalEle = await this.#portalEle;
94
115
  portalEle.onmouseenter = (e) => {
@@ -101,6 +122,8 @@ export const portalMixin =
101
122
 
102
123
  async init() {
103
124
  super.init?.();
125
+ // Initialize portal element lookup here (deferred from constructor for React compatibility)
126
+ this.#portalEle = this.#getPortalElement();
104
127
  const portalEle = await this.#portalEle;
105
128
  forwardAttrs(this, portalEle, {
106
129
  [include ? 'includeAttrs' : 'excludeAttrs']: attributes,