semantic-forms 5.1.10 → 5.1.12

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.
@@ -61,6 +61,12 @@
61
61
  <input id="customize-password" name="customize-password" type="password" minlength="8" required data-clear-field-text="Vaporize this text" data-show-password-text="Reveal this password" data-hide-password-text="omg no hide it again!">
62
62
  <p data-invalid-text>Password should be at least 8 characters long.</p>
63
63
  </dd>
64
+
65
+ <dt><label for="input-button-1">Input with button</label></dt>
66
+ <dd>
67
+ <input type="text" id="input-button-1" name="input-button-1" placeholder="This input has a button">
68
+ <button type="button">Go</button>
69
+ </dd>
64
70
  </dl>
65
71
 
66
72
  <dl>
@@ -68,6 +74,20 @@
68
74
  <dd><input type="text" name="single-input" id="single-input"></dd>
69
75
  </dl>
70
76
 
77
+ <dl class="colspan-1">
78
+ <dt><label for="max-content-input"><code>data-max-content</code>text input</label></dt>
79
+ <dd><input type="text" name="max-content-input" id="max-content-input" placeholder="This is a placeholder." value="This is some text." data-max-content></dd>
80
+
81
+ <dt><label for="max-content-select"><code>data-max-content</code> select</label></dt>
82
+ <dd>
83
+ <select name="max-content-select" id="max-content-select" data-max-content>
84
+ <option>Short</option>
85
+ <option>Some really really really really really really really really long text</option>
86
+ <option>This is some medium text</option>
87
+ </select>
88
+ </dd>
89
+ </dl>
90
+
71
91
  <fieldset class="colspan-full">
72
92
  <legend>Fieldset legend</legend>
73
93
 
@@ -145,6 +165,23 @@
145
165
  <dt><label for="file">File field</label></dt>
146
166
  <dd><input id="file" name="file" type="file"></dd>
147
167
 
168
+ <dt><label for="input-button-2">Input with button</label></dt>
169
+ <dd>
170
+ <input type="text" id="input-button-2" name="input-button-2" placeholder="This input has a button" value="John Doe">
171
+ <label for="input-button-2">Some help text that should span the entire width of the input/button combo.</label>
172
+ <input type="submit" value="Submit">
173
+ </dd>
174
+
175
+ <dt><label for="select-button">Select with button</label></dt>
176
+ <dd>
177
+ <select id="select-button" name="select-button">
178
+ <option value="1">Option 1</option>
179
+ <option value="2">Option 2</option>
180
+ <option value="3">Option 3</option>
181
+ </select>
182
+ <button type="submit">Pick</button>
183
+ </dd>
184
+
148
185
  <dt><label for="range">Range field</label></dt>
149
186
  <dd><input id="range" name="range" type="range"></dd>
150
187
 
@@ -366,6 +403,16 @@
366
403
  <textarea name="disable-autosize-textarea" id="disable-autosize-textarea" rows="5" placeholder="e.g. He just kept talking in one incredibly unbroken sentence moving from topic to topic so that no one had a chance to interrupt it was really quite hypnotic." data-disable-autosize>Row 1&#10;Row 2&#10;Row 3&#10;Row 4&#10;Row 5&#10;Row 6</textarea>
367
404
  <label for="disable-autosize-textarea">This <code>textarea</code> element has the <code>data-disable-autosize</code> attribute applied, and has <code>rows</code> set to 5.</label>
368
405
  </dd>
406
+
407
+ <dt><label for="auto-grow-textarea">Auto-grow textarea</label></dt>
408
+ <dd>
409
+ <textarea name="auto-grow-textarea" id="auto-grow-textarea"data-auto-grow>Start typing to see me grow</textarea>
410
+ </dd>
411
+
412
+ <dt><label for="auto-grow-input">Auto-grow input</label></dt>
413
+ <dd>
414
+ <input type="text" name="auto-grow-input" id="auto-grow-input" value="Start typing to see me grow" data-auto-grow>
415
+ </dd>
369
416
  </dl>
370
417
 
371
418
  <h3>Tables</h3>
@@ -391,7 +438,7 @@
391
438
  <td>
392
439
  <menu>
393
440
  <li><button type="button">Button 1</button></li>
