@descope/web-components-ui 1.0.331 → 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.
@@ -134,7 +134,7 @@ const forwardAttrs = (source, dest, options = {}) => {
134
134
  observeAttributes(source, createSyncAttrsCb(source, dest, options.mapAttrs), options);
135
135
  };
136
136
 
137
- const forwardProps = (src, target, props = []) => {
137
+ const forwardProps$1 = (src, target, props = []) => {
138
138
  if (!props.length) return;
139
139
 
140
140
  const config = props.reduce(
@@ -1158,7 +1158,7 @@ const createProxy = ({
1158
1158
  });
1159
1159
 
1160
1160
  // this is needed for components that uses props, such as combo box
1161
- forwardProps(this.baseElement, this, includeForwardProps);
1161
+ forwardProps$1(this.baseElement, this, includeForwardProps);
1162
1162
 
1163
1163
  syncAttrs(this.baseElement, this, {
1164
1164
  excludeAttrs: excludeAttrsSync,
@@ -2171,13 +2171,17 @@ const inputValidationMixin = (superclass) =>
2171
2171
 
2172
2172
  const errorAttrs = ['invalid', 'required'];
2173
2173
 
2174
- const propertyObserver = (src, target, property) => {
2174
+ const forwardProps = (src, targets, property) => {
2175
+ const targetArr = Array.isArray(targets) ? targets : [targets];
2176
+
2175
2177
  Object.defineProperty(src, property, {
2176
2178
  set(v) {
2177
- target[property] = v;
2179
+ targetArr.forEach((target) => {
2180
+ target[property] = v;
2181
+ });
2178
2182
  },
2179
2183
  get() {
2180
- return target[property];
2184
+ return targets[0][property];
2181
2185
  },
2182
2186
  configurable: true,
2183
2187
  });
@@ -2201,6 +2205,10 @@ const getNestedInput = (ele) => {
2201
2205
  const proxyInputMixin =
2202
2206
  ({
2203
2207
  proxyProps = [],
2208
+ // useProxyTargets flag allows to forwardProps to other targets, other than
2209
+ // `this.inputElement`. It's to be used within `external-input` components,
2210
+ // if needed
2211
+ useProxyTargets = false,
2204
2212
  // allows us to set the event that should trigger validation
2205
2213
  // it can be either a string or an array of strings (for multiple events)
2206
2214
  inputEvent = 'input',
@@ -2327,7 +2335,11 @@ const proxyInputMixin =
2327
2335
 
2328
2336
  // sync properties
2329
2337
  proxyProps.forEach((prop) => {
2330
- propertyObserver(this, this.inputElement, prop);
2338
+ const externalInput = this.querySelector('input[slot="external-input"]') || null;
2339
+ const proxyTargets = useProxyTargets
2340
+ ? [this.baseElement, externalInput].filter(Boolean)
2341
+ : [];
2342
+ forwardProps(this, [this.inputElement, ...proxyTargets], prop);
2331
2343
  });
2332
2344
 
2333
2345
  this.setSelectionRange = this.inputElement.setSelectionRange?.bind(this.inputElement);
@@ -3269,7 +3281,7 @@ const TextFieldClass = compose(
3269
3281
  mappings: textFieldMappings,
3270
3282
  }),
3271
3283
  draggableMixin,
3272
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3284
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
3273
3285
  componentNameValidationMixin,
3274
3286
  customMixin$a
3275
3287
  )(
@@ -3552,8 +3564,13 @@ const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
3552
3564
  return inputEle;
3553
3565
  };
3554
3566
 
3555
- const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) => {
3567
+ // We apply the original input's style to the external-input.
3568
+ // Eventually, the user should interact directly with the external input.
3569
+ // We keep the original input
3570
+ const applyExternalInputStyles = (sourceInputEle, targetInputEle, labelType) => {
3556
3571
  const computedStyle = getComputedStyle(sourceInputEle);
3572
+
3573
+ // Get minimal set of computed theme properties to set on external input
3557
3574
  const height = computedStyle.getPropertyValue('height');
3558
3575
  const paddingLeft = computedStyle.getPropertyValue('padding-left');
3559
3576
  const paddingRight = computedStyle.getPropertyValue('padding-right');
@@ -3561,24 +3578,33 @@ const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) =
3561
3578
  const fontFamily = computedStyle.getPropertyValue('font-family');
3562
3579
  const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
3563
3580
  const caretColor = computedStyle.getPropertyValue('caret-color');
3581
+
3564
3582
  const valueColor = getValueColor(sourceInputEle, computedStyle);
3565
3583
 
3566
- // set external input style (and lock it with `all: unset` and `!important` all around)
3567
- // eslint-disable-next-line no-param-reassign
3568
- targetInputEle.style = `
3569
- all: unset !important;
3570
- position: absolute !important;
3571
- background-color: transparent !important;
3572
- color: ${valueColor} !important;
3573
- height: ${height} !important;
3574
- left: ${paddingLeft} !important;
3575
- right: ${paddingRight} !important;
3576
- font-size: ${fontSize} !important;
3577
- font-family: ${fontFamily} !important;
3578
- letter-spacing: ${letterSpacing} !important;
3579
- caret-color: ${caretColor} !important;
3580
- ${customStyle || ''}
3581
- `;
3584
+ const commonThemeStyles = [
3585
+ ['all', 'unset'],
3586
+ ['position', 'absolute'],
3587
+ ['background-color', 'transparent'],
3588
+ ['height', height],
3589
+ ['left', paddingLeft],
3590
+ ['right', paddingRight],
3591
+ ['font-size', fontSize],
3592
+ ['font-family', fontFamily],
3593
+ ['letter-spacing', letterSpacing],
3594
+ ['width', `calc(100% - ${paddingLeft} - ${paddingRight}`],
3595
+ ['caret-color', caretColor], // this is for seeing caret when focusing on external input
3596
+ ['color', valueColor],
3597
+ ];
3598
+
3599
+ commonThemeStyles.forEach(([key, val]) =>
3600
+ targetInputEle.style.setProperty(key, val, 'important')
3601
+ );
3602
+
3603
+ // Handle floating label theme properties
3604
+ if (labelType === 'floating') {
3605
+ const marginBottom = computedStyle.getPropertyValue('margin-bottom');
3606
+ targetInputEle.style.setProperty('margin-bottom', marginBottom, 'important');
3607
+ }
3582
3608
  };
3583
3609
 
3584
3610
  const componentName$O = getComponentName('password');
@@ -3596,6 +3622,11 @@ const customMixin$9 = (superclass) =>
3596
3622
  // use original input element as reference
3597
3623
  const origInput = this.baseElement.querySelector('input');
3598
3624
 
3625
+ // to avoid focus loop between external-input and origInput
3626
+ // we set origInput's tabindex to -1
3627
+ // otherwise, shift-tab will never leave the component focus
3628
+ origInput.setAttribute('tabindex', '-1');
3629
+
3599
3630
  // create external slot
3600
3631
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
3601
3632
  // append external slot to base element
@@ -3612,13 +3643,7 @@ const customMixin$9 = (superclass) =>
3612
3643
 
3613
3644
  // apply original input's styles to external input
3614
3645
  setTimeout(() => {
3615
- applyExternalInputStyles(
3616
- origInput,
3617
- externalInput,
3618
- `
3619
- width: calc(100% - 3em) !important;
3620
- `
3621
- );
3646
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
3622
3647
  });
3623
3648
 
3624
3649
  // set external input events
@@ -3643,11 +3668,6 @@ const customMixin$9 = (superclass) =>
3643
3668
  }
3644
3669
  });
3645
3670
 
3646
- this.addEventListener('focus', (e) => {
3647
- e.preventDefault();
3648
- this.focus();
3649
- });
3650
-
3651
3671
  // append external input to component's DOM
3652
3672
  this.appendChild(externalInput);
3653
3673
  }
@@ -3719,6 +3739,10 @@ const customMixin$9 = (superclass) =>
3719
3739
  inputEle.addEventListener('focus', () => {
3720
3740
  this.setAttribute('focused', 'true');
3721
3741
  });
3742
+
3743
+ inputEle.addEventListener('blur', () => {
3744
+ this.removeAttribute('focused');
3745
+ });
3722
3746
  }
3723
3747
  };
3724
3748
 
@@ -3877,8 +3901,11 @@ const PasswordClass = compose(
3877
3901
 
3878
3902
  ::part(reveal-button) {
3879
3903
  align-self: center;
3880
- }
3881
-
3904
+ }
3905
+
3906
+ vaadin-password-field > input:not(:placeholder-shown) {
3907
+ opacity: 0;
3908
+ }
3882
3909
  `,
3883
3910
  excludeAttrsSync: ['tabindex'],
3884
3911
  componentName: componentName$O,
@@ -4033,19 +4060,44 @@ const customMixin$8 = (superclass) =>
4033
4060
 
4034
4061
  this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
4035
4062
 
4036
- this.handleExternalInput();
4063
+ this.externalInput = this.handleExternalInput();
4064
+
4065
+ this.addEventListener('focus', () => {
4066
+ this.externalInput.focus();
4067
+ });
4037
4068
  }
4038
4069
 
4039
- handleExternalInput() {
4040
- // reset vaadin's checkValidity
4041
- this.baseElement.checkValidity = () => {};
4070
+ forwardInputValue(source, target) {
4071
+ // set internal sync events
4072
+ const valueDescriptor = Object.getOwnPropertyDescriptor(
4073
+ this.inputElement.constructor.prototype,
4074
+ 'value'
4075
+ );
4076
+
4077
+ Object.defineProperty(source, 'value', {
4078
+ ...valueDescriptor,
4079
+
4080
+ set(v) {
4081
+ valueDescriptor.set.call(this, v);
4082
+ // eslint-disable-next-line no-param-reassign
4083
+ target.value = v;
4084
+ },
4085
+ configurable: true,
4086
+ });
4087
+ }
4042
4088
 
4089
+ handleExternalInput() {
4043
4090
  // set safety attribute `external-input`
4044
4091
  this.setAttribute('external-input', 'true');
4045
4092
 
4046
4093
  // use original input element as reference
4047
4094
  const origInput = this.baseElement.querySelector('input');
4048
4095
 
4096
+ // to avoid focus loop between external-input and origInput
4097
+ // we set origInput's tabindex to -1
4098
+ // otherwise, shift-tab will never leave the component focus
4099
+ origInput.setAttribute('tabindex', '-1');
4100
+
4049
4101
  // create external slot
4050
4102
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
4051
4103
  // append external slot to base element
@@ -4059,42 +4111,41 @@ const customMixin$8 = (superclass) =>
4059
4111
 
4060
4112
  // apply original input's styles to external input
4061
4113
  setTimeout(() => {
4062
- applyExternalInputStyles(origInput, externalInput);
4114
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
4063
4115
  });
4064
4116
 
4065
4117
  // set external input events
4066
4118
  this.handleExternalInputEvents(externalInput);
4067
4119
 
4068
- syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
4120
+ // 1Password catches the internal input, so we forward the value to the external input
4121
+ this.forwardInputValue(origInput, externalInput);
4069
4122
 
4070
- externalInput.addEventListener('input', (e) => {
4071
- if (!e.target.value) {
4072
- this.removeAttribute('has-value');
4073
- } else {
4074
- this.setAttribute('has-value', 'true');
4075
- }
4123
+ syncAttrs(origInput, externalInput, {
4124
+ includeAttrs: ['disabled', 'readonly', 'pattern'],
4076
4125
  });
4077
4126
 
4078
4127
  // append external input to component's DOM
4079
4128
  this.appendChild(externalInput);
4129
+
4130
+ return externalInput;
4080
4131
  }
4081
4132
 
4082
4133
  getAutocompleteType() {
4083
4134
  return this.getAttribute('autocomplete') || 'username';
4084
4135
  }
4085
4136
 
4086
- handleExternalInputEvents(inputEle) {
4137
+ handleExternalInputEvents(externalInput) {
4087
4138
  // sync value of insible input back to original input
4088
- inputEle.addEventListener('input', (e) => {
4139
+ externalInput.addEventListener('input', (e) => {
4089
4140
  this.value = e.target.value;
4090
4141
  });
4091
4142
 
4092
4143
  // sync `focused` attribute on host when focusing on external input
4093
- inputEle.addEventListener('focus', () => {
4144
+ externalInput.addEventListener('focus', () => {
4094
4145
  this.setAttribute('focused', 'true');
4095
4146
  });
4096
4147
 
4097
- inputEle.addEventListener('blur', () => {
4148
+ externalInput.addEventListener('blur', () => {
4098
4149
  this.removeAttribute('focused');
4099
4150
  });
4100
4151
  }
@@ -4105,7 +4156,7 @@ const EmailFieldClass = compose(
4105
4156
  mappings: textFieldMappings,
4106
4157
  }),
4107
4158
  draggableMixin,
4108
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
4159
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
4109
4160
  componentNameValidationMixin,
4110
4161
  customMixin$8
4111
4162
  )(
@@ -4132,6 +4183,14 @@ const EmailFieldClass = compose(
4132
4183
  vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
4133
4184
  opacity: 0;
4134
4185
  }
4186
+
4187
+ vaadin-email-field > input:not(:placeholder-shown) {
4188
+ opacity: 0;
4189
+ }
4190
+
4191
+ :host ::slotted(*) {
4192
+ -webkit-mask-image: none;
4193
+ }
4135
4194
  `,
4136
4195
  excludeAttrsSync: ['tabindex'],
4137
4196
  componentName: componentName$M,
@@ -4349,7 +4408,7 @@ const booleanFieldMixin = (superclass) =>
4349
4408
  ],
4350
4409
  });
4351
4410
 
4352
- forwardProps(this.inputElement, this, ['checked']);
4411
+ forwardProps$1(this.inputElement, this, ['checked']);
4353
4412
  syncAttrs(this, this.inputElement, { includeAttrs: ['checked'] });
4354
4413
  }
4355
4414
  };