@webority/theme 0.13.4 → 0.14.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 +48 -4
- package/dist/purge-safelist.json +805 -0
- package/dist/webority-flags.css +1 -0
- package/dist/webority-theme.css +1 -1
- package/index.scss +3 -3
- package/package.json +4 -2
- package/scss/_components.scss +6 -6
- package/scss/_tokens.scss +6 -0
- package/scss/_wui-aliases.scss +36 -0
- package/scss/_wui-components.scss +4 -14
- package/scss/wui/_choice.scss +106 -27
- package/scss/wui/_controls.scss +26 -6
- package/scss/wui/_display.scss +24 -15
- package/scss/wui/_flow.scss +10 -3
- package/scss/wui/_media.scss +6 -4
- package/scss/wui/_overlays.scss +13 -8
- package/scss/wui/_utilities.scss +213 -206
- package/scss/wui/_workspace.scss +1 -1
package/scss/wui/_media.scss
CHANGED
|
@@ -552,7 +552,7 @@
|
|
|
552
552
|
}
|
|
553
553
|
.file-input:focus-within {
|
|
554
554
|
background: var(--color-surface);
|
|
555
|
-
border-color: var(--
|
|
555
|
+
border-color: var(--color-focus-border);
|
|
556
556
|
box-shadow: none;
|
|
557
557
|
}
|
|
558
558
|
.file-input-btn {
|
|
@@ -614,7 +614,7 @@
|
|
|
614
614
|
.file-input.file-input-tall:focus-within,
|
|
615
615
|
.file-input.file-input-tall:active,
|
|
616
616
|
.file-input.file-input-tall.dragging {
|
|
617
|
-
border-color: var(--
|
|
617
|
+
border-color: var(--color-focus-border);
|
|
618
618
|
background: var(--color-surface);
|
|
619
619
|
box-shadow: none;
|
|
620
620
|
}
|
|
@@ -664,7 +664,7 @@
|
|
|
664
664
|
background: var(--color-bg-muted);
|
|
665
665
|
}
|
|
666
666
|
.file-input.file-input-tall.has-files.dragging {
|
|
667
|
-
border-color: var(--
|
|
667
|
+
border-color: var(--color-focus-border);
|
|
668
668
|
background: var(--color-surface);
|
|
669
669
|
}
|
|
670
670
|
// Width presets — put a .file-w-* class on the field (React className / Razor class) to cap the
|
|
@@ -820,7 +820,9 @@
|
|
|
820
820
|
gap: 8px;
|
|
821
821
|
padding: 9px 18px;
|
|
822
822
|
background: rgba(255, 255, 255, 0.96);
|
|
823
|
-
|
|
823
|
+
// The pill stays white in every theme, so its ink is fixed too: --color-text flips light in
|
|
824
|
+
// dark mode and would vanish on the white pill.
|
|
825
|
+
color: var(--wui-text-heading);
|
|
824
826
|
font-size: 14px;
|
|
825
827
|
font-weight: 600;
|
|
826
828
|
border-radius: 999px;
|
package/scss/wui/_overlays.scss
CHANGED
|
@@ -316,18 +316,23 @@
|
|
|
316
316
|
// keeps a non-square source whole rather than cropping it.
|
|
317
317
|
.wui-confirm-icon img {
|
|
318
318
|
display: block;
|
|
319
|
-
width: 80px;
|
|
320
|
-
height: 80px;
|
|
319
|
+
width: var(--wui-confirm-icon-size, 80px);
|
|
320
|
+
height: var(--wui-confirm-icon-size, 80px);
|
|
321
321
|
object-fit: contain;
|
|
322
322
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
323
|
+
.wui-confirm-icon svg {
|
|
324
|
+
width: var(--wui-confirm-icon-size, 80px);
|
|
325
|
+
height: var(--wui-confirm-icon-size, 80px);
|
|
326
|
+
}
|
|
327
|
+
// Icon size tracks the copy: a title+message dialog keeps the full 80px badge, but a lone
|
|
328
|
+
// title (no message) is one line and gets a smaller badge. `.wui-confirm-msg` is a real
|
|
329
|
+
// element rendered only when a message exists, so `:has()` is reliable here; CSS width/height
|
|
330
|
+
// override the SVG's own width/height attributes. An explicit iconSize / icon-size sets
|
|
331
|
+
// --wui-confirm-icon-size on the badge and wins in both cases.
|
|
327
332
|
.wui-confirm-content:not(:has(.wui-confirm-msg)) .wui-confirm-icon svg,
|
|
328
333
|
.wui-confirm-content:not(:has(.wui-confirm-msg)) .wui-confirm-icon img {
|
|
329
|
-
width: 56px;
|
|
330
|
-
height: 56px;
|
|
334
|
+
width: var(--wui-confirm-icon-size, 56px);
|
|
335
|
+
height: var(--wui-confirm-icon-size, 56px);
|
|
331
336
|
}
|
|
332
337
|
.wui-confirm-title {
|
|
333
338
|
margin: 0 0 10px;
|
package/scss/wui/_utilities.scss
CHANGED
|
@@ -432,15 +432,43 @@
|
|
|
432
432
|
// custom class both put on Bootstrap's `.popover` panel.
|
|
433
433
|
// The card surface — header and body alike — is pure white, lifted off the page with the shared
|
|
434
434
|
// overlay shadow (the one ink menus/popovers/modals use; not a hand-rolled per-component shadow).
|
|
435
|
-
|
|
435
|
+
// The field help popover (AppInfoTip, `.infotip-popover`) shares the same card, so the two
|
|
436
|
+
// help surfaces a form shows read as one family.
|
|
437
|
+
.pw-popover,
|
|
438
|
+
.infotip-popover {
|
|
436
439
|
--bs-popover-bg: var(--wui-bg-light);
|
|
437
440
|
--bs-popover-header-bg: var(--wui-bg-light);
|
|
441
|
+
// A 14px heading: one step above the 13px body, so the card reads as help, not a dialog.
|
|
442
|
+
--bs-popover-header-font-size: 14px;
|
|
438
443
|
box-shadow: var(--wui-shadow-overlay);
|
|
439
444
|
}
|
|
440
|
-
.pw-popover .popover-body
|
|
445
|
+
.pw-popover .popover-body,
|
|
446
|
+
.infotip-popover .popover-body {
|
|
441
447
|
padding: 14px 16px;
|
|
448
|
+
}
|
|
449
|
+
.pw-popover .popover-body {
|
|
442
450
|
min-width: 232px;
|
|
443
451
|
}
|
|
452
|
+
// AppInfoTip `width`: how wide the help card may grow before its text wraps. md is Bootstrap's
|
|
453
|
+
// own 276px, so leaving the prop out changes nothing. It sets the MAX width, so a short tip stays
|
|
454
|
+
// as narrow as its text.
|
|
455
|
+
.infotip-popover-sm {
|
|
456
|
+
--bs-popover-max-width: 220px;
|
|
457
|
+
}
|
|
458
|
+
.infotip-popover-lg {
|
|
459
|
+
--bs-popover-max-width: 360px;
|
|
460
|
+
}
|
|
461
|
+
.infotip-popover-xl {
|
|
462
|
+
--bs-popover-max-width: 480px;
|
|
463
|
+
}
|
|
464
|
+
// Help prose takes the checklist's type: 13px medium in the subtle ink. It keeps a little more
|
|
465
|
+
// leading than a one-line rule because it wraps into a paragraph.
|
|
466
|
+
.infotip-popover .popover-body {
|
|
467
|
+
font-size: 13px;
|
|
468
|
+
line-height: 1.5;
|
|
469
|
+
font-weight: 500;
|
|
470
|
+
color: var(--color-text-subtle);
|
|
471
|
+
}
|
|
444
472
|
.pw-criteria {
|
|
445
473
|
list-style: none;
|
|
446
474
|
margin: 0;
|
|
@@ -482,17 +510,20 @@
|
|
|
482
510
|
color: var(--color-text-subtle);
|
|
483
511
|
--pw-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.8'%3E%3Ccircle cx='12' cy='12' r='8.25'/%3E%3C/svg%3E");
|
|
484
512
|
}
|
|
485
|
-
// Met: success
|
|
513
|
+
// Met: the bright success fill — a filled circle with a knocked-out check. The rule text takes the
|
|
514
|
+
// same fill rather than --color-success-text, a deliberate choice for the brighter look; it sits
|
|
515
|
+
// under AA text contrast on a white card.
|
|
486
516
|
.pw-criteria .pw-rule.met {
|
|
487
|
-
color: var(--
|
|
517
|
+
color: var(--wui-success-active);
|
|
488
518
|
--pw-mark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' fill-rule='evenodd' d='M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm4.03-11.28a.9.9 0 0 0-1.32-1.22l-4.02 4.35-1.4-1.5a.9.9 0 1 0-1.32 1.22l2.06 2.22a.9.9 0 0 0 1.32 0l4.68-5.07Z' clip-rule='evenodd'/%3E%3C/svg%3E");
|
|
489
519
|
}
|
|
490
|
-
// The checklist
|
|
520
|
+
// The checklist and the field help tip open with a PLAIN FADE only — no drop / zoom / scale. It opts out of the shared
|
|
491
521
|
// menu-open motion (_menu-motion.scss animates every `.popover.show`) and lets Bootstrap's own
|
|
492
522
|
// `.fade` opacity transition carry the fade in and out. Both surfaces render `.popover.pw-popover`
|
|
493
523
|
// (React via react-bootstrap's Popover, Razor via Bootstrap's popover), so this makes the two
|
|
494
524
|
// identical. Higher specificity than `.popover.show` so it wins regardless of partial load order.
|
|
495
|
-
.popover.pw-popover.show
|
|
525
|
+
.popover.pw-popover.show,
|
|
526
|
+
.popover.infotip-popover.show {
|
|
496
527
|
animation: none;
|
|
497
528
|
scale: none;
|
|
498
529
|
translate: none;
|
|
@@ -560,6 +591,16 @@
|
|
|
560
591
|
border-bottom: 1px solid var(--color-border);
|
|
561
592
|
}
|
|
562
593
|
|
|
594
|
+
// The track. Bootstrap's default is --bs-secondary-bg, which is near-white on a white card in
|
|
595
|
+
// light mode and the card surface itself in dark mode, so the empty part of the bar disappeared
|
|
596
|
+
// in both. Set on .progress because Bootstrap declares --bs-progress-bg there, not on :root.
|
|
597
|
+
.progress {
|
|
598
|
+
--bs-progress-bg: var(--color-progress-track);
|
|
599
|
+
// The showLabel text inside the bar: white on the light-mode fills, a dark ink on the bright
|
|
600
|
+
// dark-mode fills (white reaches only 2.3:1 to 3.9:1 on those).
|
|
601
|
+
--bs-progress-bar-color: var(--color-progress-label);
|
|
602
|
+
}
|
|
603
|
+
|
|
563
604
|
// Determinate progress-bar fill tones (AppProgress / AppMeter / <app-progress>) — the fill sits
|
|
564
605
|
// in Bootstrap's .progress track; only the bar colour is brand-toned.
|
|
565
606
|
//
|
|
@@ -568,17 +609,21 @@
|
|
|
568
609
|
// --wui-danger (#F8285A) fails AA (2.78:1 / 3.86:1). The -strong fills clear it (both ~5.8:1),
|
|
569
610
|
// the same trick btn-danger uses. info/warning/neutral stay on their mid tones (info/neutral
|
|
570
611
|
// pass with white; warning is not shown with a white label).
|
|
612
|
+
//
|
|
613
|
+
// They read the --color-*-strong aliases, not --wui-*-strong, because dark mode remaps the
|
|
614
|
+
// aliases to the bright fills: the deep fills sink into the dark track (about 2:1). The label
|
|
615
|
+
// flips to a dark ink there (--color-progress-label), which clears AA on all five dark fills.
|
|
571
616
|
.wui-progress-info {
|
|
572
617
|
background-color: var(--color-info);
|
|
573
618
|
}
|
|
574
619
|
.wui-progress-success {
|
|
575
|
-
background-color: var(--
|
|
620
|
+
background-color: var(--color-success-strong);
|
|
576
621
|
}
|
|
577
622
|
.wui-progress-warning {
|
|
578
623
|
background-color: var(--color-warning);
|
|
579
624
|
}
|
|
580
625
|
.wui-progress-danger {
|
|
581
|
-
background-color: var(--
|
|
626
|
+
background-color: var(--color-danger-strong);
|
|
582
627
|
}
|
|
583
628
|
.wui-progress-neutral {
|
|
584
629
|
background-color: var(--color-text-subtle);
|
|
@@ -668,187 +713,10 @@
|
|
|
668
713
|
}
|
|
669
714
|
}
|
|
670
715
|
|
|
671
|
-
//
|
|
672
|
-
//
|
|
673
|
-
//
|
|
674
|
-
//
|
|
675
|
-
// edge, the icon badge fill, the heading colour, and the compact body text.
|
|
676
|
-
.info-callout {
|
|
677
|
-
--callout-accent: var(--color-info-active);
|
|
678
|
-
// AA-safe text colour for the heading / compact body / <strong> (the vivid --callout-accent
|
|
679
|
-
// is fine for the badge fill, left edge and halo, but fails AA as text on the soft bg).
|
|
680
|
-
--callout-text: var(--color-info-text);
|
|
681
|
-
--callout-border: var(--color-info-30);
|
|
682
|
-
--callout-bg: var(--color-info-10);
|
|
683
|
-
|
|
684
|
-
display: flex;
|
|
685
|
-
align-items: center;
|
|
686
|
-
// On phones the trailing action drops onto its own row BELOW the content (the flex `gap`
|
|
687
|
-
// supplies the vertical space) so a button never crushes the message into a sliver; from md
|
|
688
|
-
// up it sits inline at the right — a VIEWPORT rule, not the callout's own width. See the
|
|
689
|
-
// `.info-callout-action` breakpoint below.
|
|
690
|
-
flex-wrap: wrap;
|
|
691
|
-
gap: 12px;
|
|
692
|
-
padding: 14px 18px;
|
|
693
|
-
border: 1px solid var(--callout-border);
|
|
694
|
-
// A thick coloured left edge — the callout's signature aside marker.
|
|
695
|
-
border-left: 4px solid var(--callout-accent);
|
|
696
|
-
border-radius: 8px;
|
|
697
|
-
background: var(--callout-bg);
|
|
698
|
-
font-size: 14px;
|
|
699
|
-
// Sub-content (the body/subtitle) reads at #252F4A / 400; the heading and the
|
|
700
|
-
// compact-size text override colour + weight below.
|
|
701
|
-
font-weight: 400;
|
|
702
|
-
line-height: 1.5;
|
|
703
|
-
color: var(--wui-text-1);
|
|
704
|
-
}
|
|
705
|
-
.info-callout.tone-success {
|
|
706
|
-
--callout-accent: var(--color-success-active);
|
|
707
|
-
--callout-text: var(--color-success-text);
|
|
708
|
-
--callout-border: var(--color-success-30);
|
|
709
|
-
--callout-bg: var(--color-success-10);
|
|
710
|
-
}
|
|
711
|
-
.info-callout.tone-warning {
|
|
712
|
-
--callout-accent: var(--color-warning-active);
|
|
713
|
-
--callout-text: var(--color-warning-text);
|
|
714
|
-
--callout-border: var(--color-warning-30);
|
|
715
|
-
--callout-bg: var(--color-warning-10);
|
|
716
|
-
}
|
|
717
|
-
.info-callout.tone-danger {
|
|
718
|
-
--callout-accent: var(--color-danger-active);
|
|
719
|
-
--callout-text: var(--color-danger-text);
|
|
720
|
-
--callout-border: var(--color-danger-30);
|
|
721
|
-
--callout-bg: var(--color-danger-10);
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
// Borderless variant (`bordered={false}` / `bordered="false"`): drop the soft ring AND
|
|
725
|
-
// the thick tone-coloured left edge, keeping only the tint fill. Colours go `transparent`
|
|
726
|
-
// rather than the widths to 0 so the box keeps its 1px / 4px-left footprint — nothing
|
|
727
|
-
// shifts when toggling the border on and off. Mirrors `.alert-borderless`.
|
|
728
|
-
.info-callout-borderless {
|
|
729
|
-
border-color: transparent;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
// The leading glyph is a solid circular badge — tone fill, white glyph centred, with a
|
|
733
|
-
// soft 3px same-colour halo ring. Base is the single-content size (20px badge / 20px
|
|
734
|
-
// glyph); a title+body stack steps it up to 24px. The badge stays VERTICALLY CENTRED
|
|
735
|
-
// against the whole block in both cases (align-items: center on .info-callout).
|
|
736
|
-
.info-callout-icon {
|
|
737
|
-
flex: none;
|
|
738
|
-
display: inline-flex;
|
|
739
|
-
align-items: center;
|
|
740
|
-
justify-content: center;
|
|
741
|
-
width: 20px;
|
|
742
|
-
height: 20px;
|
|
743
|
-
border-radius: 50%;
|
|
744
|
-
background: var(--callout-accent);
|
|
745
|
-
color: #fff;
|
|
746
|
-
// 4px translucent ring in the badge's own colour — the "outer shadow".
|
|
747
|
-
box-shadow: 0 0 0 4px color-mix(in srgb, var(--callout-accent) 20%, transparent);
|
|
748
|
-
|
|
749
|
-
.wui-icon {
|
|
750
|
-
line-height: 1;
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
// A title+body stack gets the larger badge (24px / 22px glyph).
|
|
754
|
-
.info-callout-stack .info-callout-icon {
|
|
755
|
-
width: 24px;
|
|
756
|
-
height: 24px;
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
// Custom image in the badge (icon replacement): the image fills the circle, so drop the
|
|
760
|
-
// tone fill and clip it round. Applies to both AppCallout and AppAlert badges.
|
|
761
|
-
.info-callout-icon-image,
|
|
762
|
-
.alert-icon-image {
|
|
763
|
-
background: transparent;
|
|
764
|
-
overflow: hidden;
|
|
765
|
-
}
|
|
766
|
-
.info-callout-icon img,
|
|
767
|
-
.alert-icon img {
|
|
768
|
-
width: 100%;
|
|
769
|
-
height: 100%;
|
|
770
|
-
object-fit: cover;
|
|
771
|
-
border-radius: 50%;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
.info-callout-content {
|
|
775
|
-
// Grows to fill the row so a trailing action (and the dismiss ×) sit at the right edge.
|
|
776
|
-
flex: 1 1 auto;
|
|
777
|
-
min-width: 0;
|
|
778
|
-
font-size: 12px;
|
|
779
|
-
}
|
|
780
|
-
// Trailing action slot — a button (or any node). Mobile-first: on phones it takes its own full
|
|
781
|
-
// row below the content (left-aligned there); from md up it collapses to its natural width and
|
|
782
|
-
// sits inline at the right edge of the content row.
|
|
783
|
-
.info-callout-action {
|
|
784
|
-
flex: 1 1 100%;
|
|
785
|
-
align-self: center;
|
|
786
|
-
display: flex;
|
|
787
|
-
justify-content: flex-start;
|
|
788
|
-
align-items: center;
|
|
789
|
-
gap: 8px;
|
|
790
|
-
}
|
|
791
|
-
// From md up the row never wraps — the content shrinks to seat the action inline at the right,
|
|
792
|
-
// so a button stays beside the text on any large screen, even when the callout sits in a narrow
|
|
793
|
-
// column (the wrap-below is a phones-only treatment).
|
|
794
|
-
@include media-breakpoint-up(md) {
|
|
795
|
-
.info-callout {
|
|
796
|
-
flex-wrap: nowrap;
|
|
797
|
-
}
|
|
798
|
-
.info-callout-action {
|
|
799
|
-
flex: none;
|
|
800
|
-
justify-content: initial;
|
|
801
|
-
margin-left: auto;
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
.info-callout-heading {
|
|
805
|
-
font-size: 14px;
|
|
806
|
-
font-weight: 600;
|
|
807
|
-
line-height: 1.3;
|
|
808
|
-
margin-bottom: 1px;
|
|
809
|
-
color: var(--callout-text);
|
|
810
|
-
}
|
|
811
|
-
.info-callout strong {
|
|
812
|
-
font-weight: 700;
|
|
813
|
-
color: var(--callout-text);
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
// Optional dismiss × — pushed to the right edge, vertically centred, subtle.
|
|
817
|
-
.info-callout-close {
|
|
818
|
-
flex: none;
|
|
819
|
-
align-self: center;
|
|
820
|
-
margin-left: auto;
|
|
821
|
-
display: inline-flex;
|
|
822
|
-
align-items: center;
|
|
823
|
-
justify-content: center;
|
|
824
|
-
padding: 4px;
|
|
825
|
-
border: none;
|
|
826
|
-
background: transparent;
|
|
827
|
-
color: var(--color-text-muted);
|
|
828
|
-
cursor: pointer;
|
|
829
|
-
opacity: 0.7;
|
|
830
|
-
border-radius: var(--radius-sm);
|
|
831
|
-
transition: opacity 0.15s;
|
|
832
|
-
}
|
|
833
|
-
.info-callout-close:hover {
|
|
834
|
-
opacity: 1;
|
|
835
|
-
}
|
|
836
|
-
.info-callout-close:focus-visible {
|
|
837
|
-
outline: 2px solid currentColor;
|
|
838
|
-
outline-offset: 2px;
|
|
839
|
-
}
|
|
840
|
-
|
|
841
|
-
// Compact size — a single tinted line: tighter padding and the body text itself carries
|
|
842
|
-
// the tone colour. The badge stays the single-content 20px base.
|
|
843
|
-
.info-callout-sm {
|
|
844
|
-
padding: 9px 14px;
|
|
845
|
-
gap: 10px;
|
|
846
|
-
font-weight: 600;
|
|
847
|
-
color: var(--callout-text);
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
// AppAlert — a soft tinted status banner with a filled circular icon badge and a
|
|
851
|
-
// coloured heading line. Bootstrap styles the base `.alert`; these rules set the
|
|
716
|
+
// AppAlert — a soft tinted banner with a filled circular icon badge and a
|
|
717
|
+
// coloured heading line. It reports a state (role="alert"/"status") or, with
|
|
718
|
+
// role="none", explains part of the page; `accent`, `size="sm"` and `action` give it the
|
|
719
|
+
// thick left edge, the compact line and the trailing button for that second job. Bootstrap styles the base `.alert`; these rules set the
|
|
852
720
|
// per-variant surface (soft-tint background, soft border, dark body text), lay out
|
|
853
721
|
// the icon column, turn the leading glyph into a solid circular badge, and colour
|
|
854
722
|
// the heading to the variant. Only the heading takes the variant colour — the body
|
|
@@ -860,30 +728,41 @@
|
|
|
860
728
|
border-width: 1px;
|
|
861
729
|
}
|
|
862
730
|
|
|
863
|
-
// Per-variant surface: soft tint fill +
|
|
731
|
+
// Per-variant surface: soft tint fill + a -50 border (deep enough to read beside the accent
|
|
732
|
+
// edge); body text stays ink. Every colour comes from a --color-* token that the dark theme
|
|
733
|
+
// remaps (_wui-aliases.scss), so the alert flips with the page in every dark path, the manual
|
|
734
|
+
// data-theme attribute and the auto media query alike, with no per-component dark rules.
|
|
864
735
|
.alert-info {
|
|
865
|
-
--bs-alert-bg: var(--
|
|
866
|
-
--bs-alert-border-color: var(--
|
|
867
|
-
--bs-alert-color: var(--
|
|
736
|
+
--bs-alert-bg: var(--color-info-soft);
|
|
737
|
+
--bs-alert-border-color: var(--color-info-50);
|
|
738
|
+
--bs-alert-color: var(--color-text-body);
|
|
868
739
|
--alert-accent: var(--wui-info-active);
|
|
740
|
+
// AA-safe text colour for the heading and an accented <strong>.
|
|
741
|
+
--alert-text: var(--color-info-text-on-soft);
|
|
869
742
|
}
|
|
870
743
|
.alert-success {
|
|
871
|
-
--bs-alert-bg: var(--
|
|
872
|
-
--bs-alert-border-color: var(--
|
|
873
|
-
--bs-alert-color: var(--
|
|
744
|
+
--bs-alert-bg: var(--color-success-soft);
|
|
745
|
+
--bs-alert-border-color: var(--color-success-50);
|
|
746
|
+
--bs-alert-color: var(--color-text-body);
|
|
874
747
|
--alert-accent: var(--wui-success-active);
|
|
748
|
+
// AA-safe text colour for the heading and an accented <strong>.
|
|
749
|
+
--alert-text: var(--color-success-text-on-soft);
|
|
875
750
|
}
|
|
876
751
|
.alert-warning {
|
|
877
|
-
--bs-alert-bg: var(--
|
|
878
|
-
--bs-alert-border-color: var(--
|
|
879
|
-
--bs-alert-color: var(--
|
|
752
|
+
--bs-alert-bg: var(--color-warning-soft);
|
|
753
|
+
--bs-alert-border-color: var(--color-warning-50);
|
|
754
|
+
--bs-alert-color: var(--color-text-body);
|
|
880
755
|
--alert-accent: var(--wui-warning-active);
|
|
756
|
+
// AA-safe text colour for the heading and an accented <strong>.
|
|
757
|
+
--alert-text: var(--color-warning-text-on-soft);
|
|
881
758
|
}
|
|
882
759
|
.alert-danger {
|
|
883
|
-
--bs-alert-bg: var(--
|
|
884
|
-
--bs-alert-border-color: var(--
|
|
885
|
-
--bs-alert-color: var(--
|
|
760
|
+
--bs-alert-bg: var(--color-danger-soft);
|
|
761
|
+
--bs-alert-border-color: var(--color-danger-50);
|
|
762
|
+
--bs-alert-color: var(--color-text-body);
|
|
886
763
|
--alert-accent: var(--wui-danger-active);
|
|
764
|
+
// AA-safe text colour for the heading and an accented <strong>.
|
|
765
|
+
--alert-text: var(--color-danger-text-on-soft);
|
|
887
766
|
}
|
|
888
767
|
|
|
889
768
|
// Borderless variant (`bordered={false}` / `bordered="false"`): drop the soft ring and
|
|
@@ -893,6 +772,73 @@
|
|
|
893
772
|
border-color: transparent;
|
|
894
773
|
}
|
|
895
774
|
|
|
775
|
+
// Accent (`accent`): a thick variant-coloured LEFT edge that marks the alert as an aside,
|
|
776
|
+
// flush with the container's outer edge, corners included.
|
|
777
|
+
// A real border cannot do this: a 4px border-left meeting 1px top/bottom borders on a rounded
|
|
778
|
+
// corner is mitred into a point, and an inset shadow drawn inside a 1px border leaves that
|
|
779
|
+
// border curving round the corner outside the edge. So the accent alert has no border at all:
|
|
780
|
+
// the soft ring is an inset 1px shadow, and the accent is a second inset shadow listed first,
|
|
781
|
+
// so it paints over the ring along the left side and fills the corners out to the edge.
|
|
782
|
+
// Padding grows by the 1px the border no longer takes (and by the 4px edge on the left), so
|
|
783
|
+
// the box and its text sit exactly where a bordered alert's do.
|
|
784
|
+
.alert-accent {
|
|
785
|
+
--alert-ring: var(--bs-alert-border-color);
|
|
786
|
+
border-width: 0;
|
|
787
|
+
box-shadow:
|
|
788
|
+
inset 4px 0 0 var(--alert-accent),
|
|
789
|
+
inset 0 0 0 1px var(--alert-ring);
|
|
790
|
+
padding: 17px 19px 17px 22px;
|
|
791
|
+
}
|
|
792
|
+
// `bordered={false}`: only the ring goes; the edge stays.
|
|
793
|
+
.alert-accent.alert-borderless {
|
|
794
|
+
--alert-ring: transparent;
|
|
795
|
+
}
|
|
796
|
+
.alert-accent strong {
|
|
797
|
+
font-weight: 700;
|
|
798
|
+
color: var(--alert-text);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// Compact size (`size="sm"`): a single tinted line with tighter padding. The body keeps the
|
|
802
|
+
// same dark ink and regular weight as md (only the heading is bold and variant-coloured); the
|
|
803
|
+
// badge stays the single-line 20px base.
|
|
804
|
+
.alert-sm {
|
|
805
|
+
padding: 9px 14px;
|
|
806
|
+
}
|
|
807
|
+
.alert-sm.alert-has-icon {
|
|
808
|
+
gap: 10px;
|
|
809
|
+
}
|
|
810
|
+
.alert-sm .alert-content {
|
|
811
|
+
font-size: 11px;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Trailing action (`action`): a button or any node. Mobile-first, it takes its own full
|
|
815
|
+
// row below the content; from md up it sits inline at the right edge. A viewport rule,
|
|
816
|
+
// not the alert's own width, so a button never crushes the message on a phone.
|
|
817
|
+
.alert-has-action {
|
|
818
|
+
display: flex;
|
|
819
|
+
align-items: center;
|
|
820
|
+
flex-wrap: wrap;
|
|
821
|
+
gap: 12px;
|
|
822
|
+
}
|
|
823
|
+
.alert-has-action .alert-content {
|
|
824
|
+
flex: 1 1 auto;
|
|
825
|
+
}
|
|
826
|
+
.alert-action {
|
|
827
|
+
flex: 1 1 100%;
|
|
828
|
+
display: flex;
|
|
829
|
+
align-items: center;
|
|
830
|
+
gap: 8px;
|
|
831
|
+
}
|
|
832
|
+
@include media-breakpoint-up(md) {
|
|
833
|
+
.alert-has-action {
|
|
834
|
+
flex-wrap: nowrap;
|
|
835
|
+
}
|
|
836
|
+
.alert-action {
|
|
837
|
+
flex: none;
|
|
838
|
+
margin-left: auto;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
896
842
|
.alert-has-icon {
|
|
897
843
|
display: flex;
|
|
898
844
|
// Single-line alerts (a lone body, or a lone title) read best with the badge
|
|
@@ -913,6 +859,21 @@
|
|
|
913
859
|
// a soft 3px same-colour halo ring around it. Base size is the SINGLE-line badge (20px,
|
|
914
860
|
// 20px glyph); the .alert-stack override above enlarges it when a title and body appear
|
|
915
861
|
// together. (The glyph itself is a Bootstrap Icons font `<i>` sized by the component.)
|
|
862
|
+
// Custom image in the badge (icon replacement): the image fills the circle, so drop the
|
|
863
|
+
// variant fill and the halo ring and clip it round. Compound selector so it beats the
|
|
864
|
+
// .alert-icon rule below, which sets both.
|
|
865
|
+
.alert-icon.alert-icon-image {
|
|
866
|
+
background: transparent;
|
|
867
|
+
box-shadow: none;
|
|
868
|
+
overflow: hidden;
|
|
869
|
+
}
|
|
870
|
+
.alert-icon img {
|
|
871
|
+
width: 100%;
|
|
872
|
+
height: 100%;
|
|
873
|
+
object-fit: cover;
|
|
874
|
+
border-radius: 50%;
|
|
875
|
+
}
|
|
876
|
+
|
|
916
877
|
.alert-icon {
|
|
917
878
|
flex: none;
|
|
918
879
|
display: inline-flex;
|
|
@@ -948,16 +909,54 @@
|
|
|
948
909
|
// Use the AA-safe `-text` tokens (not the vivid `-active`, which fails AA as text on
|
|
949
910
|
// the soft `-10` background); the badge fill / halo keep the vivid `-active`.
|
|
950
911
|
.alert-info .alert-heading {
|
|
951
|
-
color: var(--
|
|
912
|
+
color: var(--alert-text);
|
|
952
913
|
}
|
|
953
914
|
.alert-success .alert-heading {
|
|
954
|
-
color: var(--
|
|
915
|
+
color: var(--alert-text);
|
|
955
916
|
}
|
|
956
917
|
.alert-warning .alert-heading {
|
|
957
|
-
color: var(--
|
|
918
|
+
color: var(--alert-text);
|
|
958
919
|
}
|
|
959
920
|
.alert-danger .alert-heading {
|
|
960
|
-
color: var(--
|
|
921
|
+
color: var(--alert-text);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Heading and body type step with the size: sm 13px / 11px, md 14px / 12px (the base above),
|
|
925
|
+
// lg 16px / 14px. Declared after the base heading rule so these override it.
|
|
926
|
+
.alert-sm .alert-heading {
|
|
927
|
+
font-size: 13px;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// Large size (`size="lg"`): roomier padding, a larger heading and body, and a larger badge
|
|
931
|
+
// (28px, or 32px for a title+body stack). Declared after the heading and stack rules so it
|
|
932
|
+
// overrides them.
|
|
933
|
+
.alert-lg {
|
|
934
|
+
padding: 20px 22px;
|
|
935
|
+
}
|
|
936
|
+
.alert-lg.alert-has-icon {
|
|
937
|
+
gap: 16px;
|
|
938
|
+
}
|
|
939
|
+
.alert-lg .alert-heading {
|
|
940
|
+
font-size: 16px;
|
|
941
|
+
}
|
|
942
|
+
.alert-lg .alert-content {
|
|
943
|
+
font-size: 14px;
|
|
944
|
+
}
|
|
945
|
+
.alert-lg.alert-has-icon .alert-icon {
|
|
946
|
+
width: 28px;
|
|
947
|
+
height: 28px;
|
|
948
|
+
}
|
|
949
|
+
.alert-lg.alert-has-icon.alert-stack .alert-icon {
|
|
950
|
+
width: 32px;
|
|
951
|
+
height: 32px;
|
|
952
|
+
}
|
|
953
|
+
// The accent's padding per size: the size's own padding + the 1px the border no longer takes,
|
|
954
|
+
// + the 4px edge on the left. Two-class selectors, so they beat the size blocks above.
|
|
955
|
+
.alert-accent.alert-sm {
|
|
956
|
+
padding: 10px 15px 10px 18px;
|
|
957
|
+
}
|
|
958
|
+
.alert-accent.alert-lg {
|
|
959
|
+
padding: 21px 23px 21px 26px;
|
|
961
960
|
}
|
|
962
961
|
|
|
963
962
|
// The body's trailing paragraph shouldn't add space below the alert.
|
|
@@ -971,6 +970,14 @@
|
|
|
971
970
|
.alert-dismissible {
|
|
972
971
|
padding-right: 52px;
|
|
973
972
|
}
|
|
973
|
+
// An accent alert has no 1px border, so it takes the missing pixel back on the right.
|
|
974
|
+
.alert-accent.alert-dismissible {
|
|
975
|
+
padding-right: 53px;
|
|
976
|
+
}
|
|
977
|
+
// The dismiss × is Bootstrap's ink-dark glyph; the token whitens it on a dark page.
|
|
978
|
+
.alert .btn-close {
|
|
979
|
+
filter: var(--color-close-filter);
|
|
980
|
+
}
|
|
974
981
|
// Centre the dismiss × vertically rather than pinning it to the top corner.
|
|
975
982
|
.alert-dismissible .btn-close {
|
|
976
983
|
top: 50%;
|
package/scss/wui/_workspace.scss
CHANGED
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
.workspace-switcher-trigger[aria-expanded="true"] {
|
|
46
46
|
outline: none;
|
|
47
47
|
background: var(--color-surface);
|
|
48
|
-
border-color: var(--
|
|
48
|
+
border-color: var(--color-focus-border);
|
|
49
49
|
box-shadow: none;
|
|
50
50
|
}
|
|
51
51
|
.workspace-switcher-trigger.is-compact {
|