@descope-ui/common 0.0.1

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 (39) hide show
  1. package/.eslintrc.json +18 -0
  2. package/README.md +7 -0
  3. package/package.json +36 -0
  4. package/project.json +7 -0
  5. package/src/baseClasses/baseClasses/createBaseClass.js +66 -0
  6. package/src/baseClasses/baseClasses/createBaseInputClass.js +14 -0
  7. package/src/baseClasses/baseClasses/createCssVarImageClass.js +55 -0
  8. package/src/baseClasses/index.js +3 -0
  9. package/src/componentsHelpers/index.js +95 -0
  10. package/src/componentsMixins/helpers/mixinsHelpers.js +10 -0
  11. package/src/componentsMixins/index.js +1 -0
  12. package/src/componentsMixins/mixins/activableMixin.js +14 -0
  13. package/src/componentsMixins/mixins/changeMixin.js +22 -0
  14. package/src/componentsMixins/mixins/componentNameValidationMixin.js +23 -0
  15. package/src/componentsMixins/mixins/componentsContextMixin.js +12 -0
  16. package/src/componentsMixins/mixins/createDynamicDataMixin.js +100 -0
  17. package/src/componentsMixins/mixins/createProxy.js +58 -0
  18. package/src/componentsMixins/mixins/createStyleMixin/helpers.js +106 -0
  19. package/src/componentsMixins/mixins/createStyleMixin/index.js +167 -0
  20. package/src/componentsMixins/mixins/draggableMixin.js +62 -0
  21. package/src/componentsMixins/mixins/externalInputHelpers.js +93 -0
  22. package/src/componentsMixins/mixins/externalInputMixin.js +170 -0
  23. package/src/componentsMixins/mixins/hoverableMixin.js +13 -0
  24. package/src/componentsMixins/mixins/index.js +14 -0
  25. package/src/componentsMixins/mixins/inputEventsDispatchingMixin.js +76 -0
  26. package/src/componentsMixins/mixins/inputValidationMixin.js +210 -0
  27. package/src/componentsMixins/mixins/lifecycleEventsMixin.js +23 -0
  28. package/src/componentsMixins/mixins/normalizeBooleanAttributesMixin.js +59 -0
  29. package/src/componentsMixins/mixins/portalMixin.js +112 -0
  30. package/src/componentsMixins/mixins/proxyInputMixin.js +242 -0
  31. package/src/constants.js +4 -0
  32. package/src/icons/errorMessageIconBase64.js +1 -0
  33. package/src/sbControls.js +302 -0
  34. package/src/sbHelpers.js +53 -0
  35. package/src/themeHelpers/colorsHelpers.js +94 -0
  36. package/src/themeHelpers/componentsThemeManager.js +45 -0
  37. package/src/themeHelpers/index.js +191 -0
  38. package/src/themeHelpers/resetHelpers.js +144 -0
  39. package/src/utils/index.js +68 -0
