@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 +79 -26
- package/package.json +4 -1
- package/parts/accordion.htm +8 -10
- package/parts/alert.htm +6 -7
- package/parts/badge.htm +3 -5
- package/parts/base.htm +15 -15
- package/parts/breadcrumb.htm +2 -4
- package/parts/button.htm +30 -38
- package/parts/card.htm +18 -23
- package/parts/carousel.htm +9 -10
- package/parts/check.htm +57 -31
- package/parts/collapse.htm +6 -7
- package/parts/dropdown.htm +10 -11
- package/parts/image.htm +10 -13
- package/parts/input.htm +37 -37
- package/parts/list-group.htm +5 -7
- package/parts/modal.htm +13 -14
- package/parts/nav.htm +10 -13
- package/parts/navbar.htm +8 -10
- package/parts/offcanvas.htm +10 -12
- package/parts/pagination.htm +9 -11
- package/parts/placeholder.htm +5 -6
- package/parts/popover.htm +6 -7
- package/parts/progress.htm +10 -11
- package/parts/scrollspy.htm +6 -8
- package/parts/select.htm +17 -16
- package/parts/spinner.htm +4 -6
- package/parts/table.htm +12 -14
- package/parts/theme.htm +29 -6
- package/parts/toast.htm +13 -16
- package/parts/tooltip.htm +5 -6
package/parts/check.htm
CHANGED
|
@@ -12,23 +12,22 @@
|
|
|
12
12
|
<:define tag="bs-check:div"
|
|
13
13
|
|
|
14
14
|
// parameters
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
:help=${null}
|
|
15
|
+
::label=${null}
|
|
16
|
+
::type=${'checkbox'} // 'checkbox' | 'radio' | 'switch'
|
|
17
|
+
::name=${null}
|
|
18
|
+
::value=${null}
|
|
19
|
+
::checked=${false}
|
|
20
|
+
::inline=${false}
|
|
21
|
+
::reverse=${false}
|
|
22
|
+
::disabled=${false}
|
|
23
|
+
::help=${null}
|
|
25
24
|
|
|
26
25
|
// private
|
|
27
26
|
:_id=${`bs-check-${$id}`}
|
|
28
27
|
:_helpId=${`bs-check-help-${$id}`}
|
|
29
28
|
:_type=${type === 'switch' ? 'checkbox' : type}
|
|
30
29
|
|
|
31
|
-
class="form-check
|
|
30
|
+
class="form-check"
|
|
32
31
|
:class-form-switch=${type === 'switch'}
|
|
33
32
|
:class-form-check-inline=${inline}
|
|
34
33
|
:class-form-check-reverse=${reverse}
|
|
@@ -41,6 +40,7 @@
|
|
|
41
40
|
role=${type === 'switch' ? 'switch' : null}
|
|
42
41
|
aria-describedby=${help ? _helpId : null}
|
|
43
42
|
:attr-checked=${checked}
|
|
43
|
+
:prop-checked=${checked}
|
|
44
44
|
:attr-disabled=${disabled}
|
|
45
45
|
:on-change=${ev => checked = ev.target.checked}>
|
|
46
46
|
|
|
@@ -56,23 +56,41 @@
|
|
|
56
56
|
A whole group of radios or checkboxes from one array, sharing a name and
|
|
57
57
|
reporting the selection back through `:value`. Entries are strings or
|
|
58
58
|
`{ name, value, disabled }`, as in `bs-select`.
|
|
59
|
+
|
|
60
|
+
What `:value` HOLDS is decided by `:type`, because that is what the two
|
|
61
|
+
controls mean: a radio group submits one value and a checkbox group
|
|
62
|
+
submits every box that is ticked, under the same name. So a radio group's
|
|
63
|
+
`:value` is the selected value or `null`, and a checkbox or switch
|
|
64
|
+
group's is an ARRAY, in the order the options were given rather than the
|
|
65
|
+
order they were clicked — a summary sentence reading it should not
|
|
66
|
+
reorder itself under the reader.
|
|
67
|
+
|
|
68
|
+
It used to be one value either way, which made a checkbox group behave
|
|
69
|
+
like a radio group that could not make up its mind: ticking a second box
|
|
70
|
+
unticked the first, and unticking a box left it ticked. Not a shape
|
|
71
|
+
guessed from a value — `:type` is declared, and it is the same thing that
|
|
72
|
+
already picks the input's type and the switch class.
|
|
59
73
|
-->
|
|
60
74
|
<:define tag="bs-check-group:div"
|
|
61
|
-
class="mb-3
|
|
75
|
+
class="mb-3"
|
|
62
76
|
role="group"
|
|
63
77
|
|
|
64
78
|
// parameters
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
:disabled=${false}
|
|
79
|
+
::legend=${null}
|
|
80
|
+
::type=${'radio'}
|
|
81
|
+
::options=${[]}
|
|
82
|
+
::value=${type === 'radio' ? null : []}
|
|
83
|
+
::inline=${false}
|
|
84
|
+
::disabled=${false}
|
|
72
85
|
|
|
73
86
|
// private
|
|
74
87
|
:_name=${`bs-check-group-${$id}`}
|
|
75
88
|
:_legendId=${`bs-check-group-legend-${$id}`}
|
|
89
|
+
:_multi=${type !== 'radio'}
|
|
90
|
+
// a lone value read as a list of one, the way `:options` reads a lone
|
|
91
|
+
// string as an entry: passing `:value="Slack"` to a checkbox group says
|
|
92
|
+
// something unambiguous, and spreading a string into characters is not it
|
|
93
|
+
:_selected=${!_multi ? [] : Array.isArray(value) ? value : value == null ? [] : [value]}
|
|
76
94
|
|
|
77
95
|
aria-labelledby=${legend ? _legendId : null}
|
|
78
96
|
:_options=${options.map(o =>
|
|
@@ -100,9 +118,17 @@
|
|
|
100
118
|
type=${type === 'switch' ? 'checkbox' : type}
|
|
101
119
|
name=${_name}
|
|
102
120
|
value=${option.value}
|
|
103
|
-
:attr-checked=${option.value === value}
|
|
121
|
+
:attr-checked=${_multi ? _selected.includes(option.value) : option.value === value}
|
|
122
|
+
:prop-checked=${_multi ? _selected.includes(option.value) : option.value === value}
|
|
104
123
|
:attr-disabled=${disabled || option.disabled}
|
|
105
|
-
:on-change=${ev =>
|
|
124
|
+
:on-change=${(ev) => {
|
|
125
|
+
if (!_multi) { value = ev.target.value; return; }
|
|
126
|
+
const on = ev.target.checked;
|
|
127
|
+
const hit = ev.target.value;
|
|
128
|
+
value = _options
|
|
129
|
+
.filter(o => (o.value === hit ? on : _selected.includes(o.value)))
|
|
130
|
+
.map(o => o.value);
|
|
131
|
+
}}>
|
|
106
132
|
<label class="form-check-label"
|
|
107
133
|
for="${_name}-${option.value}">${option.name}</label>
|
|
108
134
|
</div>
|
|
@@ -110,18 +136,17 @@
|
|
|
110
136
|
|
|
111
137
|
<!--- A range slider, with its label and its current value. -->
|
|
112
138
|
<:define tag="bs-range:div"
|
|
113
|
-
class="mb-3
|
|
139
|
+
class="mb-3"
|
|
114
140
|
|
|
115
141
|
// parameters
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
:showValue=${false}
|
|
142
|
+
::label=${null}
|
|
143
|
+
::name=${null}
|
|
144
|
+
::min=${0}
|
|
145
|
+
::max=${100}
|
|
146
|
+
::step=${1}
|
|
147
|
+
::value=${50}
|
|
148
|
+
::disabled=${false}
|
|
149
|
+
::showValue=${false}
|
|
125
150
|
|
|
126
151
|
// private
|
|
127
152
|
:_id=${`bs-range-${$id}`}
|
|
@@ -157,6 +182,7 @@
|
|
|
157
182
|
max=${max}
|
|
158
183
|
step=${step}
|
|
159
184
|
value=${value}
|
|
185
|
+
:prop-value=${value}
|
|
160
186
|
:attr-disabled=${disabled}
|
|
161
187
|
:on-input=${ev => value = Number(ev.target.value)}>
|
|
162
188
|
</:define>
|
package/parts/collapse.htm
CHANGED
|
@@ -6,20 +6,19 @@
|
|
|
6
6
|
anything can open a collapse, and often several things do — so the region
|
|
7
7
|
takes a `:name` and a `bs-button` points at it:
|
|
8
8
|
|
|
9
|
-
<bs-button
|
|
10
|
-
<bs-collapse
|
|
9
|
+
<bs-button ::toggle="collapse" ::target="#details">Details</bs-button>
|
|
10
|
+
<bs-collapse ::name="details">…</bs-collapse>
|
|
11
11
|
|
|
12
12
|
`:horizontal` collapses width instead of height, in which case Bootstrap
|
|
13
13
|
needs the content to have a width of its own.
|
|
14
14
|
-->
|
|
15
15
|
<:define tag="bs-collapse:div"
|
|
16
|
-
class="collapse
|
|
16
|
+
class="collapse"
|
|
17
17
|
|
|
18
18
|
// parameters
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
:horizontal=${false}
|
|
19
|
+
::name=${null}
|
|
20
|
+
::open=${false}
|
|
21
|
+
::horizontal=${false}
|
|
23
22
|
|
|
24
23
|
id=${name}
|
|
25
24
|
:class-show=${open}
|
package/parts/dropdown.htm
CHANGED
|
@@ -15,25 +15,24 @@
|
|
|
15
15
|
<:define tag="bs-dropdown:div"
|
|
16
16
|
|
|
17
17
|
// parameters
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
:items=${[
|
|
18
|
+
::label=${'Dropdown'}
|
|
19
|
+
::items=${[
|
|
21
20
|
{ name: 'Action', link: '#' },
|
|
22
21
|
{ name: 'Another action', link: '#' },
|
|
23
22
|
{ divider: true },
|
|
24
23
|
{ name: 'Something else here', link: '#' },
|
|
25
24
|
]}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
::variant=${'primary'}
|
|
26
|
+
::outline=${false}
|
|
27
|
+
::size=${null}
|
|
28
|
+
::split=${false}
|
|
29
|
+
::direction=${'down'} // 'down' | 'up' | 'start' | 'end'
|
|
30
|
+
::align=${'start'} // 'start' | 'end'
|
|
31
|
+
::dark=${false}
|
|
33
32
|
|
|
34
33
|
// private
|
|
35
34
|
:_id=${`bs-dropdown-${$id}`}
|
|
36
|
-
:_class=${[direction === 'down' ? 'dropdown' : `drop${direction}
|
|
35
|
+
:_class=${[direction === 'down' ? 'dropdown' : `drop${direction}`]
|
|
37
36
|
.filter(s => s).join(' ')}
|
|
38
37
|
:_btnClass=${[
|
|
39
38
|
'btn',
|
package/parts/image.htm
CHANGED
|
@@ -8,14 +8,12 @@
|
|
|
8
8
|
<:define tag="bs-image:img"
|
|
9
9
|
|
|
10
10
|
// parameters
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
:rounded=${false}
|
|
11
|
+
::src=${null}
|
|
12
|
+
::alt=${''}
|
|
13
|
+
::fluid=${true}
|
|
14
|
+
::thumbnail=${false}
|
|
15
|
+
::rounded=${false}
|
|
17
16
|
|
|
18
|
-
class=${extra}
|
|
19
17
|
src=${src}
|
|
20
18
|
alt=${alt}
|
|
21
19
|
:class-img-fluid=${fluid}
|
|
@@ -25,14 +23,13 @@
|
|
|
25
23
|
|
|
26
24
|
<!--- An image with its caption, as one thing. -->
|
|
27
25
|
<:define tag="bs-figure:figure"
|
|
28
|
-
class="figure
|
|
26
|
+
class="figure"
|
|
29
27
|
|
|
30
28
|
// parameters
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
:align=${null} // 'center' | 'end'
|
|
29
|
+
::src=${null}
|
|
30
|
+
::alt=${''}
|
|
31
|
+
::caption=${null}
|
|
32
|
+
::align=${null} // 'center' | 'end'
|
|
36
33
|
>
|
|
37
34
|
<img class="figure-img img-fluid rounded"
|
|
38
35
|
src=${src}
|
package/parts/input.htm
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
typed, so a page can name the instance and read it from anywhere else on
|
|
10
10
|
the page —
|
|
11
11
|
|
|
12
|
-
<bs-input :aka="email"
|
|
13
|
-
<bs-button
|
|
12
|
+
<bs-input :aka="email" ::label="Email" ::type="email" />
|
|
13
|
+
<bs-button ::disabled=${!email.value}>Send</bs-button>
|
|
14
14
|
|
|
15
15
|
— which is `:aka` doing what it does everywhere else, not a mechanism
|
|
16
16
|
special to forms.
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
|
|
22
22
|
`:valid` is the other side of that, and what a form's own controls read —
|
|
23
23
|
|
|
24
|
-
<bs-input :aka="email"
|
|
25
|
-
<bs-button
|
|
24
|
+
<bs-input :aka="email" ::label="Email" ::check=${v => v.includes('@')} />
|
|
25
|
+
<bs-button ::disabled=${!email.valid}>Send</bs-button>
|
|
26
26
|
|
|
27
27
|
It is deliberately NOT the negation of the error state, which is the one
|
|
28
28
|
thing about it worth knowing. An untouched field is not wrong — that is
|
|
@@ -35,23 +35,22 @@
|
|
|
35
35
|
layouts are two regions rather than one with a class toggled on it.
|
|
36
36
|
-->
|
|
37
37
|
<:define tag="bs-input:div"
|
|
38
|
-
class="mb-3
|
|
38
|
+
class="mb-3"
|
|
39
39
|
|
|
40
40
|
// parameters
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
:message=${'Please check this value.'}
|
|
41
|
+
::label=${null}
|
|
42
|
+
::type=${'text'}
|
|
43
|
+
::name=${null}
|
|
44
|
+
::value=${''}
|
|
45
|
+
::placeholder=${''}
|
|
46
|
+
::help=${null}
|
|
47
|
+
::size=${null} // 'sm' | 'lg'
|
|
48
|
+
::disabled=${false}
|
|
49
|
+
::readonly=${false}
|
|
50
|
+
::required=${false}
|
|
51
|
+
::floating=${false}
|
|
52
|
+
::check=${(v) => true}
|
|
53
|
+
::message=${'Please check this value.'}
|
|
55
54
|
|
|
56
55
|
// private
|
|
57
56
|
:_id=${`bs-input-${$id}`}
|
|
@@ -75,6 +74,7 @@
|
|
|
75
74
|
type=${type}
|
|
76
75
|
name=${name}
|
|
77
76
|
value=${value}
|
|
77
|
+
:prop-value=${value}
|
|
78
78
|
placeholder=${placeholder}
|
|
79
79
|
aria-describedby=${help ? _helpId : null}
|
|
80
80
|
:class-is-invalid=${_invalid}
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
type=${type}
|
|
98
98
|
name=${name}
|
|
99
99
|
value=${value}
|
|
100
|
+
:prop-value=${value}
|
|
100
101
|
placeholder=${placeholder || label || ' '}
|
|
101
102
|
:class-is-invalid=${_invalid}
|
|
102
103
|
:attr-disabled=${disabled}
|
|
@@ -116,21 +117,20 @@
|
|
|
116
117
|
`rows`, and a type that isn't one of HTML's would be a small lie.
|
|
117
118
|
-->
|
|
118
119
|
<:define tag="bs-textarea:div"
|
|
119
|
-
class="mb-3
|
|
120
|
+
class="mb-3"
|
|
120
121
|
|
|
121
122
|
// parameters
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
:message=${'Please check this value.'}
|
|
123
|
+
::label=${null}
|
|
124
|
+
::name=${null}
|
|
125
|
+
::value=${''}
|
|
126
|
+
::placeholder=${''}
|
|
127
|
+
::rows=${3}
|
|
128
|
+
::help=${null}
|
|
129
|
+
::disabled=${false}
|
|
130
|
+
::readonly=${false}
|
|
131
|
+
::required=${false}
|
|
132
|
+
::check=${(v) => true}
|
|
133
|
+
::message=${'Please check this value.'}
|
|
134
134
|
|
|
135
135
|
// private
|
|
136
136
|
:_id=${`bs-textarea-${$id}`}
|
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
:attr-disabled=${disabled}
|
|
156
156
|
:attr-readonly=${readonly}
|
|
157
157
|
:attr-required=${required}
|
|
158
|
+
:prop-value=${value}
|
|
158
159
|
:on-input=${ev => value = ev.target.value}>${value}</textarea>
|
|
159
160
|
|
|
160
161
|
<div class="form-text"
|
|
@@ -172,13 +173,12 @@
|
|
|
172
173
|
<:define tag="bs-input-group:div"
|
|
173
174
|
|
|
174
175
|
// parameters
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
:size=${null}
|
|
176
|
+
::prefix=${null}
|
|
177
|
+
::suffix=${null}
|
|
178
|
+
::size=${null}
|
|
179
179
|
|
|
180
180
|
// private
|
|
181
|
-
:_class=${['input-group', size ? `input-group-${size}` : ''
|
|
181
|
+
:_class=${['input-group', size ? `input-group-${size}` : '']
|
|
182
182
|
.filter(s => s).join(' ')}
|
|
183
183
|
|
|
184
184
|
class=${_class}
|
package/parts/list-group.htm
CHANGED
|
@@ -14,21 +14,19 @@
|
|
|
14
14
|
<:define tag="bs-list-group:div"
|
|
15
15
|
|
|
16
16
|
// parameters
|
|
17
|
-
|
|
18
|
-
:items=${[
|
|
17
|
+
::items=${[
|
|
19
18
|
{ name: 'An item', active: true },
|
|
20
19
|
{ name: 'A second item' },
|
|
21
20
|
{ name: 'A disabled item', disabled: true },
|
|
22
21
|
]}
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
::flush=${false}
|
|
23
|
+
::horizontal=${false}
|
|
25
24
|
|
|
26
25
|
// private
|
|
27
26
|
:_class=${[
|
|
28
27
|
'list-group',
|
|
29
28
|
flush ? 'list-group-flush' : '',
|
|
30
29
|
horizontal ? 'list-group-horizontal' : '',
|
|
31
|
-
extra,
|
|
32
30
|
].filter(s => s).join(' ')}
|
|
33
31
|
|
|
34
32
|
class=${_class}
|
|
@@ -49,8 +47,8 @@
|
|
|
49
47
|
:if=${item.text}>${item.text}</span>
|
|
50
48
|
</span>
|
|
51
49
|
|
|
52
|
-
<bs-badge
|
|
53
|
-
|
|
50
|
+
<bs-badge ::variant=${item.badge?.variant ?? 'secondary'}
|
|
51
|
+
::pill
|
|
54
52
|
:if=${item.badge}>${item.badge?.name ?? item.badge}</bs-badge>
|
|
55
53
|
</a>
|
|
56
54
|
</:define>
|
package/parts/modal.htm
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
<!---
|
|
6
6
|
A modal. Opened the Bootstrap way, by a trigger naming it:
|
|
7
7
|
|
|
8
|
-
<bs-button
|
|
9
|
-
<bs-modal
|
|
8
|
+
<bs-button ::toggle="modal" ::target="#signup">Sign up</bs-button>
|
|
9
|
+
<bs-modal ::name="signup" ::title="Sign up">…</bs-modal>
|
|
10
10
|
|
|
11
11
|
The footer is a named slot with a working default, so a modal that only
|
|
12
12
|
needs a Close button doesn't have to say so. That is also why it isn't an
|
|
@@ -19,19 +19,18 @@
|
|
|
19
19
|
amount of markup expresses them, and a handler is what runs them.
|
|
20
20
|
-->
|
|
21
21
|
<:define tag="bs-modal:div"
|
|
22
|
-
class="modal fade
|
|
22
|
+
class="modal fade"
|
|
23
23
|
tabindex="-1"
|
|
24
24
|
|
|
25
25
|
// parameters
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
:open=${false}
|
|
26
|
+
::name=${null}
|
|
27
|
+
::title=${''}
|
|
28
|
+
::size=${null} // 'sm' | 'lg' | 'xl'
|
|
29
|
+
::centered=${false}
|
|
30
|
+
::scrollable=${false}
|
|
31
|
+
::fullscreen=${null} // true | 'sm-down' | 'md-down' | ...
|
|
32
|
+
::staticBackdrop=${false}
|
|
33
|
+
::open=${false}
|
|
35
34
|
|
|
36
35
|
// private
|
|
37
36
|
:_labelId=${`bs-modal-title-${$id}`}
|
|
@@ -100,7 +99,7 @@
|
|
|
100
99
|
<div class="modal-content">
|
|
101
100
|
<div class="modal-header">
|
|
102
101
|
<h1 class="modal-title fs-5" id=${_labelId}>${title}</h1>
|
|
103
|
-
<bs-close
|
|
102
|
+
<bs-close ::dismiss="modal" />
|
|
104
103
|
</div>
|
|
105
104
|
|
|
106
105
|
<div class="modal-body">
|
|
@@ -109,7 +108,7 @@
|
|
|
109
108
|
|
|
110
109
|
<div class="modal-footer">
|
|
111
110
|
<:slot name="footer">
|
|
112
|
-
<bs-button
|
|
111
|
+
<bs-button ::variant="secondary" ::dismiss="modal">Close</bs-button>
|
|
113
112
|
</:slot>
|
|
114
113
|
</div>
|
|
115
114
|
</div>
|
package/parts/nav.htm
CHANGED
|
@@ -12,18 +12,17 @@
|
|
|
12
12
|
<:define tag="bs-nav:ul"
|
|
13
13
|
|
|
14
14
|
// parameters
|
|
15
|
-
|
|
16
|
-
:items=${[
|
|
15
|
+
::items=${[
|
|
17
16
|
{ name: 'Active', link: '#', active: true },
|
|
18
17
|
{ name: 'Link', link: '#' },
|
|
19
18
|
{ name: 'Disabled', link: '#', disabled: true },
|
|
20
19
|
]}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
::variant=${null} // 'tabs' | 'pills' | 'underline'
|
|
21
|
+
::fill=${false}
|
|
22
|
+
::justified=${false}
|
|
23
|
+
::vertical=${false}
|
|
24
|
+
::align=${'start'} // 'start' | 'center' | 'end'
|
|
25
|
+
::toggle=${null} // 'tab' | 'pill' — for tabbed panes
|
|
27
26
|
|
|
28
27
|
// private
|
|
29
28
|
:_class=${[
|
|
@@ -34,7 +33,6 @@
|
|
|
34
33
|
vertical ? 'flex-column' : '',
|
|
35
34
|
align === 'center' ? 'justify-content-center' : '',
|
|
36
35
|
align === 'end' ? 'justify-content-end' : '',
|
|
37
|
-
extra,
|
|
38
36
|
].filter(s => s).join(' ')}
|
|
39
37
|
|
|
40
38
|
class=${_class}
|
|
@@ -70,13 +68,12 @@
|
|
|
70
68
|
</:define>
|
|
71
69
|
|
|
72
70
|
<:define tag="bs-tab-pane:div"
|
|
73
|
-
class="tab-pane fade
|
|
71
|
+
class="tab-pane fade"
|
|
74
72
|
role="tabpanel"
|
|
75
73
|
|
|
76
74
|
// parameters
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
:active=${false}
|
|
75
|
+
::name=${null}
|
|
76
|
+
::active=${false}
|
|
80
77
|
|
|
81
78
|
id=${name}
|
|
82
79
|
:class-show=${active}
|
package/parts/navbar.htm
CHANGED
|
@@ -17,19 +17,18 @@
|
|
|
17
17
|
<:define tag="bs-navbar:nav"
|
|
18
18
|
|
|
19
19
|
// parameters
|
|
20
|
-
|
|
21
|
-
:items=${[
|
|
20
|
+
::items=${[
|
|
22
21
|
{ name: 'Home', link: '#', active: true },
|
|
23
22
|
{ name: 'Features', link: '#' },
|
|
24
23
|
{ name: 'Pricing', link: '#' },
|
|
25
24
|
]}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
::brand=${'#'}
|
|
26
|
+
::expand=${'lg'}
|
|
27
|
+
::container=${'container'} // 'container' | 'container-fluid' | ...
|
|
28
|
+
::sticky=${false}
|
|
29
|
+
::fixed=${false}
|
|
30
|
+
::theme=${null} // 'light' | 'dark' — independent of the page
|
|
31
|
+
::bg=${'body-tertiary'}
|
|
33
32
|
|
|
34
33
|
// private
|
|
35
34
|
:_id=${`bs-navbar-${$id}`}
|
|
@@ -37,7 +36,6 @@
|
|
|
37
36
|
'navbar',
|
|
38
37
|
expand ? `navbar-expand-${expand}` : '',
|
|
39
38
|
bg ? `bg-${bg}` : '',
|
|
40
|
-
extra,
|
|
41
39
|
].filter(s => s).join(' ')}
|
|
42
40
|
|
|
43
41
|
// The gap under the links is only wanted while they are stacked, which
|
package/parts/offcanvas.htm
CHANGED
|
@@ -6,29 +6,27 @@
|
|
|
6
6
|
An offcanvas panel: the same shape as `bs-modal`, opened by a trigger
|
|
7
7
|
naming it or by the `:open` value.
|
|
8
8
|
|
|
9
|
-
<bs-button
|
|
10
|
-
<bs-offcanvas
|
|
9
|
+
<bs-button ::toggle="offcanvas" ::target="#menu">Menu</bs-button>
|
|
10
|
+
<bs-offcanvas ::name="menu" ::title="Menu">…</bs-offcanvas>
|
|
11
11
|
-->
|
|
12
12
|
<:define tag="bs-offcanvas:div"
|
|
13
13
|
class="offcanvas"
|
|
14
14
|
tabindex="-1"
|
|
15
15
|
|
|
16
16
|
// parameters
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
:open=${false}
|
|
17
|
+
::name=${null}
|
|
18
|
+
::title=${''}
|
|
19
|
+
::placement=${'start'} // 'start' | 'end' | 'top' | 'bottom'
|
|
20
|
+
::backdrop=${true}
|
|
21
|
+
::scroll=${false}
|
|
22
|
+
::responsive=${null} // 'lg' — an offcanvas below this breakpoint only
|
|
23
|
+
::open=${false}
|
|
25
24
|
|
|
26
25
|
// private
|
|
27
26
|
:_labelId=${`bs-offcanvas-title-${$id}`}
|
|
28
27
|
:_class=${[
|
|
29
28
|
responsive ? `offcanvas-${responsive}` : 'offcanvas',
|
|
30
29
|
`offcanvas-${placement}`,
|
|
31
|
-
extra,
|
|
32
30
|
].join(' ')}
|
|
33
31
|
|
|
34
32
|
class=${_class}
|
|
@@ -79,7 +77,7 @@
|
|
|
79
77
|
>
|
|
80
78
|
<div class="offcanvas-header">
|
|
81
79
|
<h5 class="offcanvas-title" id=${_labelId}>${title}</h5>
|
|
82
|
-
<bs-close
|
|
80
|
+
<bs-close ::dismiss="offcanvas" />
|
|
83
81
|
</div>
|
|
84
82
|
|
|
85
83
|
<div class="offcanvas-body">
|
package/parts/pagination.htm
CHANGED
|
@@ -19,16 +19,15 @@
|
|
|
19
19
|
<:define tag="bs-pagination:nav"
|
|
20
20
|
|
|
21
21
|
// parameters
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
:label=${'Page navigation'}
|
|
22
|
+
::current=${1}
|
|
23
|
+
::pages=${5}
|
|
24
|
+
::size=${null} // 'sm' | 'lg'
|
|
25
|
+
::align=${'start'} // 'start' | 'center' | 'end'
|
|
26
|
+
::prev=${'«'}
|
|
27
|
+
::next=${'»'}
|
|
28
|
+
::link=${(n) => null}
|
|
29
|
+
::select=${(n) => {}}
|
|
30
|
+
::label=${'Page navigation'}
|
|
32
31
|
|
|
33
32
|
// private
|
|
34
33
|
:_class=${[
|
|
@@ -39,7 +38,6 @@
|
|
|
39
38
|
].filter(s => s).join(' ')}
|
|
40
39
|
:_numbers=${Array.from({ length: pages }, (_, i) => i + 1)}
|
|
41
40
|
|
|
42
|
-
class=${extra}
|
|
43
41
|
aria-label=${label}
|
|
44
42
|
>
|
|
45
43
|
<ul class=${_class}>
|