@webority/theme 0.17.4 → 0.18.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webority/theme",
3
- "version": "0.17.4",
3
+ "version": "0.18.1",
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": {
@@ -173,7 +173,8 @@ $input-focus-color: $body-color;
173
173
  $input-padding-y: 0.5rem; // filler inside --wui-control-height (44px)
174
174
  $input-padding-x: 0.875rem; // 14px
175
175
  $input-border-radius: $border-radius;
176
- $input-placeholder-color: #99A1B7; // --wui-text-4
176
+ // Themed, so it flips in dark mode. The old fixed #99A1B7 was 2.58:1 on white and read as typed text on dark.
177
+ $input-placeholder-color: var(--color-text-subtle);
177
178
 
178
179
 
179
180
  // ---- Cards ----------------------------------------------------------
@@ -38,7 +38,7 @@
38
38
  // so they must stay in the layer that loads after Bootstrap.
39
39
  .card-title {
40
40
  margin: 0;
41
- font-size: 15px;
41
+ font-size: 16px;
42
42
  font-weight: 600;
43
43
  line-height: 1.3;
44
44
  color: var(--color-text);
@@ -74,6 +74,32 @@
74
74
  grid-column: 2;
75
75
  }
76
76
 
77
+ // AppRadioGroup: options in a column, or a wrapping row with `inline`.
78
+ .wui-radio-group {
79
+ display: flex;
80
+ flex-direction: column;
81
+ gap: 10px;
82
+ }
83
+ .wui-radio-group-inline {
84
+ flex-direction: row;
85
+ flex-wrap: wrap;
86
+ column-gap: 24px;
87
+ }
88
+ .wui-radio-group > .form-check {
89
+ margin-bottom: 0;
90
+ }
91
+ // A lone .form-check lets its label shrink to nothing so long consent text can wrap; in a row
92
+ // of options that broke words mid-way ("Mont hly"). Keep each option's words whole and let the
93
+ // row wrap instead.
94
+ .wui-radio-group .form-check-label {
95
+ min-width: auto;
96
+ }
97
+ // Beside-label forms centre a label on a text control; a radio group's first option is shorter,
98
+ // so its label lines up with that row instead.
99
+ .wui-form-labels-start .field:has(> .wui-radio-group) > .label {
100
+ padding-top: 0;
101
+ }
102
+
77
103
  // Glyph — shared by BS form-check-input and the wui-check alias.
78
104
  .form-check-input,
79
105
  .wui-check,
@@ -780,9 +780,20 @@ button.step:focus-visible .step-circle {
780
780
  flex-direction: column;
781
781
  gap: 6px;
782
782
  }