@@ -0,0 +1,210 @@
1
+ import 'element-internals-polyfill'; // this is needed in order to support older browsers
2
+
3
+ const observedAttributes = ['required', 'pattern'];
4
+
5
+ const errorAttributes = {
6
+ valueMissing: 'data-errormessage-value-missing',
7
+ patternMismatch: 'data-errormessage-pattern-mismatch',
8
+ tooShort: 'data-errormessage-pattern-mismatch-too-short',
9
+ tooLong: 'data-errormessage-pattern-mismatch-too-long',
10
+ rangeUnderflow: 'data-errormessage-pattern-range-underflow',
11
+ rangeOverflow: 'data-errormessage-pattern-range-overflow',
12
+ typeMismatch: 'data-errormessage-type-mismatch',
13
+ };
14
+
15
+ const validationTargetSymbol = Symbol('validationTarget');
16
+
17
+ export const inputValidationMixin = (superclass) =>
18
+ class InputValidationMixinClass extends superclass {
19
+ #validationTarget = validationTargetSymbol;
20
+
21
+ static get observedAttributes() {
22
+ return [...(superclass.observedAttributes || []), ...observedAttributes];
23
+ }
24
+
25
+ static get formAssociated() {
26
+ return true;
27
+ }
28
+
29
+ #internals;
30
+
31
+ get internals() {
32
+ return this.#internals;
33
+ }
34
+
35
+ set internals(value) {
36
+ this.#internals = value;
37
+ }
38
+
39
+ constructor() {
40
+ super();
41
+
42
+ this.#internals = this.attachInternals();
43
+ }
44
+
45
+ // eslint-disable-next-line class-methods-use-this
46
+ get defaultErrorMsgValueMissing() {
47
+ return 'Please fill out this field.';
48
+ }
49
+
50
+ // eslint-disable-next-line class-methods-use-this
51
+ get defaultErrorMsgPatternMismatch() {
52
+ return 'Please match the requested format.';
53
+ }
54
+
55
+ get defaultErrorMsgTooShort() {
56
+ return `Minimum length is ${this.getAttribute('minlength')}.`;
57
+ }
58
+
59
+ get defaultErrorMsgTooLong() {
60
+ return `Maximum length is ${this.getAttribute('maxlength')}. `;
61
+ }
62
+
63
+ get defaultErrorMsgRangeUnderflow() {
64
+ return `At least ${this.getAttribute('min-items-selection')} items are required.`;
65
+ }
66
+
67
+ get defaultErrorMsgRangeOverflow() {
68
+ return `At most ${this.getAttribute('max-items-selection')} items are allowed.`;
69
+ }
70
+
71
+ // eslint-disable-next-line class-methods-use-this
72
+ get defaultErrorMsgTypeMismatch() {
73
+ return `Please match the requested type.`;
74
+ }
75
+
76
+ getErrorMessage(flags) {
77
+ const {
78
+ valueMissing,
79
+ patternMismatch,
80
+ typeMismatch,
81
+ stepMismatch,
82
+ tooShort,
83
+ tooLong,
84
+ rangeOverflow,
85
+ rangeUnderflow,
86
+ badInput,
87
+ customError,
88
+ } = flags;
89
+
90
+ switch (true) {
91
+ case valueMissing:
92
+ return (
93
+ this.getAttribute(errorAttributes.valueMissing) || this.defaultErrorMsgValueMissing
94
+ );
95
+ case patternMismatch || stepMismatch || badInput:
96
+ return (
97
+ this.getAttribute(errorAttributes.patternMismatch) ||
98
+ this.defaultErrorMsgPatternMismatch
99
+ );
100
+ case typeMismatch:
101
+ return (
102
+ this.getAttribute(errorAttributes.typeMismatch) ||
103
+ this.getAttribute(errorAttributes.patternMismatch) ||
104
+ this.defaultErrorMsgTypeMismatch
105
+ );
106
+ case tooShort:
107
+ return this.getAttribute(errorAttributes.tooShort) || this.defaultErrorMsgTooShort;
108
+ case tooLong:
109
+ return this.getAttribute(errorAttributes.tooLong) || this.defaultErrorMsgTooLong;
110
+ case rangeUnderflow:
111
+ return (
112
+ this.getAttribute(errorAttributes.rangeUnderflow) || this.defaultErrorMsgRangeUnderflow
113
+ );
114
+ case rangeOverflow:
115
+ return (
116
+ this.getAttribute(errorAttributes.rangeOverflow) || this.defaultErrorMsgRangeOverflow
117
+ );
118
+ case customError:
119
+ return this.validationMessage;
120
+ default:
121
+ return '';
122
+ }
123
+ }
124
+
125
+ #setValidity() {
126
+ const validity = this.isReadOnly ? {} : this.getValidity();
127
+ this.#internals.setValidity(validity, this.getErrorMessage(validity), this.validationTarget);
128
+ }
129
+
130
+ get validationMessage() {
131
+ return this.#internals.validationMessage;
132
+ }
133
+
134
+ // eslint-disable-next-line class-methods-use-this
135
+ getValidity() {
136
+ // eslint-disable-next-line no-console
137
+ console.warn('getValidity', 'is not implemented');
138
+ }
139
+
140
+ checkValidity() {
141
+ return this.#internals.validity.valid;
142
+ }
143
+
144
+ reportValidity() {
145
+ return this.#internals.reportValidity();
146
+ }
147
+
148
+ get validity() {
149
+ return this.#internals.validity;
150
+ }
151
+
152
+ get validationTarget() {
153
+ return this.#validationTarget === validationTargetSymbol
154
+ ? this.inputElement
155
+ : this.#validationTarget;
156
+ }
157
+
158
+ set validationTarget(val) {
159
+ this.#validationTarget = val;
160
+ }
161
+
162
+ setCustomValidity(errorMessage) {
163
+ if (errorMessage) {
164
+ this.#internals.setValidity({ customError: true }, errorMessage, this.validationTarget);
165
+ } else {
166
+ this.#internals.setValidity({});
167
+ this.#setValidity();
168
+ }
169
+ }
170
+
171
+ get isRequired() {
172
+ return this.hasAttribute('required') && this.getAttribute('required') !== 'false';
173
+ }
174
+
175
+ get isReadOnly() {
176
+ return this.hasAttribute('readonly') && this.getAttribute('readonly') !== 'false';
177
+ }
178
+
179
+ get isDisabled() {
180
+ return this.hasAttribute('disabled') && this.getAttribute('disabled') !== 'false';
181
+ }
182
+
183
+ get pattern() {
184
+ return this.getAttribute('pattern');
185
+ }
186
+
187
+ get form() {
188
+ return this.#internals.form;
189
+ }
190
+
191
+ attributeChangedCallback(attrName, oldValue, newValue) {
192
+ super.attributeChangedCallback?.(attrName, oldValue, newValue);
193
+
194
+ if (observedAttributes.includes(attrName)) {
195
+ this.#setValidity();
196
+ }
197
+ }
198
+
199
+ init() {
200
+ super.init?.();
201
+ this.addEventListener('change', this.#setValidity);
202
+ this.addEventListener('invalid', (e) => e.stopPropagation());
203
+ this.addEventListener('input', this.#setValidity);
204
+
205
+ // The attribute sync takes time, so getValidity returns valid,
206
+ // even when it shouldn't. This way allows all attributes to sync
207
+ // after render, before checking the validity.
208
+ setTimeout(() => this.#setValidity());
209
+ }
210
+ };
@@ -0,0 +1,23 @@
1
+ import { createDispatchEvent } from '../helpers/mixinsHelpers';
2
+
3
+ export const lifecycleEventsMixin = (superclass) =>
4
+ class LifecycleEventsMixinClass extends superclass {
5
+ #dispatchConnected = createDispatchEvent.bind(this, 'connected');
6
+
7
+ #dispatchDisconnected = createDispatchEvent.bind(this, 'disconnected');
8
+
9
+ connectedCallback() {
10
+ if (this.rootElement.isConnected) {
11
+ super.connectedCallback?.();
12
+
13
+ // we are waiting for all components to listen before dispatching
14
+ setTimeout(this.#dispatchConnected);
15
+ }
16
+ }
17
+
18
+ disconnectedCallback() {
19
+ super.disconnectedCallback?.();
20
+
21
+ this.#dispatchDisconnected();
22
+ }
23
+ };
@@ -0,0 +1,59 @@
1
+ import { observeAttributes } from '../../componentsHelpers';
2
+
3
+ const booleanAttributesList = [
4
+ 'readonly',
5
+ 'focused',
6
+ 'invalid',
7
+ 'has-label',
8
+ 'required',
9
+ 'disabled',
10
+ 'checked',
11
+ 'has-helper',
12
+ 'has-value',
13
+ 'step-buttons-visible',
14
+ 'hover',
15
+ 'has-error-message',
16
+ 'focus-ring',
17
+ 'opened',
18
+ 'active',
19
+ 'password-visible',
20
+ 'opening',
21
+ 'closing',
22
+ 'has-no-options',
23
+ 'loading',
24
+ 'allow-custom-value',
25
+ ];
26
+
27
+ const isBooleanAttribute = (attr) => {
28
+ return booleanAttributesList.includes(attr);
29
+ };
30
+ // we want all the valueless attributes to have "true" value
31
+ // and all the falsy attribute to be removed
32
+ export const normalizeBooleanAttributesMixin = (superclass) =>
33
+ class NormalizeBooleanAttributesMixinClass extends superclass {
34
+ init() {
35
+ super.init?.();
36
+
37
+ observeAttributes(
38
+ this,
39
+ (attrs) =>
40
+ attrs.forEach((attr) => {
41
+ const attrVal = this.getAttribute(attr);
42
+
43
+ if (isBooleanAttribute(attr)) {
44
+ if (attrVal === '') {
45
+ this.setAttribute(attr, 'true');
46
+ } else if (attrVal === 'false') {
47
+ this.removeAttribute(attr);
48
+ }
49
+ } else if (!attrVal) {
50
+ // eslint-disable-next-line no-console
51
+ console.debug(
52
+ `attribute "${attr}" has no value, should it be added to the boolean attributes list?`
53
+ );
54
+ }
55
+ }),
56
+ {}
57
+ );
58
+ }
59
+ };
@@ -0,0 +1,112 @@
1
+ import { kebabCaseJoin } from '../../utils';
2
+ import { forwardAttrs } from '../../componentsHelpers';
3
+ import { createStyleMixin } from '../mixins/createStyleMixin';
4
+ import { createCssVarsList } from './createStyleMixin/helpers';
5
+
6
+ // this is needed because we might generate the same css vars names
7
+ // e.g. "overlayColor" attribute in style mixin's mapping,
8
+ // will generate the same var as "color" attribute in portals's mapping
9
+ // when the portal name is "overlay".
10
+ // because of that, we are adding this separator that is also used as a differentiator
11
+ const DISPLAY_NAME_SEPARATOR = '_';
12
+ const PORTAL_THEME_PREFIX = '@';
13
+
14
+
15
+ const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
16
+
17
+ const withWaitForShadowRoot = (getRootElementFn) => async (that) => {
18
+ const ele = await getRootElementFn(that);
19
+
20
+ return new Promise((res) => {
21
+ const MAX_RETRIES = 20;
22
+ let counter = 0;
23
+
24
+ const check = () => {
25
+ if (counter > MAX_RETRIES) {
26
+ // eslint-disable-next-line no-console
27
+ console.error('could not get shadow root for element', ele);
28
+ res(ele);
29
+ return;
30
+ }
31
+
32
+ counter++;
33
+
34
+ if (!ele?.shadowRoot) {
35
+ setTimeout(check);
36
+ } else {
37
+ res(ele.shadowRoot);
38
+ }
39
+ };
40
+ check();
41
+ });
42
+ };
43
+
44
+ export const portalMixin =
45
+ ({ name, selector, mappings = {}, forward: { attributes = [], include = true } = {} }) =>
46
+ (superclass) => {
47
+ const eleDisplayName = name || sanitizeSelector(selector);
48
+
49
+ const BaseClass = createStyleMixin({
50
+ mappings,
51
+ })(superclass);
52
+
53
+ return class PortalMixinClass extends BaseClass {
54
+ static get cssVarList() {
55
+ return {
56
+ ...BaseClass.cssVarList,
57
+ [eleDisplayName]: createCssVarsList(
58
+ kebabCaseJoin(superclass.componentName, DISPLAY_NAME_SEPARATOR + eleDisplayName),
59
+ mappings
60
+ ),
61
+ };
62
+ }
63
+
64
+ #portalEle;
65
+
66
+ constructor() {
67
+ // we cannot use "this" before calling "super"
68
+ const getRootElement = async (that) => {
69
+ const baseEle = (that.shadowRoot || that).querySelector(that.baseSelector);
70
+ if (!selector) {
71
+ return baseEle;
72
+ }
73
+
74
+ // in case we have a selector, we should first wait for the base element shadow root
75
+ // and then look for the internal element
76
+ const baseEleShadowRoot = await withWaitForShadowRoot(() => baseEle)(that);
77
+ return baseEleShadowRoot.querySelector(selector);
78
+ };
79
+
80
+ const getPortalElement = withWaitForShadowRoot(getRootElement);
81
+
82
+ super({
83
+ getRootElement: getPortalElement,
84
+ componentNameSuffix: DISPLAY_NAME_SEPARATOR + eleDisplayName,
85
+ themeSection: PORTAL_THEME_PREFIX + eleDisplayName,
86
+ baseSelector: ':host',
87
+ });
88
+
89
+ this.#portalEle = getPortalElement(this).then((ele) => ele.host);
90
+ }
91
+
92
+ async #handleHoverAttribute() {
93
+ const portalEle = await this.#portalEle;
94
+ portalEle.onmouseenter = (e) => {
95
+ e.target.setAttribute('hover', 'true');
96
+ };
97
+ portalEle.onmouseleave = (e) => {
98
+ e.target.removeAttribute('hover');
99
+ };
100
+ }
101
+
102
+ async init() {
103
+ super.init?.();
104
+ const portalEle = await this.#portalEle;
105
+ forwardAttrs(this, portalEle, {
106
+ [include ? 'includeAttrs' : 'excludeAttrs']: attributes,
107
+ });
108
+
109
+ this.#handleHoverAttribute();
110
+ }
111
+ };
112
+ };
@@ -0,0 +1,242 @@
1
+ /* eslint-disable no-param-reassign */
2
+ import { compose } from '../../utils';
3
+ import { forwardAttrs, getComponentName } from '../../componentsHelpers';
4
+ import { createDispatchEvent } from '../helpers/mixinsHelpers';
5
+ import { inputValidationMixin } from '../mixins/inputValidationMixin';
6
+ import { createStyleMixin } from '../mixins/createStyleMixin';
7
+
8
+ const errorAttrs = ['invalid', 'required'];
9
+
10
+ const forwardProps = (src, targets, property) => {
11
+ const targetArr = Array.isArray(targets) ? targets : [targets];
12
+
13
+ Object.defineProperty(src, property, {
14
+ set(v) {
15
+ targetArr.forEach((target) => {
16
+ target[property] = v;
17
+ });
18
+ },
19
+ get() {
20
+ return targets[0][property];
21
+ },
22
+ configurable: true,
23
+ });
24
+ };
25
+
26
+ // recursively take the first slot child until it finds an element which is not a slot
27
+ // stops after "nestingLevel" times
28
+ const getNestedInput = (ele) => {
29
+ if (!ele) return undefined;
30
+
31
+ const nestingLevel = 10;
32
+
33
+ let nonSlotEle = ele;
34
+ for (let i = 0; i < nestingLevel; i++) {
35
+ [nonSlotEle] = nonSlotEle.assignedElements();
36
+ if (nonSlotEle?.localName !== 'slot') return nonSlotEle;
37
+ }
38
+ return undefined;
39
+ };
40
+
41
+ const proxyInputMixin =
42
+ ({
43
+ proxyProps = [],
44
+ // useProxyTargets flag allows to forwardProps to other targets, other than
45
+ // `this.inputElement`. It's to be used within `external-input` components,
46
+ // if needed
47
+ useProxyTargets = false,
48
+ // allows us to set the event that should trigger validation
49
+ // it can be either a string or an array of strings (for multiple events)
50
+ inputEvent = 'input',
51
+ triggerValidationEvents = [],
52
+ // Proxies all validations from the parent component to the input element
53
+ proxyParentValidation = false,
54
+ }) =>
55
+ (superclass) =>
56
+ class ProxyInputMixinClass extends inputValidationMixin(superclass) {
57
+ static get observedAttributes() {
58
+ return [...(superclass.observedAttributes || []), ...errorAttrs];
59
+ }
60
+
61
+ #inputElement;
62
+
63
+ #dispatchChange = createDispatchEvent.bind(this, 'change');
64
+
65
+ constructor() {
66
+ super();
67
+
68
+ this.#inputElement = super.inputElement;
69
+ }
70
+
71
+ // the web-component does not loaded immediately, so we want to defer the warning
72
+ // and show it only if the input element was not found after the component is loaded
73
+ warnIfInputElementIsMissing() {
74
+ clearTimeout(this.inputElementTimerId);
75
+
76
+ this.inputElementTimerId = setTimeout(() => {
77
+ // eslint-disable-next-line no-console
78
+ !this.#inputElement && console.warn(this.localName, 'no input was found');
79
+ }, 0);
80
+ }
81
+
82
+ get inputElement() {
83
+ if (this.#inputElement) return this.#inputElement;
84
+
85
+ this.warnIfInputElementIsMissing();
86
+
87
+ const inputSlot = this.baseElement.shadowRoot?.querySelector('slot[name="input"]');
88
+ const textAreaSlot = this.baseElement.shadowRoot?.querySelector('slot[name="textarea"]');
89
+
90
+ this.#inputElement = getNestedInput(inputSlot) || getNestedInput(textAreaSlot);
91
+
92
+ return this.#inputElement;
93
+ }
94
+
95
+ set inputElement(ele) {
96
+ this.#inputElement = ele;
97
+ }
98
+
99
+ getValidity() {
100
+ return this.inputElement?.validity || {};
101
+ }
102
+
103
+ #handleErrorMessage() {
104
+ this.setAttribute('error-message', this.validationMessage);
105
+ }
106
+
107
+ // We do not want to show the default validity report tooltip
108
+ // So we are overriding the reportValidity fn to show the input's error message
109
+ reportValidity = () => {
110
+ // we want to update validity so in case the value was set programmatically, we won't get an error
111
+ this.inputElement.setCustomValidity('');
112
+ this.setCustomValidity('');
113
+ if (!this.checkValidity()) {
114
+ this.setAttribute('invalid', 'true');
115
+ this.#handleErrorMessage();
116
+ this.focus();
117
+ }
118
+ };
119
+
120
+ // we are keeping also the default reportValidity because there are some components that still using it
121
+ defaultReportValidity() {
122
+ return super.reportValidity();
123
+ }
124
+
125
+ init() {
126
+ super.init?.();
127
+
128
+ // vaadin sets invalid indication on blur
129
+ // we want invalid indication to appear only when calling reportValidity
130
+ // this is why we are overriding vaadin's setInvalid behavior
131
+ // to update only when the element is valid (so invalid indication will only be removed)
132
+ // and we are adding it in reportValidity
133
+ // eslint-disable-next-line func-names
134
+ this.baseElement._setInvalid = function (invalid) {
135
+ if (!invalid && this._shouldSetInvalid(invalid)) {
136
+ this.invalid = invalid;
137
+ }
138
+ };
139
+
140
+ // We want to ensure that `input` events properly cross ShadowDOM boundries
141
+ // e.g. When we autofill a component's input with 1Password, for instance,
142
+ // the event is fired without `composed: true` and doesn't our component's
143
+ // ShadowDOM.
144
+ this.baseElement.addEventListener('input', (e) => {
145
+ if (!e.composed) {
146
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
147
+ }
148
+ });
149
+
150
+ triggerValidationEvents.forEach((e) => {
151
+ this.baseElement?.addEventListener(e, () => {
152
+ this.inputElement?.setCustomValidity('');
153
+ });
154
+ });
155
+
156
+ // on some cases the base element is not ready so the inputElement is empty
157
+ // we are deferring this section to make sure the base element is ready
158
+ setTimeout(() => {
159
+ const validationEvents = Array.isArray(inputEvent) ? inputEvent : [inputEvent];
160
+
161
+ validationEvents.forEach((e) => {
162
+ this.baseElement?.addEventListener(e, () => {
163
+ if (!this.baseElement.checkValidity()) {
164
+ this.#handleErrorMessage();
165
+ } else {
166
+ this.removeAttribute('invalid');
167
+ }
168
+ });
169
+ });
170
+
171
+ this.baseElement.addEventListener('change', () => {
172
+ this.#dispatchChange();
173
+ });
174
+
175
+ this.addEventListener('invalid', () => {
176
+ if (!this.checkValidity()) {
177
+ this.setAttribute('invalid', 'true');
178
+ }
179
+ this.#handleErrorMessage();
180
+ });
181
+
182
+ // sync properties
183
+ proxyProps.forEach((prop) => {
184
+ const externalInput = this.querySelector('input[slot="external-input"]') || null;
185
+ const proxyTargets = useProxyTargets
186
+ ? [this.baseElement, externalInput].filter(Boolean)
187
+ : [];
188
+ forwardProps(this, [this.inputElement, ...proxyTargets], prop);
189
+ });
190
+
191
+ this.setSelectionRange = this.inputElement.setSelectionRange?.bind(this.inputElement);
192
+
193
+ forwardAttrs(this, this.inputElement, { includeAttrs: ['inputmode'] });
194
+ });
195
+
196
+ if (proxyParentValidation) {
197
+ // All functions called on the inputElement internals will be applied to the parent
198
+ // component internals as well. As a result, there's no need to add outer mechanisms
199
+ // to update the parent component's validity state based on the input elements validity.
200
+ const inputElementInternals = this.inputElement.internals;
201
+ const parentThis = this;
202
+ this.inputElement.internals = new Proxy(inputElementInternals, {
203
+ get: (target, prop) => {
204
+ if (typeof target[prop] === 'function' && prop === 'setValidity') {
205
+ return (...args) => {
206
+ // If we're calling setValidity with 3 args, then the validationTarget
207
+ // needs to be swapped to be the inputElement
208
+ if (args.length === 3) {
209
+ const newArgs = args.slice(0, args.length - 1);
210
+ newArgs.push(parentThis.inputElement);
211
+ parentThis.internals[prop](...newArgs);
212
+ } else {
213
+ parentThis.internals[prop](...args);
214
+ }
215
+ return target[prop](...args);
216
+ };
217
+ }
218
+
219
+ if (typeof target[prop] === 'function') {
220
+ return (...args) => {
221
+ parentThis.internals[prop](...args);
222
+ return target[prop](...args);
223
+ };
224
+ }
225
+
226
+ return target[prop];
227
+ },
228
+ });
229
+ }
230
+ }
231
+ };
232
+
233
+ const composedProxyInputMixin = (proxyInputMixinConfig) =>
234
+ compose(
235
+ proxyInputMixin(proxyInputMixinConfig),
236
+ // in order to use input-wrapper across all our input components, we need to inject its theme
237
+ // to every proxy input mixin, to allow its css vars to be scoped properly and accessible
238
+ // in the proxy input component
239
+ createStyleMixin({ componentNameOverride: getComponentName('input-wrapper') })
240
+ );
241
+
242
+ export { composedProxyInputMixin as proxyInputMixin };
@@ -0,0 +1,4 @@
1
+ export const DESCOPE_PREFIX = 'descope';
2
+ export const CSS_SELECTOR_SPECIFIER_MULTIPLY = 3;
3
+ export const BASE_THEME_SECTION = 'host';
4
+ export const PORTAL_THEME_PREFIX = '@';
@@ -0,0 +1 @@
1
+ export default `data:image/svg+xml;base64,PHN2ZyBmaWxsPSIjZTIxZDEyIiB2ZXJzaW9uPSIxLjEiIGlkPSJDYXBhXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIA0KCSB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCAzMC4zMzQgMzAuMzM0Ig0KCSB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0xNS4xNjcsMEM2LjgwNSwwLDAuMDAxLDYuODA0LDAuMDAxLDE1LjE2N2MwLDguMzYyLDYuODA0LDE1LjE2NywxNS4xNjYsMTUuMTY3YzguMzYxLDAsMTUuMTY2LTYuODA1LDE1LjE2Ni0xNS4xNjcNCgkJQzMwLjMzMyw2LjgwNCwyMy41MjgsMCwxNS4xNjcsMHogTTE3LjE2NywyNS42NjdoLTR2LTQuNWg0VjI1LjY2N3ogTTE3LjE2NywxOS41NDJoLTRWNS4xNjdoNFYxOS41NDJ6Ii8+DQo8L2c+DQo8L3N2Zz4=`;