@descope/web-components-ui 1.0.64 → 1.0.66

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.
Files changed (54) hide show
  1. package/dist/cjs/index.cjs.js +6 -4
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js +706 -464
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/umd/233.js +5 -1
  6. package/dist/umd/314.js +283 -0
  7. package/dist/umd/314.js.LICENSE.txt +27 -0
  8. package/dist/umd/541.js +744 -0
  9. package/dist/umd/541.js.LICENSE.txt +21 -0
  10. package/dist/umd/725.js +37 -1
  11. package/dist/umd/786.js +1 -1
  12. package/dist/umd/824.js +229 -0
  13. package/dist/umd/{54.js.LICENSE.txt → 824.js.LICENSE.txt} +0 -6
  14. package/dist/umd/840.js +9 -9
  15. package/dist/umd/860.js +1 -0
  16. package/dist/umd/descope-button-index-js.js +1 -1
  17. package/dist/umd/descope-checkbox-index-js.js +1 -1
  18. package/dist/umd/descope-combo-box-index-js.js +1 -0
  19. package/dist/umd/descope-container-index-js.js +1 -1
  20. package/dist/umd/descope-date-picker-index-js.js +1 -1
  21. package/dist/umd/descope-divider-index-js.js +1 -1
  22. package/dist/umd/descope-email-field-index-js.js +1 -1
  23. package/dist/umd/descope-link-index-js.js +1 -1
  24. package/dist/umd/descope-loader-linear-index-js.js +1 -1
  25. package/dist/umd/descope-loader-radial-index-js.js +1 -1
  26. package/dist/umd/descope-logo-index-js.js +1 -1
  27. package/dist/umd/descope-number-field-index-js.js +1 -1
  28. package/dist/umd/descope-passcode-descope-passcode-internal-index-js.js +1 -1
  29. package/dist/umd/descope-passcode-index-js.js +1 -1
  30. package/dist/umd/descope-password-field-index-js.js +1 -1
  31. package/dist/umd/descope-switch-toggle-index-js.js +1 -1
  32. package/dist/umd/descope-text-area-index-js.js +1 -1
  33. package/dist/umd/descope-text-field-index-js.js +1 -1
  34. package/dist/umd/descope-text-index-js.js +1 -1
  35. package/dist/umd/index.js +1 -1
  36. package/package.json +2 -1
  37. package/src/components/descope-combo-box/ComboBox.js +111 -0
  38. package/src/components/descope-combo-box/index.js +6 -0
  39. package/src/components/descope-passcode/Passcode.js +1 -0
  40. package/src/components/descope-passcode/descope-passcode-internal/PasscodeInternal.js +9 -5
  41. package/src/constants.js +3 -1
  42. package/src/helpers/componentHelpers.js +55 -36
  43. package/src/helpers/index.js +2 -1
  44. package/src/helpers/themeHelpers/index.js +3 -3
  45. package/src/mixins/createStyleMixin/index.js +116 -90
  46. package/src/mixins/index.js +1 -0
  47. package/src/mixins/inputMixin.js +12 -7
  48. package/src/mixins/portalMixin.js +62 -0
  49. package/src/mixins/proxyInputMixin.js +23 -22
  50. package/src/theme/components/comboBox.js +32 -0
  51. package/src/theme/components/index.js +3 -1
  52. package/dist/umd/54.js +0 -971
  53. package/dist/umd/666.js +0 -37
  54. /package/dist/umd/{666.js.LICENSE.txt → 725.js.LICENSE.txt} +0 -0
@@ -1,109 +1,135 @@
1
- import { CSS_SELECTOR_SPECIFIER_MULTIPLY } from '../../constants';
1
+ import { BASE_THEME_SECTION, CSS_SELECTOR_SPECIFIER_MULTIPLY } from '../../constants';
2
2
  import { kebabCaseJoin } from '../../helpers';
3
- import { getCssVarName } from '../../helpers/componentHelpers';
3
+ import { getCssVarName, observeAttributes } from '../../helpers/componentHelpers';
4
4
  import { componentsThemeManager } from '../../helpers/themeHelpers/componentsThemeManager';
5
5
  import { createStyle, createCssVarsList, createClassSelectorSpecifier } from './helpers';
6
6
 
