@scalewing/react 1.29.0 → 1.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.
Files changed (41) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +9 -3
  3. package/dist/components/ActionMenu.d.ts +14 -0
  4. package/dist/components/ActionMenu.js +4 -0
  5. package/dist/components/ButtonGroup.d.ts +9 -1
  6. package/dist/components/ButtonGroup.js +2 -2
  7. package/dist/components/FilterChips.d.ts +17 -1
  8. package/dist/components/FilterChips.js +11 -6
  9. package/dist/components/ScrollRegion.d.ts +6 -2
  10. package/dist/components/ScrollRegion.js +9 -3
  11. package/dist/components/SectionNav.d.ts +25 -2
  12. package/dist/components/SectionNav.js +13 -4
  13. package/dist/components/Table.d.ts +49 -5
  14. package/dist/components/Table.js +11 -4
  15. package/dist/components/action-menu/ActionMenuList.js +7 -7
  16. package/dist/components/table/TableCell.d.ts +8 -0
  17. package/dist/components/table/TableCell.js +4 -2
  18. package/dist/components/table/TableRow.d.ts +39 -0
  19. package/dist/components/table/TableRow.js +8 -0
  20. package/dist/components/use-scroll-overflow.d.ts +8 -3
  21. package/dist/components/use-scroll-overflow.js +15 -4
  22. package/dist/css/css-action-menu.js +41 -0
  23. package/dist/css/css-button-group-attached.d.ts +2 -0
  24. package/dist/css/css-button-group-attached.js +70 -0
  25. package/dist/css/css-button.js +5 -1
  26. package/dist/css/css-components.js +1 -0
  27. package/dist/css/css-filter-chips.js +26 -0
  28. package/dist/css/css-section-nav-filled.d.ts +6 -0
  29. package/dist/css/css-section-nav-filled.js +80 -0
  30. package/dist/css/css-section-nav.js +4 -0
  31. package/dist/css/css-table-footer.d.ts +2 -0
  32. package/dist/css/css-table-footer.js +57 -0
  33. package/dist/css/css-table-ledger.d.ts +10 -0
  34. package/dist/css/css-table-ledger.js +122 -0
  35. package/dist/css/css-table.js +8 -0
  36. package/dist/css/stacking.d.ts +9 -3
  37. package/dist/css/stacking.js +24 -7
  38. package/dist/index.d.ts +2 -2
  39. package/dist/index.js +2 -2
  40. package/dist/styles.css +278 -5
  41. package/package.json +1 -1
@@ -1,10 +1,16 @@
1
1
  export declare const stackingOrder: {
2
2
  readonly stickyCell: 1;
3
- readonly bottomChrome: 2;
4
- readonly popupHost: 3;
5
- readonly topChrome: 4;
3
+ readonly stickyFooter: 2;
4
+ readonly bottomChrome: 3;
5
+ readonly popupHost: 4;
6
+ readonly topChrome: 5;
6
7
  readonly popup: 10;
7
8
  };
8
9
  export type StackingLayer = keyof typeof stackingOrder;
10
+ export declare const joinedControlOrder: {
11
+ readonly pressed: 1;
12
+ readonly focused: 2;
13
+ };
14
+ export declare function joinedZIndex(layer: keyof typeof joinedControlOrder): string;
9
15
  export declare function zIndex(layer: StackingLayer): string;
10
16
  export declare function cssPopupHostRules(): string;
@@ -4,16 +4,19 @@
4
4
  *
5
5
  * 1. `stickyCell`: a sticky table header cell or row label over the cells
6
6
  * that scroll under it.
7
- * 2. `bottomChrome`: the sticky ActionBar over the page flow it follows.
8
- * 3. `popupHost`: a glass surface (glass Card, Accordion) while it holds an
7
+ * 2. `stickyFooter`: a sticky table footer (a pinned total row) over the
8
+ * cells and pinned header cells that scroll under it, and under the
9
+ * ActionBar, which stays the page's last word at the bottom edge.
10
+ * 3. `bottomChrome`: the sticky ActionBar over the page flow it follows.
11
+ * 4. `popupHost`: a glass surface (glass Card, Accordion) while it holds an
9
12
  * open popup. Backdrop blur makes that surface its own stacking context, so
10
13
  * its popup can only paint as high as the surface does; lifting the surface
11
14
  * over the ActionBar keeps an open list tappable where the bar would cover
12
15
  * it, and over the next surface in the flow.