394
- <li><button type="button">Button 2</button></li>
441
+ <li><a href="fullDemo.html" class="button-link">Link button 1</a></li>
395
442
  </menu>
396
443
  </td>
397
444
  </tr>
@@ -402,8 +449,8 @@
402
449
  </td>
403
450
  <td>
404
451
  <menu>
405
- <li><button type="button">Button 1</button></li>
406
452
  <li><button type="button">Button 2</button></li>
453
+ <li><a href="fullDemo.html" class="button-link">Link button 2</a></li>
407
454
  </menu>
408
455
  </td>
409
456
  </tr>
@@ -414,8 +461,8 @@
414
461
  </td>
415
462
  <td>
416
463
  <menu>
417
- <li><button type="button">Button 1</button></li>
418
- <li><button type="button">Button 2</button></li>
464
+ <li><button type="button">Button 3</button></li>
465
+ <li><a href="fullDemo.html" class="button-link">Link button 3</a></li>
419
466
  </menu>
420
467
  </td>
421
468
  </tr>
@@ -749,7 +796,7 @@
749
796
  <td>
750
797
  <menu>
751
798
  <li><button type="button">Button 1</button></li>
752
- <li><button type="button">Button 2</button></li>
799
+ <li><a href="fullDemo.html" class="button-link">Link button 1</a></li>
753
800
  </menu>
754
801
  </td>
755
802
  </tr>
@@ -760,8 +807,8 @@
760
807
  </td>
761
808
  <td>
762
809
  <menu>
763
- <li><button type="button">Button 1</button></li>
764
810
  <li><button type="button">Button 2</button></li>
811
+ <li><a href="fullDemo.html" class="button-link">Link button 2</a></li>
765
812
  </menu>
766
813
  </td>
767
814
  </tr>
@@ -772,8 +819,8 @@
772
819
  </td>
773
820
  <td>
774
821
  <menu>
775
- <li><button type="button">Button 1</button></li>
776
- <li><button type="button">Button 2</button></li>
822
+ <li><button type="button">Button 3</button></li>
823
+ <li><a href="fullDemo.html" class="button-link">Link button 3</a></li>
777
824
  </menu>
778
825
  </td>
779
826
  </tr>
@@ -106,6 +106,32 @@
106
106
  </dl>
107
107
  </form>
108
108
 
109
+ <h5>Add inline buttons</h5>
110
+
111
+ <p>Include a button or input with the type "submit" in the <code><!--#<dd>--></code> element to place it next to the input:</p>
112
+
113
+ <pre><code class='language-html' lang='html'><escape>
114
+ <form class="semanticForms" method="post">
115
+ <dl>
116
+ <dt><label for="email">Email address</label></dt>
117
+ <dd>
118
+ <input id="email" name="email" type="email" placeholder="Enter an email address" autocomplete="off">
119
+ <button type="submit">Sign up</button>
120
+ </dd>
121
+ </dl>
122
+ </form>
123
+ </escape></code></pre>
124
+
125
+ <form class="semanticForms" method="post">
126
+ <dl>
127
+ <dt><label for="email">Email address</label></dt>
128
+ <dd>
129
+ <input id="email" name="email" type="email" placeholder="Enter an email address" autocomplete="off">
130
+ <button type="submit">Sign up!</button>
131
+ </dd>
132
+ </dl>
133
+ </form>
134
+
109
135
  <h5 id="custominputfields">Customizing input fields</h5>
110
136
 
111
137
  <p>By default, input fields will display an X icon to clear the text and password fields will also display a show/hide toggle for displaying the password in plain text. You can customize this behavior as follows:</p>
@@ -121,6 +147,13 @@
121
147
  <li>Note that checkboxes and radios should have a <code>title</code> attribute on the label instead of the inputs.</li>
122
148
  </ul>
123
149
  </li>
150
+ <li><p>Allow fixed-width inputs to grow/shrink to their longest content by applying a <code>data-max-content</code> attribute to the input.</p></li>
151
+ <li>
152
+ <p>Create a one-line text input that grows in height by applying a <code>data-auto-grow</code> attribute to a <code>textarea</code> or <code>input</code> (with type "text") element.</p>
153
+ <ul>
154
+ <li>Note that pressing <kbd>Enter</kbd> with this attribute will attempt to submit the form. Use <kbd>Shift + Enter</kbd> to add new lines.</li>
155
+ </ul>
156
+ </li>
124
157
  </ul>