7
- export const createStyleMixin =
8
- ({ mappings = {} }) =>
9
- (superclass) => {
10
- const styleAttributes = Object.keys(mappings).map((key) =>
11
- kebabCaseJoin('st', key)
12
- );
13
- return class CustomStyleMixinClass extends superclass {
14
- static get observedAttributes() {
15
- const superAttrs = superclass.observedAttributes || [];
16
- return [...superAttrs, ...styleAttributes];
17
- }
7
+ const STYLE_OVERRIDE_ATTR_PREFIX = 'st'
18
8
 
19
- static get cssVarList() {
20
- return createCssVarsList(superclass.componentName, {
9
+
10
+ export const createStyleMixin =
11
+ ({ mappings = {} }) => (superclass) =>
12
+ class CustomStyleMixinClass extends superclass {
13
+ static get cssVarList() {
14
+ return {
15
+ ...superclass.cssVarList,
16
+ ...createCssVarsList(superclass.componentName, {
21
17
  ...mappings,
22
- });
18
+ })
19
+ };
20
+ }
21
+
22
+ #overrideStyleEle;
23
+ #themeStyleEle;
24
+ #disconnectThemeManager
25
+ #componentNameSuffix
26
+ #themeSection
27
+ #rootElement
28
+ #baseSelector
29
+ #styleAttributes
30
+
31
+ // we are using this mixin also for portalMixin
32
+ // so we should be able to inject styles to other DOM elements
33
+ // this is why we need to support these overrides
34
+ constructor({
35
+ getRootElement,
36
+ componentNameSuffix = '',
37
+ themeSection = BASE_THEME_SECTION,
38
+ baseSelector
39
+ } = {}) {
40
+ super();
41
+ this.#componentNameSuffix = componentNameSuffix
42
+ this.#themeSection = themeSection
43
+ this.#rootElement = getRootElement?.(this) || this.shadowRoot
44
+ this.#baseSelector = baseSelector ?? this.baseSelector
45
+
46
+ this.#styleAttributes = Object.keys(mappings).map((key) =>
47
+ kebabCaseJoin(STYLE_OVERRIDE_ATTR_PREFIX, componentNameSuffix, key)
48
+ );
49
+ }
50
+
51
+ get componentTheme() {
52
+ return componentsThemeManager.currentTheme?.[superclass.componentName] || ''
53
+ }
54
+
55
+ #onComponentThemeChange() {
56
+ this.#themeStyleEle.innerHTML = this.componentTheme[this.#themeSection]
57
+ }
58
+
59
+ #createComponentTheme() {
60
+ this.#themeStyleEle = document.createElement('style');
61
+ this.#themeStyleEle.id = 'style-mixin-theme';
62
+ this.#rootElement.prepend(this.#themeStyleEle);
63
+ this.#disconnectThemeManager = componentsThemeManager.onCurrentThemeChange(this.#onComponentThemeChange.bind(this))
64
+ this.#onComponentThemeChange()
65
+ }
66
+
67
+ #createAttrOverrideStyle() {
68
+ this.#overrideStyleEle = document.createElement('style');
69
+ this.#overrideStyleEle.id = 'style-mixin-overrides';
70
+
71
+ const classSpecifier = createClassSelectorSpecifier(superclass.componentName, CSS_SELECTOR_SPECIFIER_MULTIPLY);
72
+
73
+ this.#overrideStyleEle.innerText = `:host(${classSpecifier}) {}`;
74
+ this.#rootElement.append(this.#overrideStyleEle);
75
+ }
76
+
77
+ #setAttrOverrideStyle(attrName, value) {
78
+ const style = this.#overrideStyleEle?.sheet?.cssRules[0].style;
79
+ if (!style) return;
80
+
81
+ const varName = getCssVarName(
82
+ superclass.componentName,
83
+ attrName.replace(new RegExp(`^${STYLE_OVERRIDE_ATTR_PREFIX}-`), '')
84
+ );
85
+
86
+ if (value) style?.setProperty(varName, value);
87
+ else style?.removeProperty(varName);
88
+ }
89
+
90
+ #updateOverrideStyle(attrs = []) {
91
+ for (const attr of attrs) {
92
+ if (this.#styleAttributes.includes(attr)) {
93
+ this.#setAttrOverrideStyle(attr, this.getAttribute(attr));
94
+ }
23
95
  }
