@scalewing/react 1.60.0 → 1.61.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 (62) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/components/AppShell.d.ts +5 -3
  3. package/dist/components/AppShell.js +9 -4
  4. package/dist/components/DescriptionList.d.ts +11 -3
  5. package/dist/components/DescriptionList.js +5 -4
  6. package/dist/components/FilterChips.d.ts +1 -1
  7. package/dist/components/FilterChips.js +3 -3
  8. package/dist/components/FixtureGroup.d.ts +7 -3
  9. package/dist/components/FixtureGroup.js +11 -4
  10. package/dist/components/Grid.d.ts +11 -3
  11. package/dist/components/Grid.js +24 -6
  12. package/dist/components/PageHeader.d.ts +40 -0
  13. package/dist/components/PageHeader.js +36 -0
  14. package/dist/components/Tabs.d.ts +19 -0
  15. package/dist/components/Tabs.js +13 -3
  16. package/dist/components/Text.d.ts +20 -0
  17. package/dist/components/Text.js +9 -2
  18. package/dist/components/app-shell/types.d.ts +15 -0
  19. package/dist/components/app-shell/validate.d.ts +3 -3
  20. package/dist/components/app-shell/validate.js +9 -3
  21. package/dist/components/description-list-layout.d.ts +9 -0
  22. package/dist/components/description-list-layout.js +15 -0
  23. package/dist/components/filter-chips/options.d.ts +10 -1
  24. package/dist/components/filter-chips/options.js +2 -0
  25. package/dist/components/filter-chips/validate.d.ts +2 -2
  26. package/dist/components/filter-chips/validate.js +6 -3
  27. package/dist/components/fixture/types.d.ts +10 -0
  28. package/dist/css/breakpoints.d.ts +2 -1
  29. package/dist/css/breakpoints.js +2 -1
  30. package/dist/css/css-app-shell.d.ts +6 -0
  31. package/dist/css/css-app-shell.js +20 -1
  32. package/dist/css/css-button.js +9 -11
  33. package/dist/css/css-components.js +6 -0
  34. package/dist/css/css-density.d.ts +9 -0
  35. package/dist/css/css-density.js +95 -0
  36. package/dist/css/css-description-list.js +21 -0
  37. package/dist/css/css-filter-chips.d.ts +8 -0
  38. package/dist/css/css-filter-chips.js +35 -1
  39. package/dist/css/css-fixture-list.d.ts +10 -0
  40. package/dist/css/css-fixture-list.js +38 -0
  41. package/dist/css/css-fixture.js +4 -1
  42. package/dist/css/css-glyph-tile.js +6 -2
  43. package/dist/css/css-grid-span.js +8 -3
  44. package/dist/css/css-grid.d.ts +8 -1
  45. package/dist/css/css-grid.js +21 -2
  46. package/dist/css/css-page-header.d.ts +2 -0
  47. package/dist/css/css-page-header.js +106 -0
  48. package/dist/css/css-table-bounded.js +3 -2
  49. package/dist/css/css-table-metrics.d.ts +5 -0
  50. package/dist/css/css-table-metrics.js +5 -0
  51. package/dist/css/css-tabs.js +8 -0
  52. package/dist/css/css-text.d.ts +5 -0
  53. package/dist/css/css-text.js +26 -1
  54. package/dist/css/stylesheet.js +4 -0
  55. package/dist/css/touch-target.d.ts +1 -0
  56. package/dist/css/touch-target.js +4 -0
  57. package/dist/index.d.ts +12 -9
  58. package/dist/index.js +8 -6
  59. package/dist/styles.css +186 -7
  60. package/dist/theme/ThemeProvider.d.ts +13 -1
  61. package/dist/theme/ThemeProvider.js +7 -2
  62. package/package.json +2 -2