125
158
 
126
159
  <p>You can also disable float labels on a per-field basis with the <code>no-float-label</code> class:</p>
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "url": "https://github.com/rooseveltframework/semantic-forms/graphs/contributors"
9
9
  }
10
10
  ],
11
- "version": "5.1.10",
11
+ "version": "5.1.12",
12
12
  "files": [
13
13
  "dist",
14
14
  "semanticForms.scss",
package/semanticForms.js CHANGED
@@ -7,7 +7,7 @@ const semanticForms = () => {
7
7
 
8
8
  const passwordShow = '<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m1 12s4-8 11-8 11 8 11 8"/><path d="m1 12s4 8 11 8 11-8 11-8"/><circle cx="12" cy="12" r="3"/></g></svg>'
9
9
  const passwordHide = '<svg fill="none" height="256" viewBox="0 0 24 24" width="256" xmlns="http://www.w3.org/2000/svg"><g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="m2 2 20 20"/><path d="m6.71277 6.7226c-3.04798 2.07267-4.71277 5.2774-4.71277 5.2774s3.63636 7 10 7c2.0503 0 3.8174-.7266 5.2711-1.7116m-6.2711-12.23018c.3254-.03809.6588-.05822 1-.05822 6.3636 0 10 7 10 7s-.6918 1.3317-2 2.8335"/><path d="m14 14.2362c-.5308.475-1.2316.7639-2 .7639-1.6569 0-3-1.3431-3-3 0-.8237.33193-1.5698.86932-2.11192"/></g></svg>'
10
- const helpTextIcon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" version="1.1" style="overflow:visible;margin-top:1px;"><rect width="16" height="16" fill="none"/><path fill="currentColor" d="M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z"/></svg>'
10
+ const helpTextIcon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16" version="1.1" style="overflow:visible;"><rect width="16" height="16" fill="none"/><path fill="currentColor" d="M8,10.5c-0.552,0-1,0.448-1,1c0,0.552,0.448,1,1,1c0.552,0,1-0.448,1-1C9,10.948,8.552,10.5,8,10.5z M8,0 C3.582,0,0,3.582,0,8c0,4.418,3.582,8,8,8s8-3.582,8-8C16,3.582,12.418,0,8,0z M12.243,12.243C11.109,13.376,9.603,14,8,14 s-3.109-0.624-4.243-1.757C2.624,11.109,2,9.603,2,8s0.624-3.109,1.757-4.243C4.891,2.624,6.397,2,8,2s3.109,0.624,4.243,1.757 C13.376,4.891,14,6.397,14,8C14,9.603,13.376,11.109,12.243,12.243z M7.927,3.755c-2.248,0-2.76,1.695-2.802,2.906h1.571 c0.028-0.256,0.101-1.418,1.221-1.418c0.672,0,1.206,0.406,1.206,1.175c0,0.695-0.724,1.155-1.303,1.711 C7.241,8.685,7.168,9.325,7.168,9.824V10c0.146,0,1.615,0,1.615,0V9.824c0-1.256,1.967-1.594,1.967-3.541 C10.75,5.059,9.874,3.755,7.927,3.755z"/></svg>'
11
11
 
12
12
  const nodeNameLookup = ['TEXTAREA', 'SELECT']
13
13
  const inputTypeLookup = ['checkbox', 'color', 'date', 'datetime-local', 'email', 'file', 'image', 'month', 'number', 'password', 'radio', 'range', 'search', 'tel', 'text', 'time', 'url', 'week']
@@ -21,7 +21,7 @@ const semanticForms = () => {
21
21
 
22
22
  // update each input in the semantic form
23
23
  const inputs = Array.from(form.querySelectorAll('input, textarea, select'))
24
- for (const input of inputs) {
24
+ for (let input of inputs) {
25
25
  // ignore input if it has previously been formatted
26
26
  if (input.classList.contains('semanticform') || !input.id) continue
27
27
 
@@ -45,7 +45,6 @@ const semanticForms = () => {
45
45
  input.classList.add('semanticform')
46
46
 
47
47
  // #region create labels
48
-
49
48
  if (type === 'checkbox' || type === 'radio') {
50
49
  // recursively find <dd> element
51
50
  let dd = input.parentNode
@@ -122,7 +121,31 @@ const semanticForms = () => {
122
121
  }
123
122
  // #endregion
124
123
 
125
- // standard inputs
124
+ // #region standard inputs
125
+ // check for auto-grow attribute on textareas
126
+ if (input.getAttribute('data-auto-grow') !== null) {
127
+ // progressively enhance inputs into textareas
128
+ if (input.nodeName === 'INPUT' && input.type === 'text') {
129
+ const newInput = document.createElement('textarea')
130
+ newInput.id = input.id
131
+ newInput.class = input.class
132
+ newInput.innerText = input.value
133
+ newInput.setAttribute('data-auto-grow', '')
134
+ input.replaceWith(newInput)
135
+ input = newInput
136
+
137
+ }
138
+
139
+ if (input.nodeName === 'TEXTAREA') {
140
+ // when pressing enter while this input is focused, we want to submit
141
+ input.addEventListener('keypress', (e) => {
142
+ if (e.key !== 'Enter' || (e.key === 'Enter' && e.shiftKey)) return
143
+ e.preventDefault()
144
+ form.requestSubmit()
145
+ })
146
+ }
147
+ }
148
+
126
149
  if (type !== 'checkbox' && type !== 'radio') {
127
150
  if (!input.getAttribute('placeholder')) input.setAttribute('placeholder', ' ')
128
151
 
@@ -139,7 +162,7 @@ const semanticForms = () => {
139
162
  continue
140
163
  }
141
164
 
142
- // #region clear button
165
+ // #region input clear button
143
166
  if (input.nodeName !== 'SELECT' && type !== 'range') {
144
167
  const clearBtn = document.createElement('button')
145
168
  clearBtn.type = 'button'
@@ -171,6 +194,22 @@ const semanticForms = () => {
171
194
  dd.classList.remove(match)
172
195
  div.classList.add(match)
173
196
  }
197
+
198
+ // check for max-content attribute
199
+ // this may be removed once fully supported in Firefox and Safari: https://caniuse.com/wf-field-sizing
200
+ if (input.getAttribute('data-max-content') !== null) {
201
+ if (!('fieldSizing' in document.createElement('input').style)) {
202
+ const adjustWidth = () => {
203
+ const value = input.value !== '' ? input.value : input.placeholder
204
+ const width = value.length * 8 + 40
205
+ input.style.width = width + 'px'
206
+ input.style.maxWidth = '100%'
207
+ div.style.width = width + 'px'
208
+ }
209
+ adjustWidth()
210
+ input.addEventListener('input', adjustWidth)
211
+ }
212
+ }
174
213
 
175
214
  div.append(dt, dd)
176
215
  dl.append(div)
@@ -178,6 +217,7 @@ const semanticForms = () => {
178
217
  // determine visibility of newly created <div>
179
218
  if (dt.style.display === 'none' && dd.style.display === 'none') div.style.display = 'none'
180
219
  }
220
+ // #endregion
181
221
 
182
222
  // handle file input clear btn, cannot be handled with CSS
183
223
  if (type === 'file') {
@@ -301,6 +341,22 @@ const semanticForms = () => {
301
341
  input.dispatchEvent(new Event('input', { bubbles: true }))
302
342
  }
303
343
 
344
+ // progressively enhance textarea for Firefox and Safari
345
+ // this may be removed once fully supported in Firefox and Safari: https://caniuse.com/wf-field-sizing
346
+ if (input.getAttribute('data-auto-grow') !== null) {
347
+ const adjustHeight = () => {
348
+ if (input.value.length) {
349
+ input.style.height = input.scrollHeight + 'px'
350
+ } else {
351
+ input.style.height = window.getComputedStyle(form).getPropertyValue('--semanticFormsInputHeight')
352
+ }
353
+ }
354
+
355
+ // set initial height to semantic-forms CSS variable
356
+ input.style.height = window.getComputedStyle(form).getPropertyValue('--semanticFormsInputHeight')
357
+ input.addEventListener('input', adjustHeight)
358
+ }
359
+
304
360
  // shifts the clear button to the right if a scrollbar is present
305
361
  const shiftClearBtn = () => {
306
362
  const clearBtn = input.parentElement?.querySelector('button.clear')