semantic-forms 5.3.13 → 5.3.14
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/CHANGELOG.md +11 -0
- package/dist/semantic-forms.cjs +49 -40
- package/dist/semantic-forms.cjs.map +1 -1
- package/dist/semantic-forms.css +691 -749
- package/dist/semantic-forms.css.map +1 -1
- package/dist/semantic-forms.js +49 -40
- package/dist/semantic-forms.js.map +1 -1
- package/dist/semantic-forms.min.js +1 -1
- package/dist/semantic-forms.min.js.map +1 -1
- package/dist/semantic-forms.min.mjs +1 -1
- package/dist/semantic-forms.min.mjs.map +1 -1
- package/dist/semantic-forms.mjs +49 -40
- package/dist/semantic-forms.mjs.map +1 -1
- package/docs/statics/css/semantic-forms-styles.scss +61 -0
- package/docs/statics/js/semantic-forms-demo.js +4 -0
- package/docs/statics/pages/layout.html +259 -0
- package/docs/statics/pages/theming.html +28 -0
- package/package.json +2 -2
- package/semanticForms.scss +18 -11
|
@@ -459,6 +459,265 @@
|
|
|
459
459
|
</p>
|
|
460
460
|
</form>
|
|
461
461
|
|
|
462
|
+
<h2 id="customlayout">Your own layout</h2>
|
|
463
|
+
|
|
464
|
+
<p>To lay a form out yourself while still using the recommended markup and the way Semantic Forms styles the controls, add the <code>customLayout</code> class to the <code><!--#<form>--></code>, a <code><!--#<fieldset>--></code> or a <code><!--#<dl>--></code>. On a fieldset it covers every <code><!--#<dl>--></code> inside it, the same way the <code>colspan-#</code> classes do.</p>
|
|
465
|
+
|
|
466
|
+
<p>Inside it, none of the library's layout of the <code><!--#<dl>--></code> applies: no responsive grid, no <code>colspan-#</code>, <code>col-#</code> or <code>align-*</code> classes, no sizing of the <code><!--#<div>--></code> and <code><!--#<dd>--></code> elements, no float labels, and no room kept beside a field for a clear button. The JavaScript adds, moves and hides nothing around the fields there: no float labels, no clear or show password buttons, no wrapping <code><!--#<div>--></code>, no extra label beside a single checkbox or switch, no required asterisk or help icon, and no value appended to the label of a <code>data-display-value</code> range. A <code><!--#<dt>--></code> label beside a <code><!--#<dd>--></code> that only holds a button stays visible too.</p>
|
|
467
|
+
|
|
468
|
+
<p>What still applies is everything that styles the controls themselves: text and number fields, selects and their arrow, buttons and button menus, checkboxes, switches, range sliders and color pickers, along with their focus, disabled, invalid and warning styles, the fieldsets and legends, and the theming variables. Switches can still be dragged, textareas still grow to fit their text, and <code>data-focus-key</code> keyboard shortcuts still work, though the shortcut is put in the field's <code>title</code> rather than drawn over the field.</p>
|
|
469
|
+
|
|
470
|
+
<p>This example puts each field's label and a description in its <code><!--#<dt>--></code> and the control in its <code><!--#<dd>--></code>, and lays each <code><!--#<div>--></code> out as a row:</p>
|
|
471
|
+
|
|
472
|
+
<pre><code class='language-html' lang='html'><escape>
|
|
473
|
+
<form class="semanticForms customLayout settingsExample">
|
|
474
|
+
<fieldset>
|
|
475
|
+
<legend>Playback</legend>
|
|
476
|
+
<dl>
|
|
477
|
+
<div>
|
|
478
|
+
<dt>
|
|
479
|
+
<label for="custom-ex-crossfade">Crossfade</label>
|
|
480
|
+
<p>Milliseconds to blend the end of one track into the next.</p>
|
|
481
|
+
</dt>
|
|
482
|
+
<dd>
|
|
483
|
+
<input type="number" id="custom-ex-crossfade" name="custom-ex-crossfade" min="0" max="10000" value="1000" required>
|
|
484
|
+
<p data-invalid-text>Enter a number from 0 to 10000.</p>
|
|
485
|
+
</dd>
|
|
486
|
+
</div>
|
|
487
|
+
|
|
488
|
+
<div>
|
|
489
|
+
<dt>
|
|
490
|
+
<label for="custom-ex-output">Output device</label>
|
|
491
|
+
<p>Where the sound goes.</p>
|
|
492
|
+
</dt>
|
|
493
|
+
<dd>
|
|
494
|
+
<select id="custom-ex-output" name="custom-ex-output">
|
|
495
|
+
<option>System default</option>
|
|
496
|
+
<option>Headphones</option>
|
|
497
|
+
</select>
|
|
498
|
+
</dd>
|
|
499
|
+
</div>
|
|
500
|
+
|
|
501
|
+
<div>
|
|
502
|
+
<dt>
|
|
503
|
+
<label for="custom-ex-gapless">Gapless playback</label>
|
|
504
|
+
<p>Play albums without a pause between tracks.</p>
|
|
505
|
+
</dt>
|
|
506
|
+
<dd><input type="checkbox" switch id="custom-ex-gapless" name="custom-ex-gapless" checked></dd>
|
|
507
|
+
</div>
|
|
508
|
+
|
|
509
|
+
<div>
|
|
510
|
+
<dt>
|
|
511
|
+
<label for="custom-ex-volume">Interface volume</label>
|
|
512
|
+
<p>How loud clicks and alerts are.</p>
|
|
513
|
+
</dt>
|
|
514
|
+
<dd>
|
|
515
|
+
<input type="range" id="custom-ex-volume" name="custom-ex-volume" value="80">
|
|
516
|
+
<output for="custom-ex-volume">80</output>
|
|
517
|
+
</dd>
|
|
518
|
+
</div>
|
|
519
|
+
</dl>
|
|
520
|
+
</fieldset>
|
|
521
|
+
|
|
522
|
+
<fieldset>
|
|
523
|
+
<legend>Appearance</legend>
|
|
524
|
+
<dl>
|
|
525
|
+
<div>
|
|
526
|
+
<dt>
|
|
527
|
+
<label for="custom-ex-accent">Accent color</label>
|
|
528
|
+
<p>Used for highlights and switches.</p>
|
|
529
|
+
</dt>
|
|
530
|
+
<dd><input type="color" id="custom-ex-accent" name="custom-ex-accent" value="#3366cc"></dd>
|
|
531
|
+
</div>
|
|
532
|
+
|
|
533
|
+
<div>
|
|
534
|
+
<dt>
|
|
535
|
+
<label id="custom-ex-columns-label">Visible columns</label>
|
|
536
|
+
<p>Which columns the track list shows.</p>
|
|
537
|
+
</dt>
|
|
538
|
+
<dd>
|
|
539
|
+
<ul aria-labelledby="custom-ex-columns-label">
|
|
540
|
+
<li><input type="checkbox" id="custom-ex-artist" name="custom-ex-columns" value="artist" checked> <label for="custom-ex-artist">Artist</label></li>
|
|
541
|
+
<li><input type="checkbox" id="custom-ex-album" name="custom-ex-columns" value="album" checked> <label for="custom-ex-album">Album</label></li>
|
|
542
|
+
<li><input type="checkbox" id="custom-ex-year" name="custom-ex-columns" value="year"> <label for="custom-ex-year">Year</label></li>
|
|
543
|
+
</ul>
|
|
544
|
+
</dd>
|
|
545
|
+
</div>
|
|
546
|
+
|
|
547
|
+
<div>
|
|
548
|
+
<dt>
|
|
549
|
+
<label for="custom-ex-reset">Reset settings</label>
|
|
550
|
+
<p>Put everything back how it was.</p>
|
|
551
|
+
</dt>
|
|
552
|
+
<dd><button type="button" id="custom-ex-reset">Reset</button></dd>
|
|
553
|
+
</div>
|
|
554
|
+
</dl>
|
|
555
|
+
</fieldset>
|
|
556
|
+
</form>
|
|
557
|
+
</escape></code></pre>
|
|
558
|
+
|
|
559
|
+
<p>With CSS of your own for the rows, along these lines:</p>
|
|
560
|
+
|
|
561
|
+
<pre><code class='language-css' lang='css'><escape>
|
|
562
|
+
form.settingsExample dl {
|
|
563
|
+
display: flex;
|
|
564
|
+
flex-direction: column;
|
|
565
|
+
gap: 15px;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/* each row: the label and description on the left, the control on the right */
|
|
569
|
+
form.settingsExample dl > div {
|
|
570
|
+
display: flex;
|
|
571
|
+
flex-wrap: wrap;
|
|
572
|
+
align-items: center;
|
|
573
|
+
justify-content: space-between;
|
|
574
|
+
gap: 10px 20px;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
form.settingsExample dt {
|
|
578
|
+
flex: 1 1 250px;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
form.settingsExample dt p {
|
|
582
|
+
margin: 2px 0 0;
|
|
583
|
+
font-size: small;
|
|
584
|
+
color: var(--semanticFormsPlaceholderColor);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
form.settingsExample dd {
|
|
588
|
+
flex: 0 0 200px;
|
|
589
|
+
margin-left: auto;
|
|
590
|
+
display: flex;
|
|
591
|
+
flex-direction: column;
|
|
592
|
+
align-items: flex-end;
|
|
593
|
+
gap: 5px;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
form.settingsExample dd:has(output) {
|
|
597
|
+
flex-direction: row;
|
|
598
|
+
align-items: center;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/* outside the grid a list of checkboxes is a wrapping row, so stack it instead */
|
|
602
|
+
form.settingsExample dd ul {
|
|
603
|
+
margin: 0;
|
|
604
|
+
padding: 0;
|
|
605
|
+
flex-direction: column;
|
|
606
|
+
align-items: flex-start;
|
|
607
|
+
gap: 5px;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
form.settingsExample dd li {
|
|
611
|
+
gap: 5px;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
form.settingsExample input[type=number] {
|
|
615
|
+
width: 110px;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
form.settingsExample input[type=color] {
|
|
619
|
+
width: 80px;
|
|
620
|
+
}
|
|
621
|
+
</escape></code></pre>
|
|
622
|
+
|
|
623
|
+
<p>And a line of JavaScript to keep the range's <code><!--#<output>--></code> up to date, since <code>data-display-value</code> writes into the label, which is left alone here:</p>
|
|
624
|
+
|
|
625
|
+
<pre><code class='language-javascript'><escape>
|
|
626
|
+
const volume = document.getElementById('custom-ex-volume')
|
|
627
|
+
volume.addEventListener('input', () => { volume.nextElementSibling.value = volume.value })
|
|
628
|
+
</escape></code></pre>
|
|
629
|
+
|
|
630
|
+
<form class="semanticForms customLayout settingsExample">
|
|
631
|
+
<fieldset>
|
|
632
|
+
<legend>Playback</legend>
|
|
633
|
+
<dl>
|
|
634
|
+
<div>
|
|
635
|
+
<dt>
|
|
636
|
+
<label for="custom-ex-crossfade">Crossfade</label>
|
|
637
|
+
<p>Milliseconds to blend the end of one track into the next.</p>
|
|
638
|
+
</dt>
|
|
639
|
+
<dd>
|
|
640
|
+
<input type="number" id="custom-ex-crossfade" name="custom-ex-crossfade" min="0" max="10000" value="1000" required>
|
|
641
|
+
<p data-invalid-text>Enter a number from 0 to 10000.</p>
|
|
642
|
+
</dd>
|
|
643
|
+
</div>
|
|
644
|
+
|
|
645
|
+
<div>
|
|
646
|
+
<dt>
|
|
647
|
+
<label for="custom-ex-output">Output device</label>
|
|
648
|
+
<p>Where the sound goes.</p>
|
|
649
|
+
</dt>
|
|
650
|
+
<dd>
|
|
651
|
+
<select id="custom-ex-output" name="custom-ex-output">
|
|
652
|
+
<option>System default</option>
|
|
653
|
+
<option>Headphones</option>
|
|
654
|
+
</select>
|
|
655
|
+
</dd>
|
|
656
|
+
</div>
|
|
657
|
+
|
|
658
|
+
<div>
|
|
659
|
+
<dt>
|
|
660
|
+
<label for="custom-ex-gapless">Gapless playback</label>
|
|
661
|
+
<p>Play albums without a pause between tracks.</p>
|
|
662
|
+
</dt>
|
|
663
|
+
<dd><input type="checkbox" switch id="custom-ex-gapless" name="custom-ex-gapless" checked></dd>
|
|
664
|
+
</div>
|
|
665
|
+
|
|
666
|
+
<div>
|
|
667
|
+
<dt>
|
|
668
|
+
<label for="custom-ex-volume">Interface volume</label>
|
|
669
|
+
<p>How loud clicks and alerts are.</p>
|
|
670
|
+
</dt>
|
|
671
|
+
<dd>
|
|
672
|
+
<input type="range" id="custom-ex-volume" name="custom-ex-volume" value="80">
|
|
673
|
+
<output for="custom-ex-volume">80</output>
|
|
674
|
+
</dd>
|
|
675
|
+
</div>
|
|
676
|
+
</dl>
|
|
677
|
+
</fieldset>
|
|
678
|
+
|
|
679
|
+
<fieldset>
|
|
680
|
+
<legend>Appearance</legend>
|
|
681
|
+
<dl>
|
|
682
|
+
<div>
|
|
683
|
+
<dt>
|
|
684
|
+
<label for="custom-ex-accent">Accent color</label>
|
|
685
|
+
<p>Used for highlights and switches.</p>
|
|
686
|
+
</dt>
|
|
687
|
+
<dd><input type="color" id="custom-ex-accent" name="custom-ex-accent" value="#3366cc"></dd>
|
|
688
|
+
</div>
|
|
689
|
+
|
|
690
|
+
<div>
|
|
691
|
+
<dt>
|
|
692
|
+
<label id="custom-ex-columns-label">Visible columns</label>
|
|
693
|
+
<p>Which columns the track list shows.</p>
|
|
694
|
+
</dt>
|
|
695
|
+
<dd>
|
|
696
|
+
<ul aria-labelledby="custom-ex-columns-label">
|
|
697
|
+
<li><input type="checkbox" id="custom-ex-artist" name="custom-ex-columns" value="artist" checked> <label for="custom-ex-artist">Artist</label></li>
|
|
698
|
+
<li><input type="checkbox" id="custom-ex-album" name="custom-ex-columns" value="album" checked> <label for="custom-ex-album">Album</label></li>
|
|
699
|
+
<li><input type="checkbox" id="custom-ex-year" name="custom-ex-columns" value="year"> <label for="custom-ex-year">Year</label></li>
|
|
700
|
+
</ul>
|
|
701
|
+
</dd>
|
|
702
|
+
</div>
|
|
703
|
+
|
|
704
|
+
<div>
|
|
705
|
+
<dt>
|
|
706
|
+
<label for="custom-ex-reset">Reset settings</label>
|
|
707
|
+
<p>Put everything back how it was.</p>
|
|
708
|
+
</dt>
|
|
709
|
+
<dd><button type="button" id="custom-ex-reset">Reset</button></dd>
|
|
710
|
+
</div>
|
|
711
|
+
</dl>
|
|
712
|
+
</fieldset>
|
|
713
|
+
</form>
|
|
714
|
+
|
|
715
|
+
<p>To show a message when a field is invalid, put an element with the <code>data-invalid-text</code> attribute after the control in the same <code><!--#<dd>--></code>, as the crossfade field above does. It is hidden until the field is invalid, which is when the browser's own validation or an <code>invalid</code> class you add says so, and it is shown in the invalid color. A <code>warn</code> class on the control shows it in the same way. It has to come after the control and share its parent, since it is found with a sibling selector.</p>
|
|
716
|
+
|
|
717
|
+
<p>The controls fill the width of whatever holds them, so give them a width of your own where that is not what you want. A list of checkboxes or radios outside the grid is laid out as a wrapping row with the browser's own list spacing, which the example above stacks into a column instead. The library's control styles weigh no more than the form's class and the element, so an ordinary rule such as <code>form.settingsExample input[type=number]</code> overrides them without needing an id or <code>!important</code>.</p>
|
|
718
|
+
|
|
719
|
+
<p>Leaving the <code><!--#<dl>--></code> out altogether works too. Everything described above as still applying is styled wherever it sits in a <code>semanticForms</code> form, and the grid, float labels and clear buttons only ever apply inside a <code><!--#<dl>--></code>, so markup of your own without one needs no extra class.</p>
|
|
720
|
+
|
|
462
721
|
<h2 id="tabs">Tabs</h2>
|
|
463
722
|
|
|
464
723
|
<p>Add the <code>tabs</code> class to an element holding one <code><!--#<fieldset>--></code> per tab. Each fieldset's <code><!--#<legend>--></code> names its tab.</p>
|
|
@@ -23,6 +23,34 @@ form.semanticForms {
|
|
|
23
23
|
}
|
|
24
24
|
</escape></code></pre>
|
|
25
25
|
|
|
26
|
+
<p>The built-in values carry no selector weight of their own, including the dark mode ones, so an override like the one above wins in both light mode and dark mode, and does not need to be heavier than <code>form.semanticForms</code>. To change a value in dark mode only, put the override inside a dark mode media query, and add a rule for the <code>dark</code> class if you use it:</p>
|
|
27
|
+
|
|
28
|
+
<pre><code class='language-css' lang='css'><escape>
|
|
29
|
+
@media (prefers-color-scheme: dark) {
|
|
30
|
+
form.semanticForms:not(.light) {
|
|
31
|
+
--semanticFormsSwitchOnColor: limegreen;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
form.semanticForms.dark {
|
|
36
|
+
--semanticFormsSwitchOnColor: limegreen;
|
|
37
|
+
}
|
|
38
|
+
</escape></code></pre>
|
|
39
|
+
|
|
40
|
+
<h3 id="pagebackground">Page background</h3>
|
|
41
|
+
|
|
42
|
+
<p>Semantic Forms only styles its own forms, so it leaves the page behind them alone. Its colors are designed against a white page in light mode and a black one in dark mode, which is what <code>--semanticFormsPageBgColor</code> holds for each mode. The library does not paint anything with it by default.</p>
|
|
43
|
+
|
|
44
|
+
<p>It matters when the page and the form are in different modes, such as a form in dark mode on a light page. A legend straddles the top border of its fieldset, so its text is drawn partly over whatever is behind the form rather than over the fieldset, and dark mode's light legend text is hard to read on a light page. Give the form the background it was designed against to fix that:</p>
|
|
45
|
+
|
|
46
|
+
<pre><code class='language-css' lang='css'><escape>
|
|
47
|
+
form.semanticForms {
|
|
48
|
+
background-color: var(--semanticFormsPageBgColor);
|
|
49
|
+
}
|
|
50
|
+
</escape></code></pre>
|
|
51
|
+
|
|
52
|
+
<p>The variable is set on the form, so it is available to the form and everything inside it, but not to the page around it. To paint the whole page instead, give the page's own background the same colors: <code>#fff</code> in light mode and <code>#000</code> in dark mode, unless you have overridden the variable.</p>
|
|
53
|
+
|
|
26
54
|
<h3 id="widthvariables">Controlling how wide fields get</h3>
|
|
27
55
|
|
|
28
56
|
<p>Fields are laid out in a grid whose columns grow to fill the available width. Three variables control the sizing:</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.3.
|
|
11
|
+
"version": "5.3.14",
|
|
12
12
|
"files": [
|
|
13
13
|
"dist",
|
|
14
14
|
"semanticForms.scss",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@playwright/test": "1.63.0",
|
|
37
37
|
"eslint-plugin-html": "8.2.1",
|
|
38
38
|
"nyc": "18.0.0",
|
|
39
|
-
"sass": "1.105.
|
|
39
|
+
"sass": "1.105.1",
|
|
40
40
|
"standard": "17.1.2",
|
|
41
41
|
"terser-webpack-plugin": "5.6.1",
|
|
42
42
|
"webpack": "5.111.1",
|
package/semanticForms.scss
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
@use 'styles/colspan.scss';
|
|
5
5
|
@use 'styles/tabs.scss';
|
|
6
6
|
@use 'styles/lowFlow.scss';
|
|
7
|
+
@use 'styles/layoutScope.scss' as *;
|
|
7
8
|
|
|
8
9
|
.semanticForms {
|
|
9
10
|
fieldset {
|
|
@@ -22,12 +23,17 @@
|
|
|
22
23
|
border: var(--semanticFormsNestedFieldsetBorder);
|
|
23
24
|
margin: 0;
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// add opacity to styled inputs to prevent blending with background
|
|
30
|
+
//
|
|
31
|
+
// the nesting is wrapped in :where so that this weighs no more than the field rules it overrides, and wins over them by coming later. a search field keeps its own background, as it always has
|
|
32
|
+
:where(fieldset fieldset, fieldset details) {
|
|
33
|
+
input:where(:not([type=submit], [type=reset], [type=button], [type=image], [type=checkbox], [type=radio], [type=search])),
|
|
34
|
+
select,
|
|
35
|
+
textarea {
|
|
36
|
+
background-color: var(--semanticFormsNestedInputBgColor);
|
|
31
37
|
}
|
|
32
38
|
}
|
|
33
39
|
|
|
@@ -115,7 +121,7 @@
|
|
|
115
121
|
}
|
|
116
122
|
}
|
|
117
123
|
|
|
118
|
-
& > dl:first-of-type {
|
|
124
|
+
& > dl:first-of-type#{$notCustomLayout} {
|
|
119
125
|
margin-top: 15px;
|
|
120
126
|
margin-bottom: 15px;
|
|
121
127
|
}
|
|
@@ -137,7 +143,8 @@
|
|
|
137
143
|
transform: rotate(0deg);
|
|
138
144
|
}
|
|
139
145
|
|
|
140
|
-
dl
|
|
146
|
+
// the grid layout. none of it applies inside a customLayout element, where the app lays the <dl> out itself: see layoutScope.scss
|
|
147
|
+
dl#{$notCustomLayout} {
|
|
141
148
|
display: grid;
|
|
142
149
|
grid-template-columns: repeat(auto-fit, minmax(var(--semanticFormsInputMinWidth), var(--semanticFormsInputColumnMaxWidth)));
|
|
143
150
|
gap: 10px;
|
|
@@ -316,17 +323,17 @@
|
|
|
316
323
|
}
|
|
317
324
|
}
|
|
318
325
|
|
|
319
|
-
div:has(.align-start) {
|
|
326
|
+
div#{$notCustomLayout}:has(.align-start) {
|
|
320
327
|
display: flex;
|
|
321
328
|
justify-content: start;
|
|
322
329
|
}
|
|
323
330
|
|
|
324
|
-
div:has(.align-center) {
|
|
331
|
+
div#{$notCustomLayout}:has(.align-center) {
|
|
325
332
|
display: flex;
|
|
326
333
|
justify-content: center;
|
|
327
334
|
}
|
|
328
335
|
|
|
329
|
-
div:has(.align-end) {
|
|
336
|
+
div#{$notCustomLayout}:has(.align-end) {
|
|
330
337
|
display: flex;
|
|
331
338
|
justify-content: end;
|
|
332
339
|
}
|