@descope/web-components-ui 1.0.331 → 1.0.333

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,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
  };