@descope/web-components-ui 1.0.321 → 1.0.323

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/dist/cjs/index.cjs.js +555 -25
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js +634 -86
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/umd/4392.js +1 -1
  6. package/dist/umd/DescopeDev.js +1 -1
  7. package/dist/umd/boolean-fields-descope-checkbox-index-js.js +1 -1
  8. package/dist/umd/boolean-fields-descope-switch-toggle-index-js.js +1 -1
  9. package/dist/umd/button-selection-group-fields-descope-button-multi-selection-group-index-js.js +1 -1
  10. package/dist/umd/button-selection-group-fields-descope-button-selection-group-index-js.js +1 -1
  11. package/dist/umd/descope-combo-box-index-js.js +7 -7
  12. package/dist/umd/descope-email-field-index-js.js +4 -4
  13. package/dist/umd/descope-grid-descope-grid-selection-column-index-js.js +1 -1
  14. package/dist/umd/descope-grid-index-js.js +1 -1
  15. package/dist/umd/descope-multi-select-combo-box-index-js.js +1 -1
  16. package/dist/umd/descope-new-password-descope-new-password-internal-index-js.js +1 -1
  17. package/dist/umd/descope-new-password-index-js.js +1 -1
  18. package/dist/umd/descope-number-field-index-js.js +1 -1
  19. package/dist/umd/descope-passcode-index-js.js +1 -1
  20. package/dist/umd/descope-password-index-js.js +1 -1
  21. package/dist/umd/descope-radio-group-index-js.js +1 -1
  22. package/dist/umd/descope-text-area-index-js.js +1 -1
  23. package/dist/umd/descope-text-field-index-js.js +2 -2
  24. package/dist/umd/index.js +1 -1
  25. package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
  26. package/dist/umd/mapping-fields-descope-saml-group-mappings-index-js.js +1 -1
  27. package/dist/umd/phone-fields-descope-phone-field-descope-phone-field-internal-index-js.js +1 -1
  28. package/dist/umd/phone-fields-descope-phone-field-index-js.js +1 -1
  29. package/dist/umd/phone-fields-descope-phone-input-box-field-descope-phone-input-box-internal-index-js.js +1 -1
  30. package/dist/umd/phone-fields-descope-phone-input-box-field-index-js.js +1 -1
  31. package/package.json +1 -1
  32. package/src/components/descope-combo-box/ComboBoxClass.js +57 -0
  33. package/src/components/descope-email-field/EmailFieldClass.js +74 -1
  34. package/src/components/descope-multi-select-combo-box/MultiSelectComboBoxClass.js +31 -0
  35. package/src/components/descope-new-password/NewPasswordClass.js +7 -0
  36. package/src/components/descope-new-password/descope-new-password-internal/NewPasswordInternal.js +1 -0
  37. package/src/components/descope-number-field/NumberFieldClass.js +9 -0
  38. package/src/components/descope-password/PasswordClass.js +43 -3
  39. package/src/components/descope-text-field/TextFieldClass.js +24 -1
  40. package/src/components/descope-text-field/textFieldMappings.js +40 -6
  41. package/src/components/phone-fields/descope-phone-field/PhoneFieldClass.js +36 -4
  42. package/src/components/phone-fields/descope-phone-field/descope-phone-field-internal/PhoneFieldInternal.js +19 -3
  43. package/src/components/phone-fields/descope-phone-input-box-field/PhoneFieldInputBoxClass.js +45 -1
  44. package/src/components/phone-fields/descope-phone-input-box-field/descope-phone-input-box-internal/PhoneFieldInternalInputBox.js +1 -0
  45. package/src/{components/descope-password/helpers.js → helpers/externalInputs.js} +5 -5
  46. package/src/helpers/themeHelpers/resetHelpers.js +15 -0
  47. package/src/theme/components/comboBox.js +17 -0
  48. package/src/theme/components/emailField.js +17 -0
  49. package/src/theme/components/inputWrapper.js +35 -0
  50. package/src/theme/components/multiSelectComboBox.js +22 -0
  51. package/src/theme/components/newPassword.js +10 -0
  52. package/src/theme/components/numberField.js +17 -0
  53. package/src/theme/components/password.js +17 -0
  54. package/src/theme/components/phoneField.js +8 -0
  55. package/src/theme/components/phoneInputBoxField.js +17 -0
  56. package/src/theme/components/textField.js +17 -0
@@ -12,12 +12,13 @@ import {
12
12
  resetInputLabelPosition,
13
13
  resetInputCursor,
14
14
  useHostExternalPadding,
15
+ inputFloatingLabelStyle,
15
16
  } from '../../helpers/themeHelpers/resetHelpers';
