@webority/theme 0.30.0 → 0.32.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 +2 -2
- package/dist/purge-safelist.json +44 -29
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/_tokens.scss +1 -0
- package/scss/_variables.scss +1 -0
- package/scss/_wui-components.scss +3 -0
- package/scss/wui/_chart.scss +5 -309
- package/scss/wui/_chat.scss +82 -0
- package/scss/wui/_floating.scss +64 -0
- package/scss/wui/_kanban.scss +67 -4
- package/scss/wui/_media.scss +12 -0
- package/scss/wui/_shell.scss +8 -0
- package/scss/wui/_table-server.scss +4 -3
- package/scss/wui/_tour.scss +97 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Webority shared design system — Bootstrap 5.3 SCSS overrides, --wui-* tokens, and shared component CSS. The single source of brand chrome for React portals and Razor sites.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"publishConfig": {
|
package/scss/_tokens.scss
CHANGED
|
@@ -331,6 +331,7 @@
|
|
|
331
331
|
--wui-z-shell-drawer: 1045; // mobile sidebar drawer
|
|
332
332
|
--wui-z-modal-backdrop: 1500;
|
|
333
333
|
--wui-z-modal: 1505;
|
|
334
|
+
--wui-z-tour: 1550; // product tour: above a modal, below menus and popovers
|
|
334
335
|
--wui-z-menu: 1600; // portalled select/date/phone menus + infotip
|
|
335
336
|
--wui-z-popover: 1600; // same rung as --wui-z-menu (above modal)
|
|
336
337
|
--wui-z-tooltip: 1650;
|
package/scss/_variables.scss
CHANGED
|
@@ -236,6 +236,7 @@ $focus-ring-width: 3px; // BS 0.25rem (4px)
|
|
|
236
236
|
//
|
|
237
237
|
// SCSS variables are compile-time and can't reference the runtime custom
|
|
238
238
|
// properties above — keep these numbers in sync with _tokens.scss by hand.
|
|
239
|
+
$zindex-tour: 1550;
|
|
239
240
|
$zindex-popover: 1600;
|
|
240
241
|
$zindex-tooltip: 1650;
|
|
241
242
|
$zindex-toast: 1700;
|
|
@@ -64,8 +64,11 @@
|
|
|
64
64
|
@import "wui/toolbar";
|
|
65
65
|
@import "wui/theme-toggle";
|
|
66
66
|
@import "wui/tree";
|
|
67
|
+
@import "wui/floating";
|
|
68
|
+
@import "wui/chat";
|
|
67
69
|
// After `overlays`: anchors the shared modal shell to the top when it holds the palette card.
|
|
68
70
|
@import "wui/command-palette";
|
|
69
71
|
@import "wui/context-menu";
|
|
72
|
+
@import "wui/tour";
|
|
70
73
|
// Last: restates the settled state of menus other partials style, so it must win.
|
|
71
74
|
@import "wui/menu-motion";
|
package/scss/wui/_chart.scss
CHANGED
|
@@ -1,315 +1,14 @@
|
|
|
1
|
-
// Charts:
|
|
1
|
+
// Charts: the <wui-chart> element behind AppChart.
|
|
2
2
|
//
|
|
3
|
-
// Part of the wui-components layer; see _wui-components.scss for the load order. The
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// dark remap in _wui-aliases.scss flips with the rest of the portal.
|
|
7
|
-
|
|
8
|
-
.wui-chart {
|
|
9
|
-
margin: 0;
|
|
10
|
-
min-width: 0;
|
|
11
|
-
color: var(--color-text-muted);
|
|
12
|
-
font-size: 12px;
|
|
13
|
-
font-variant-numeric: tabular-nums;
|
|
14
|
-
}
|
|
15
|
-
.wui-chart-title {
|
|
16
|
-
margin-bottom: 12px;
|
|
17
|
-
font-size: 14px;
|
|
18
|
-
font-weight: 600;
|
|
19
|
-
color: var(--color-text);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ============================================================================
|
|
23
|
-
// Line chart
|
|
24
|
-
// ============================================================================
|
|
25
|
-
// The top tick label sits above the top gridline, so the plot leaves room for it.
|
|
26
|
-
.wui-chart-plot {
|
|
27
|
-
position: relative;
|
|
28
|
-
margin-top: 8px;
|
|
29
|
-
}
|
|
30
|
-
// Strokes overhang the plot by half their width at the top and bottom gridlines.
|
|
31
|
-
.wui-chart-svg {
|
|
32
|
-
display: block;
|
|
33
|
-
overflow: visible;
|
|
34
|
-
}
|
|
35
|
-
.wui-chart-grid {
|
|
36
|
-
stroke: var(--color-border);
|
|
37
|
-
stroke-width: 1;
|
|
38
|
-
}
|
|
39
|
-
.wui-chart-reference {
|
|
40
|
-
stroke: var(--color-border-strong);
|
|
41
|
-
stroke-width: 1;
|
|
42
|
-
stroke-dasharray: 4 4;
|
|
43
|
-
}
|
|
44
|
-
.wui-chart-line {
|
|
45
|
-
stroke: var(--color-primary);
|
|
46
|
-
stroke-width: 2;
|
|
47
|
-
stroke-linecap: round;
|
|
48
|
-
}
|
|
49
|
-
// Bands are a quiet wash behind the series; the tone tints, it does not shout.
|
|
50
|
-
.wui-chart-band {
|
|
51
|
-
fill: var(--color-bg-muted);
|
|
52
|
-
opacity: 0.6;
|
|
53
|
-
}
|
|
54
|
-
.wui-chart-band-info {
|
|
55
|
-
fill: var(--color-info-soft);
|
|
56
|
-
}
|
|
57
|
-
.wui-chart-band-success {
|
|
58
|
-
fill: var(--color-success-soft);
|
|
59
|
-
}
|
|
60
|
-
.wui-chart-band-warning {
|
|
61
|
-
fill: var(--color-warning-soft);
|
|
62
|
-
}
|
|
63
|
-
.wui-chart-band-danger {
|
|
64
|
-
fill: var(--color-danger-soft);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Y tick values sit just above their gridline at the left edge, inside the plot, so the chart
|
|
68
|
-
// spends no width on a label gutter at 320px.
|
|
69
|
-
.wui-chart-tick,
|
|
70
|
-
.wui-chart-band-label,
|
|
71
|
-
.wui-chart-reference-label {
|
|
72
|
-
position: absolute;
|
|
73
|
-
font-size: 11px;
|
|
74
|
-
line-height: 1;
|
|
75
|
-
white-space: nowrap;
|
|
76
|
-
color: var(--color-text-muted);
|
|
77
|
-
pointer-events: none;
|
|
78
|
-
}
|
|
79
|
-
.wui-chart-tick {
|
|
80
|
-
left: 0;
|
|
81
|
-
padding-bottom: 3px;
|
|
82
|
-
transform: translateY(-100%);
|
|
83
|
-
}
|
|
84
|
-
.wui-chart-band-label {
|
|
85
|
-
right: 0;
|
|
86
|
-
padding-top: 3px;
|
|
87
|
-
}
|
|
88
|
-
.wui-chart-reference-label {
|
|
89
|
-
right: 0;
|
|
90
|
-
padding-bottom: 3px;
|
|
91
|
-
transform: translateY(-100%);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// A 24px hit area per point (WCAG 2.2 target size), drawn as an 8px ring.
|
|
95
|
-
.wui-chart-point {
|
|
96
|
-
position: absolute;
|
|
97
|
-
width: 24px;
|
|
98
|
-
height: 24px;
|
|
99
|
-
margin: -12px 0 0 -12px;
|
|
100
|
-
padding: 0;
|
|
101
|
-
display: grid;
|
|
102
|
-
place-items: center;
|
|
103
|
-
border: 0;
|
|
104
|
-
border-radius: 50%;
|
|
105
|
-
background: transparent;
|
|
106
|
-
cursor: default;
|
|
107
|
-
}
|
|
108
|
-
.wui-chart-point:focus-visible {
|
|
109
|
-
outline: 2px solid var(--color-primary);
|
|
110
|
-
outline-offset: 0;
|
|
111
|
-
}
|
|
112
|
-
.wui-chart-dot {
|
|
113
|
-
width: 8px;
|
|
114
|
-
height: 8px;
|
|
115
|
-
border-radius: 50%;
|
|
116
|
-
border: 2px solid var(--color-primary);
|
|
117
|
-
background: var(--color-surface);
|
|
118
|
-
transition: transform 120ms var(--wui-ease-out-quart);
|
|
119
|
-
}
|
|
120
|
-
.wui-chart-point:hover .wui-chart-dot,
|
|
121
|
-
.wui-chart-point:focus-visible .wui-chart-dot {
|
|
122
|
-
transform: scale(1.35);
|
|
123
|
-
background: var(--color-primary);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// CSS-only tooltip above the point; the first and last points anchor it to their own edge so
|
|
127
|
-
// it never runs off a narrow chart.
|
|
128
|
-
.wui-chart-tip {
|
|
129
|
-
position: absolute;
|
|
130
|
-
bottom: calc(100% + 4px);
|
|
131
|
-
left: 50%;
|
|
132
|
-
z-index: 1;
|
|
133
|
-
display: flex;
|
|
134
|
-
flex-direction: column;
|
|
135
|
-
align-items: flex-start;
|
|
136
|
-
gap: 2px;
|
|
137
|
-
padding: 6px 10px;
|
|
138
|
-
border: 1px solid var(--color-border-light);
|
|
139
|
-
border-radius: var(--radius);
|
|
140
|
-
background: var(--color-surface);
|
|
141
|
-
box-shadow: var(--wui-shadow-overlay);
|
|
142
|
-
white-space: nowrap;
|
|
143
|
-
text-align: left;
|
|
144
|
-
pointer-events: none;
|
|
145
|
-
visibility: hidden;
|
|
146
|
-
opacity: 0;
|
|
147
|
-
transform: translateX(-50%);
|
|
148
|
-
transition:
|
|
149
|
-
opacity 120ms var(--wui-ease-out-quart),
|
|
150
|
-
visibility 120ms;
|
|
151
|
-
}
|
|
152
|
-
.wui-chart-point-start .wui-chart-tip {
|
|
153
|
-
left: 0;
|
|
154
|
-
transform: none;
|
|
155
|
-
}
|
|
156
|
-
.wui-chart-point-end .wui-chart-tip {
|
|
157
|
-
left: auto;
|
|
158
|
-
right: 0;
|
|
159
|
-
transform: none;
|
|
160
|
-
}
|
|
161
|
-
.wui-chart-point:hover .wui-chart-tip,
|
|
162
|
-
.wui-chart-point:focus-visible .wui-chart-tip {
|
|
163
|
-
visibility: visible;
|
|
164
|
-
opacity: 1;
|
|
165
|
-
}
|
|
166
|
-
.wui-chart-tip-label {
|
|
167
|
-
font-size: 11px;
|
|
168
|
-
color: var(--color-text-muted);
|
|
169
|
-
}
|
|
170
|
-
.wui-chart-tip-value {
|
|
171
|
-
font-size: 13px;
|
|
172
|
-
font-weight: 600;
|
|
173
|
-
color: var(--color-text);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.wui-chart-xaxis {
|
|
177
|
-
position: relative;
|
|
178
|
-
height: 16px;
|
|
179
|
-
margin-top: 6px;
|
|
180
|
-
}
|
|
181
|
-
.wui-chart-xlabel {
|
|
182
|
-
position: absolute;
|
|
183
|
-
top: 0;
|
|
184
|
-
font-size: 11px;
|
|
185
|
-
line-height: 16px;
|
|
186
|
-
white-space: nowrap;
|
|
187
|
-
transform: translateX(-50%);
|
|
188
|
-
}
|
|
189
|
-
// Below md only every Nth label shows (the component marks the rest minor); a 12-month axis
|
|
190
|
-
// would otherwise overlap on a phone.
|
|
191
|
-
.wui-chart-xlabel-minor {
|
|
192
|
-
display: none;
|
|
193
|
-
}
|
|
194
|
-
@media (min-width: 768px) {
|
|
195
|
-
.wui-chart-xlabel-minor {
|
|
196
|
-
display: block;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// ============================================================================
|
|
201
|
-
// Bar chart
|
|
202
|
-
// ============================================================================
|
|
203
|
-
.wui-bar-chart-list {
|
|
204
|
-
margin: 0;
|
|
205
|
-
padding: 0;
|
|
206
|
-
list-style: none;
|
|
207
|
-
}
|
|
208
|
-
.wui-bar-chart-label {
|
|
209
|
-
min-width: 0;
|
|
210
|
-
color: var(--color-text-body);
|
|
211
|
-
overflow-wrap: anywhere;
|
|
212
|
-
}
|
|
213
|
-
.wui-bar-chart-value {
|
|
214
|
-
font-weight: 600;
|
|
215
|
-
white-space: nowrap;
|
|
216
|
-
color: var(--color-text);
|
|
217
|
-
}
|
|
218
|
-
.wui-bar-chart-track {
|
|
219
|
-
position: relative;
|
|
220
|
-
overflow: hidden;
|
|
221
|
-
border-radius: 999px;
|
|
222
|
-
background: var(--color-progress-track);
|
|
223
|
-
}
|
|
224
|
-
.wui-bar-chart-fill {
|
|
225
|
-
border-radius: inherit;
|
|
226
|
-
background: var(--color-primary);
|
|
227
|
-
}
|
|
228
|
-
// Each track is a focus stop; the ring sits outside the track's own clipped content.
|
|
229
|
-
.wui-bar-chart-track:focus-visible {
|
|
230
|
-
outline: 2px solid var(--color-primary);
|
|
231
|
-
outline-offset: 2px;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Horizontal: a label/value line over each bar, so a long label wraps instead of squeezing
|
|
235
|
-
// the bar at 320px.
|
|
236
|
-
.wui-bar-chart-horizontal .wui-bar-chart-list {
|
|
237
|
-
display: flex;
|
|
238
|
-
flex-direction: column;
|
|
239
|
-
gap: 14px;
|
|
240
|
-
}
|
|
241
|
-
.wui-bar-chart-horizontal .wui-bar-chart-item {
|
|
242
|
-
display: grid;
|
|
243
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
244
|
-
grid-template-areas:
|
|
245
|
-
"label value"
|
|
246
|
-
"track track";
|
|
247
|
-
column-gap: 12px;
|
|
248
|
-
row-gap: 6px;
|
|
249
|
-
align-items: baseline;
|
|
250
|
-
}
|
|
251
|
-
.wui-bar-chart-horizontal .wui-bar-chart-label {
|
|
252
|
-
grid-area: label;
|
|
253
|
-
}
|
|
254
|
-
.wui-bar-chart-horizontal .wui-bar-chart-value {
|
|
255
|
-
grid-area: value;
|
|
256
|
-
}
|
|
257
|
-
.wui-bar-chart-horizontal .wui-bar-chart-track {
|
|
258
|
-
grid-area: track;
|
|
259
|
-
height: 8px;
|
|
260
|
-
}
|
|
261
|
-
.wui-bar-chart-horizontal .wui-bar-chart-fill {
|
|
262
|
-
height: 100%;
|
|
263
|
-
transition: width 300ms var(--wui-ease-out-quart);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Vertical: bars side by side, value above and label below each. The plot height is one var a
|
|
267
|
-
// caller can set from its own class.
|
|
268
|
-
.wui-bar-chart-vertical .wui-bar-chart-list {
|
|
269
|
-
display: flex;
|
|
270
|
-
gap: 8px;
|
|
271
|
-
}
|
|
272
|
-
.wui-bar-chart-vertical .wui-bar-chart-item {
|
|
273
|
-
flex: 1 1 0;
|
|
274
|
-
min-width: 0;
|
|
275
|
-
display: grid;
|
|
276
|
-
grid-template-areas:
|
|
277
|
-
"value"
|
|
278
|
-
"track"
|
|
279
|
-
"label";
|
|
280
|
-
justify-items: center;
|
|
281
|
-
row-gap: 6px;
|
|
282
|
-
text-align: center;
|
|
283
|
-
}
|
|
284
|
-
// Seven bars on a 320px phone leave about 40px a column, so "18 of 25" may wrap here.
|
|
285
|
-
.wui-bar-chart-vertical .wui-bar-chart-value {
|
|
286
|
-
grid-area: value;
|
|
287
|
-
white-space: normal;
|
|
288
|
-
}
|
|
289
|
-
.wui-bar-chart-vertical .wui-bar-chart-track {
|
|
290
|
-
grid-area: track;
|
|
291
|
-
display: flex;
|
|
292
|
-
align-items: flex-end;
|
|
293
|
-
width: 100%;
|
|
294
|
-
max-width: 32px;
|
|
295
|
-
height: var(--wui-bar-chart-height, 180px);
|
|
296
|
-
border-radius: var(--radius-sm);
|
|
297
|
-
}
|
|
298
|
-
.wui-bar-chart-vertical .wui-bar-chart-fill {
|
|
299
|
-
width: 100%;
|
|
300
|
-
transition: height 300ms var(--wui-ease-out-quart);
|
|
301
|
-
}
|
|
302
|
-
.wui-bar-chart-vertical .wui-bar-chart-label {
|
|
303
|
-
grid-area: label;
|
|
304
|
-
font-size: 11px;
|
|
305
|
-
}
|
|
3
|
+
// Part of the wui-components layer; see _wui-components.scss for the load order. The element draws
|
|
4
|
+
// series in the --wui-chart-* colours. Every colour is a token the dark remap in _wui-aliases.scss
|
|
5
|
+
// flips with the rest of the portal.
|
|
306
6
|
|
|
307
7
|
// ============================================================================
|
|
308
8
|
// Chart element: <wui-chart> (AppChart, <app-chart>)
|
|
309
9
|
// ============================================================================
|
|
310
10
|
// The element builds the legend, the drawing surface, the state box and the data table; the
|
|
311
|
-
// engine draws inside .wui-chart-canvas with colours the element reads from --wui-chart-*.
|
|
312
|
-
// names here stay clear of the line and bar chart classes above.
|
|
11
|
+
// engine draws inside .wui-chart-canvas with colours the element reads from --wui-chart-*.
|
|
313
12
|
wui-chart {
|
|
314
13
|
position: relative;
|
|
315
14
|
display: block;
|
|
@@ -513,9 +212,6 @@ wui-chart[aria-busy="true"] .wui-chart-surface {
|
|
|
513
212
|
}
|
|
514
213
|
|
|
515
214
|
@media (prefers-reduced-motion: reduce) {
|
|
516
|
-
.wui-chart-dot,
|
|
517
|
-
.wui-chart-tip,
|
|
518
|
-
.wui-bar-chart-fill,
|
|
519
215
|
.wui-chart-legend-item,
|
|
520
216
|
.wui-chart-legend-swatch,
|
|
521
217
|
.wui-chart-surface {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// ── Assistant chat ──
|
|
2
|
+
// <wui-chat> / <app-chat>: a launcher pinned to a bottom corner and a side panel holding the
|
|
3
|
+
// conversation and the question box. The header, buttons, form field and alerts inside are the
|
|
4
|
+
// theme's own (.drawer-header, .btn, .form-control, .alert); only the placement and the two chat
|
|
5
|
+
// shapes live here. A compact launcher is the shared .wui-floating-btn circle (_floating.scss).
|
|
6
|
+
//
|
|
7
|
+
// Part of the wui-components layer — see _wui-components.scss for load order.
|
|
8
|
+
|
|
9
|
+
// The element is a plain host: its two parts are fixed to the viewport.
|
|
10
|
+
wui-chat {
|
|
11
|
+
display: contents;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.wui-chat-launcher {
|
|
15
|
+
position: fixed;
|
|
16
|
+
bottom: 0;
|
|
17
|
+
inset-inline-end: 0;
|
|
18
|
+
z-index: var(--wui-z-fixed);
|
|
19
|
+
margin: 1rem;
|
|
20
|
+
}
|
|
21
|
+
wui-chat[position="start"] .wui-chat-launcher {
|
|
22
|
+
inset-inline-end: auto;
|
|
23
|
+
inset-inline-start: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Above the shell chrome and below modals, like the drawer it stands in for.
|
|
27
|
+
.wui-chat-panel {
|
|
28
|
+
position: fixed;
|
|
29
|
+
top: 0;
|
|
30
|
+
bottom: 0;
|
|
31
|
+
inset-inline-end: 0;
|
|
32
|
+
z-index: var(--wui-z-shell-drawer);
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
width: min(440px, 100%);
|
|
36
|
+
background: var(--color-surface);
|
|
37
|
+
border-inline-start: 1px solid var(--color-border);
|
|
38
|
+
box-shadow: var(--wui-shadow-overlay-lg);
|
|
39
|
+
}
|
|
40
|
+
wui-chat[position="start"] .wui-chat-panel {
|
|
41
|
+
inset-inline-end: auto;
|
|
42
|
+
inset-inline-start: 0;
|
|
43
|
+
border-inline-start: 0;
|
|
44
|
+
border-inline-end: 1px solid var(--color-border);
|
|
45
|
+
}
|
|
46
|
+
// `hidden` is how the element closes the panel; display: flex above would otherwise win over it.
|
|
47
|
+
.wui-chat-panel[hidden] {
|
|
48
|
+
display: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.wui-chat-body {
|
|
52
|
+
flex: 1 1 auto;
|
|
53
|
+
min-height: 0;
|
|
54
|
+
padding: 20px;
|
|
55
|
+
overflow-y: auto;
|
|
56
|
+
}
|
|
57
|
+
.wui-chat-empty {
|
|
58
|
+
padding-block: 2rem;
|
|
59
|
+
}
|
|
60
|
+
.wui-chat-foot {
|
|
61
|
+
flex: none;
|
|
62
|
+
padding: 16px 20px;
|
|
63
|
+
border-top: 1px solid var(--color-border);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// The person's question, on the right; the answer is plain text on the panel.
|
|
67
|
+
.wui-chat-question {
|
|
68
|
+
max-width: 85%;
|
|
69
|
+
}
|
|
70
|
+
.wui-chat-bubble {
|
|
71
|
+
padding: 10px 14px;
|
|
72
|
+
background: var(--color-bg-muted);
|
|
73
|
+
border-radius: var(--wui-radius-lg);
|
|
74
|
+
white-space: pre-wrap;
|
|
75
|
+
overflow-wrap: anywhere;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// The question box grows with its text, up to a few lines.
|
|
79
|
+
.wui-chat-foot .form-control {
|
|
80
|
+
max-height: 9rem;
|
|
81
|
+
resize: none;
|
|
82
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// ── Floating stack ──
|
|
2
|
+
// The one fixed corner container the compact floating buttons (the chat launcher, the report-an-issue
|
|
3
|
+
// button) portal into, so they stack with a gap and never overlap or need a hand-set offset. React's
|
|
4
|
+
// useFloatingStack creates it; the items inside are not fixed themselves.
|
|
5
|
+
//
|
|
6
|
+
// Part of the wui-components layer — see _wui-components.scss for load order.
|
|
7
|
+
|
|
8
|
+
.wui-floating-stack {
|
|
9
|
+
position: fixed;
|
|
10
|
+
bottom: 0;
|
|
11
|
+
z-index: var(--wui-z-fixed);
|
|
12
|
+
display: flex;
|
|
13
|
+
// The primary item sits in the corner and the secondary one stacks above it.
|
|
14
|
+
flex-direction: column-reverse;
|
|
15
|
+
gap: 12px;
|
|
16
|
+
margin: 1rem;
|
|
17
|
+
// The container spans only its items, but a gap between them must not swallow clicks on the page.
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
}
|
|
20
|
+
.wui-floating-stack[data-position="end"] {
|
|
21
|
+
inset-inline-end: 0;
|
|
22
|
+
align-items: flex-end;
|
|
23
|
+
}
|
|
24
|
+
.wui-floating-stack[data-position="start"] {
|
|
25
|
+
inset-inline-start: 0;
|
|
26
|
+
align-items: flex-start;
|
|
27
|
+
}
|
|
28
|
+
.wui-floating-stack-item {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
pointer-events: auto;
|
|
31
|
+
}
|
|
32
|
+
.wui-floating-stack-item--primary {
|
|
33
|
+
order: 0;
|
|
34
|
+
}
|
|
35
|
+
.wui-floating-stack-item--secondary {
|
|
36
|
+
order: 1;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ── Compact floating button ──
|
|
40
|
+
// An icon-only circle. The label lives in the tooltip and the aria-label, never on the button.
|
|
41
|
+
.wui-floating-btn {
|
|
42
|
+
--wui-floating-size: 48px;
|
|
43
|
+
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
width: var(--wui-floating-size);
|
|
48
|
+
height: var(--wui-floating-size);
|
|
49
|
+
padding: 0;
|
|
50
|
+
border-radius: 50%;
|
|
51
|
+
box-shadow: var(--wui-shadow-overlay);
|
|
52
|
+
}
|
|
53
|
+
// Quieter than the primary circle: a light brand tint, the brand icon and a thin brand border.
|
|
54
|
+
.wui-floating-btn--secondary {
|
|
55
|
+
--wui-floating-size: 40px;
|
|
56
|
+
--bs-btn-border-color: var(--wui-primary-30);
|
|
57
|
+
--bs-btn-hover-border-color: var(--wui-primary-30);
|
|
58
|
+
--bs-btn-active-border-color: var(--wui-primary-30);
|
|
59
|
+
}
|
|
60
|
+
@media (prefers-reduced-motion: reduce) {
|
|
61
|
+
.wui-floating-btn {
|
|
62
|
+
transition: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
package/scss/wui/_kanban.scss
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
// classes, so a React re-render never wipes it.
|
|
6
6
|
//
|
|
7
7
|
// Below md the board is one column per screen: a scroll-snapped strip with a column switcher
|
|
8
|
-
// above it
|
|
8
|
+
// above it that stays at the top of the viewport while the page scrolls. The board scrolls inside
|
|
9
|
+
// itself, so the page never scrolls sideways.
|
|
9
10
|
//
|
|
10
11
|
// Sizing variables, set on .wui-kanban (or any ancestor) to override:
|
|
11
12
|
// --wui-kanban-column-width basis width of an open column (288px)
|
|
@@ -13,6 +14,8 @@
|
|
|
13
14
|
// --wui-kanban-gap space between columns (16px)
|
|
14
15
|
// --wui-kanban-column-min-height least height of a column, so short columns still read as
|
|
15
16
|
// lanes (560px; not applied in the phone one-column mode)
|
|
17
|
+
// --wui-kanban-sticky-top where the phone switcher sticks (0, or under the app shell's
|
|
18
|
+
// topbar inside .app-shell)
|
|
16
19
|
//
|
|
17
20
|
// Part of the wui-components layer, see _wui-components.scss for load order.
|
|
18
21
|
|
|
@@ -21,11 +24,18 @@
|
|
|
21
24
|
--wui-kanban-collapsed-width: 56px;
|
|
22
25
|
--wui-kanban-gap: 16px;
|
|
23
26
|
--wui-kanban-column-min-height: 560px;
|
|
27
|
+
--wui-kanban-sticky-top: 0px;
|
|
24
28
|
display: block;
|
|
25
29
|
position: relative;
|
|
26
30
|
min-width: 0;
|
|
27
31
|
max-width: 100%;
|
|
28
32
|
}
|
|
33
|
+
// The shell's topbar is sticky too, so the switcher stops below it. 72px is .app-topbar's
|
|
34
|
+
// min-height in _shell.scss; change both together. :where() keeps this at .wui-kanban's own
|
|
35
|
+
// weight, so a page's `.wui-kanban { --wui-kanban-sticky-top: … }` still wins inside the shell.
|
|
36
|
+
:where(.app-shell) .wui-kanban {
|
|
37
|
+
--wui-kanban-sticky-top: 72px;
|
|
38
|
+
}
|
|
29
39
|
|
|
30
40
|
.wui-kanban-board {
|
|
31
41
|
display: flex;
|
|
@@ -210,9 +220,42 @@
|
|
|
210
220
|
outline: 2px solid var(--color-primary);
|
|
211
221
|
outline-offset: 2px;
|
|
212
222
|
}
|
|
213
|
-
.wui-kanban-card[hidden]
|
|
223
|
+
.wui-kanban-card[hidden],
|
|
224
|
+
.wui-kanban-card[data-wui-overflow] {
|
|
225
|
+
display: none;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// "Show N more" under a capped column's cards; "Show fewer" once it is open.
|
|
229
|
+
.wui-kanban-more {
|
|
230
|
+
display: block;
|
|
231
|
+
width: calc(100% - 16px);
|
|
232
|
+
min-height: 36px;
|
|
233
|
+
margin: 0 8px 8px;
|
|
234
|
+
padding: 6px 10px;
|
|
235
|
+
border: 0;
|
|
236
|
+
border-radius: var(--wui-radius);
|
|
237
|
+
background: transparent;
|
|
238
|
+
color: var(--color-text-muted);
|
|
239
|
+
font-size: 0.8125rem;
|
|
240
|
+
font-weight: 600;
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
}
|
|
243
|
+
.wui-kanban-more[hidden] {
|
|
214
244
|
display: none;
|
|
215
245
|
}
|
|
246
|
+
.wui-kanban-more:hover {
|
|
247
|
+
background: var(--color-surface);
|
|
248
|
+
color: var(--color-text);
|
|
249
|
+
}
|
|
250
|
+
.wui-kanban-more:focus-visible {
|
|
251
|
+
outline: 2px solid var(--color-primary);
|
|
252
|
+
outline-offset: 2px;
|
|
253
|
+
}
|
|
254
|
+
@media (pointer: coarse) {
|
|
255
|
+
.wui-kanban-more {
|
|
256
|
+
min-height: 44px;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
216
259
|
.wui-kanban[readonly] .wui-kanban-card,
|
|
217
260
|
.wui-kanban-card[data-wui-locked] {
|
|
218
261
|
cursor: default;
|
|
@@ -354,6 +397,7 @@
|
|
|
354
397
|
}
|
|
355
398
|
.wui-kanban-summary,
|
|
356
399
|
.wui-kanban-body,
|
|
400
|
+
.wui-kanban-more,
|
|
357
401
|
.wui-kanban-empty {
|
|
358
402
|
display: none;
|
|
359
403
|
}
|
|
@@ -365,18 +409,34 @@
|
|
|
365
409
|
}
|
|
366
410
|
}
|
|
367
411
|
|
|
368
|
-
// ── Phone column switcher (hidden from md up) ──
|
|
369
|
-
.wui-kanban-switcher
|
|
412
|
+
// ── Phone column switcher and swipe hint (hidden from md up) ──
|
|
413
|
+
.wui-kanban-switcher,
|
|
414
|
+
.wui-kanban-hint {
|
|
370
415
|
display: none;
|
|
371
416
|
}
|
|
372
417
|
|
|
373
418
|
@media (max-width: 767.98px) {
|
|
419
|
+
// Sticky over the page's own background, under the shell topbar (z-index 10).
|
|
374
420
|
.wui-kanban-switcher {
|
|
421
|
+
position: sticky;
|
|
422
|
+
top: var(--wui-kanban-sticky-top);
|
|
423
|
+
z-index: 5;
|
|
375
424
|
display: flex;
|
|
376
425
|
gap: 6px;
|
|
377
426
|
margin-bottom: 12px;
|
|
427
|
+
padding-block: 6px;
|
|
378
428
|
overflow-x: auto;
|
|
379
429
|
scrollbar-width: none;
|
|
430
|
+
background: var(--color-bg);
|
|
431
|
+
}
|
|
432
|
+
.wui-kanban-hint {
|
|
433
|
+
display: flex;
|
|
434
|
+
align-items: center;
|
|
435
|
+
justify-content: center;
|
|
436
|
+
gap: 6px;
|
|
437
|
+
margin: -6px 0 12px;
|
|
438
|
+
color: var(--color-text-muted);
|
|
439
|
+
font-size: 0.75rem;
|
|
380
440
|
}
|
|
381
441
|
.wui-kanban-switch {
|
|
382
442
|
display: inline-flex;
|
|
@@ -443,6 +503,9 @@
|
|
|
443
503
|
.wui-kanban-body {
|
|
444
504
|
display: flex;
|
|
445
505
|
}
|
|
506
|
+
.wui-kanban-more:not([hidden]) {
|
|
507
|
+
display: block;
|
|
508
|
+
}
|
|
446
509
|
.wui-kanban-empty:not([hidden]) {
|
|
447
510
|
display: block;
|
|
448
511
|
}
|
package/scss/wui/_media.scss
CHANGED
|
@@ -867,6 +867,18 @@
|
|
|
867
867
|
.file-preview[aria-busy="true"] {
|
|
868
868
|
cursor: progress;
|
|
869
869
|
}
|
|
870
|
+
// A disabled drop zone (AppDropZone `disabled`): dimmed, no pointer affordance, and no hover lift.
|
|
871
|
+
.file-input[aria-disabled="true"] {
|
|
872
|
+
opacity: 0.6;
|
|
873
|
+
cursor: not-allowed;
|
|
874
|
+
}
|
|
875
|
+
.file-input[aria-disabled="true"] > .file-input-zone-label {
|
|
876
|
+
cursor: not-allowed;
|
|
877
|
+
}
|
|
878
|
+
.file-input.file-input-tall[aria-disabled="true"]:hover:not(:focus-within):not(.dragging) {
|
|
879
|
+
background: var(--color-bg-muted);
|
|
880
|
+
border-color: var(--color-border);
|
|
881
|
+
}
|
|
870
882
|
.wui-file-busy {
|
|
871
883
|
position: absolute;
|
|
872
884
|
inset: 0;
|
package/scss/wui/_shell.scss
CHANGED
|
@@ -351,6 +351,12 @@
|
|
|
351
351
|
padding-top: 12px;
|
|
352
352
|
border-top: 1px solid var(--color-border);
|
|
353
353
|
}
|
|
354
|
+
// A node the author places right after a group's links (`groups[].after` /
|
|
355
|
+
// `<app-nav-group-after>`). Like sidebarStart it has no place on the 88px rail.
|
|
356
|
+
.wui-nav-group-after {
|
|
357
|
+
flex: none;
|
|
358
|
+
margin-top: 4px;
|
|
359
|
+
}
|
|
354
360
|
.app-nav-group-label {
|
|
355
361
|
padding: 6px 14px;
|
|
356
362
|
font-size: 12px;
|
|
@@ -439,6 +445,7 @@
|
|
|
439
445
|
}
|
|
440
446
|
.app-shell.collapsed .app-nav-badge,
|
|
441
447
|
.app-shell.collapsed .app-nav-group-label,
|
|
448
|
+
.app-shell.collapsed .wui-nav-group-after,
|
|
442
449
|
.app-shell.collapsed .app-sidebar-brand-text,
|
|
443
450
|
.app-shell.collapsed .app-sidebar-start {
|
|
444
451
|
display: none;
|
|
@@ -756,6 +763,7 @@
|
|
|
756
763
|
.app-shell.app-shell.collapsed .app-nav-text,
|
|
757
764
|
.app-shell.app-shell.collapsed .app-nav-badge,
|
|
758
765
|
.app-shell.app-shell.collapsed .app-nav-group-label,
|
|
766
|
+
.app-shell.app-shell.collapsed .wui-nav-group-after,
|
|
759
767
|
.app-shell.app-shell.collapsed .app-sidebar-start {
|
|
760
768
|
display: revert;
|
|
761
769
|
}
|