@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/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 propertyObserver = (src, target, property) => {
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[property] = v;
958
+ targetArr.forEach((target) => {
959
+ target[property] = v;
960
+ });
957
961
  },
958
962
  get() {
959
- return target[property];
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
- propertyObserver(this, this.inputElement, prop);
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
- const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) => {
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
- // set external input style (and lock it with `all: unset` and `!important` all around)
2651
- // eslint-disable-next-line no-param-reassign
2652
- targetInputEle.style = `
2653
- all: unset !important;
2654
- position: absolute !important;
2655
- background-color: transparent !important;
2656
- color: ${valueColor} !important;
2657
- height: ${height} !important;
2658
- left: ${paddingLeft} !important;
2659
- right: ${paddingRight} !important;
2660
- font-size: ${fontSize} !important;
2661
- font-family: ${fontFamily} !important;
2662
- letter-spacing: ${letterSpacing} !important;
2663
- caret-color: ${caretColor} !important;
2664
- ${customStyle || ''}
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.handleExternalInput();
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
- handleExternalInput() {
2681
- // reset vaadin's checkValidity
2682
- this.baseElement.checkValidity = () => {};
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
- syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
2768
+ // 1Password catches the internal input, so we forward the value to the external input
2769
+ this.forwardInputValue(origInput, externalInput);
2710
2770
 
2711
- externalInput.addEventListener('input', (e) => {
2712
- if (!e.target.value) {
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(inputEle) {
2785
+ handleExternalInputEvents(externalInput) {
2728
2786
  // sync value of insible input back to original input
2729
- inputEle.addEventListener('input', (e) => {
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
- inputEle.addEventListener('focus', () => {
2792
+ externalInput.addEventListener('focus', () => {
2735
2793
  this.setAttribute('focused', 'true');
2736
2794
  });
2737
2795
 
2738
- inputEle.addEventListener('blur', () => {
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,