16
17
  import {
17
18
  applyExternalInputStyles,
18
19
  createExternalInputEle,
19
20
  createExternalInputSlot,
20
- } from './helpers';
21
+ } from '../../helpers/externalInputs';
21
22
 
22
23
  export const componentName = getComponentName('password');
23
24
 
@@ -40,13 +41,23 @@ const customMixin = (superclass) =>
40
41
  this.baseElement.appendChild(externalInputSlot);
41
42
 
42
43
  // create external input
43
- const externalInput = createExternalInputEle('external-input', this.getAutocompleteType());
44
+ const externalInput = createExternalInputEle(
45
+ 'external-input',
46
+ 'password',
47
+ this.getAutocompleteType()
48
+ );
44
49
 
45
50
  this.handlePasswordVisibility(externalInput);
46
51
 
47
52
  // apply original input's styles to external input
48
53
  setTimeout(() => {
49
- applyExternalInputStyles(origInput, externalInput);
54
+ applyExternalInputStyles(
55
+ origInput,
56
+ externalInput,
57
+ `
58
+ width: calc(100% - 3em) !important;
59
+ `
60
+ );
50
61
  });
51
62
 
52
63
  // set external input events
@@ -191,6 +202,8 @@ export const PasswordClass = compose(
191
202
  inputOutlineOffset: { ...inputField, property: 'outline-offset' },
192
203
  inputOutlineWidth: { ...inputField, property: 'outline-width' },
193
204
 
205
+ labelFontSize: { ...label, property: 'font-size' },
206
+ labelFontWeight: { ...label, property: 'font-weight' },
194
207
  labelTextColor: [
195
208
  { ...label, property: 'color' },
196
209
  { ...requiredIndicator, property: 'color' },
@@ -213,6 +226,22 @@ export const PasswordClass = compose(
213
226
  ],
214
227
  revealButtonSize: { ...revealButtonContainer, property: 'font-size' },
215
228
  revealButtonColor: { ...revealButtonIcon, property: 'color' },
229
+
230
+ labelPosition: { ...label, property: 'position' },
231
+ labelTopPosition: { ...label, property: 'top' },
232
+ labelHorizontalPosition: [
233
+ { ...label, property: 'left' },
234
+ { ...label, property: 'right' },
235
+ ],
236
+ inputTransformY: { ...label, property: 'transform' },
237
+ inputTransition: { ...label, property: 'transition' },
238
+ marginInlineStart: { ...label, property: 'margin-inline-start' },
239
+ placeholderOpacity: [
240
+ { selector: '> input:placeholder-shown', property: 'opacity' },
241
+ { ...inputElement, property: 'opacity' },
242
+ ],
243
+ inputVerticalAlignment: { ...inputField, property: 'align-items' },
244
+ valueInputHeight: { ...inputElement, property: 'height' },
216
245
  },
217
246
  }),
218
247
  draggableMixin,
