@descope/web-components-ui 1.0.67 → 1.0.69

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.map +1 -1
  2. package/dist/index.esm.js +510 -395
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/umd/135.js +1 -0
  5. package/dist/umd/descope-button-index-js.js +1 -1
  6. package/dist/umd/descope-checkbox-index-js.js +1 -1
  7. package/dist/umd/descope-combo-box-index-js.js +1 -1
  8. package/dist/umd/descope-container-index-js.js +1 -1
  9. package/dist/umd/descope-date-picker-index-js.js +1 -1
  10. package/dist/umd/descope-divider-index-js.js +1 -1
  11. package/dist/umd/descope-email-field-index-js.js +1 -1
  12. package/dist/umd/descope-link-index-js.js +1 -1
  13. package/dist/umd/descope-loader-linear-index-js.js +1 -1
  14. package/dist/umd/descope-loader-radial-index-js.js +1 -1
  15. package/dist/umd/descope-logo-index-js.js +1 -1
  16. package/dist/umd/descope-number-field-index-js.js +1 -1
  17. package/dist/umd/descope-passcode-descope-passcode-internal-index-js.js +1 -1
  18. package/dist/umd/descope-passcode-index-js.js +1 -1
  19. package/dist/umd/descope-password-field-index-js.js +1 -1
  20. package/dist/umd/descope-switch-toggle-index-js.js +1 -1
  21. package/dist/umd/descope-text-area-index-js.js +1 -1
  22. package/dist/umd/descope-text-field-index-js.js +1 -1
  23. package/dist/umd/descope-text-index-js.js +1 -1
  24. package/dist/umd/index.js +1 -1
  25. package/package.json +1 -1
  26. package/src/baseClasses/BaseInputClass.js +3 -2
  27. package/src/baseClasses/createBaseClass.js +29 -0
  28. package/src/components/descope-combo-box/ComboBox.js +18 -4
  29. package/src/components/descope-container/Container.js +17 -25
  30. package/src/components/descope-divider/Divider.js +32 -40
  31. package/src/components/descope-link/Link.js +8 -17
  32. package/src/components/descope-loader-linear/LoaderLinear.js +24 -29
  33. package/src/components/descope-loader-radial/LoaderRadial.js +18 -26
  34. package/src/components/descope-logo/Logo.js +4 -12
  35. package/src/components/descope-passcode/Passcode.js +4 -11
  36. package/src/components/descope-passcode/descope-passcode-internal/PasscodeInternal.js +41 -53
  37. package/src/components/descope-text/Text.js +4 -12
  38. package/src/helpers/index.js +2 -0
  39. package/src/helpers/mixinsHelpers.js +18 -0
  40. package/src/mixins/changeMixin.js +47 -0
  41. package/src/mixins/componentNameValidationMixin.js +1 -1
  42. package/src/mixins/createProxy.js +26 -28
  43. package/src/mixins/createStyleMixin/helpers.js +3 -3
  44. package/src/mixins/createStyleMixin/index.js +10 -9
  45. package/src/mixins/draggableMixin.js +1 -1
  46. package/src/mixins/focusMixin.js +130 -0
  47. package/src/mixins/hoverableMixin.js +14 -13
  48. package/src/mixins/index.js +3 -1
  49. package/src/mixins/{inputMixin.js → inputValidationMixin.js} +17 -58
  50. package/src/mixins/portalMixin.js +11 -7
  51. package/src/mixins/proxyInputMixin.js +50 -45
  52. package/src/theme/components/comboBox.js +2 -9
  53. package/dist/umd/860.js +0 -1
  54. package/src/baseClasses/DescopeBaseClass.js +0 -1
@@ -1,4 +1,4 @@
1
- import { kebabCase } from '../../helpers';
1
+ import { isFunction, kebabCase } from '../../helpers';
2
2
  import { getCssVarName } from '../../helpers/componentHelpers';
3
3
 
4
4
  const createCssVarFallback = (first, ...rest) =>
@@ -8,7 +8,7 @@ const createCssSelector = (
8
8
  baseSelector = '',
9
9
  relativeSelectorOrSelectorFn = ''
10
10
  ) =>
11
- typeof relativeSelectorOrSelectorFn === 'function'
11
+ isFunction(relativeSelectorOrSelectorFn)
12
12
  ? relativeSelectorOrSelectorFn(baseSelector)
