@descope/web-components-ui 1.0.66 → 1.0.68
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/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +481 -377
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/135.js +1 -0
- package/dist/umd/descope-button-index-js.js +1 -1
- package/dist/umd/descope-checkbox-index-js.js +1 -1
- package/dist/umd/descope-combo-box-index-js.js +1 -1
- package/dist/umd/descope-container-index-js.js +1 -1
- package/dist/umd/descope-date-picker-index-js.js +1 -1
- package/dist/umd/descope-divider-index-js.js +1 -1
- package/dist/umd/descope-email-field-index-js.js +1 -1
- package/dist/umd/descope-link-index-js.js +1 -1
- package/dist/umd/descope-loader-linear-index-js.js +1 -1
- package/dist/umd/descope-loader-radial-index-js.js +1 -1
- package/dist/umd/descope-logo-index-js.js +1 -1
- package/dist/umd/descope-number-field-index-js.js +1 -1
- package/dist/umd/descope-passcode-descope-passcode-internal-index-js.js +1 -1
- package/dist/umd/descope-passcode-index-js.js +1 -1
- package/dist/umd/descope-password-field-index-js.js +1 -1
- package/dist/umd/descope-switch-toggle-index-js.js +1 -1
- package/dist/umd/descope-text-area-index-js.js +1 -1
- package/dist/umd/descope-text-field-index-js.js +1 -1
- package/dist/umd/descope-text-index-js.js +1 -1
- package/dist/umd/index.js +1 -1
- package/package.json +1 -1
- package/src/baseClasses/BaseInputClass.js +3 -2
- package/src/baseClasses/createBaseClass.js +29 -0
- package/src/components/descope-container/Container.js +17 -25
- package/src/components/descope-divider/Divider.js +32 -40
- package/src/components/descope-link/Link.js +8 -17
- package/src/components/descope-loader-linear/LoaderLinear.js +24 -29
- package/src/components/descope-loader-radial/LoaderRadial.js +18 -26
- package/src/components/descope-logo/Logo.js +4 -12
- package/src/components/descope-passcode/Passcode.js +4 -11
- package/src/components/descope-passcode/descope-passcode-internal/PasscodeInternal.js +41 -53
- package/src/components/descope-text/Text.js +4 -12
- package/src/helpers/index.js +2 -0
- package/src/helpers/mixinsHelpers.js +18 -0
- package/src/mixins/changeMixin.js +47 -0
- package/src/mixins/componentNameValidationMixin.js +1 -1
- package/src/mixins/createProxy.js +26 -28
- package/src/mixins/createStyleMixin/helpers.js +3 -3
- package/src/mixins/createStyleMixin/index.js +10 -9
- package/src/mixins/draggableMixin.js +1 -1
- package/src/mixins/focusMixin.js +130 -0
- package/src/mixins/hoverableMixin.js +14 -13
- package/src/mixins/index.js +3 -1
- package/src/mixins/{inputMixin.js → inputValidationMixin.js} +17 -58
- package/src/mixins/proxyInputMixin.js +50 -45
- package/dist/umd/860.js +0 -1
- package/src/baseClasses/DescopeBaseClass.js +0 -1
package/dist/index.esm.js
CHANGED
@@ -24,6 +24,8 @@ const compose = (...fns) =>
|
|
24
24
|
|
25
25
|
const upperFirst = (str) => str.charAt(0).toUpperCase() + str.slice(1);
|
26
26
|
|
27
|
+
const isFunction = (maybeFunc) => typeof maybeFunc === 'function';
|
28
|
+
|
27
29
|
const DESCOPE_PREFIX = 'descope';
|
28
30
|
const CSS_SELECTOR_SPECIFIER_MULTIPLY = 3;
|
29
31
|
const BASE_THEME_SECTION = 'host';
|
@@ -175,7 +177,7 @@ const createCssSelector = (
|
|
175
177
|
baseSelector = '',
|
176
178
|
relativeSelectorOrSelectorFn = ''
|
177
179
|
) =>
|
178
|
-
|
180
|
+
isFunction(relativeSelectorOrSelectorFn)
|
179
181
|
? relativeSelectorOrSelectorFn(baseSelector)
|
180
182
|
: `${baseSelector}${/^[A-Za-z]/.test(relativeSelectorOrSelectorFn)
|
181
183
|
? ` ${relativeSelectorOrSelectorFn}`
|
@@ -232,7 +234,7 @@ const createStyle = (componentName, baseSelector, mappings) => {
|
|
232
234
|
({ selector: relativeSelectorOrSelectorFn, property }) => {
|
233
235
|
style.add(
|
234
236
|
createCssSelector(baseSelector, relativeSelectorOrSelectorFn),
|
235
|
-
property,
|
237
|
+
isFunction(property) ? property() : property,
|
236
238
|
createCssVarFallback(cssVarName)
|
237
239
|
);
|
238
240
|
}
|
@@ -315,7 +317,7 @@ const createStyleMixin =
|
|
315
317
|
this.#onComponentThemeChange();
|
316
318
|
}
|
317
319
|
|
318
|
-
#
|
320
|
+
#createOverridesStyle() {
|
319
321
|
this.#overrideStyleEle = document.createElement('style');
|
320
322
|
this.#overrideStyleEle.id = 'style-mixin-overrides';
|
321
323
|
|
@@ -325,7 +327,7 @@ const createStyleMixin =
|
|
325
327
|
this.#rootElement.append(this.#overrideStyleEle);
|
326
328
|
}
|
327
329
|
|
328
|
-
#
|
330
|
+
#setAttrOverride(attrName, value) {
|
329
331
|
const style = this.#overrideStyleEle?.sheet?.cssRules[0].style;
|
330
332
|
if (!style) return;
|
331
333
|
|
@@ -338,10 +340,10 @@ const createStyleMixin =
|
|
338
340
|
else style?.removeProperty(varName);
|
339
341
|
}
|
340
342
|
|
341
|
-
#
|
343
|
+
#updateOverridesStyle(attrs = []) {
|
342
344
|
for (const attr of attrs) {
|
343
345
|
if (this.#styleAttributes.includes(attr)) {
|
344
|
-
this.#
|
346
|
+
this.#setAttrOverride(attr, this.getAttribute(attr));
|
345
347
|
}
|
346
348
|
}
|
347
349
|
|
@@ -349,7 +351,7 @@ const createStyleMixin =
|
|
349
351
|
this.#overrideStyleEle.innerHTML = this.#overrideStyleEle?.sheet?.cssRules[0].cssText;
|
350
352
|
}
|
351
353
|
|
352
|
-
#
|
354
|
+
#createMappingStyle() {
|
353
355
|
const themeStyle = document.createElement('style');
|
354
356
|
themeStyle.id = 'style-mixin-mappings';
|
355
357
|
themeStyle.innerHTML = createStyle(
|
@@ -370,13 +372,14 @@ const createStyleMixin =
|
|
370
372
|
|
371
373
|
this.#addClassName(superclass.componentName);
|
372
374
|
|
373
|
-
|
375
|
+
// TODO: we should do everything we can on the constructor
|
376
|
+
// when dragging & dropping these styles are created over & over
|
377
|
+
this.#createMappingStyle();
|
374
378
|
this.#createComponentTheme();
|
375
|
-
this.#
|
379
|
+
this.#createOverridesStyle();
|
376
380
|
|
377
381
|
// this is instead attributeChangedCallback because we cannot use static methods in this case
|
378
|
-
observeAttributes(this, this.#
|
379
|
-
|
382
|
+
observeAttributes(this, this.#updateOverridesStyle.bind(this), {});
|
380
383
|
}
|
381
384
|
}
|
382
385
|
|
@@ -398,7 +401,7 @@ const draggableMixin = (superclass) =>
|
|
398
401
|
super();
|
399
402
|
|
400
403
|
this.#styleEle = document.createElement('style');
|
401
|
-
this.#styleEle.innerText =
|
404
|
+
this.#styleEle.innerText = `* { cursor: inherit!important }`;
|
402
405
|
}
|
403
406
|
|
404
407
|
#handleDraggableStyle(isDraggable) {
|
@@ -417,31 +420,32 @@ const draggableMixin = (superclass) =>
|
|
417
420
|
}
|
418
421
|
};
|
419
422
|
|
420
|
-
|
423
|
+
const createBaseClass = ({ componentName, baseSelector = '' }) => {
|
424
|
+
class DescopeBaseClass extends HTMLElement {
|
425
|
+
static get componentName() {
|
426
|
+
return componentName;
|
427
|
+
}
|
421
428
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
connectedCallback() {
|
427
|
-
super.connectedCallback?.();
|
429
|
+
#baseElement;
|
430
|
+
get baseSelector() {
|
431
|
+
return baseSelector
|
432
|
+
}
|
428
433
|
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
() => this.shadowRoot.host.removeAttribute('hover'),
|
434
|
-
{ once: true }
|
435
|
-
);
|
436
|
-
};
|
434
|
+
get baseElement() {
|
435
|
+
this.#baseElement ??= this.baseSelector ?
|
436
|
+
this.rootElement.querySelector(this.baseSelector) :
|
437
|
+
this;
|
437
438
|
|
438
|
-
|
439
|
-
|
440
|
-
);
|
439
|
+
return this.#baseElement
|
440
|
+
}
|
441
441
|
|
442
|
-
|
443
|
-
|
444
|
-
|
442
|
+
get rootElement() {
|
443
|
+
return this.shadowRoot || this
|
444
|
+
}
|
445
|
+
}
|
446
|
+
|
447
|
+
return compose(componentNameValidationMixin, hoverableMixin)(DescopeBaseClass)
|
448
|
+
};
|
445
449
|
|
446
450
|
const createProxy = ({
|
447
451
|
componentName,
|
@@ -460,38 +464,39 @@ const createProxy = ({
|
|
460
464
|
</${wrappedEleName}>
|
461
465
|
`;
|
462
466
|
|
463
|
-
class
|
464
|
-
static get componentName() {
|
465
|
-
return componentName;
|
466
|
-
}
|
467
|
-
|
467
|
+
class ProxyClass extends createBaseClass({ componentName, baseSelector: wrappedEleName }) {
|
468
468
|
constructor() {
|
469
469
|
super().attachShadow({ mode: 'open' }).innerHTML = template;
|
470
470
|
this.hostElement = this.shadowRoot.host;
|
471
|
-
this.baseSelector = wrappedEleName;
|
472
471
|
this.shadowRoot.getElementById('create-proxy').innerHTML =
|
473
|
-
|
472
|
+
isFunction(style) ? style() : style;
|
474
473
|
}
|
475
474
|
|
475
|
+
#boundOnFocus = this.#onFocus.bind(this);
|
476
|
+
|
477
|
+
// we want to focus on the proxy element when focusing our WCP
|
478
|
+
#onFocus() {
|
479
|
+
this.proxyElement.focus();
|
480
|
+
}
|
481
|
+
|
482
|
+
focus = this.#onFocus
|
483
|
+
|
476
484
|
connectedCallback() {
|
477
485
|
if (this.shadowRoot.isConnected) {
|
478
486
|
this.proxyElement = this.shadowRoot.querySelector(wrappedEleName);
|
479
487
|
|
488
|
+
this.addEventListener('focus', this.#boundOnFocus);
|
489
|
+
|
480
490
|
// this is needed for components that uses props, such as combo box
|
481
491
|
forwardProps(this.hostElement, this.proxyElement, includeForwardProps);
|
482
492
|
|
483
|
-
this.setAttribute('tabindex', '0');
|
484
|
-
|
485
|
-
// we want to focus on the proxy element when focusing our WC
|
486
|
-
this.addEventListener('focus', () => {
|
487
|
-
this.proxyElement.focus();
|
488
|
-
});
|
489
|
-
|
490
493
|
// `onkeydown` is set on `proxyElement` support proper tab-index navigation
|
491
494
|
// this support is needed since both proxy host and element catch `focus`/`blur` event
|
492
|
-
// which causes faulty
|
495
|
+
// which causes faulty behavior.
|
496
|
+
// we need this to happen only when the proxy component is in the light DOM,
|
497
|
+
// otherwise it will focus the nested proxy element
|
493
498
|
this.proxyElement.onkeydown = (e) => {
|
494
|
-
if (e.shiftKey && e.keyCode === 9) {
|
499
|
+
if (e.shiftKey && e.keyCode === 9 && this.getRootNode() === document) {
|
495
500
|
this.removeAttribute('tabindex');
|
496
501
|
// We want to defer the action of setting the tab index back
|
497
502
|
// so it will happen after focusing the previous element
|
@@ -499,10 +504,6 @@ const createProxy = ({
|
|
499
504
|
}
|
500
505
|
};
|
501
506
|
|
502
|
-
// sync events
|
503
|
-
this.addEventListener = (...args) =>
|
504
|
-
this.proxyElement.addEventListener(...args);
|
505
|
-
|
506
507
|
syncAttrs(this.proxyElement, this.hostElement, {
|
507
508
|
excludeAttrs: excludeAttrsSync,
|
508
509
|
includeAttrs: includeAttrsSync
|
@@ -510,28 +511,30 @@ const createProxy = ({
|
|
510
511
|
}
|
511
512
|
}
|
512
513
|
|
513
|
-
disconnectedCallback() {
|
514
|
-
this.proxyElement.removeEventListener('mouseover', this.mouseoverCbRef);
|
515
|
-
}
|
516
|
-
|
517
514
|
attributeChangedCallback() {
|
518
515
|
if (!this.proxyElement) {
|
519
516
|
return;
|
520
517
|
}
|
521
518
|
}
|
519
|
+
|
520
|
+
disconnectedCallback() {
|
521
|
+
super.disconnectedCallback?.();
|
522
|
+
|
523
|
+
this.removeEventListener('focus', this.#boundOnFocus);
|
524
|
+
}
|
522
525
|
}
|
523
526
|
|
524
|
-
return
|
527
|
+
return ProxyClass;
|
525
528
|
};
|
526
529
|
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
530
|
+
// move create event to here
|
531
|
+
|
532
|
+
// usage example:
|
533
|
+
// #dispatchSomething = createDispatchEvent.bind(this, 'something')
|
534
|
+
function createDispatchEvent(eventName) {
|
535
|
+
this[`on${eventName}`]?.(); // in case we got an event callback as property
|
536
|
+
this.dispatchEvent(new Event(eventName));
|
537
|
+
}
|
535
538
|
|
536
539
|
const observedAttributes = [
|
537
540
|
'required',
|
@@ -542,7 +545,7 @@ const errorAttributes = {
|
|
542
545
|
valueMissing: 'data-errormessage-value-missing',
|
543
546
|
patternMismatch: 'data-errormessage-pattern-mismatch'
|
544
547
|
};
|
545
|
-
const
|
548
|
+
const inputValidationMixin = (superclass) => class InputValidationMixinClass extends superclass {
|
546
549
|
static get observedAttributes() {
|
547
550
|
return [
|
548
551
|
...superclass.observedAttributes || [],
|
@@ -554,18 +557,19 @@ const inputMixin = (superclass) => class InputMixinClass extends superclass {
|
|
554
557
|
return true;
|
555
558
|
}
|
556
559
|
|
560
|
+
#dispatchValid = createDispatchEvent.bind(this, 'valid')
|
561
|
+
#dispatchInvalid = createDispatchEvent.bind(this, 'invalid')
|
562
|
+
|
557
563
|
#internals
|
558
564
|
|
565
|
+
#boundedHandleInput
|
566
|
+
|
559
567
|
constructor() {
|
560
568
|
super();
|
561
569
|
|
562
570
|
this.#internals = this.attachInternals();
|
563
571
|
|
564
|
-
|
565
|
-
this[`dispatch${upperFirst(event)}`] = function () {
|
566
|
-
this.dispatchInputEvent(event);
|
567
|
-
};
|
568
|
-
}
|
572
|
+
this.#boundedHandleInput = this.#handleInput.bind(this);
|
569
573
|
}
|
570
574
|
|
571
575
|
get defaultErrorMsgValueMissing() {
|
@@ -591,13 +595,7 @@ const inputMixin = (superclass) => class InputMixinClass extends superclass {
|
|
591
595
|
}
|
592
596
|
}
|
593
597
|
|
594
|
-
get isReadOnly() {
|
595
|
-
return this.getAttribute('readonly') !== 'false'
|
596
|
-
}
|
597
|
-
|
598
598
|
setValidity() {
|
599
|
-
if (this.isReadOnly) return;
|
600
|
-
|
601
599
|
const validity = this.getValidity();
|
602
600
|
this.#internals.setValidity(validity, this.getErrorMessage(validity));
|
603
601
|
}
|
@@ -607,7 +605,7 @@ const inputMixin = (superclass) => class InputMixinClass extends superclass {
|
|
607
605
|
}
|
608
606
|
|
609
607
|
getValidity() {
|
610
|
-
|
608
|
+
console.warn('getValidity', 'is not implemented');
|
611
609
|
}
|
612
610
|
|
613
611
|
checkValidity() {
|
@@ -639,36 +637,11 @@ const inputMixin = (superclass) => class InputMixinClass extends superclass {
|
|
639
637
|
return this.getAttribute('pattern')
|
640
638
|
}
|
641
639
|
|
642
|
-
|
643
|
-
throw Error('get value', 'is not implemented')
|
644
|
-
}
|
645
|
-
|
646
|
-
set value(value) {
|
647
|
-
throw Error('set value', 'is not implemented')
|
648
|
-
}
|
649
|
-
|
650
|
-
handleFocus() {
|
651
|
-
throw Error('handleFocus', 'is not implemented')
|
652
|
-
}
|
653
|
-
|
654
|
-
handleInput() {
|
640
|
+
#handleInput() {
|
655
641
|
this.setValidity();
|
656
642
|
this.handleDispatchValidationEvents();
|
657
643
|
}
|
658
644
|
|
659
|
-
handleBlur() {
|
660
|
-
throw Error('handleBlur', 'is not implemented')
|
661
|
-
}
|
662
|
-
|
663
|
-
handleChange() {
|
664
|
-
throw Error('handleChange', 'is not implemented')
|
665
|
-
}
|
666
|
-
|
667
|
-
dispatchInputEvent(eventName) {
|
668
|
-
this[`on${eventName}`]?.(); // in case we got an event callback as property
|
669
|
-
this.dispatchEvent(new InputEvent(eventName));
|
670
|
-
}
|
671
|
-
|
672
645
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
673
646
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
674
647
|
|
@@ -679,25 +652,23 @@ const inputMixin = (superclass) => class InputMixinClass extends superclass {
|
|
679
652
|
|
680
653
|
handleDispatchValidationEvents() {
|
681
654
|
if (this.checkValidity()) {
|
682
|
-
this
|
655
|
+
this.#dispatchValid();
|
683
656
|
} else {
|
684
|
-
this
|
657
|
+
this.#dispatchInvalid();
|
685
658
|
}
|
686
659
|
}
|
687
660
|
|
688
661
|
connectedCallback() {
|
689
662
|
super.connectedCallback?.();
|
690
663
|
|
664
|
+
this.addEventListener('input', this.#boundedHandleInput);
|
665
|
+
|
691
666
|
this.setValidity();
|
692
667
|
this.handleDispatchValidationEvents();
|
668
|
+
}
|
693
669
|
|
694
|
-
|
695
|
-
|
696
|
-
// of this element and not the nested element's events
|
697
|
-
this.onfocus = this.handleFocus.bind(this);
|
698
|
-
this.addEventListener('input', this.handleInput.bind(this));
|
699
|
-
this.addEventListener('blur', this.handleBlur.bind(this));
|
700
|
-
this.addEventListener('change', this.handleBlur.bind(this));
|
670
|
+
disconnectedCallback() {
|
671
|
+
this.removeEventListener('input', this.#boundedHandleInput);
|
701
672
|
}
|
702
673
|
};
|
703
674
|
|
@@ -730,18 +701,28 @@ const getNestedInput = (ele) => {
|
|
730
701
|
};
|
731
702
|
|
732
703
|
const proxyInputMixin = (superclass) =>
|
733
|
-
class proxyInputMixinClass extends
|
704
|
+
class proxyInputMixinClass extends inputValidationMixin(superclass) {
|
734
705
|
static get observedAttributes() {
|
735
706
|
return [...superclass.observedAttributes || [], ...errorAttrs];
|
736
707
|
}
|
737
708
|
|
738
709
|
#inputElement
|
739
710
|
|
711
|
+
#boundHandleFocus
|
712
|
+
#boundHandleInvalid
|
713
|
+
#boundHandleValid
|
714
|
+
|
740
715
|
constructor() {
|
741
716
|
super();
|
742
717
|
|
743
718
|
this.#inputElement = super.inputElement;
|
744
719
|
|
720
|
+
this.#boundHandleFocus = this.#handleFocus.bind(this);
|
721
|
+
this.#boundHandleInvalid = this.#handleInvalid.bind(this);
|
722
|
+
this.#boundHandleValid = this.#handleValid.bind(this);
|
723
|
+
|
724
|
+
this.baseEle = this.shadowRoot.querySelector(this.baseSelector);
|
725
|
+
|
745
726
|
}
|
746
727
|
|
747
728
|
get inputElement() {
|
@@ -749,7 +730,7 @@ const proxyInputMixin = (superclass) =>
|
|
749
730
|
const textAreaSlot = this.baseEle.shadowRoot.querySelector('slot[name="textarea"]');
|
750
731
|
|
751
732
|
this.#inputElement ??= getNestedInput(inputSlot) || getNestedInput(textAreaSlot);
|
752
|
-
|
733
|
+
|
753
734
|
if (!this.#inputElement) throw Error('no input was found');
|
754
735
|
|
755
736
|
return this.#inputElement
|
@@ -765,27 +746,17 @@ const proxyInputMixin = (superclass) =>
|
|
765
746
|
|
766
747
|
reportValidityOnInternalInput() {
|
767
748
|
setTimeout(() => {
|
749
|
+
this.baseEle.focus(); //TODO: check if this is needed
|
768
750
|
this.inputElement.reportValidity();
|
769
|
-
}
|
770
|
-
}
|
771
|
-
|
772
|
-
handleBlur() { }
|
773
|
-
|
774
|
-
handleFocus() {
|
775
|
-
this.inputElement.focus();
|
776
|
-
if (this.hasAttribute('invalid')) {
|
777
|
-
this.reportValidityOnInternalInput();
|
778
|
-
}
|
751
|
+
});
|
779
752
|
}
|
780
753
|
|
781
754
|
// we want reportValidity to behave like form submission
|
782
755
|
reportValidity() {
|
783
|
-
const isValid = super.reportValidity();
|
784
756
|
if (!isValid) {
|
785
757
|
this.setAttribute('invalid', 'true');
|
786
|
-
this.
|
758
|
+
this.reportValidityOnInternalInput();
|
787
759
|
}
|
788
|
-
this.reportValidityOnInternalInput();
|
789
760
|
}
|
790
761
|
|
791
762
|
setInternalInputErrorMessage() {
|
@@ -794,48 +765,47 @@ const proxyInputMixin = (superclass) =>
|
|
794
765
|
}
|
795
766
|
}
|
796
767
|
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
if (!this.checkValidity()) {
|
805
|
-
this.setAttribute('invalid', 'true');
|
806
|
-
}
|
768
|
+
// when clicking on the form submit button and the input is invalid
|
769
|
+
// we want it to appear as invalid
|
770
|
+
#handleFocus(e) {
|
771
|
+
if (e.relatedTarget?.form) {
|
772
|
+
if (!this.checkValidity()) {
|
773
|
+
this.setAttribute('invalid', 'true');
|
774
|
+
}
|
807
775
|
|
808
|
-
|
809
|
-
|
810
|
-
}
|
776
|
+
if (this.hasAttribute('invalid')) {
|
777
|
+
this.reportValidityOnInternalInput();
|
811
778
|
}
|
812
|
-
}
|
779
|
+
}
|
780
|
+
}
|
813
781
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
782
|
+
#handleInvalid() {
|
783
|
+
this.setInternalInputErrorMessage();
|
784
|
+
this.setAttribute('error-message', this.validationMessage);
|
785
|
+
}
|
818
786
|
|
819
|
-
|
820
|
-
|
821
|
-
|
787
|
+
#handleValid() {
|
788
|
+
this.removeAttribute('invalid');
|
789
|
+
}
|
822
790
|
|
791
|
+
connectedCallback() {
|
823
792
|
super.connectedCallback?.();
|
824
793
|
|
825
|
-
this
|
794
|
+
// this is our way to identify that the form was submitted
|
795
|
+
// in this case, we want the input to be in error state if it's not valid
|
796
|
+
this.addEventListener('focus', this.#boundHandleFocus);
|
797
|
+
|
798
|
+
this.addEventListener('invalid', this.#boundHandleInvalid);
|
799
|
+
this.addEventListener('valid', this.#boundHandleValid);
|
800
|
+
|
801
|
+
this.addEventListener('input', () => {
|
826
802
|
this.inputElement.setCustomValidity('');
|
827
803
|
if (!this.inputElement.checkValidity())
|
828
804
|
this.setInternalInputErrorMessage();
|
829
805
|
});
|
830
806
|
|
831
|
-
this.inputElement.addEventListener('invalid', () => {
|
832
|
-
this.setValidity();
|
833
|
-
this.setInternalInputErrorMessage();
|
834
|
-
this.setAttribute('error-message', this.validationMessage);
|
835
|
-
});
|
836
|
-
|
837
807
|
// this is needed in order to make sure the form input validation is working
|
838
|
-
if (!this.hasAttribute('tabindex')) {
|
808
|
+
if (!this.hasAttribute('tabindex') && this.getRootNode() === document) {
|
839
809
|
this.setAttribute('tabindex', 0);
|
840
810
|
}
|
841
811
|
|
@@ -844,6 +814,12 @@ const proxyInputMixin = (superclass) =>
|
|
844
814
|
this.setSelectionRange = this.inputElement.setSelectionRange?.bind(this.inputElement);
|
845
815
|
}
|
846
816
|
|
817
|
+
disconnectedCallback() {
|
818
|
+
this.removeEventListener('focus', this.#boundHandleFocus);
|
819
|
+
this.removeEventListener('invalid', this.#boundHandleInvalid);
|
820
|
+
this.removeEventListener('valid', this.#boundHandleValid);
|
821
|
+
}
|
822
|
+
|
847
823
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
848
824
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
849
825
|
|
@@ -854,7 +830,7 @@ const proxyInputMixin = (superclass) =>
|
|
854
830
|
};
|
855
831
|
|
856
832
|
const componentNameValidationMixin = (superclass) =>
|
857
|
-
class
|
833
|
+
class ComponentNameValidationMixinClass extends superclass {
|
858
834
|
#checkComponentName() {
|
859
835
|
const currentComponentName = this.shadowRoot.host.tagName.toLowerCase();
|
860
836
|
|
@@ -879,6 +855,160 @@ const componentNameValidationMixin = (superclass) =>
|
|
879
855
|
}
|
880
856
|
};
|
881
857
|
|
858
|
+
const hoverableMixin =
|
859
|
+
(superclass) =>
|
860
|
+
class HoverableMixinClass extends superclass {
|
861
|
+
#boundOnMouseOver = this.#onMouseOver.bind(this)
|
862
|
+
|
863
|
+
#onMouseOver(e) {
|
864
|
+
this.setAttribute('hover', 'true');
|
865
|
+
e.target.addEventListener(
|
866
|
+
'mouseleave',
|
867
|
+
() => this.shadowRoot.host.removeAttribute('hover'),
|
868
|
+
{ once: true }
|
869
|
+
);
|
870
|
+
}
|
871
|
+
|
872
|
+
connectedCallback() {
|
873
|
+
super.connectedCallback?.();
|
874
|
+
|
875
|
+
const baseElement = this.shadowRoot.querySelector(
|
876
|
+
this.baseSelector
|
877
|
+
);
|
878
|
+
|
879
|
+
baseElement.addEventListener('mouseover', this.#boundOnMouseOver);
|
880
|
+
}
|
881
|
+
};
|
882
|
+
|
883
|
+
const events = [
|
884
|
+
'blur',
|
885
|
+
'focus',
|
886
|
+
'focusin',
|
887
|
+
'focusout',
|
888
|
+
];
|
889
|
+
|
890
|
+
const focusMixin = (superclass) => class FocusMixinClass extends superclass {
|
891
|
+
#isFocused = false
|
892
|
+
#setFocusTimer
|
893
|
+
|
894
|
+
#boundedHandleFocus
|
895
|
+
#boundedHandleBlur
|
896
|
+
#boundedHandleFocusIn
|
897
|
+
#boundedHandleFocusOut
|
898
|
+
|
899
|
+
constructor() {
|
900
|
+
super();
|
901
|
+
|
902
|
+
for (const event of events) {
|
903
|
+
this[`dispatch${upperFirst(event)}`] = function () {
|
904
|
+
this.dispatchInputEvent(event);
|
905
|
+
};
|
906
|
+
}
|
907
|
+
|
908
|
+
this.#boundedHandleFocus = this.#handleFocus.bind(this);
|
909
|
+
this.#boundedHandleBlur = this.#handleBlur.bind(this);
|
910
|
+
this.#boundedHandleFocusIn = this.#handleFocusIn.bind(this);
|
911
|
+
this.#boundedHandleFocusOut = this.#handleFocusOut.bind(this);
|
912
|
+
}
|
913
|
+
|
914
|
+
#handleFocus(e) {
|
915
|
+
if (this.isReadOnly) {
|
916
|
+
e.stopPropagation();
|
917
|
+
return
|
918
|
+
}
|
919
|
+
// we want to listen only to browser events
|
920
|
+
// and not to events we are dispatching
|
921
|
+
if (e.isTrusted) { // TODO: check if this is needed, because Vaadin is also dispatching events
|
922
|
+
// we want to control the focus events that dispatched by the component
|
923
|
+
// so we are stopping propagation and handling it in setFocus
|
924
|
+
e.stopPropagation();
|
925
|
+
this.setFocus(true);
|
926
|
+
|
927
|
+
// if the focus event is on the root component (and not on the inner components)
|
928
|
+
// we want to notify the component and let it decide what to do with it
|
929
|
+
if (e.target === this) {
|
930
|
+
this.onFocus(e);
|
931
|
+
}
|
932
|
+
}
|
933
|
+
}
|
934
|
+
|
935
|
+
#handleFocusOut(e) {
|
936
|
+
// we want to listen only to browser events
|
937
|
+
// and not to events we are dispatching
|
938
|
+
if (e.isTrusted) {
|
939
|
+
// we want to control the focus events that dispatched by the component
|
940
|
+
// so we are stopping propagation and handling it in setFocus
|
941
|
+
e.stopPropagation();
|
942
|
+
}
|
943
|
+
}
|
944
|
+
|
945
|
+
#handleFocusIn(e) {
|
946
|
+
// we want to listen only to browser events
|
947
|
+
// and not to events we are dispatching
|
948
|
+
if (e.isTrusted) {
|
949
|
+
// we want to control the focus events that dispatched by the component
|
950
|
+
// so we are stopping propagation and handling it in setFocus
|
951
|
+
e.stopPropagation();
|
952
|
+
}
|
953
|
+
}
|
954
|
+
|
955
|
+
#handleBlur(e) {
|
956
|
+
if (e.isTrusted) {
|
957
|
+
e.stopPropagation();
|
958
|
+
this.setFocus(false);
|
959
|
+
}
|
960
|
+
}
|
961
|
+
|
962
|
+
get isReadOnly() {
|
963
|
+
return this.hasAttribute('readonly') && this.getAttribute('readonly') !== 'false'
|
964
|
+
}
|
965
|
+
|
966
|
+
// we want to debounce the calls to this fn
|
967
|
+
// so we can support input like components with multiple inputs inside
|
968
|
+
setFocus(isFocused) {
|
969
|
+
clearTimeout(this.#setFocusTimer);
|
970
|
+
|
971
|
+
this.#setFocusTimer = setTimeout(() => {
|
972
|
+
if (this.#isFocused !== isFocused) {
|
973
|
+
this.#isFocused = isFocused;
|
974
|
+
if (isFocused) {
|
975
|
+
this.dispatchFocus();
|
976
|
+
this.dispatchFocusin();
|
977
|
+
}
|
978
|
+
else {
|
979
|
+
this.dispatchBlur();
|
980
|
+
this.dispatchFocusout();
|
981
|
+
}
|
982
|
+
}
|
983
|
+
});
|
984
|
+
}
|
985
|
+
|
986
|
+
onFocus() {
|
987
|
+
console.warn('onFocus', 'is not implemented');
|
988
|
+
}
|
989
|
+
|
990
|
+
dispatchInputEvent(eventName) {
|
991
|
+
this[`on${eventName}`]?.(); // in case we got an event callback as property
|
992
|
+
this.dispatchEvent(new InputEvent(eventName));
|
993
|
+
}
|
994
|
+
|
995
|
+
connectedCallback() {
|
996
|
+
super.connectedCallback?.();
|
997
|
+
|
998
|
+
this.addEventListener('focus', this.#boundedHandleFocus, true);
|
999
|
+
this.addEventListener('blur', this.#boundedHandleBlur, true);
|
1000
|
+
this.addEventListener('focusin', this.#boundedHandleFocusIn);
|
1001
|
+
this.addEventListener('focusout', this.#boundedHandleFocusOut);
|
1002
|
+
}
|
1003
|
+
|
1004
|
+
disconnectedCallback() {
|
1005
|
+
this.removeEventListener('focus', this.#boundedHandleFocus);
|
1006
|
+
this.removeEventListener('blur', this.#boundedHandleBlur);
|
1007
|
+
this.removeEventListener('focusin', this.#boundedHandleFocusIn);
|
1008
|
+
this.removeEventListener('focusout', this.#boundedHandleFocusOut);
|
1009
|
+
}
|
1010
|
+
};
|
1011
|
+
|
882
1012
|
const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
|
883
1013
|
|
884
1014
|
const appendSuffixToKeys = (obj, suffix) => Object.keys(obj).reduce((acc, key) =>
|
@@ -936,6 +1066,52 @@ const portalMixin = ({ name, selector, mappings = {} }) => (superclass) => {
|
|
936
1066
|
}
|
937
1067
|
};
|
938
1068
|
|
1069
|
+
const changeMixin = (superclass) => class ChangeMixinClass extends superclass {
|
1070
|
+
|
1071
|
+
#boundedHandleChange
|
1072
|
+
#boundedHandleBlur
|
1073
|
+
|
1074
|
+
#removeChangeListener
|
1075
|
+
#removeBlurListener
|
1076
|
+
|
1077
|
+
#dispatchChange = createDispatchEvent.bind(this, 'change')
|
1078
|
+
|
1079
|
+
constructor() {
|
1080
|
+
super();
|
1081
|
+
|
1082
|
+
this.#boundedHandleChange = this.#handleChange.bind(this);
|
1083
|
+
this.#boundedHandleBlur = this.#handleBlur.bind(this);
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
#handleChange(e) {
|
1087
|
+
// we want to listen only to browser events
|
1088
|
+
// and not to events we are dispatching
|
1089
|
+
if (e.isTrusted) {
|
1090
|
+
// we want to control the change events that dispatched by the component
|
1091
|
+
// so we are stopping propagation and handling it in handleBlur
|
1092
|
+
e.stopPropagation();
|
1093
|
+
}
|
1094
|
+
}
|
1095
|
+
|
1096
|
+
#handleBlur() {
|
1097
|
+
// on blur, we want to dispatch a change event
|
1098
|
+
this.#dispatchChange();
|
1099
|
+
}
|
1100
|
+
|
1101
|
+
connectedCallback() {
|
1102
|
+
super.connectedCallback?.();
|
1103
|
+
|
1104
|
+
this.#removeChangeListener = addEventListener.bind();
|
1105
|
+
this.addEventListener('change', this.#boundedHandleChange, true);
|
1106
|
+
this.addEventListener('blur', this.#boundedHandleBlur);
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
disconnectedCallback() {
|
1110
|
+
this.removeEventListener('change', this.#boundedHandleChange);
|
1111
|
+
this.removeEventListener('blur', this.#boundedHandleBlur);
|
1112
|
+
}
|
1113
|
+
};
|
1114
|
+
|
939
1115
|
const componentName$i = getComponentName('button');
|
940
1116
|
|
941
1117
|
const editorOverrides = `vaadin-button::part(label) { pointer-events: none; }`;
|
@@ -1063,41 +1239,36 @@ customElements.define(componentName$h, Checkbox);
|
|
1063
1239
|
|
1064
1240
|
const componentName$g = getComponentName('loader-linear');
|
1065
1241
|
|
1066
|
-
class RawLoaderLinear extends
|
1242
|
+
class RawLoaderLinear extends createBaseClass({ componentName: componentName$g, baseSelector: ':host > div' }) {
|
1067
1243
|
static get componentName() {
|
1068
1244
|
return componentName$g;
|
1069
1245
|
}
|
1070
1246
|
constructor() {
|
1071
1247
|
super();
|
1072
|
-
const template = document.createElement('template');
|
1073
|
-
template.innerHTML = `
|
1074
|
-
<style>
|
1075
|
-
@keyframes tilt {
|
1076
|
-
0% { transform: translateX(0); }
|
1077
|
-
50% { transform: translateX(400%); }
|
1078
|
-
}
|
1079
|
-
:host {
|
1080
|
-
position: relative;
|
1081
|
-
display: inline-block
|
1082
|
-
}
|
1083
|
-
div::after {
|
1084
|
-
content: '';
|
1085
|
-
animation-name: tilt;
|
1086
|
-
position: absolute;
|
1087
|
-
left: 0;
|
1088
|
-
}
|
1089
1248
|
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1249
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1250
|
+
<style>
|
1251
|
+
@keyframes tilt {
|
1252
|
+
0% { transform: translateX(0); }
|
1253
|
+
50% { transform: translateX(400%); }
|
1254
|
+
}
|
1255
|
+
:host {
|
1256
|
+
position: relative;
|
1257
|
+
display: inline-block
|
1258
|
+
}
|
1259
|
+
div::after {
|
1260
|
+
content: '';
|
1261
|
+
animation-name: tilt;
|
1262
|
+
position: absolute;
|
1263
|
+
left: 0;
|
1264
|
+
}
|
1099
1265
|
|
1100
|
-
|
1266
|
+
:host > div {
|
1267
|
+
width: 100%;
|
1268
|
+
}
|
1269
|
+
</style>
|
1270
|
+
<div></div>
|
1271
|
+
`;
|
1101
1272
|
}
|
1102
1273
|
}
|
1103
1274
|
|
@@ -1132,34 +1303,26 @@ customElements.define(componentName$g, LoaderLinear);
|
|
1132
1303
|
|
1133
1304
|
const componentName$f = getComponentName('loader-radial');
|
1134
1305
|
|
1135
|
-
class RawLoaderRadial extends
|
1136
|
-
static get componentName() {
|
1137
|
-
return componentName$f;
|
1138
|
-
}
|
1306
|
+
class RawLoaderRadial extends createBaseClass({ componentName: componentName$f, baseSelector: ':host > div' }) {
|
1139
1307
|
constructor() {
|
1140
1308
|
super();
|
1141
|
-
const template = document.createElement('template');
|
1142
|
-
template.innerHTML = `
|
1143
|
-
<style>
|
1144
|
-
@keyframes spin {
|
1145
|
-
0% { transform: rotate(0deg); }
|
1146
|
-
100% { transform: rotate(360deg); }
|
1147
|
-
}
|
1148
|
-
:host {
|
1149
|
-
position: relative;
|
1150
|
-
display: inline-flex;
|
1151
|
-
}
|
1152
|
-
:host > div {
|
1153
|
-
animation-name: spin;
|
1154
|
-
}
|
1155
|
-
</style>
|
1156
|
-
<div></div>
|
1157
|
-
`;
|
1158
|
-
|
1159
|
-
this.attachShadow({ mode: 'open' });
|
1160
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1161
1309
|
|
1162
|
-
this.
|
1310
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1311
|
+
<style>
|
1312
|
+
@keyframes spin {
|
1313
|
+
0% { transform: rotate(0deg); }
|
1314
|
+
100% { transform: rotate(360deg); }
|
1315
|
+
}
|
1316
|
+
:host {
|
1317
|
+
position: relative;
|
1318
|
+
display: inline-flex;
|
1319
|
+
}
|
1320
|
+
:host > div {
|
1321
|
+
animation-name: spin;
|
1322
|
+
}
|
1323
|
+
</style>
|
1324
|
+
<div></div>
|
1325
|
+
`;
|
1163
1326
|
}
|
1164
1327
|
}
|
1165
1328
|
|
@@ -1190,33 +1353,25 @@ customElements.define(componentName$f, LoaderRadial);
|
|
1190
1353
|
|
1191
1354
|
const componentName$e = getComponentName('container');
|
1192
1355
|
|
1193
|
-
class RawContainer extends
|
1194
|
-
static get componentName() {
|
1195
|
-
return componentName$e;
|
1196
|
-
}
|
1356
|
+
class RawContainer extends createBaseClass({componentName: componentName$e, baseSelector: ':host > slot'}) {
|
1197
1357
|
constructor() {
|
1198
1358
|
super();
|
1199
|
-
const template = document.createElement('template');
|
1200
|
-
template.innerHTML = `
|
1201
|
-
<style>
|
1202
|
-
:host > slot {
|
1203
|
-
box-sizing: border-box;
|
1204
|
-
width: 100%;
|
1205
|
-
height: 100%;
|
1206
|
-
display: flex;
|
1207
|
-
overflow: auto;
|
1208
|
-
}
|
1209
|
-
:host {
|
1210
|
-
display: inline-block;
|
1211
|
-
}
|
1212
|
-
</style>
|
1213
|
-
<slot></slot>
|
1214
|
-
`;
|
1215
1359
|
|
1216
|
-
this.attachShadow({ mode: 'open' })
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1360
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1361
|
+
<style>
|
1362
|
+
:host > slot {
|
1363
|
+
box-sizing: border-box;
|
1364
|
+
width: 100%;
|
1365
|
+
height: 100%;
|
1366
|
+
display: flex;
|
1367
|
+
overflow: auto;
|
1368
|
+
}
|
1369
|
+
:host {
|
1370
|
+
display: inline-block;
|
1371
|
+
}
|
1372
|
+
</style>
|
1373
|
+
<slot></slot>
|
1374
|
+
`;
|
1220
1375
|
}
|
1221
1376
|
}
|
1222
1377
|
|
@@ -1273,51 +1428,43 @@ const DatePicker = compose(
|
|
1273
1428
|
customElements.define(componentName$d, DatePicker);
|
1274
1429
|
|
1275
1430
|
const componentName$c = getComponentName('divider');
|
1276
|
-
class RawDivider extends
|
1277
|
-
static get componentName() {
|
1278
|
-
return componentName$c;
|
1279
|
-
}
|
1431
|
+
class RawDivider extends createBaseClass({ componentName: componentName$c, baseSelector: ':host > div' }) {
|
1280
1432
|
constructor() {
|
1281
1433
|
super();
|
1282
1434
|
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
:
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
:
|
1293
|
-
|
1294
|
-
|
1295
|
-
}
|
1296
|
-
|
1297
|
-
descope-text {
|
1298
|
-
flex-grow: 0;
|
1299
|
-
flex-shrink: 0;
|
1300
|
-
}
|
1435
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1436
|
+
<style>
|
1437
|
+
:host > div {
|
1438
|
+
display: flex;
|
1439
|
+
height: 100%;
|
1440
|
+
width: 100%;
|
1441
|
+
}
|
1442
|
+
:host > div::before,
|
1443
|
+
:host > div::after {
|
1444
|
+
content: '';
|
1445
|
+
flex-grow: 1;
|
1446
|
+
}
|
1301
1447
|
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1448
|
+
descope-text {
|
1449
|
+
flex-grow: 0;
|
1450
|
+
flex-shrink: 0;
|
1451
|
+
}
|
1305
1452
|
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1453
|
+
:host(:empty) descope-text {
|
1454
|
+
display: none;
|
1455
|
+
}
|
1309
1456
|
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
<slot></slot>
|
1314
|
-
</descope-text>
|
1315
|
-
</div>
|
1316
|
-
`;
|
1317
|
-
this.attachShadow({ mode: 'open' });
|
1318
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1457
|
+
:host([vertical="true"]) div {
|
1458
|
+
width: fit-content;
|
1459
|
+
}
|
1319
1460
|
|
1320
|
-
|
1461
|
+
</style>
|
1462
|
+
<div>
|
1463
|
+
<descope-text>
|
1464
|
+
<slot></slot>
|
1465
|
+
</descope-text>
|
1466
|
+
</div>
|
1467
|
+
`;
|
1321
1468
|
|
1322
1469
|
this.textComponent = this.shadowRoot.querySelector('descope-text');
|
1323
1470
|
|
@@ -1345,7 +1492,7 @@ const Divider = compose(
|
|
1345
1492
|
alignItems: root,
|
1346
1493
|
alignSelf: root,
|
1347
1494
|
flexDirection: root,
|
1348
|
-
textPadding: {...text$2, property: 'padding'},
|
1495
|
+
textPadding: { ...text$2, property: 'padding' },
|
1349
1496
|
width: host$1,
|
1350
1497
|
padding: host$1,
|
1351
1498
|
backgroundColor: [before, after],
|
@@ -1361,14 +1508,11 @@ const Divider = compose(
|
|
1361
1508
|
|
1362
1509
|
const componentName$b = getComponentName('text');
|
1363
1510
|
|
1364
|
-
class RawText extends
|
1365
|
-
static get componentName() {
|
1366
|
-
return componentName$b;
|
1367
|
-
}
|
1511
|
+
class RawText extends createBaseClass({ componentName: componentName$b, baseSelector: ':host > slot' }) {
|
1368
1512
|
constructor() {
|
1369
1513
|
super();
|
1370
|
-
|
1371
|
-
|
1514
|
+
|
1515
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1372
1516
|
<style>
|
1373
1517
|
:host {
|
1374
1518
|
display: inline-block;
|
@@ -1380,11 +1524,6 @@ class RawText extends DescopeBaseClass {
|
|
1380
1524
|
</style>
|
1381
1525
|
<slot></slot>
|
1382
1526
|
`;
|
1383
|
-
|
1384
|
-
this.attachShadow({ mode: 'open' });
|
1385
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1386
|
-
|
1387
|
-
this.baseSelector = ':host > slot';
|
1388
1527
|
}
|
1389
1528
|
}
|
1390
1529
|
|
@@ -1516,15 +1655,12 @@ overrides$5 = `
|
|
1516
1655
|
customElements.define(componentName$a, EmailField);
|
1517
1656
|
|
1518
1657
|
const componentName$9 = getComponentName('link');
|
1519
|
-
class RawLink extends
|
1520
|
-
static get componentName() {
|
1521
|
-
return componentName$9;
|
1522
|
-
}
|
1658
|
+
class RawLink extends createBaseClass({ componentName: componentName$9, baseSelector: ':host a' }) {
|
1523
1659
|
constructor() {
|
1524
1660
|
super();
|
1525
|
-
|
1661
|
+
document.createElement('template');
|
1526
1662
|
|
1527
|
-
|
1663
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1528
1664
|
<style>
|
1529
1665
|
:host {
|
1530
1666
|
display: inline-block;
|
@@ -1542,9 +1678,6 @@ class RawLink extends DescopeBaseClass {
|
|
1542
1678
|
</div>
|
1543
1679
|
`;
|
1544
1680
|
|
1545
|
-
this.attachShadow({ mode: 'open' });
|
1546
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1547
|
-
|
1548
1681
|
forwardAttrs(this, this.shadowRoot.querySelector('a'), {
|
1549
1682
|
includeAttrs: ['href', 'target', 'tooltip'],
|
1550
1683
|
mapAttrs: {
|
@@ -1555,24 +1688,23 @@ class RawLink extends DescopeBaseClass {
|
|
1555
1688
|
forwardAttrs(this, this.shadowRoot.querySelector('descope-text'), {
|
1556
1689
|
includeAttrs: ['mode', 'variant'],
|
1557
1690
|
});
|
1558
|
-
|
1559
|
-
this.baseSelector = ':host > div';
|
1560
1691
|
}
|
1561
1692
|
}
|
1562
1693
|
|
1563
1694
|
const selectors$2 = {
|
1564
1695
|
host: { selector: () => 'host' },
|
1565
|
-
anchor: {
|
1566
|
-
|
1696
|
+
anchor: {},
|
1697
|
+
wrapper: {selector: () => ':host > div'},
|
1698
|
+
text: { selector: () => Text.componentName }
|
1567
1699
|
};
|
1568
1700
|
|
1569
|
-
const { anchor, text: text$1, host } = selectors$2;
|
1701
|
+
const { anchor, text: text$1, host, wrapper } = selectors$2;
|
1570
1702
|
|
1571
1703
|
const Link = compose(
|
1572
1704
|
createStyleMixin({
|
1573
1705
|
mappings: {
|
1574
1706
|
width: host,
|
1575
|
-
textAlign:
|
1707
|
+
textAlign: wrapper,
|
1576
1708
|
color: [anchor, { ...text$1, property: Text.cssVarList.color }],
|
1577
1709
|
cursor: anchor,
|
1578
1710
|
borderBottomWidth: anchor,
|
@@ -1580,7 +1712,6 @@ const Link = compose(
|
|
1580
1712
|
borderBottomColor: anchor
|
1581
1713
|
},
|
1582
1714
|
}),
|
1583
|
-
hoverableMixin(anchor.selector),
|
1584
1715
|
draggableMixin,
|
1585
1716
|
componentNameValidationMixin
|
1586
1717
|
)(RawLink);
|
@@ -1592,23 +1723,15 @@ const componentName$8 = getComponentName('logo');
|
|
1592
1723
|
let style;
|
1593
1724
|
const getStyle = () => style;
|
1594
1725
|
|
1595
|
-
class RawLogo extends
|
1596
|
-
static get componentName() {
|
1597
|
-
return componentName$8;
|
1598
|
-
}
|
1726
|
+
class RawLogo extends createBaseClass({ componentName: componentName$8, baseSelector: ':host > div' }) {
|
1599
1727
|
constructor() {
|
1600
1728
|
super();
|
1601
|
-
|
1602
|
-
|
1729
|
+
|
1730
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1603
1731
|
<style>
|
1604
1732
|
${getStyle()}
|
1605
1733
|
</style>
|
1606
1734
|
<div></div>`;
|
1607
|
-
|
1608
|
-
this.attachShadow({ mode: 'open' });
|
1609
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1610
|
-
|
1611
|
-
this.baseSelector = ':host > div';
|
1612
1735
|
}
|
1613
1736
|
}
|
1614
1737
|
|
@@ -1702,7 +1825,7 @@ overrides$4 = `
|
|
1702
1825
|
|
1703
1826
|
customElements.define(componentName$7, NumberField);
|
1704
1827
|
|
1705
|
-
var BaseInputClass =
|
1828
|
+
var BaseInputClass = compose(focusMixin, inputValidationMixin, changeMixin)(HTMLElement); //todo: maybe we should use base class?
|
1706
1829
|
|
1707
1830
|
const focusElement = (ele) => {
|
1708
1831
|
ele?.focus();
|
@@ -1723,11 +1846,10 @@ const componentName$6 = getComponentName('passcode-internal');
|
|
1723
1846
|
class PasscodeInternal extends BaseInputClass {
|
1724
1847
|
static get observedAttributes() {
|
1725
1848
|
return [
|
1726
|
-
...BaseInputClass.observedAttributes,
|
1849
|
+
...(BaseInputClass.observedAttributes || []),
|
1727
1850
|
'disabled',
|
1728
1851
|
'bordered',
|
1729
1852
|
'size',
|
1730
|
-
'readonly'
|
1731
1853
|
];
|
1732
1854
|
}
|
1733
1855
|
|
@@ -1735,10 +1857,12 @@ class PasscodeInternal extends BaseInputClass {
|
|
1735
1857
|
return componentName$6;
|
1736
1858
|
}
|
1737
1859
|
|
1860
|
+
#boundHandleInvalid = this.#handleInvalid.bind(this)
|
1861
|
+
#boundHandleValid = this.#handleValid.bind(this)
|
1862
|
+
#boundHandleBlur = this.#handleBlur.bind(this)
|
1863
|
+
|
1738
1864
|
constructor() {
|
1739
1865
|
super();
|
1740
|
-
const template = document.createElement('template');
|
1741
|
-
|
1742
1866
|
const inputs = [...Array(this.digits).keys()].map((idx) => `
|
1743
1867
|
<descope-text-field
|
1744
1868
|
st-width="35px"
|
@@ -1748,14 +1872,12 @@ class PasscodeInternal extends BaseInputClass {
|
|
1748
1872
|
></descope-text-field>
|
1749
1873
|
`);
|
1750
1874
|
|
1751
|
-
|
1875
|
+
this.innerHTML = `
|
1752
1876
|
<div>
|
1753
1877
|
${inputs.join('')}
|
1754
1878
|
</div>
|
1755
1879
|
`;
|
1756
1880
|
|
1757
|
-
this.appendChild(template.content.cloneNode(true));
|
1758
|
-
|
1759
1881
|
this.baseSelector = ':host > div';
|
1760
1882
|
|
1761
1883
|
this.inputs = Array.from(this.querySelectorAll('descope-text-field'));
|
@@ -1783,15 +1905,13 @@ class PasscodeInternal extends BaseInputClass {
|
|
1783
1905
|
return `^$|^\\d{${this.digits},}$`
|
1784
1906
|
}
|
1785
1907
|
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
}
|
1791
|
-
});
|
1908
|
+
#handleInvalid() {
|
1909
|
+
if (this.hasAttribute('invalid')) {
|
1910
|
+
this.inputs.forEach(input => input.setAttribute('invalid', 'true'));
|
1911
|
+
}
|
1792
1912
|
}
|
1793
1913
|
|
1794
|
-
|
1914
|
+
#handleValid() {
|
1795
1915
|
this.inputs.forEach(input => input.removeAttribute('invalid'));
|
1796
1916
|
}
|
1797
1917
|
|
@@ -1807,17 +1927,25 @@ class PasscodeInternal extends BaseInputClass {
|
|
1807
1927
|
}
|
1808
1928
|
};
|
1809
1929
|
|
1810
|
-
|
1930
|
+
onFocus(){
|
1811
1931
|
this.inputs[0].focus();
|
1812
1932
|
}
|
1813
1933
|
|
1814
|
-
|
1815
|
-
super.connectedCallback();
|
1934
|
+
connectedCallback() {
|
1935
|
+
super.connectedCallback?.();
|
1816
1936
|
|
1817
1937
|
this.initInputs();
|
1818
1938
|
|
1819
|
-
this.addEventListener('invalid', this
|
1820
|
-
this.addEventListener('valid', this
|
1939
|
+
this.addEventListener('invalid', this.#boundHandleInvalid);
|
1940
|
+
this.addEventListener('valid', this.#boundHandleValid);
|
1941
|
+
this.addEventListener('blur', this.#boundHandleBlur);
|
1942
|
+
}
|
1943
|
+
|
1944
|
+
disconnectedCallback() {
|
1945
|
+
super.connectedCallback?.();
|
1946
|
+
this.removeEventListener('invalid', this.#boundHandleInvalid);
|
1947
|
+
this.removeEventListener('valid', this.#boundHandleValid);
|
1948
|
+
this.removeEventListener('blur', this.#boundHandleBlur);
|
1821
1949
|
}
|
1822
1950
|
|
1823
1951
|
getInputIdx(inputEle) {
|
@@ -1841,66 +1969,49 @@ class PasscodeInternal extends BaseInputClass {
|
|
1841
1969
|
currentInput.value = charArr[i] ?? '';
|
1842
1970
|
|
1843
1971
|
const nextInput = this.getNextInput(currentInput);
|
1972
|
+
|
1844
1973
|
if (nextInput === currentInput) break;
|
1845
1974
|
currentInput = nextInput;
|
1846
1975
|
}
|
1847
1976
|
|
1848
|
-
|
1977
|
+
focusElement(currentInput);
|
1849
1978
|
};
|
1850
1979
|
|
1851
|
-
handleBlur() {
|
1852
|
-
this
|
1980
|
+
#handleBlur() {
|
1981
|
+
this.#handleInvalid();
|
1853
1982
|
}
|
1854
1983
|
|
1855
1984
|
initInputs() {
|
1856
1985
|
this.inputs.forEach((input) => {
|
1857
|
-
|
1858
|
-
// in order to simulate blur on the input
|
1859
|
-
// we are checking if focus on one of the digits happened immediately after blur on another digit
|
1860
|
-
// if not, the component is no longer focused and we should simulate blur
|
1861
|
-
input.addEventListener('blur', (e) => {
|
1862
|
-
e.stopPropagation();
|
1863
|
-
const timerId = setTimeout(() => {
|
1864
|
-
this.dispatchBlur();
|
1865
|
-
});
|
1866
|
-
|
1867
|
-
this.inputs.forEach((ele) =>
|
1868
|
-
ele.addEventListener('focus', () => clearTimeout(timerId), { once: true })
|
1869
|
-
);
|
1870
|
-
});
|
1871
|
-
|
1872
1986
|
input.oninput = (e) => {
|
1873
|
-
e.stopPropagation();
|
1874
1987
|
const charArr = getSanitizedCharacters(input.value);
|
1875
1988
|
|
1876
|
-
if (!charArr.length)
|
1989
|
+
if (!charArr.length) {
|
1990
|
+
// if we got an invalid value we want to clear the input
|
1991
|
+
input.value = '';
|
1992
|
+
if (e.data === null) {
|
1993
|
+
// if the user deleted the char, we want to focus the prev digit
|
1994
|
+
focusElement(this.getPrevInput(input));
|
1995
|
+
}
|
1996
|
+
}
|
1877
1997
|
else this.fillDigits(charArr, input);
|
1878
|
-
|
1879
|
-
this.dispatchInput();
|
1880
1998
|
};
|
1881
1999
|
|
1882
2000
|
input.onkeydown = ({ key }) => {
|
2001
|
+
// when user deletes a digit, we want to focus the previous digit
|
1883
2002
|
if (key === 'Backspace') {
|
1884
|
-
|
1885
|
-
|
1886
|
-
// if the user deleted the digit we want to focus the previous digit
|
1887
|
-
const prevInput = this.getPrevInput(input);
|
1888
|
-
|
1889
|
-
!prevInput.hasAttribute('focused') && setTimeout(() => {
|
1890
|
-
focusElement(prevInput);
|
2003
|
+
setTimeout(() => {
|
2004
|
+
focusElement(this.getPrevInput(input));
|
1891
2005
|
});
|
1892
|
-
|
1893
|
-
this.dispatchInput();
|
1894
2006
|
} else if (key.match(/^(\d)$/g)) { // if input is a digit
|
1895
2007
|
input.value = ''; // we are clearing the previous value so we can override it with the new value
|
1896
2008
|
}
|
1897
|
-
|
1898
2009
|
};
|
1899
2010
|
});
|
1900
2011
|
}
|
1901
2012
|
|
1902
2013
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
1903
|
-
super.attributeChangedCallback(attrName, oldValue, newValue);
|
2014
|
+
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
1904
2015
|
|
1905
2016
|
if (oldValue !== newValue) {
|
1906
2017
|
if (PasscodeInternal.observedAttributes.includes(attrName) && !BaseInputClass.observedAttributes.includes(attrName)) {
|
@@ -1999,21 +2110,10 @@ const customMixin = (superclass) =>
|
|
1999
2110
|
|
2000
2111
|
this.proxyElement.appendChild(template.content.cloneNode(true));
|
2001
2112
|
|
2002
|
-
// we want to control when the element is out of focus
|
2003
|
-
// so the validations will be triggered blur event is dispatched from descope-passcode internal (and not every time focusing a digit)
|
2004
|
-
this.proxyElement._setFocused = () => { };
|
2005
|
-
|
2006
2113
|
this.inputElement = this.shadowRoot.querySelector(componentName$6);
|
2007
2114
|
|
2008
2115
|
forwardAttrs(this.shadowRoot.host, this.inputElement, { includeAttrs: ['required', 'pattern'] });
|
2009
2116
|
|
2010
|
-
// we want to trigger validation only when dispatching a blur event from the descope-passcode-internal
|
2011
|
-
this.inputElement.addEventListener('blur', (e) => {
|
2012
|
-
// we do not want native blur events, only the ones that we are sending
|
2013
|
-
if (!e.isTrusted){
|
2014
|
-
this.proxyElement.validate();
|
2015
|
-
}
|
2016
|
-
});
|
2017
2117
|
}
|
2018
2118
|
};
|
2019
2119
|
|
@@ -2050,6 +2150,10 @@ const Passcode = compose(
|
|
2050
2150
|
display: inline-block;
|
2051
2151
|
}
|
2052
2152
|
|
2153
|
+
:host([readonly]) descope-passcode-internal > div {
|
2154
|
+
pointer-events: none;
|
2155
|
+
}
|
2156
|
+
|
2053
2157
|
descope-passcode-internal {
|
2054
2158
|
-webkit-mask-image: none;
|
2055
2159
|
display: flex;
|