@@ -274,6 +303,17 @@ export const PasswordClass = compose(
274
303
  vaadin-password-field-button[focus-ring] {
275
304
  box-shadow: 0 0 0 2px var(${PasswordClass.cssVarList.inputOutlineColor});
276
305
  }
306
+
307
+ ${inputFloatingLabelStyle()}
308
+
309
+ :host ::slotted(input) {
310
+ display: none !important;
311
+ }
312
+
313
+ ::part(reveal-button) {
314
+ align-self: center;
315
+ }
316
+
277
317
  `,
278
318
  excludeAttrsSync: ['tabindex'],
279
319
  componentName,
@@ -9,6 +9,7 @@ import textFieldMappings from './textFieldMappings';
9
9
  import { compose } from '../../helpers';
10
10
  import { getComponentName } from '../../helpers/componentHelpers';
11
11
  import {
12
+ inputFloatingLabelStyle,
12
13
  resetInputLabelPosition,
13
14
  resetInputOverrides,
14
15
  useHostExternalPadding,
@@ -16,7 +17,7 @@ import {
16
17
 
17
18
  export const componentName = getComponentName('text-field');
18
19
 
19
- const observedAttrs = ['type'];
20
+ const observedAttrs = ['type', 'label-type'];
20
21
 
21
22
  const customMixin = (superclass) =>
22
23
  class TextFieldClass extends superclass {
@@ -24,6 +25,10 @@ const customMixin = (superclass) =>
24
25
  return observedAttrs.concat(superclass.observedAttributes || []);
25
26
  }
26
27
 
28
+ onLabelClick() {
29
+ this.focus();
30
+ }
31
+
27
32
  attributeChangedCallback(attrName, oldVal, newVal) {
28
33
  super.attributeChangeCallback?.(attrName, oldVal, newVal);
29
34
 
@@ -35,6 +40,16 @@ const customMixin = (superclass) =>
35
40
  if (attrName === 'type') {
36
41
  this.baseElement._setType(newVal);
37
42
  }
43
+
44
+ if (oldVal !== newVal) {
45
+ if (attrName === 'label-type') {
46
+ if (newVal === 'floating') {
47
+ this.addEventListener('click', this.onLabelClick);
48
+ } else {
49
+ this.removeEventListener('click', this.onLabelClick);
50
+ }
51
+ }
52
+ }
38
53
  }
39
54
 
40
55
  // webauthn is not working when the native input element is nested inside multiple shadow roots
@@ -87,9 +102,17 @@ export const TextFieldClass = compose(
87
102
  :host(:is([readonly], [disabled])) ::slotted(:is(input, textarea):placeholder-shown) {
88
103
  opacity: 1;
89
104
  }
105
+
106
+ vaadin-text-field[label-type="floating"]:not([focused])[readonly] > input:placeholder-shown {
107
+ opacity: 0;
108
+ }
109
+ vaadin-text-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
110
+ opacity: 0;
111
+ }
90
112
  ${resetInputLabelPosition('vaadin-text-field')}
91
113
  ${useHostExternalPadding(TextFieldClass.cssVarList)}
92
114
  ${resetInputOverrides('vaadin-text-field', TextFieldClass.cssVarList)}
115
+ ${inputFloatingLabelStyle()}
93
116
  `,
94
117
  excludeAttrsSync: ['tabindex'],
95
118
  componentName,
@@ -17,7 +17,10 @@ const {
17
17
  host: { selector: () => ':host' },
18
18
  label: { selector: '::part(label)' },
19
19
  requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
20
- placeholder: { selector: '> input:placeholder-shown' },
20
+ placeholder: [
21
+ { selector: '> input:placeholder-shown' },
22
+ { selector: () => ':host::slotted(input:placeholder-shown)' },
23
+ ],
21
24
  disabledPlaceholder: { selector: '> input:disabled::placeholder' },
22
25
  inputField: { selector: '::part(input-field)' },
23
26
  input: { selector: 'input' },
@@ -35,11 +38,8 @@ export default {
35
38
  fontSize: [{}, host],
36
39
  fontFamily: [label, inputField, helperText, errorMessage],
37
40
 
38
- hostWidth: { ...host, property: 'width' },
39
- hostMinWidth: { ...host, property: 'min-width' },
40
- hostDirection: { ...host, property: 'direction' },
41
-
42
- inputBackgroundColor: { ...inputField, property: 'background-color' },
41
+ labelFontSize: { ...label, property: 'font-size' },
42
+ labelFontWeight: { ...label, property: 'font-weight' },
43
43
 
44
44
  labelTextColor: [
45
45
  { ...label, property: 'color' },
@@ -47,6 +47,13 @@ export default {
47
47
  { ...label, property: '-webkit-text-fill-color' },
48
48
  { ...requiredIndicator, property: '-webkit-text-fill-color' },
49
49
  ],
50
+
51
+ hostWidth: { ...host, property: 'width' },
52
+ hostMinWidth: { ...host, property: 'min-width' },
53
+ hostDirection: { ...host, property: 'direction' },
54
+
55
+ inputBackgroundColor: { ...inputField, property: 'background-color' },
56
+
50
57
  errorMessageTextColor: { ...errorMessage, property: 'color' },
51
58
  helperTextColor: { ...helperText, property: '-webkit-text-fill-color' },
52
59
 
@@ -86,9 +93,36 @@ export default {
86
93
  ],
87
94
 
88
95
  inputPlaceholderColor: [
96
+ { selector: () => ':host input:placeholder-shown', property: 'color' },
89
97
  { ...placeholder, property: 'color' },
90
98
  { ...externalPlaceholder, property: 'color' },
91
99
  { ...disabledPlaceholder, property: '-webkit-text-fill-color' },
92
100
  { ...externalDisabledPlaceholder, property: '-webkit-text-fill-color' },
93
101
  ],
102
+
103
+ labelPosition: { ...label, property: 'position' },
104
+ labelTopPosition: { ...label, property: 'top' },
105
+ labelHorizontalPosition: [
106
+ { ...label, property: 'left' },
107
+ { ...label, property: 'right' },
108
+ ],
109
+ inputTransformY: { ...label, property: 'transform' },
110
+ inputTransition: { ...label, property: 'transition' },
111
+ marginInlineStart: { ...label, property: 'margin-inline-start' },
112
+ placeholderOpacity: [
113
+ { selector: '> input:placeholder-shown', property: 'opacity' },
114
+ { ...externalPlaceholder, property: 'opacity' },
115
+ ],
116
+ inputVerticalAlignment: [
117
+ { ...inputField, property: 'align-items' },
118
+ { ...externalInput, property: 'align-items' },
119
+ ],
120
+ valueInputHeight: [
121
+ { ...input, property: 'height' },
122
+ { ...externalInput, property: 'height' },
123
+ ],
124
+ valueInputMarginBottom: [
125
+ { ...input, property: 'margin-bottom' },
126
+ { ...externalInput, property: 'margin-bottom' },
127
+ ],
94
128
  };
@@ -52,6 +52,10 @@ const customMixin = (superclass) =>
52
52
  'phone-input-placeholder',
53
53
  'disabled',
54
54
  'restrict-countries',
55
+ 'label-type',
56
+ 'country-input-label',
57
+ 'phone-input-label',
58
+ 'readonly',
55
59
  ],
56
60
  });
