@descope/web-components-ui 1.0.330 → 1.0.332

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/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