material-inspired-component-library 1.0.3 → 1.1.0

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.
package/README.md CHANGED
@@ -97,3 +97,9 @@ The library currently consists of the following components:
97
97
  - [x] [Slider](components/slider/README.md)
98
98
  - [x] [Switch](components/switch/README.md)
99
99
  - [x] [Text field](components/textfield/README.md)
100
+
101
+ ## Change Log
102
+
103
+ #### 1.1.0 (12.08.2025)
104
+ **Features**
105
+ - **Text field**: Added support for multi-line text fields.
@@ -25,6 +25,7 @@
25
25
  @mixin slider-track() {
26
26
  block-size: var(--md-sys-slider-track-height);
27
27
  border-radius: var(--md-sys-slider-track-radius);
28
+ background-color: inherit;
28
29
  background-image: linear-gradient(
29
30
  var(--md-sys-slider-track-direction),
30
31
  var(--md-sys-color-primary) calc(100% * (var(--md-sys-slider-value) - var(--md-sys-slider-min)) / (var(--md-sys-slider-max) - var(--md-sys-slider-min))),
@@ -48,13 +49,12 @@
48
49
  appearance: none;
49
50
  box-sizing: content-box;
50
51
  position: relative;
51
- inline-size: 4px;
52
+ inline-size: 16px;
52
53
  block-size: var(--md-sys-slider-handle-height);
53
54
  inset: 0;
54
- inset-block-start: calc(-1 * (var(--md-sys-slider-handle-height) + 2 * var(--md-sys-slider-thumb-space) - var(--md-sys-slider-track-height)) / 2);
55
- border: var(--md-sys-slider-thumb-space) solid currentColor;
56
- border-radius: 8px;
57
- background-color: var(--md-sys-color-primary);
55
+ inset-block-start: calc(-1 * (var(--md-sys-slider-handle-height) - var(--md-sys-slider-track-height)) / 2);
56
+ background-color: inherit;
57
+ background-image: linear-gradient(to right,transparent 0px,transparent var(--md-sys-slider-thumb-space), var(--md-sys-color-primary) var(--md-sys-slider-thumb-space),var(--md-sys-color-primary) 10px,transparent 10px, transparent 16px);
58
58
  cursor: pointer;
59
59
  z-index: 2;
60
60
  }
@@ -105,7 +105,7 @@ input[type=range].micl-slider-xl {
105
105
  margin: 0;
106
106
  outline: none;
107
107
  color: var(--md-sys-color-surface-container-low);
108
- background-color: transparent;
108
+ background-color: inherit;
109
109
  accent-color: var(--md-sys-color-primary);
110
110
 
111
111
  &::before {
@@ -145,6 +145,9 @@ input[type=range].micl-slider-xl {
145
145
  z-index: 3;
146
146
  transition: opacity var(--md-sys-motion-duration-long2) motion.$md-sys-motion-easing-emphasized-decelerate;
147
147
  }
148
+ &::-webkit-slider-container {
149
+ background-color: inherit;
150
+ }
148
151
  &::-webkit-slider-runnable-track {
149
152
  @include slider-track;
150
153
  }
@@ -195,12 +198,12 @@ input[type=range].micl-slider-xl {
195
198
  }
196
199
  &:not(:disabled):active {
197
200
  &::-webkit-slider-thumb {
198
- inline-size: 2px;
201
+ background-image: linear-gradient(to right,transparent 0px, transparent calc(var(--md-sys-slider-thumb-space) + 1px), var(--md-sys-color-primary) calc(var(--md-sys-slider-thumb-space) + 1px), var(--md-sys-color-primary) calc(var(--md-sys-slider-thumb-space) + 3px), transparent calc(var(--md-sys-slider-thumb-space) + 3px), transparent calc(2 * var(--md-sys-slider-thumb-space) + 4px));
199
202
  outline: none;
200
203
  cursor: grabbing;
201
204
  }
202
205
  &::-moz-range-thumb {
203
- inline-size: 2px;
206
+ background-image: linear-gradient(to right,transparent 0px, transparent calc(var(--md-sys-slider-thumb-space) + 1px), var(--md-sys-color-primary) calc(var(--md-sys-slider-thumb-space) + 1px), var(--md-sys-color-primary) calc(var(--md-sys-slider-thumb-space) + 3px), transparent calc(var(--md-sys-slider-thumb-space) + 3px), transparent calc(2 * var(--md-sys-slider-thumb-space) + 4px));
204
207
  outline: none;
205
208
  cursor: grabbing;
206
209
  }
@@ -41,35 +41,68 @@ The following example shows a text field with every available feature. You can i
41
41
 
42
42
  ```HTML
43
43
  <div class="micl-textfield-filled">
44
- <span class="micl-textfield__icon-leading material-symbols-outlined" aria-hidden="true">search</span>
44
+ <span class="micl-textfield__icon-leading material-symbols-outlined">search</span>
45
45
  <label for="mytextfield">Label text</label>
46
- <span class="micl-textfield__prefix">$</span>
47
- <input type="text" id="mytextfield" maxlength="20">
48
- <span class="micl-textfield__suffix">kg</span>
49
- <span class="micl-textfield__icon-trailing material-symbols-outlined" aria-hidden="true">cancel</span>
50
- <span class="micl-textfield__supporting-text">Supporting text</span>
46
+ <span class="micl-textfield__prefix" aria-label="US dollars">$</span>
47
+ <input type="text" id="mytextfield" maxlength="20" aria-describedby="mysupport">
48
+ <span class="micl-textfield__suffix" aria-label="kilograms">kg</span>
49
+ <span class="micl-textfield__icon-trailing material-symbols-outlined">cancel</span>
50
+ <span id="mysupport" class="micl-textfield__supporting-text">Supporting text</span>
51
51
  <span class="micl-textfield__character-counter"></span>
52
52
  </div>
53
53
  ```
54
54
 
55
55
  The `<input>` element can have the following types: `text`, `date`, `datetime-local`, `email`, `month`, `number`, `password`, `tel`, `time`, `url` and `week`.
56
56
 
57
- Two icons may be included in the layout: a **leading icon** (an element containing the `micl-textfield__icon-leading` class), and a **trailing icon** (an element containing the `micl-textfield__icon-trailing` class).
57
+ Adding the `disabled` boolean attribute to the `<input>` element causes the text field to be displayed in a disabled state.
58
58
 
59
- A **prefix** (e.g., "$") and a **suffix** (e.g., "kg") can be included to provide additional context. You can customize the spacing by overriding CSS variables:
59
+ Adding the `micl-textfield--error` class to the text field displays it in an error state.
60
60
 
61
- ```HTML
62
- <span class="micl-textfield__prefix" style="--md-sys-textfield-prefix-space:20px">USD</span>
63
- <span class="micl-textfield__suffix" style="--md-sys-textfield-suffix-space:10em">@gmail.com</span>
64
- ```
61
+ ### Leading Content
62
+ The data-input element can be preceded by various elements:
63
+
64
+ - **Icon**: Use `micl-textfield__icon-leading` with a (Material Symbols) icon.
65
+
66
+ - **Prefix**: A prefix (e.g., "$", "NOK") can be included to provide additional context. You can customize the spacing by overriding CSS variables:
67
+ ```HTML
68
+ <span class="micl-textfield__prefix" style="--md-sys-textfield-prefix-space:20px">USD</span>
69
+ ```
65
70
 
66
- Use an element with the `micl-textfield__supporting-text` class to add extra information about the text field.
71
+ ### Trailing Content
72
+ The data-input element may be followed by a trailing text or other element:
73
+
74
+ - **Icon**: Use `micl-textfield__icon-trailing` with a (Material Symbols) icon.
75
+
76
+ - **Suffix**: A suffix (e.g., "kg", "@gmail.com") can be included to provide additional context. You can customize the spacing by overriding CSS variables:
77
+ ```HTML
78
+ <span class="micl-textfield__suffix" style="--md-sys-textfield-suffix-space:10em">@gmail.com</span>
79
+ ```
80
+
81
+ ### Supporting Content
82
+ Use an element with the `micl-textfield__supporting-text` class to add extra information about the text field. If you want this element only to be visible when the text field is focused, add the `micl-textfield__supporting-text--focus` as well.
67
83
 
68
84
  If the `<input>` element includes the `maxlength` attribute, the **character counter** will display automatically in the element with the `micl-textfield__character-counter` class.
69
85
 
70
- Adding the `disabled` boolean attribute to the `<input>` element causes the text field to be displayed in a disabled state.
86
+ ### Multi-line Text Field
87
+ Replace the `<input>` element with the `<textarea>` element to create a multi-line text field:
71
88
 
72
- Adding the `micl-textfield--error` class to the text field displays it in an error state.
89
+ ```HTML
90
+ <div class="micl-textfield-outlined">
91
+ <label for="mytextfield">Label text</label>
92
+ <textarea id="mytextfield"></textarea>
93
+ </div>
94
+ ```
95
+
96
+ Add a value to the `rows` attribute of the `<textarea>` element to create a text field of fixed height:
97
+
98
+ ```HTML
99
+ <div class="micl-textfield-outlined">
100
+ <label for="mytextfield">Label text</label>
101
+ <textarea id="mytextfield" rows="4"></textarea>
102
+ </div>
103
+ ```
73
104
 
74
105
  ## Compatibility
75
106
  This component uses relative RGB colors, which might not be supported in your browser. Please check [Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#browser_compatibility) for details.
107
+
108
+ The multi-line text field variant uses the `field-sizing` CSS property, which might not be supported in your browser. Please check [Browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/field-sizing#browser_compatibility) for details.
@@ -24,6 +24,7 @@
24
24
 
25
25
  .micl-textfield-filled,
26
26
  .micl-textfield-outlined {
27
+ --md-sys-textfield-height: 56px;
27
28
  --md-sys-textfield-icon-size: 24px;
28
29
  --md-sys-textfield-icon-space: 12px;
29
30
  --md-sys-textfield-input-space: 16px;
@@ -40,30 +41,29 @@
40
41
 
41
42
  box-sizing: content-box;
42
43
  grid-area: textfield;
44
+ align-self: flex-start;
43
45
  width: fit-content;
44
- line-height: 1;
45
46
  padding-inline: 4px;
46
- margin-block-start: 0px;
47
+ margin-block-start: calc((var(--md-sys-textfield-height) - var(--md-sys-typescale-body-large-line-height)) / 2);
47
48
  margin-inline-start: 12px;
48
49
  border-radius: 4px;
49
50
  background-color: inherit;
50
51
  color: var(--md-sys-color-on-surface-variant);
51
52
  z-index: 1;
52
53
  transition:
53
- margin-block-start var(--md-sys-motion-duration-long1) var(--md-sys-motion-duration-short3) linear(motion.$md-sys-motion-spring-default-spatial),
54
- margin-inline-start var(--md-sys-motion-duration-long1) var(--md-sys-motion-duration-short3) linear(motion.$md-sys-motion-spring-default-spatial),
55
- font-size var(--md-sys-motion-duration-long1),
56
- letter-spacing var(--md-sys-motion-duration-long1);
54
+ margin-block-start var(--md-sys-motion-duration-medium2) var(--md-sys-motion-duration-short3),
55
+ margin-inline-start var(--md-sys-motion-duration-medium2) var(--md-sys-motion-duration-short3),
56
+ font-size var(--md-sys-motion-duration-medium2),
57
+ letter-spacing var(--md-sys-motion-duration-medium2);
57
58
  }
58
59
  &> input,
59
- &> select {
60
+ &> select,
61
+ &> textarea {
60
62
  @include typography.body-large;
61
63
 
62
64
  box-sizing: border-box;
63
65
  grid-area: textfield;
64
- height: 56px;
65
66
  margin: 0;
66
- padding-block: 0;
67
67
  padding-inline: var(--md-sys-textfield-input-space);
68
68
  border: none;
69
69
  border-block-end: 1px solid var(--md-sys-color-on-surface-variant);
@@ -75,7 +75,7 @@
75
75
  caret-color: var(--md-sys-color-primary);
76
76
 
77
77
  &:disabled {
78
- border-color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
78
+ border-block-end-color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
79
79
  color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
80
80
  }
81
81
  &::placeholder {
@@ -90,13 +90,32 @@
90
90
  -moz-appearance: textfield;
91
91
  }
92
92
  }
93
+ &> input,
94
+ &> select {
95
+ height: var(--md-sys-textfield-height);
96
+ padding-block: 0;
97
+ }
98
+ &> textarea {
99
+ min-height: var(--md-sys-textfield-height);
100
+ padding-block: calc((var(--md-sys-textfield-height) - var(--md-sys-typescale-body-large-line-height)) / 2);
101
+ resize: none;
102
+
103
+ &[rows] {
104
+ padding-block-start: 0;
105
+ border-block-start: 8px solid transparent;
106
+ overflow: hidden;
107
+ }
108
+ &:not([rows]) {
109
+ field-sizing: content;
110
+ }
111
+ }
93
112
  &> .micl-textfield__prefix,
94
113
  &> .micl-textfield__suffix {
95
114
  @include typography.body-large;
96
115
 
97
116
  grid-area: textfield;
98
117
  align-content: center;
99
- height: 56px;
118
+ height: var(--md-sys-textfield-height);
100
119
  color: var(--md-sys-color-on-surface-variant);
101
120
  opacity: 0;
102
121
  z-index: 1;
@@ -124,12 +143,14 @@
124
143
  margin-inline: auto var(--md-sys-textfield-icon-space);
125
144
  }
126
145
  &:has(> .micl-textfield__prefix) {
127
- &> input {
146
+ &> input,
147
+ &> textarea {
128
148
  padding-inline-start: calc(var(--md-sys-textfield-input-space) + var(--md-sys-textfield-prefix-space));
129
149
  }
130
150
  }
131
151
  &:has(> .micl-textfield__suffix) {
132
- &> input {
152
+ &> input,
153
+ &> textarea {
133
154
  padding-inline-end: calc(var(--md-sys-textfield-suffix-space) + var(--md-sys-textfield-input-space));
134
155
  }
135
156
  }
@@ -138,19 +159,23 @@
138
159
  margin-inline-start: calc(var(--md-sys-textfield-icon-space) + var(--md-sys-textfield-icon-size) + var(--md-sys-textfield-input-space));
139
160
  }
140
161
  &> .micl-textfield__prefix,
141
- &> input {
162
+ &> input,
163
+ &> textarea {
142
164
  padding-inline-start: calc(var(--md-sys-textfield-icon-space) + var(--md-sys-textfield-icon-size) + var(--md-sys-textfield-input-space));
143
165
  }
144
- &:has(> .micl-textfield__prefix) > input {
166
+ &:has(> .micl-textfield__prefix) > input,
167
+ &:has(> .micl-textfield__prefix) > textarea {
145
168
  padding-inline-start: calc(var(--md-sys-textfield-input-space) + var(--md-sys-textfield-icon-size) + var(--md-sys-textfield-icon-space) + var(--md-sys-textfield-prefix-space));
146
169
  }
147
170
  }
148
171
  &:has(> .micl-textfield__icon-trailing) {
149
172
  &> .micl-textfield__suffix,
150
- &> input {
173
+ &> input,
174
+ &> textarea {
151
175
  padding-inline-end: calc(var(--md-sys-textfield-input-space) + var(--md-sys-textfield-icon-size) + var(--md-sys-textfield-icon-space));
152
176
  }
153
- &:has(> .micl-textfield__suffix) > input {
177
+ &:has(> .micl-textfield__suffix) > input,
178
+ &:has(> .micl-textfield__suffix) > textarea {
154
179
  padding-inline-end: calc(var(--md-sys-textfield-input-space) + var(--md-sys-textfield-icon-size) + var(--md-sys-textfield-prefix-space) + var(--md-sys-textfield-icon-space));
155
180
  }
156
181
  }
@@ -162,28 +187,33 @@
162
187
  padding-block: 4px 0;
163
188
  padding-inline: 16px;
164
189
  color: var(--md-sys-color-on-surface-variant);
190
+
191
+ &.micl-textfield__supporting-text--focus {
192
+ visibility: hidden;
193
+ }
165
194
  }
166
195
  &> .micl-textfield__character-counter {
167
196
  justify-self: flex-end;
168
197
  }
169
198
  &:has(> input:active),
170
199
  &:has(> select:active),
200
+ &:has(> textarea:active),
171
201
  &:has(> input:focus),
172
202
  &:has(> select:focus),
203
+ &:has(> textarea:focus),
173
204
  &:has(> input:focus-visible),
174
- &:has(> select:focus-visible) {
205
+ &:has(> select:focus-visible),
206
+ &:has(> textarea:focus-visible) {
175
207
  &> label {
176
208
  color: var(--md-sys-color-primary);
177
209
  }
178
- &> .micl-textfield__icon-leading,
179
- &> .micl-textfield__icon-trailing,
180
- &> .micl-textfield__supporting-text,
181
- &> .micl-textfield__character-counter {
182
- color: var(--md-sys-color-on-surface-variant);
210
+ &> .micl-textfield__supporting-text.micl-textfield__supporting-text--focus {
211
+ visibility: visible;
183
212
  }
184
213
  }
185
214
  &:has(> input:disabled),
186
- &:has(> select:disabled) {
215
+ &:has(> select:disabled),
216
+ &:has(> textarea:disabled) {
187
217
  &> label {
188
218
  color: rgb(from var(--md-sys-color-on-surface) r g b / 38%);
189
219
  }
@@ -196,12 +226,14 @@
196
226
  display: none;
197
227
  }
198
228
  }
199
- &:has(> input:not([maxlength])) {
229
+ &:has(> input:not([maxlength])),
230
+ &:has(> textarea:not([maxlength])) {
200
231
  &> .micl-textfield__character-counter {
201
232
  display: none;
202
233
  }
203
234
  }
204
- &:has(> input[maxlength]:not(:disabled)):has(> .micl-textfield__character-counter) {
235
+ &:has(> input[maxlength]:not(:disabled)):has(> .micl-textfield__character-counter),
236
+ &:has(> textarea[maxlength]:not(:disabled)):has(> .micl-textfield__character-counter) {
205
237
  &> .micl-textfield__supporting-text {
206
238
  padding-inline-end: 64px;
207
239
  }
@@ -214,14 +246,17 @@
214
246
  }
215
247
  &:hover {
216
248
  &> input:not(:disabled),
217
- &> select:not(:disabled) {
218
- border-color: var(--md-sys-color-on-surface);
249
+ &> select:not(:disabled),
250
+ &> textarea:not(:disabled) {
251
+ border-block-end-color: var(--md-sys-color-on-surface);
219
252
  background-color: color-mix(in srgb, var(--md-sys-color-surface-container-highest), var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity));
220
253
  }
221
254
  }
222
255
  &> input,
223
- &> select {
224
- padding-block-start: 16px;
256
+ &> select,
257
+ &> textarea {
258
+ padding-block-start: 18px;
259
+ padding-block-end: 2px;
225
260
  background-color: var(--md-sys-color-surface-container-highest);
226
261
  border-end-start-radius: 0;
227
262
  border-end-end-radius: 0;
@@ -233,14 +268,17 @@
233
268
  &:not(:disabled):focus,
234
269
  &:not(:disabled):focus-visible,
235
270
  &:not(:disabled):active {
236
- padding-block-start: 18px;
237
- border-width: 3px;
238
- border-color: var(--md-sys-color-primary);
271
+ padding-block-end: 0px;
272
+ border-block-end-width: 3px;
273
+ border-block-end-color: var(--md-sys-color-primary);
239
274
  }
240
275
  }
241
276
  &> select {
242
277
  line-height: 28px;
243
278
  }
279
+ &> textarea {
280
+ padding-block-start: 24px;
281
+ }
244
282
  &:has(
245
283
  > input:focus,
246
284
  > input[value]:not([value='']):not([data-miclinitialized]),
@@ -252,12 +290,15 @@
252
290
  > input[type=week],
253
291
  > select:focus,
254
292
  > select[value]:not([value='']):not([data-miclinitialized]),
255
- > select[data-miclvalue]
293
+ > select[data-miclvalue],
294
+ > textarea:focus,
295
+ > textarea:not(:empty):not([data-miclinitialized]),
296
+ > textarea[data-miclvalue]
256
297
  ) {
257
298
  &> label {
258
299
  @include typography.body-small;
259
300
 
260
- margin-block-start: -24px;
301
+ margin-block-start: 8px;
261
302
  margin-inline-start: 12px;
262
303
  }
263
304
  &:has(> .micl-textfield__icon-leading) > label {
@@ -279,13 +320,15 @@
279
320
  color: var(--md-sys-color-on-surface);
280
321
  }
281
322
  &> input:not(:disabled),
282
- &> select:not(:disabled) {
323
+ &> select:not(:disabled),
324
+ &> textarea:not(:disabled) {
283
325
  outline-color: var(--md-sys-color-on-surface);
284
326
  color: var(--md-sys-color-on-surface);
285
327
  }
286
328
  }
287
329
  &> input,
288
- &> select {
330
+ &> select,
331
+ &> textarea {
289
332
  border: none;
290
333
  outline: 1px solid var(--md-sys-color-outline);
291
334
 
@@ -300,7 +343,7 @@
300
343
  }
301
344
  }
302
345
  &> select {
303
- line-height: 56px;
346
+ line-height: var(--md-sys-textfield-height);
304
347
  }
305
348
  &:has(
306
349
  > input:focus,
@@ -313,12 +356,15 @@
313
356
  > input[type=week],
314
357
  > select:focus,
315
358
  > select[value]:not([value='']):not([data-miclinitialized]),
316
- > select[data-miclvalue]
359
+ > select[data-miclvalue],
360
+ > textarea:focus,
361
+ > textarea:not(:empty):not([data-miclinitialized]),
362
+ > textarea[data-miclvalue]
317
363
  ) {
318
364
  &> label {
319
365
  @include typography.body-small;
320
366
 
321
- margin-block-start: -56px;
367
+ margin-block-start: calc(-2px - var(--md-sys-typescale-body-small-line-height) / 2);
322
368
  margin-inline-start: 12px;
323
369
  }
324
370
  &> .micl-textfield__prefix,
@@ -336,18 +382,17 @@
336
382
  &> .micl-textfield__character-counter {
337
383
  color: var(--md-sys-color-error);
338
384
  }
339
- &> input {
340
- border-color: var(--md-sys-color-error);
385
+ &> input,
386
+ &> textarea {
387
+ border-block-end-color: var(--md-sys-color-error);
341
388
  outline-color: var(--md-sys-color-error);
342
- color: var(--md-sys-color-on-surface);
343
389
  caret-color: var(--md-sys-color-error);
344
390
 
345
391
  &:active,
346
392
  &:focus,
347
393
  &:focus-visible {
348
- border-color: var(--md-sys-color-error);
394
+ border-block-end-color: var(--md-sys-color-error);
349
395
  outline-color: var(--md-sys-color-error);
350
- color: var(--md-sys-color-on-surface);
351
396
  }
352
397
  }
353
398
  &:hover {
@@ -355,22 +400,20 @@
355
400
  &> .micl-textfield__icon-trailing {
356
401
  color: var(--md-sys-color-on-error-container);
357
402
  }
358
- &> input {
359
- border-color: var(--md-sys-color-on-error-container);
403
+ &> input,
404
+ &> textarea {
405
+ border-block-end-color: var(--md-sys-color-on-error-container);
360
406
  outline-color: var(--md-sys-color-on-error-container);
361
407
  }
362
- &> .micl-textfield__supporting-text,
363
- &> .micl-textfield__character-counter {
364
- color: var(--md-sys-color-error);
365
- }
366
408
  }
367
409
  &:has(> input:active),
368
410
  &:has(> input:focus),
369
- &:has(> input:focus-visible) {
411
+ &:has(> input:focus-visible),
412
+ &:has(> textarea:active),
413
+ &:has(> textarea:focus),
414
+ &:has(> textarea:focus-visible) {
370
415
  &> label,
371
- &> .micl-textfield__icon-trailing,
372
- &> .micl-textfield__supporting-text,
373
- &> .micl-textfield__character-counter {
416
+ &> .micl-textfield__icon-trailing {
374
417
  color: var(--md-sys-color-error);
375
418
  }
376
419
  }
@@ -21,13 +21,14 @@
21
21
 
22
22
  export const textfieldSelector = '.micl-textfield-outlined > input,.micl-textfield-filled > input';
23
23
  export const selectSelector = '.micl-textfield-outlined > select,.micl-textfield-filled > select';
24
+ export const textareaSelector = '.micl-textfield-outlined > textarea,.micl-textfield-filled > textarea';
24
25
 
25
26
  export default (() =>
26
27
  {
27
- const counterSelector = '.micl-textfield-character-counter';
28
+ const counterSelector = '.micl-textfield__character-counter';
28
29
 
29
30
  return {
30
- initialize: (element: HTMLInputElement | HTMLSelectElement): void =>
31
+ initialize: (element: HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement): void =>
31
32
  {
32
33
  if (element.dataset.miclinitialized) {
33
34
  return;
@@ -39,21 +40,25 @@ export default (() =>
39
40
  }
40
41
 
41
42
  if (
42
- (element instanceof HTMLInputElement)
43
- && !!element.maxLength
43
+ (element instanceof HTMLSelectElement)
44
+ || !element.maxLength
44
45
  ) {
45
- const counter = element.parentElement?.querySelector(counterSelector);
46
- if (counter) {
47
- counter.textContent = `${element.value.length}/${element.maxLength}`;
48
- }
46
+ return;
47
+ }
48
+
49
+ const counter = element.parentElement?.querySelector(counterSelector);
50
+ if (counter) {
51
+ counter.textContent = `${element.value.length}/${element.maxLength}`;
49
52
  }
50
53
  },
51
54
 
52
55
  input: (event: Event): void =>
53
56
  {
54
57
  if (
55
- !(event.target as Element).matches(`${textfieldSelector},${selectSelector}`)
56
- || !((event.target instanceof HTMLInputElement) || (event.target instanceof HTMLSelectElement))
58
+ !(event.target as Element).matches(`${textfieldSelector},${selectSelector},${textareaSelector}`)
59
+ || !((event.target instanceof HTMLInputElement)
60
+ || (event.target instanceof HTMLSelectElement)
61
+ || (event.target instanceof HTMLTextAreaElement))
57
62
  || !event.target.dataset.miclinitialized
58
63
  || event.target.disabled
59
64
  ) {
@@ -68,13 +73,15 @@ export default (() =>
68
73
  }
69
74
 
70
75
  if (
71
- (event.target instanceof HTMLInputElement)
72
- && !!event.target.maxLength
76
+ (event.target instanceof HTMLSelectElement)
77
+ || !event.target.maxLength
73
78
  ) {
74
- const counter = event.target.parentElement?.querySelector(counterSelector);
75
- if (counter) {
76
- counter.textContent = `${event.target.value.length}/${event.target.maxLength}`;
77
- }
79
+ return;
80
+ }
81
+
82
+ const counter = event.target.parentElement?.querySelector(counterSelector);
83
+ if (counter) {
84
+ counter.textContent = `${event.target.value.length}/${event.target.maxLength}`;
78
85
  }
79
86
  }
80
87
  };
package/components.ts CHANGED
@@ -25,7 +25,7 @@ import _checkbox, { checkboxSelector } from './components/checkbox';
25
25
  import _list, { listSelector } from './components/list';
26
26
  import _menu, { menuSelector } from './components/menu';
27
27
  import _slider, { sliderSelector } from './components/slider';
28
- import _textfield, { textfieldSelector, selectSelector } from './components/textfield';
28
+ import _textfield, { textfieldSelector, selectSelector, textareaSelector } from './components/textfield';
29
29
 
30
30
  interface ComponentEntry<T extends HTMLElement> {
31
31
  component: {
@@ -47,6 +47,7 @@ export default (() =>
47
47
  [menuSelector] : { component: _menu, type: HTMLElement },
48
48
  [selectSelector] : { component: _textfield, type: HTMLSelectElement },
49
49
  [sliderSelector] : { component: _slider, type: HTMLInputElement },
50
+ [textareaSelector] : { component: _textfield, type: HTMLTextAreaElement },
50
51
  [textfieldSelector] : { component: _textfield, type: HTMLInputElement }
51
52
  };
52
53