57
61
  }
@@ -64,6 +68,7 @@ const {
64
68
  inputField,
65
69
  countryCodeInput,
66
70
  phoneInput,
71
+ phoneExternalInput,
67
72
  separator,
68
73
  errorMessage,
69
74
  helperText,
@@ -73,6 +78,7 @@ const {
73
78
  requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
74
79
  inputField: { selector: '::part(input-field)' },
75
80
  phoneInput: { selector: () => 'descope-text-field' },
81
+ phoneExternalInput: { selector: () => '::slotted(input)' },
76
82
  countryCodeInput: { selector: () => 'descope-combo-box' },
77
83
  separator: { selector: 'descope-phone-field-internal .separator' },
78
84
  helperText: { selector: '::part(helper-text)' },
@@ -131,6 +137,13 @@ export const PhoneFieldClass = compose(
131
137
  },
132
138
  phoneInputWidth: { ...phoneInput, property: 'width' },
133
139
 
140
+ horizontalPadding: [
141
+ { ...phoneInput, property: 'padding-left' },
142
+ { ...phoneInput, property: 'padding-right' },
143
+ { ...countryCodeInput, property: 'padding-left' },
144
+ { ...countryCodeInput, property: 'padding-right' },
145
+ ],
146
+
134
147
  labelTextColor: [
135
148
  { ...label, property: 'color' },
136
149
  { ...requiredIndicator, property: 'color' },
@@ -154,6 +167,20 @@ export const PhoneFieldClass = compose(
154
167
  inputOutlineColor: { ...inputField, property: 'outline-color' },
155
168
  inputOutlineWidth: { ...inputField, property: 'outline-width' },
156
169
  inputOutlineOffset: { ...inputField, property: 'outline-offset' },
170
+
171
+ valueInputHeight: [
172
+ { ...phoneExternalInput, property: textVars.valueInputHeight },
173
+ { ...countryCodeInput, property: comboVars.valueInputHeight },
174
+ ],
175
+ valueInputMarginBottom: [
176
+ { ...phoneInput, property: textVars.valueInputMarginBottom },
177
+ { ...phoneExternalInput, property: 'margin-bottom' },
178
+ ],
179
+ marginInlineStart: [
180
+ { ...phoneInput, property: textVars.marginInlineStart },
181
+ { ...phoneExternalInput, property: 'margin-inline-start' },
182
+ { ...countryCodeInput, property: comboVars.marginInlineStart },
183
+ ],
157
184
  },
158
185
  }),
159
186
  draggableMixin,
@@ -224,10 +251,15 @@ export const PhoneFieldClass = compose(
224
251
  ${textVars.inputOutlineOffset}: 0;
225
252
  ${textVars.inputBorderWidth}: 0;
226
253
  ${textVars.inputBorderRadius}: 0;
227
- }
228
- vaadin-text-field[readonly] > input:placeholder-shown {
229
- opacity: 1;
230
- }
254
+ }
255
+
256
+ descope-text-field[label-type="floating"]:not([focused])[readonly] > input:placeholder-shown {
257
+ opacity: 0;
258
+ }
259
+ descope-text-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
260
+ opacity: 0;
261
+ }
262
+
231
263
  vaadin-text-field::part(input-field)::after {
232
264
  border: none;
233
265
  }
