@smwb/ui-styles 2.2.0 → 2.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/less/components/bottomBar/bottomBar.less +1 -1
- package/less/components/chip/chip.less +11 -0
- package/less/components/list/list.less +7 -0
- package/less/components/menu/menu.less +5 -0
- package/less/components/sheet/sheet.less +19 -8
- package/less/components/snackbar/snackbar.less +6 -3
- package/less/components/stack/stack.less +27 -0
- package/less/components/tabGroups/tabGroups.less +28 -2
- package/less/components/tabs/tab/tab.less +5 -0
- package/less/components/tabs/tabs.less +10 -0
- package/less/default/globals/default.variables.less +4 -0
- package/less/foundation/sizing.less +25 -0
- package/less/tokens.entry.less +7 -0
- package/less/variables.less +18 -0
- package/package.json +1 -1
|
@@ -134,6 +134,17 @@
|
|
|
134
134
|
min-height: 24px;
|
|
135
135
|
padding: 0 @smui-space-sm;
|
|
136
136
|
font-size: 0.75rem;
|
|
137
|
+
|
|
138
|
+
// On a coarse pointer a small chip that is a button or a link is as tall as the sm step
|
|
139
|
+
// (44px there): its content is the button (the link is the box itself), and the box is
|
|
140
|
+
// what a finger has to hit. A small chip that only labels, or only deletes, stays 24px.
|
|
141
|
+
@media (pointer: coarse) {
|
|
142
|
+
&:is(a[href]),
|
|
143
|
+
&:has(> .smwb-chip__content[role="button"]) {
|
|
144
|
+
height: var(--smui-control-h-sm, @smui-control-h-sm-coarse);
|
|
145
|
+
min-height: var(--smui-control-h-sm, @smui-control-h-sm-coarse);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
// A color repaints the neutral filled/outlined rules above. The guard mirrors
|
|
@@ -62,6 +62,9 @@
|
|
|
62
62
|
min-height: 36px;
|
|
63
63
|
padding-top: @smui-space-xs;
|
|
64
64
|
padding-bottom: @smui-space-xs;
|
|
65
|
+
@media (pointer: coarse) {
|
|
66
|
+
min-height: max(36px, var(--smui-control-h-sm, @smui-control-h-sm-coarse));
|
|
67
|
+
}
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
&_divider {
|
|
@@ -73,6 +76,10 @@
|
|
|
73
76
|
min-height: 36px;
|
|
74
77
|
padding-top: @smui-space-xs;
|
|
75
78
|
padding-bottom: @smui-space-xs;
|
|
79
|
+
// On a coarse pointer a dense row is the sm step (44px there) at least.
|
|
80
|
+
@media (pointer: coarse) {
|
|
81
|
+
min-height: max(36px, var(--smui-control-h-sm, @smui-control-h-sm-coarse));
|
|
82
|
+
}
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
// A row that is a link: the anchor takes the padding, so the whole row is the link.
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
// sets it from its `offsetTop` prop and `AppLayout` publishes its sticky header's height as the
|
|
4
4
|
// page default, so a panel starts below the header; with neither it is 0 and nothing moves.
|
|
5
5
|
@sheetOffsetTop: var(--smui-sheet-offset-top, 0px);
|
|
6
|
+
// Gap between the bottom edge of the window and the bottom of the sheet and of its modal scrim. `BottomBar`
|
|
7
|
+
// publishes its height (with the safe-area inset) as the page default, so a panel stops above the bar; with the
|
|
8
|
+
// bar absent it is 0 and nothing moves.
|
|
9
|
+
@sheetOffsetBottom: var(--smui-bottom-bar-offset, 0px);
|
|
6
10
|
|
|
7
11
|
background-color: var(--smui-surfaceBackground);
|
|
8
12
|
position: fixed;
|
|
@@ -20,6 +24,11 @@
|
|
|
20
24
|
display: flex;
|
|
21
25
|
max-width: 100vw;
|
|
22
26
|
|
|
27
|
+
// A finger is dragging the panel (swipe to dismiss): it follows without easing.
|
|
28
|
+
&[data-smwb-swiping] {
|
|
29
|
+
transition: none;
|
|
30
|
+
}
|
|
31
|
+
|
|
23
32
|
&__header {
|
|
24
33
|
display: flex;
|
|
25
34
|
justify-content: space-between;
|
|
@@ -121,10 +130,12 @@
|
|
|
121
130
|
|
|
122
131
|
&.smwb-bottom {
|
|
123
132
|
border-radius: @sheetBorderRadius @sheetBorderRadius 0 0;
|
|
124
|
-
bottom:
|
|
133
|
+
bottom: @sheetOffsetBottom;
|
|
125
134
|
left: 0;
|
|
126
135
|
width: 100%;
|
|
127
136
|
height: var(--sizeProp);
|
|
137
|
+
// A tall panel stops at the top of the window (below any offset) instead of running past it by the bar's height.
|
|
138
|
+
max-height: calc(100% - @sheetOffsetTop - @sheetOffsetBottom);
|
|
128
139
|
transform: translateY(100%);
|
|
129
140
|
flex-direction: column;
|
|
130
141
|
.smwb-sheet__header {
|
|
@@ -139,7 +150,7 @@
|
|
|
139
150
|
width: 100%;
|
|
140
151
|
height: var(--sizeProp);
|
|
141
152
|
// A tall panel stops at the bottom of the window instead of running past it by the offset.
|
|
142
|
-
max-height: calc(100% - @sheetOffsetTop);
|
|
153
|
+
max-height: calc(100% - @sheetOffsetTop - @sheetOffsetBottom);
|
|
143
154
|
transform: translateY(-100%);
|
|
144
155
|
flex-direction: column;
|
|
145
156
|
.smwb-sheet__header {
|
|
@@ -151,7 +162,7 @@
|
|
|
151
162
|
border-radius: 0 @sheetBorderRadius @sheetBorderRadius 0;
|
|
152
163
|
top: @sheetOffsetTop;
|
|
153
164
|
left: 0;
|
|
154
|
-
height: calc(100% - @sheetOffsetTop);
|
|
165
|
+
height: calc(100% - @sheetOffsetTop - @sheetOffsetBottom);
|
|
155
166
|
width: var(--sizeProp);
|
|
156
167
|
transform: translateX(-100%);
|
|
157
168
|
flex-direction: row-reverse;
|
|
@@ -166,7 +177,7 @@
|
|
|
166
177
|
border-radius: @sheetBorderRadius 0 0 @sheetBorderRadius;
|
|
167
178
|
top: @sheetOffsetTop;
|
|
168
179
|
right: 0;
|
|
169
|
-
height: calc(100% - @sheetOffsetTop);
|
|
180
|
+
height: calc(100% - @sheetOffsetTop - @sheetOffsetBottom);
|
|
170
181
|
width: var(--sizeProp);
|
|
171
182
|
transform: translateX(100%);
|
|
172
183
|
.smwb-sheet__header {
|
|
@@ -180,7 +191,7 @@
|
|
|
180
191
|
top: @sheetOffsetTop;
|
|
181
192
|
left: 0;
|
|
182
193
|
width: 100%;
|
|
183
|
-
height: calc(100% - @sheetOffsetTop);
|
|
194
|
+
height: calc(100% - @sheetOffsetTop - @sheetOffsetBottom);
|
|
184
195
|
display: flex;
|
|
185
196
|
flex-direction: column;
|
|
186
197
|
z-index: 100;
|
|
@@ -203,7 +214,7 @@
|
|
|
203
214
|
.smwb-sheet {
|
|
204
215
|
opacity: 1;
|
|
205
216
|
&.smwb-bottom {
|
|
206
|
-
transform: translateY(
|
|
217
|
+
transform: translateY(var(--smwb-sheet-swipe, 0px));
|
|
207
218
|
&.smwb-expanded {
|
|
208
219
|
height: 90%;
|
|
209
220
|
}
|
|
@@ -221,7 +232,7 @@
|
|
|
221
232
|
}
|
|
222
233
|
}
|
|
223
234
|
&.smwb-left {
|
|
224
|
-
transform: translateX(
|
|
235
|
+
transform: translateX(var(--smwb-sheet-swipe, 0px));
|
|
225
236
|
&.smwb-expanded {
|
|
226
237
|
width: 90%;
|
|
227
238
|
}
|
|
@@ -230,7 +241,7 @@
|
|
|
230
241
|
}
|
|
231
242
|
}
|
|
232
243
|
&.smwb-right {
|
|
233
|
-
transform: translateX(
|
|
244
|
+
transform: translateX(var(--smwb-sheet-swipe, 0px));
|
|
234
245
|
&.smwb-expanded {
|
|
235
246
|
width: 90%;
|
|
236
247
|
}
|
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
gap: @snackbarGap;
|
|
5
5
|
position: fixed;
|
|
6
6
|
z-index: 777;
|
|
7
|
+
// Gap above the window's bottom edge for a stack drawn at the bottom: `BottomBar` publishes its height as
|
|
8
|
+
// --smui-bottom-bar-offset, so the snackbars sit above the bar. With the variable unset it is 0 and nothing moves.
|
|
9
|
+
@snackbarsBottomOffset: var(--smui-bottom-bar-offset, 0px);
|
|
7
10
|
&.smwb-top {
|
|
8
11
|
top: 1rem;
|
|
9
12
|
left: 50%;
|
|
@@ -18,17 +21,17 @@
|
|
|
18
21
|
top: 1rem;
|
|
19
22
|
}
|
|
20
23
|
&.smwb-bottom {
|
|
21
|
-
bottom: 1rem;
|
|
24
|
+
bottom: calc(1rem + @snackbarsBottomOffset);
|
|
22
25
|
left: 50%;
|
|
23
26
|
transform: translateX(-50%);
|
|
24
27
|
}
|
|
25
28
|
&.smwb-bottom-right {
|
|
26
29
|
right: 1rem;
|
|
27
|
-
bottom: 1rem;
|
|
30
|
+
bottom: calc(1rem + @snackbarsBottomOffset);
|
|
28
31
|
}
|
|
29
32
|
&.smwb-bottom-left {
|
|
30
33
|
left: 1rem;
|
|
31
|
-
bottom: 1rem;
|
|
34
|
+
bottom: calc(1rem + @snackbarsBottomOffset);
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
|
|
@@ -1,7 +1,34 @@
|
|
|
1
|
+
@stackDirections: row, row-reverse, column, column-reverse;
|
|
2
|
+
|
|
3
|
+
// `direction` given per breakpoint: one class per breakpoint and direction, base first and then
|
|
4
|
+
// the breakpoints in ascending order, so a wider one wins at the same specificity.
|
|
5
|
+
.stack-direction(@bp) {
|
|
6
|
+
each(@stackDirections, {
|
|
7
|
+
&--direction-@{bp}-@{value} {
|
|
8
|
+
flex-direction: @value;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
.smwb-stack {
|
|
2
14
|
// layout is driven by inline flex props; this hook is for overrides
|
|
3
15
|
min-width: 0;
|
|
4
16
|
|
|
17
|
+
.stack-direction(base);
|
|
18
|
+
|
|
19
|
+
.smui-media-up(sm; {
|
|
20
|
+
.stack-direction(sm);
|
|
21
|
+
});
|
|
22
|
+
.smui-media-up(md; {
|
|
23
|
+
.stack-direction(md);
|
|
24
|
+
});
|
|
25
|
+
.smui-media-up(lg; {
|
|
26
|
+
.stack-direction(lg);
|
|
27
|
+
});
|
|
28
|
+
.smui-media-up(xl; {
|
|
29
|
+
.stack-direction(xl);
|
|
30
|
+
});
|
|
31
|
+
|
|
5
32
|
&__divider {
|
|
6
33
|
display: flex;
|
|
7
34
|
align-items: center;
|
|
@@ -61,19 +61,45 @@
|
|
|
61
61
|
align-self: center;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// The group's actions button
|
|
64
|
+
// The group's actions button is an icon-only control: it carries the `smwb-button_icon-only` marker
|
|
65
|
+
// that `Button` writes for `iconOnly`, and its box is a square of the row's control height - the
|
|
66
|
+
// height the tabs beside it are. The side is a component variable, not Tabs' fixed 40px trigger
|
|
67
|
+
// width: that width, stretched over a dense row, drew a 40x36 rectangle where the mockups draw a
|
|
68
|
+
// square. A dense row is `@tabDenseHeight`, off the `--smui-control-h-*` grid, and marks itself.
|
|
69
|
+
// `min-width` and the horizontal padding are gone with it, so the icon sits in the middle.
|
|
65
70
|
&__actions-trigger {
|
|
71
|
+
--smwb-tab-groups-actions-size: var(--smui-control-h-lg, @smui-control-h-lg);
|
|
72
|
+
|
|
66
73
|
display: inline-flex;
|
|
67
74
|
align-items: center;
|
|
68
75
|
justify-content: center;
|
|
76
|
+
box-sizing: border-box;
|
|
69
77
|
flex: 0 0 auto;
|
|
70
|
-
|
|
78
|
+
// Its own height is the square now, not the row's stretch, so a row that grows past it (a tab
|
|
79
|
+
// with a two-line label) still keeps the button in the middle of the row.
|
|
80
|
+
align-self: center;
|
|
81
|
+
min-width: 0;
|
|
82
|
+
width: var(--smwb-tab-groups-actions-size);
|
|
83
|
+
height: var(--smwb-tab-groups-actions-size);
|
|
71
84
|
padding: 0;
|
|
72
85
|
border: none;
|
|
73
86
|
background: none;
|
|
74
87
|
color: var(--smui-onSurfaceVariant);
|
|
75
88
|
cursor: pointer;
|
|
76
89
|
|
|
90
|
+
// Compact tab rows (`TabGroups` `dense`): the square follows the shorter row.
|
|
91
|
+
&--dense {
|
|
92
|
+
--smwb-tab-groups-actions-size: var(--smui-tabDenseHeight, @tabDenseHeight);
|
|
93
|
+
|
|
94
|
+
// The tabs beside it are the sm step (44px) at least on a coarse pointer, so it is too.
|
|
95
|
+
@media (pointer: coarse) {
|
|
96
|
+
--smwb-tab-groups-actions-size: max(
|
|
97
|
+
var(--smui-tabDenseHeight, @tabDenseHeight),
|
|
98
|
+
var(--smui-control-h-sm, @smui-control-h-sm-coarse)
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
77
103
|
&:hover:not(:disabled) {
|
|
78
104
|
background-color: var(--smui-onSurfaceHover);
|
|
79
105
|
}
|
|
@@ -211,6 +211,11 @@
|
|
|
211
211
|
font-weight: 500;
|
|
212
212
|
letter-spacing: normal;
|
|
213
213
|
text-transform: none;
|
|
214
|
+
|
|
215
|
+
// On a coarse pointer the row is never shorter than the sm step (44px there).
|
|
216
|
+
@media (pointer: coarse) {
|
|
217
|
+
min-height: max(var(--smui-tabDenseHeight, @tabDenseHeight), var(--smui-control-h-sm, @smui-control-h-sm-coarse));
|
|
218
|
+
}
|
|
214
219
|
}
|
|
215
220
|
|
|
216
221
|
// Content-width tabs (Tabs `fit`): a tab is as wide as what it holds — marker, label, close button —
|
|
@@ -69,6 +69,11 @@
|
|
|
69
69
|
opacity: 0.38;
|
|
70
70
|
cursor: default;
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
// On a coarse pointer the button is at least as wide as the sm step (44px there).
|
|
74
|
+
@media (pointer: coarse) {
|
|
75
|
+
width: max(@tabsScrollButtonWidth, var(--smui-control-h-sm, @smui-control-h-sm-coarse));
|
|
76
|
+
}
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
// The overflow-menu trigger (Tabs `overflowMenu`) renders beside the scroller in the
|
|
@@ -95,6 +100,11 @@
|
|
|
95
100
|
opacity: 0.38;
|
|
96
101
|
cursor: default;
|
|
97
102
|
}
|
|
103
|
+
|
|
104
|
+
// On a coarse pointer the button is at least as wide as the sm step (44px there).
|
|
105
|
+
@media (pointer: coarse) {
|
|
106
|
+
width: max(@tabsOverflowTriggerWidth, var(--smui-control-h-sm, @smui-control-h-sm-coarse));
|
|
107
|
+
}
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
&__indicator {
|
|
@@ -142,6 +142,10 @@
|
|
|
142
142
|
// this one carries dark ink instead of @onWarningColor. 5.5:1 on @warningColor.
|
|
143
143
|
@badgeWarningColor: #1c1b1f;
|
|
144
144
|
|
|
145
|
+
// Height of the `BottomBar` row, without the safe-area inset it adds below; the bar publishes the sum as
|
|
146
|
+
// --smui-bottom-bar-offset.
|
|
147
|
+
@bottomBarHeight: 56px;
|
|
148
|
+
|
|
145
149
|
@buttonGap: @smui-space-sm;
|
|
146
150
|
@buttonPaddingSmall: @smui-space-xs 10px; // 10 off-grid
|
|
147
151
|
@buttonPaddingMedium: 6px 14px; // off-grid
|
|
@@ -43,6 +43,23 @@
|
|
|
43
43
|
// Button, so they inherit the tokens
|
|
44
44
|
//
|
|
45
45
|
// Override one step from theme.config, e.g. @smui-control-h-md: 44px;
|
|
46
|
+
//
|
|
47
|
+
// Touch density: on a coarse pointer (finger, stylus) the three steps are
|
|
48
|
+
// replaced by @smui-control-h-*-coarse, so every control above is at least
|
|
49
|
+
// @smui-touch-target (44px) tall. variables.less remaps the runtime tokens in
|
|
50
|
+
// an `@media (pointer: coarse)` block, which is why most components need no
|
|
51
|
+
// rule of their own; only what sits off the scale has one (small clickable
|
|
52
|
+
// or link Chip, Tabs dense and its scroll buttons, TabGroups dense actions button,
|
|
53
|
+
// Menu dense items, List dense rows). A mouse keeps the sizes above.
|
|
54
|
+
// Still exempt on touch: the --filled and --inline fields, the compact Toggle
|
|
55
|
+
// (capped at @toggleCompactMaxHeight) and a small Chip that is neither a button
|
|
56
|
+
// nor a link.
|
|
57
|
+
// The -coarse steps never drop below the matching fine step, so a theme that
|
|
58
|
+
// raises a step is not shrunk on touch. Override one from theme.config
|
|
59
|
+
// (@smui-control-h-md-coarse: 48px;) or at runtime (--smui-control-h-md-coarse).
|
|
60
|
+
// A runtime override of --smui-control-h-* on :root, loaded after the library,
|
|
61
|
+
// also applies on a coarse pointer (the token layer always loses to it); set
|
|
62
|
+
// the -coarse token too, or scope the override to @media (pointer: fine).
|
|
46
63
|
//=====================================================================
|
|
47
64
|
|
|
48
65
|
// Control height (form fields, buttons, chips)
|
|
@@ -50,6 +67,14 @@
|
|
|
50
67
|
@smui-control-h-md: 40px;
|
|
51
68
|
@smui-control-h-lg: 48px;
|
|
52
69
|
|
|
70
|
+
// Smallest touch target (Material and WCAG 2.5.5 call for 44-48px)
|
|
71
|
+
@smui-touch-target: 44px;
|
|
72
|
+
|
|
73
|
+
// Control height on a coarse pointer (finger, stylus): the fine step, raised to the touch target
|
|
74
|
+
@smui-control-h-sm-coarse: max(@smui-touch-target, @smui-control-h-sm);
|
|
75
|
+
@smui-control-h-md-coarse: max(@smui-touch-target, @smui-control-h-md);
|
|
76
|
+
@smui-control-h-lg-coarse: max(@smui-touch-target, @smui-control-h-lg);
|
|
77
|
+
|
|
53
78
|
// Horizontal padding inside controls
|
|
54
79
|
@smui-control-px-sm: @smui-space-md; // 12
|
|
55
80
|
@smui-control-px-md: @smui-space-lg; // 16
|
package/less/tokens.entry.less
CHANGED
|
@@ -14,6 +14,13 @@
|
|
|
14
14
|
.smui-tokens-light();
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
// A coarse pointer swaps the control heights for the -coarse steps (foundation/sizing.less).
|
|
18
|
+
@media (pointer: coarse) {
|
|
19
|
+
:where(:root) {
|
|
20
|
+
.smui-tokens-coarse();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
:where(:root[data-theme="dark"]) {
|
|
18
25
|
.smui-tokens-dark();
|
|
19
26
|
}
|
package/less/variables.less
CHANGED
|
@@ -153,6 +153,10 @@
|
|
|
153
153
|
--smui-control-h-sm: @smui-control-h-sm;
|
|
154
154
|
--smui-control-h-md: @smui-control-h-md;
|
|
155
155
|
--smui-control-h-lg: @smui-control-h-lg;
|
|
156
|
+
// Their values on a coarse pointer (see .smui-tokens-coarse below)
|
|
157
|
+
--smui-control-h-sm-coarse: @smui-control-h-sm-coarse;
|
|
158
|
+
--smui-control-h-md-coarse: @smui-control-h-md-coarse;
|
|
159
|
+
--smui-control-h-lg-coarse: @smui-control-h-lg-coarse;
|
|
156
160
|
|
|
157
161
|
/* Border-radius scale */
|
|
158
162
|
--smui-radius-xs: @smui-radius-xs;
|
|
@@ -279,10 +283,24 @@
|
|
|
279
283
|
--smui-messageBackground: @messageBgDark;
|
|
280
284
|
}
|
|
281
285
|
|
|
286
|
+
// Touch density: on a coarse pointer the control heights are the -coarse steps. Not part of
|
|
287
|
+
// the light/dark mixins for the same reason the heights are light-only: mode-independent.
|
|
288
|
+
.smui-tokens-coarse() {
|
|
289
|
+
--smui-control-h-sm: var(--smui-control-h-sm-coarse, @smui-control-h-sm-coarse);
|
|
290
|
+
--smui-control-h-md: var(--smui-control-h-md-coarse, @smui-control-h-md-coarse);
|
|
291
|
+
--smui-control-h-lg: var(--smui-control-h-lg-coarse, @smui-control-h-lg-coarse);
|
|
292
|
+
}
|
|
293
|
+
|
|
282
294
|
:root {
|
|
283
295
|
.smui-tokens-light();
|
|
284
296
|
}
|
|
285
297
|
|
|
298
|
+
@media (pointer: coarse) {
|
|
299
|
+
:root {
|
|
300
|
+
.smui-tokens-coarse();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
286
304
|
:root[data-theme="dark"] {
|
|
287
305
|
.smui-tokens-dark();
|
|
288
306
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smwb/ui-styles",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Framework-agnostic LESS design tokens and component styles (smwb-*) shared by the @smwb UI libraries. Prebuilt aggregate CSS lives in @smwb/ui-css.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": [
|