@descope/web-components-ui 1.0.331 → 1.0.333
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/cjs/index.cjs.js +123 -56
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +123 -56
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/4392.js +1 -1
- package/dist/umd/4978.js +1 -1
- package/dist/umd/DescopeDev.js +1 -1
- package/dist/umd/descope-email-field-index-js.js +4 -4
- package/dist/umd/descope-new-password-descope-new-password-internal-index-js.js +1 -1
- package/dist/umd/descope-new-password-index-js.js +1 -1
- package/dist/umd/descope-passcode-index-js.js +1 -1
- package/dist/umd/descope-password-index-js.js +1 -1
- package/dist/umd/descope-text-field-index-js.js +1 -1
- package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
- package/package.json +1 -1
- package/src/components/descope-email-field/EmailFieldClass.js +57 -17
- package/src/components/descope-password/PasswordClass.js +15 -14
- package/src/components/descope-text-field/TextFieldClass.js +1 -1
- package/src/helpers/externalInputs.js +32 -18
- package/src/mixins/proxyInputMixin.js +16 -4
package/dist/index.esm.js
CHANGED
@@ -152,7 +152,7 @@ const forwardAttrs = (source, dest, options = {}) => {
|
|
152
152
|
observeAttributes(source, createSyncAttrsCb(source, dest, options.mapAttrs), options);
|
153
153
|
};
|
154
154
|
|
155
|
-
const forwardProps = (src, target, props = []) => {
|
155
|
+
const forwardProps$1 = (src, target, props = []) => {
|
156
156
|
if (!props.length) return;
|
157
157
|
|
158
158
|
const config = props.reduce(
|
@@ -744,7 +744,7 @@ const createProxy = ({
|
|
744
744
|
});
|
745
745
|
|
746
746
|
// this is needed for components that uses props, such as combo box
|
747
|
-
forwardProps(this.baseElement, this, includeForwardProps);
|
747
|
+
forwardProps$1(this.baseElement, this, includeForwardProps);
|
748
748
|
|
749
749
|
syncAttrs(this.baseElement, this, {
|
750
750
|
excludeAttrs: excludeAttrsSync,
|
@@ -950,13 +950,17 @@ const inputValidationMixin = (superclass) =>
|
|
950
950
|
|
951
951
|
const errorAttrs = ['invalid', 'required'];
|
952
952
|
|
953
|
-
const
|
953
|
+
const forwardProps = (src, targets, property) => {
|
954
|
+
const targetArr = Array.isArray(targets) ? targets : [targets];
|
955
|
+
|
954
956
|
Object.defineProperty(src, property, {
|
955
957
|
set(v) {
|
956
|
-
target
|
958
|
+
targetArr.forEach((target) => {
|
959
|
+
target[property] = v;
|
960
|
+
});
|
957
961
|
},
|
958
962
|
get() {
|
959
|
-
return
|
963
|
+
return targets[0][property];
|
960
964
|
},
|
961
965
|
configurable: true,
|
962
966
|
});
|
@@ -980,6 +984,10 @@ const getNestedInput = (ele) => {
|
|
980
984
|
const proxyInputMixin =
|
981
985
|
({
|
982
986
|
proxyProps = [],
|
987
|
+
// useProxyTargets flag allows to forwardProps to other targets, other than
|
988
|
+
// `this.inputElement`. It's to be used within `external-input` components,
|
989
|
+
// if needed
|
990
|
+
useProxyTargets = false,
|
983
991
|
// allows us to set the event that should trigger validation
|
984
992
|
// it can be either a string or an array of strings (for multiple events)
|
985
993
|
inputEvent = 'input',
|
@@ -1106,7 +1114,11 @@ const proxyInputMixin =
|
|
1106
1114
|
|
1107
1115
|
// sync properties
|
1108
1116
|
proxyProps.forEach((prop) => {
|
1109
|
-
|
1117
|
+
const externalInput = this.querySelector('input[slot="external-input"]') || null;
|
1118
|
+
const proxyTargets = useProxyTargets
|
1119
|
+
? [this.baseElement, externalInput].filter(Boolean)
|
1120
|
+
: [];
|
1121
|
+
forwardProps(this, [this.inputElement, ...proxyTargets], prop);
|
1110
1122
|
});
|
1111
1123
|
|
1112
1124
|
this.setSelectionRange = this.inputElement.setSelectionRange?.bind(this.inputElement);
|
@@ -1687,7 +1699,7 @@ const booleanFieldMixin = (superclass) =>
|
|
1687
1699
|
],
|
1688
1700
|
});
|
1689
1701
|
|
1690
|
-
forwardProps(this.inputElement, this, ['checked']);
|
1702
|
+
forwardProps$1(this.inputElement, this, ['checked']);
|
1691
1703
|
syncAttrs(this, this.inputElement, { includeAttrs: ['checked'] });
|
1692
1704
|
}
|
1693
1705
|
};
|
@@ -2636,8 +2648,13 @@ const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
|
|
2636
2648
|
return inputEle;
|
2637
2649
|
};
|
2638
2650
|
|
2639
|
-
|
2651
|
+
// We apply the original input's style to the external-input.
|
2652
|
+
// Eventually, the user should interact directly with the external input.
|
2653
|
+
// We keep the original input
|
2654
|
+
const applyExternalInputStyles = (sourceInputEle, targetInputEle, labelType) => {
|
2640
2655
|
const computedStyle = getComputedStyle(sourceInputEle);
|
2656
|
+
|
2657
|
+
// Get minimal set of computed theme properties to set on external input
|
2641
2658
|
const height = computedStyle.getPropertyValue('height');
|
2642
2659
|
const paddingLeft = computedStyle.getPropertyValue('padding-left');
|
2643
2660
|
const paddingRight = computedStyle.getPropertyValue('padding-right');
|
@@ -2645,24 +2662,33 @@ const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) =
|
|
2645
2662
|
const fontFamily = computedStyle.getPropertyValue('font-family');
|
2646
2663
|
const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
|
2647
2664
|
const caretColor = computedStyle.getPropertyValue('caret-color');
|
2665
|
+
|
2648
2666
|
const valueColor = getValueColor(sourceInputEle, computedStyle);
|
2649
2667
|
|
2650
|
-
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2655
|
-
|
2656
|
-
|
2657
|
-
|
2658
|
-
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2668
|
+
const commonThemeStyles = [
|
2669
|
+
['all', 'unset'],
|
2670
|
+
['position', 'absolute'],
|
2671
|
+
['background-color', 'transparent'],
|
2672
|
+
['height', height],
|
2673
|
+
['left', paddingLeft],
|
2674
|
+
['right', paddingRight],
|
2675
|
+
['font-size', fontSize],
|
2676
|
+
['font-family', fontFamily],
|
2677
|
+
['letter-spacing', letterSpacing],
|
2678
|
+
['width', `calc(100% - ${paddingLeft} - ${paddingRight}`],
|
2679
|
+
['caret-color', caretColor], // this is for seeing caret when focusing on external input
|
2680
|
+
['color', valueColor],
|
2681
|
+
];
|
2682
|
+
|
2683
|
+
commonThemeStyles.forEach(([key, val]) =>
|
2684
|
+
targetInputEle.style.setProperty(key, val, 'important')
|
2685
|
+
);
|
2686
|
+
|
2687
|
+
// Handle floating label theme properties
|
2688
|
+
if (labelType === 'floating') {
|
2689
|
+
const marginBottom = computedStyle.getPropertyValue('margin-bottom');
|
2690
|
+
targetInputEle.style.setProperty('margin-bottom', marginBottom, 'important');
|
2691
|
+
}
|
2666
2692
|
};
|
2667
2693
|
|
2668
2694
|
const componentName$M = getComponentName('email-field');
|
@@ -2674,19 +2700,52 @@ const customMixin$a = (superclass) =>
|
|
2674
2700
|
|
2675
2701
|
this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
|
2676
2702
|
|
2677
|
-
this.
|
2703
|
+
if (!this.isNoExternalInput) {
|
2704
|
+
this.externalInput = this.handleExternalInput();
|
2705
|
+
|
2706
|
+
this.addEventListener('focus', () => {
|
2707
|
+
this.externalInput.focus();
|
2708
|
+
});
|
2709
|
+
} else {
|
2710
|
+
this.setAttribute('autocomplete', this.getAutocompleteType());
|
2711
|
+
}
|
2678
2712
|
}
|
2679
2713
|
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2714
|
+
get isNoExternalInput() {
|
2715
|
+
return this.getAttribute('no-external-input') === 'true';
|
2716
|
+
}
|
2717
|
+
|
2718
|
+
forwardInputValue(source, target) {
|
2719
|
+
// set internal sync events
|
2720
|
+
const valueDescriptor = Object.getOwnPropertyDescriptor(
|
2721
|
+
this.inputElement.constructor.prototype,
|
2722
|
+
'value'
|
2723
|
+
);
|
2724
|
+
|
2725
|
+
Object.defineProperty(source, 'value', {
|
2726
|
+
...valueDescriptor,
|
2727
|
+
|
2728
|
+
set(v) {
|
2729
|
+
valueDescriptor.set.call(this, v);
|
2730
|
+
// eslint-disable-next-line no-param-reassign
|
2731
|
+
target.value = v;
|
2732
|
+
},
|
2733
|
+
configurable: true,
|
2734
|
+
});
|
2735
|
+
}
|
2683
2736
|
|
2737
|
+
handleExternalInput() {
|
2684
2738
|
// set safety attribute `external-input`
|
2685
2739
|
this.setAttribute('external-input', 'true');
|
2686
2740
|
|
2687
2741
|
// use original input element as reference
|
2688
2742
|
const origInput = this.baseElement.querySelector('input');
|
2689
2743
|
|
2744
|
+
// to avoid focus loop between external-input and origInput
|
2745
|
+
// we set origInput's tabindex to -1
|
2746
|
+
// otherwise, shift-tab will never leave the component focus
|
2747
|
+
origInput.setAttribute('tabindex', '-1');
|
2748
|
+
|
2690
2749
|
// create external slot
|
2691
2750
|
const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
|
2692
2751
|
// append external slot to base element
|
@@ -2700,42 +2759,41 @@ const customMixin$a = (superclass) =>
|
|
2700
2759
|
|
2701
2760
|
// apply original input's styles to external input
|
2702
2761
|
setTimeout(() => {
|
2703
|
-
applyExternalInputStyles(origInput, externalInput);
|
2762
|
+
applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
|
2704
2763
|
});
|
2705
2764
|
|
2706
2765
|
// set external input events
|
2707
2766
|
this.handleExternalInputEvents(externalInput);
|
2708
2767
|
|
2709
|
-
|
2768
|
+
// 1Password catches the internal input, so we forward the value to the external input
|
2769
|
+
this.forwardInputValue(origInput, externalInput);
|
2710
2770
|
|
2711
|
-
|
2712
|
-
|
2713
|
-
this.removeAttribute('has-value');
|
2714
|
-
} else {
|
2715
|
-
this.setAttribute('has-value', 'true');
|
2716
|
-
}
|
2771
|
+
syncAttrs(origInput, externalInput, {
|
2772
|
+
includeAttrs: ['disabled', 'readonly', 'pattern'],
|
2717
2773
|
});
|
2718
2774
|
|
2719
2775
|
// append external input to component's DOM
|
2720
2776
|
this.appendChild(externalInput);
|
2777
|
+
|
2778
|
+
return externalInput;
|
2721
2779
|
}
|
2722
2780
|
|
2723
2781
|
getAutocompleteType() {
|
2724
2782
|
return this.getAttribute('autocomplete') || 'username';
|
2725
2783
|
}
|
2726
2784
|
|
2727
|
-
handleExternalInputEvents(
|
2785
|
+
handleExternalInputEvents(externalInput) {
|
2728
2786
|
// sync value of insible input back to original input
|
2729
|
-
|
2787
|
+
externalInput.addEventListener('input', (e) => {
|
2730
2788
|
this.value = e.target.value;
|
2731
2789
|
});
|
2732
2790
|
|
2733
2791
|
// sync `focused` attribute on host when focusing on external input
|
2734
|
-
|
2792
|
+
externalInput.addEventListener('focus', () => {
|
2735
2793
|
this.setAttribute('focused', 'true');
|
2736
2794
|
});
|
2737
2795
|
|
2738
|
-
|
2796
|
+
externalInput.addEventListener('blur', () => {
|
2739
2797
|
this.removeAttribute('focused');
|
2740
2798
|
});
|
2741
2799
|
}
|
@@ -2746,7 +2804,7 @@ const EmailFieldClass = compose(
|
|
2746
2804
|
mappings: textFieldMappings,
|
2747
2805
|
}),
|
2748
2806
|
draggableMixin,
|
2749
|
-
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
|
2807
|
+
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
|
2750
2808
|
componentNameValidationMixin,
|
2751
2809
|
customMixin$a
|
2752
2810
|
)(
|
@@ -2773,6 +2831,14 @@ const EmailFieldClass = compose(
|
|
2773
2831
|
vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
|
2774
2832
|
opacity: 0;
|
2775
2833
|
}
|
2834
|
+
|
2835
|
+
vaadin-email-field:not([no-external-input="true"]) > input:not(:placeholder-shown) {
|
2836
|
+
opacity: 0;
|
2837
|
+
}
|
2838
|
+
|
2839
|
+
:host ::slotted(*) {
|
2840
|
+
-webkit-mask-image: none;
|
2841
|
+
}
|
2776
2842
|
`,
|
2777
2843
|
excludeAttrsSync: ['tabindex'],
|
2778
2844
|
componentName: componentName$M,
|
@@ -3287,7 +3353,7 @@ const TextFieldClass = compose(
|
|
3287
3353
|
mappings: textFieldMappings,
|
3288
3354
|
}),
|
3289
3355
|
draggableMixin,
|
3290
|
-
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
|
3356
|
+
composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
|
3291
3357
|
componentNameValidationMixin,
|
3292
3358
|
customMixin$9
|
3293
3359
|
)(
|
@@ -3563,6 +3629,11 @@ const customMixin$7 = (superclass) =>
|
|
3563
3629
|
// use original input element as reference
|
3564
3630
|
const origInput = this.baseElement.querySelector('input');
|
3565
3631
|
|
3632
|
+
// to avoid focus loop between external-input and origInput
|
3633
|
+
// we set origInput's tabindex to -1
|
3634
|
+
// otherwise, shift-tab will never leave the component focus
|
3635
|
+
origInput.setAttribute('tabindex', '-1');
|
3636
|
+
|
3566
3637
|
// create external slot
|
3567
3638
|
const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
|
3568
3639
|
// append external slot to base element
|
@@ -3579,13 +3650,7 @@ const customMixin$7 = (superclass) =>
|
|
3579
3650
|
|
3580
3651
|
// apply original input's styles to external input
|
3581
3652
|
setTimeout(() => {
|
3582
|
-
applyExternalInputStyles(
|
3583
|
-
origInput,
|
3584
|
-
externalInput,
|
3585
|
-
`
|
3586
|
-
width: calc(100% - 3em) !important;
|
3587
|
-
`
|
3588
|
-
);
|
3653
|
+
applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
|
3589
3654
|
});
|
3590
3655
|
|
3591
3656
|
// set external input events
|
@@ -3610,11 +3675,6 @@ const customMixin$7 = (superclass) =>
|
|
3610
3675
|
}
|
3611
3676
|
});
|
3612
3677
|
|
3613
|
-
this.addEventListener('focus', (e) => {
|
3614
|
-
e.preventDefault();
|
3615
|
-
this.focus();
|
3616
|
-
});
|
3617
|
-
|
3618
3678
|
// append external input to component's DOM
|
3619
3679
|
this.appendChild(externalInput);
|
3620
3680
|
}
|
@@ -3686,6 +3746,10 @@ const customMixin$7 = (superclass) =>
|
|
3686
3746
|
inputEle.addEventListener('focus', () => {
|
3687
3747
|
this.setAttribute('focused', 'true');
|
3688
3748
|
});
|
3749
|
+
|
3750
|
+
inputEle.addEventListener('blur', () => {
|
3751
|
+
this.removeAttribute('focused');
|
3752
|
+
});
|
3689
3753
|
}
|
3690
3754
|
};
|
3691
3755
|
|
@@ -3844,8 +3908,11 @@ const PasswordClass = compose(
|
|
3844
3908
|
|
3845
3909
|
::part(reveal-button) {
|
3846
3910
|
align-self: center;
|
3847
|
-
}
|
3848
|
-
|
3911
|
+
}
|
3912
|
+
|
3913
|
+
vaadin-password-field > input:not(:placeholder-shown) {
|
3914
|
+
opacity: 0;
|
3915
|
+
}
|
3849
3916
|
`,
|
3850
3917
|
excludeAttrsSync: ['tabindex'],
|
3851
3918
|
componentName: componentName$D,
|