@@ -1,19 +1,22 @@
1
1
  import { createBaseInputClass } from '../../../../baseClasses/createBaseInputClass';
2
- import { getComponentName } from '../../../../helpers/componentHelpers';
2
+ import { forwardAttrs, getComponentName, syncAttrs } from '../../../../helpers/componentHelpers';
3
3
  import CountryCodes from '../../CountryCodes';
4
4
  import { comboBoxItem } from '../helpers';
5
5
 
6
6
  export const componentName = getComponentName('phone-field-internal');
7
7
 
8
- const commonAttrs = ['disabled', 'size', 'bordered', 'invalid', 'readonly'];
8
+ const commonAttrs = ['disabled', 'size', 'bordered', 'invalid', 'readonly', 'label-type'];
9
9
  const countryAttrs = ['country-input-placeholder', 'default-code', 'restrict-countries'];
10
10
  const phoneAttrs = ['phone-input-placeholder', 'maxlength', 'autocomplete', 'name'];
11
+ const labelTypeAttrs = ['country-input-label', 'phone-input-label'];
11
12
  const mapAttrs = {
13
+ 'country-input-label': 'label',
14
+ 'phone-input-label': 'label',
12
15
  'country-input-placeholder': 'placeholder',
13
16
  'phone-input-placeholder': 'placeholder',
14
17
  };
15
18
 
16
- const inputRelatedAttrs = [].concat(commonAttrs, countryAttrs, phoneAttrs);
19
+ const inputRelatedAttrs = [].concat(commonAttrs, countryAttrs, phoneAttrs, labelTypeAttrs);
17
20
 
18
21
  const BaseInputClass = createBaseInputClass({ componentName, baseSelector: 'div' });
19
22
 
@@ -42,6 +45,12 @@ class PhoneFieldInternal extends BaseInputClass {
42
45
  this.phoneNumberInput = this.querySelector('descope-text-field');
43
46
  this.inputs = [this.countryCodeInput, this.phoneNumberInput];
44
47
 
48
+ forwardAttrs(this, this.countryCodeInput, { includeAttrs: ['label-type'] });
49
+ forwardAttrs(this, this.phoneNumberInput, { includeAttrs: ['label-type'] });
50
+
51
+ const externalInput = this.phoneNumberInput.querySelector('input');
52
+ syncAttrs(this.phoneNumberInput, externalInput, { includeAttrs: ['focused'] });
53
+
45
54
  // override combo box setter to display dialCode value in input
46
55
  this.countryCodeInput.customValueTransformFn = (val) => {
47
56
  const [, dialCode] = val?.split?.(' ') || [];
@@ -178,6 +187,13 @@ class PhoneFieldInternal extends BaseInputClass {
178
187
  this.countryCodeInput.setAttribute(attr, newValue);
179
188
  } else if (phoneAttrs.includes(attrName)) {
180
189
  this.phoneNumberInput.setAttribute(attr, newValue);
190
+ } else if (labelTypeAttrs.includes(attrName)) {
191
+ if (attrName === 'country-input-label') {
192
+ this.countryCodeInput.setAttribute(attr, newValue);
193
+ }
194
+ if (attrName === 'phone-input-label') {
195
+ this.phoneNumberInput.setAttribute(attr, newValue);
196
+ }
181
197
  }
182
198
  }
183
199
  if (attrName === 'restrict-countries') {
@@ -10,6 +10,7 @@ import {
10
10
  resetInputFieldDefaultWidth,
11
11
  resetInputFieldInvalidBackgroundColor,
12
12
  useHostExternalPadding,
13
+ inputFloatingLabelStyle,
13
14
  } from '../../../helpers/themeHelpers/resetHelpers';
14
15
 
15
16
  const textVars = TextFieldClass.cssVarList;
@@ -48,14 +49,26 @@ const customMixin = (superclass) =>
48
49
  'default-code',
49
50
  'disabled',
50
51
  'phone-input-placeholder',
52
+ 'label-type',
51
53
  ],
52
54
  });
53
55
  }
54
56
  };
55
57
 
