@everymatrix/general-input 0.0.1

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.
Files changed (121) hide show
  1. package/dist/cjs/checkbox-group-input_10.cjs.entry.js +34870 -0
  2. package/dist/cjs/general-input.cjs.entry.js +51 -0
  3. package/dist/cjs/general-input.cjs.js +19 -0
  4. package/dist/cjs/index-1768513d.js +1286 -0
  5. package/dist/cjs/index.cjs.js +2 -0
  6. package/dist/cjs/loader.cjs.js +21 -0
  7. package/dist/collection/collection-manifest.json +22 -0
  8. package/dist/collection/components/checkbox-group-input/checkbox-group-input.css +62 -0
  9. package/dist/collection/components/checkbox-group-input/checkbox-group-input.js +344 -0
  10. package/dist/collection/components/checkbox-input/checkbox-input.css +62 -0
  11. package/dist/collection/components/checkbox-input/checkbox-input.js +322 -0
  12. package/dist/collection/components/date-input/date-input.css +85 -0
  13. package/dist/collection/components/date-input/date-input.js +341 -0
  14. package/dist/collection/components/email-input/email-input.css +83 -0
  15. package/dist/collection/components/email-input/email-input.js +382 -0
  16. package/dist/collection/components/general-input/general-input.css +3 -0
  17. package/dist/collection/components/general-input/general-input.js +296 -0
  18. package/dist/collection/components/number-input/number-input.css +90 -0
  19. package/dist/collection/components/number-input/number-input.js +349 -0
  20. package/dist/collection/components/password-input/password-input.css +86 -0
  21. package/dist/collection/components/password-input/password-input.js +395 -0
  22. package/dist/collection/components/radio-input/radio-input.css +43 -0
  23. package/dist/collection/components/radio-input/radio-input.js +298 -0
  24. package/dist/collection/components/select-input/select-input.css +93 -0
  25. package/dist/collection/components/select-input/select-input.js +412 -0
  26. package/dist/collection/components/tel-input/tel-input.css +116 -0
  27. package/dist/collection/components/tel-input/tel-input.js +421 -0
  28. package/dist/collection/components/text-input/text-input.css +83 -0
  29. package/dist/collection/components/text-input/text-input.js +406 -0
  30. package/dist/collection/index.js +1 -0
  31. package/dist/collection/utils/locale.utils.js +26 -0
  32. package/dist/collection/utils/tooltipIcon.svg +5 -0
  33. package/dist/collection/utils/types.js +1 -0
  34. package/dist/collection/utils/utils.js +5 -0
  35. package/dist/components/active-mixin.js +975 -0
  36. package/dist/components/checkbox-group-input.d.ts +11 -0
  37. package/dist/components/checkbox-group-input.js +6 -0
  38. package/dist/components/checkbox-group-input2.js +5793 -0
  39. package/dist/components/checkbox-input.d.ts +11 -0
  40. package/dist/components/checkbox-input.js +6 -0
  41. package/dist/components/checkbox-input2.js +127 -0
  42. package/dist/components/date-input.d.ts +11 -0
  43. package/dist/components/date-input.js +6 -0
  44. package/dist/components/date-input2.js +5182 -0
  45. package/dist/components/email-input.d.ts +11 -0
  46. package/dist/components/email-input.js +6 -0
  47. package/dist/components/email-input2.js +150 -0
  48. package/dist/components/field-mixin.js +12712 -0
  49. package/dist/components/general-input.d.ts +11 -0
  50. package/dist/components/general-input.js +140 -0
  51. package/dist/components/index.d.ts +26 -0
  52. package/dist/components/index.js +1 -0
  53. package/dist/components/input-field-shared-styles.js +1067 -0
  54. package/dist/components/number-input.d.ts +11 -0
  55. package/dist/components/number-input.js +6 -0
  56. package/dist/components/number-input2.js +139 -0
  57. package/dist/components/password-input.d.ts +11 -0
  58. package/dist/components/password-input.js +6 -0
  59. package/dist/components/password-input2.js +879 -0
  60. package/dist/components/pattern-mixin.js +85 -0
  61. package/dist/components/radio-input.d.ts +11 -0
  62. package/dist/components/radio-input.js +6 -0
  63. package/dist/components/radio-input2.js +115 -0
  64. package/dist/components/select-input.d.ts +11 -0
  65. package/dist/components/select-input.js +6 -0
  66. package/dist/components/select-input2.js +166 -0
  67. package/dist/components/tel-input.d.ts +11 -0
  68. package/dist/components/tel-input.js +6 -0
  69. package/dist/components/tel-input2.js +178 -0
  70. package/dist/components/text-input.d.ts +11 -0
  71. package/dist/components/text-input.js +6 -0
  72. package/dist/components/text-input2.js +157 -0
  73. package/dist/components/tooltipIcon.js +30 -0
  74. package/dist/components/vaadin-button.js +461 -0
  75. package/dist/components/vaadin-combo-box.js +4329 -0
  76. package/dist/components/virtual-keyboard-controller.js +2693 -0
  77. package/dist/esm/checkbox-group-input_10.entry.js +34857 -0
  78. package/dist/esm/general-input.entry.js +47 -0
  79. package/dist/esm/general-input.js +17 -0
  80. package/dist/esm/index-7e24a6f1.js +1259 -0
  81. package/dist/esm/index.js +1 -0
  82. package/dist/esm/loader.js +17 -0
  83. package/dist/esm/polyfills/core-js.js +11 -0
  84. package/dist/esm/polyfills/css-shim.js +1 -0
  85. package/dist/esm/polyfills/dom.js +79 -0
  86. package/dist/esm/polyfills/es5-html-element.js +1 -0
  87. package/dist/esm/polyfills/index.js +34 -0
  88. package/dist/esm/polyfills/system.js +6 -0
  89. package/dist/general-input/general-input.esm.js +1 -0
  90. package/dist/general-input/index.esm.js +0 -0
  91. package/dist/general-input/p-61d76ec3.entry.js +1 -0
  92. package/dist/general-input/p-a79eb0a3.entry.js +4413 -0
  93. package/dist/general-input/p-fb647820.js +1 -0
  94. package/dist/index.cjs.js +1 -0
  95. package/dist/index.js +1 -0
  96. package/dist/stencil.config.js +22 -0
  97. package/dist/types/Users/adrian.pripon/Documents/Work/stencil/widgets-stencil/packages/general-input/.stencil/packages/general-input/stencil.config.d.ts +2 -0
  98. package/dist/types/components/checkbox-group-input/checkbox-group-input.d.ts +72 -0
  99. package/dist/types/components/checkbox-input/checkbox-input.d.ts +64 -0
  100. package/dist/types/components/date-input/date-input.d.ts +70 -0
  101. package/dist/types/components/email-input/email-input.d.ts +77 -0
  102. package/dist/types/components/general-input/general-input.d.ts +60 -0
  103. package/dist/types/components/number-input/number-input.d.ts +70 -0
  104. package/dist/types/components/password-input/password-input.d.ts +79 -0
  105. package/dist/types/components/radio-input/radio-input.d.ts +59 -0
  106. package/dist/types/components/select-input/select-input.d.ts +82 -0
  107. package/dist/types/components/tel-input/tel-input.d.ts +85 -0
  108. package/dist/types/components/text-input/text-input.d.ts +81 -0
  109. package/dist/types/components.d.ts +1140 -0
  110. package/dist/types/index.d.ts +1 -0
  111. package/dist/types/stencil-public-runtime.d.ts +1565 -0
  112. package/dist/types/utils/locale.utils.d.ts +5 -0
  113. package/dist/types/utils/types.d.ts +76 -0
  114. package/dist/types/utils/utils.d.ts +1 -0
  115. package/loader/cdn.js +3 -0
  116. package/loader/index.cjs.js +3 -0
  117. package/loader/index.d.ts +12 -0
  118. package/loader/index.es2017.js +3 -0
  119. package/loader/index.js +4 -0
  120. package/loader/package.json +10 -0
  121. package/package.json +26 -0