package/dist/styles.css CHANGED
@@ -927,7 +927,7 @@ body {
927
927
  .sw-text-align-center { text-align: center; }
928
928
  .sw-text-align-end { text-align: end; }
929
929
 
930
- :where(.sw-text-hero, .sw-text-display, .sw-text-headline, .sw-text-heading, .sw-text-title, .sw-text-lead, .sw-text-body, .sw-text-label, .sw-text-caption, .sw-text-data) { margin: 0; }
930
+ :where(.sw-text-hero, .sw-text-display, .sw-text-headline, .sw-text-heading, .sw-text-title, .sw-text-lead, .sw-text-body, .sw-text-bodySm, .sw-text-label, .sw-text-caption, .sw-text-data) { margin: 0; }
931
931
 
932
932
  .sw-text-hero { font-family: var(--sw-font-sans); font-size: 56px; line-height: 60px; font-weight: 700; letter-spacing: -1.7px; }
933
933
  .sw-text-display { font-family: var(--sw-font-sans); font-size: 40px; line-height: 48px; font-weight: 600; letter-spacing: -0.8px; }
@@ -936,6 +936,7 @@ body {
936
936
  .sw-text-title { font-family: var(--sw-font-sans); font-size: 20px; line-height: 28px; font-weight: 600; letter-spacing: -0.3px; }
937
937
  .sw-text-lead { font-family: var(--sw-font-sans); font-size: 20px; line-height: 29px; font-weight: 400; letter-spacing: -0.3px; }
938
938
  .sw-text-body { font-family: var(--sw-font-sans); font-size: 17px; line-height: 25px; font-weight: 400; letter-spacing: -0.2px; }
939
+ .sw-text-bodySm { font-family: var(--sw-font-sans); font-size: 15px; line-height: 22px; font-weight: 400; letter-spacing: -0.2px; }
939
940
  .sw-text-label { font-family: var(--sw-font-sans); font-size: 15px; line-height: 20px; font-weight: 600; letter-spacing: -0.2px; }
940
941
  .sw-text-caption { font-family: var(--sw-font-sans); font-size: 13px; line-height: 18px; font-weight: 400; letter-spacing: -0.08px; }
941
942
  .sw-text-data { font-family: var(--sw-font-sans); font-size: 13px; line-height: 18px; font-weight: 500; letter-spacing: -0.08px; font-variant-numeric: tabular-nums; }
@@ -948,6 +949,21 @@ body {
948
949
  .sw-text-lead { font-size: 17px; line-height: 25px; letter-spacing: -0.2px; }
949
950
  }
950
951
 
952
+ .sw-text-clamp-2 {
953
+ -webkit-box-orient: vertical;
954
+ display: -webkit-box;
955
+ -webkit-line-clamp: 2;
956
+ line-clamp: 2;
957
+ overflow: hidden;
958
+ }
959
+ .sw-text-clamp-3 {
960
+ -webkit-box-orient: vertical;
961
+ display: -webkit-box;
962
+ -webkit-line-clamp: 3;
963
+ line-clamp: 3;
964
+ overflow: hidden;
965
+ }
966
+
951
967
  [data-theme] .sw-font-mono,
952
968
  [data-theme] :is(input[type='text'], input[type='email'], input[type='number'], input[type='search'], input[type='url'], input[type='password'], input:not([type]), textarea).sw-font-mono {
953
969
  font-family: ui-monospace, monospace;
@@ -1007,9 +1023,9 @@ body {
1007
1023
  .sw-button[aria-disabled='true'],
1008
1024
  .sw-button-disabled-neutral[aria-disabled='true']:not(.sw-button-ghost) { border-color: GrayText; color: GrayText; }
1009
1025
  }
1010
- .sw-button-xs { min-height: 28px; padding-inline: 10px; }
1011
- .sw-button-sm { min-height: 32px; padding-inline: 12px; }
1012
- .sw-button-md { min-height: 44px; padding-inline: 16px; }
1026
+ .sw-button-xs { min-height: var(--sw-control-xs-min-height); padding-inline: var(--sw-control-xs-padding-inline); }
1027
+ .sw-button-sm { min-height: var(--sw-control-sm-min-height); padding-inline: var(--sw-control-sm-padding-inline); }
1028
+ .sw-button-md { min-height: var(--sw-control-md-min-height); padding-inline: var(--sw-control-md-padding-inline); }
1013
1029
  @media (pointer: coarse) {
1014
1030
  .sw-button { min-height: var(--sw-control-md-min-height); min-width: var(--sw-control-md-min-height); }
1015
1031
  }
@@ -2070,7 +2086,8 @@ body {
2070
2086
  --sw-table-cell-pad: var(--sw-space-2);
2071
2087
  --sw-table-head-block: 0px;
2072
2088
  --sw-table-foot-rows: 0;
2073
- max-height: calc((var(--sw-table-max-rows) + var(--sw-table-foot-rows)) * (25px + 2 * var(--sw-table-cell-pad) + 1px) + var(--sw-table-head-block));
2089
+ --sw-table-row-line: 25px;
2090
+ max-height: calc((var(--sw-table-max-rows) + var(--sw-table-foot-rows)) * (var(--sw-table-row-line) + 2 * var(--sw-table-cell-pad) + 1px) + var(--sw-table-head-block));
2074
2091
  }
2075
2092
 
2076
2093
  .sw-table-bounded:has(> .sw-table-compact) {
@@ -3529,6 +3546,18 @@ button.sw-date-toggle-day[aria-disabled='true'] {
3529
3546
  }
3530
3547
  }
3531
3548
 
3549
+ @media (min-width: 48rem) {
3550
+ .sw-fixture-list-sides-fixed {
3551
+ grid-template-columns: auto minmax(0, 16rem) minmax(7rem, auto) minmax(0, 16rem) 1fr auto auto;
3552
+ }
3553
+
3554
+ @supports not (grid-template-columns: subgrid) {
3555
+ .sw-fixture-list-sides-fixed .sw-fixture-row {
3556
+ grid-template-columns: minmax(0, 16rem) minmax(7rem, auto) minmax(0, 16rem) 1fr auto;
3557
+ }
3558
+ }
3559
+ }
3560
+
3532
3561
  .sw-fixture-flag {
3533
3562
  align-self: center;
3534
3563
  display: inline-flex;
@@ -5458,6 +5487,76 @@ button.sw-date-toggle-day[aria-disabled='true'] {
5458
5487
  .sw-hero-actions { align-items: stretch; flex-direction: column; }
5459
5488
  }
5460
5489
 
5490
+ .sw-page-header {
5491
+ display: flex;
5492
+ flex-direction: column;
5493
+ gap: var(--sw-space-3);
5494
+ min-width: 0;
5495
+ }
5496
+
5497
+ .sw-page-header-row {
5498
+ align-items: flex-start;
5499
+ display: flex;
5500
+ flex-wrap: wrap;
5501
+ gap: var(--sw-space-3) var(--sw-space-4);
5502
+ min-width: 0;
5503
+ }
5504
+
5505
+ .sw-page-header-words {
5506
+ display: flex;
5507
+ flex: 1 1 min(100%, 20rem);
5508
+ flex-direction: column;
5509
+ gap: var(--sw-space-1);
5510
+ min-width: 0;
5511
+ overflow-wrap: anywhere;
5512
+ }
5513
+
5514
+ .sw-page-header-actions {
5515
+ align-items: center;
5516
+ display: flex;
5517
+ flex: 0 1 auto;
5518
+ flex-wrap: wrap;
5519
+ gap: var(--sw-space-2);
5520
+ max-width: 100%;
5521
+ min-width: 0;
5522
+ }
5523
+
5524
+ .sw-page-header-below {
5525
+ min-width: 0;
5526
+ }
5527
+
5528
+ .sw-page-header-back {
5529
+ align-items: center;
5530
+ align-self: flex-start;
5531
+ display: inline-flex;
5532
+ font-family: var(--sw-font-sans);
5533
+ font-size: 15px;
5534
+ font-weight: 500;
5535
+ gap: var(--sw-space-2);
5536
+ letter-spacing: -0.2px;
5537
+ line-height: 20px;
5538
+ max-width: 100%;
5539
+ min-height: var(--sw-control-xs-min-height);
5540
+ overflow-wrap: anywhere;
5541
+ }
5542
+
5543
+ .sw-page-header-back::before {
5544
+ border-bottom: 2px solid currentColor;
5545
+ border-right: 2px solid currentColor;
5546
+ box-sizing: border-box;
5547
+ height: var(--sw-space-2);
5548
+ width: var(--sw-space-2);
5549
+ content: '';
5550
+ flex: none;
5551
+ transform: rotate(135deg);
5552
+ }
5553
+
5554
+ .sw-page-header-back:dir(rtl)::before { transform: rotate(-45deg); }
5555
+
5556
+ @media (pointer: coarse) {
5557
+ .sw-page-header-back { min-height: var(--sw-control-md-min-height); }
5558
+ }
5559
+
5461
5560
  .sw-site-footer-top {
5462
5561
  display: grid;
5463
5562
  gap: var(--sw-space-6) var(--sw-space-5);
@@ -6253,6 +6352,10 @@ html:has(.sw-site-header-sticky) {
6253
6352
 
6254
6353
  .sw-app-shell-main:focus { outline: none; }
6255
6354
 
6355
+ .sw-app-shell-sidebar-subtle :is(.sw-app-shell-sidebar, .sw-app-shell-drawer) {
6356
+ background: var(--sw-color-subtle);
6357
+ }
6358
+
6256
6359
  .sw-dialog {
6257
6360
  background: var(--sw-glass-fill);
6258
6361
  border: 1px solid var(--sw-glass-border);
@@ -8481,7 +8584,7 @@ html:has(.sw-site-header-sticky) {
8481
8584
  }
8482
8585
 
8483
8586
  .sw-glyph-tile-sm { --sw-glyph-tile-side: var(--sw-space-5); height: var(--sw-space-5); width: var(--sw-space-5); }
8484
- .sw-glyph-tile-md { --sw-glyph-tile-side: var(--sw-control-xs-min-height); height: var(--sw-control-xs-min-height); width: var(--sw-control-xs-min-height); }
8587
+ .sw-glyph-tile-md { --sw-glyph-tile-side: 28px; height: 28px; width: 28px; }
8485
8588
  .sw-glyph-tile-lg { --sw-glyph-tile-side: var(--sw-space-6); height: var(--sw-space-6); width: var(--sw-space-6); }
8486
8589
 
8487
8590
  @media (forced-colors: active) {
@@ -8671,6 +8774,12 @@ html:has(.sw-site-header-sticky) {
8671
8774
  text-align: end;
8672
8775
  }
8673
8776
 
8777
+ @media (min-width: 48rem) {
8778
+ .sw-description-list-term-sm { grid-template-columns: min(8rem, 50%) minmax(0, 1fr); }
8779
+ .sw-description-list-term-md { grid-template-columns: min(12rem, 50%) minmax(0, 1fr); }
8780
+ .sw-description-list-term-lg { grid-template-columns: min(16rem, 50%) minmax(0, 1fr); }
8781
+ }
8782
+
8674
8783
  @media (forced-colors: active) {
8675
8784
  .sw-description-item + .sw-description-item { border-top-color: CanvasText; }
8676
8785
  }
@@ -8723,6 +8832,13 @@ html:has(.sw-site-header-sticky) {
8723
8832
  color: var(--sw-color-accent);
8724
8833
  }
8725
8834
 
8835
+ /* A tab with a count: its label and the shared pill centred, a space-2 apart. */
8836
+ .sw-tab-counted {
8837
+ align-items: center;
8838
+ display: inline-flex;
8839
+ gap: var(--sw-space-2);
8840
+ }
8841
+
8726
8842
  .sw-tab-panel:focus-visible {
8727
8843
  outline: var(--sw-focus-ring-width) solid var(--sw-color-accent);
8728
8844
  outline-offset: var(--sw-focus-ring-offset);
@@ -8802,13 +8918,14 @@ html:has(.sw-site-header-sticky) {
8802
8918
  background: var(--sw-glass-fill);
8803
8919
  border: 1px solid var(--sw-color-border);
8804
8920
  border-radius: var(--sw-radius-pill);
8921
+ box-sizing: border-box;
8805
8922
  color: var(--sw-color-text);
8806
8923
  display: inline-flex;
8807
8924
  font-family: var(--sw-font-sans);
8808
8925
  font-size: 15px;
8809
8926
  gap: var(--sw-space-2);
8810
8927
  line-height: 20px;
8811
- min-height: var(--sw-control-md-min-height);
8928
+ min-height: var(--sw-filter-chip-min-height, var(--sw-control-md-min-height));
8812
8929
  min-width: 0;
8813
8930
  overflow-wrap: anywhere;
8814
8931
  padding: var(--sw-space-1) var(--sw-space-3);
@@ -8841,6 +8958,12 @@ html:has(.sw-site-header-sticky) {
8841
8958
  color: var(--sw-color-onAccent);
8842
8959
  }
8843
8960
 
8961
+ :where(.sw-filter-chips-selected-subtle) .sw-filter-chip-input:checked + .sw-filter-chip-face {
8962
+ background: var(--sw-color-accentSubtle);
8963
+ border-color: var(--sw-color-accent);
8964
+ color: color-mix(in srgb, var(--sw-color-accent) 70%, var(--sw-color-text));
8965
+ }
8966
+
8844
8967
  .sw-filter-chip-input:checked + .sw-filter-chip-face .sw-filter-chip-count {
8845
8968
  color: inherit;
8846
8969
  }
@@ -8991,6 +9114,14 @@ html:has(.sw-site-header-sticky) {
8991
9114
  .sw-grid-fit-narrow { grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); }
8992
9115
  .sw-grid-fit-medium { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16.25rem), 1fr)); }
8993
9116
  .sw-grid-fit-wide { grid-template-columns: repeat(auto-fit, minmax(min(100%, 18.75rem), 1fr)); }
9117
+ .sw-grid-rail-md { grid-template-columns: minmax(0, 1fr); }
9118
+ @media (min-width: 48rem) {
9119
+ .sw-grid-rail-md { grid-template-columns: minmax(0, 1fr) 20rem; }
9120
+ }
9121
+ .sw-grid-rail-lg { grid-template-columns: minmax(0, 1fr); }
9122
+ @media (min-width: 64rem) {
9123
+ .sw-grid-rail-lg { grid-template-columns: minmax(0, 1fr) 20rem; }
9124
+ }
8994
9125
  .sw-grid-span-1 { grid-column: span 1; }
8995
9126
  .sw-grid-span-2 { grid-column: span 2; }
8996
9127
  .sw-grid-span-3 { grid-column: span 3; }
@@ -9018,6 +9149,14 @@ html:has(.sw-site-header-sticky) {
9018
9149
  :where(.sw-grid-fit-wide) > .sw-grid-span-3 { grid-column: auto; }
9019
9150
  :where(.sw-grid-fit-wide) > .sw-grid-span-4 { grid-column: auto; }
9020
9151
  :where(.sw-grid-fit-wide) > .sw-grid-span-6 { grid-column: auto; }
9152
+ :where(.sw-grid-rail-md) > .sw-grid-span-2 { grid-column: auto; }
9153
+ :where(.sw-grid-rail-md) > .sw-grid-span-3 { grid-column: auto; }
9154
+ :where(.sw-grid-rail-md) > .sw-grid-span-4 { grid-column: auto; }
9155
+ :where(.sw-grid-rail-md) > .sw-grid-span-6 { grid-column: auto; }
9156
+ :where(.sw-grid-rail-lg) > .sw-grid-span-2 { grid-column: auto; }
9157
+ :where(.sw-grid-rail-lg) > .sw-grid-span-3 { grid-column: auto; }
9158
+ :where(.sw-grid-rail-lg) > .sw-grid-span-4 { grid-column: auto; }
9159
+ :where(.sw-grid-rail-lg) > .sw-grid-span-6 { grid-column: auto; }
9021
9160
  @media not all and (min-width: 48rem) {
9022
9161
  :where(.sw-grid-cols-below-md-1) > .sw-grid-span-2 { grid-column: span 1; }
9023
9162
  :where(.sw-grid-cols-below-md-1) > .sw-grid-span-3 { grid-column: span 1; }
@@ -10787,6 +10926,46 @@ html:has(.sw-site-header-sticky) {
10787
10926
  .sw-border-dashed { border: 1px dashed var(--sw-color-border); }
10788
10927
  .sw-border-bottom { border-width: 0 0 1px; border-style: solid; border-color: var(--sw-color-border); }
10789
10928
 
10929
+ @media (pointer: fine) {
10930
+ [data-theme][data-density='compact'] {
10931
+ --sw-control-xs-min-height: 24px;
10932
+ --sw-control-xs-padding-inline: 8px;
10933
+ --sw-control-sm-min-height: 28px;
10934
+ --sw-control-sm-padding-inline: 10px;
10935
+ --sw-control-md-min-height: 36px;
10936
+ --sw-control-md-padding-inline: 14px;
10937
+ --sw-filter-chip-min-height: 32px;
10938
+ font-size: 15px;
10939
+ letter-spacing: -0.2px;
10940
+ line-height: 22px;
10941
+ }
10942
+
10943
+ [data-theme][data-density='compact'] :is(.sw-card, .sw-table, .sw-description-list) .sw-text-body {
10944
+ font-size: 15px;
10945
+ letter-spacing: -0.2px;
10946
+ line-height: 22px;
10947
+ }
10948
+
10949
+ [data-theme][data-density='compact'] :is(.sw-date-field-input, .sw-fixture-score-box, .sw-segmented-filled .sw-segmented-item, .sw-stepper-input, .sw-stepper-unit) {
10950
+ font-size: 15px;
10951
+ letter-spacing: -0.2px;
10952
+ line-height: 22px;
10953
+ }
10954
+
10955
+ [data-theme][data-density='compact'] .sw-table-bounded {
10956
+ --sw-table-row-line: 22px;
10957
+ }
10958
+
10959
+ [data-theme][data-density='compact'] .sw-card {
10960
+ border-radius: var(--sw-radius-md);
10961
+ }
10962
+
10963
+ [data-theme][data-density='compact'] .sw-app-shell-sidebar .sw-app-shell-count {
10964
+ inset-block-start: calc(-1 * var(--sw-space-1));
10965
+ inset-inline-end: calc(-1 * var(--sw-space-2));
10966
+ }
10967
+ }
10968
+
10790
10969
  @media (prefers-reduced-transparency: reduce) {
10791
10970
  .sw-card-glass,
10792
10971
  .sw-app-header,
@@ -1,6 +1,7 @@
1
1
  import { type ReactNode } from 'react';
2
2
  import { type ColorScheme, type PaletteId, type Theme, type ThemeColors } from '@scalewing/tokens';
3
3
  import { type ThemeCanvas } from '../css/css-canvas-grouped.js';
4
+ import { type ThemeDensity } from '../css/css-density.js';
4
5
  import { type ThemeFrame } from '../css/css-theme-frame.js';
5
6
  export type ThemeProviderProps = {
6
7
  colorScheme?: ColorScheme | 'system';
@@ -23,7 +24,18 @@ export type ThemeProviderProps = {
23
24
  * a `RangeError`.
24
25
  */
25
26
  frame?: ThemeFrame;
27
+ /**
28
+ * `comfortable` (default) draws today's touch-sized controls. `compact`
29
+ * (opt-in) is a desktop data tool's scale, on a fine pointer only (a touch
30
+ * screen keeps its 44 px targets): md controls 36 px high with 14 px side
31
+ * padding, sm 28/10, xs 24/8, FilterChips 32 px, Card corners at the md
32
+ * radius, and 15/22 reading text in a Card, a Table and a DescriptionList
33
+ * and for everything that inherits the root's type. It reaches everything
34
+ * inside: a ThemeProvider nested in a compact one is compact too. An
35
+ * unknown value throws a `RangeError`.
36
+ */
37
+ density?: ThemeDensity;
26
38
  children: ReactNode;
27
39
  };
28
- export declare function ThemeProvider({ colorScheme, palette, colors, canvas, frame, children, }: ThemeProviderProps): import("react").JSX.Element;
40
+ export declare function ThemeProvider({ colorScheme, palette, colors, canvas, frame, density, children, }: ThemeProviderProps): import("react").JSX.Element;
29
41
  export declare function useTheme(): Theme;
@@ -2,8 +2,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { createContext, useContext, useEffect, useMemo, useState, } from 'react';
3
3
  import { createTheme, secondaryActionBorder, semanticColorKeys, } from '@scalewing/tokens';
4
4
  import { assertThemeCanvas, } from '../css/css-canvas-grouped.js';
5
+ import { assertThemeDensity } from '../css/css-density.js';
5
6
  import { assertThemeFrame } from '../css/css-theme-frame.js';
6
7
  const ThemeContext = createContext(null);
8
+ /** The density of the ThemeProvider around this one. */
9
+ const DensityContext = createContext('comfortable');
7
10
  function schemeFromMedia() {
8
11
  if (typeof window === 'undefined' ||
9
12
  typeof window.matchMedia !== 'function') {
@@ -26,9 +29,11 @@ function themeCssVars(theme) {
26
29
  vars['--sw-glass-specular'] = theme.glass.specular;
27
30
  return vars;
28
31
  }
29
- export function ThemeProvider({ colorScheme = 'system', palette, colors, canvas = 'default', frame = 'none', children, }) {
32
+ export function ThemeProvider({ colorScheme = 'system', palette, colors, canvas = 'default', frame = 'none', density = 'comfortable', children, }) {
30
33
  assertThemeCanvas(canvas);
31
34
  assertThemeFrame(frame);
35
+ assertThemeDensity(density);
36
+ const resolvedDensity = useContext(DensityContext) === 'compact' ? 'compact' : density;
32
37
  const [systemScheme, setSystemScheme] = useState(schemeFromMedia);
33
38
  useEffect(() => {
34
39
  if (colorScheme !== 'system' || typeof window.matchMedia !== 'function') {
@@ -44,7 +49,7 @@ export function ThemeProvider({ colorScheme = 'system', palette, colors, canvas
44
49
  }, [colorScheme]);
45
50
  const resolvedScheme = colorScheme === 'system' ? systemScheme : colorScheme;
46
51
  const theme = useMemo(() => createTheme({ colorScheme: resolvedScheme, palette, colors }), [colors, palette, resolvedScheme]);
47
- return (_jsx(ThemeContext.Provider, { value: theme, children: _jsx("div", { "data-canvas": canvas === 'default' ? undefined : canvas, "data-frame": frame === 'none' ? undefined : frame, "data-palette": palette, "data-theme": theme.colorScheme, style: themeCssVars(theme), children: children }) }));
52
+ return (_jsx(ThemeContext.Provider, { value: theme, children: _jsx(DensityContext.Provider, { value: resolvedDensity, children: _jsx("div", { "data-canvas": canvas === 'default' ? undefined : canvas, "data-density": resolvedDensity === 'compact' ? 'compact' : undefined, "data-frame": frame === 'none' ? undefined : frame, "data-palette": palette, "data-theme": theme.colorScheme, style: themeCssVars(theme), children: children }) }) }));
48
53
  }
49
54
  export function useTheme() {
50
55
  const theme = useContext(ThemeContext);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalewing/react",
3
- "version": "1.60.0",
3
+ "version": "1.61.0",
4
4
  "description": "Scalewing DOM components and package-owned CSS utilities.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  "dependencies": {
46
46
  "markdown-it": "14.3.2",
47
47
  "pdfjs-dist": "6.4.299",
48
- "@scalewing/tokens": "^1.7.0"
48
+ "@scalewing/tokens": "^1.8.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "react": "^19.0.0",