783
+ // Consecutive sections are separated by space and a light rule, and the action bar keeps its
784
+ // distance from the last field, so a long form never reads as one run of fields.
785
+ .form-section + .form-section {
786
+ margin-top: 32px;
787
+ padding-top: 32px;
788
+ border-top: 1px solid var(--color-border);
789
+ }
790
+ .form-section + .form-actions {
791
+ margin-top: 32px;
792
+ }
793
+ // Ranks below the card title (16px) a section usually sits in, and above the 14px field labels.
783
794
  .form-section-title {
784
795
  margin: 0;
785
- font-size: 17px;
796
+ font-size: 15px;
786
797
  font-weight: 600;
787
798
  line-height: 1.3;
788
799
  color: var(--color-text);
@@ -799,6 +810,65 @@ button.step:focus-visible .step-circle {
799
810
  gap: 16px;
800
811
  }
801
812
 
813
+ // layout="side": the title and description take a column beside the fields. Below lg the
814
+ // section stacks as usual, since a 240px column would starve the fields.
815
+ @include media-breakpoint-up(lg) {
816
+ .wui-form-side {
817
+ display: grid;
818
+ grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
819
+ column-gap: 32px;
820
+ align-items: start;
821
+ }
822
+ .wui-form-side > .form-section-body {
823
+ grid-column: 2;
824
+ }
825
+ }
826
+
827
+ // labels="start": each label sits beside its control, one field per row. The label column is
828
+ // narrower when the section title already takes a column of its own. Below md labels return
829
+ // to the top.
830
+ .wui-form-labels-start {
831
+ --wui-form-label-width: 180px;
832
+ }
833
+ .wui-form-side.wui-form-labels-start {
834
+ --wui-form-label-width: 150px;
835
+ }
836
+ @include media-breakpoint-up(md) {
837
+ // Two classes outrank the row's own column count.
838
+ .wui-form-labels-start .form-row-grid {
839
+ grid-template-columns: minmax(0, 1fr);
840
+ }
841
+ .wui-form-labels-start .field {
842
+ display: grid;
843
+ grid-template-columns: var(--wui-form-label-width) minmax(0, 1fr);
844
+ column-gap: 20px;
845
+ row-gap: 4px;
846
+ align-items: start;
847
+ }
848
+ // Centres the label's first line on the control beside it, at any control height.
849
+ .wui-form-labels-start .field > .label {
850
+ grid-column: 1;
851
+ padding-top: calc((var(--wui-control-height) - 1.2em) / 2);
852
+ }
853
+ .wui-form-labels-start .field > :not(.label) {
854
+ grid-column: 2;
855
+ }
856
+ // A checkbox or switch has its label after the box; line the box up with the controls.
857
+ .wui-form-labels-start .form-row-grid > .form-check {
858
+ margin-left: calc(var(--wui-form-label-width) + 20px);
859
+ }
860
+ }
861
+
862
+ // density="compact": small-tier controls and tighter gaps, for admin screens and dialogs.
863
+ .wui-form-compact {
864
+ --wui-control-height: var(--wui-control-height-sm);
865
+ gap: 12px;
866
+ }
867
+ .wui-form-compact .form-section-body,
868
+ .wui-form-compact .form-row-grid {
869
+ gap: 12px;
870
+ }
871
+
802
872
  // ============================================================================
803
873
  .form-row-grid {
804
874
  display: grid;
@@ -441,20 +441,8 @@ wui-multiselect[collapse-chips] .ms-chips {
441
441
  .ms-input:focus {
442
442
  outline: none;
443
443
  }
444
- // AppTagInput lays the input on the LEFT with the chips filling and wrapping to its
445
- // right (its template renders the input before the chips). Multiselect keeps its
446
- // chips-first layout, so these overrides are scoped to `wui-taginput`.
447
- wui-taginput .ms-input {
448
- // Don't grow to fill — hold a modest resting width on the left; the chips take
449
- // everything to the right. (align-items:center on the control centres the input
450
- // against the chip row, so it needs no min-height of its own.)
451
- flex: 0 1 auto;
452
- flex-basis: 120px;
453
- min-width: 96px;
454
- }
455
- wui-taginput .ms-chips {
456
- flex: 1 1 auto;
457
- }
444
+ // AppTagInput renders its input inside the chip row, after the chips, so the shared
445
+ // `.ms-chips > .ms-input` rule above lets it wrap with them and fill the rest of the line.
458
446
  // Match AppInput's per-size heights: the shared `.search-select-multi` floors md at
459
447
  // 40px, but AppInput's md is the 44px control-height token — raise the floor so the
460
448
  // sm/md/lg progression lines up with a text field beside it. (sm 36 / lg 52 already
@@ -246,6 +246,10 @@
246
246
  align-items: center;
247
247
  }
248
248
  .page-title {
249
+ // A real heading element: drop the browser/Bootstrap heading margin and keep the body rhythm.
250
+ margin: 0;
251
+ font-family: inherit;
252
+ line-height: inherit;
249
253
  font-size: 24px;
250
254
  font-weight: 600;
251
255
  letter-spacing: -0.02em;
@@ -765,6 +769,32 @@
765
769
  --alert-text: var(--color-danger-text-on-soft);
766
770
  }
767
771
 
772
+ // AppErrorSummary: a danger alert holding a heading and one link per field error. It takes
773
+ // focus when it appears, so its focus ring is the alert's own edge rather than an outline.
774
+ .wui-error-summary:focus {
775
+ outline: none;
776
+ box-shadow: 0 0 0 3px var(--color-danger-soft), 0 0 0 4px var(--alert-accent);
777
+ }
778
+ .wui-error-summary-title {
779
+ margin: 0 0 6px;
780
+ font-size: 15px;
781
+ font-weight: 600;
782
+ line-height: 1.4;
783
+ color: var(--alert-text);
784
+ }
785
+ .wui-error-summary-list {
786
+ margin: 0;
787
+ padding-left: 20px;
788
+ }
789
+ .wui-error-summary-list li + li {
790
+ margin-top: 2px;
791
+ }
792
+ .wui-error-summary-list a {
793
+ color: var(--alert-text);
794
+ text-decoration: underline;
795
+ text-underline-offset: 2px;
796
+ }
797
+
768
798
  // Borderless variant (`bordered={false}` / `bordered="false"`): drop the soft ring and
769
799
  // keep only the tint fill. `transparent` rather than `border: 0` so the box keeps its
770
800
  // 1px so nothing shifts when toggling the border on and off.