@descope/web-components-ui 1.0.331 → 1.0.333

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,52 @@ const customMixin$8 = (superclass) =>
4033
4060
 
4034
4061
  this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
4035
4062
 
4036
- this.handleExternalInput();
4063
+ if (!this.isNoExternalInput) {
4064
+ this.externalInput = this.handleExternalInput();
4065
+
4066
+ this.addEventListener('focus', () => {
4067
+ this.externalInput.focus();
4068
+ });
4069
+ } else {
4070
+ this.setAttribute('autocomplete', this.getAutocompleteType());
4071
+ }
4037
4072
  }
4038
4073
 
4039
- handleExternalInput() {
4040
- // reset vaadin's checkValidity
4041
- this.baseElement.checkValidity = () => {};
4074
+ get isNoExternalInput() {
4075
+ return this.getAttribute('no-external-input') === 'true';
4076
+ }
4042
4077
 
4078
+ forwardInputValue(source, target) {
4079
+ // set internal sync events
4080
+ const valueDescriptor = Object.getOwnPropertyDescriptor(
4081
+ this.inputElement.constructor.prototype,
4082
+ 'value'
4083
+ );
4084
+
4085
+ Object.defineProperty(source, 'value', {
4086
+ ...valueDescriptor,
4087
+
4088
+ set(v) {
4089
+ valueDescriptor.set.call(this, v);
4090
+ // eslint-disable-next-line no-param-reassign
4091
+ target.value = v;
4092
+ },
4093
+ configurable: true,
4094
+ });
4095
+ }
4096
+
4097
+ handleExternalInput() {
4043
4098
  // set safety attribute `external-input`
4044
4099
  this.setAttribute('external-input', 'true');
4045
4100
 
4046
4101
  // use original input element as reference
4047
4102
  const origInput = this.baseElement.querySelector('input');
4048
4103
 
4104
+ // to avoid focus loop between external-input and origInput
4105
+ // we set origInput's tabindex to -1
4106
+ // otherwise, shift-tab will never leave the component focus
4107
+ origInput.setAttribute('tabindex', '-1');
4108
+
4049
4109
  // create external slot
4050
4110
  const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
4051
4111
  // append external slot to base element
@@ -4059,42 +4119,41 @@ const customMixin$8 = (superclass) =>
4059
4119
 
4060
4120
  // apply original input's styles to external input
4061
4121
  setTimeout(() => {
4062
- applyExternalInputStyles(origInput, externalInput);
4122
+ applyExternalInputStyles(origInput, externalInput, this.getAttribute('label-type'));
4063
4123
  });
4064
4124
 
4065
4125
  // set external input events
4066
4126
  this.handleExternalInputEvents(externalInput);
4067
4127
 
4068
- syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
4128
+ // 1Password catches the internal input, so we forward the value to the external input
4129
+ this.forwardInputValue(origInput, externalInput);
4069
4130
 
4070
- externalInput.addEventListener('input', (e) => {
4071
- if (!e.target.value) {
4072
- this.removeAttribute('has-value');
4073
- } else {
4074
- this.setAttribute('has-value', 'true');
4075
- }
4131
+ syncAttrs(origInput, externalInput, {
4132
+ includeAttrs: ['disabled', 'readonly', 'pattern'],
4076
4133
  });
4077
4134
 
4078
4135
  // append external input to component's DOM
4079
4136
  this.appendChild(externalInput);
4137
+
4138
+ return externalInput;
4080
4139
  }
4081
4140
 
4082
4141
  getAutocompleteType() {
4083
4142
  return this.getAttribute('autocomplete') || 'username';
4084
4143
  }
4085
4144
 
4086
- handleExternalInputEvents(inputEle) {
4145
+ handleExternalInputEvents(externalInput) {
4087
4146
  // sync value of insible input back to original input
4088
- inputEle.addEventListener('input', (e) => {
4147
+ externalInput.addEventListener('input', (e) => {
4089
4148
  this.value = e.target.value;
4090
4149
  });
4091
4150
 
4092
4151
  // sync `focused` attribute on host when focusing on external input
4093
- inputEle.addEventListener('focus', () => {
4152
+ externalInput.addEventListener('focus', () => {
4094
4153
  this.setAttribute('focused', 'true');
4095
4154
  });
4096
4155
 
4097
- inputEle.addEventListener('blur', () => {
4156
+ externalInput.addEventListener('blur', () => {
4098
4157
  this.removeAttribute('focused');
4099
4158
  });
4100
4159
  }
@@ -4105,7 +4164,7 @@ const EmailFieldClass = compose(
4105
4164
  mappings: textFieldMappings,
4106
4165
  }),
4107
4166
  draggableMixin,
4108
- composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
4167
+ composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'], useProxyTargets: true }),
4109
4168
  componentNameValidationMixin,
4110
4169
  customMixin$8
4111
4170
  )(
@@ -4132,6 +4191,14 @@ const EmailFieldClass = compose(
4132
4191
  vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
4133
4192
  opacity: 0;
4134
4193
  }
4194
+
4195
+ vaadin-email-field:not([no-external-input="true"]) > input:not(:placeholder-shown) {
4196
+ opacity: 0;
4197
+ }
4198
+
4199
+ :host ::slotted(*) {
4200
+ -webkit-mask-image: none;
4201
+ }
4135
4202
  `,
4136
4203
  excludeAttrsSync: ['tabindex'],
4137
4204
  componentName: componentName$M,
@@ -4349,7 +4416,7 @@ const booleanFieldMixin = (superclass) =>
4349
4416
  ],
4350
4417
  });
4351
4418
 
4352
- forwardProps(this.inputElement, this, ['checked']);
4419
+ forwardProps$1(this.inputElement, this, ['checked']);
4353
4420
  syncAttrs(this, this.inputElement, { includeAttrs: ['checked'] });
4354
4421
  }
4355
4422
  };