24
96
 
25
- #overrideStyleEle = null;
26
- #themeStyleEle = null;
27
- #disconnectThemeManager
97
+ // we are rewriting the style back to the style tag
98
+ this.#overrideStyleEle.innerHTML = this.#overrideStyleEle?.sheet?.cssRules[0].cssText
99
+ }
100
+
101
+ #createComponentStyle() {
102
+ const themeStyle = document.createElement('style');
103
+ themeStyle.id = 'style-mixin-mappings'
104
+ themeStyle.innerHTML = createStyle(
105
+ kebabCaseJoin(superclass.componentName, this.#componentNameSuffix),
106
+ this.#baseSelector,
107
+ mappings
108
+ );
109
+ this.#rootElement.prepend(themeStyle);
110
+ }
111
+
112
+ #addClassName(className) {
113
+ (this.#rootElement.classList || this.#rootElement.host.classList).add(className)
114
+ }
28
115
 
29
- constructor() {
30
- super();
116
+ connectedCallback() {
117
+ super.connectedCallback?.();
118
+ if (this.shadowRoot.isConnected) {
31
119
 
32
- this.classList.add(superclass.componentName)
120
+ this.#addClassName(superclass.componentName)
33
121
 
34
122
  this.#createComponentStyle();
35
123
  this.#createComponentTheme();
36
124
  this.#createAttrOverrideStyle();
37
- }
38
-
39
- get componentTheme() {
40
- return componentsThemeManager.currentTheme?.[superclass.componentName] || ''
41
- }
42
-
43
- onComponentThemeChange() {
44
- this.#themeStyleEle.innerHTML = this.componentTheme.theme
45
- }
46
-
47
- #createComponentTheme() {
48
- this.#themeStyleEle = document.createElement('style');
49
- this.#themeStyleEle.id = 'style-mixin-component-theme';
50
- this.shadowRoot.prepend(this.#themeStyleEle);
51
- this.#disconnectThemeManager = componentsThemeManager.onCurrentThemeChange(this.onComponentThemeChange.bind(this))
52
- this.onComponentThemeChange()
53
- }
54
125
 
55
- #createAttrOverrideStyle() {
56
- this.#overrideStyleEle = document.createElement('style');
57
- this.#overrideStyleEle.id = 'style-mixin-overrides';
126
+ // this is instead attributeChangedCallback because we cannot use static methods in this case
127
+ observeAttributes(this, this.#updateOverrideStyle.bind(this), {})
58
128
 
59
- const classSpecifier = createClassSelectorSpecifier(superclass.componentName, CSS_SELECTOR_SPECIFIER_MULTIPLY);
60
- this.#overrideStyleEle.innerText = `:host(${classSpecifier}) {}`;
61
- this.shadowRoot.append(this.#overrideStyleEle);
62
129
  }
130
+ }
63
131
 
64
- #updateAttrOverrideStyle(attrName, value) {
65
- const style = this.#overrideStyleEle.sheet?.cssRules[0].style;
66
- const varName = getCssVarName(
67
- superclass.componentName,
68
- attrName.replace(/^st-/, '')
69
- );
70
-
71
- if (value) style?.setProperty(varName, value);
72
- else style?.removeProperty(varName);
73
- }
74
-
75
- #createComponentStyle() {
76
- const themeStyle = document.createElement('style');
77
- themeStyle.id = 'style-mixin-component';
78
- themeStyle.innerHTML = createStyle(
79
- superclass.componentName,
80
- this.baseSelector,
81
- mappings
82
- );
83
- this.shadowRoot.prepend(themeStyle);
84
- }
85
-
86
- attributeChangedCallback(attrName, oldValue, newValue) {
87
- super.attributeChangedCallback?.(attrName, oldValue, newValue);
88
-
89
- if (styleAttributes.includes(attrName)) {
90
- this.#updateAttrOverrideStyle(attrName, newValue);
91
- }
92
- }
93
-
94
- connectedCallback() {
95
- super.connectedCallback?.();
96
- if (this.shadowRoot.isConnected) {
97
- Array.from(this.attributes).forEach((attr) => {
98
- if (styleAttributes.includes(attr.nodeName)) {
99
- this.#updateAttrOverrideStyle(attr.nodeName, attr.value);
100
- }
101
- });
102
- }
103
- }
104
-
105
- disconnectedCallback() {
106
- this.#disconnectThemeManager?.();
107
- }
108
- };
132
+ disconnectedCallback() {
133
+ this.#disconnectThemeManager?.();
134
+ }
109
135
  };
