@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.
@@ -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
  };