@webority/theme 0.25.0 → 0.26.1
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/dist/purge-safelist.json +76 -2
- package/dist/webority-theme.css +1 -1
- package/fonts/sans/WeboritySans-Bold.woff2 +0 -0
- package/fonts/sans/WeboritySans-BoldItalic.woff2 +0 -0
- package/fonts/sans/WeboritySans-Medium.woff2 +0 -0
- package/fonts/sans/WeboritySans-Regular.woff2 +0 -0
- package/fonts/sans/WeboritySans-RegularItalic.woff2 +0 -0
- package/fonts/sans/WeboritySans-SemiBold.woff2 +0 -0
- package/package.json +1 -1
- package/scss/_fonts.scss +2 -1
- package/scss/_wui-components.scss +1 -0
- package/scss/wui/_data.scss +8 -6
- package/scss/wui/_kanban.scss +434 -0
- package/scss/wui/_modal-remote.scss +53 -1
- package/scss/wui/_overlays.scss +39 -0
- package/scss/wui/_shell-parts.scss +500 -0
- package/scss/wui/_shell.scss +11 -0
- package/scss/wui/_table-server.scss +37 -0
|
@@ -1,3 +1,503 @@
|
|
|
1
1
|
// Shell parts: notification bell, topbar search, phone tab bar, user menu.
|
|
2
2
|
//
|
|
3
3
|
// Part of the wui-components layer; imported after its base partial (see _wui-components.scss).
|
|
4
|
+
// The same markup comes from React AppShell (userMenu / notifications / search / tab items) and
|
|
5
|
+
// the Razor <app-shell-*> helpers. Every class here is wui-*; the frame classes it hangs off
|
|
6
|
+
// (.app-shell, .app-topbar-start, .app-content, .app-footer) are the shell's own.
|
|
7
|
+
//
|
|
8
|
+
// Phone floor: every control here is at least 44px tall below 768px, and nothing that opens is
|
|
9
|
+
// wider than the viewport less 24px.
|
|
10
|
+
|
|
11
|
+
.app-shell {
|
|
12
|
+
// One height the tab bar, the content's bottom padding and the footer's offset agree on.
|
|
13
|
+
--wui-tabbar-h: 60px;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ── Phone tab bar ───────────────────────────────────────────────────────────────────────────
|
|
17
|
+
// Four destinations plus More (or five), fixed to the bottom below md. Above md the sidebar or
|
|
18
|
+
// drawer carries the nav, so the bar is not rendered visible at all.
|
|
19
|
+
.wui-tabbar {
|
|
20
|
+
display: none;
|
|
21
|
+
}
|
|
22
|
+
@include media-breakpoint-down(md) {
|
|
23
|
+
.wui-tabbar {
|
|
24
|
+
position: fixed;
|
|
25
|
+
right: 0;
|
|
26
|
+
bottom: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
z-index: var(--wui-z-fixed);
|
|
29
|
+
display: grid;
|
|
30
|
+
grid-auto-columns: 1fr;
|
|
31
|
+
grid-auto-flow: column;
|
|
32
|
+
padding-bottom: env(safe-area-inset-bottom);
|
|
33
|
+
border-top: 1px solid var(--color-border);
|
|
34
|
+
background: var(--color-surface);
|
|
35
|
+
}
|
|
36
|
+
// The last content must scroll clear of the bar, and a footer sits on top of it.
|
|
37
|
+
.app-shell:has(> .wui-tabbar) .app-content {
|
|
38
|
+
padding-bottom: calc(var(--wui-tabbar-h) + 28px + env(safe-area-inset-bottom));
|
|
39
|
+
}
|
|
40
|
+
.app-shell:has(> .wui-tabbar) .app-footer {
|
|
41
|
+
bottom: calc(var(--wui-tabbar-h) + env(safe-area-inset-bottom));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
.wui-tabbar-item {
|
|
45
|
+
position: relative;
|
|
46
|
+
display: flex;
|
|
47
|
+
flex-direction: column;
|
|
48
|
+
align-items: center;
|
|
49
|
+
justify-content: center;
|
|
50
|
+
gap: 2px;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
min-height: var(--wui-tabbar-h);
|
|
53
|
+
padding: 6px 4px;
|
|
54
|
+
border: 0;
|
|
55
|
+
background: transparent;
|
|
56
|
+
font: inherit;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
font-weight: 500;
|
|
59
|
+
color: var(--color-text-muted);
|
|
60
|
+
text-decoration: none;
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
}
|
|
63
|
+
.wui-tabbar-item:hover {
|
|
64
|
+
color: var(--color-text);
|
|
65
|
+
text-decoration: none;
|
|
66
|
+
}
|
|
67
|
+
.wui-tabbar-item.active {
|
|
68
|
+
color: var(--color-primary);
|
|
69
|
+
font-weight: 600;
|
|
70
|
+
}
|
|
71
|
+
.wui-tabbar-item:focus-visible {
|
|
72
|
+
outline: 2px solid var(--color-primary);
|
|
73
|
+
outline-offset: -4px;
|
|
74
|
+
border-radius: var(--radius-lg);
|
|
75
|
+
}
|
|
76
|
+
.wui-tabbar-icon {
|
|
77
|
+
display: inline-grid;
|
|
78
|
+
place-items: center;
|
|
79
|
+
}
|
|
80
|
+
.wui-tabbar-label {
|
|
81
|
+
max-width: 100%;
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
text-overflow: ellipsis;
|
|
84
|
+
white-space: nowrap;
|
|
85
|
+
}
|
|
86
|
+
// A count over the icon. Neutral by default, toned like the nav badge it mirrors (-text on -soft,
|
|
87
|
+
// the 4.5:1 pairing the nav badge tones use).
|
|
88
|
+
.wui-tabbar-badge {
|
|
89
|
+
position: absolute;
|
|
90
|
+
top: 6px;
|
|
91
|
+
left: calc(50% + 6px);
|
|
92
|
+
min-width: 18px;
|
|
93
|
+
height: 18px;
|
|
94
|
+
padding: 0 5px;
|
|
95
|
+
border-radius: 999px;
|
|
96
|
+
background: var(--color-bg-muted);
|
|
97
|
+
color: var(--color-text-muted);
|
|
98
|
+
font-size: 11px;
|
|
99
|
+
font-weight: 700;
|
|
100
|
+
line-height: 18px;
|
|
101
|
+
text-align: center;
|
|
102
|
+
}
|
|
103
|
+
.wui-tabbar-badge.tone-danger {
|
|
104
|
+
background: var(--color-danger-soft);
|
|
105
|
+
color: var(--color-danger-text);
|
|
106
|
+
}
|
|
107
|
+
.wui-tabbar-badge.tone-success {
|
|
108
|
+
background: var(--color-success-soft);
|
|
109
|
+
color: var(--color-success-text);
|
|
110
|
+
}
|
|
111
|
+
.wui-tabbar-badge.tone-warning {
|
|
112
|
+
background: var(--color-warning-soft);
|
|
113
|
+
color: var(--color-warning-text);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ── Topbar menus: shared card ───────────────────────────────────────────────────────────────
|
|
117
|
+
// Both menus open with Bootstrap's static display (Razor data-bs-display="static"; React sets
|
|
118
|
+
// data-bs-popper="static" while open), so placement is plain CSS: under the trigger, end-aligned.
|
|
119
|
+
.wui-usermenu-menu,
|
|
120
|
+
.wui-bell-menu {
|
|
121
|
+
top: calc(100% + 8px);
|
|
122
|
+
right: 0;
|
|
123
|
+
left: auto;
|
|
124
|
+
max-width: calc(100vw - 24px);
|
|
125
|
+
border: 1px solid var(--color-border);
|
|
126
|
+
border-radius: var(--radius-lg);
|
|
127
|
+
background: var(--color-surface);
|
|
128
|
+
box-shadow: var(--shadow-overlay);
|
|
129
|
+
}
|
|
130
|
+
.wui-usermenu-menu .dropdown-item {
|
|
131
|
+
display: flex;
|
|
132
|
+
align-items: center;
|
|
133
|
+
gap: 10px;
|
|
134
|
+
min-height: 44px;
|
|
135
|
+
border-radius: var(--radius-sm);
|
|
136
|
+
color: var(--color-text-body);
|
|
137
|
+
white-space: normal;
|
|
138
|
+
}
|
|
139
|
+
.wui-usermenu-menu .dropdown-item:hover {
|
|
140
|
+
background: var(--color-bg-muted);
|
|
141
|
+
color: var(--color-text);
|
|
142
|
+
}
|
|
143
|
+
.wui-usermenu-menu .dropdown-item.danger {
|
|
144
|
+
color: var(--color-danger-text);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ── User menu ───────────────────────────────────────────────────────────────────────────────
|
|
148
|
+
.wui-usermenu-trigger {
|
|
149
|
+
display: inline-flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
gap: 10px;
|
|
152
|
+
min-height: 44px;
|
|
153
|
+
padding: 4px 8px 4px 4px;
|
|
154
|
+
border: 0;
|
|
155
|
+
border-radius: 999px;
|
|
156
|
+
background: transparent;
|
|
157
|
+
color: var(--color-text);
|
|
158
|
+
font: inherit;
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
}
|
|
161
|
+
.wui-usermenu-trigger:hover {
|
|
162
|
+
background: var(--color-bg-muted);
|
|
163
|
+
}
|
|
164
|
+
.wui-usermenu-trigger:focus-visible {
|
|
165
|
+
outline: 2px solid var(--color-primary);
|
|
166
|
+
outline-offset: 2px;
|
|
167
|
+
}
|
|
168
|
+
.wui-usermenu-text {
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
line-height: 1.2;
|
|
172
|
+
text-align: left;
|
|
173
|
+
}
|
|
174
|
+
.wui-usermenu-name {
|
|
175
|
+
font-size: 14px;
|
|
176
|
+
font-weight: 600;
|
|
177
|
+
color: var(--color-text);
|
|
178
|
+
}
|
|
179
|
+
.wui-usermenu-role {
|
|
180
|
+
font-size: 12px;
|
|
181
|
+
color: var(--color-text-muted);
|
|
182
|
+
}
|
|
183
|
+
.wui-usermenu-caret {
|
|
184
|
+
color: var(--color-text-muted);
|
|
185
|
+
}
|
|
186
|
+
// Below xl the name and role give way to the avatar alone.
|
|
187
|
+
@include media-breakpoint-down(xl) {
|
|
188
|
+
.wui-usermenu-text,
|
|
189
|
+
.wui-usermenu-caret {
|
|
190
|
+
display: none;
|
|
191
|
+
}
|
|
192
|
+
// The avatar alone is narrower than a touch target.
|
|
193
|
+
.wui-usermenu-trigger {
|
|
194
|
+
min-width: 44px;
|
|
195
|
+
justify-content: center;
|
|
196
|
+
padding: 4px;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
.wui-usermenu-menu {
|
|
200
|
+
min-width: 260px;
|
|
201
|
+
padding: 8px;
|
|
202
|
+
}
|
|
203
|
+
.wui-usermenu-head {
|
|
204
|
+
display: flex;
|
|
205
|
+
align-items: center;
|
|
206
|
+
gap: 12px;
|
|
207
|
+
margin-bottom: 6px;
|
|
208
|
+
padding: 8px 8px 12px;
|
|
209
|
+
border-bottom: 1px solid var(--color-border);
|
|
210
|
+
}
|
|
211
|
+
.wui-usermenu-who {
|
|
212
|
+
min-width: 0;
|
|
213
|
+
overflow-wrap: anywhere;
|
|
214
|
+
}
|
|
215
|
+
.wui-usermenu-logout {
|
|
216
|
+
margin: 0;
|
|
217
|
+
}
|
|
218
|
+
.wui-usermenu-logout .dropdown-item {
|
|
219
|
+
width: 100%;
|
|
220
|
+
border: 0;
|
|
221
|
+
background: transparent;
|
|
222
|
+
text-align: left;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ── Notification bell ───────────────────────────────────────────────────────────────────────
|
|
226
|
+
.wui-bell-trigger {
|
|
227
|
+
position: relative;
|
|
228
|
+
}
|
|
229
|
+
// White on the strong danger fill, the avatar badge's pairing. Ringed in the surface colour so it
|
|
230
|
+
// reads as sitting on the bell rather than touching it.
|
|
231
|
+
.wui-bell-count {
|
|
232
|
+
position: absolute;
|
|
233
|
+
top: 2px;
|
|
234
|
+
right: 0;
|
|
235
|
+
box-sizing: content-box;
|
|
236
|
+
min-width: 18px;
|
|
237
|
+
height: 18px;
|
|
238
|
+
padding: 0 5px;
|
|
239
|
+
border: 2px solid var(--color-surface);
|
|
240
|
+
border-radius: 999px;
|
|
241
|
+
background: var(--color-danger-strong);
|
|
242
|
+
color: var(--wui-bg-light);
|
|
243
|
+
font-size: 11px;
|
|
244
|
+
font-weight: 700;
|
|
245
|
+
line-height: 18px;
|
|
246
|
+
text-align: center;
|
|
247
|
+
}
|
|
248
|
+
.wui-bell-count[hidden] {
|
|
249
|
+
display: none;
|
|
250
|
+
}
|
|
251
|
+
.wui-bell-menu {
|
|
252
|
+
width: 360px;
|
|
253
|
+
padding: 0;
|
|
254
|
+
overflow: hidden;
|
|
255
|
+
}
|
|
256
|
+
.wui-bell-head {
|
|
257
|
+
display: flex;
|
|
258
|
+
align-items: center;
|
|
259
|
+
justify-content: space-between;
|
|
260
|
+
gap: 12px;
|
|
261
|
+
padding: 10px 16px;
|
|
262
|
+
border-bottom: 1px solid var(--color-border);
|
|
263
|
+
}
|
|
264
|
+
.wui-bell-title {
|
|
265
|
+
font-weight: 600;
|
|
266
|
+
color: var(--color-text);
|
|
267
|
+
}
|
|
268
|
+
.wui-bell-markall {
|
|
269
|
+
display: inline-flex;
|
|
270
|
+
align-items: center;
|
|
271
|
+
min-height: 44px;
|
|
272
|
+
padding: 0 4px;
|
|
273
|
+
border: 0;
|
|
274
|
+
background: none;
|
|
275
|
+
color: var(--color-primary);
|
|
276
|
+
font: inherit;
|
|
277
|
+
font-size: 14px;
|
|
278
|
+
font-weight: 500;
|
|
279
|
+
cursor: pointer;
|
|
280
|
+
}
|
|
281
|
+
.wui-bell-markall:hover {
|
|
282
|
+
text-decoration: underline;
|
|
283
|
+
}
|
|
284
|
+
.wui-bell-markall:disabled {
|
|
285
|
+
opacity: 0.6;
|
|
286
|
+
cursor: default;
|
|
287
|
+
}
|
|
288
|
+
.wui-bell-list {
|
|
289
|
+
max-height: min(420px, 60vh);
|
|
290
|
+
overflow-y: auto;
|
|
291
|
+
}
|
|
292
|
+
.wui-bell-list[aria-busy="true"] {
|
|
293
|
+
opacity: 0.7;
|
|
294
|
+
}
|
|
295
|
+
.wui-bell-item {
|
|
296
|
+
display: flex;
|
|
297
|
+
gap: 12px;
|
|
298
|
+
min-height: 44px;
|
|
299
|
+
padding: 12px 16px;
|
|
300
|
+
border-bottom: 1px solid var(--color-border-light);
|
|
301
|
+
color: var(--color-text-body);
|
|
302
|
+
text-decoration: none;
|
|
303
|
+
}
|
|
304
|
+
a.wui-bell-item:hover {
|
|
305
|
+
background: var(--color-bg-muted);
|
|
306
|
+
text-decoration: none;
|
|
307
|
+
}
|
|
308
|
+
.wui-bell-item:last-child {
|
|
309
|
+
border-bottom: 0;
|
|
310
|
+
}
|
|
311
|
+
.wui-bell-dot {
|
|
312
|
+
flex: none;
|
|
313
|
+
width: 8px;
|
|
314
|
+
height: 8px;
|
|
315
|
+
margin-top: 6px;
|
|
316
|
+
border-radius: 50%;
|
|
317
|
+
background: var(--color-primary);
|
|
318
|
+
}
|
|
319
|
+
.wui-bell-item-read .wui-bell-dot {
|
|
320
|
+
visibility: hidden;
|
|
321
|
+
}
|
|
322
|
+
.wui-bell-icon {
|
|
323
|
+
flex: none;
|
|
324
|
+
color: var(--color-text-subtle);
|
|
325
|
+
}
|
|
326
|
+
.wui-bell-body {
|
|
327
|
+
display: flex;
|
|
328
|
+
flex-direction: column;
|
|
329
|
+
min-width: 0;
|
|
330
|
+
}
|
|
331
|
+
.wui-bell-item-title {
|
|
332
|
+
font-size: 14px;
|
|
333
|
+
font-weight: 500;
|
|
334
|
+
color: var(--color-text);
|
|
335
|
+
overflow-wrap: anywhere;
|
|
336
|
+
}
|
|
337
|
+
.wui-bell-item-read .wui-bell-item-title {
|
|
338
|
+
font-weight: 400;
|
|
339
|
+
}
|
|
340
|
+
.wui-bell-when {
|
|
341
|
+
font-size: 12px;
|
|
342
|
+
color: var(--color-text-muted);
|
|
343
|
+
}
|
|
344
|
+
.wui-bell-state {
|
|
345
|
+
padding: 20px 16px;
|
|
346
|
+
font-size: 14px;
|
|
347
|
+
color: var(--color-text-muted);
|
|
348
|
+
text-align: center;
|
|
349
|
+
}
|
|
350
|
+
.wui-bell-foot {
|
|
351
|
+
display: flex;
|
|
352
|
+
align-items: center;
|
|
353
|
+
justify-content: center;
|
|
354
|
+
min-height: 44px;
|
|
355
|
+
border-top: 1px solid var(--color-border);
|
|
356
|
+
color: var(--color-primary);
|
|
357
|
+
font-size: 14px;
|
|
358
|
+
font-weight: 500;
|
|
359
|
+
text-decoration: none;
|
|
360
|
+
}
|
|
361
|
+
.wui-bell-foot:hover {
|
|
362
|
+
background: var(--color-bg-muted);
|
|
363
|
+
}
|
|
364
|
+
// A 360px card would overflow a 375px phone: below md the panel is a sheet inset 12px, under the
|
|
365
|
+
// 72px topbar.
|
|
366
|
+
@include media-breakpoint-down(md) {
|
|
367
|
+
.wui-bell-menu {
|
|
368
|
+
position: fixed;
|
|
369
|
+
top: 72px;
|
|
370
|
+
right: 12px;
|
|
371
|
+
left: 12px;
|
|
372
|
+
width: auto;
|
|
373
|
+
max-width: none;
|
|
374
|
+
}
|
|
375
|
+
.wui-bell-list {
|
|
376
|
+
max-height: calc(100dvh - 72px - 12px - 120px);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ── Topbar search ───────────────────────────────────────────────────────────────────────────
|
|
381
|
+
// A field after the topbar-start content above md; an icon button that opens the field as a
|
|
382
|
+
// full-width panel under the topbar below it.
|
|
383
|
+
.app-topbar-start:has(> .wui-topsearch) {
|
|
384
|
+
flex: 1 1 auto;
|
|
385
|
+
}
|
|
386
|
+
.wui-topsearch {
|
|
387
|
+
position: relative;
|
|
388
|
+
width: min(380px, 38vw);
|
|
389
|
+
}
|
|
390
|
+
.wui-topsearch-open {
|
|
391
|
+
display: none;
|
|
392
|
+
}
|
|
393
|
+
.wui-topsearch-results {
|
|
394
|
+
position: absolute;
|
|
395
|
+
top: calc(100% + 6px);
|
|
396
|
+
right: 0;
|
|
397
|
+
left: 0;
|
|
398
|
+
z-index: var(--wui-z-dropdown);
|
|
399
|
+
max-height: min(440px, 70vh);
|
|
400
|
+
padding: 6px;
|
|
401
|
+
overflow-y: auto;
|
|
402
|
+
border: 1px solid var(--color-border);
|
|
403
|
+
border-radius: var(--radius-lg);
|
|
404
|
+
background: var(--color-surface);
|
|
405
|
+
box-shadow: var(--shadow-overlay);
|
|
406
|
+
}
|
|
407
|
+
.wui-topsearch-results[hidden] {
|
|
408
|
+
display: none;
|
|
409
|
+
}
|
|
410
|
+
.wui-topsearch-group + .wui-topsearch-group {
|
|
411
|
+
margin-top: 4px;
|
|
412
|
+
padding-top: 4px;
|
|
413
|
+
border-top: 1px solid var(--color-border-light);
|
|
414
|
+
}
|
|
415
|
+
.wui-topsearch-group-label {
|
|
416
|
+
padding: 6px 10px 4px;
|
|
417
|
+
font-size: 12px;
|
|
418
|
+
font-weight: 600;
|
|
419
|
+
letter-spacing: 0.06em;
|
|
420
|
+
text-transform: uppercase;
|
|
421
|
+
color: var(--color-text-subtle);
|
|
422
|
+
}
|
|
423
|
+
.wui-topsearch-hit {
|
|
424
|
+
display: flex;
|
|
425
|
+
align-items: center;
|
|
426
|
+
gap: 10px;
|
|
427
|
+
min-height: 44px;
|
|
428
|
+
padding: 6px 10px;
|
|
429
|
+
border-radius: var(--radius-sm);
|
|
430
|
+
color: var(--color-text-body);
|
|
431
|
+
text-decoration: none;
|
|
432
|
+
}
|
|
433
|
+
.wui-topsearch-hit:hover,
|
|
434
|
+
.wui-topsearch-hit.is-active {
|
|
435
|
+
background: var(--color-bg-muted);
|
|
436
|
+
color: var(--color-text);
|
|
437
|
+
text-decoration: none;
|
|
438
|
+
}
|
|
439
|
+
.wui-topsearch-hit-icon {
|
|
440
|
+
flex: none;
|
|
441
|
+
display: inline-grid;
|
|
442
|
+
place-items: center;
|
|
443
|
+
color: var(--color-text-subtle);
|
|
444
|
+
}
|
|
445
|
+
.wui-topsearch-hit-text {
|
|
446
|
+
display: flex;
|
|
447
|
+
flex-direction: column;
|
|
448
|
+
min-width: 0;
|
|
449
|
+
}
|
|
450
|
+
.wui-topsearch-hit-title {
|
|
451
|
+
font-size: 14px;
|
|
452
|
+
font-weight: 500;
|
|
453
|
+
color: var(--color-text);
|
|
454
|
+
overflow-wrap: anywhere;
|
|
455
|
+
}
|
|
456
|
+
.wui-topsearch-hit-sub {
|
|
457
|
+
font-size: 12px;
|
|
458
|
+
color: var(--color-text-muted);
|
|
459
|
+
}
|
|
460
|
+
.wui-topsearch-all {
|
|
461
|
+
margin-top: 4px;
|
|
462
|
+
border-top: 1px solid var(--color-border-light);
|
|
463
|
+
border-radius: 0 0 var(--radius-sm) var(--radius-sm);
|
|
464
|
+
}
|
|
465
|
+
.wui-topsearch-empty {
|
|
466
|
+
padding: 14px 10px;
|
|
467
|
+
font-size: 14px;
|
|
468
|
+
color: var(--color-text-muted);
|
|
469
|
+
}
|
|
470
|
+
// While suggestions load, the leading glyph dims; the field stays usable.
|
|
471
|
+
.wui-topsearch.is-loading .search-icon {
|
|
472
|
+
opacity: 0.5;
|
|
473
|
+
}
|
|
474
|
+
@include media-breakpoint-down(md) {
|
|
475
|
+
.wui-topsearch {
|
|
476
|
+
width: auto;
|
|
477
|
+
margin-left: auto;
|
|
478
|
+
}
|
|
479
|
+
.wui-topsearch-open {
|
|
480
|
+
display: inline-flex;
|
|
481
|
+
}
|
|
482
|
+
.wui-topsearch-panel {
|
|
483
|
+
display: none;
|
|
484
|
+
}
|
|
485
|
+
.wui-topsearch.is-open .wui-topsearch-panel {
|
|
486
|
+
position: fixed;
|
|
487
|
+
top: 72px;
|
|
488
|
+
right: 0;
|
|
489
|
+
left: 0;
|
|
490
|
+
z-index: var(--wui-z-dropdown);
|
|
491
|
+
display: block;
|
|
492
|
+
padding: 12px;
|
|
493
|
+
border-bottom: 1px solid var(--color-border);
|
|
494
|
+
background: var(--color-surface);
|
|
495
|
+
box-shadow: var(--shadow-overlay);
|
|
496
|
+
}
|
|
497
|
+
.wui-topsearch-results {
|
|
498
|
+
position: static;
|
|
499
|
+
max-height: calc(100dvh - 72px - 24px - 52px);
|
|
500
|
+
margin-top: 8px;
|
|
501
|
+
box-shadow: none;
|
|
502
|
+
}
|
|
503
|
+
}
|
package/scss/wui/_shell.scss
CHANGED
|
@@ -736,6 +736,17 @@
|
|
|
736
736
|
.app-shell.app-shell .app-topbar {
|
|
737
737
|
padding-inline: 16px;
|
|
738
738
|
}
|
|
739
|
+
.app-shell.app-shell .app-content {
|
|
740
|
+
padding-block: 16px 32px;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
// Phones: the topbar's icon controls meet the 44px touch floor (36px is a pointer size).
|
|
744
|
+
@include media-breakpoint-down(md) {
|
|
745
|
+
.app-shell.app-shell .app-topbar-menu,
|
|
746
|
+
.app-topbar .topbar-icon-btn {
|
|
747
|
+
width: 44px;
|
|
748
|
+
height: 44px;
|
|
749
|
+
}
|
|
739
750
|
}
|
|
740
751
|
// The scrim exists only while the drawer is open, and only below lg — it is
|
|
741
752
|
// rendered unconditionally and made visible here so there is no JS breakpoint check.
|
|
@@ -1,3 +1,40 @@
|
|
|
1
1
|
// Server-paged data table: loading, empty and error states, the busy dim and the server sort affordance.
|
|
2
2
|
//
|
|
3
3
|
// Part of the wui-components layer; imported after its base partial (see _wui-components.scss).
|
|
4
|
+
//
|
|
5
|
+
// `<app-data-table src>` wraps the usual `.table-wrap` in `.wui-table-server`; the rows, pager and
|
|
6
|
+
// states are swapped in by the behaviour layer (ui-elements serverTable.js). The sortable header
|
|
7
|
+
// (`th[data-sort-key]` gets `.sortable` and the `.sort-icon`) and the empty state
|
|
8
|
+
// (`.tbl-empty-block`) reuse the client-side table rules in _data.scss unchanged.
|
|
9
|
+
|
|
10
|
+
// While a page is in flight the current rows stay in place, dimmed, so the table does not jump;
|
|
11
|
+
// they are not interactive until the new page lands.
|
|
12
|
+
.wui-table-server > .table-wrap[aria-busy="true"] {
|
|
13
|
+
cursor: progress;
|
|
14
|
+
}
|
|
15
|
+
.wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody {
|
|
16
|
+
opacity: 0.55;
|
|
17
|
+
pointer-events: none;
|
|
18
|
+
transition: opacity 0.15s ease;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// A failed fetch shows its message and Retry in the state block; the stale rows of the previous
|
|
22
|
+
// page are hidden rather than left looking current.
|
|
23
|
+
.wui-table-server > .table-wrap[data-wui-table-error] > .table > tbody {
|
|
24
|
+
display: none;
|
|
25
|
+
}
|
|
26
|
+
.wui-table-error .tbl-empty-icon {
|
|
27
|
+
color: var(--color-danger-text);
|
|
28
|
+
background: var(--color-danger-soft);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// The pager region exists from the first paint; an empty list has no pager to show.
|
|
32
|
+
.wui-table-pager:empty {
|
|
33
|
+
display: none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media (prefers-reduced-motion: reduce) {
|
|
37
|
+
.wui-table-server > .table-wrap[aria-busy="true"] > .table > tbody {
|
|
38
|
+
transition: none;
|
|
39
|
+
}
|
|
40
|
+
}
|