@webority/theme 0.29.0 → 0.30.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/dist/purge-safelist.json +5 -1
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/wui/_choice.scss +84 -29
- package/scss/wui/_kanban.scss +42 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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/wui/_choice.scss
CHANGED
|
@@ -579,8 +579,7 @@
|
|
|
579
579
|
// shut, the trigger keeps the focus look only for keyboard focus (:focus-visible); a pick or
|
|
580
580
|
// close by pointer returns it to rest. An errored field (aria-invalid on the host) keeps its red.
|
|
581
581
|
wui-datepicker:not([aria-invalid="true"]) .datepicker:not(.open) .datepicker-trigger:focus:not(:focus-visible),
|
|
582
|
-
wui-date-range:not([aria-invalid="true"]) .daterange:not(.open) .daterange-trigger:focus:not(:focus-visible)
|
|
583
|
-
wui-timepicker:not([aria-invalid="true"]) .timepicker:not(.open) .timepicker-trigger:focus:not(:focus-visible) {
|
|
582
|
+
wui-date-range:not([aria-invalid="true"]) .daterange:not(.open) .daterange-trigger:focus:not(:focus-visible) {
|
|
584
583
|
background-color: var(--color-field-bg);
|
|
585
584
|
border-color: var(--color-border);
|
|
586
585
|
}
|
|
@@ -1350,37 +1349,56 @@ wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
|
1350
1349
|
font-size: 14px;
|
|
1351
1350
|
}
|
|
1352
1351
|
|
|
1353
|
-
// timepicker — time-of-day field with
|
|
1352
|
+
// timepicker — time-of-day text field (type "7:45 pm") with a clock button that opens hour /
|
|
1353
|
+
// minute / AM-PM columns (min/max bounds, step granularity, 12/24 display).
|
|
1354
1354
|
.timepicker {
|
|
1355
1355
|
position: relative;
|
|
1356
1356
|
width: var(--wui-timepicker-width, 12rem);
|
|
1357
1357
|
max-width: 100%;
|
|
1358
1358
|
}
|
|
1359
|
+
.wui-timepicker-field {
|
|
1360
|
+
position: relative;
|
|
1361
|
+
}
|
|
1362
|
+
// The input leaves room on the right for the clock button laid over it.
|
|
1359
1363
|
.timepicker-trigger {
|
|
1360
|
-
|
|
1361
|
-
align-items: center;
|
|
1362
|
-
justify-content: space-between;
|
|
1363
|
-
gap: 8px;
|
|
1364
|
-
text-align: left;
|
|
1365
|
-
cursor: pointer;
|
|
1364
|
+
padding-right: 44px;
|
|
1366
1365
|
}
|
|
1367
|
-
.timepicker-trigger
|
|
1368
|
-
|
|
1369
|
-
white-space: nowrap;
|
|
1370
|
-
text-overflow: ellipsis;
|
|
1366
|
+
.timepicker-trigger.input-sm {
|
|
1367
|
+
padding-right: 36px;
|
|
1371
1368
|
}
|
|
1372
|
-
.timepicker-
|
|
1373
|
-
|
|
1369
|
+
.wui-timepicker-toggle {
|
|
1370
|
+
position: absolute;
|
|
1371
|
+
top: 0;
|
|
1372
|
+
right: 0;
|
|
1373
|
+
bottom: 0;
|
|
1374
|
+
display: grid;
|
|
1375
|
+
place-items: center;
|
|
1376
|
+
width: 44px;
|
|
1377
|
+
padding: 0;
|
|
1378
|
+
border: none;
|
|
1379
|
+
border-radius: 0 var(--wui-field-radius) var(--wui-field-radius) 0;
|
|
1380
|
+
background: transparent;
|
|
1374
1381
|
color: var(--color-text-subtle);
|
|
1382
|
+
cursor: pointer;
|
|
1383
|
+
transition: color 0.12s ease;
|
|
1375
1384
|
}
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
// even when the trigger classes are toggled independently.
|
|
1379
|
-
.timepicker-placeholder {
|
|
1380
|
-
color: var(--color-text-subtle);
|
|
1385
|
+
.timepicker-trigger.input-sm + .wui-timepicker-toggle {
|
|
1386
|
+
width: 36px;
|
|
1381
1387
|
}
|
|
1382
|
-
.timepicker-
|
|
1383
|
-
|
|
1388
|
+
.wui-timepicker-toggle:hover:not(:disabled),
|
|
1389
|
+
.timepicker.open .wui-timepicker-toggle {
|
|
1390
|
+
color: var(--color-primary);
|
|
1391
|
+
}
|
|
1392
|
+
.wui-timepicker-toggle:focus-visible {
|
|
1393
|
+
outline: 2px solid var(--color-primary);
|
|
1394
|
+
outline-offset: -4px;
|
|
1395
|
+
}
|
|
1396
|
+
.wui-timepicker-toggle:disabled {
|
|
1397
|
+
cursor: not-allowed;
|
|
1398
|
+
}
|
|
1399
|
+
// The control's own message for typed text it refuses; the shell's .field-error sits below it.
|
|
1400
|
+
.wui-timepicker-error {
|
|
1401
|
+
margin-top: 4px;
|
|
1384
1402
|
}
|
|
1385
1403
|
// Width presets.
|
|
1386
1404
|
.time-w-sm {
|
|
@@ -1396,18 +1414,21 @@ wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
|
1396
1414
|
--wui-timepicker-width: 100%;
|
|
1397
1415
|
}
|
|
1398
1416
|
.timepicker.open .timepicker-trigger {
|
|
1399
|
-
// Stay white while the
|
|
1417
|
+
// Stay white while the columns are open — see the note on .datepicker.open above.
|
|
1400
1418
|
background-color: var(--color-surface);
|
|
1401
1419
|
border-color: var(--color-focus-border);
|
|
1402
1420
|
box-shadow: none;
|
|
1403
1421
|
}
|
|
1422
|
+
// Refused typed text keeps the soft danger border while the columns are open, as the shell's
|
|
1423
|
+
// host-level aria-invalid already does.
|
|
1424
|
+
.timepicker.open .timepicker-trigger[aria-invalid="true"] {
|
|
1425
|
+
border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
|
|
1426
|
+
}
|
|
1404
1427
|
.timepicker-pop {
|
|
1405
1428
|
position: fixed;
|
|
1406
1429
|
z-index: var(--wui-z-menu);
|
|
1407
|
-
width:
|
|
1430
|
+
width: max-content;
|
|
1408
1431
|
max-width: calc(100vw - 16px);
|
|
1409
|
-
max-height: 360px;
|
|
1410
|
-
overflow-y: auto;
|
|
1411
1432
|
padding: 8px;
|
|
1412
1433
|
background: var(--color-surface);
|
|
1413
1434
|
border: 1px solid var(--color-border);
|
|
@@ -1439,14 +1460,37 @@ wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
|
1439
1460
|
transform: translateY(0);
|
|
1440
1461
|
}
|
|
1441
1462
|
}
|
|
1463
|
+
.wui-timepicker-cols {
|
|
1464
|
+
display: flex;
|
|
1465
|
+
gap: 4px;
|
|
1466
|
+
}
|
|
1467
|
+
// Each column scrolls on its own; overscroll stays inside so a flick never scrolls the page.
|
|
1468
|
+
.wui-timepicker-col {
|
|
1469
|
+
position: relative;
|
|
1470
|
+
display: flex;
|
|
1471
|
+
flex-direction: column;
|
|
1472
|
+
gap: 2px;
|
|
1473
|
+
min-width: 56px;
|
|
1474
|
+
max-height: 264px;
|
|
1475
|
+
overflow-y: auto;
|
|
1476
|
+
overscroll-behavior: contain;
|
|
1477
|
+
scrollbar-width: thin;
|
|
1478
|
+
}
|
|
1479
|
+
.wui-timepicker-col + .wui-timepicker-col {
|
|
1480
|
+
padding-left: 4px;
|
|
1481
|
+
border-left: 1px solid var(--color-border);
|
|
1482
|
+
}
|
|
1442
1483
|
.timepicker-option {
|
|
1443
1484
|
display: block;
|
|
1485
|
+
flex-shrink: 0;
|
|
1444
1486
|
width: 100%;
|
|
1445
|
-
|
|
1487
|
+
min-height: 36px;
|
|
1488
|
+
padding: 6px 12px;
|
|
1446
1489
|
border: none;
|
|
1447
1490
|
background: transparent;
|
|
1448
|
-
text-align:
|
|
1491
|
+
text-align: center;
|
|
1449
1492
|
font-size: 14px;
|
|
1493
|
+
font-variant-numeric: tabular-nums;
|
|
1450
1494
|
color: var(--color-text);
|
|
1451
1495
|
cursor: pointer;
|
|
1452
1496
|
border-radius: var(--radius-sm);
|
|
@@ -1454,7 +1498,13 @@ wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
|
1454
1498
|
background 0.1s,
|
|
1455
1499
|
color 0.1s;
|
|
1456
1500
|
}
|
|
1457
|
-
.
|
|
1501
|
+
// Touch screens get full 44px rows.
|
|
1502
|
+
@media (pointer: coarse) {
|
|
1503
|
+
.timepicker-option {
|
|
1504
|
+
min-height: 44px;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
.timepicker-option:hover:not(:disabled),
|
|
1458
1508
|
.timepicker-option.is-active {
|
|
1459
1509
|
background: var(--color-primary-soft, color-mix(in srgb, var(--color-primary) 8%, transparent));
|
|
1460
1510
|
color: var(--color-primary);
|
|
@@ -1464,6 +1514,11 @@ wui-timepicker[aria-invalid="true"] .timepicker.open .timepicker-trigger {
|
|
|
1464
1514
|
color: var(--color-primary-text);
|
|
1465
1515
|
font-weight: 600;
|
|
1466
1516
|
}
|
|
1517
|
+
.timepicker-option:disabled {
|
|
1518
|
+
color: var(--color-text-subtle);
|
|
1519
|
+
opacity: 0.5;
|
|
1520
|
+
cursor: not-allowed;
|
|
1521
|
+
}
|
|
1467
1522
|
.timepicker-option:focus-visible {
|
|
1468
1523
|
outline: none;
|
|
1469
1524
|
box-shadow: inset 0 0 0 2px var(--color-primary);
|
package/scss/wui/_kanban.scss
CHANGED
|
@@ -7,12 +7,20 @@
|
|
|
7
7
|
// Below md the board is one column per screen: a scroll-snapped strip with a column switcher
|
|
8
8
|
// above it. The board scrolls inside itself, so the page never scrolls sideways.
|
|
9
9
|
//
|
|
10
|
+
// Sizing variables, set on .wui-kanban (or any ancestor) to override:
|
|
11
|
+
// --wui-kanban-column-width basis width of an open column (288px)
|
|
12
|
+
// --wui-kanban-collapsed-width width of a collapsed column strip (56px)
|
|
13
|
+
// --wui-kanban-gap space between columns (16px)
|
|
14
|
+
// --wui-kanban-column-min-height least height of a column, so short columns still read as
|
|
15
|
+
// lanes (560px; not applied in the phone one-column mode)
|
|
16
|
+
//
|
|
10
17
|
// Part of the wui-components layer, see _wui-components.scss for load order.
|
|
11
18
|
|
|
12
19
|
.wui-kanban {
|
|
13
20
|
--wui-kanban-column-width: 288px;
|
|
14
21
|
--wui-kanban-collapsed-width: 56px;
|
|
15
22
|
--wui-kanban-gap: 16px;
|
|
23
|
+
--wui-kanban-column-min-height: 560px;
|
|
16
24
|
display: block;
|
|
17
25
|
position: relative;
|
|
18
26
|
min-width: 0;
|
|
@@ -34,8 +42,9 @@
|
|
|
34
42
|
flex: 1 0 var(--wui-kanban-column-width);
|
|
35
43
|
min-width: 0;
|
|
36
44
|
max-width: 100%;
|
|
37
|
-
|
|
38
|
-
|
|
45
|
+
min-height: var(--wui-kanban-column-min-height);
|
|
46
|
+
background: var(--color-bg-muted);
|
|
47
|
+
border: 1px solid var(--color-border);
|
|
39
48
|
border-radius: var(--wui-radius-lg);
|
|
40
49
|
transition:
|
|
41
50
|
background-color 160ms var(--wui-ease-ui),
|
|
@@ -74,12 +83,14 @@
|
|
|
74
83
|
background: var(--color-danger);
|
|
75
84
|
}
|
|
76
85
|
|
|
86
|
+
// The title takes its own width so the count sits right beside it; the collapse button keeps to
|
|
87
|
+
// the far edge through its own auto margin.
|
|
77
88
|
.wui-kanban-title {
|
|
78
|
-
flex:
|
|
89
|
+
flex: 0 1 auto;
|
|
79
90
|
min-width: 0;
|
|
80
91
|
margin: 0;
|
|
81
|
-
font-size: 0.
|
|
82
|
-
font-weight:
|
|
92
|
+
font-size: 0.875rem;
|
|
93
|
+
font-weight: 700;
|
|
83
94
|
line-height: 1.3;
|
|
84
95
|
color: var(--color-text);
|
|
85
96
|
overflow-wrap: anywhere;
|
|
@@ -117,6 +128,7 @@
|
|
|
117
128
|
flex: none;
|
|
118
129
|
width: 32px;
|
|
119
130
|
height: 32px;
|
|
131
|
+
margin-inline-start: auto;
|
|
120
132
|
padding: 0;
|
|
121
133
|
border: 0;
|
|
122
134
|
border-radius: var(--wui-radius);
|
|
@@ -128,8 +140,9 @@
|
|
|
128
140
|
transition: transform 160ms var(--wui-ease-ui);
|
|
129
141
|
}
|
|
130
142
|
}
|
|
143
|
+
// The column itself is the muted fill, so hover lifts to the surface.
|
|
131
144
|
.wui-kanban-collapse:hover {
|
|
132
|
-
background: var(--color-
|
|
145
|
+
background: var(--color-surface);
|
|
133
146
|
color: var(--color-text);
|
|
134
147
|
}
|
|
135
148
|
.wui-kanban-collapse:focus-visible,
|
|
@@ -247,7 +260,11 @@
|
|
|
247
260
|
margin: 0;
|
|
248
261
|
pointer-events: none;
|
|
249
262
|
cursor: grabbing;
|
|
250
|
-
box
|
|
263
|
+
// A 2px primary edge drawn as border plus ring, so the clone keeps the card's exact box.
|
|
264
|
+
border-color: var(--color-primary);
|
|
265
|
+
box-shadow:
|
|
266
|
+
0 0 0 1px var(--color-primary),
|
|
267
|
+
var(--wui-shadow-overlay-lg);
|
|
251
268
|
rotate: 2deg;
|
|
252
269
|
}
|
|
253
270
|
.wui-kanban[data-wui-dragging] {
|
|
@@ -267,17 +284,30 @@
|
|
|
267
284
|
.wui-kanban-column[data-wui-drop="ok"] {
|
|
268
285
|
border: 1px dashed var(--color-primary);
|
|
269
286
|
}
|
|
287
|
+
// The column under the card: a 2px dashed primary edge (an inset outline over a hidden border,
|
|
288
|
+
// so nothing inside shifts) on the soft primary fill, and the note becomes a filled label bar.
|
|
270
289
|
.wui-kanban-column[data-wui-drop="ok"][data-wui-over],
|
|
271
290
|
.wui-kanban-column[data-wui-drop="ok"][data-wui-target] {
|
|
272
291
|
background: var(--color-primary-soft);
|
|
273
|
-
border-
|
|
292
|
+
border-color: transparent;
|
|
293
|
+
outline: 2px dashed var(--color-primary);
|
|
294
|
+
outline-offset: -2px;
|
|
274
295
|
}
|
|
275
296
|
.wui-kanban-column[data-wui-drop="ok"] .wui-kanban-drop-note {
|
|
276
297
|
color: var(--color-text);
|
|
277
298
|
}
|
|
278
|
-
|
|
299
|
+
.wui-kanban-column[data-wui-drop="ok"][data-wui-over] .wui-kanban-drop-note,
|
|
300
|
+
.wui-kanban-column[data-wui-drop="ok"][data-wui-target] .wui-kanban-drop-note {
|
|
301
|
+
border-radius: var(--wui-radius-sm);
|
|
302
|
+
background: var(--color-primary);
|
|
303
|
+
color: var(--color-primary-text);
|
|
304
|
+
font-weight: 600;
|
|
305
|
+
}
|
|
306
|
+
// Refused: hatched and locked, with the reason in the note. The hatch is drawn over the subtle
|
|
307
|
+
// fill, since its stripes are the muted fill an open column already has.
|
|
279
308
|
.wui-kanban-column[data-wui-drop="refused"] {
|
|
280
309
|
border-color: var(--color-border);
|
|
310
|
+
background-color: var(--color-bg-subtle);
|
|
281
311
|
background-image: repeating-linear-gradient(
|
|
282
312
|
135deg,
|
|
283
313
|
var(--color-bg-muted) 0 8px,
|
|
@@ -317,6 +347,7 @@
|
|
|
317
347
|
}
|
|
318
348
|
.wui-kanban-collapse {
|
|
319
349
|
order: -1;
|
|
350
|
+
margin-inline-start: 0;
|
|
320
351
|
}
|
|
321
352
|
.wui-kanban-collapse svg {
|
|
322
353
|
transform: rotate(180deg);
|
|
@@ -389,6 +420,7 @@
|
|
|
389
420
|
.wui-kanban-column,
|
|
390
421
|
.wui-kanban-column[data-collapsed] {
|
|
391
422
|
flex: 0 0 100%;
|
|
423
|
+
min-height: 0;
|
|
392
424
|
scroll-snap-align: start;
|
|
393
425
|
align-self: flex-start;
|
|
394
426
|
|
|
@@ -399,7 +431,7 @@
|
|
|
399
431
|
}
|
|
400
432
|
.wui-kanban-title {
|
|
401
433
|
writing-mode: horizontal-tb;
|
|
402
|
-
flex:
|
|
434
|
+
flex: 0 1 auto;
|
|
403
435
|
white-space: normal;
|
|
404
436
|
}
|
|
405
437
|
.wui-kanban-collapse {
|