@markout-lang/bootstrap-kit 0.2.2 → 0.4.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
@@ -24,8 +24,15 @@ logical root it declares. See [npm kits](../../docs/design/npm-kits.md) —
24
24
  including the other case, a kit vendored into a docroot, which is imported by
25
25
  its path instead.
26
26
 
27
- `all.htm` pulls in everything. Each part imports `base.htm` itself and a file
28
- is only imported once per page, so importing parts by hand never leaves
27
+ `all.htm` pulls in everything, and that is the ordinary thing to import: a
28
+ component no tag on the page uses is dropped before the page is served, so
29
+ what the whole kit costs is what you actually reach for. A page importing all
30
+ of it and using one `bs-alert` serves 4.7KB where the same page with that
31
+ pass turned off is 19.8KB.
32
+
33
+ Importing parts by hand is for when you want to be explicit rather than to
34
+ save weight — it is worth 134 bytes on that page. Each part imports
35
+ `base.htm` itself and a file is only imported once, so it never leaves
29
36
  Bootstrap out:
30
37
 
31
38
  ```html
@@ -33,6 +40,20 @@ Bootstrap out:
33
40
  <:import src="/npm/@markout-lang/bootstrap-kit/parts/card.htm" />
34
41
  ```
35
42
 
43
+ Those 134 bytes are the pass being careful rather than a component sneaking
44
+ through, and they are two stencils: `bs-alert` names `<bs-close>` in its
45
+ body, `bs-close` lives in `button.htm`, and so `bs-button` and `bs-badge`
46
+ count as used. A tag named inside another definition's body is kept even
47
+ when that definition is itself dropped — narrowing that needs the usage
48
+ graph rather than a flat set, and getting it wrong deletes markup a page
49
+ needs.
50
+
51
+ Both pages there do the same things, which is what makes the comparison mean
52
+ anything. `theme.htm` used to be the exception: importing `all.htm` brought a
53
+ pre-paint script the hand-picked page never got, so the whole-kit page was
54
+ 278 bytes larger for doing something more. Colour modes are opt-in now, so
55
+ that difference belongs to whichever page asks for them.
56
+
36
57
  Every component below is shown one after another in the [kitchen
37
58
  sink](https://markout.dev/demos/kitchen-sink), and
38
59
  [Orbit](https://markout.dev/demos/orbit) is an operations dashboard built out
@@ -65,24 +86,31 @@ all of them.
65
86
  **Parameters for the chrome, the slot for the content.** What a card *has* —
66
87
  a title, a footer, an image — is a parameter. What it *contains* is slotted.
67
88
 
68
- **`:extra` adds classes.** A `class` written at a usage site *replaces* the
89
+ **`class+=` adds classes.** A `class` written at a usage site *replaces* the
69
90
  one a definition sets, which is the language's rule and not something this
70
- kit overrides. So every component takes `:extra` for the utility classes a
71
- caller wants on top:
91
+ kit overrides and since every component here computes its own, writing one
92
+ gets you a warning naming `class+=`. That is the spelling to reach for:
72
93
 
73
94
  ```html
74
- <bs-alert :variant="warning" :extra="mb-0">Careful</bs-alert>
95
+ <bs-alert ::variant="warning" class+="mb-0">Careful</bs-alert>
96
+ <bs-alert ::dismissible class-="fade">No animation, please</bs-alert>
75
97
  ```
76
98
 
99
+ Every component used to declare an `::extra` parameter for this, hand-rolled
100
+ into its own class list — 28 files agreeing on a convention the language now
101
+ has a spelling for. `::bodyExtra` on `bs-card` stays, and says why the rest
102
+ went: `class+=` reaches a component's own element, and the card's *body* is a
103
+ different element.
104
+
77
105
  **Comments in a tag: `//` for one line, `/* … */` for more.** Both are
78
106
  stripped at parse time. A run of `//` lines reads as a stack of fragments;
79
107
  one block says it once.
80
108
 
81
- **Lists are arrays.** `:items`, `:options`, `:columns`, `:rows`, `:slides`.
109
+ **Lists are arrays.** `::items`, `::options`, `::columns`, `::rows`, `::slides`.
82
110
  The default value of each is the shape it expects — read the definition to
83
111
  see it.
84
112
 
85
- **Callbacks are values, not events.** `:select`, `:check` and `:link` are
113
+ **Callbacks are values, not events.** `::select`, `::check` and `::link` are
86
114
  functions the component calls. `:on-click` and friends stay what they are in
87
115
  the language: DOM events.
88
116
 
@@ -95,13 +123,13 @@ and a plugin left holding a removed element leaves its backdrop, its popper
95
123
  and the page's scroll lock behind.
96
124
 
97
125
  **Values are read and written.** `bs-input`, `bs-select`, `bs-check`,
98
- `bs-range`, `bs-modal`, `bs-offcanvas` and `bs-toast` keep `:value` or
99
- `:open` in step with what is on screen. Name the instance and read it from
126
+ `bs-range`, `bs-modal`, `bs-offcanvas` and `bs-toast` keep `::value` or
127
+ `::open` in step with what is on screen. Name the instance and read it from
100
128
  anywhere:
101
129
 
102
130
  ```html
103
- <bs-input :aka="email" :label="Email" :type="email" />
104
- <bs-button :disabled=${!email.value}>Send</bs-button>
131
+ <bs-input :aka="email" ::label="Email" ::type="email" />
132
+ <bs-button ::disabled=${!email.value}>Send</bs-button>
105
133
  ```
106
134
 
107
135
  That holds however deeply the component sits: a `bs-toast :aka="saved"`
@@ -112,8 +140,8 @@ written inside a `bs-toast-container` is still named where you wrote it, so
112
140
  and does it pass `check`? -- which is what a submit button needs:
113
141
 
114
142
  ```html
115
- <bs-input :aka="email" :label="Email" :check=${v => v.includes('@')} />
116
- <bs-button :disabled=${!email.valid}>Send</bs-button>
143
+ <bs-input :aka="email" ::label="Email" ::check=${v => v.includes('@')} />
144
+ <bs-button ::disabled=${!email.valid}>Send</bs-button>
117
145
  ```
118
146
 
119
147
  It is not the negation of the error state. An empty field is not marked
@@ -155,7 +183,7 @@ it binds the item as `data`. The kit has no use for it: every optional region
155
183
  here renders a parameter it already has a name for.
156
184
 
157
185
  Optional parts of a component are parameters, and a named slot where markup
158
- belongs — `bs-card`'s header is both: `:header` sets the text, and a
186
+ belongs — `bs-card`'s header is both: `::header` sets the text, and a
159
187
  `:slot="header"` replaces it with markup. A `<:slot>` may sit inside a
160
188
  `:for-data` but not inside a `:for-each`, which is what makes that possible.
161
189
 
@@ -165,10 +193,10 @@ The CDN URLs and their hashes are tokens like any other, so a page points the
165
193
  kit at its own copy without forking `base.htm`:
166
194
 
167
195
  ```html
168
- <head ::bsCssUrl="/vendor/bootstrap.min.css"
169
- ::bsJsUrl="/vendor/bootstrap.bundle.min.js"
170
- ::bsCssIntegrity=${null}
171
- ::bsJsIntegrity=${null}>
196
+ <head :const-bsCssUrl="/vendor/bootstrap.min.css"
197
+ :const-bsJsUrl="/vendor/bootstrap.bundle.min.js"
198
+ :const-bsCssIntegrity=${null}
199
+ :const-bsJsIntegrity=${null}>
172
200
  <:import src="/bootstrap-kit/all.htm" />
173
201
  </head>
174
202
  ```
@@ -201,7 +229,7 @@ Four reasons this is worth having rather than a convenience:
201
229
  variables, so restyling everything is setting one value at the import site:
202
230
 
203
231
  ```html
204
- <head ::bsRadius="1rem" ::bsLinkDecoration="none">
232
+ <head :const-bsRadius="1rem" :const-bsLinkDecoration="none">
205
233
  <:import src="/bootstrap-kit/all.htm" />
206
234
  </head>
207
235
  ```
@@ -215,13 +243,21 @@ variables, so restyling everything is setting one value at the import site:
215
243
  | `bsFontSans` | Bootstrap's system stack |
216
244
  | `bsLinkDecoration` | `underline` |
217
245
 
218
- Colour modes are `theme.htm`: an inline pre-paint script so the page never
219
- flashes the wrong mode, and `<bs-theme-toggle />` to switch it.
246
+ Colour modes are `theme.htm`, and they are opt-in: write `<bs-theme-auto />`
247
+ for the behaviour on its own the page follows a stored choice, or the
248
+ system — or a `<bs-theme-toggle />` for the behaviour and a button to drive
249
+ it. Either keeps the inline pre-paint script that stops the page flashing the
250
+ wrong mode; a page that writes neither ships neither, even having imported
251
+ the whole kit.
252
+
253
+ That is `:when-used` doing what it is for. Before it, importing `all.htm`
254
+ gave every page colour modes whether it had asked or not, which is the one
255
+ thing in this kit that DID something merely because a file was imported.
220
256
 
221
257
  ## Components
222
258
 
223
- Every tag also takes `:extra`. Defaults are in the definitions, which are
224
- commented.
259
+ Every tag takes `class+=` and `class-=`, which are the language's and not
260
+ listed here. Defaults are in the definitions, which are commented.
225
261
 
226
262
  ### Content
227
263
 
@@ -239,13 +275,29 @@ commented.
239
275
  | `bs-textarea` | `label` `name` `value` `placeholder` `rows` `help` `disabled` `readonly` `required` `check` `message` |
240
276
  | `bs-select` | `label` `name` `options` `value` `placeholder` `help` `size` `multiple` `disabled` `required` `floating` |
241
277
  | `bs-check` | `label` `type` (`checkbox`/`radio`/`switch`) `name` `value` `checked` `inline` `reverse` `disabled` `help` |
242
- | `bs-check-group` | `legend` `type` `options` `value` `inline` `disabled` |
278
+ | `bs-check-group` | `legend` `type` `options` `value` (see below) `inline` `disabled` |
243
279
  | `bs-range` | `label` `name` `min` `max` `step` `value` `disabled` `showValue` |
244
280
  | `bs-input-group` | `prefix` `suffix` `size` |
245
281
 
246
282
  `bs-input` and `bs-textarea` also answer `valid`, which is read rather than
247
283
  passed -- see *Values are read and written* above.
248
284
 
285
+ **`bs-check-group`'s `::value` is decided by its `::type`**, because that is
286
+ what the two controls mean: a radio group submits one value and a checkbox
287
+ group submits every box that is ticked, under the same name. So a radio
288
+ group's is the selected value or `null`, and a checkbox or switch group's is
289
+ an **array**, in the order the options were given rather than the order they
290
+ were clicked:
291
+
292
+ ```html
293
+ <bs-check-group :aka="channels"
294
+ ::type="checkbox"
295
+ ::value=${['Slack']}
296
+ ::options=${['Email', 'Slack', 'SMS']} />
297
+
298
+ Deliver to ${channels.value.join(', ')}
299
+ ```
300
+
249
301
  ### Components
250
302
 
251
303
  | Tag | Parameters |
@@ -278,6 +330,7 @@ passed -- see *Values are read and written* above.
278
330
  | `bs-progress-stacked` | — |
279
331
  | `bs-scrollspy` | `target` `offset` `smooth` `height` |
280
332
  | `bs-spinner` | `variant` `type` `small` `label` |
333
+ | `bs-theme-auto` | — (declares that the page uses colour modes) |
281
334
  | `bs-theme-toggle` | `variant` `outline` `size` |
282
335
  | `bs-toast` | `title` `time` `variant` `open` `autohide` `delay` |
283
336
  | `bs-toast-container` | `placement` |
@@ -293,7 +346,7 @@ Bootstrap, and each says so in its own file:
293
346
  cannot reach it by name. `$host` is the instance it was slotted *into* —
294
347
  the one place the kit needs the structural relationship rather than the
295
348
  lexical one. No id is written by anyone.
296
- - **`bs-pagination` says `:current`, not `:page`.** `page` is already the
349
+ - **`bs-pagination` says `::current`, not `::page`.** `page` is already the
297
350
  name of `<html>`'s own scope, so a parameter of that name would resolve to
298
351
  the scope rather than to the number.
299
352
  - **`bs-tooltip` and `bs-popover` construct their plugin from a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markout-lang/bootstrap-kit",
3
- "version": "0.2.2",
3
+ "version": "0.4.0",
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",
@@ -11,6 +11,9 @@
11
11
  "url": "https://github.com/fcapolini/markout/issues"
12
12
  },
13
13
  "homepage": "https://markout.dev",
14
+ "peerDependencies": {
15
+ "@markout-lang/core": ">=0.5.0 <1.0.0"
16
+ },
14
17
  "markout": {
15
18
  "root": "/bootstrap-kit"
16
19
  },
@@ -6,8 +6,8 @@
6
6
  markup belongs in a slot rather than in an array.
7
7
 
8
8
  <bs-accordion>
9
- <bs-accordion-item :title="First" :open>…</bs-accordion-item>
10
- <bs-accordion-item :title="Second">…</bs-accordion-item>
9
+ <bs-accordion-item ::title="First" ::open>…</bs-accordion-item>
10
+ <bs-accordion-item ::title="Second">…</bs-accordion-item>
11
11
  </bs-accordion>
12
12
 
13
13
  The item needs one thing from the accordion — the id Bootstrap closes the
@@ -25,12 +25,11 @@
25
25
  collide and nothing has to be named.
26
26
  -->
27
27
  <:define tag="bs-accordion:div"
28
- class="accordion ${extra ?? ''}"
28
+ class="accordion"
29
29
 
30
30
  // parameters
31
- :extra=${null} // extra classes for this instance
32
- :exclusive=${true} // one open panel at a time
33
- :flush=${false}
31
+ ::exclusive=${true} // one open panel at a time
32
+ ::flush=${false}
34
33
 
35
34
  /*
36
35
  private: the id the items point at. Owned here rather than
@@ -45,12 +44,11 @@
45
44
  </:define>
46
45
 
47
46
  <:define tag="bs-accordion-item:div"
48
- class="accordion-item ${extra ?? ''}"
47
+ class="accordion-item"
49
48
 
50
49
  // parameters
51
- :extra=${null} // extra classes for this instance
52
- :title=${''}
53
- :open=${false}
50
+ ::title=${''}
51
+ ::open=${false}
54
52
 
55
53
  // private: the accordion this item was slotted into, if any
56
54
  :_parent=${$host && $host.exclusive ? $host._id : null}
package/parts/alert.htm CHANGED
@@ -22,13 +22,12 @@
22
22
  role="alert"
23
23
 
24
24
  // parameters
25
- :extra=${null} // extra classes for this instance
26
- :variant=${'primary'}
27
- :heading=${null}
28
- :dismissible=${false}
25
+ ::variant=${'primary'}
26
+ ::heading=${null}
27
+ ::dismissible=${false}
29
28
 
30
29
  // private
31
- :_class=${['alert', `alert-${variant}`, extra].filter(s => s).join(' ')}
30
+ :_class=${`alert alert-${variant}`}
32
31
 
33
32
  class=${_class}
34
33
  :class-alert-dismissible=${dismissible}
@@ -40,8 +39,8 @@
40
39
 
41
40
  <:slot />
42
41
 
43
- <bs-close :dismiss="alert"
44
- :label="Close alert"
42
+ <bs-close ::dismiss="alert"
43
+ ::label="Close alert"
45
44
  :if=${dismissible} />
46
45
  </:define>
47
46
 
package/parts/badge.htm CHANGED
@@ -9,10 +9,9 @@
9
9
  <:define tag="bs-badge:span"
10
10
 
11
11
  // parameters
12
- :extra=${null} // extra classes for this instance
13
- :variant=${'primary'}
14
- :pill=${false}
15
- :position=${null} // 'top-end' | 'bottom-end' — for a badge on a button
12
+ ::variant=${'primary'}
13
+ ::pill=${false}
14
+ ::position=${null} // 'top-end' | 'bottom-end' — for a badge on a button
16
15
 
17
16
  // private
18
17
  :_class=${[
@@ -22,7 +21,6 @@
22
21
  position ? 'position-absolute translate-middle' : '',
23
22
  position === 'top-end' ? 'top-0 start-100' : '',
24
23
  position === 'bottom-end' ? 'top-100 start-100' : '',
25
- extra,
26
24
  ].filter(s => s).join(' ')}
27
25
 
28
26
  class=${_class}
package/parts/base.htm CHANGED
@@ -6,7 +6,7 @@
6
6
  once into Bootstrap's own CSS variables below, so restyling the kit means
7
7
  setting one value at the import site instead of patching each component:
8
8
 
9
- <head ::bsRadius="1rem">
9
+ <head :const-bsRadius="1rem">
10
10
  <:import src="/bootstrap-kit/all.htm" />
11
11
  </head>
12
12
 
@@ -16,25 +16,25 @@
16
16
  forking this file — and so does a page serving its own Sass build, which is
17
17
  how a design system gets past what the tokens below can reach:
18
18
 
19
- <head ::bsCssUrl="/vendor/bootstrap.min.css"
20
- ::bsJsUrl="/vendor/bootstrap.bundle.min.js"
21
- ::bsCssIntegrity=${null}
22
- ::bsJsIntegrity=${null}>
19
+ <head :const-bsCssUrl="/vendor/bootstrap.min.css"
20
+ :const-bsJsUrl="/vendor/bootstrap.bundle.min.js"
21
+ :const-bsCssIntegrity=${null}
22
+ :const-bsJsIntegrity=${null}>
23
23
  -->
24
24
  <lib
25
25
  // where Bootstrap comes from
26
- ::bsCssUrl=${'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css'}
27
- ::bsCssIntegrity=${'sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB'}
28
- ::bsJsUrl=${'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js'}
29
- ::bsJsIntegrity=${'sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI'}
26
+ :const-bsCssUrl=${'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css'}
27
+ :const-bsCssIntegrity=${'sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB'}
28
+ :const-bsJsUrl=${'https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js'}
29
+ :const-bsJsIntegrity=${'sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI'}
30
30
 
31
31
  // tokens
32
- ::bsRadius=${'0.375rem'}
33
- ::bsRadiusSm=${'0.25rem'}
34
- ::bsRadiusLg=${'0.5rem'}
35
- ::bsRadiusPill=${'50rem'}
36
- ::bsFontSans=${'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'}
37
- ::bsLinkDecoration=${'underline'}
32
+ :const-bsRadius=${'0.375rem'}
33
+ :const-bsRadiusSm=${'0.25rem'}
34
+ :const-bsRadiusLg=${'0.5rem'}
35
+ :const-bsRadiusPill=${'50rem'}
36
+ :const-bsFontSans=${'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'}
37
+ :const-bsLinkDecoration=${'underline'}
38
38
  >
39
39
  <meta charset="utf-8">
40
40
  <meta name="viewport"
@@ -12,16 +12,14 @@
12
12
  -->
13
13
  <:define tag="bs-breadcrumb:nav"
14
14
  aria-label="breadcrumb"
15
- class=${extra}
16
15
 
17
16
  // parameters
18
- :extra=${null} // extra classes for this instance
19
- :items=${[
17
+ ::items=${[
20
18
  { name: 'Home', link: '#' },
21
19
  { name: 'Library', link: '#' },
22
20
  { name: 'Data' },
23
21
  ]}
24
- :divider=${null}
22
+ ::divider=${null}
25
23
 
26
24
  /*
27
25
  Bootstrap reads the separator from a CSS custom property, and
package/parts/button.htm CHANGED
@@ -9,8 +9,8 @@
9
9
  a modal, an offcanvas or a collapse is this same tag rather than a
10
10
  component of its own:
11
11
 
12
- <bs-button :toggle="modal" :target="#signup">Sign up</bs-button>
13
- <bs-button :dismiss="modal" :variant="secondary">Close</bs-button>
12
+ <bs-button ::toggle="modal" ::target="#signup">Sign up</bs-button>
13
+ <bs-button ::dismiss="modal" ::variant="secondary">Close</bs-button>
14
14
 
15
15
  Note the two spellings of "conditional attribute" used throughout the kit:
16
16
  a plain `name=${expr}` sets a VALUE and removes the attribute when the
@@ -20,23 +20,21 @@
20
20
  <:define tag="bs-button:button"
21
21
 
22
22
  // parameters
23
- :extra=${null} // extra classes for this instance
24
- :variant=${'primary'}
25
- :outline=${false}
26
- :size=${null}
27
- :active=${false}
28
- :disabled=${false}
29
- :type=${'button'}
30
- :toggle=${null}
31
- :target=${null}
32
- :dismiss=${null}
23
+ ::variant=${'primary'}
24
+ ::outline=${false}
25
+ ::size=${null}
26
+ ::active=${false}
27
+ ::disabled=${false}
28
+ ::type=${'button'}
29
+ ::toggle=${null}
30
+ ::target=${null}
31
+ ::dismiss=${null}
33
32
 
34
33
  // private
35
34
  :_class=${[
36
35
  'btn',
37
36
  variant ? `btn-${outline ? 'outline-' : ''}${variant}` : '',
38
37
  size ? `btn-${size}` : '',
39
- extra,
40
38
  ].filter(s => s).join(' ')}
41
39
 
42
40
  class=${_class}
@@ -59,16 +57,15 @@
59
57
  <:define tag="bs-link:a"
60
58
 
61
59
  // parameters
62
- :extra=${null} // extra classes for this instance
63
- :href=${'#'}
64
- :variant=${null}
65
- :outline=${false}
66
- :size=${null}
67
- :active=${false}
68
- :disabled=${false}
69
- :button=${false}
70
- :toggle=${null}
71
- :target=${null}
60
+ ::href=${'#'}
61
+ ::variant=${null}
62
+ ::outline=${false}
63
+ ::size=${null}
64
+ ::active=${false}
65
+ ::disabled=${false}
66
+ ::button=${false}
67
+ ::toggle=${null}
68
+ ::target=${null}
72
69
 
73
70
  // private
74
71
  :_class=${[
@@ -76,7 +73,6 @@
76
73
  button && variant ? `btn-${outline ? 'outline-' : ''}${variant}` : '',
77
74
  button && size ? `btn-${size}` : '',
78
75
  !button && variant ? `link-${variant}` : '',
79
- extra,
80
76
  ].filter(s => s).join(' ') || null}
81
77
 
82
78
  class=${_class}
@@ -99,16 +95,14 @@
99
95
  <:define tag="bs-button-group:div"
100
96
 
101
97
  // parameters
102
- :extra=${null} // extra classes for this instance
103
- :label=${'Button group'}
104
- :size=${null}
105
- :vertical=${false}
98
+ ::label=${'Button group'}
99
+ ::size=${null}
100
+ ::vertical=${false}
106
101
 
107
102
  // private
108
103
  :_class=${[
109
104
  vertical ? 'btn-group-vertical' : 'btn-group',
110
105
  size ? `btn-group-${size}` : '',
111
- extra,
112
106
  ].filter(s => s).join(' ')}
113
107
 
114
108
  class=${_class}
@@ -123,13 +117,12 @@
123
117
  buttons inside one, and this is the wrapper that says so.
124
118
  -->
125
119
  <:define tag="bs-button-toolbar:div"
126
- class="btn-toolbar ${extra ?? ''}"
120
+ class="btn-toolbar"
127
121
  role="toolbar"
128
122
 
129
123
  // parameters
130
- :extra=${null} // extra classes for this instance
131
- :label=${'Toolbar'}
132
- :gap=${2}
124
+ ::label=${'Toolbar'}
125
+ ::gap=${2}
133
126
 
134
127
  aria-label=${label}
135
128
  :class-gap-1=${gap === 1}
@@ -146,13 +139,12 @@
146
139
  -->
147
140
  <:define tag="bs-close:button"
148
141
  type="button"
149
- class="btn-close ${extra ?? ''}"
142
+ class="btn-close"
150
143
 
151
144
  // parameters
152
- :extra=${null} // extra classes for this instance
153
- :label=${'Close'}
154
- :dismiss=${null}
155
- :disabled=${false}
145
+ ::label=${'Close'}
146
+ ::dismiss=${null}
147
+ ::disabled=${false}
156
148
 
157
149
  aria-label=${label}
158
150
  :attr-disabled=${disabled}
package/parts/card.htm CHANGED
@@ -7,30 +7,29 @@
7
7
  given, which is the kit's general shape — a caller writes what the card
8
8
  HAS, not the markup that produces it.
9
9
 
10
- <bs-card :title="Card title" :footer="2 days ago">
10
+ <bs-card ::title="Card title" ::footer="2 days ago">
11
11
  <p class="card-text">Some quick example text.</p>
12
12
  </bs-card>
13
13
 
14
- The body is the one region a caller cannot reach with `:extra`, which
15
- goes on the card itself -- hence `:bodyExtra`, for the padding Bootstrap
14
+ The body is the one region a caller cannot reach with `class+=`, which
15
+ goes on the card itself -- hence `::bodyExtra`, for the padding Bootstrap
16
16
  leaves to a utility class: `p-0` for a table or a code surface that runs
17
17
  to the edges, `p-4` for a card that is mostly one paragraph.
18
18
  -->
19
19
  <:define tag="bs-card:div"
20
20
 
21
21
  // parameters
22
- :extra=${null} // extra classes for this instance
23
- :bodyExtra=${null} // extra classes for the body: `p-0`, `p-4`, `d-flex`
24
- :title=${null}
25
- :subtitle=${null}
26
- :header=${null}
27
- :footer=${null}
28
- :image=${null}
29
- :imageAlt=${''}
30
- :imageBottom=${false}
31
- :variant=${null} // colours the whole card, e.g. 'primary'
32
- :border=${null} // colours only the border
33
- :align=${null} // 'center' | 'end'
22
+ ::bodyExtra=${null} // extra classes for the body: `p-0`, `p-4`, `d-flex`
23
+ ::title=${null}
24
+ ::subtitle=${null}
25
+ ::header=${null}
26
+ ::footer=${null}
27
+ ::image=${null}
28
+ ::imageAlt=${''}
29
+ ::imageBottom=${false}
30
+ ::variant=${null} // colours the whole card, e.g. 'primary'
31
+ ::border=${null} // colours only the border
32
+ ::align=${null} // 'center' | 'end'
34
33
 
35
34
  // private
36
35
  :_class=${[
@@ -38,7 +37,6 @@
38
37
  variant ? `text-bg-${variant}` : '',
39
38
  border ? `border-${border}` : '',
40
39
  align ? `text-${align}` : '',
41
- extra,
42
40
  ].filter(s => s).join(' ')}
43
41
 
44
42
  class=${_class}
@@ -84,18 +82,15 @@
84
82
  <:define tag="bs-card-group:div"
85
83
 
86
84
  // parameters
87
- :extra=${null} // extra classes for this instance
88
- :cols=${3}
89
- :gap=${4}
90
- :attached=${false} // a seamless strip instead of separate cards
85
+ ::cols=${3}
86
+ ::gap=${4}
87
+ ::attached=${false} // a seamless strip instead of separate cards
91
88
 
92
89
  // private
93
90
  :_class=${attached
94
91
  ? 'card-group'
95
92
  : `row row-cols-1 row-cols-md-${cols} g-${gap}`}
96
- :_groupClass=${extra ? `${_class} ${extra}` : _class}
97
-
98
- class=${_groupClass}
93
+ class=${_class}
99
94
  >
100
95
  <:slot />
101
96
  </:define>
@@ -10,18 +10,17 @@
10
10
  is worth a component at all.
11
11
  -->
12
12
  <:define tag="bs-carousel:div"
13
- class="carousel slide ${extra ?? ''}"
13
+ class="carousel slide"
14
14
 
15
15
  // parameters
16
- :extra=${null} // extra classes for this instance
17
- :slides=${[]}
18
- :controls=${true}
19
- :indicators=${true}
20
- :captions=${true}
21
- :fade=${false}
22
- :ride=${true}
23
- :interval=${5000}
24
- :dark=${false}
16
+ ::slides=${[]}
17
+ ::controls=${true}
18
+ ::indicators=${true}
19
+ ::captions=${true}
20
+ ::fade=${false}
21
+ ::ride=${true}
22
+ ::interval=${5000}
23
+ ::dark=${false}
25
24
 
26
25
  // private
27
26
  :_id=${`bs-carousel-${$id}`}