Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.

Commit 45c6cf6

Browse files
authored
feat(textfield): Implement updated UX states for text fields (#998)
BREAKING CHANGE: DOM change to add a bottom line element. Adapter API changes to consolidate event handlers. Renamed multi-line text field to textarea.
1 parent 68f134a commit 45c6cf6

File tree

11 files changed

+983
-419
lines changed

11 files changed

+983
-419
lines changed

demos/textfield.html

Lines changed: 167 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@
4242
.hero .mdc-textfield {
4343
min-width: 240px;
4444
}
45+
46+
.demo-note {
47+
padding: 20px;
48+
margin: 20px 0;
49+
background-color: #f2f2f2;
50+
}
51+
52+
.custom-textfield-input {
53+
width: 300px;
54+
}
55+
56+
.full-width-textarea-example {
57+
margin-top: 16px;
58+
}
59+
4560
</style>
4661
</head>
4762
<body>
@@ -60,9 +75,9 @@
6075
<section class="hero">
6176
<div class="mdc-textfield">
6277
<input type="text" class="mdc-textfield__input" id="my-textfield"
63-
name="email" aria-controls="my-textfield-helptext"
64-
data-demo-no-auto-js autocomplete="email">
78+
aria-controls="my-textfield-helptext" data-demo-no-auto-js>
6579
<label for="my-textfield" class="mdc-textfield__label">Text Field</label>
80+
<div class="mdc-textfield__bottom-line"></div>
6681
</div>
6782
</section>
6883

@@ -73,13 +88,13 @@
7388
</em></section>
7489

7590
<section class="example">
76-
<h2>Full Functionality JS Component (Floating Label, Validation, Autocomplete)</h2>
91+
<h2>Full Functionality JS Component (Floating Label, Validation)</h2>
7792
<section id="demo-textfield-wrapper">
7893
<div class="mdc-textfield">
7994
<input type="text" class="mdc-textfield__input" id="my-textfield"
80-
name="email" aria-controls="my-textfield-helptext"
81-
data-demo-no-auto-js autocomplete="email">
95+
aria-controls="my-textfield-helptext" data-demo-no-auto-js>
8296
<label for="my-textfield" class="mdc-textfield__label">Email Address</label>
97+
<div class="mdc-textfield__bottom-line"></div>
8398
</div>
8499
<p id="my-textfield-helptext" class="mdc-textfield-helptext"
85100
aria-hidden="true" style="display:none;">
@@ -128,6 +143,7 @@ <h2>Password field with validation</h2>
128143
aria-controls="pw-validation-msg"
129144
autocomplete="current-password">
130145
<label for="pw" class="mdc-textfield__label">Choose password</label>
146+
<div class="mdc-textfield__bottom-line"></div>
131147
</div>
132148
<p class="mdc-textfield-helptext mdc-textfield-helptext--persistent mdc-textfield-helptext--validation-msg"
133149
id="pw-validation-msg">
@@ -138,7 +154,7 @@ <h2>Password field with validation</h2>
138154
<h2>Textfield box</h2>
139155
<div id="demo-tf-box-wrapper">
140156
<div id="tf-box-example" class="mdc-textfield mdc-textfield--box" data-demo-no-auto-js>
141-
<input type="text" id="tf-box" class="mdc-textfield__input" required
157+
<input required pattern=".{8,}" type="text" id="tf-box" class="mdc-textfield__input"
142158
aria-controls="name-validation-message">
143159
<label for="tf-box" class="mdc-textfield__label">Your Name</label>
144160
<div class="mdc-textfield__bottom-line"></div>
@@ -194,12 +210,73 @@ <h2>Textfield box</h2>
194210
}, 0);
195211
</script>
196212
</section>
213+
214+
<section class="example">
215+
<h2>Textfield - Leading/Trailing icons</h2>
216+
<div class="demo-note">
217+
<em>
218+
Note: Some implementations utilizing leading and trailing icons may wish to set a width on the
219+
<code>input</code> element to achieve uniform widths on textfields.
220+
This demo achieves that by adding a custom class name: <code>custom-textfield-input</code> and setting
221+
some style:
222+
</em>
223+
<br />
224+
<!--
225+
The following text formatting achieves the visual output we are aiming for
226+
since the <pre> tag honors whitespace and line breaks.
227+
-->
228+
<pre>
229+
<code>.custom-textfield-input {
230+
width: 300px;
231+
}</code></pre>
232+
</div>
233+
<div id="demo-tf-box-leading-wrapper">
234+
<div id="tf-box-leading-example"
235+
class="mdc-textfield mdc-textfield--box mdc-textfield--with-leading-icon" data-demo-no-auto-js>
236+
<i class="material-icons mdc-textfield__icon" tabindex="0">event</i>
237+
<input type="text" id="tf-box-leading" class="mdc-textfield__input custom-textfield-input">
238+
<label for="tf-box-leading" class="mdc-textfield__label">Your name</label>
239+
<div class="mdc-textfield__bottom-line"></div>
240+
</div>
241+
</div>
242+
<div id="demo-tf-box-trailing-wrapper">
243+
<div id="tf-box-trailing-example"
244+
class="mdc-textfield mdc-textfield--box mdc-textfield--with-trailing-icon" data-demo-no-auto-js>
245+
<input type="text" id="tf-box-trailing" class="mdc-textfield__input custom-textfield-input">
246+
<label for="tf-box-trailing" class="mdc-textfield__label">Your other name</label>
247+
<i class="material-icons mdc-textfield__icon" tabindex="0">delete</i>
248+
<div class="mdc-textfield__bottom-line"></div>
249+
</div>
250+
</div>
251+
<div>
252+
<input id="box-disable-leading-trailing" type="checkbox">
253+
<label for="box-disable-leading-trailing">Disabled</label>
254+
</div>
255+
<div>
256+
<input id="box-rtl-leading-trailing" type="checkbox">
257+
<label for="box-rtl-leading-trailing">RTL</label>
258+
</div>
259+
<div>
260+
<input id="box-dark-theme-leading-trailing" type="checkbox">
261+
<label for="box-dark-theme-leading-trailing">Dark Theme</label>
262+
</div>
263+
<div>
264+
<input id="box-dense-leading-trailing" type="checkbox">
265+
<label for="box-dense-leading-trailing">Dense</label>
266+
</div>
267+
<div>
268+
<input id="box-unclickable-leading-trailing" type="checkbox">
269+
<label for="box-unclickable-leading-trailing">Unclickable icons</label>
270+
</div>
271+
</section>
272+
197273
<section class="example">
198274
<h2>CSS Only Textfield</h2>
199275
<div class="mdc-form-field mdc-form-field--align-end">
200276
<div class="mdc-textfield" data-demo-no-auto-js>
201277
<input type="text" class="mdc-textfield__input" id="css-only-textfield"
202278
placeholder="Name">
279+
<div class="mdc-textfield__bottom-line"></div>
203280
</div>
204281
<label for="css-only-textfield">Your name:</label>
205282
</div>
@@ -221,51 +298,55 @@ <h2>Preventing FOUC</h2>
221298
<label for="fouc" class="mdc-textfield__label mdc-textfield__label--float-above">
222299
Label floating above
223300
</label>
301+
<div class="mdc-textfield__bottom-line"></div>
224302
</div>
225303
</section>
304+
226305
<section class="example">
227-
<h2>Multi-line Textfields</h2>
228-
<section id="demo-textfield-multiline-wrapper" style="overflow:hidden;">
229-
<div class="mdc-textfield mdc-textfield--multiline">
230-
<textarea id="multi-line" class="mdc-textfield__input" rows="8" cols="40"></textarea>
231-
<label for="multi-line" class="mdc-textfield__label">Multi-line Label</label>
306+
<h2>Textarea</h2>
307+
<section id="demo-textfield-textarea-wrapper">
308+
<div class="mdc-textfield mdc-textfield--textarea">
309+
<textarea id="textarea" class="mdc-textfield__input" rows="8" cols="40"></textarea>
310+
<label for="textarea" class="mdc-textfield__label">Textarea Label</label>
232311
</div>
233312
</section>
234313
<div>
235-
<input id="multi-disable" type="checkbox">
236-
<label for="multi-disable">Disabled</label>
314+
<input id="textarea-disable" type="checkbox">
315+
<label for="textarea-disable">Disabled</label>
237316
</div>
238317
<div>
239-
<input id="multi-rtl" type="checkbox">
240-
<label for="multi-rtl">RTL</label>
318+
<input id="textarea-rtl" type="checkbox">
319+
<label for="textarea-rtl">RTL</label>
241320
</div>
242321
<div>
243-
<input id="multi-dark-theme" type="checkbox">
244-
<label for="multi-dark-theme">Dark Theme</label>
322+
<input id="textarea-dark-theme" type="checkbox">
323+
<label for="textarea-dark-theme">Dark Theme</label>
245324
</div>
246325
<div>
247-
<input id="multi-required" type="checkbox">
248-
<label for="multi-required">Required</label>
326+
<input id="textarea-required" type="checkbox">
327+
<label for="textarea-required">Required</label>
249328
</div>
250329
</section>
330+
251331
<section class="example">
252-
<h2>Multi-line Textfields - CSS Only</h2>
253-
<label for="css-only-multiline" style="margin-bottom:4px;">About you:</label>
254-
<div class="mdc-textfield mdc-textfield--multiline" data-demo-no-auto-js>
255-
<textarea class="mdc-textfield__input"
256-
id="css-only-multiline"
257-
rows="8" cols="40"
258-
placeholder="Tell the world something about yourself!"></textarea>
259-
</div>
332+
<h2>CSS Only Textarea</h2>
333+
<section>
334+
<div class="mdc-textfield mdc-textfield--textarea" data-demo-no-auto-js>
335+
<textarea id="textarea-css-only" class="mdc-textfield__input" rows="8" cols="40" placeholder="Enter something about yourself"></textarea>
336+
</div>
337+
</section>
260338
</section>
339+
261340
<section class="example">
262-
<h2>Full-Width Textfields</h2>
341+
<h2>Full-Width Textfield and Textarea</h2>
263342
<div id="demo-fullwidth-wrapper">
264-
<div class="mdc-textfield mdc-textfield--fullwidth" data-demo-no-auto-js>
343+
<div class="mdc-textfield mdc-textfield--fullwidth">
265344
<input class="mdc-textfield__input" type="text" placeholder="Subject" aria-label="Subject">
345+
<div class="mdc-textfield__bottom-line"></div>
266346
</div>
267-
<div class="mdc-textfield mdc-textfield--multiline mdc-textfield--fullwidth" data-demo-no-auto-js>
268-
<textarea class="mdc-textfield__input" placeholder="Message" rows="8" cols="40" aria-label="Message"></textarea>
347+
<div class="mdc-textfield mdc-textfield--textarea mdc-textfield--fullwidth full-width-textarea-example">
348+
<textarea id="full-width-textarea" class="mdc-textfield__input" rows="8"></textarea>
349+
<label for="full-width-textarea" class="mdc-textfield__label">Textarea Label</label>
269350
</div>
270351
</div>
271352
<div>
@@ -293,6 +374,55 @@ <h2>Full-Width Textfields</h2>
293374
}
294375
})();
295376
</script>
377+
<script>
378+
setTimeout(function() {
379+
var tfLeadingEl = document.getElementById('tf-box-leading-example');
380+
var tfLeading = new mdc.textfield.MDCTextfield(tfLeadingEl);
381+
var wrapperLeading = document.getElementById('demo-tf-box-leading-wrapper');
382+
383+
var tfTrailingEl = document.getElementById('tf-box-trailing-example');
384+
var tfTrailing = new mdc.textfield.MDCTextfield(tfTrailingEl);
385+
var wrapperTrailing = document.getElementById('demo-tf-box-trailing-wrapper');
386+
387+
var tfIcons = document.querySelectorAll('.mdc-textfield__icon');
388+
389+
document.getElementById('box-disable-leading-trailing').addEventListener('change', function(evt) {
390+
tfLeading.disabled = evt.target.checked;
391+
tfTrailing.disabled = evt.target.checked;
392+
});
393+
394+
document.getElementById('box-rtl-leading-trailing').addEventListener('change', function(evt) {
395+
if (evt.target.checked) {
396+
wrapperLeading.setAttribute('dir', 'rtl');
397+
wrapperTrailing.setAttribute('dir', 'rtl');
398+
} else {
399+
wrapperLeading.removeAttribute('dir');
400+
wrapperTrailing.removeAttribute('dir');
401+
}
402+
tfLeading.ripple.layout();
403+
tfTrailing.ripple.layout();
404+
});
405+
406+
document.getElementById('box-dark-theme-leading-trailing').addEventListener('change', function(evt) {
407+
wrapperLeading.classList[evt.target.checked ? 'add' : 'remove']('mdc-theme--dark');
408+
wrapperTrailing.classList[evt.target.checked ? 'add' : 'remove']('mdc-theme--dark');
409+
});
410+
411+
document.getElementById('box-dense-leading-trailing').addEventListener('change', function(evt) {
412+
tfLeadingEl.classList[evt.target.checked ? 'add' : 'remove']('mdc-textfield--dense');
413+
tfLeading.ripple.layout();
414+
tfTrailingEl.classList[evt.target.checked ? 'add' : 'remove']('mdc-textfield--dense');
415+
tfTrailing.ripple.layout();
416+
});
417+
418+
document.getElementById('box-unclickable-leading-trailing').addEventListener('change', function(evt) {
419+
[].slice.call(tfIcons).forEach(function (icon) {
420+
icon.setAttribute('tabindex', evt.target.checked ? '-1' : '0');
421+
});
422+
});
423+
424+
}, 0);
425+
</script>
296426
<script>
297427
(function() {
298428
var section = document.getElementById('demo-textfield-wrapper');
@@ -347,26 +477,26 @@ <h2>Full-Width Textfields</h2>
347477
</script>
348478
<script>
349479
(function() {
350-
var section = document.getElementById('demo-textfield-multiline-wrapper');
480+
var section = document.getElementById('demo-textfield-textarea-wrapper');
351481
var tfRoot = section.querySelector('.mdc-textfield');
352482
var tf = new mdc.textfield.MDCTextfield(tfRoot);
353-
document.getElementById('multi-disable').addEventListener('change', function(evt) {
483+
document.getElementById('textarea-disable').addEventListener('change', function(evt) {
354484
var target = evt.target;
355485
tf.disabled = target.checked;
356486
});
357-
document.getElementById('multi-rtl').addEventListener('change', function(evt) {
487+
document.getElementById('textarea-rtl').addEventListener('change', function(evt) {
358488
var target = evt.target;
359489
if (target.checked) {
360490
section.setAttribute('dir', 'rtl');
361491
} else {
362492
section.removeAttribute('dir');
363493
}
364494
});
365-
document.getElementById('multi-dark-theme').addEventListener('change', function(evt) {
495+
document.getElementById('textarea-dark-theme').addEventListener('change', function(evt) {
366496
var target = evt.target;
367497
section.classList[target.checked ? 'add' : 'remove']('mdc-theme--dark');
368498
});
369-
document.getElementById('multi-required').addEventListener('change', function(evt) {
499+
document.getElementById('textarea-required').addEventListener('change', function(evt) {
370500
var target = evt.target;
371501
tfRoot.querySelector('.mdc-textfield__input').required = target.checked;
372502
});
@@ -376,7 +506,7 @@ <h2>Full-Width Textfields</h2>
376506
(function() {
377507
var section = document.getElementById('demo-fullwidth-wrapper');
378508
var tfRoot = section.querySelector('.mdc-textfield');
379-
var tfMultiRoot = section.querySelector('.mdc-textfield--multiline');
509+
var tfMultiRoot = section.querySelector('.mdc-textfield--textarea');
380510
var tf = new mdc.textfield.MDCTextfield(tfRoot);
381511
var tfMulti = new mdc.textfield.MDCTextfield(tfMultiRoot);
382512

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)