56
- const { host, label, requiredIndicator, inputField, phoneInput, errorMessage, helperText } = {
58
+ const {
59
+ host,
60
+ label,
61
+ inputElement,
62
+ requiredIndicator,
63
+ inputField,
64
+ phoneInput,
65
+ errorMessage,
66
+ helperText,
67
+ } = {
57
68
  host: { selector: () => ':host' },
58
69
  label: { selector: '::part(label)' },
70
+ placeholder: { selector: '> input:placeholder-shown' },
71
+ inputElement: { selector: 'input' },
59
72
  requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
60
73
  inputField: { selector: '::part(input-field)' },
61
74
  phoneInput: { selector: () => 'descope-text-field' },
@@ -84,6 +97,13 @@ export const PhoneFieldInputBoxClass = compose(
84
97
  inputBorderColor: { ...inputField, property: 'border-color' },
85
98
  inputBorderRadius: { ...inputField, property: 'border-radius' },
86
99
 
100
+ inputHorizontalPadding: [
101
+ { ...phoneInput, property: 'padding-left' },
102
+ { ...phoneInput, property: 'padding-right' },
103
+ ],
104
+
105
+ labelFontSize: { ...label, property: 'font-size' },
106
+ labelFontWeight: { ...label, property: 'font-weight' },
87
107
  labelTextColor: [
88
108
  { ...label, property: 'color' },
89
109
  { ...requiredIndicator, property: 'color' },
@@ -99,6 +119,21 @@ export const PhoneFieldInputBoxClass = compose(
99
119
  inputOutlineColor: { ...inputField, property: 'outline-color' },
100
120
  inputOutlineWidth: { ...inputField, property: 'outline-width' },
101
121
  inputOutlineOffset: { ...inputField, property: 'outline-offset' },
122
+
123
+ labelPosition: { ...label, property: 'position' },
124
+ labelTopPosition: { ...label, property: 'top' },
125
+ labelHorizontalPosition: [
126
+ { ...label, property: 'left' },
127
+ { ...label, property: 'right' },
128
+ ],
129
+ inputTransformY: { ...label, property: 'transform' },
130
+ inputTransition: { ...label, property: 'transition' },
131
+ marginInlineStart: { ...label, property: 'margin-inline-start' },
132
+ valueInputHeight: { ...inputElement, property: 'height' },
133
+ valueInputMarginBottom: {
134
+ selector: TextFieldClass.componentName,
135
+ property: textVars.valueInputMarginBottom,
136
+ },
102
137
  },
103
138
  }),
104
139
  draggableMixin,
@@ -166,7 +201,16 @@ export const PhoneFieldInputBoxClass = compose(
166
201
  vaadin-text-field::part(input-field)::after {
167
202
  border: none;
168
203
  }
204
+
205
+ vaadin-text-field[label-type="floating"]:not([focused])[readonly] input:placeholder-shown {
206
+ opacity: 0;
207
+ }
208
+ vaadin-text-field[label-type="floating"]:not([focused])[disabled] input:placeholder-shown {
209
+ opacity: 0;
210
+ }
211
+
169
212
  ${resetInputLabelPosition('vaadin-text-field')}
213
+ ${inputFloatingLabelStyle()}
170
214
  `,
171
215
  excludeAttrsSync: ['tabindex'],
172
216
  componentName,
@@ -13,6 +13,7 @@ const observedAttributes = [
13
13
  'phone-input-placeholder',
14
14
  'name',
15
15
  'autocomplete',
16
+ 'label-type',
16
17
  ];
17
18
  const mapAttrs = {
18
19
  'phone-input-placeholder': 'placeholder',
@@ -1,6 +1,6 @@
1
1
  // since on load we can only sample the color of the placeholder,
2
2
  // we need to temporarily populate the input in order to sample the value color
3
- const getValueColor = (ele, computedStyle) => {
3
+ export const getValueColor = (ele, computedStyle) => {
4
4
  // eslint-disable-next-line no-param-reassign
5
5
  ele.value = '_';
6
6
 
@@ -21,18 +21,18 @@ export const createExternalInputSlot = (slotName, targetSlotName) => {
21
21
  return slotEle;
22
22
  };
23
23
 
24
- export const createExternalInputEle = (targetSlotName, autocompleteType) => {
24
+ export const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
25
25
  const inputEle = document.createElement('input');
26
26
 
27
27
  inputEle.setAttribute('slot', targetSlotName);
28
- inputEle.setAttribute('type', 'password');
28
+ inputEle.setAttribute('type', type);
29
29
  inputEle.setAttribute('data-hidden-input', 'true');
30
30
  inputEle.setAttribute('autocomplete', autocompleteType);
31
31
 
32
32
  return inputEle;
33
33
  };
34
34
 
35
- export const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
35
+ export const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) => {
36
36
  const computedStyle = getComputedStyle(sourceInputEle);
37
37
  const height = computedStyle.getPropertyValue('height');
38
38
  const paddingLeft = computedStyle.getPropertyValue('padding-left');
@@ -48,7 +48,6 @@ export const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
48
48
  targetInputEle.style = `
49
49
  all: unset !important;
50
50
  position: absolute !important;
51
- width: calc(100% - 3em) !important;
52
51
  background-color: transparent !important;
53
52
  color: ${valueColor} !important;
54
53
  height: ${height} !important;
@@ -58,5 +57,6 @@ export const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
58
57
  font-family: ${fontFamily} !important;
59
58
  letter-spacing: ${letterSpacing} !important;
60
59
  caret-color: ${caretColor} !important;
60
+ ${customStyle || ''}
61
61
  `;
62
62
  };
@@ -126,3 +126,18 @@ export const resetInputLabelPosition = (name) => `
126
126
  padding-bottom: 0.5em;
127
127
  }
128
128
  `;
129
+
130
+ export const inputFloatingLabelStyle = () => {
131
+ return `
132
+ :host([label-type="floating"]) {
133
+ position: relative;
134
+ }
135
+ :host([label-type="floating"][has-label]) [slot="label"] {
136
+ padding: 0;
137
+ }
138
+ :host([label-type="floating"][has-label]) > ::part(label) {
139
+ z-index: 1;
140
+ padding: 0;
141
+ }
142
+ `;
143
+ };
@@ -11,6 +11,8 @@ export const comboBox = {
11
11
  [vars.hostDirection]: refs.direction,
12
12
  [vars.fontSize]: refs.fontSize,
13
13
  [vars.fontFamily]: refs.fontFamily,
14
+ [vars.labelFontSize]: refs.labelFontSize,
15
+ [vars.labelFontWeight]: refs.labelFontWeight,
14
16
  [vars.labelTextColor]: refs.labelTextColor,
15
17
  [vars.errorMessageTextColor]: refs.errorMessageTextColor,
16
18
  [vars.inputBorderColor]: refs.borderColor,
@@ -34,6 +36,21 @@ export const comboBox = {
34
36
  [vars.overlayItemPaddingInlineStart]: globalRefs.spacing.xs,
35
37
  [vars.overlayItemPaddingInlineEnd]: globalRefs.spacing.lg,
36
38
 
39
+ labelType: {
40
+ floating: {
41
+ [vars.labelPosition]: refs.labelPosition,
42
+ [vars.labelTopPosition]: refs.labelTopPosition,
43
+ [vars.labelHorizontalPosition]: refs.labelHorizontalPosition,
44
+ [vars.inputTransformY]: refs.inputTransformY,
45
+ [vars.inputTransition]: refs.inputTransition,
46
+ [vars.marginInlineStart]: refs.marginInlineStart,
47
+ [vars.placeholderOpacity]: refs.placeholderOpacity,
48
+ [vars.inputVerticalAlignment]: refs.inputVerticalAlignment,
49
+ [vars.valueInputHeight]: refs.valueInputHeight,
50
+ [vars.valueInputMarginBottom]: refs.valueInputMarginBottom,
51
+ },
52
+ },
53
+
37
54
  _readonly: {
38
55
  [vars.inputDropdownButtonCursor]: 'default',
39
56
  },
@@ -9,6 +9,8 @@ const emailField = {
9
9
  [vars.hostDirection]: refs.direction,
10
10
  [vars.fontSize]: refs.fontSize,
11
11
  [vars.fontFamily]: refs.fontFamily,
12
+ [vars.labelFontSize]: refs.labelFontSize,
13
+ [vars.labelFontWeight]: refs.labelFontWeight,
12
14
  [vars.labelTextColor]: refs.labelTextColor,
13
15
  [vars.errorMessageTextColor]: refs.errorMessageTextColor,
14
16
  [vars.inputValueTextColor]: refs.valueTextColor,
@@ -25,6 +27,21 @@ const emailField = {
25
27
  [vars.inputBackgroundColor]: refs.backgroundColor,
26
28
  [vars.inputHorizontalPadding]: refs.horizontalPadding,
27
29
  [vars.inputHeight]: refs.inputHeight,
30
+
31
+ labelType: {
32
+ floating: {
33
+ [vars.labelPosition]: refs.labelPosition,
34
+ [vars.labelTopPosition]: refs.labelTopPosition,
35
+ [vars.labelHorizontalPosition]: refs.labelHorizontalPosition,
36
+ [vars.inputTransformY]: refs.inputTransformY,
37
+ [vars.inputTransition]: refs.inputTransition,
38
+ [vars.marginInlineStart]: refs.marginInlineStart,
39
+ [vars.placeholderOpacity]: refs.placeholderOpacity,
40
+ [vars.inputVerticalAlignment]: refs.inputVerticalAlignment,
41
+ [vars.valueInputHeight]: refs.valueInputHeight,
42
+ [vars.valueInputMarginBottom]: refs.valueInputMarginBottom,
43
+ },
44
+ },
28
45
  };
29
46
 
30
47
  export default emailField;
@@ -9,6 +9,7 @@ const [theme, refs, vars] = createHelperVars(
9
9
  {
10
10
  labelTextColor: globalRefs.colors.surface.dark,
11
11
  labelFontSize: '14px', // not taken from globals as it is fixed in all inputs
12
+ labelFontWeight: '500', // not taken from globals as it is fixed in all inputs
12
13
  valueTextColor: globalRefs.colors.surface.contrast,
13
14
  placeholderTextColor: globalRefs.colors.surface.dark,
14
15
  requiredIndicator: "'*'",
@@ -46,6 +47,40 @@ const [theme, refs, vars] = createHelperVars(
46
47
  lg: { fontSize: '18px', chipFontSize: '16px' },
47
48
  },
48
49
 
50
+ labelType: {
51
+ floating: {
52
+ labelPosition: 'absolute',
53
+ labelTopPosition: '0',
54
+ labelHorizontalPosition: '0.9em',
55
+ labelFontSize: '1em',
56
+ placeholderOpacity: 0,
57
+ inputHeight: '3.5em',
58
+ inputVerticalAlignment: 'flex-end',
59
+ inputTransformY: 'translateY(1.55em)',
60
+ inputTransition: 'all 75ms ease-in-out',
61
+ marginInlineStart: '0', // `calc(0.25em + ${globalRefs.border.sm})`,
62
+ valueInputHeight: '1.5702em',
63
+ valueInputMarginBottom: '0.5em',
64
+
65
+ _focused: {
66
+ labelFontSize: '0.75em',
67
+ inputTransformY: 'translateY(1.05em)',
68
+ labelFontWeight: '400',
69
+ placeholderOpacity: 1,
70
+ },
71
+
72
+ _readOnly: {
73
+ placeholderOpacity: 0,
74
+ },
75
+
76
+ _hasValue: {
77
+ inputTransformY: 'translateY(1.05em)',
78
+ labelFontSize: '0.75em',
79
+ labelFontWeight: '400',
80
+ },
81
+ },
82
+ },
83
+
49
84
  _fullWidth: {
50
85
  width: '100%',
51
86
  },
@@ -11,6 +11,8 @@ export const multiSelectComboBox = {
11
11
  [vars.hostDirection]: refs.direction,
12
12
  [vars.fontSize]: refs.fontSize,
13
13
  [vars.fontFamily]: refs.fontFamily,
14
+ [vars.labelFontSize]: refs.labelFontSize,
15
+ [vars.labelFontWeight]: refs.labelFontWeight,
14
16
  [vars.labelTextColor]: refs.labelTextColor,
15
17
  [vars.errorMessageTextColor]: refs.errorMessageTextColor,
16
18
  [vars.inputBorderColor]: refs.borderColor,
@@ -38,6 +40,26 @@ export const multiSelectComboBox = {
38
40
  [vars.chipTextColor]: globalRefs.colors.surface.contrast,
39
41
  [vars.chipBackgroundColor]: globalRefs.colors.surface.light,
40
42
 
43
+ labelType: {
44
+ floating: {
45
+ [vars.labelPosition]: refs.labelPosition,
46
+ [vars.labelTopPosition]: refs.labelTopPosition,
47
+ [vars.labelLeftPosition]: refs.labelLeftPosition,
48
+ [vars.labelHorizontalPosition]: refs.labelHorizontalPosition,
49
+ [vars.inputTransformY]: refs.inputTransformY,
50
+ [vars.inputTransition]: refs.inputTransition,
51
+ [vars.marginInlineStart]: refs.marginInlineStart,
52
+ [vars.placeholderOpacity]: refs.placeholderOpacity,
53
+ [vars.inputVerticalAlignment]: refs.inputVerticalAlignment,
54
+ [vars.valueInputHeight]: refs.valueInputHeight,
55
+ [vars.inputHorizontalPadding]: '0.25em',
56
+
57
+ _hasValue: {
58
+ [vars.inputHorizontalPadding]: '0.45em',
59
+ },
60
+ },
61
+ },
62
+
41
63
  _readonly: {
42
64
  [vars.inputDropdownButtonCursor]: 'default',
43
65
  },