@@ -0,0 +1,1067 @@
1
+ import { r as registerStyles, i, T as ThemableMixin, G as DirMixin, P as PolymerElement, h as html, j as requiredField, k as helper, d as dedupingMixin, D as DelegateStateMixin, V as ValidateMixin, I as InputMixin, c as DelegateFocusMixin, l as FieldMixin, K as KeyboardMixin, A as Debouncer, B as timeOut } from './field-mixin.js';
2
+
3
+ registerStyles(
4
+ 'vaadin-input-container',
5
+ i`
6
+ :host {
7
+ border-radius: var(--lumo-border-radius-m);
8
+ background-color: var(--lumo-contrast-10pct);
9
+ padding: 0 calc(0.375em + var(--lumo-border-radius-m) / 4 - 1px);
10
+ font-weight: 500;
11
+ line-height: 1;
12
+ position: relative;
13
+ cursor: text;
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ /* Used for hover and activation effects */
18
+ :host::after {
19
+ content: '';
20
+ position: absolute;
21
+ top: 0;
22
+ right: 0;
23
+ bottom: 0;
24
+ left: 0;
25
+ border-radius: inherit;
26
+ pointer-events: none;
27
+ background-color: var(--lumo-contrast-50pct);
28
+ opacity: 0;
29
+ transition: transform 0.15s, opacity 0.2s;
30
+ transform-origin: 100% 0;
31
+ }
32
+
33
+ ::slotted(:not([slot$='fix'])) {
34
+ cursor: inherit;
35
+ min-height: var(--lumo-text-field-size, var(--lumo-size-m));
36
+ padding: 0 0.25em;
37
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to left, transparent, #000 1.25em);
38
+ -webkit-mask-image: var(--_lumo-text-field-overflow-mask-image);
39
+ mask-image: var(--_lumo-text-field-overflow-mask-image);
40
+ }
41
+
42
+ /* Read-only */
43
+ :host([readonly]) {
44
+ color: var(--lumo-secondary-text-color);
45
+ background-color: transparent;
46
+ cursor: default;
47
+ }
48
+
49
+ :host([readonly])::after {
50
+ background-color: transparent;
51
+ opacity: 1;
52
+ border: 1px dashed var(--lumo-contrast-30pct);
53
+ }
54
+
55
+ /* Disabled */
56
+ :host([disabled]) {
57
+ background-color: var(--lumo-contrast-5pct);
58
+ }
59
+
60
+ :host([disabled]) ::slotted(*) {
61
+ color: var(--lumo-disabled-text-color);
62
+ -webkit-text-fill-color: var(--lumo-disabled-text-color);
63
+ }
64
+
65
+ /* Invalid */
66
+ :host([invalid]) {
67
+ background-color: var(--lumo-error-color-10pct);
68
+ }
69
+
70
+ :host([invalid])::after {
71
+ background-color: var(--lumo-error-color-50pct);
72
+ }
73
+
74
+ /* Slotted icons */
75
+ ::slotted(iron-icon),
76
+ ::slotted(vaadin-icon) {
77
+ color: var(--lumo-contrast-60pct);
78
+ width: var(--lumo-icon-size-m);
79
+ height: var(--lumo-icon-size-m);
80
+ }
81
+
82
+ /* Vaadin icons are based on a 16x16 grid (unlike Lumo and Material icons with 24x24), so they look too big by default */
83
+ ::slotted(iron-icon[icon^='vaadin:']),
84
+ ::slotted(vaadin-icon[icon^='vaadin:']) {
85
+ padding: 0.25em;
86
+ box-sizing: border-box !important;
87
+ }
88
+
89
+ /* Text align */
90
+ :host([dir='rtl']) ::slotted(:not([slot$='fix'])) {
91
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to right, transparent, #000 1.25em);
92
+ }
93
+
94
+ @-moz-document url-prefix() {
95
+ :host([dir='rtl']) ::slotted(:not([slot$='fix'])) {
96
+ mask-image: var(--_lumo-text-field-overflow-mask-image);
97
+ }
98
+ }
99
+
100
+ :host([theme~='align-left']) ::slotted(:not([slot$='fix'])) {
101
+ text-align: start;
102
+ --_lumo-text-field-overflow-mask-image: none;
103
+ }
104
+
105
+ :host([theme~='align-center']) ::slotted(:not([slot$='fix'])) {
106
+ text-align: center;
107
+ --_lumo-text-field-overflow-mask-image: none;
108
+ }
109
+
110
+ :host([theme~='align-right']) ::slotted(:not([slot$='fix'])) {
111
+ text-align: end;
112
+ --_lumo-text-field-overflow-mask-image: none;
113
+ }
114
+
115
+ @-moz-document url-prefix() {
116
+ /* Firefox is smart enough to align overflowing text to right */
117
+ :host([theme~='align-right']) ::slotted(:not([slot$='fix'])) {
118
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to right, transparent 0.25em, #000 1.5em);
119
+ }
120
+ }
121
+
122
+ @-moz-document url-prefix() {
123
+ /* Firefox is smart enough to align overflowing text to right */
124
+ :host([theme~='align-left']) ::slotted(:not([slot$='fix'])) {
125
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to left, transparent 0.25em, #000 1.5em);
126
+ }
127
+ }
128
+
129
+ /* RTL specific styles */
130
+ :host([dir='rtl'])::after {
131
+ transform-origin: 0% 0;
132
+ }
133
+
134
+ :host([theme~='align-left'][dir='rtl']) ::slotted(:not([slot$='fix'])) {
135
+ --_lumo-text-field-overflow-mask-image: none;
136
+ }
137
+
138
+ :host([theme~='align-center'][dir='rtl']) ::slotted(:not([slot$='fix'])) {
139
+ --_lumo-text-field-overflow-mask-image: none;
140
+ }
141
+
142
+ :host([theme~='align-right'][dir='rtl']) ::slotted(:not([slot$='fix'])) {
143
+ --_lumo-text-field-overflow-mask-image: none;
144
+ }
145
+
146
+ @-moz-document url-prefix() {
147
+ /* Firefox is smart enough to align overflowing text to right */
148
+ :host([theme~='align-right'][dir='rtl']) ::slotted(:not([slot$='fix'])) {
149
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to right, transparent 0.25em, #000 1.5em);
150
+ }
151
+ }
152
+
153
+ @-moz-document url-prefix() {
154
+ /* Firefox is smart enough to align overflowing text to right */
155
+ :host([theme~='align-left'][dir='rtl']) ::slotted(:not([slot$='fix'])) {
156
+ --_lumo-text-field-overflow-mask-image: linear-gradient(to left, transparent 0.25em, #000 1.5em);
157
+ }
158
+ }
159
+ `,
160
+ { moduleId: 'lumo-input-container' },
161
+ );
162
+
163
+ /**
164
+ * @license
165
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
166
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
167
+ */
168
+
169
+ class InputContainer extends ThemableMixin(DirMixin(PolymerElement)) {
170
+ static get is() {
171
+ return 'vaadin-input-container';
172
+ }
173
+
174
+ static get template() {
175
+ return html`
176
+ <style>
177
+ :host {
178
+ display: flex;
179
+ align-items: center;
180
+ flex: 0 1 auto;
181
+ }
182
+
183
+ :host([hidden]) {
184
+ display: none !important;
185
+ }
186
+
187
+ /* Reset the native input styles */
188
+ ::slotted(input) {
189
+ -webkit-appearance: none;
190
+ -moz-appearance: none;
191
+ flex: auto;
192
+ white-space: nowrap;
193
+ overflow: hidden;
194
+ width: 100%;
195
+ height: 100%;
196
+ outline: none;
197
+ margin: 0;
198
+ padding: 0;
199
+ border: 0;
200
+ border-radius: 0;
201
+ min-width: 0;
202
+ font: inherit;
203
+ line-height: normal;
204
+ color: inherit;
205
+ background-color: transparent;
206
+ /* Disable default invalid style in Firefox */
207
+ box-shadow: none;
208
+ }
209
+
210
+ ::slotted(*) {
211
+ flex: none;
212
+ }
213
+
214
+ ::slotted(:is(input, textarea))::placeholder {
215
+ /* Use ::slotted(input:placeholder-shown) in themes to style the placeholder. */
216
+ /* because ::slotted(...)::placeholder does not work in Safari. */
217
+ font: inherit;
218
+ color: inherit;
219
+ /* Override default opacity in Firefox */
220
+ opacity: 1;
221
+ }
222
+ </style>
223
+ <slot name="prefix"></slot>
224
+ <slot></slot>
225
+ <slot name="suffix"></slot>
226
+ `;
227
+ }
228
+
229
+ static get properties() {
230
+ return {
231
+ /**
232
+ * If true, the user cannot interact with this element.
233
+ */
234
+ disabled: {
235
+ type: Boolean,
236
+ reflectToAttribute: true,
237
+ },
238
+
239
+ /**
240
+ * Set to true to make this element read-only.
241
+ */
242
+ readonly: {
243
+ type: Boolean,
244
+ reflectToAttribute: true,
245
+ },
246
+
247
+ /**
248
+ * Set to true when the element is invalid.
249
+ */
250
+ invalid: {
251
+ type: Boolean,
252
+ reflectToAttribute: true,
253
+ },
254
+ };
255
+ }
256
+
257
+ /** @protected */
258
+ ready() {
259
+ super.ready();
260
+
261
+ this.addEventListener('pointerdown', (event) => {
262
+ if (event.target === this) {
263
+ // Prevent direct clicks to the input container from blurring the input
264
+ event.preventDefault();
265
+ }
266
+ });
267
+
268
+ this.addEventListener('click', (event) => {
269
+ if (event.target === this) {
270
+ // The vaadin-input-container element was directly clicked,
271
+ // focus any focusable child element from the default slot
272
+ this.shadowRoot
273
+ .querySelector('slot:not([name])')
274
+ .assignedNodes({ flatten: true })
275
+ .forEach((node) => node.focus && node.focus());
276
+ }
277
+ });
278
+ }
279
+ }
280
+
281
+ customElements.define(InputContainer.is, InputContainer);
282
+
283
+ /**
284
+ * @license
285
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
286
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
287
+ */
288
+
289
+ const fieldButton = i`
290
+ [part$='button'] {
291
+ flex: none;
292
+ width: 1em;
293
+ height: 1em;
294
+ line-height: 1;
295
+ font-size: var(--lumo-icon-size-m);
296
+ text-align: center;
297
+ color: var(--lumo-contrast-60pct);
298
+ transition: 0.2s color;
299
+ cursor: var(--lumo-clickable-cursor);
300
+ }
301
+
302
+ [part$='button']:hover {
303
+ color: var(--lumo-contrast-90pct);
304
+ }
305
+
306
+ :host([disabled]) [part$='button'],
307
+ :host([readonly]) [part$='button'] {
308
+ color: var(--lumo-contrast-20pct);
309
+ cursor: default;
310
+ }
311
+
312
+ [part$='button']::before {
313
+ font-family: 'lumo-icons';
314
+ display: block;
315
+ }
316
+ `;
317
+ registerStyles('', fieldButton, { moduleId: 'lumo-field-button' });
318
+
319
+ /**
320
+ * @license
321
+ * Copyright (c) 2017 - 2022 Vaadin Ltd.
322
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
323
+ */
324
+
325
+ const inputField = i`
326
+ :host {
327
+ --lumo-text-field-size: var(--lumo-size-m);
328
+ color: var(--lumo-body-text-color);
329
+ font-size: var(--lumo-font-size-m);
330
+ font-family: var(--lumo-font-family);
331
+ -webkit-font-smoothing: antialiased;
332
+ -moz-osx-font-smoothing: grayscale;
333
+ -webkit-tap-highlight-color: transparent;
334
+ padding: var(--lumo-space-xs) 0;
335
+ }
336
+
337
+ :host::before {
338
+ height: var(--lumo-text-field-size);
339
+ box-sizing: border-box;
340
+ display: inline-flex;
341
+ align-items: center;
342
+ }
343
+
344
+ :host([focused]:not([readonly])) [part='label'] {
345
+ color: var(--lumo-primary-text-color);
346
+ }
347
+
348
+ :host([focused]) [part='input-field'] ::slotted(:is(input, textarea)) {
349
+ -webkit-mask-image: none;
350
+ mask-image: none;
351
+ }
352
+
353
+ ::slotted(:is(input, textarea):placeholder-shown) {
354
+ color: var(--lumo-secondary-text-color);
355
+ }
356
+
357
+ /* Hover */
358
+ :host(:hover:not([readonly]):not([focused])) [part='label'] {
359
+ color: var(--lumo-body-text-color);
360
+ }
361
+
362
+ :host(:hover:not([readonly]):not([focused])) [part='input-field']::after {
363
+ opacity: 0.1;
364
+ }
365
+
366
+ /* Touch device adjustment */
367
+ @media (pointer: coarse) {
368
+ :host(:hover:not([readonly]):not([focused])) [part='label'] {
369
+ color: var(--lumo-secondary-text-color);
370
+ }
371
+
372
+ :host(:hover:not([readonly]):not([focused])) [part='input-field']::after {
373
+ opacity: 0;
374
+ }
375
+
376
+ :host(:active:not([readonly]):not([focused])) [part='input-field']::after {
377
+ opacity: 0.2;
378
+ }
379
+ }
380
+
381
+ /* Trigger when not focusing using the keyboard */
382
+ :host([focused]:not([focus-ring]):not([readonly])) [part='input-field']::after {
383
+ transform: scaleX(0);
384
+ transition-duration: 0.15s, 1s;
385
+ }
386
+
387
+ /* Focus-ring */
388
+ :host([focus-ring]) [part='input-field'] {
389
+ box-shadow: 0 0 0 2px var(--lumo-primary-color-50pct);
390
+ }
391
+
392
+ /* Read-only and disabled */
393
+ :host(:is([readonly], [disabled])) ::slotted(:is(input, textarea):placeholder-shown) {
394
+ opacity: 0;
395
+ }
396
+
397
+ /* Disabled style */
398
+ :host([disabled]) {
399
+ pointer-events: none;
400
+ }
401
+
402
+ :host([disabled]) [part='label'],
403
+ :host([disabled]) [part='input-field'] ::slotted(*) {
404
+ color: var(--lumo-disabled-text-color);
405
+ -webkit-text-fill-color: var(--lumo-disabled-text-color);
406
+ }
407
+
408
+ /* Invalid style */
409
+ :host([invalid][focus-ring]) [part='input-field'] {
410
+ box-shadow: 0 0 0 2px var(--lumo-error-color-50pct);
411
+ }
412
+
413
+ :host([input-prevented]) [part='input-field'] {
414
+ animation: shake 0.15s infinite;
415
+ }
416
+
417
+ @keyframes shake {
418
+ 25% {
419
+ transform: translateX(4px);
420
+ }
421
+ 75% {
422
+ transform: translateX(-4px);
423
+ }
424
+ }
425
+
426
+ /* Small theme */
427
+ :host([theme~='small']) {
428
+ font-size: var(--lumo-font-size-s);
429
+ --lumo-text-field-size: var(--lumo-size-s);
430
+ }
431
+
432
+ :host([theme~='small']) [part='label'] {
433
+ font-size: var(--lumo-font-size-xs);
434
+ }
435
+
436
+ :host([theme~='small']) [part='error-message'] {
437
+ font-size: var(--lumo-font-size-xxs);
438
+ }
439
+
440
+ /* Slotted content */
441
+ [part='input-field'] ::slotted(:not(iron-icon):not(vaadin-icon):not(input):not(textarea)) {
442
+ color: var(--lumo-secondary-text-color);
443
+ font-weight: 400;
444
+ }
445
+
446
+ [part='clear-button']::before {
447
+ content: var(--lumo-icons-cross);
448
+ }
449
+ `;
450
+
451
+ const inputFieldShared$1 = [requiredField, fieldButton, helper, inputField];
452
+
453
+ registerStyles('', inputFieldShared$1, {
454
+ moduleId: 'lumo-input-field-shared-styles',
455
+ });
456
+
457
+ /**
458
+ * @license
459
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
460
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
461
+ */
462
+
463
+ /**
464
+ * A mixin to combine multiple input validation constraints.
465
+ *
466
+ * @polymerMixin
467
+ * @mixes DelegateStateMixin
468
+ * @mixes InputMixin
469
+ * @mixes ValidateMixin
470
+ */
471
+ const InputConstraintsMixin = dedupingMixin(
472
+ (superclass) =>
473
+ class InputConstraintsMixinClass extends DelegateStateMixin(ValidateMixin(InputMixin(superclass))) {
474
+ /**
475
+ * An array of attributes which participate in the input validation.
476
+ * Changing these attributes will cause the input to re-validate.
477
+ *
478
+ * IMPORTANT: The attributes should be properly delegated to the input element
479
+ * from the host using `delegateAttrs` getter (see `DelegateStateMixin`).
480
+ * The `required` attribute is already delegated.
481
+ */
482
+ static get constraints() {
483
+ return ['required'];
484
+ }
485
+
486
+ static get delegateAttrs() {
487
+ return [...super.delegateAttrs, 'required'];
488
+ }
489
+
490
+ /** @protected */
491
+ ready() {
492
+ super.ready();
493
+
494
+ this._createConstraintsObserver();
495
+ }
496
+
497
+ /**
498
+ * Returns true if the current input value satisfies all constraints (if any).
499
+ * @return {boolean}
500
+ */
501
+ checkValidity() {
502
+ if (this.inputElement && this._hasValidConstraints(this.constructor.constraints.map((c) => this[c]))) {
503
+ return this.inputElement.checkValidity();
504
+ }
505
+ return !this.invalid;
506
+ }
507
+
508
+ /**
509
+ * Returns true if some of the provided set of constraints are valid.
510
+ * @param {Array} constraints
511
+ * @return {boolean}
512
+ * @protected
513
+ */
514
+ _hasValidConstraints(constraints) {
515
+ return constraints.some((c) => this.__isValidConstraint(c));
516
+ }
517
+
518
+ /**
519
+ * Override this method to customize setting up constraints observer.
520
+ * @protected
521
+ */
522
+ _createConstraintsObserver() {
523
+ // This complex observer needs to be added dynamically instead of using `static get observers()`
524
+ // to make it possible to tweak this behavior in classes that apply this mixin.
525
+ this._createMethodObserver(`_constraintsChanged(stateTarget, ${this.constructor.constraints.join(', ')})`);
526
+ }
527
+
528
+ /**
529
+ * Override this method to implement custom validation constraints.
530
+ * @param {HTMLElement | undefined} stateTarget
531
+ * @param {unknown[]} constraints
532
+ * @protected
533
+ */
534
+ _constraintsChanged(stateTarget, ...constraints) {
535
+ // The input element's validity cannot be determined until
536
+ // all the necessary constraint attributes aren't set on it.
537
+ if (!stateTarget) {
538
+ return;
539
+ }
540
+
541
+ const hasConstraints = this._hasValidConstraints(constraints);
542
+ const isLastConstraintRemoved = this.__previousHasConstraints && !hasConstraints;
543
+
544
+ if ((this._hasValue || this.invalid) && hasConstraints) {
545
+ this.validate();
546
+ } else if (isLastConstraintRemoved) {
547
+ this._setInvalid(false);
548
+ }
549
+
550
+ this.__previousHasConstraints = hasConstraints;
551
+ }
552
+
553
+ /**
554
+ * Override an event listener inherited from `InputMixin`
555
+ * to capture native `change` event and make sure that
556
+ * a new one is dispatched after validation runs.
557
+ * @param {Event} event
558
+ * @protected
559
+ * @override
560
+ */
561
+ _onChange(event) {
562
+ event.stopPropagation();
563
+
564
+ this.validate();
565
+
566
+ this.dispatchEvent(
567
+ new CustomEvent('change', {
568
+ detail: {
569
+ sourceEvent: event,
570
+ },
571
+ bubbles: event.bubbles,
572
+ cancelable: event.cancelable,
573
+ }),
574
+ );
575
+ }
576
+
577
+ /** @private */
578
+ __isValidConstraint(constraint) {
579
+ // 0 is valid for `minlength` and `maxlength`
580
+ return Boolean(constraint) || constraint === 0;
581
+ }
582
+ },
583
+ );
584
+
585
+ /**
586
+ * @license
587
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
588
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
589
+ */
590
+
591
+ const stylesMap = new WeakMap();
592
+
593
+ /**
594
+ * Get all the styles inserted into root.
595
+ * @param {DocumentOrShadowRoot} root
596
+ * @return {Set<string>}
597
+ */
598
+ function getRootStyles(root) {
599
+ if (!stylesMap.has(root)) {
600
+ stylesMap.set(root, new Set());
601
+ }
602
+
603
+ return stylesMap.get(root);
604
+ }
605
+
606
+ /**
607
+ * Insert styles into the root.
608
+ * @param {string} styles
609
+ * @param {DocumentOrShadowRoot} root
610
+ */
611
+ function insertStyles(styles, root) {
612
+ const style = document.createElement('style');
613
+ style.textContent = styles;
614
+
615
+ if (root === document) {
616
+ document.head.appendChild(style);
617
+ } else {
618
+ root.insertBefore(style, root.firstChild);
619
+ }
620
+ }
621
+
622
+ /**
623
+ * Mixin to insert styles into the outer scope to handle slotted components.
624
+ * This is useful e.g. to hide native `<input type="number">` controls.
625
+ *
626
+ * @polymerMixin
627
+ */
628
+ const SlotStylesMixin = dedupingMixin(
629
+ (superclass) =>
630
+ class SlotStylesMixinClass extends superclass {
631
+ /**
632
+ * List of styles to insert into root.
633
+ * @protected
634
+ */
635
+ get slotStyles() {
636
+ return {};
637
+ }
638
+
639
+ /** @protected */
640
+ connectedCallback() {
641
+ super.connectedCallback();
642
+
643
+ this.__applySlotStyles();
644
+ }
645
+
646
+ /** @private */
647
+ __applySlotStyles() {
648
+ const root = this.getRootNode();
649
+ const rootStyles = getRootStyles(root);
650
+
651
+ this.slotStyles.forEach((styles) => {
652
+ if (!rootStyles.has(styles)) {
653
+ insertStyles(styles, root);
654
+ rootStyles.add(styles);
655
+ }
656
+ });
657
+ }
658
+ },
659
+ );
660
+
661
+ /**
662
+ * @license
663
+ * Copyright (c) 2021 - 2022 Vaadin Ltd.
664
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
665
+ */
666
+
667
+ /**
668
+ * A mixin to provide shared logic for the editable form input controls.
669
+ *
670
+ * @polymerMixin
671
+ * @mixes DelegateFocusMixin
672
+ * @mixes FieldMixin
673
+ * @mixes InputConstraintsMixin
674
+ * @mixes KeyboardMixin
675
+ * @mixes SlotStylesMixin
676
+ */
677
+ const InputControlMixin = (superclass) =>
678
+ class InputControlMixinClass extends SlotStylesMixin(
679
+ DelegateFocusMixin(InputConstraintsMixin(FieldMixin(KeyboardMixin(superclass)))),
680
+ ) {
681
+ static get properties() {
682
+ return {
683
+ /**
684
+ * A pattern matched against individual characters the user inputs.
685
+ *
686
+ * When set, the field will prevent:
687
+ * - `keydown` events if the entered key doesn't match `/^allowedCharPattern$/`
688
+ * - `paste` events if the pasted text doesn't match `/^allowedCharPattern*$/`
689
+ * - `drop` events if the dropped text doesn't match `/^allowedCharPattern*$/`
690
+ *
691
+ * For example, to allow entering only numbers and minus signs, use:
692
+ * `allowedCharPattern = "[\\d-]"`
693
+ * @attr {string} allowed-char-pattern
694
+ */
695
+ allowedCharPattern: {
696
+ type: String,
697
+ observer: '_allowedCharPatternChanged',
698
+ },
699
+
700
+ /**
701
+ * If true, the input text gets fully selected when the field is focused using click or touch / tap.
702
+ */
703
+ autoselect: {
704
+ type: Boolean,
705
+ value: false,
706
+ },
707
+
708
+ /**
709
+ * Set to true to display the clear icon which clears the input.
710
+ * @attr {boolean} clear-button-visible
711
+ */
712
+ clearButtonVisible: {
713
+ type: Boolean,
714
+ reflectToAttribute: true,
715
+ value: false,
716
+ },
717
+
718
+ /**
719
+ * The name of this field.
720
+ */
721
+ name: {
722
+ type: String,
723
+ reflectToAttribute: true,
724
+ },
725
+
726
+ /**
727
+ * A hint to the user of what can be entered in the field.
728
+ */
729
+ placeholder: {
730
+ type: String,
731
+ reflectToAttribute: true,
732
+ },
733
+
734
+ /**
735
+ * When present, it specifies that the field is read-only.
736
+ */
737
+ readonly: {
738
+ type: Boolean,
739
+ value: false,
740
+ reflectToAttribute: true,
741
+ },
742
+
743
+ /**
744
+ * The text usually displayed in a tooltip popup when the mouse is over the field.
745
+ */
746
+ title: {
747
+ type: String,
748
+ reflectToAttribute: true,
749
+ },
750
+ };
751
+ }
752
+
753
+ static get delegateAttrs() {
754
+ return [...super.delegateAttrs, 'name', 'type', 'placeholder', 'readonly', 'invalid', 'title'];
755
+ }
756
+
757
+ constructor() {
758
+ super();
759
+
760
+ this._boundOnPaste = this._onPaste.bind(this);
761
+ this._boundOnDrop = this._onDrop.bind(this);
762
+ this._boundOnBeforeInput = this._onBeforeInput.bind(this);
763
+ }
764
+
765
+ /**
766
+ * Any element extending this mixin is required to implement this getter.
767
+ * It returns the reference to the clear button element.
768
+ * @protected
769
+ * @return {Element | null | undefined}
770
+ */
771
+ get clearElement() {
772
+ console.warn(`Please implement the 'clearElement' property in <${this.localName}>`);
773
+ return null;
774
+ }
775
+
776
+ /** @protected */
777
+ get slotStyles() {
778
+ // Needed for Safari, where ::slotted(...)::placeholder does not work
779
+ return [
780
+ `
781
+ :is(input[slot='input'], textarea[slot='textarea'])::placeholder {
782
+ font: inherit;
783
+ color: inherit;
784
+ }
785
+ `,
786
+ ];
787
+ }
788
+
789
+ /** @protected */
790
+ ready() {
791
+ super.ready();
792
+
793
+ if (this.clearElement) {
794
+ this.clearElement.addEventListener('click', (e) => this._onClearButtonClick(e));
795
+ }
796
+ }
797
+
798
+ /**
799
+ * @param {Event} event
800
+ * @protected
801
+ */
802
+ _onClearButtonClick(event) {
803
+ event.preventDefault();
804
+ this.inputElement.focus();
805
+ this.__clear();
806
+ }
807
+
808
+ /**
809
+ * Override an event listener from `DelegateFocusMixin`.
810
+ * @param {FocusEvent} event
811
+ * @protected
812
+ * @override
813
+ */
814
+ _onFocus(event) {
815
+ super._onFocus(event);
816
+
817
+ if (this.autoselect && this.inputElement) {
818
+ this.inputElement.select();
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Override an event listener inherited from `KeydownMixin` to clear on Esc.
824
+ * Components that extend this mixin can prevent this behavior by overriding
825
+ * this method without calling `super._onEscape` to provide custom logic.
826
+ * @param {KeyboardEvent} event
827
+ * @protected
828
+ * @override
829
+ */
830
+ _onEscape(event) {
831
+ super._onEscape(event);
832
+
833
+ if (this.clearButtonVisible && !!this.value) {
834
+ event.stopPropagation();
835
+ this.__clear();
836
+ }
837
+ }
838
+
839
+ /**
840
+ * Override an event listener inherited from `InputMixin`
841
+ * to capture native `change` event and make sure that
842
+ * a new one is dispatched after validation runs.
843
+ * @param {Event} event
844
+ * @protected
845
+ * @override
846
+ */
847
+ _onChange(event) {
848
+ event.stopPropagation();
849
+
850
+ this.validate();
851
+
852
+ this.dispatchEvent(
853
+ new CustomEvent('change', {
854
+ detail: {
855
+ sourceEvent: event,
856
+ },
857
+ bubbles: event.bubbles,
858
+ cancelable: event.cancelable,
859
+ }),
860
+ );
861
+ }
862
+
863
+ /** @private */
864
+ __clear() {
865
+ this.clear();
866
+ this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
867
+ this.inputElement.dispatchEvent(new Event('change', { bubbles: true }));
868
+ }
869
+
870
+ /**
871
+ * Override a method from `InputMixin`.
872
+ * @param {!HTMLElement} input
873
+ * @protected
874
+ * @override
875
+ */
876
+ _addInputListeners(input) {
877
+ super._addInputListeners(input);
878
+
879
+ input.addEventListener('paste', this._boundOnPaste);
880
+ input.addEventListener('drop', this._boundOnDrop);
881
+ input.addEventListener('beforeinput', this._boundOnBeforeInput);
882
+ }
883
+
884
+ /**
885
+ * Override a method from `InputMixin`.
886
+ * @param {!HTMLElement} input
887
+ * @protected
888
+ * @override
889
+ */
890
+ _removeInputListeners(input) {
891
+ super._removeInputListeners(input);
892
+
893
+ input.removeEventListener('paste', this._boundOnPaste);
894
+ input.removeEventListener('drop', this._boundOnDrop);
895
+ input.removeEventListener('beforeinput', this._boundOnBeforeInput);
896
+ }
897
+
898
+ /**
899
+ * Override an event listener from `KeyboardMixin`.
900
+ * @param {!KeyboardEvent} event
901
+ * @protected
902
+ * @override
903
+ */
904
+ _onKeyDown(event) {
905
+ super._onKeyDown(event);
906
+
907
+ if (this.allowedCharPattern && !this.__shouldAcceptKey(event)) {
908
+ event.preventDefault();
909
+ this._markInputPrevented();
910
+ }
911
+ }
912
+
913
+ /** @protected */
914
+ _markInputPrevented() {
915
+ // Add input-prevented attribute for 200ms
916
+ this.setAttribute('input-prevented', '');
917
+ this._preventInputDebouncer = Debouncer.debounce(this._preventInputDebouncer, timeOut.after(200), () => {
918
+ this.removeAttribute('input-prevented');
919
+ });
920
+ }
921
+
922
+ /** @private */
923
+ __shouldAcceptKey(event) {
924
+ return (
925
+ event.metaKey ||
926
+ event.ctrlKey ||
927
+ !event.key || // Allow typing anything if event.key is not supported
928
+ event.key.length !== 1 || // Allow "Backspace", "ArrowLeft" etc.
929
+ this.__allowedCharRegExp.test(event.key)
930
+ );
931
+ }
932
+
933
+ /** @private */
934
+ _onPaste(e) {
935
+ if (this.allowedCharPattern) {
936
+ const pastedText = e.clipboardData.getData('text');
937
+ if (!this.__allowedTextRegExp.test(pastedText)) {
938
+ e.preventDefault();
939
+ this._markInputPrevented();
940
+ }
941
+ }
942
+ }
943
+
944
+ /** @private */
945
+ _onDrop(e) {
946
+ if (this.allowedCharPattern) {
947
+ const draggedText = e.dataTransfer.getData('text');
948
+ if (!this.__allowedTextRegExp.test(draggedText)) {
949
+ e.preventDefault();
950
+ this._markInputPrevented();
951
+ }
952
+ }
953
+ }
954
+
955
+ /** @private */
956
+ _onBeforeInput(e) {
957
+ // The `beforeinput` event covers all the cases for `allowedCharPattern`: keyboard, pasting and dropping,
958
+ // but it is still experimental technology so we can't rely on it. It's used here just as an additional check,
959
+ // because it seems to be the only way to detect and prevent specific keys on mobile devices.
960
+ // See https://github.com/vaadin/vaadin-text-field/issues/429
961
+ if (this.allowedCharPattern && e.data && !this.__allowedTextRegExp.test(e.data)) {
962
+ e.preventDefault();
963
+ this._markInputPrevented();
964
+ }
965
+ }
966
+
967
+ /** @private */
968
+ _allowedCharPatternChanged(charPattern) {
969
+ if (charPattern) {
970
+ try {
971
+ this.__allowedCharRegExp = new RegExp(`^${charPattern}$`);
972
+ this.__allowedTextRegExp = new RegExp(`^${charPattern}*$`);
973
+ } catch (e) {
974
+ console.error(e);
975
+ }
976
+ }
977
+ }
978
+
979
+ /**
980
+ * Fired when the user commits a value change.
981
+ *
982
+ * @event change
983
+ */
984
+
985
+ /**
986
+ * Fired when the value is changed by the user: on every typing keystroke,
987
+ * and the value is cleared using the clear button.
988
+ *
989
+ * @event input
990
+ */
991
+ };
992
+
993
+ /**
994
+ * @license
995
+ * Copyright (c) 2021 - 2022 Vaadin Ltd..
996
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
997
+ */
998
+
999
+ const clearButton = i`
1000
+ [part='clear-button'] {
1001
+ display: none;
1002
+ cursor: default;
1003
+ }
1004
+
1005
+ [part='clear-button']::before {
1006
+ content: '✕';
1007
+ }
1008
+
1009
+ :host([clear-button-visible][has-value]:not([disabled]):not([readonly])) [part='clear-button'] {
1010
+ display: block;
1011
+ }
1012
+ `;
1013
+
1014
+ /**
1015
+ * @license
1016
+ * Copyright (c) 2021 - 2022 Vaadin Ltd..
1017
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1018
+ */
1019
+
1020
+ const fieldShared = i`
1021
+ :host {
1022
+ display: inline-flex;
1023
+ outline: none;
1024
+ }
1025
+
1026
+ :host::before {
1027
+ content: '\\2003';
1028
+ width: 0;
1029
+ display: inline-block;
1030
+ /* Size and position this element on the same vertical position as the input-field element
1031
+ to make vertical align for the host element work as expected */
1032
+ }
1033
+
1034
+ :host([hidden]) {
1035
+ display: none !important;
1036
+ }
1037
+
1038
+ :host(:not([has-label])) [part='label'] {
1039
+ display: none;
1040
+ }
1041
+ `;
1042
+
1043
+ /**
1044
+ * @license
1045
+ * Copyright (c) 2021 - 2022 Vaadin Ltd..
1046
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1047
+ */
1048
+
1049
+ const inputFieldContainer = i`
1050
+ [class$='container'] {
1051
+ display: flex;
1052
+ flex-direction: column;
1053
+ min-width: 100%;
1054
+ max-width: 100%;
1055
+ width: var(--vaadin-field-default-width, 12em);
1056
+ }
1057
+ `;
1058
+
1059
+ /**
1060
+ * @license
1061
+ * Copyright (c) 2021 - 2022 Vaadin Ltd..
1062
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
1063
+ */
1064
+
1065
+ const inputFieldShared = [fieldShared, inputFieldContainer, clearButton];
1066
+
1067
+ export { InputConstraintsMixin as I, InputControlMixin as a, inputFieldShared as b, inputFieldShared$1 as i };