@markout-lang/bootstrap-kit 0.2.1 → 0.2.2

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
@@ -108,6 +108,19 @@ That holds however deeply the component sits: a `bs-toast :aka="saved"`
108
108
  written inside a `bs-toast-container` is still named where you wrote it, so
109
109
  `saved.open = true` reaches it from anywhere on the page.
110
110
 
111
+ `bs-input` and `bs-textarea` answer `valid` the same way -- is there a value,
112
+ and does it pass `check`? -- which is what a submit button needs:
113
+
114
+ ```html
115
+ <bs-input :aka="email" :label="Email" :check=${v => v.includes('@')} />
116
+ <bs-button :disabled=${!email.valid}>Send</bs-button>
117
+ ```
118
+
119
+ It is not the negation of the error state. An empty field is not marked
120
+ wrong, which is what keeps a form from opening in red, and it is not
121
+ something to submit either -- so it shows nothing and answers `false`.
122
+ `required` is what makes empty an error as well as a gap.
123
+
111
124
  **Optional regions are `:if`.** A region that exists only when a parameter
112
125
  was given is written `:if=${header}`, and nothing inside it evaluates while
113
126
  the condition is false — which is what makes `${user.name}` safe to write in
@@ -230,6 +243,9 @@ commented.
230
243
  | `bs-range` | `label` `name` `min` `max` `step` `value` `disabled` `showValue` |
231
244
  | `bs-input-group` | `prefix` `suffix` `size` |
232
245
 
246
+ `bs-input` and `bs-textarea` also answer `valid`, which is read rather than
247
+ passed -- see *Values are read and written* above.
248
+
233
249
  ### Components
234
250
 
235
251
  | Tag | Parameters |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markout-lang/bootstrap-kit",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Bootstrap 5.3 as Markout components: one part per component, with the id wiring, the ARIA attributes and the repetition written once",
5
5
  "repository": {
6
6
  "type": "git",
package/parts/input.htm CHANGED
@@ -19,6 +19,17 @@
19
19
  invalid once it is non-empty and fails `:check`. Empty is neutral, so a
20
20
  form doesn't open covered in errors. `:required` extends that to empty.
21
21
 
22
+ `:valid` is the other side of that, and what a form's own controls read —
23
+
24
+ <bs-input :aka="email" :label="Email" :check=${v => v.includes('@')} />
25
+ <bs-button :disabled=${!email.valid}>Send</bs-button>
26
+
27
+ It is deliberately NOT the negation of the error state, which is the one
28
+ thing about it worth knowing. An untouched field is not wrong — that is
29
+ what keeps the form out of red — and it is also not something to submit.
30
+ So empty answers `false` here while showing nothing, and `:required` is
31
+ what makes empty an error as well as a gap.
32
+
22
33
  Floating labels are the same control with the label after the input
23
34
  instead of before it — Bootstrap's CSS keys off that order — so the two
24
35
  layouts are two regions rather than one with a class toggled on it.
@@ -49,6 +60,9 @@
49
60
  :_invalid=${_empty ? required : !check(value)}
50
61
  :_class=${['form-control', size ? `form-control-${size}` : '']
51
62
  .filter(s => s).join(' ')}
63
+
64
+ // read from outside: is there a value, and does it pass?
65
+ :valid=${!_empty && check(value)}
52
66
  >
53
67
  <!--- plain layout: label, control, feedback -->
54
68
  <div :if=${!floating}>
@@ -123,6 +137,9 @@
123
137
  :_helpId=${`bs-textarea-help-${$id}`}
124
138
  :_empty=${value === '' || value == null}
125
139
  :_invalid=${_empty ? required : !check(value)}
140
+
141
+ // read from outside, as bs-input's is
142
+ :valid=${!_empty && check(value)}
126
143
  >
127
144
  <label class="form-label"
128
145
  for=${_id}
package/parts/navbar.htm CHANGED
@@ -40,6 +40,17 @@
40
40
  extra,
41
41
  ].filter(s => s).join(' ')}
42
42
 
43
+ // The gap under the links is only wanted while they are stacked, which
44
+ // is up to `expand` and not to any one breakpoint: left at `mb-lg-0` it
45
+ // would survive into a bar that has already gone horizontal and push the
46
+ // links up off the brand's line. A navbar that never collapses has no
47
+ // stacked state to space out, hence the plain `mb-0`.
48
+ :_navClass=${[
49
+ 'navbar-nav',
50
+ 'me-auto',
51
+ expand ? `mb-2 mb-${expand}-0` : 'mb-0',
52
+ ].join(' ')}
53
+
43
54
  class=${_class}
44
55
  :class-sticky-top=${sticky}
45
56
  :class-fixed-top=${fixed}
@@ -59,7 +70,7 @@
59
70
  </button>
60
71
 
61
72
  <div class="collapse navbar-collapse" id=${_id}>
62
- <ul class="navbar-nav me-auto mb-2 mb-lg-0">
73
+ <ul class=${_navClass}>
63
74
  <li class="nav-item" :for-each=${items} :for-as="item">
64
75
  <a class="nav-link"
65
76
  :class-active=${item.active}