@descope/web-components-ui 1.0.330 → 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,34 +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);
2762
+
2763
+ syncAttrs(origInput, externalInput, {
2764
+ includeAttrs: ['disabled', 'readonly', 'pattern'],
2765
+ });
2710
2766
 
2711
2767
  // append external input to component's DOM
2712
2768
  this.appendChild(externalInput);
2769
+
2770
+ return externalInput;
2713
2771
  }
2714
2772
 
2715
2773
  getAutocompleteType() {
2716
2774
  return this.getAttribute('autocomplete') || 'username';
2717
2775
  }
2718
2776
 
2719
- handleExternalInputEvents(inputEle) {
2777
+ handleExternalInputEvents(externalInput) {
2720
2778
  // sync value of insible input back to original input
2721
- inputEle.addEventListener('input', (e) => {
2779
+ externalInput.addEventListener('input', (e) => {
2722
2780
  this.value = e.target.value;
2723
2781
  });
2724
2782
 
2725
2783
  // sync `focused` attribute on host when focusing on external input
2726
- inputEle.addEventListener('focus', () => {
2784
+ externalInput.addEventListener('focus', () => {
2727
2785
  this.setAttribute('focused', 'true');
2728
2786
  });
2729
2787
 
2730
- inputEle.addEventListener('blur', () => {
2788
+ externalInput.addEventListener('blur', () => {
2731
2789
  this.removeAttribute('focused');
2732
2790
  });
2733
2791
  }
@@ -2738,7 +2796,7 @@ const EmailFieldClass = compose(
2738
2796
  mappings: textFieldMappings,
2739
2797
  }),
2740
2798
  draggableMixin,
2741
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
2799
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
2742
2800
  componentNameValidationMixin,
2743
2801
  customMixin$a
2744
2802
  )(
@@ -2765,8 +2823,13 @@ const EmailFieldClass = compose(
2765
2823
  vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
2766
2824
  opacity: 0;
2767
2825
  }
2768
- :host ::slotted(input) {
2769
- display: none !important;
2826
+
2827
+ vaadin-email-field > input:not(:placeholder-shown) {
2828
+ opacity: 0;
2829
+ }
2830
+
2831
+ :host ::slotted(*) {
2832
+ -webkit-mask-image: none;
2770
2833
  }
2771
2834
  `,
2772
2835
  excludeAttrsSync: ['tabindex'],
@@ -3282,7 +3345,7 @@ const TextFieldClass = compose(
3282
3345
  mappings: textFieldMappings,
3283
3346
  }),
3284
3347
  draggableMixin,
3285
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3348
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
3286
3349
  componentNameValidationMixin,
3287
3350
  customMixin$9
3288
3351
  )(
@@ -3558,6 +3621,11 @@ const customMixin$7 = (superclass) =>
3558
3621
  // use original input element as reference
3559
3622
  const origInput = this.baseElement.querySelector('input');
3560
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
+
3561
3629
  // create external slot
3562
3630
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
3563
3631
  // append external slot to base element
@@ -3574,13 +3642,7 @@ const customMixin$7 = (superclass) =>
3574
3642
 
3575
3643
  // apply original input's styles to external input
3576
3644
  setTimeout(() => {
3577
- applyExternalInputStyles(
3578
- origInput,
3579
- externalInput,
3580
- `
3581
- width: calc(100% - 3em) !important;
3582
- `
3583
- );
3645
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
3584
3646
  });
3585
3647
 
3586
3648
  // set external input events
@@ -3597,9 +3659,12 @@ const customMixin$7 = (superclass) =>
3597
3659
  }
3598
3660
  });
3599
3661
 
3600
- this.addEventListener('focus', (e) => {
3601
- e.preventDefault();
3602
- this.focus();
3662
+ externalInput.addEventListener('input', (e) => {
3663
+ if (!e.target.value) {
3664
+ this.removeAttribute('has-value');
3665
+ } else {
3666
+ this.setAttribute('has-value', 'true');
3667
+ }
3603
3668
  });
3604
3669
 
3605
3670
  // append external input to component's DOM
@@ -3673,6 +3738,10 @@ const customMixin$7 = (superclass) =>
3673
3738
  inputEle.addEventListener('focus', () => {
3674
3739
  this.setAttribute('focused', 'true');
3675
3740
  });
3741
+
3742
+ inputEle.addEventListener('blur', () => {
3743
+ this.removeAttribute('focused');
3744
+ });
3676
3745
  }
3677
3746
  };
3678
3747
 
@@ -3828,15 +3897,14 @@ const PasswordClass = compose(
3828
3897
  }
3829
3898
 
3830
3899
  ${inputFloatingLabelStyle()}
3831
-
3832
- :host ::slotted(input) {
3833
- display: none !important;
3834
- }
3835
3900
 
3836
3901
  ::part(reveal-button) {
3837
3902
  align-self: center;
3838
- }
3839
-
3903
+ }
3904
+
3905
+ vaadin-password-field > input:not(:placeholder-shown) {
3906
+ opacity: 0;
3907
+ }
3840
3908
  `,
3841
3909
  excludeAttrsSync: ['tabindex'],
3842
3910
  componentName: componentName$D,
@@ -12282,7 +12350,7 @@ const [theme$1, refs, vars$H] = createHelperVars(
12282
12350
  inputVerticalAlignment: 'flex-end',
12283
12351
  inputTransformY: 'translateY(1.55em)',
12284
12352
  inputTransition: 'all 75ms ease-in-out',
12285
- marginInlineStart: '0', // `calc(0.25em + ${globalRefs.border.sm})`,
12353
+ marginInlineStart: '0',
12286
12354
  valueInputHeight: '1.5702em',
12287
12355
  valueInputMarginBottom: '0.5em',
12288
12356