13
- * 4. `topChrome`: the sticky AppHeader or sticky Tabs strip, over a lifted
16
+ * 5. `topChrome`: the sticky AppHeader or sticky Tabs strip, over a lifted
14
17
  * surface that scrolls up under it (the header is the page's way back, the
15
18
  * strip its way between sections, and a popup opens downward).
16
- * 5. `popup`: a popup outside any lifted surface (Select list, ActionMenu
19
+ * 6. `popup`: a popup outside any lifted surface (Select list, ActionMenu
17
20
  * list, MultiSelect panel, Tooltip, the DateField and CalendarButton
18
21
  * calendar) over everything in the page.
19
22
  *
@@ -21,11 +24,25 @@
21
24
  */
22
25
  export const stackingOrder = {
23
26
  stickyCell: 1,
24
- bottomChrome: 2,
25
- popupHost: 3,
26
- topChrome: 4,
27
+ stickyFooter: 2,
28
+ bottomChrome: 3,
29
+ popupHost: 4,
30
+ topChrome: 5,
27
31
  popup: 10,
28
32
  };
33
+ /*
34
+ * The order inside a joined control (an attached ButtonGroup), which is
35
+ * its own stacking context (`isolation: isolate`), so these never meet the
36
+ * page's layers: a pressed button's ring over its neighbours, and the
37
+ * focused button's ring over both.
38
+ */
39
+ export const joinedControlOrder = {
40
+ pressed: 1,
41
+ focused: 2,
42
+ };
43
+ export function joinedZIndex(layer) {
44
+ return `z-index: ${joinedControlOrder[layer]};`;
45
+ }
29
46
  export function zIndex(layer) {
30
47
  return `z-index: ${stackingOrder[layer]};`;
31
48
  }
package/dist/index.d.ts CHANGED
@@ -32,13 +32,13 @@ export { Inline, type InlineProps } from './components/Inline.js';
32
32
  export { Split } from './components/Split.js';
33
33
  export type { SplitProps } from './components/Split.js';
34
34
  export { Nav, type NavProps } from './components/Nav.js';
35
- export { SectionNav, type SectionNavItem, type SectionNavProps, } from './components/SectionNav.js';
35
+ export { SectionNav, sectionNavAppearances, type SectionNavAppearance, type SectionNavItem, type SectionNavProps, } from './components/SectionNav.js';
36
36
  export { SegmentedControl, type SegmentedControlProps, type SegmentedControlVariant, type SegmentedItem, } from './components/SegmentedControl.js';
37
37
  export { Select } from './components/Select.js';
38
38
  export type { SelectAction, SelectOption, SelectProps, SelectWidth, } from './components/Select.js';
39
39
  export { MultiSelect, type MultiSelectAlign, type MultiSelectOption, type MultiSelectProps, } from './components/MultiSelect.js';
40
40
  export { Stack, type Align, type Justify, type StackProps, } from './components/Stack.js';
41
- export { Table, TableBody, TableCell, TableHeader, TableRow, type TableBodyProps, type TableCellProps, type TableColumnWidth, type TableDensity, type TableHeaderProps, type TableLayout, type TableProps, type TableRowProps, type TableSort, type TableVerticalAlign, } from './components/Table.js';
41
+ export { Table, TableBody, TableCell, TableFooter, TableHeader, TableRow, tableCellTones, tableRowVariants, type TableBodyProps, type TableCellProps, type TableCellTone, type TableColumnWidth, type TableDensity, type TableFooterProps, type TableHeaderProps, type TableLayout, type TableProps, type TableRowProps, type TableRowVariant, type TableSort, type TableVerticalAlign, } from './components/Table.js';
42
42
  export { Text, type TextAlign, type TextElement, type TextProps, } from './components/Text.js';
43
43
  export { ThemeProvider, useTheme, type ThemeProviderProps, } from './theme/ThemeProvider.js';
44
44
  export { utilityClassCatalog } from './css/stylesheet.js';
package/dist/index.js CHANGED
@@ -29,12 +29,12 @@ export { Stepper, } from './components/Stepper.js';
29
29
  export { Inline } from './components/Inline.js';
30
30
  export { Split } from './components/Split.js';
31
31
  export { Nav } from './components/Nav.js';
32
- export { SectionNav, } from './components/SectionNav.js';
32
+ export { SectionNav, sectionNavAppearances, } from './components/SectionNav.js';
33
33
  export { SegmentedControl, } from './components/SegmentedControl.js';
34
34
  export { Select } from './components/Select.js';
35
35
  export { MultiSelect, } from './components/MultiSelect.js';
36
36
  export { Stack, } from './components/Stack.js';
37
- export { Table, TableBody, TableCell, TableHeader, TableRow, } from './components/Table.js';
37
+ export { Table, TableBody, TableCell, TableFooter, TableHeader, TableRow, tableCellTones, tableRowVariants, } from './components/Table.js';
38
38
  export { Text, } from './components/Text.js';
39
39
  export { ThemeProvider, useTheme, } from './theme/ThemeProvider.js';
40
40
  export { utilityClassCatalog } from './css/stylesheet.js';
package/dist/styles.css CHANGED
@@ -831,7 +831,7 @@ body {
831
831
  .sw-card-glass:has(.sw-select-list, .sw-action-menu-list, .sw-multi-select-panel, .sw-tooltip:not([hidden]), .sw-date-field-calendar),
832
832
  .sw-accordion:has(.sw-select-list, .sw-action-menu-list, .sw-multi-select-panel, .sw-tooltip:not([hidden]), .sw-date-field-calendar) {
833
833
  position: relative;
834
- z-index: 3;
834
+ z-index: 4;
835
835
  }
836
836
 
837
837
  .sw-card-outlined {
@@ -931,6 +931,53 @@ body {
931
931
  .sw-button-group > * { width: 100%; }
932
932
  }
933
933
 
934
+ .sw-button-group.sw-button-group-attached {
935
+ align-items: stretch;
936
+ display: inline-flex;
937
+ flex-wrap: nowrap;
938
+ gap: 0;
939
+ isolation: isolate;
940
+ max-width: 100%;
941
+ width: fit-content;
942
+ }
943
+
944
+ .sw-button-group.sw-button-group-attached > .sw-button {
945
+ border-radius: 0;
946
+ }
947
+
948
+ .sw-button-group.sw-button-group-attached > .sw-button + .sw-button {
949
+ margin-inline-start: -1px;
950
+ }
951
+
952
+ .sw-button-group.sw-button-group-attached > .sw-button:first-child {
953
+ border-end-start-radius: var(--sw-radius-sm);
954
+ border-start-start-radius: var(--sw-radius-sm);
955
+ }
956
+
957
+ .sw-button-group.sw-button-group-attached > .sw-button:last-child {
958
+ border-end-end-radius: var(--sw-radius-sm);
959
+ border-start-end-radius: var(--sw-radius-sm);
960
+ }
961
+
962
+ .sw-button-group.sw-button-group-attached > .sw-button + .sw-button:not(.sw-button-secondary) {
963
+ border-inline-start-color: color-mix(in srgb, currentColor 30%, transparent);
964
+ }
965
+
966
+ .sw-button-group.sw-button-group-attached > .sw-button[aria-pressed='true'] {
967
+ position: relative;
968
+ z-index: 1;
969
+ }
970
+
971
+ .sw-button-group.sw-button-group-attached > .sw-button:focus-visible {
972
+ position: relative;
973
+ z-index: 2;
974
+ }
975
+
976
+ @media not all and (min-width: 48rem) {
977
+ .sw-button-group.sw-button-group-attached { align-items: stretch; flex-direction: row; }
978
+ .sw-button-group.sw-button-group-attached > * { width: auto; }
979
+ }
980
+
934
981
  .sw-checkbox {
935
982
  display: flex;
936
983
  flex-direction: column;
@@ -1593,6 +1640,118 @@ body {
1593
1640
  .sw-table-sort-none { opacity: 1; }
1594
1641
  }
1595
1642
 
1643
+ .sw-table .sw-table-tone-success {
1644
+ color: var(--sw-color-success);
1645
+ }
1646
+
1647
+ .sw-table .sw-table-tone-danger {
1648
+ color: var(--sw-color-danger);
1649
+ }
1650
+
1651
+ .sw-table .sw-table-tone-muted {
1652
+ color: var(--sw-color-muted);
1653
+ }
1654
+
1655
+ .sw-table .sw-table-tone-accent {
1656
+ color: var(--sw-color-accent);
1657
+ }
1658
+
1659
+ .sw-table-column-rules :is(th, td) + :is(th, td) {
1660
+ border-inline-start: 1px solid var(--sw-color-border);
1661
+ }
1662
+
1663
+ /* A sticky header cell is positioned, so the next cell's fill covers a
1664
+ collapsed border; its rule is a border on its own ::after instead, so
1665
+ forced colours keep it and the logical inset mirrors it. */
1666
+ .sw-table-sticky.sw-table-column-rules thead :is(th, td) + :is(th, td)::after {
1667
+ border-inline-start: 1px solid var(--sw-color-border);
1668
+ content: '';
1669
+ inset-block: 0;
1670
+ inset-inline-start: 0;
1671
+ pointer-events: none;
1672
+ position: absolute;
1673
+ }
1674
+
1675
+ :where(.sw-table tbody, .sw-table tfoot) th[scope='row'] {
1676
+ color: inherit;
1677
+ font: inherit;
1678
+ letter-spacing: inherit;
1679
+ }
1680
+
1681
+ .sw-table-row-sub > th[scope='row'] {
1682
+ padding-inline-start: calc(var(--sw-space-3) + var(--sw-space-6) + var(--sw-space-3));
1683
+ position: relative;
1684
+ }
1685
+
1686
+ .sw-table-compact .sw-table-row-sub > th[scope='row'] {
1687
+ padding-inline-start: calc(var(--sw-space-2) + var(--sw-space-6) + var(--sw-space-3));
1688
+ }
1689
+
1690
+ .sw-table-row-sub > th[scope='row']::after {
1691
+ block-size: var(--sw-space-5);
1692
+ border-inline-start: 2px solid var(--sw-color-border);
1693
+ content: '';
1694
+ inset-block-start: 50%;
1695
+ inset-inline-start: calc(var(--sw-space-3) + var(--sw-space-6));
1696
+ pointer-events: none;
1697
+ position: absolute;
1698
+ transform: translateY(-50%);
1699
+ }
1700
+
1701
+ .sw-table-compact .sw-table-row-sub > th[scope='row']::after {
1702
+ inset-inline-start: calc(var(--sw-space-2) + var(--sw-space-6));
1703
+ }
1704
+
1705
+ .sw-table .sw-table-row-struck > :is(td, th) {
1706
+ background: var(--sw-color-subtle);
1707
+ color: var(--sw-color-muted);
1708
+ text-decoration: line-through;
1709
+ }
1710
+
1711
+ .sw-table .sw-table-row-struck > [class*='sw-table-tone-'] {
1712
+ color: var(--sw-color-muted);
1713
+ }
1714
+
1715
+ @media (forced-colors: active) {
1716
+ .sw-table-column-rules :is(th, td) + :is(th, td),
1717
+ .sw-table-sticky.sw-table-column-rules thead :is(th, td) + :is(th, td)::after { border-color: CanvasText; }
1718
+ .sw-table-row-sub > th[scope='row']::after { border-color: CanvasText; }
1719
+ }
1720
+
1721
+ .sw-table tfoot :is(th, td) {
1722
+ font-weight: 600;
1723
+ position: relative;
1724
+ }
1725
+
1726
+ .sw-table tfoot > tr:first-child > :is(th, td)::before {
1727
+ border-top: 2px solid var(--sw-color-border);
1728
+ content: '';
1729
+ /* Over the last body row's 1 px border, so the rule reads 2 px. */
1730
+ inset-block-start: -1px;
1731
+ inset-inline: 0;
1732
+ pointer-events: none;
1733
+ position: absolute;
1734
+ }
1735
+
1736
+ .sw-table .sw-table-footer-sticky :is(th, td) {
1737
+ background: var(--sw-glass-fill);
1738
+ backdrop-filter: blur(var(--sw-glass-blur)) saturate(var(--sw-glass-saturate));
1739
+ -webkit-backdrop-filter: blur(var(--sw-glass-blur)) saturate(var(--sw-glass-saturate));
1740
+ bottom: 0;
1741
+ position: sticky;
1742
+ z-index: 2;
1743
+ }
1744
+
1745
+ .sw-table-wrap.sw-scroll-fits:has(> .sw-table > .sw-table-footer-sticky) {
1746
+ overflow: visible;
1747
+ }
1748
+
1749
+ @media (forced-colors: active) {
1750
+ .sw-table tfoot > tr:first-child > :is(th, td)::before { border-color: CanvasText; }
1751
+ .sw-table .sw-table-footer-sticky :is(th, td),
1752
+ .sw-table-sticky thead th { background: Canvas; backdrop-filter: none; -webkit-backdrop-filter: none; }
1753
+ }
1754
+
1596
1755
  .sw-table-row-selected > :first-child {
1597
1756
  position: relative;
1598
1757
  }
@@ -2086,7 +2245,7 @@ body {
2086
2245
  .sw-app-header-sticky {
2087
2246
  position: sticky;
2088
2247
  top: 0;
2089
- z-index: 4;
2248
+ z-index: 5;
2090
2249
  }
2091
2250
 
2092
2251
  .sw-nav {
@@ -2210,6 +2369,54 @@ body {
2210
2369
  }
2211
2370
  }
2212
2371
 
2372
+ .sw-section-nav.sw-section-nav-filled .sw-section-nav-list {
2373
+ border-bottom: 0;
2374
+ }
2375
+
2376
+ /* (0,4,0): outranks the underline and the side list's start bar. */
2377
+ [data-theme] .sw-section-nav.sw-section-nav-filled .sw-section-nav-link {
2378
+ border: 2px solid transparent;
2379
+ border-radius: var(--sw-radius-sm);
2380
+ font-weight: 500;
2381
+ margin-bottom: 0;
2382
+ min-height: var(--sw-control-sm-min-height);
2383
+ padding-inline: var(--sw-control-sm-padding-inline);
2384
+ }
2385
+
2386
+ [data-theme] .sw-section-nav.sw-section-nav-filled .sw-section-nav-link[aria-current] {
2387
+ background: color-mix(in srgb, var(--sw-color-muted) 18%, transparent);
2388
+ border-color: transparent;
2389
+ color: var(--sw-color-text);
2390
+ font-weight: 600;
2391
+ }
2392
+
2393
+ [data-theme] .sw-section-nav-count {
2394
+ align-items: center;
2395
+ background: var(--sw-color-danger);
2396
+ border-radius: var(--sw-radius-pill);
2397
+ box-sizing: border-box;
2398
+ color: var(--sw-color-onDanger);
2399
+ display: inline-flex;
2400
+ font-size: 13px;
2401
+ font-variant-numeric: tabular-nums;
2402
+ font-weight: 700;
2403
+ justify-content: center;
2404
+ letter-spacing: -0.08px;
2405
+ line-height: 1;
2406
+ min-height: calc(var(--sw-space-5) - var(--sw-space-1));
2407
+ min-width: calc(var(--sw-space-5) - var(--sw-space-1));
2408
+ padding-inline: var(--sw-space-1);
2409
+ }
2410
+
2411
+ @media (pointer: coarse) {
2412
+ [data-theme] .sw-section-nav.sw-section-nav-filled .sw-section-nav-link { min-height: var(--sw-control-md-min-height); }
2413
+ }
2414
+
2415
+ @media (forced-colors: active) {
2416
+ [data-theme] .sw-section-nav.sw-section-nav-filled .sw-section-nav-link[aria-current] { border-color: Highlight; }
2417
+ [data-theme] .sw-section-nav-count { border: 1px solid CanvasText; }
2418
+ }
2419
+
2213
2420
  @media (pointer: coarse) {
2214
2421
  [data-theme] .sw-section-nav-link { min-height: var(--sw-control-md-min-height); }
2215
2422
  }
@@ -2760,6 +2967,47 @@ body {
2760
2967
  color: var(--sw-color-danger);
2761
2968
  }
2762
2969
 
2970
+ /*
2971
+ * A command's detail: its current value at the inline end in the muted
2972
+ * colour, then a chevron pointing to the inline end (mirrored right to
2973
+ * left). A long value wraps between words, never inside one (the command
2974
+ * itself may break anywhere), and the chevron stays last.
2975
+ */
2976
+ .sw-action-menu-detail {
2977
+ align-items: center;
2978
+ color: var(--sw-color-muted);
2979
+ display: inline-flex;
2980
+ gap: var(--sw-space-2);
2981
+ margin-inline-start: auto;
2982
+ overflow-wrap: normal;
2983
+ padding-inline-start: var(--sw-space-3);
2984
+ text-align: end;
2985
+ }
2986
+
2987
+ .sw-action-menu-chevron {
2988
+ border-bottom: 2px solid var(--sw-color-muted);
2989
+ border-right: 2px solid var(--sw-color-muted);
2990
+ box-sizing: border-box;
2991
+ height: var(--sw-space-2);
2992
+ width: var(--sw-space-2);
2993
+ flex: none;
2994
+ transform: rotate(-45deg);
2995
+ }
2996
+
2997
+ .sw-action-menu-chevron:dir(rtl) {
2998
+ transform: rotate(135deg);
2999
+ }
3000
+
3001
+ /* A hairline that sets a command apart from the ones above. */
3002
+ .sw-action-menu-separator {
3003
+ border-top: 1px solid var(--sw-color-border);
3004
+ margin-block: var(--sw-space-1);
3005
+ }
3006
+
3007
+ @media (forced-colors: active) {
3008
+ .sw-action-menu-chevron { border-color: CanvasText; }
3009
+ }
3010
+
2763
3011
  /* A coarse pointer gets the full touch target: the trigger at least square, and every command as tall. */
2764
3012
  @media (pointer: coarse) {
2765
3013
  .sw-action-menu-trigger {
@@ -2995,14 +3243,14 @@ body {
2995
3243
  .sw-action-bar-sticky {
2996
3244
  bottom: calc(var(--sw-space-2) + env(safe-area-inset-bottom, 0px));
2997
3245
  position: sticky;
2998
- z-index: 2;
3246
+ z-index: 3;
2999
3247
  }
3000
3248
 
3001
3249
  @media not all and (min-width: 48rem) {
3002
3250
  .sw-action-bar-sticky-below-md {
3003
3251
  bottom: calc(var(--sw-space-2) + env(safe-area-inset-bottom, 0px));
3004
3252
  position: sticky;
3005
- z-index: 2;
3253
+ z-index: 3;
3006
3254
  }
3007
3255
  }
3008
3256
 
@@ -3577,7 +3825,7 @@ body {
3577
3825
  -webkit-backdrop-filter: blur(var(--sw-glass-blur)) saturate(var(--sw-glass-saturate));
3578
3826
  position: sticky;
3579
3827
  top: env(safe-area-inset-top, 0px);
3580
- z-index: 4;
3828
+ z-index: 5;
3581
3829
  }
3582
3830
 
3583
3831
  @media (prefers-reduced-transparency: reduce) {
@@ -3692,11 +3940,35 @@ body {
3692
3940
  opacity: var(--sw-disabled-opacity);
3693
3941
  }
3694
3942
 
3943
+ /*
3944
+ * An error: the message under the chips in the danger colour (a polite live
3945
+ * region, out of the layout while empty) and every chip's edge in danger,
3946
+ * the chosen one too (it keeps its accent fill), in normal and forced
3947
+ * colours alike.
3948
+ */
3949
+ .sw-filter-chips-error {
3950
+ color: var(--sw-color-danger);
3951
+ display: block;
3952
+ font-family: var(--sw-font-sans);
3953
+ font-size: 13px;
3954
+ line-height: 18px;
3955
+ padding-top: var(--sw-space-2);
3956
+ }
3957
+
3958
+ .sw-filter-chips-error:empty { position: absolute; }
3959
+
3960
+ .sw-filter-chips[aria-invalid='true'] .sw-filter-chip-face {
3961
+ border-color: var(--sw-color-danger);
3962
+ }
3963
+
3695
3964
  @media (forced-colors: active) {
3696
3965
  .sw-filter-chip-face { background: Canvas; border-color: CanvasText; color: CanvasText; }
3966
+ .sw-filter-chips-error { color: Mark; }
3697
3967
  .sw-filter-chip-input:checked + .sw-filter-chip-face { background: Highlight; border-color: Highlight; color: HighlightText; }
3698
3968
  .sw-filter-chip-input:focus-visible + .sw-filter-chip-face { outline-color: Highlight; }
3699
3969
  .sw-filter-chip-count { color: inherit; }
3970
+ /* After the checked rule, so every chip, the chosen one too, takes the edge. */
3971
+ .sw-filter-chips[aria-invalid='true'] .sw-filter-chip-face { border-color: Mark; }
3700
3972
  }
3701
3973
 
3702
3974
  .sw-grid {
@@ -4837,6 +5109,7 @@ body {
4837
5109
  .sw-badge-neutral,
4838
5110
  .sw-segmented,
4839
5111
  .sw-table-sticky thead th,
5112
+ .sw-table .sw-table-footer-sticky :is(th, td),
4840
5113
  .sw-denomination-strip .sw-denomination-label,
4841
5114
  .sw-denomination-strip thead .sw-denomination-corner:first-child,
4842
5115
  .sw-bar-chart-track,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalewing/react",
3
- "version": "1.29.0",
3
+ "version": "1.30.0",
4
4
  "description": "Scalewing DOM components and package-owned CSS utilities.",
5
5
  "type": "module",
6
6
  "license": "MIT",