@descope/web-components-ui 1.0.331 → 1.0.332

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,44 @@ const customMixin$a = (superclass) =>
2674
2700
 
2675
2701
  this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
2676
2702
 
2677
- this.handleExternalInput();
2703
+ this.externalInput = this.handleExternalInput();
2704
+
2705
+ this.addEventListener('focus', () => {
2706
+ this.externalInput.focus();
2707
+ });
2678
2708
  }
2679
2709
 
2680
- handleExternalInput() {
2681
- // reset vaadin's checkValidity
2682
- this.baseElement.checkValidity = () => {};
2710
+ forwardInputValue(source, target) {
2711
+ // set internal sync events
2712
+ const valueDescriptor = Object.getOwnPropertyDescriptor(
2713
+ this.inputElement.constructor.prototype,
2714
+ 'value'
2715
+ );
2716
+
2717
+ Object.defineProperty(source, 'value', {
2718
+ ...valueDescriptor,
2719
+
2720
+ set(v) {
2721
+ valueDescriptor.set.call(this, v);
2722
+ // eslint-disable-next-line no-param-reassign
2723
+ target.value = v;
2724
+ },
2725
+ configurable: true,
2726
+ });
2727
+ }
2683
2728
 
2729
+ handleExternalInput() {
2684
2730
  // set safety attribute `external-input`
2685
2731
  this.setAttribute('external-input', 'true');
2686
2732
 
2687
2733
  // use original input element as reference
2688
2734
  const origInput = this.baseElement.querySelector('input');
2689
2735
 
2736
+ // to avoid focus loop between external-input and origInput
2737
+ // we set origInput's tabindex to -1
2738
+ // otherwise, shift-tab will never leave the component focus
2739
+ origInput.setAttribute('tabindex', '-1');
2740
+
2690
2741
  // create external slot
2691
2742
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
2692
2743
  // append external slot to base element
@@ -2700,42 +2751,41 @@ const customMixin$a = (superclass) =>
2700
2751
 
2701
2752
  // apply original input's styles to external input
2702
2753
  setTimeout(() => {
2703
- applyExternalInputStyles(origInput, externalInput);
2754
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
2704
2755
  });
2705
2756
 
2706
2757
  // set external input events
2707
2758
  this.handleExternalInputEvents(externalInput);
2708
2759
 
2709
- syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
2760
+ // 1Password catches the internal input, so we forward the value to the external input
2761
+ this.forwardInputValue(origInput, externalInput);
2710
2762
 
2711
- externalInput.addEventListener('input', (e) => {
2712
- if (!e.target.value) {
2713
- this.removeAttribute('has-value');
2714
- } else {
2715
- this.setAttribute('has-value', 'true');
2716
- }
2763
+ syncAttrs(origInput, externalInput, {
2764
+ includeAttrs: ['disabled', 'readonly', 'pattern'],
2717
2765
  });
2718
2766
 
2719
2767
  // append external input to component's DOM
2720
2768
  this.appendChild(externalInput);
2769
+
2770
+ return externalInput;
2721
2771
  }
2722
2772
 
2723
2773
  getAutocompleteType() {
2724
2774
  return this.getAttribute('autocomplete') || 'username';
2725
2775
  }
2726
2776
 
2727
- handleExternalInputEvents(inputEle) {
2777
+ handleExternalInputEvents(externalInput) {
2728
2778
  // sync value of insible input back to original input
2729
- inputEle.addEventListener('input', (e) => {
2779
+ externalInput.addEventListener('input', (e) => {
2730
2780
  this.value = e.target.value;
2731
2781
  });
2732
2782
 
2733
2783
  // sync `focused` attribute on host when focusing on external input
2734
- inputEle.addEventListener('focus', () => {
2784
+ externalInput.addEventListener('focus', () => {
2735
2785
  this.setAttribute('focused', 'true');
2736
2786
  });
2737
2787
 
2738
- inputEle.addEventListener('blur', () => {
2788
+ externalInput.addEventListener('blur', () => {
2739
2789
  this.removeAttribute('focused');
2740
2790
  });
2741
2791
  }
@@ -2746,7 +2796,7 @@ const EmailFieldClass = compose(
2746
2796
  mappings: textFieldMappings,
2747
2797
  }),
2748
2798
  draggableMixin,
2749
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
2799
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
2750
2800
  componentNameValidationMixin,
2751
2801
  customMixin$a
2752
2802
  )(
@@ -2773,6 +2823,14 @@ const EmailFieldClass = compose(
2773
2823
  vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
2774
2824
  opacity: 0;
2775
2825
  }
2826
+
2827
+ vaadin-email-field > input:not(:placeholder-shown) {
2828
+ opacity: 0;
2829
+ }
2830
+
2831
+ :host ::slotted(*) {
2832
+ -webkit-mask-image: none;
2833
+ }
2776
2834
  `,
2777
2835
  excludeAttrsSync: ['tabindex'],
2778
2836
  componentName: componentName$M,
@@ -3287,7 +3345,7 @@ const TextFieldClass = compose(
3287
3345
  mappings: textFieldMappings,
3288
3346
  }),
3289
3347
  draggableMixin,
3290
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3348
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
3291
3349
  componentNameValidationMixin,
3292
3350
  customMixin$9
3293
3351
  )(
@@ -3563,6 +3621,11 @@ const customMixin$7 = (superclass) =>
3563
3621
  // use original input element as reference
3564
3622
  const origInput = this.baseElement.querySelector('input');
3565
3623
 
3624
+ // to avoid focus loop between external-input and origInput
3625
+ // we set origInput's tabindex to -1
3626
+ // otherwise, shift-tab will never leave the component focus
3627
+ origInput.setAttribute('tabindex', '-1');
3628
+
3566
3629
  // create external slot
3567
3630
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
3568
3631
  // append external slot to base element
@@ -3579,13 +3642,7 @@ const customMixin$7 = (superclass) =>
3579
3642
 
3580
3643
  // apply original input's styles to external input
3581
3644
  setTimeout(() => {
3582
- applyExternalInputStyles(
3583
- origInput,
3584
- externalInput,
3585
- `
3586
- width: calc(100% - 3em) !important;
3587
- `
3588
- );
3645
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
3589
3646
  });
3590
3647
 
3591
3648
  // set external input events
@@ -3610,11 +3667,6 @@ const customMixin$7 = (superclass) =>
3610
3667
  }
3611
3668
  });
3612
3669
 
3613
- this.addEventListener('focus', (e) => {
3614
- e.preventDefault();
3615
- this.focus();
3616
- });
3617
-
3618
3670
  // append external input to component's DOM
3619
3671
  this.appendChild(externalInput);
3620
3672
  }
@@ -3686,6 +3738,10 @@ const customMixin$7 = (superclass) =>
3686
3738
  inputEle.addEventListener('focus', () => {
3687
3739
  this.setAttribute('focused', 'true');
3688
3740
  });
3741
+
3742
+ inputEle.addEventListener('blur', () => {
3743
+ this.removeAttribute('focused');
3744
+ });
3689
3745
  }
3690
3746
  };
3691
3747
 
@@ -3844,8 +3900,11 @@ const PasswordClass = compose(
3844
3900
 
3845
3901
  ::part(reveal-button) {
3846
3902
  align-self: center;
3847
- }
3848
-
3903
+ }
3904
+
3905
+ vaadin-password-field > input:not(:placeholder-shown) {
3906
+ opacity: 0;
3907
+ }
3849
3908
  `,
3850
3909
  excludeAttrsSync: ['tabindex'],
3851
3910
  componentName: componentName$D,