13
13
  : `${baseSelector}${/^[A-Za-z]/.test(relativeSelectorOrSelectorFn)
14
14
  ? ` ${relativeSelectorOrSelectorFn}`
@@ -65,7 +65,7 @@ export const createStyle = (componentName, baseSelector, mappings) => {
65
65
  ({ selector: relativeSelectorOrSelectorFn, property }) => {
66
66
  style.add(
67
67
  createCssSelector(baseSelector, relativeSelectorOrSelectorFn),
68
- property,
68
+ isFunction(property) ? property() : property,
69
69
  createCssVarFallback(cssVarName)
70
70
  );
71
71
  }
@@ -64,7 +64,7 @@ export const createStyleMixin =
64
64
  this.#onComponentThemeChange()
65
65
  }
66
66
 
67
- #createAttrOverrideStyle() {
67
+ #createOverridesStyle() {
68
68
  this.#overrideStyleEle = document.createElement('style');
69
69
  this.#overrideStyleEle.id = 'style-mixin-overrides';
70
70
 
@@ -74,7 +74,7 @@ export const createStyleMixin =
74
74
  this.#rootElement.append(this.#overrideStyleEle);
75
75
  }
76
76
 
77
- #setAttrOverrideStyle(attrName, value) {
77
+ #setAttrOverride(attrName, value) {
78
78
  const style = this.#overrideStyleEle?.sheet?.cssRules[0].style;
79
79
  if (!style) return;
80
80
 
@@ -87,10 +87,10 @@ export const createStyleMixin =
87
87
  else style?.removeProperty(varName);
88
88
  }
89
89
 
90
- #updateOverrideStyle(attrs = []) {
90
+ #updateOverridesStyle(attrs = []) {
91
91
  for (const attr of attrs) {
92
92
  if (this.#styleAttributes.includes(attr)) {
93
- this.#setAttrOverrideStyle(attr, this.getAttribute(attr));
93
+ this.#setAttrOverride(attr, this.getAttribute(attr));
94
94
  }
95
95
  }
96
96
 
@@ -98,7 +98,7 @@ export const createStyleMixin =
98
98
  this.#overrideStyleEle.innerHTML = this.#overrideStyleEle?.sheet?.cssRules[0].cssText
99
99
  }
100
100
 
101
- #createComponentStyle() {
101
+ #createMappingStyle() {
102
102
  const themeStyle = document.createElement('style');
103
103
  themeStyle.id = 'style-mixin-mappings'
104
104
  themeStyle.innerHTML = createStyle(
@@ -119,13 +119,14 @@ export const createStyleMixin =
119
119
 
120
120
  this.#addClassName(superclass.componentName)
121
121
 
122
- this.#createComponentStyle();
122
+ // TODO: we should do everything we can on the constructor
123
+ // when dragging & dropping these styles are created over & over
124
+ this.#createMappingStyle();
123
125
  this.#createComponentTheme();
124
- this.#createAttrOverrideStyle();
126
+ this.#createOverridesStyle();
125
127
 
126
128
  // this is instead attributeChangedCallback because we cannot use static methods in this case
127
- observeAttributes(this, this.#updateOverrideStyle.bind(this), {})
128
-
129
+ observeAttributes(this, this.#updateOverridesStyle.bind(this), {})
129
130
  }
130
131
  }
131
132
 
@@ -11,7 +11,7 @@ export const draggableMixin = (superclass) =>
11
11
  super();
12
12
 
13
13
  this.#styleEle = document.createElement('style');
14
- this.#styleEle.innerText = `${this.baseSelector} { cursor: inherit }`;
14
+ this.#styleEle.innerText = `* { cursor: inherit!important }`;
15
15
  }
16
16
 
17
17
  #handleDraggableStyle(isDraggable) {
@@ -0,0 +1,130 @@
1
+ import { upperFirst } from "../helpers";
2
+
3
+ const events = [
4
+ 'blur',
5
+ 'focus',
6
+ 'focusin',
7
+ 'focusout',
8
+ ]
9
+
10
+ export const focusMixin = (superclass) => class FocusMixinClass extends superclass {
11
+ #isFocused = false
12
+ #setFocusTimer
13
+
14
+ #boundedHandleFocus
15
+ #boundedHandleBlur
16
+ #boundedHandleFocusIn
17
+ #boundedHandleFocusOut
18
+
19
+ constructor() {
20
+ super();
21
+
22
+ for (const event of events) {
23
+ this[`dispatch${upperFirst(event)}`] = function () {
24
+ this.dispatchInputEvent(event)
25
+ }
26
+ }
27
+
28
+ this.#boundedHandleFocus = this.#handleFocus.bind(this);
29
+ this.#boundedHandleBlur = this.#handleBlur.bind(this);
30
+ this.#boundedHandleFocusIn = this.#handleFocusIn.bind(this);
31
+ this.#boundedHandleFocusOut = this.#handleFocusOut.bind(this);
32
+ }
33
+
34
+ #handleFocus(e) {
35
+ if (this.isReadOnly) {
36
+ e.stopPropagation()
37
+ return
38
+ }
39
+ // we want to listen only to browser events
40
+ // and not to events we are dispatching
41
+ if (e.isTrusted) { // TODO: check if this is needed, because Vaadin is also dispatching events
42
+ // we want to control the focus events that dispatched by the component
43
+ // so we are stopping propagation and handling it in setFocus
44
+ e.stopPropagation()
45
+ this.setFocus(true)
46
+
47
+ // if the focus event is on the root component (and not on the inner components)
48
+ // we want to notify the component and let it decide what to do with it
49
+ if (e.target === this) {
50
+ this.onFocus(e)
51
+ }
52
+ }
53
+ }
54
+
55
+ #handleFocusOut(e) {
56
+ // we want to listen only to browser events
57
+ // and not to events we are dispatching
58
+ if (e.isTrusted) {
59
+ // we want to control the focus events that dispatched by the component
60
+ // so we are stopping propagation and handling it in setFocus
61
+ e.stopPropagation()
62
+ }
63
+ }
64
+
65
+ #handleFocusIn(e) {
66
+ // we want to listen only to browser events
67
+ // and not to events we are dispatching
68
+ if (e.isTrusted) {
69
+ // we want to control the focus events that dispatched by the component
70
+ // so we are stopping propagation and handling it in setFocus
71
+ e.stopPropagation()
72
+ }
73
+ }
74
+
75
+ #handleBlur(e) {
76
+ if (e.isTrusted) {
77
+ e.stopPropagation()
78
+ this.setFocus(false)
79
+ }
80
+ }
81
+
82
+ get isReadOnly() {
83
+ return this.hasAttribute('readonly') && this.getAttribute('readonly') !== 'false'
84
+ }
85
+
86
+ // we want to debounce the calls to this fn
87
+ // so we can support input like components with multiple inputs inside
88
+ setFocus(isFocused) {
89
+ clearTimeout(this.#setFocusTimer)
90
+
91
+ this.#setFocusTimer = setTimeout(() => {
92
+ if (this.#isFocused !== isFocused) {
93
+ this.#isFocused = isFocused
94
+ if (isFocused) {
95
+ this.dispatchFocus();
96
+ this.dispatchFocusin();
97
+ }
98
+ else {
99
+ this.dispatchBlur()
100
+ this.dispatchFocusout();
101
+ }
102
+ }
103
+ })
104
+ }
105
+
106
+ onFocus() {
107
+ console.warn('onFocus', 'is not implemented')
108
+ }
109
+
110
+ dispatchInputEvent(eventName) {
111
+ this[`on${eventName}`]?.(); // in case we got an event callback as property
112
+ this.dispatchEvent(new InputEvent(eventName));
113
+ }
114
+
115
+ connectedCallback() {
116
+ super.connectedCallback?.();
117
+
118
+ this.addEventListener('focus', this.#boundedHandleFocus, true)
119
+ this.addEventListener('blur', this.#boundedHandleBlur, true)
120
+ this.addEventListener('focusin', this.#boundedHandleFocusIn)
121
+ this.addEventListener('focusout', this.#boundedHandleFocusOut)
122
+ }
123
+
124
+ disconnectedCallback() {
125
+ this.removeEventListener('focus', this.#boundedHandleFocus)
126
+ this.removeEventListener('blur', this.#boundedHandleBlur)
127
+ this.removeEventListener('focusin', this.#boundedHandleFocusIn)
128
+ this.removeEventListener('focusout', this.#boundedHandleFocusOut)
129
+ }
130
+ }
@@ -1,23 +1,24 @@
1
1
  export const hoverableMixin =
2
- (relativeSelector = '') =>
3
2
  (superclass) =>
4
- class HovrerableMixinClass extends superclass {
3
+ class HoverableMixinClass extends superclass {
4
+ #boundOnMouseOver = this.#onMouseOver.bind(this)
5
+
6
+ #onMouseOver(e) {
7
+ this.setAttribute('hover', 'true');
8
+ e.target.addEventListener(
9
+ 'mouseleave',
10
+ () => this.shadowRoot.host.removeAttribute('hover'),
11
+ { once: true }
12
+ );
13
+ }
14
+
5
15
  connectedCallback() {
6
16
  super.connectedCallback?.();
7
17
 
8
- const onMouseOver = (e) => {
9
- this.shadowRoot.host.setAttribute('hover', 'true');
10
- e.target.addEventListener(
11
- 'mouseleave',
12
- () => this.shadowRoot.host.removeAttribute('hover'),
13
- { once: true }
14
- );
15
- };
16
-
17
18
  const baseElement = this.shadowRoot.querySelector(
18
- this.baseSelector + relativeSelector
19
+ this.baseSelector
19
20
  );
20
21
 
21
- baseElement.addEventListener('mouseover', onMouseOver);
22
+ baseElement.addEventListener('mouseover', this.#boundOnMouseOver);
22
23
  }
23
24
  };
@@ -4,5 +4,7 @@ export { createProxy } from './createProxy';
4
4
  export { proxyInputMixin } from './proxyInputMixin';
5
5
  export { componentNameValidationMixin } from './componentNameValidationMixin';
6
6
  export { hoverableMixin } from './hoverableMixin';
7
- export { inputMixin } from './inputMixin'
7
+ export { focusMixin } from './focusMixin'
8
+ export { inputValidationMixin } from './inputValidationMixin'
8
9
  export { portalMixin } from './portalMixin'
10
+ export { changeMixin } from './changeMixin'
@@ -1,13 +1,4 @@
1
- import { upperFirst } from "../helpers";
2
-
3
- const events = [
4
- 'change',
5
- 'input',
6
- 'blur',
7
- 'focus',
8
- 'invalid',
9
- 'valid',
10
- ]
1
+ import { createDispatchEvent } from "../helpers/mixinsHelpers";
11
2
 
12
3
  const observedAttributes = [
13
4
  'required',
@@ -18,7 +9,7 @@ const errorAttributes = {
18
9
  valueMissing: 'data-errormessage-value-missing',
19
10
  patternMismatch: 'data-errormessage-pattern-mismatch'
20
11
  }
21
- export const inputMixin = (superclass) => class InputMixinClass extends superclass {
12
+ export const inputValidationMixin = (superclass) => class InputValidationMixinClass extends superclass {
22
13
  static get observedAttributes() {
23
14
  return [
24
15
  ...superclass.observedAttributes || [],
@@ -30,18 +21,19 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
30
21
  return true;
31
22
  }
32
23
 
24
+ #dispatchValid = createDispatchEvent.bind(this, 'valid')
25
+ #dispatchInvalid = createDispatchEvent.bind(this, 'invalid')
26
+
33
27
  #internals
34
28
 
29
+ #boundedHandleInput
30
+
35
31
  constructor() {
36
32
  super();
37
33
 
38
34
  this.#internals = this.attachInternals();
39
35
 
40
- for (const event of events) {
41
- this[`dispatch${upperFirst(event)}`] = function () {
42
- this.dispatchInputEvent(event)
43
- }
44
- }
36
+ this.#boundedHandleInput = this.#handleInput.bind(this);
45
37
  }
46
38
 
47
39
  get defaultErrorMsgValueMissing() {
@@ -67,13 +59,7 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
67
59
  }
68
60
  }
69
61
 
70
- get isReadOnly() {
71
- return this.hasAttribute('readonly') && this.getAttribute('readonly') !== 'false'
72
- }
73
-
74
62
  setValidity() {
75
- if (this.isReadOnly) return;
76
-
77
63
  const validity = this.getValidity()
78
64
  this.#internals.setValidity(validity, this.getErrorMessage(validity))
79
65
  }
@@ -83,7 +69,7 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
83
69
  }
84
70
 
85
71
  getValidity() {
86
- throw Error('getValidity', 'is not implemented')
72
+ console.warn('getValidity', 'is not implemented')
87
73
  }
88
74
 
89
75
  checkValidity() {
@@ -115,36 +101,11 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
115
101
  return this.getAttribute('pattern')
116
102
  }
117
103
 
118
- get value() {
119
- throw Error('get value', 'is not implemented')
120
- }
121
-
122
- set value(value) {
123
- throw Error('set value', 'is not implemented')
124
- }
125
-
126
- handleFocus() {
127
- throw Error('handleFocus', 'is not implemented')
128
- }
129
-
130
- handleInput() {
104
+ #handleInput() {
131
105
  this.setValidity()
132
106
  this.handleDispatchValidationEvents()
133
107
  }
134
108
 
135
- handleBlur() {
136
- throw Error('handleBlur', 'is not implemented')
137
- }
138
-
139
- handleChange() {
140
- throw Error('handleChange', 'is not implemented')
141
- }
142
-
143
- dispatchInputEvent(eventName) {
144
- this[`on${eventName}`]?.(); // in case we got an event callback as property
145
- this.dispatchEvent(new InputEvent(eventName));
146
- }
147
-
148
109
  attributeChangedCallback(attrName, oldValue, newValue) {
149
110
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
150
111
 
@@ -155,24 +116,22 @@ export const inputMixin = (superclass) => class InputMixinClass extends supercla
155
116
 
156
117
  handleDispatchValidationEvents() {
157
118
  if (this.checkValidity()) {
158
- this.dispatchValid()
119
+ this.#dispatchValid()
159
120
  } else {
160
- this.dispatchInvalid()
121
+ this.#dispatchInvalid()
161
122
  }
162
123
  }
163
124
 
164
125
  connectedCallback() {
165
126
  super.connectedCallback?.();
166
127
 
128
+ this.addEventListener('input', this.#boundedHandleInput)
129
+
167
130
  this.setValidity();
168
131
  this.handleDispatchValidationEvents();
132
+ }
169
133
 
170
- // create proxy replace the addEventListener fn
171
- // and we want to be able to access the focus events
172
- // of this element and not the nested element's events
173
- this.onfocus = this.handleFocus.bind(this);
174
- this.addEventListener('input', this.handleInput.bind(this))
175
- this.addEventListener('blur', this.handleBlur.bind(this))
176
- this.addEventListener('change', this.handleBlur.bind(this))
134
+ disconnectedCallback() {
135
+ this.removeEventListener('input', this.#boundedHandleInput)
177
136
  }
178
137
  }
@@ -1,13 +1,17 @@
1
1
  import { PORTAL_THEME_PREFIX } from "../constants";
2
- import { upperFirst } from "../helpers";
2
+ import { kebabCaseJoin, upperFirst } from "../helpers";
3
3
  import { forwardAttrs } from "../helpers/componentHelpers";
4
4
  import { createStyleMixin } from "./createStyleMixin";
5
5
  import { createCssVarsList } from "./createStyleMixin/helpers";
6
6
 
7
- const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
7
+ // this is needed because we might generate the same css vars names
8
+ // e.g. "overlayColor" attribute in style mixin's mapping,
9
+ // will generate the same var as "color" attribute in portals's mapping
10
+ // when the portal name is "overlay".
11
+ // because of that, we are adding this separator that is also used as a differentiator
12
+ const DISPLAY_NAME_SEPARATOR = '_'
8
13
 
9
- const appendSuffixToKeys = (obj, suffix) => Object.keys(obj).reduce((acc, key) =>
10
- Object.assign(acc, { [suffix + upperFirst(key)]: obj[key] }), {})
14
+ const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
11
15
 
12
16
  const getDomNode = (maybeDomNode) => maybeDomNode.host || maybeDomNode;
13
17
 
@@ -22,7 +26,7 @@ export const portalMixin = ({ name, selector, mappings = {} }) => (superclass) =
22
26
  static get cssVarList() {
23
27
  return {
24
28
  ...BaseClass.cssVarList,
25
- ...createCssVarsList(superclass.componentName, appendSuffixToKeys(mappings, eleDisplayName))
29
+ [eleDisplayName]: createCssVarsList(kebabCaseJoin(superclass.componentName, DISPLAY_NAME_SEPARATOR + eleDisplayName), mappings)
26
30
  };
27
31
  }
28
32
 
@@ -32,14 +36,14 @@ export const portalMixin = ({ name, selector, mappings = {} }) => (superclass) =
32
36
  // we cannot use "this" before calling "super"
33
37
  const getRootElement = (that) => {
34
38
  const baseEle = that.shadowRoot.querySelector(that.baseSelector)
35
- const portal = baseEle.shadowRoot.querySelector(selector)
39
+ const portal = selector ? baseEle.shadowRoot.querySelector(selector) : baseEle
36
40
 
37
41
  return portal.shadowRoot || portal
38
42
  };
39
43
 
40
44
  super({
41
45
  getRootElement,
42
- componentNameSuffix: eleDisplayName,
46
+ componentNameSuffix: DISPLAY_NAME_SEPARATOR + eleDisplayName,
43
47
  themeSection: PORTAL_THEME_PREFIX + eleDisplayName,
44
48
  baseSelector: ':host'
45
49
  })
@@ -1,4 +1,4 @@
1
- import { inputMixin } from "./inputMixin";
1
+ import { inputValidationMixin } from "./inputValidationMixin";
2
2
 
3
3
  const errorAttrs = ['invalid', 'has-error-message'];
4
4
 
@@ -29,18 +29,28 @@ const getNestedInput = (ele) => {
29
29
  }
30
30
 
31
31
  export const proxyInputMixin = (superclass) =>
32
- class proxyInputMixinClass extends inputMixin(superclass) {
32
+ class proxyInputMixinClass extends inputValidationMixin(superclass) {
33
33
  static get observedAttributes() {
34
34
  return [...superclass.observedAttributes || [], ...errorAttrs];
35
35
  }
36
36
 
37
37
  #inputElement
38
38
 
39
+ #boundHandleFocus
40
+ #boundHandleInvalid
41
+ #boundHandleValid
42
+
39
43
  constructor() {
40
44
  super();
41
45
 
42
46
  this.#inputElement = super.inputElement
43
47
 
48
+ this.#boundHandleFocus = this.#handleFocus.bind(this);
49
+ this.#boundHandleInvalid = this.#handleInvalid.bind(this);
50
+ this.#boundHandleValid = this.#handleValid.bind(this);
51
+
52
+ this.baseEle = this.shadowRoot.querySelector(this.baseSelector);
53
+
44
54
  }
45
55
 
46
56
  get inputElement() {
@@ -48,7 +58,7 @@ export const proxyInputMixin = (superclass) =>
48
58
  const textAreaSlot = this.baseEle.shadowRoot.querySelector('slot[name="textarea"]')
49
59
 
50
60
  this.#inputElement ??= getNestedInput(inputSlot) || getNestedInput(textAreaSlot)
51
-
61
+
52
62
  if (!this.#inputElement) throw Error('no input was found');
53
63
 
54
64
  return this.#inputElement
@@ -64,27 +74,17 @@ export const proxyInputMixin = (superclass) =>
64
74
 
65
75
  reportValidityOnInternalInput() {
66
76
  setTimeout(() => {
77
+ this.baseEle.focus() //TODO: check if this is needed
67
78
  this.inputElement.reportValidity()
68
- }, 0)
69
- }
70
-
71
- handleBlur() { }
72
-
73
- handleFocus() {
74
- this.inputElement.focus();
75
- if (this.hasAttribute('invalid')) {
76
- this.reportValidityOnInternalInput()
77
- }
79
+ })
78
80
  }
79
81
 
80
82
  // we want reportValidity to behave like form submission
81
83
  reportValidity() {
82
- const isValid = super.reportValidity()
83
84
  if (!isValid) {
84
85
  this.setAttribute('invalid', 'true');
85
- this.inputElement.focus()
86
+ this.reportValidityOnInternalInput()
86
87
  }
87
- this.reportValidityOnInternalInput()
88
88
  }
89
89
 
90
90
  setInternalInputErrorMessage() {
@@ -93,48 +93,47 @@ export const proxyInputMixin = (superclass) =>
93
93
  }
94
94
  }
95
95
 
96
- connectedCallback() {
97
- this.baseEle = this.shadowRoot.querySelector(this.baseSelector);
96
+ // when clicking on the form submit button and the input is invalid
97
+ // we want it to appear as invalid
98
+ #handleFocus(e) {
99
+ if (e.relatedTarget?.form) {
100
+ if (!this.checkValidity()) {
101
+ this.setAttribute('invalid', 'true');
102
+ }
98
103
 
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
- }
104
+ if (this.hasAttribute('invalid')) {
105
+ this.reportValidityOnInternalInput()
110
106
  }
111
- })
107
+ }
108
+ }
112
109
 
113
- this.addEventListener('invalid', () => {
114
- this.setInternalInputErrorMessage()
115
- this.setAttribute('error-message', this.validationMessage)
116
- })
110
+ #handleInvalid() {
111
+ this.setInternalInputErrorMessage()
112
+ this.setAttribute('error-message', this.validationMessage)
113
+ }
117
114
 
118
- this.addEventListener('valid', () => {
119
- this.removeAttribute('invalid')
120
- })
115
+ #handleValid() {
116
+ this.removeAttribute('invalid')
117
+ }
121
118
 
119
+ connectedCallback() {
122
120
  super.connectedCallback?.();
123
121
 
124
- this.inputElement.addEventListener('input', () => {
122
+ // this is our way to identify that the form was submitted
123
+ // in this case, we want the input to be in error state if it's not valid
124
+ this.addEventListener('focus', this.#boundHandleFocus)
125
+
126
+ this.addEventListener('invalid', this.#boundHandleInvalid)
127
+ this.addEventListener('valid', this.#boundHandleValid)
128
+
129
+ this.addEventListener('input', () => {
125
130
  this.inputElement.setCustomValidity('')
126
131
  if (!this.inputElement.checkValidity())
127
132
  this.setInternalInputErrorMessage()
128
133
  })
129
134
 
130
- this.inputElement.addEventListener('invalid', () => {
131
- this.setValidity()
132
- this.setInternalInputErrorMessage()
133
- this.setAttribute('error-message', this.validationMessage)
134
- })
135
-
136
135
  // this is needed in order to make sure the form input validation is working
137
- if (!this.hasAttribute('tabindex')) {
136
+ if (!this.hasAttribute('tabindex') && this.getRootNode() === document) {
138
137
  this.setAttribute('tabindex', 0);
139
138
  }
140
139
 
@@ -143,6 +142,12 @@ export const proxyInputMixin = (superclass) =>
143
142
  this.setSelectionRange = this.inputElement.setSelectionRange?.bind(this.inputElement);
144
143
  }
145
144
 
145
+ disconnectedCallback() {
146
+ this.removeEventListener('focus', this.#boundHandleFocus)
147
+ this.removeEventListener('invalid', this.#boundHandleInvalid)
148
+ this.removeEventListener('valid', this.#boundHandleValid)
149
+ }
150
+
146
151
  attributeChangedCallback(attrName, oldValue, newValue) {
147
152
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
148
153
 
@@ -18,15 +18,8 @@ export const comboBox = {
18
18
  [vars.borderWidth]: '0',
19
19
  [vars.cursor]: 'pointer',
20
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
- }
21
+ // [vars.overlayBackground]: 'blue',
22
+ // [vars.overlayBorder]: '3px solid red',
30
23
  };
31
24
 
32
25
  export default comboBox;
package/dist/umd/860.js DELETED
@@ -1 +0,0 @@
1
- "use strict";(self.webpackChunkDescopeUI=self.webpackChunkDescopeUI||[]).push([[860],{9989:(t,e,s)=>{s.d(e,{V:()=>i});class i extends HTMLElement{}},5279:(t,e,s)=>{s.d(e,{gh:()=>i,k4:()=>n,qM:()=>a,qg:()=>r});const i="descope",n=3,r="host",a="@"},4567:(t,e,s)=>{s.d(e,{Db:()=>u,FX:()=>r,P$:()=>a,Tk:()=>c,iY:()=>h,oP:()=>d,tg:()=>l});var i=s(2061),n=s(5279);const r=(t,e,{excludeAttrs:s=[],includeAttrs:i=[]})=>{const n=Array.from(t.attributes).filter((t=>!s.includes(t.name)&&(!i.length||i.includes(t.name)))).map((t=>t.name));e(n),new MutationObserver((t=>{for(const n of t)"attributes"!==n.type||s.includes(n.attributeName)||i.length&&!i.includes(n.attributeName)||e([n.attributeName])})).observe(t,{attributes:!0})},a=(t,e)=>{e({addedNodes:Array.from(t.children),removedNodes:[]}),new MutationObserver((t=>{for(const s of t)"childList"===s.type&&e(s)})).observe(t,{childList:!0})},o=(t,e,s={})=>i=>{i.forEach((i=>{const n=s[i]||i,r=t.getAttribute(i);null!==r?e.getAttribute(n)!==r&&e.setAttribute(n,r):e.removeAttribute(n)}))},l=(t,e,s)=>{r(t,o(t,e),s),r(e,o(e,t),s)},h=t=>(0,i.E3)(n.gh,t),c=(...t)=>`--${(0,i.E3)(...t)}`,d=(t,e,s={})=>{r(t,o(t,e,s.mapAttrs),s)},u=(t,e,s=[])=>{if(!s.length)return;const i=s.reduce(((t,s)=>Object.assign(t,{[s]:{get:()=>e[s],set(t){e[s]=t}}})),{});Object.defineProperties(t,i)}},2061:(t,e,s)=>{s.d(e,{E3:()=>n,GL:()=>i,jC:()=>a,qC:()=>r});const i=t=>t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[\s_.]+/g,"-").toLowerCase(),n=(...t)=>i(t.filter((t=>!!t)).join("-")),r=(...t)=>e=>t.reduceRight(((t,e)=>e(t)),e),a=t=>t.charAt(0).toUpperCase()+t.slice(1)},6860:(t,e,s)=>{s.d(e,{Ae:()=>C,DM:()=>p,yk:()=>c,e4:()=>d,_A:()=>m,y7:()=>g,Iw:()=>A,dj:()=>f});var i=s(5279),n=s(2061),r=s(4567),a=s(5561);const o=(t,...e)=>`var(${t}${e.length?` , ${o(...e)}`:""})`;class l{constructor(){this.styleMap=new Map}add(t,e,s){this.styleMap.has(t)||this.styleMap.set(t,[]),this.styleMap.set(t,[...this.styleMap.get(t),{property:e,value:s}])}toString(){return Array.from(this.styleMap.entries()).reduce(((t,[e,s])=>t+`${e} { \n${s.map((({property:t,value:e})=>`${t}: ${e}`)).join(";\n")} \n}\n\n`),"")}}const h=(t,e)=>Object.keys(e).reduce(((e,s)=>Object.assign(e,{[s]:(0,r.Tk)(t,s)})),{}),c=({mappings:t={}})=>e=>class extends e{static get cssVarList(){return{...e.cssVarList,...h(e.componentName,{...t})}}#t;#e;#s;#i;#n;#r;#a;#o;constructor({getRootElement:e,componentNameSuffix:s="",themeSection:r=i.qg,baseSelector:a}={}){super(),this.#i=s,this.#n=r,this.#r=e?.(this)||this.shadowRoot,this.#a=a??this.baseSelector,this.#o=Object.keys(t).map((t=>(0,n.E3)("st",s,t)))}get componentTheme(){return a.componentsThemeManager.currentTheme?.[e.componentName]||""}#l(){this.#e.innerHTML=this.componentTheme[this.#n]}#h(){this.#e=document.createElement("style"),this.#e.id="style-mixin-theme",this.#r.prepend(this.#e),this.#s=a.componentsThemeManager.onCurrentThemeChange(this.#l.bind(this)),this.#l()}#c(){this.#t=document.createElement("style"),this.#t.id="style-mixin-overrides";const t=(s=e.componentName,n=i.k4,Array(n).fill(`.${s}`).join(""));var s,n;this.#t.innerText=`:host(${t}) {}`,this.#r.append(this.#t)}#d(t,s){const i=this.#t?.sheet?.cssRules[0].style;if(!i)return;const n=(0,r.Tk)(e.componentName,t.replace(new RegExp("^st-"),""));s?i?.setProperty(n,s):i?.removeProperty(n)}#u(t=[]){for(const e of t)this.#o.includes(e)&&this.#d(e,this.getAttribute(e));this.#t.innerHTML=this.#t?.sheet?.cssRules[0].cssText}#m(){const s=document.createElement("style");s.id="style-mixin-mappings",s.innerHTML=((t,e,s)=>{const i=new l;return Object.keys(s).forEach((a=>{const l=((t,e)=>{const s={selector:"",property:(0,n.GL)(t)};return e&&Object.keys(e).length?Array.isArray(e)?e.map((t=>Object.assign({},s,t))):[Object.assign({},s,e)]:[s]})(a,s[a]),h=(0,r.Tk)(t,a);l.forEach((({selector:t,property:s})=>{i.add(((t="",e="")=>"function"==typeof e?e(t):`${t}${/^[A-Za-z]/.test(e)?` ${e}`:e}`)(e,t),s,o(h))}))})),i.toString()})((0,n.E3)(e.componentName,this.#i),this.#a,t),this.#r.prepend(s)}#p(t){(this.#r.classList||this.#r.host.classList).add(t)}connectedCallback(){super.connectedCallback?.(),this.shadowRoot.isConnected&&(this.#p(e.componentName),this.#m(),this.#h(),this.#c(),(0,r.FX)(this,this.#u.bind(this),{}))}disconnectedCallback(){this.#s?.()}},d=t=>class extends t{#b=null;static get observedAttributes(){return[...t.observedAttributes||[],"draggable"]}constructor(){super(),this.#b=document.createElement("style"),this.#b.innerText=`${this.baseSelector} { cursor: inherit }`}#y(t){t?this.shadowRoot.appendChild(this.#b):this.#b.remove()}attributeChangedCallback(t,e,s){super.attributeChangedCallback?.(t,e,s),"draggable"===t&&this.#y("true"===s)}};var u=s(9989);const m=(t="")=>e=>class extends e{connectedCallback(){super.connectedCallback?.(),this.shadowRoot.querySelector(this.baseSelector+t).addEventListener("mouseover",(t=>{this.shadowRoot.host.setAttribute("hover","true"),t.target.addEventListener("mouseleave",(()=>this.shadowRoot.host.removeAttribute("hover")),{once:!0})}))}},p=({componentName:t,wrappedEleName:e,slots:s=[],style:i,excludeAttrsSync:a=[],includeAttrsSync:o=[],includeForwardProps:l=[]})=>{const h=`\n\t\t<style id="create-proxy"></style>\n\t\t<${e}>\n\t\t<slot></slot>\n\t\t${s.map((t=>`<slot name="${t}" slot="${t}"></slot>`)).join("")}\n\t\t</${e}>\n\t`;class c extends u.V{static get componentName(){return t}constructor(){super().attachShadow({mode:"open"}).innerHTML=h,this.hostElement=this.shadowRoot.host,this.baseSelector=e,this.shadowRoot.getElementById("create-proxy").innerHTML="function"==typeof i?i():i}connectedCallback(){this.shadowRoot.isConnected&&(this.proxyElement=this.shadowRoot.querySelector(e),(0,r.Db)(this.hostElement,this.proxyElement,l),this.setAttribute("tabindex","0"),this.addEventListener("focus",(()=>{this.proxyElement.focus()})),this.proxyElement.onkeydown=t=>{t.shiftKey&&9===t.keyCode&&(this.removeAttribute("tabindex"),setTimeout((()=>this.setAttribute("tabindex","0")),0))},this.addEventListener=(...t)=>this.proxyElement.addEventListener(...t),(0,r.tg)(this.proxyElement,this.hostElement,{excludeAttrs:a,includeAttrs:o}))}disconnectedCallback(){this.proxyElement.removeEventListener("mouseover",this.mouseoverCbRef)}attributeChangedCallback(){this.proxyElement}}return(0,n.qC)(m())(c)},b=["change","input","blur","focus","invalid","valid"],y=["required","pattern"],g=t=>class extends t{static get observedAttributes(){return[...t.observedAttributes||[],...y]}static get formAssociated(){return!0}#g;constructor(){super(),this.#g=this.attachInternals();for(const t of b)this[`dispatch${(0,n.jC)(t)}`]=function(){this.dispatchInputEvent(t)}}get defaultErrorMsgValueMissing(){return"Please fill out this field."}get defaultErrorMsgPatternMismatch(){return"Please match the requested format."}getErrorMessage(t){switch(!0){case t.valueMissing:return this.getAttribute("data-errormessage-value-missing")||this.defaultErrorMsgValueMissing;case t.patternMismatch||t.typeMismatch:return this.getAttribute("data-errormessage-pattern-mismatch")||this.defaultErrorMsgPatternMismatch;case t.customError:return this.validationMessage;default:return""}}get isReadOnly(){return this.hasAttribute("readonly")&&"false"!==this.getAttribute("readonly")}setValidity(){if(this.isReadOnly)return;const t=this.getValidity();this.#g.setValidity(t,this.getErrorMessage(t))}get validationMessage(){return this.#g.validationMessage}getValidity(){throw Error("getValidity","is not implemented")}checkValidity(){return this.#g.validity.valid}reportValidity(){return this.#g.reportValidity()}get validity(){return this.#g.validity}setCustomValidity(t){t?this.#g.setValidity({customError:!0},t):(this.#g.setValidity({}),this.setValidity())}get isRequired(){return this.hasAttribute("required")&&"false"!==this.getAttribute("required")}get pattern(){return this.getAttribute("pattern")}get value(){throw Error("get value","is not implemented")}set value(t){throw Error("set value","is not implemented")}handleFocus(){throw Error("handleFocus","is not implemented")}handleInput(){this.setValidity(),this.handleDispatchValidationEvents()}handleBlur(){throw Error("handleBlur","is not implemented")}handleChange(){throw Error("handleChange","is not implemented")}dispatchInputEvent(t){this[`on${t}`]?.(),this.dispatchEvent(new InputEvent(t))}attributeChangedCallback(t,e,s){super.attributeChangedCallback?.(t,e,s),y.includes(t)&&this.setValidity()}handleDispatchValidationEvents(){this.checkValidity()?this.dispatchValid():this.dispatchInvalid()}connectedCallback(){super.connectedCallback?.(),this.setValidity(),this.handleDispatchValidationEvents(),this.onfocus=this.handleFocus.bind(this),this.addEventListener("input",this.handleInput.bind(this)),this.addEventListener("blur",this.handleBlur.bind(this)),this.addEventListener("change",this.handleBlur.bind(this))}},E=["invalid","has-error-message"],v=t=>{if(!t)return;let e=t;for(let t=0;t<10;t++)if(e=e.assignedElements()[0],"slot"!==e.localName)return e},f=t=>class extends(g(t)){static get observedAttributes(){return[...t.observedAttributes||[],...E]}#E;constructor(){super(),this.#E=super.inputElement}get inputElement(){const t=this.baseEle.shadowRoot.querySelector('slot[name="input"]'),e=this.baseEle.shadowRoot.querySelector('slot[name="textarea"]');if(this.#E??=v(t)||v(e),!this.#E)throw Error("no input was found");return this.#E}set inputElement(t){this.#E=t}getValidity(){return this.inputElement.validity}reportValidityOnInternalInput(){setTimeout((()=>{this.inputElement.reportValidity()}),0)}handleBlur(){}handleFocus(){this.inputElement.focus(),this.hasAttribute("invalid")&&this.reportValidityOnInternalInput()}reportValidity(){super.reportValidity()||(this.setAttribute("invalid","true"),this.inputElement.focus()),this.reportValidityOnInternalInput()}setInternalInputErrorMessage(){this.checkValidity()||this.inputElement.setCustomValidity(this.validationMessage)}connectedCallback(){var t,e;this.baseEle=this.shadowRoot.querySelector(this.baseSelector),this.addEventListener("focus",(t=>{t.relatedTarget?.form&&(this.checkValidity()||this.setAttribute("invalid","true"),this.hasAttribute("invalid")&&this.reportValidityOnInternalInput())})),this.addEventListener("invalid",(()=>{this.setInternalInputErrorMessage(),this.setAttribute("error-message",this.validationMessage)})),this.addEventListener("valid",(()=>{this.removeAttribute("invalid")})),super.connectedCallback?.(),this.inputElement.addEventListener("input",(()=>{this.inputElement.setCustomValidity(""),this.inputElement.checkValidity()||this.setInternalInputErrorMessage()})),this.inputElement.addEventListener("invalid",(()=>{this.setValidity(),this.setInternalInputErrorMessage(),this.setAttribute("error-message",this.validationMessage)})),this.hasAttribute("tabindex")||this.setAttribute("tabindex",0),t=this.inputElement,e="value",Object.defineProperty(this,e,{set:function(s){return t[e]=s},get:function(){return t[e]},configurable:!0}),this.setSelectionRange=this.inputElement.setSelectionRange?.bind(this.inputElement)}attributeChangedCallback(t,e,s){super.attributeChangedCallback?.(t,e,s),"invalid"===t&&""===s&&this.setAttribute("invalid","true")}},C=t=>class extends t{#v(){const e=this.shadowRoot.host.tagName.toLowerCase();if(!t.componentName)throw Error('component name is not defined on super class, make sure you have a static get for "componentName"');if(e!==t.componentName)throw Error(`component name mismatch, expected "${t.componentName}", current "${e}"`)}connectedCallback(){super.connectedCallback?.(),this.shadowRoot.isConnected&&this.#v()}},A=({name:t,selector:e,mappings:s={}})=>a=>{const o=t||(t=>t.replace(/[^\w\s]/gi,""))(e),l=c({mappings:s})(a);return class extends l{static get cssVarList(){return{...l.cssVarList,...h(a.componentName,(t=s,e=o,Object.keys(t).reduce(((s,i)=>Object.assign(s,{[e+(0,n.jC)(i)]:t[i]})),{})))};var t,e}#f;constructor(){const t=t=>{const s=t.shadowRoot.querySelector(t.baseSelector).shadowRoot.querySelector(e);return s.shadowRoot||s};var s;super({getRootElement:t,componentNameSuffix:o,themeSection:i.qM+o,baseSelector:":host"}),this.#f=(s=t(this)).host||s}#C(){this.#f.onmouseenter=t=>{t.target.setAttribute("hover","true")},this.#f.onmouseleave=t=>{t.target.removeAttribute("hover")}}connectedCallback(){super.connectedCallback?.(),(0,r.oP)(this,this.#f,{excludeAttrs:["hover"]}),this.#C()}}}}}]);
@@ -1 +0,0 @@
1
- export class DescopeBaseClass extends HTMLElement {}