@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.
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +510 -395
- 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-combo-box/ComboBox.js +18 -4
- 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/portalMixin.js +11 -7
- package/src/mixins/proxyInputMixin.js +50 -45
- package/src/theme/components/comboBox.js +2 -9
- 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.hasAttribute('readonly') && 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,10 +855,168 @@ const componentNameValidationMixin = (superclass) =>
|
|
879
855
|
}
|
880
856
|
};
|
881
857
|
|
882
|
-
const
|
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
|
+
];
|
883
889
|
|
884
|
-
const
|
885
|
-
|
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
|
+
|
1012
|
+
// this is needed because we might generate the same css vars names
|
1013
|
+
// e.g. "overlayColor" attribute in style mixin's mapping,
|
1014
|
+
// will generate the same var as "color" attribute in portals's mapping
|
1015
|
+
// when the portal name is "overlay".
|
1016
|
+
// because of that, we are adding this separator that is also used as a differentiator
|
1017
|
+
const DISPLAY_NAME_SEPARATOR = '_';
|
1018
|
+
|
1019
|
+
const sanitizeSelector = (selector) => selector.replace(/[^\w\s]/gi, '');
|
886
1020
|
|
887
1021
|
const getDomNode = (maybeDomNode) => maybeDomNode.host || maybeDomNode;
|
888
1022
|
|
@@ -897,7 +1031,7 @@ const portalMixin = ({ name, selector, mappings = {} }) => (superclass) => {
|
|
897
1031
|
static get cssVarList() {
|
898
1032
|
return {
|
899
1033
|
...BaseClass.cssVarList,
|
900
|
-
|
1034
|
+
[eleDisplayName]: createCssVarsList(kebabCaseJoin(superclass.componentName, DISPLAY_NAME_SEPARATOR + eleDisplayName), mappings)
|
901
1035
|
};
|
902
1036
|
}
|
903
1037
|
|
@@ -907,14 +1041,14 @@ const portalMixin = ({ name, selector, mappings = {} }) => (superclass) => {
|
|
907
1041
|
// we cannot use "this" before calling "super"
|
908
1042
|
const getRootElement = (that) => {
|
909
1043
|
const baseEle = that.shadowRoot.querySelector(that.baseSelector);
|
910
|
-
const portal = baseEle.shadowRoot.querySelector(selector);
|
1044
|
+
const portal = selector ? baseEle.shadowRoot.querySelector(selector) : baseEle;
|
911
1045
|
|
912
1046
|
return portal.shadowRoot || portal
|
913
1047
|
};
|
914
1048
|
|
915
1049
|
super({
|
916
1050
|
getRootElement,
|
917
|
-
componentNameSuffix: eleDisplayName,
|
1051
|
+
componentNameSuffix: DISPLAY_NAME_SEPARATOR + eleDisplayName,
|
918
1052
|
themeSection: PORTAL_THEME_PREFIX + eleDisplayName,
|
919
1053
|
baseSelector: ':host'
|
920
1054
|
});
|
@@ -936,6 +1070,52 @@ const portalMixin = ({ name, selector, mappings = {} }) => (superclass) => {
|
|
936
1070
|
}
|
937
1071
|
};
|
938
1072
|
|
1073
|
+
const changeMixin = (superclass) => class ChangeMixinClass extends superclass {
|
1074
|
+
|
1075
|
+
#boundedHandleChange
|
1076
|
+
#boundedHandleBlur
|
1077
|
+
|
1078
|
+
#removeChangeListener
|
1079
|
+
#removeBlurListener
|
1080
|
+
|
1081
|
+
#dispatchChange = createDispatchEvent.bind(this, 'change')
|
1082
|
+
|
1083
|
+
constructor() {
|
1084
|
+
super();
|
1085
|
+
|
1086
|
+
this.#boundedHandleChange = this.#handleChange.bind(this);
|
1087
|
+
this.#boundedHandleBlur = this.#handleBlur.bind(this);
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
#handleChange(e) {
|
1091
|
+
// we want to listen only to browser events
|
1092
|
+
// and not to events we are dispatching
|
1093
|
+
if (e.isTrusted) {
|
1094
|
+
// we want to control the change events that dispatched by the component
|
1095
|
+
// so we are stopping propagation and handling it in handleBlur
|
1096
|
+
e.stopPropagation();
|
1097
|
+
}
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
#handleBlur() {
|
1101
|
+
// on blur, we want to dispatch a change event
|
1102
|
+
this.#dispatchChange();
|
1103
|
+
}
|
1104
|
+
|
1105
|
+
connectedCallback() {
|
1106
|
+
super.connectedCallback?.();
|
1107
|
+
|
1108
|
+
this.#removeChangeListener = addEventListener.bind();
|
1109
|
+
this.addEventListener('change', this.#boundedHandleChange, true);
|
1110
|
+
this.addEventListener('blur', this.#boundedHandleBlur);
|
1111
|
+
}
|
1112
|
+
|
1113
|
+
disconnectedCallback() {
|
1114
|
+
this.removeEventListener('change', this.#boundedHandleChange);
|
1115
|
+
this.removeEventListener('blur', this.#boundedHandleBlur);
|
1116
|
+
}
|
1117
|
+
};
|
1118
|
+
|
939
1119
|
const componentName$i = getComponentName('button');
|
940
1120
|
|
941
1121
|
const editorOverrides = `vaadin-button::part(label) { pointer-events: none; }`;
|
@@ -1063,41 +1243,36 @@ customElements.define(componentName$h, Checkbox);
|
|
1063
1243
|
|
1064
1244
|
const componentName$g = getComponentName('loader-linear');
|
1065
1245
|
|
1066
|
-
class RawLoaderLinear extends
|
1246
|
+
class RawLoaderLinear extends createBaseClass({ componentName: componentName$g, baseSelector: ':host > div' }) {
|
1067
1247
|
static get componentName() {
|
1068
1248
|
return componentName$g;
|
1069
1249
|
}
|
1070
1250
|
constructor() {
|
1071
1251
|
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
|
-
|
1090
|
-
:host > div {
|
1091
|
-
width: 100%;
|
1092
|
-
}
|
1093
|
-
</style>
|
1094
|
-
<div></div>
|
1095
|
-
`;
|
1096
1252
|
|
1097
|
-
this.attachShadow({ mode: 'open' })
|
1098
|
-
|
1253
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1254
|
+
<style>
|
1255
|
+
@keyframes tilt {
|
1256
|
+
0% { transform: translateX(0); }
|
1257
|
+
50% { transform: translateX(400%); }
|
1258
|
+
}
|
1259
|
+
:host {
|
1260
|
+
position: relative;
|
1261
|
+
display: inline-block
|
1262
|
+
}
|
1263
|
+
div::after {
|
1264
|
+
content: '';
|
1265
|
+
animation-name: tilt;
|
1266
|
+
position: absolute;
|
1267
|
+
left: 0;
|
1268
|
+
}
|
1099
1269
|
|
1100
|
-
|
1270
|
+
:host > div {
|
1271
|
+
width: 100%;
|
1272
|
+
}
|
1273
|
+
</style>
|
1274
|
+
<div></div>
|
1275
|
+
`;
|
1101
1276
|
}
|
1102
1277
|
}
|
1103
1278
|
|
@@ -1132,34 +1307,26 @@ customElements.define(componentName$g, LoaderLinear);
|
|
1132
1307
|
|
1133
1308
|
const componentName$f = getComponentName('loader-radial');
|
1134
1309
|
|
1135
|
-
class RawLoaderRadial extends
|
1136
|
-
static get componentName() {
|
1137
|
-
return componentName$f;
|
1138
|
-
}
|
1310
|
+
class RawLoaderRadial extends createBaseClass({ componentName: componentName$f, baseSelector: ':host > div' }) {
|
1139
1311
|
constructor() {
|
1140
1312
|
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
1313
|
|
1159
|
-
this.attachShadow({ mode: 'open' })
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1314
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1315
|
+
<style>
|
1316
|
+
@keyframes spin {
|
1317
|
+
0% { transform: rotate(0deg); }
|
1318
|
+
100% { transform: rotate(360deg); }
|
1319
|
+
}
|
1320
|
+
:host {
|
1321
|
+
position: relative;
|
1322
|
+
display: inline-flex;
|
1323
|
+
}
|
1324
|
+
:host > div {
|
1325
|
+
animation-name: spin;
|
1326
|
+
}
|
1327
|
+
</style>
|
1328
|
+
<div></div>
|
1329
|
+
`;
|
1163
1330
|
}
|
1164
1331
|
}
|
1165
1332
|
|
@@ -1190,33 +1357,25 @@ customElements.define(componentName$f, LoaderRadial);
|
|
1190
1357
|
|
1191
1358
|
const componentName$e = getComponentName('container');
|
1192
1359
|
|
1193
|
-
class RawContainer extends
|
1194
|
-
static get componentName() {
|
1195
|
-
return componentName$e;
|
1196
|
-
}
|
1360
|
+
class RawContainer extends createBaseClass({componentName: componentName$e, baseSelector: ':host > slot'}) {
|
1197
1361
|
constructor() {
|
1198
1362
|
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
|
-
|
1216
|
-
this.attachShadow({ mode: 'open' });
|
1217
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1218
1363
|
|
1219
|
-
this.
|
1364
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1365
|
+
<style>
|
1366
|
+
:host > slot {
|
1367
|
+
box-sizing: border-box;
|
1368
|
+
width: 100%;
|
1369
|
+
height: 100%;
|
1370
|
+
display: flex;
|
1371
|
+
overflow: auto;
|
1372
|
+
}
|
1373
|
+
:host {
|
1374
|
+
display: inline-block;
|
1375
|
+
}
|
1376
|
+
</style>
|
1377
|
+
<slot></slot>
|
1378
|
+
`;
|
1220
1379
|
}
|
1221
1380
|
}
|
1222
1381
|
|
@@ -1273,51 +1432,43 @@ const DatePicker = compose(
|
|
1273
1432
|
customElements.define(componentName$d, DatePicker);
|
1274
1433
|
|
1275
1434
|
const componentName$c = getComponentName('divider');
|
1276
|
-
class RawDivider extends
|
1277
|
-
static get componentName() {
|
1278
|
-
return componentName$c;
|
1279
|
-
}
|
1435
|
+
class RawDivider extends createBaseClass({ componentName: componentName$c, baseSelector: ':host > div' }) {
|
1280
1436
|
constructor() {
|
1281
1437
|
super();
|
1282
1438
|
|
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
|
-
}
|
1439
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1440
|
+
<style>
|
1441
|
+
:host > div {
|
1442
|
+
display: flex;
|
1443
|
+
height: 100%;
|
1444
|
+
width: 100%;
|
1445
|
+
}
|
1446
|
+
:host > div::before,
|
1447
|
+
:host > div::after {
|
1448
|
+
content: '';
|
1449
|
+
flex-grow: 1;
|
1450
|
+
}
|
1301
1451
|
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1452
|
+
descope-text {
|
1453
|
+
flex-grow: 0;
|
1454
|
+
flex-shrink: 0;
|
1455
|
+
}
|
1305
1456
|
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1457
|
+
:host(:empty) descope-text {
|
1458
|
+
display: none;
|
1459
|
+
}
|
1309
1460
|
|
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));
|
1461
|
+
:host([vertical="true"]) div {
|
1462
|
+
width: fit-content;
|
1463
|
+
}
|
1319
1464
|
|
1320
|
-
|
1465
|
+
</style>
|
1466
|
+
<div>
|
1467
|
+
<descope-text>
|
1468
|
+
<slot></slot>
|
1469
|
+
</descope-text>
|
1470
|
+
</div>
|
1471
|
+
`;
|
1321
1472
|
|
1322
1473
|
this.textComponent = this.shadowRoot.querySelector('descope-text');
|
1323
1474
|
|
@@ -1345,7 +1496,7 @@ const Divider = compose(
|
|
1345
1496
|
alignItems: root,
|
1346
1497
|
alignSelf: root,
|
1347
1498
|
flexDirection: root,
|
1348
|
-
textPadding: {...text$2, property: 'padding'},
|
1499
|
+
textPadding: { ...text$2, property: 'padding' },
|
1349
1500
|
width: host$1,
|
1350
1501
|
padding: host$1,
|
1351
1502
|
backgroundColor: [before, after],
|
@@ -1361,14 +1512,11 @@ const Divider = compose(
|
|
1361
1512
|
|
1362
1513
|
const componentName$b = getComponentName('text');
|
1363
1514
|
|
1364
|
-
class RawText extends
|
1365
|
-
static get componentName() {
|
1366
|
-
return componentName$b;
|
1367
|
-
}
|
1515
|
+
class RawText extends createBaseClass({ componentName: componentName$b, baseSelector: ':host > slot' }) {
|
1368
1516
|
constructor() {
|
1369
1517
|
super();
|
1370
|
-
|
1371
|
-
|
1518
|
+
|
1519
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1372
1520
|
<style>
|
1373
1521
|
:host {
|
1374
1522
|
display: inline-block;
|
@@ -1380,11 +1528,6 @@ class RawText extends DescopeBaseClass {
|
|
1380
1528
|
</style>
|
1381
1529
|
<slot></slot>
|
1382
1530
|
`;
|
1383
|
-
|
1384
|
-
this.attachShadow({ mode: 'open' });
|
1385
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1386
|
-
|
1387
|
-
this.baseSelector = ':host > slot';
|
1388
1531
|
}
|
1389
1532
|
}
|
1390
1533
|
|
@@ -1516,15 +1659,12 @@ overrides$5 = `
|
|
1516
1659
|
customElements.define(componentName$a, EmailField);
|
1517
1660
|
|
1518
1661
|
const componentName$9 = getComponentName('link');
|
1519
|
-
class RawLink extends
|
1520
|
-
static get componentName() {
|
1521
|
-
return componentName$9;
|
1522
|
-
}
|
1662
|
+
class RawLink extends createBaseClass({ componentName: componentName$9, baseSelector: ':host a' }) {
|
1523
1663
|
constructor() {
|
1524
1664
|
super();
|
1525
|
-
|
1665
|
+
document.createElement('template');
|
1526
1666
|
|
1527
|
-
|
1667
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1528
1668
|
<style>
|
1529
1669
|
:host {
|
1530
1670
|
display: inline-block;
|
@@ -1542,9 +1682,6 @@ class RawLink extends DescopeBaseClass {
|
|
1542
1682
|
</div>
|
1543
1683
|
`;
|
1544
1684
|
|
1545
|
-
this.attachShadow({ mode: 'open' });
|
1546
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1547
|
-
|
1548
1685
|
forwardAttrs(this, this.shadowRoot.querySelector('a'), {
|
1549
1686
|
includeAttrs: ['href', 'target', 'tooltip'],
|
1550
1687
|
mapAttrs: {
|
@@ -1555,24 +1692,23 @@ class RawLink extends DescopeBaseClass {
|
|
1555
1692
|
forwardAttrs(this, this.shadowRoot.querySelector('descope-text'), {
|
1556
1693
|
includeAttrs: ['mode', 'variant'],
|
1557
1694
|
});
|
1558
|
-
|
1559
|
-
this.baseSelector = ':host > div';
|
1560
1695
|
}
|
1561
1696
|
}
|
1562
1697
|
|
1563
1698
|
const selectors$2 = {
|
1564
1699
|
host: { selector: () => 'host' },
|
1565
|
-
anchor: {
|
1566
|
-
|
1700
|
+
anchor: {},
|
1701
|
+
wrapper: {selector: () => ':host > div'},
|
1702
|
+
text: { selector: () => Text.componentName }
|
1567
1703
|
};
|
1568
1704
|
|
1569
|
-
const { anchor, text: text$1, host } = selectors$2;
|
1705
|
+
const { anchor, text: text$1, host, wrapper } = selectors$2;
|
1570
1706
|
|
1571
1707
|
const Link = compose(
|
1572
1708
|
createStyleMixin({
|
1573
1709
|
mappings: {
|
1574
1710
|
width: host,
|
1575
|
-
textAlign:
|
1711
|
+
textAlign: wrapper,
|
1576
1712
|
color: [anchor, { ...text$1, property: Text.cssVarList.color }],
|
1577
1713
|
cursor: anchor,
|
1578
1714
|
borderBottomWidth: anchor,
|
@@ -1580,7 +1716,6 @@ const Link = compose(
|
|
1580
1716
|
borderBottomColor: anchor
|
1581
1717
|
},
|
1582
1718
|
}),
|
1583
|
-
hoverableMixin(anchor.selector),
|
1584
1719
|
draggableMixin,
|
1585
1720
|
componentNameValidationMixin
|
1586
1721
|
)(RawLink);
|
@@ -1592,23 +1727,15 @@ const componentName$8 = getComponentName('logo');
|
|
1592
1727
|
let style;
|
1593
1728
|
const getStyle = () => style;
|
1594
1729
|
|
1595
|
-
class RawLogo extends
|
1596
|
-
static get componentName() {
|
1597
|
-
return componentName$8;
|
1598
|
-
}
|
1730
|
+
class RawLogo extends createBaseClass({ componentName: componentName$8, baseSelector: ':host > div' }) {
|
1599
1731
|
constructor() {
|
1600
1732
|
super();
|
1601
|
-
|
1602
|
-
|
1733
|
+
|
1734
|
+
this.attachShadow({ mode: 'open' }).innerHTML = `
|
1603
1735
|
<style>
|
1604
1736
|
${getStyle()}
|
1605
1737
|
</style>
|
1606
1738
|
<div></div>`;
|
1607
|
-
|
1608
|
-
this.attachShadow({ mode: 'open' });
|
1609
|
-
this.shadowRoot.appendChild(template.content.cloneNode(true));
|
1610
|
-
|
1611
|
-
this.baseSelector = ':host > div';
|
1612
1739
|
}
|
1613
1740
|
}
|
1614
1741
|
|
@@ -1702,7 +1829,7 @@ overrides$4 = `
|
|
1702
1829
|
|
1703
1830
|
customElements.define(componentName$7, NumberField);
|
1704
1831
|
|
1705
|
-
var BaseInputClass =
|
1832
|
+
var BaseInputClass = compose(focusMixin, inputValidationMixin, changeMixin)(HTMLElement); //todo: maybe we should use base class?
|
1706
1833
|
|
1707
1834
|
const focusElement = (ele) => {
|
1708
1835
|
ele?.focus();
|
@@ -1723,11 +1850,10 @@ const componentName$6 = getComponentName('passcode-internal');
|
|
1723
1850
|
class PasscodeInternal extends BaseInputClass {
|
1724
1851
|
static get observedAttributes() {
|
1725
1852
|
return [
|
1726
|
-
...BaseInputClass.observedAttributes,
|
1853
|
+
...(BaseInputClass.observedAttributes || []),
|
1727
1854
|
'disabled',
|
1728
1855
|
'bordered',
|
1729
1856
|
'size',
|
1730
|
-
'readonly'
|
1731
1857
|
];
|
1732
1858
|
}
|
1733
1859
|
|
@@ -1735,10 +1861,12 @@ class PasscodeInternal extends BaseInputClass {
|
|
1735
1861
|
return componentName$6;
|
1736
1862
|
}
|
1737
1863
|
|
1864
|
+
#boundHandleInvalid = this.#handleInvalid.bind(this)
|
1865
|
+
#boundHandleValid = this.#handleValid.bind(this)
|
1866
|
+
#boundHandleBlur = this.#handleBlur.bind(this)
|
1867
|
+
|
1738
1868
|
constructor() {
|
1739
1869
|
super();
|
1740
|
-
const template = document.createElement('template');
|
1741
|
-
|
1742
1870
|
const inputs = [...Array(this.digits).keys()].map((idx) => `
|
1743
1871
|
<descope-text-field
|
1744
1872
|
st-width="35px"
|
@@ -1748,14 +1876,12 @@ class PasscodeInternal extends BaseInputClass {
|
|
1748
1876
|
></descope-text-field>
|
1749
1877
|
`);
|
1750
1878
|
|
1751
|
-
|
1879
|
+
this.innerHTML = `
|
1752
1880
|
<div>
|
1753
1881
|
${inputs.join('')}
|
1754
1882
|
</div>
|
1755
1883
|
`;
|
1756
1884
|
|
1757
|
-
this.appendChild(template.content.cloneNode(true));
|
1758
|
-
|
1759
1885
|
this.baseSelector = ':host > div';
|
1760
1886
|
|
1761
1887
|
this.inputs = Array.from(this.querySelectorAll('descope-text-field'));
|
@@ -1783,15 +1909,13 @@ class PasscodeInternal extends BaseInputClass {
|
|
1783
1909
|
return `^$|^\\d{${this.digits},}$`
|
1784
1910
|
}
|
1785
1911
|
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
}
|
1791
|
-
});
|
1912
|
+
#handleInvalid() {
|
1913
|
+
if (this.hasAttribute('invalid')) {
|
1914
|
+
this.inputs.forEach(input => input.setAttribute('invalid', 'true'));
|
1915
|
+
}
|
1792
1916
|
}
|
1793
1917
|
|
1794
|
-
|
1918
|
+
#handleValid() {
|
1795
1919
|
this.inputs.forEach(input => input.removeAttribute('invalid'));
|
1796
1920
|
}
|
1797
1921
|
|
@@ -1807,17 +1931,25 @@ class PasscodeInternal extends BaseInputClass {
|
|
1807
1931
|
}
|
1808
1932
|
};
|
1809
1933
|
|
1810
|
-
|
1934
|
+
onFocus(){
|
1811
1935
|
this.inputs[0].focus();
|
1812
1936
|
}
|
1813
1937
|
|
1814
|
-
|
1815
|
-
super.connectedCallback();
|
1938
|
+
connectedCallback() {
|
1939
|
+
super.connectedCallback?.();
|
1816
1940
|
|
1817
1941
|
this.initInputs();
|
1818
1942
|
|
1819
|
-
this.addEventListener('invalid', this
|
1820
|
-
this.addEventListener('valid', this
|
1943
|
+
this.addEventListener('invalid', this.#boundHandleInvalid);
|
1944
|
+
this.addEventListener('valid', this.#boundHandleValid);
|
1945
|
+
this.addEventListener('blur', this.#boundHandleBlur);
|
1946
|
+
}
|
1947
|
+
|
1948
|
+
disconnectedCallback() {
|
1949
|
+
super.connectedCallback?.();
|
1950
|
+
this.removeEventListener('invalid', this.#boundHandleInvalid);
|
1951
|
+
this.removeEventListener('valid', this.#boundHandleValid);
|
1952
|
+
this.removeEventListener('blur', this.#boundHandleBlur);
|
1821
1953
|
}
|
1822
1954
|
|
1823
1955
|
getInputIdx(inputEle) {
|
@@ -1841,66 +1973,49 @@ class PasscodeInternal extends BaseInputClass {
|
|
1841
1973
|
currentInput.value = charArr[i] ?? '';
|
1842
1974
|
|
1843
1975
|
const nextInput = this.getNextInput(currentInput);
|
1976
|
+
|
1844
1977
|
if (nextInput === currentInput) break;
|
1845
1978
|
currentInput = nextInput;
|
1846
1979
|
}
|
1847
1980
|
|
1848
|
-
|
1981
|
+
focusElement(currentInput);
|
1849
1982
|
};
|
1850
1983
|
|
1851
|
-
handleBlur() {
|
1852
|
-
this
|
1984
|
+
#handleBlur() {
|
1985
|
+
this.#handleInvalid();
|
1853
1986
|
}
|
1854
1987
|
|
1855
1988
|
initInputs() {
|
1856
1989
|
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
1990
|
input.oninput = (e) => {
|
1873
|
-
e.stopPropagation();
|
1874
1991
|
const charArr = getSanitizedCharacters(input.value);
|
1875
1992
|
|
1876
|
-
if (!charArr.length)
|
1993
|
+
if (!charArr.length) {
|
1994
|
+
// if we got an invalid value we want to clear the input
|
1995
|
+
input.value = '';
|
1996
|
+
if (e.data === null) {
|
1997
|
+
// if the user deleted the char, we want to focus the prev digit
|
1998
|
+
focusElement(this.getPrevInput(input));
|
1999
|
+
}
|
2000
|
+
}
|
1877
2001
|
else this.fillDigits(charArr, input);
|
1878
|
-
|
1879
|
-
this.dispatchInput();
|
1880
2002
|
};
|
1881
2003
|
|
1882
2004
|
input.onkeydown = ({ key }) => {
|
2005
|
+
// when user deletes a digit, we want to focus the previous digit
|
1883
2006
|
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);
|
2007
|
+
setTimeout(() => {
|
2008
|
+
focusElement(this.getPrevInput(input));
|
1891
2009
|
});
|
1892
|
-
|
1893
|
-
this.dispatchInput();
|
1894
2010
|
} else if (key.match(/^(\d)$/g)) { // if input is a digit
|
1895
2011
|
input.value = ''; // we are clearing the previous value so we can override it with the new value
|
1896
2012
|
}
|
1897
|
-
|
1898
2013
|
};
|
1899
2014
|
});
|
1900
2015
|
}
|
1901
2016
|
|
1902
2017
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
1903
|
-
super.attributeChangedCallback(attrName, oldValue, newValue);
|
2018
|
+
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
1904
2019
|
|
1905
2020
|
if (oldValue !== newValue) {
|
1906
2021
|
if (PasscodeInternal.observedAttributes.includes(attrName) && !BaseInputClass.observedAttributes.includes(attrName)) {
|
@@ -1999,21 +2114,10 @@ const customMixin = (superclass) =>
|
|
1999
2114
|
|
2000
2115
|
this.proxyElement.appendChild(template.content.cloneNode(true));
|
2001
2116
|
|
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
2117
|
this.inputElement = this.shadowRoot.querySelector(componentName$6);
|
2007
2118
|
|
2008
2119
|
forwardAttrs(this.shadowRoot.host, this.inputElement, { includeAttrs: ['required', 'pattern'] });
|
2009
2120
|
|
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
2121
|
}
|
2018
2122
|
};
|
2019
2123
|
|
@@ -2050,6 +2154,10 @@ const Passcode = compose(
|
|
2050
2154
|
display: inline-block;
|
2051
2155
|
}
|
2052
2156
|
|
2157
|
+
:host([readonly]) descope-passcode-internal > div {
|
2158
|
+
pointer-events: none;
|
2159
|
+
}
|
2160
|
+
|
2053
2161
|
descope-passcode-internal {
|
2054
2162
|
-webkit-mask-image: none;
|
2055
2163
|
display: flex;
|
@@ -3231,9 +3339,21 @@ const ComboBoxMixin = (superclass) => class ComboBoxMixinClass extends superclas
|
|
3231
3339
|
};
|
3232
3340
|
}
|
3233
3341
|
|
3342
|
+
// the default vaadin behavior is to attach the overlay to the body when opened
|
3343
|
+
// we do not want that because it's difficult to style the overlay in this way
|
3344
|
+
// so we override it to open inside the shadow DOM
|
3345
|
+
#overrideOverlaySettings() {
|
3346
|
+
const overlay = this.baseElement.shadowRoot.querySelector('vaadin-combo-box-overlay');
|
3347
|
+
|
3348
|
+
overlay._attachOverlay = function () { this.bringToFront(); };
|
3349
|
+
overlay._detachOverlay = function () { };
|
3350
|
+
overlay._enterModalState = function () { };
|
3351
|
+
}
|
3352
|
+
|
3234
3353
|
connectedCallback() {
|
3235
3354
|
super.connectedCallback?.();
|
3236
3355
|
|
3356
|
+
this.#overrideOverlaySettings();
|
3237
3357
|
observeChildren(this, this.#onChildrenChange.bind(this));
|
3238
3358
|
}
|
3239
3359
|
};
|
@@ -3251,15 +3371,17 @@ const ComboBox = compose(
|
|
3251
3371
|
borderWidth: input,
|
3252
3372
|
cursor: toggle,
|
3253
3373
|
height: input,
|
3374
|
+
// overlayBackground: { property: () => ComboBox.cssVarList.overlay.backgroundColor },
|
3375
|
+
// overlayBorder: { property: () => ComboBox.cssVarList.overlay.border }
|
3254
3376
|
}
|
3255
3377
|
}),
|
3256
3378
|
draggableMixin,
|
3257
3379
|
portalMixin({
|
3258
3380
|
name: 'overlay',
|
3259
|
-
selector: '
|
3381
|
+
selector: '',
|
3260
3382
|
mappings: {
|
3261
|
-
border: { selector:
|
3262
|
-
backgroundColor: {},
|
3383
|
+
// border: { selector: 'vaadin-combo-box-scroller' },
|
3384
|
+
// backgroundColor: { selector: 'vaadin-combo-box-item' },
|
3263
3385
|
}
|
3264
3386
|
}),
|
3265
3387
|
proxyInputMixin,
|
@@ -3296,15 +3418,8 @@ const comboBox = {
|
|
3296
3418
|
[vars.borderWidth]: '0',
|
3297
3419
|
[vars.cursor]: 'pointer',
|
3298
3420
|
[vars.padding]: '0',
|
3299
|
-
|
3300
|
-
'
|
3301
|
-
[vars.overlayBackgroundColor] : 'red',
|
3302
|
-
[vars.overlayBorder]: '3px solid blue',
|
3303
|
-
|
3304
|
-
_hover: {
|
3305
|
-
[vars.overlayBackgroundColor] : 'blue',
|
3306
|
-
}
|
3307
|
-
}
|
3421
|
+
// [vars.overlayBackground]: 'blue',
|
3422
|
+
// [vars.overlayBorder]: '3px solid red',
|
3308
3423
|
};
|
3309
3424
|
|
3310
3425
|
var components = {
|