@@ -5,3 +5,4 @@ export { proxyInputMixin } from './proxyInputMixin';
5
5
  export { componentNameValidationMixin } from './componentNameValidationMixin';
6
6
  export { hoverableMixin } from './hoverableMixin';
7
7
  export { inputMixin } from './inputMixin'
8
+ export { portalMixin } from './portalMixin'
@@ -1,5 +1,4 @@
1
-
2
- const upperFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1)
1
+ import { upperFirst } from "../helpers";
3
2
 
4
3
  const events = [
5
4
  'change',
@@ -68,7 +67,13 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
68
67
  }
69
68
  }
70
69
 
70
+ get isReadOnly() {
71
+ return this.getAttribute('readonly') !== 'false'
72
+ }
73
+
71
74
  setValidity() {
75
+ if (this.isReadOnly) return;
76
+
72
77
  const validity = this.getValidity()
73
78
  this.#internals.setValidity(validity, this.getErrorMessage(validity))
74
79
  }
@@ -94,8 +99,8 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
94
99
  }
95
100
 
96
101
  setCustomValidity(errorMessage) {
97
- if(errorMessage){
98
- this.#internals.setValidity({customError: true}, errorMessage)
102
+ if (errorMessage) {
103
+ this.#internals.setValidity({ customError: true }, errorMessage)
99
104
  } else {
100
105
  this.#internals.setValidity({})
101
106
  this.setValidity()
@@ -148,9 +153,9 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
148
153
  }
149
154
  }
150
155
 
151
- handleDispatchValidationEvents(){
152
- if(this.checkValidity()) {
153
- this.dispatchValid()
156
+ handleDispatchValidationEvents() {
157
+ if (this.checkValidity()) {
158
+ this.dispatchValid()
154
159
  } else {
155
160
  this.dispatchInvalid()
156
161
  }
@@ -0,0 +1,62 @@
1
+ import { PORTAL_THEME_PREFIX } from "../constants";
2
+ import { upperFirst } from "../helpers";
3
+ import { forwardAttrs } from "../helpers/componentHelpers";
4
+ import { createStyleMixin } from "./createStyleMixin";
5
+ import { createCssVarsList } from "./createStyleMixin/helpers";
6
+
7
+ const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
8
+
9
+ const appendSuffixToKeys = (obj, suffix) => Object.keys(obj).reduce((acc, key) =>
10
+ Object.assign(acc, { [suffix + upperFirst(key)]: obj[key] }), {})
11
+
12
+ const getDomNode = (maybeDomNode) => maybeDomNode.host || maybeDomNode;
13
+
14
+ export const portalMixin = ({ name, selector, mappings = {} }) => (superclass) => {
15
+ const eleDisplayName = name || sanitizeSelector(selector)
16
+
17
+ const BaseClass = createStyleMixin({
18
+ mappings
19
+ })(superclass)
20
+
21
+ return class PortalMixinClass extends BaseClass {
22
+ static get cssVarList() {
23
+ return {
24
+ ...BaseClass.cssVarList,
25
+ ...createCssVarsList(superclass.componentName, appendSuffixToKeys(mappings, eleDisplayName))
26
+ };
27
+ }
28
+
29
+ #portalEle
30
+
31
+ constructor() {
32
+ // we cannot use "this" before calling "super"
33
+ const getRootElement = (that) => {
34
+ const baseEle = that.shadowRoot.querySelector(that.baseSelector)
35
+ const portal = baseEle.shadowRoot.querySelector(selector)
36
+
37
+ return portal.shadowRoot || portal
38
+ };
39
+
40
+ super({
41
+ getRootElement,
42
+ componentNameSuffix: eleDisplayName,
43
+ themeSection: PORTAL_THEME_PREFIX + eleDisplayName,
44
+ baseSelector: ':host'
45
+ })
46
+
47
+ this.#portalEle = getDomNode(getRootElement(this))
48
+ }
49
+
50
+ #handleHoverAttribute() {
51
+ this.#portalEle.onmouseenter = (e) => { e.target.setAttribute('hover', 'true') }
52
+ this.#portalEle.onmouseleave = (e) => { e.target.removeAttribute('hover') }
53
+ }
54
+
55
+ connectedCallback() {
56
+ super.connectedCallback?.();
57
+ forwardAttrs(this, this.#portalEle, { excludeAttrs: ['hover'] })
58
+
59
+ this.#handleHoverAttribute();
60
+ }
61
+ }
62
+ }
@@ -41,28 +41,6 @@ export const proxyInputMixin = (superclass) =>
41
41
 
42
42
  this.#inputElement = super.inputElement
43
43
 
44
- // this is our way to identify that the form was submitted
45
- // in this case, we want the input to be in error state if it's not valid
46
- this.addEventListener('focus', (e) => {
47
- if (e.relatedTarget?.form) {
48
- if (!this.checkValidity()) {
49
- this.setAttribute('invalid', 'true');
50
- }
51
-
52
- if (this.hasAttribute('invalid')) {
53
- this.reportValidityOnInternalInput()
54
- }
55
- }
56
- })
57
-
58
- this.addEventListener('invalid', () => {
59
- this.setInternalInputErrorMessage()
60
- this.setAttribute('error-message', this.validationMessage)
61
- })
62
-
63
- this.addEventListener('valid', () => {
64
- this.removeAttribute('invalid')
65
- })
66
44
  }
67
45
 
68
46
  get inputElement() {
@@ -118,6 +96,29 @@ export const proxyInputMixin = (superclass) =>
118
96
  connectedCallback() {
119
97
  this.baseEle = this.shadowRoot.querySelector(this.baseSelector);
120
98
 
99
+ // this is our way to identify that the form was submitted
100
+ // in this case, we want the input to be in error state if it's not valid
101
+ this.addEventListener('focus', (e) => {
102
+ if (e.relatedTarget?.form) {
103
+ if (!this.checkValidity()) {
104
+ this.setAttribute('invalid', 'true');
105
+ }
106
+
107
+ if (this.hasAttribute('invalid')) {
108
+ this.reportValidityOnInternalInput()
109
+ }
110
+ }
111
+ })
112
+
113
+ this.addEventListener('invalid', () => {
114
+ this.setInternalInputErrorMessage()
115
+ this.setAttribute('error-message', this.validationMessage)
116
+ })
117
+
118
+ this.addEventListener('valid', () => {
119
+ this.removeAttribute('invalid')
120
+ })
121
+
121
122
  super.connectedCallback?.();
122
123
 
123
124
  this.inputElement.addEventListener('input', () => {
@@ -0,0 +1,32 @@
1
+ import globals from '../globals';
2
+ import ComboBox from '../../components/descope-combo-box/ComboBox';
3
+ import { textField } from './textField';
4
+ import { getThemeRefs } from '../../helpers/themeHelpers';
5
+
6
+ const globalRefs = getThemeRefs(globals);
7
+
8
+ const vars = ComboBox.cssVarList;
9
+
10
+ export const comboBox = {
11
+ ...textField(ComboBox.cssVarList),
12
+ size: {
13
+ xs: {
14
+ [vars.width]: '30px'
15
+ }
16
+ },
17
+ [vars.borderColor]: 'green',
18
+ [vars.borderWidth]: '0',
19
+ [vars.cursor]: 'pointer',
20
+ [vars.padding]: '0',
21
+
22
+ '@overlay': {
23
+ [vars.overlayBackgroundColor] : 'red',
24
+ [vars.overlayBorder]: '3px solid blue',
25
+
26
+ _hover: {
27
+ [vars.overlayBackgroundColor] : 'blue',
28
+ }
29
+ }
30
+ };
31
+
32
+ export default comboBox;
@@ -13,6 +13,7 @@ import link from './link';
13
13
  import divider from './divider';
14
14
  import passcode from './passcode';
15
15
  import { loaderRadial, loaderLinear } from './loader';
16
+ import comboBox from './comboBox';
16
17
 
17
18
  export default {
18
19
  button,
@@ -30,5 +31,6 @@ export default {
30
31
  divider,
31
32
  passcode,
32
33
  loaderRadial,
33
- loaderLinear
34
+ loaderLinear,
35
+ comboBox
34
36
  };