@webority/theme 0.7.7 → 0.7.9
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 +50 -0
- package/dist/webority-theme.css +1 -1
- package/package.json +1 -1
- package/scss/_components.scss +184 -14
- package/scss/_tokens.scss +11 -3
- package/scss/_wui-aliases.scss +35 -5
- package/scss/_wui-components.scss +8 -1
- package/scss/wui/_card.scss +2 -2
- package/scss/wui/_choice.scss +11 -4
- package/scss/wui/_controls.scss +93 -48
- package/scss/wui/_data.scss +20 -0
- package/scss/wui/_flow.scss +250 -34
- package/scss/wui/_media.scss +1 -1
- package/scss/wui/_overlays.scss +254 -25
- package/scss/wui/_shell.scss +37 -3
- package/scss/wui/_tone-pill.scss +23 -0
- package/scss/wui/_typography.scss +45 -15
- package/scss/wui/_utilities.scss +29 -1
- package/scss/wui/_workspace.scss +239 -0
package/scss/wui/_overlays.scss
CHANGED
|
@@ -329,46 +329,275 @@
|
|
|
329
329
|
font-weight: 500;
|
|
330
330
|
}
|
|
331
331
|
|
|
332
|
+
// ── Tooltip ──
|
|
333
|
+
// Both surfaces render Bootstrap's .tooltip / .tooltip-inner (React via react-bootstrap
|
|
334
|
+
// <Tooltip>, Razor via Bootstrap's own tooltip JS). The wrappers tag the tooltip element with
|
|
335
|
+
// `wui-tooltip` (React className, Razor data-bs-custom-class), so this design lands on App
|
|
336
|
+
// tooltips only and never on a raw Bootstrap one. Every colour flows --wui-tooltip-* →
|
|
337
|
+
// Bootstrap's own --bs-tooltip-* vars, so the arrow (which Bootstrap paints from
|
|
338
|
+
// --bs-tooltip-bg) always tracks the body. Customisation seam: override a --wui-tooltip-* var
|
|
339
|
+
// from a caller className for any colour, or add a tone-* class for a preset.
|
|
340
|
+
//
|
|
341
|
+
// The --wui-tooltip-* defaults sit at ZERO specificity (:where) so a caller's own single class
|
|
342
|
+
// (or inline style) overrides them; the tone presets are ordinary (0,3,0) rules that win over
|
|
343
|
+
// the defaults but lose to nothing a caller would reasonably write.
|
|
344
|
+
:where(.tooltip.wui-tooltip) {
|
|
345
|
+
--wui-tooltip-bg: var(--color-surface);
|
|
346
|
+
--wui-tooltip-color: var(--color-text);
|
|
347
|
+
--wui-tooltip-border: var(--color-border-light);
|
|
348
|
+
--wui-tooltip-radius: var(--radius, 10px);
|
|
349
|
+
--wui-tooltip-shadow: var(--wui-shadow-overlay);
|
|
350
|
+
// Size is these four vars — the `md` default. A size-* class swaps them; a caller can
|
|
351
|
+
// override any one from its own className for a fully custom size.
|
|
352
|
+
--wui-tooltip-max-width: 240px;
|
|
353
|
+
--wui-tooltip-font-size: 0.8125rem;
|
|
354
|
+
--wui-tooltip-padding-y: 7px;
|
|
355
|
+
--wui-tooltip-padding-x: 11px;
|
|
356
|
+
}
|
|
357
|
+
.tooltip.wui-tooltip {
|
|
358
|
+
--bs-tooltip-bg: var(--wui-tooltip-bg);
|
|
359
|
+
--bs-tooltip-color: var(--wui-tooltip-color);
|
|
360
|
+
--bs-tooltip-max-width: var(--wui-tooltip-max-width);
|
|
361
|
+
--bs-tooltip-border-radius: var(--wui-tooltip-radius);
|
|
362
|
+
--bs-tooltip-font-size: var(--wui-tooltip-font-size);
|
|
363
|
+
--bs-tooltip-padding-y: var(--wui-tooltip-padding-y);
|
|
364
|
+
--bs-tooltip-padding-x: var(--wui-tooltip-padding-x);
|
|
365
|
+
--bs-tooltip-opacity: 1;
|
|
366
|
+
}
|
|
367
|
+
.tooltip.wui-tooltip .tooltip-inner {
|
|
368
|
+
// Padding + font-size come from the --bs-tooltip-* vars above (driven by --wui-tooltip-*),
|
|
369
|
+
// so a size-* class or a custom var resizes the tip without touching this rule.
|
|
370
|
+
font-weight: 500;
|
|
371
|
+
line-height: 1.4;
|
|
372
|
+
text-align: left;
|
|
373
|
+
border: 1px solid var(--wui-tooltip-border);
|
|
374
|
+
box-shadow: var(--wui-tooltip-shadow);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Size presets — swap the four size vars. `md` is the :where default (no class).
|
|
378
|
+
.tooltip.wui-tooltip.size-sm {
|
|
379
|
+
--wui-tooltip-max-width: 200px;
|
|
380
|
+
--wui-tooltip-font-size: 0.75rem;
|
|
381
|
+
--wui-tooltip-padding-y: 4px;
|
|
382
|
+
--wui-tooltip-padding-x: 8px;
|
|
383
|
+
}
|
|
384
|
+
.tooltip.wui-tooltip.size-lg {
|
|
385
|
+
--wui-tooltip-max-width: 300px;
|
|
386
|
+
--wui-tooltip-font-size: 0.9375rem;
|
|
387
|
+
--wui-tooltip-padding-y: 10px;
|
|
388
|
+
--wui-tooltip-padding-x: 14px;
|
|
389
|
+
}
|
|
390
|
+
// A hairline shadow so the light default's white arrow still reads on a white page; on a tinted
|
|
391
|
+
// tone the arrow is coloured and this just adds subtle depth.
|
|
392
|
+
.tooltip.wui-tooltip .tooltip-arrow {
|
|
393
|
+
filter: drop-shadow(0 1px 1px color-mix(in srgb, var(--color-text) 14%, transparent));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Tone presets — swap the three colour vars; the arrow follows --bs-tooltip-bg automatically.
|
|
397
|
+
// Fills that carry white text use the AA-cleared -strong tokens; warning stays dark-on-yellow.
|
|
398
|
+
.tooltip.wui-tooltip.tone-dark {
|
|
399
|
+
--wui-tooltip-bg: var(--color-text);
|
|
400
|
+
--wui-tooltip-color: #fff;
|
|
401
|
+
--wui-tooltip-border: transparent;
|
|
402
|
+
}
|
|
403
|
+
.tooltip.wui-tooltip.tone-primary {
|
|
404
|
+
--wui-tooltip-bg: var(--color-primary);
|
|
405
|
+
--wui-tooltip-color: var(--color-primary-text);
|
|
406
|
+
--wui-tooltip-border: transparent;
|
|
407
|
+
}
|
|
408
|
+
.tooltip.wui-tooltip.tone-success {
|
|
409
|
+
--wui-tooltip-bg: var(--wui-success-strong);
|
|
410
|
+
--wui-tooltip-color: #fff;
|
|
411
|
+
--wui-tooltip-border: transparent;
|
|
412
|
+
}
|
|
413
|
+
.tooltip.wui-tooltip.tone-danger {
|
|
414
|
+
--wui-tooltip-bg: var(--wui-danger-strong);
|
|
415
|
+
--wui-tooltip-color: #fff;
|
|
416
|
+
--wui-tooltip-border: transparent;
|
|
417
|
+
}
|
|
418
|
+
.tooltip.wui-tooltip.tone-warning {
|
|
419
|
+
--wui-tooltip-bg: var(--color-warning);
|
|
420
|
+
--wui-tooltip-color: var(--color-text);
|
|
421
|
+
--wui-tooltip-border: transparent;
|
|
422
|
+
}
|
|
423
|
+
|
|
332
424
|
// ── Toast (notifications) ──
|
|
333
|
-
//
|
|
334
|
-
//
|
|
425
|
+
// Surface-card toasts shared by React <AppToast/> and Razor <app-toast>/WUI.toast: an elevated
|
|
426
|
+
// card with a left accent bar + variant icon, an auto-dismiss progress bar (pauses on hover/focus),
|
|
427
|
+
// and swipe-to-dismiss. The variant tint drives one custom prop so every part stays in step.
|
|
335
428
|
|
|
336
|
-
|
|
337
|
-
|
|
429
|
+
.wui-toast-container {
|
|
430
|
+
z-index: var(--wui-z-toast);
|
|
338
431
|
display: flex;
|
|
339
|
-
|
|
340
|
-
|
|
432
|
+
flex-direction: column;
|
|
433
|
+
gap: 10px;
|
|
434
|
+
max-width: min(92vw, 400px);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.wui-toast {
|
|
438
|
+
--wui-toast-accent: var(--color-primary);
|
|
439
|
+
position: relative;
|
|
440
|
+
display: flex;
|
|
441
|
+
align-items: flex-start;
|
|
341
442
|
gap: 12px;
|
|
342
|
-
|
|
343
|
-
|
|
443
|
+
width: 100%;
|
|
444
|
+
padding: 14px 14px 14px 18px;
|
|
445
|
+
background: var(--color-surface);
|
|
446
|
+
color: var(--color-text);
|
|
447
|
+
border: 1px solid var(--color-border-light);
|
|
448
|
+
border-radius: var(--radius-lg, 12px);
|
|
449
|
+
box-shadow: var(--wui-shadow-overlay);
|
|
450
|
+
overflow: hidden;
|
|
451
|
+
touch-action: pan-y;
|
|
452
|
+
user-select: none;
|
|
453
|
+
transition:
|
|
454
|
+
transform 0.2s ease,
|
|
455
|
+
opacity 0.2s ease;
|
|
456
|
+
animation: wui-toast-in 0.24s ease;
|
|
344
457
|
}
|
|
345
458
|
|
|
346
|
-
|
|
347
|
-
|
|
459
|
+
// The left accent bar reads the variant tint.
|
|
460
|
+
.wui-toast::before {
|
|
461
|
+
content: "";
|
|
462
|
+
position: absolute;
|
|
463
|
+
inset: 0 auto 0 0;
|
|
464
|
+
width: 4px;
|
|
465
|
+
background: var(--wui-toast-accent);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// While a swipe is in progress the toast follows the pointer with no transition.
|
|
469
|
+
.wui-toast--dragging {
|
|
470
|
+
transition: none;
|
|
471
|
+
cursor: grabbing;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.wui-toast--success {
|
|
475
|
+
--wui-toast-accent: var(--color-success);
|
|
476
|
+
}
|
|
477
|
+
.wui-toast--info {
|
|
478
|
+
--wui-toast-accent: var(--color-info);
|
|
479
|
+
}
|
|
480
|
+
.wui-toast--warning {
|
|
481
|
+
--wui-toast-accent: var(--color-warning);
|
|
482
|
+
}
|
|
483
|
+
.wui-toast--error,
|
|
484
|
+
.wui-toast--danger {
|
|
485
|
+
--wui-toast-accent: var(--color-danger);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.wui-toast-icon {
|
|
489
|
+
flex: none;
|
|
490
|
+
display: inline-flex;
|
|
491
|
+
margin-top: 1px;
|
|
492
|
+
color: var(--wui-toast-accent);
|
|
493
|
+
line-height: 1;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.wui-toast-content {
|
|
497
|
+
flex: 1 1 auto;
|
|
498
|
+
min-width: 0;
|
|
499
|
+
display: flex;
|
|
500
|
+
flex-direction: column;
|
|
501
|
+
gap: 2px;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.wui-toast-title {
|
|
505
|
+
font-size: 0.9375rem;
|
|
348
506
|
font-weight: 600;
|
|
349
|
-
color:
|
|
507
|
+
color: var(--color-text);
|
|
350
508
|
}
|
|
351
509
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
510
|
+
.wui-toast-message {
|
|
511
|
+
font-size: 0.875rem;
|
|
512
|
+
color: var(--color-text);
|
|
513
|
+
overflow-wrap: anywhere;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// Action button — tinted with the variant accent, scoped to the toast so it never
|
|
517
|
+
// restyles an arbitrary .btn-link a rich body might contain.
|
|
518
|
+
.wui-toast-action {
|
|
519
|
+
flex: none;
|
|
520
|
+
align-self: center;
|
|
521
|
+
color: var(--wui-toast-accent);
|
|
356
522
|
text-decoration: none;
|
|
357
|
-
font-size:
|
|
358
|
-
font-weight:
|
|
523
|
+
font-size: 0.8125rem;
|
|
524
|
+
font-weight: 600;
|
|
359
525
|
padding: 2px 8px;
|
|
360
526
|
white-space: nowrap;
|
|
527
|
+
}
|
|
528
|
+
.wui-toast-action:hover {
|
|
529
|
+
color: var(--wui-toast-accent);
|
|
530
|
+
text-decoration: underline;
|
|
531
|
+
}
|
|
532
|
+
.wui-toast-action:focus-visible {
|
|
533
|
+
outline: 2px solid var(--wui-toast-accent);
|
|
534
|
+
outline-offset: 2px;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.wui-toast-close {
|
|
361
538
|
flex: none;
|
|
362
|
-
|
|
363
|
-
|
|
539
|
+
margin-top: 1px;
|
|
540
|
+
font-size: 0.65rem;
|
|
364
541
|
}
|
|
365
542
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
543
|
+
// A pure-CSS auto-dismiss countdown: the bar shrinks over the toast's duration; the JS side
|
|
544
|
+
// listens for animationend to remove it. Because :hover/:focus-within pause the animation,
|
|
545
|
+
// animationend cannot fire while the toast is being read — a self-synchronising timer.
|
|
546
|
+
.wui-toast-progress {
|
|
547
|
+
position: absolute;
|
|
548
|
+
left: 0;
|
|
549
|
+
bottom: 0;
|
|
550
|
+
height: 3px;
|
|
551
|
+
width: 100%;
|
|
552
|
+
transform-origin: left center;
|
|
553
|
+
background: var(--wui-toast-accent);
|
|
554
|
+
opacity: 0.5;
|
|
555
|
+
animation-name: wui-toast-countdown;
|
|
556
|
+
animation-timing-function: linear;
|
|
557
|
+
animation-fill-mode: forwards;
|
|
558
|
+
}
|
|
559
|
+
.wui-toast:hover .wui-toast-progress,
|
|
560
|
+
.wui-toast:focus-within .wui-toast-progress {
|
|
561
|
+
animation-play-state: paused;
|
|
369
562
|
}
|
|
370
563
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
564
|
+
// "+N more" chip when the stack exceeds maxVisible.
|
|
565
|
+
.wui-toast-more {
|
|
566
|
+
align-self: center;
|
|
567
|
+
font-size: 0.75rem;
|
|
568
|
+
font-weight: 600;
|
|
569
|
+
color: var(--color-text-subtle);
|
|
570
|
+
background: var(--color-surface);
|
|
571
|
+
border: 1px solid var(--color-border-light);
|
|
572
|
+
border-radius: 999px;
|
|
573
|
+
padding: 2px 12px;
|
|
574
|
+
box-shadow: var(--wui-shadow-overlay);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
@keyframes wui-toast-countdown {
|
|
578
|
+
from {
|
|
579
|
+
transform: scaleX(1);
|
|
580
|
+
}
|
|
581
|
+
to {
|
|
582
|
+
transform: scaleX(0);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
@keyframes wui-toast-in {
|
|
587
|
+
from {
|
|
588
|
+
opacity: 0;
|
|
589
|
+
transform: translateY(8px);
|
|
590
|
+
}
|
|
591
|
+
to {
|
|
592
|
+
opacity: 1;
|
|
593
|
+
transform: translateY(0);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
@media (prefers-reduced-motion: reduce) {
|
|
598
|
+
// Drop the entrance slide; the countdown bar stays — it is the auto-dismiss timer, not decoration.
|
|
599
|
+
.wui-toast {
|
|
600
|
+
animation: none;
|
|
601
|
+
transition: none;
|
|
602
|
+
}
|
|
374
603
|
}
|
package/scss/wui/_shell.scss
CHANGED
|
@@ -263,13 +263,25 @@
|
|
|
263
263
|
height: 0;
|
|
264
264
|
}
|
|
265
265
|
// Between the brand row and the nav — a workspace/tenant switcher, an environment
|
|
266
|
-
// badge. It must not shrink when the nav overflows
|
|
267
|
-
// 88px rail, so the collapsed state
|
|
266
|
+
// badge. It must not shrink when the nav overflows. The full card has no place on
|
|
267
|
+
// the 88px rail, so the collapsed state hides it (the mobile drawer restores it).
|
|
268
|
+
// The compact twin (`sidebarStartCompact` / `<app-shell-sidebar-start-compact>`) is
|
|
269
|
+
// the inverse: hidden expanded, shown only on the desktop collapsed rail, sized for
|
|
270
|
+
// a 36px monogram control (AppWorkspaceSwitcher compact).
|
|
268
271
|
.app-sidebar-start {
|
|
269
272
|
flex: none;
|
|
270
273
|
margin-bottom: 8px;
|
|
271
274
|
overflow: hidden;
|
|
272
275
|
}
|
|
276
|
+
.app-sidebar-start-compact {
|
|
277
|
+
display: none;
|
|
278
|
+
flex: none;
|
|
279
|
+
margin-bottom: 8px;
|
|
280
|
+
// Centre the fixed square in the 88px rail so it lines up with the icon column.
|
|
281
|
+
justify-content: center;
|
|
282
|
+
align-items: center;
|
|
283
|
+
overflow: hidden;
|
|
284
|
+
}
|
|
273
285
|
.app-sidebar-foot {
|
|
274
286
|
flex: none;
|
|
275
287
|
padding-top: 12px;
|
|
@@ -374,13 +386,31 @@
|
|
|
374
386
|
gap: 0;
|
|
375
387
|
padding: 9px 0;
|
|
376
388
|
}
|
|
377
|
-
.app-shell.collapsed .app-nav-text,
|
|
378
389
|
.app-shell.collapsed .app-nav-badge,
|
|
379
390
|
.app-shell.collapsed .app-nav-group-label,
|
|
380
391
|
.app-shell.collapsed .app-sidebar-brand-text,
|
|
381
392
|
.app-shell.collapsed .app-sidebar-start {
|
|
382
393
|
display: none;
|
|
383
394
|
}
|
|
395
|
+
// The label leaves the VISUAL flow but must stay in the accessibility tree — an
|
|
396
|
+
// icon-only rail link with display:none text has no accessible name (axe
|
|
397
|
+
// link-name, serious). Clip-rect keeps the name; no phantom gap since it takes
|
|
398
|
+
// no space.
|
|
399
|
+
.app-shell.collapsed .app-nav-text {
|
|
400
|
+
position: absolute;
|
|
401
|
+
width: 1px;
|
|
402
|
+
height: 1px;
|
|
403
|
+
margin: -1px;
|
|
404
|
+
padding: 0;
|
|
405
|
+
overflow: hidden;
|
|
406
|
+
clip-path: inset(50%);
|
|
407
|
+
white-space: nowrap;
|
|
408
|
+
border: 0;
|
|
409
|
+
}
|
|
410
|
+
// Swap: expanded slot off, compact monogram on — only when the author filled the compact slot.
|
|
411
|
+
.app-shell.collapsed .app-sidebar-start-compact {
|
|
412
|
+
display: flex;
|
|
413
|
+
}
|
|
384
414
|
|
|
385
415
|
// ── Badge tones ──────────────────────────────────────────────────────────────
|
|
386
416
|
// A nav badge can carry a status tone so an alert count reads red, not neutral.
|
|
@@ -651,6 +681,10 @@
|
|
|
651
681
|
.app-shell.app-shell.collapsed .app-sidebar-start {
|
|
652
682
|
display: revert;
|
|
653
683
|
}
|
|
684
|
+
// Drawer always shows full labels — the compact rail control has no role here.
|
|
685
|
+
.app-shell.app-shell.collapsed .app-sidebar-start-compact {
|
|
686
|
+
display: none;
|
|
687
|
+
}
|
|
654
688
|
.app-shell.app-shell .app-sidebar-toggle {
|
|
655
689
|
display: none;
|
|
656
690
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// ── Shared tone-pill color mixin ──
|
|
2
|
+
// Consolidates the tone→color mapping used by .badge, .status-label, and .chip:
|
|
3
|
+
// background: var(--color-{tone}-soft)
|
|
4
|
+
// color: var(--color-{tone}-text) (override via $text — see below)
|
|
5
|
+
// border-color: transparent
|
|
6
|
+
//
|
|
7
|
+
// $text exists because the status tones and `primary` name their on-tint color
|
|
8
|
+
// differently: --color-{status}-text IS the on-tint hue, but --color-primary-text
|
|
9
|
+
// is the text-on-SOLID-primary color (near-black in dark mode) and fails AA on the
|
|
10
|
+
// soft tint — primary pills pass var(--color-primary) instead.
|
|
11
|
+
//
|
|
12
|
+
// Component-specific overrides (e.g. .badge-primary's colored border) are applied
|
|
13
|
+
// after the mixin call.
|
|
14
|
+
|
|
15
|
+
@mixin wui-tone-pill-colors($tone, $text: null) {
|
|
16
|
+
background: var(--color-#{$tone}-soft);
|
|
17
|
+
@if $text {
|
|
18
|
+
color: $text;
|
|
19
|
+
} @else {
|
|
20
|
+
color: var(--color-#{$tone}-text);
|
|
21
|
+
}
|
|
22
|
+
border-color: transparent;
|
|
23
|
+
}
|
|
@@ -121,29 +121,19 @@
|
|
|
121
121
|
|
|
122
122
|
/* Tones — tinted surface + on-tint text; icon/remove inherit the tone colour. */
|
|
123
123
|
.chip.primary {
|
|
124
|
-
|
|
125
|
-
background: var(--color-primary-soft);
|
|
126
|
-
color: var(--color-primary);
|
|
124
|
+
@include wui-tone-pill-colors(primary, var(--color-primary));
|
|
127
125
|
}
|
|
128
126
|
.chip.success {
|
|
129
|
-
|
|
130
|
-
background: var(--color-success-soft);
|
|
131
|
-
color: var(--color-success-text);
|
|
127
|
+
@include wui-tone-pill-colors(success);
|
|
132
128
|
}
|
|
133
129
|
.chip.warning {
|
|
134
|
-
|
|
135
|
-
background: var(--color-warning-soft);
|
|
136
|
-
color: var(--color-warning-text);
|
|
130
|
+
@include wui-tone-pill-colors(warning);
|
|
137
131
|
}
|
|
138
132
|
.chip.danger {
|
|
139
|
-
|
|
140
|
-
background: var(--color-danger-soft);
|
|
141
|
-
color: var(--color-danger-text);
|
|
133
|
+
@include wui-tone-pill-colors(danger);
|
|
142
134
|
}
|
|
143
135
|
.chip.info {
|
|
144
|
-
|
|
145
|
-
background: var(--color-info-soft);
|
|
146
|
-
color: var(--color-info-text);
|
|
136
|
+
@include wui-tone-pill-colors(info);
|
|
147
137
|
}
|
|
148
138
|
.chip.primary .chip-ic,
|
|
149
139
|
.chip.success .chip-ic,
|
|
@@ -238,6 +228,25 @@
|
|
|
238
228
|
min-width: 0;
|
|
239
229
|
align-items: center;
|
|
240
230
|
}
|
|
231
|
+
// Chips scale with the control size — the taller the field, the larger its tokens
|
|
232
|
+
// (the element always emits `.chip.chip-sm`; these override it per size tier). The
|
|
233
|
+
// two-class `.ms-chips .chip` outranks the single `.chip-sm`, so md is the base and
|
|
234
|
+
// the sm/lg tiers layer over it.
|
|
235
|
+
.ms-chips .chip {
|
|
236
|
+
gap: 5px;
|
|
237
|
+
padding: 3px 9px;
|
|
238
|
+
font-size: 0.8125rem;
|
|
239
|
+
}
|
|
240
|
+
.search-select-sm .ms-chips .chip {
|
|
241
|
+
gap: 4px;
|
|
242
|
+
padding: 2px 8px;
|
|
243
|
+
font-size: 0.75rem;
|
|
244
|
+
}
|
|
245
|
+
.search-select-lg .ms-chips .chip {
|
|
246
|
+
gap: 6px;
|
|
247
|
+
padding: 5px 12px;
|
|
248
|
+
font-size: 0.875rem;
|
|
249
|
+
}
|
|
241
250
|
// Collapse mode (collapse-chips): chips stay on one row; the JS folds the overflow into
|
|
242
251
|
// a "+N" counter (see WuiMultiSelect._collapseChips).
|
|
243
252
|
wui-multiselect[collapse-chips] .ms-chips {
|
|
@@ -295,6 +304,27 @@ wui-multiselect[collapse-chips] .ms-chips {
|
|
|
295
304
|
.ms-input:focus {
|
|
296
305
|
outline: none;
|
|
297
306
|
}
|
|
307
|
+
// AppTagInput lays the input on the LEFT with the chips filling and wrapping to its
|
|
308
|
+
// right (its template renders the input before the chips). Multiselect keeps its
|
|
309
|
+
// chips-first layout, so these overrides are scoped to `wui-taginput`.
|
|
310
|
+
wui-taginput .ms-input {
|
|
311
|
+
// Don't grow to fill — hold a modest resting width on the left; the chips take
|
|
312
|
+
// everything to the right. (align-items:center on the control centres the input
|
|
313
|
+
// against the chip row, so it needs no min-height of its own.)
|
|
314
|
+
flex: 0 1 auto;
|
|
315
|
+
flex-basis: 120px;
|
|
316
|
+
min-width: 96px;
|
|
317
|
+
}
|
|
318
|
+
wui-taginput .ms-chips {
|
|
319
|
+
flex: 1 1 auto;
|
|
320
|
+
}
|
|
321
|
+
// Match AppInput's per-size heights: the shared `.search-select-multi` floors md at
|
|
322
|
+
// 40px, but AppInput's md is the 44px control-height token — raise the floor so the
|
|
323
|
+
// sm/md/lg progression lines up with a text field beside it. (sm 36 / lg 52 already
|
|
324
|
+
// come from the size-specific `.search-select-{sm,lg} .search-select-control` rules.)
|
|
325
|
+
wui-taginput .search-select-multi {
|
|
326
|
+
min-height: var(--wui-control-height);
|
|
327
|
+
}
|
|
298
328
|
|
|
299
329
|
/* ── Choice card: image / custom-template variant ── */
|
|
300
330
|
.struct-card-img-card {
|
package/scss/wui/_utilities.scss
CHANGED
|
@@ -73,7 +73,6 @@
|
|
|
73
73
|
background: transparent;
|
|
74
74
|
color: var(--color-text-subtle);
|
|
75
75
|
cursor: help;
|
|
76
|
-
transform: scaleY(-1);
|
|
77
76
|
transition: color 0.15s;
|
|
78
77
|
}
|
|
79
78
|
.infotip-btn:hover {
|
|
@@ -598,6 +597,35 @@
|
|
|
598
597
|
color: var(--color-primary);
|
|
599
598
|
}
|
|
600
599
|
|
|
600
|
+
// AppAlert extras — a leading icon and/or a bold heading line. Bootstrap already
|
|
601
|
+
// styles `.alert`/`.alert-{variant}`; these rules only lay out the icon column and
|
|
602
|
+
// give the plain `.alert-heading` div its type treatment (Bootstrap's own rule is
|
|
603
|
+
// just `color: inherit`, meant for an <h4>).
|
|
604
|
+
.alert-has-icon {
|
|
605
|
+
display: flex;
|
|
606
|
+
align-items: flex-start;
|
|
607
|
+
gap: 12px;
|
|
608
|
+
}
|
|
609
|
+
.alert-icon {
|
|
610
|
+
flex: none;
|
|
611
|
+
display: inline-flex;
|
|
612
|
+
// Nudge onto the first line's optical centre.
|
|
613
|
+
margin-top: 1px;
|
|
614
|
+
}
|
|
615
|
+
.alert-content {
|
|
616
|
+
flex: 1;
|
|
617
|
+
min-width: 0;
|
|
618
|
+
}
|
|
619
|
+
.alert .alert-heading {
|
|
620
|
+
margin-bottom: 2px;
|
|
621
|
+
font-size: 1rem;
|
|
622
|
+
font-weight: 700;
|
|
623
|
+
}
|
|
624
|
+
// The body's trailing paragraph shouldn't add space below the alert.
|
|
625
|
+
.alert .alert-content > :last-child {
|
|
626
|
+
margin-bottom: 0;
|
|
627
|
+
}
|
|
628
|
+
|
|
601
629
|
// ============================================================================
|
|
602
630
|
// Inline help glyph — a hint attached to a word rather than to a field label.
|
|
603
631
|
// (For a field label use `.infotip`, which is a real popover button.)
|