@ricsam/react-spreadsheets 0.0.3 → 0.0.5

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/react-spreadsheets",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "type": "module"
5
5
  }
package/dist/styles.css CHANGED
@@ -16,12 +16,8 @@
16
16
  * ---------------------------------------------------------------------------
17
17
  * Light / dark
18
18
  * ---------------------------------------------------------------------------
19
- * Colors resolve through `light-dark()`, which follows the inherited
20
- * `color-scheme`. The grid deliberately does NOT declare `color-scheme` on
21
- * `.rsp-root`, because doing so would override a `color-scheme` pin set by an
22
- * ancestor and de-sync the grid from the surrounding page.
23
- *
24
- * To pin a subtree, set `color-scheme` on any ancestor (or on `.rsp-root`):
19
+ * By default the grid follows the user's OS preference. To pin a subtree, set
20
+ * `color-scheme` on the grid root or on any ancestor:
25
21
  *
26
22
  * .workbook-stage { color-scheme: light; } // always light
27
23
  * .workbook-stage { color-scheme: dark; } // always dark
@@ -30,26 +26,96 @@
30
26
  *
31
27
  * <FormulaWorkbook className="rsp-theme-light" />
32
28
  * <FormulaWorkbook className="rsp-theme-dark" />
29
+ *
30
+ * Implementation note — why not `light-dark()`?
31
+ * ---------------------------------------------------------------------------
32
+ * `light-dark()` would be the natural choice, but bundlers that target
33
+ * browsers without native support (Vite's Lightning CSS, for example) lower it
34
+ * to a pair of switch custom properties that are only emitted in rules which
35
+ * *also* declare `color-scheme`. Tokens declared once on a shared root then
36
+ * compute to an invalid value like `#ffffff #0f1523`, and every themed surface
37
+ * silently falls back to `transparent` / inherited text — a failure that only
38
+ * appears in a production build.
39
+ *
40
+ * Instead the same space-toggle trick is applied directly, using our own
41
+ * `--rsp-light` / `--rsp-dark` switches. Exactly one of the two is set to
42
+ * `initial` (making its `var()` fall back to the color) while the other is set
43
+ * to a single space (contributing nothing), so each token resolves to one
44
+ * color. This is plain custom-property substitution that no bundler rewrites,
45
+ * and it inherits, so an ancestor's pin still wins.
46
+ *
47
+ * A plain stylesheet cannot read an ancestor's `color-scheme`, so the component
48
+ * resolves it from the mounted element and reflects the result onto the grid
49
+ * root as `data-rsp-scheme`. That covers a pin declared in CSS, inline, or via
50
+ * the helper classes. The media query below is the pre-resolution default.
33
51
  */
34
52
 
53
+ /* Default: follow the OS preference. `.rsp-root` is included so the grid still
54
+ themes correctly when the stylesheet is loaded into a shadow root or another
55
+ tree where `:root` is not an ancestor. Only the two switches are repeated —
56
+ never the tokens themselves (see below). */
57
+ :root,
58
+ .rsp-root {
59
+ --rsp-light: initial;
60
+ --rsp-dark: ;
61
+ }
62
+
63
+ @media (prefers-color-scheme: dark) {
64
+ :root,
65
+ .rsp-root {
66
+ --rsp-light: ;
67
+ --rsp-dark: initial;
68
+ }
69
+ }
70
+
71
+ /* Resolved by the component from the inherited `color-scheme`, so a pin set in
72
+ CSS, inline, or via the helper classes below is all honoured. */
73
+ [data-rsp-scheme="light"] {
74
+ --rsp-light: initial;
75
+ --rsp-dark: ;
76
+ }
77
+
78
+ [data-rsp-scheme="dark"] {
79
+ --rsp-light: ;
80
+ --rsp-dark: initial;
81
+ }
82
+
83
+ /* Explicit opt-in pins. `color-scheme` is set too so native scrollbars and
84
+ form controls agree with the token switch. */
85
+ .rsp-theme-light {
86
+ color-scheme: light;
87
+ --rsp-light: initial;
88
+ --rsp-dark: ;
89
+ }
90
+
91
+ .rsp-theme-dark {
92
+ color-scheme: dark;
93
+ --rsp-light: ;
94
+ --rsp-dark: initial;
95
+ }
96
+
97
+ /* Tokens are declared ONLY on `:root`, so a consumer can override any of them
98
+ from any ancestor of the grid. Repeating this block on `.rsp-root` would let
99
+ the built-in defaults beat an ancestor's override, because `.rsp-root` is the
100
+ closer element. */
35
101
  :root {
36
102
  /* Surfaces */
37
- --rsp-bg: light-dark(#ffffff, #0f1523);
38
- --rsp-surface: light-dark(#ffffff, #151c2c);
39
- --rsp-header-bg: light-dark(#f7f8fa, #1a2233);
40
- --rsp-header-active-bg: light-dark(#e9edf5, #24304a);
41
- --rsp-corner-bg: light-dark(#eef1f6, #1a2233);
42
- --rsp-editor-bg: light-dark(#ffffff, #1a2233);
103
+ --rsp-bg: var(--rsp-light, #ffffff) var(--rsp-dark, #0f1523);
104
+ --rsp-surface: var(--rsp-light, #ffffff) var(--rsp-dark, #151c2c);
105
+ --rsp-header-bg: var(--rsp-light, #f7f8fa) var(--rsp-dark, #1a2233);
106
+ --rsp-header-active-bg: var(--rsp-light, #e9edf5) var(--rsp-dark, #24304a);
107
+ --rsp-corner-bg: var(--rsp-light, #eef1f6) var(--rsp-dark, #1a2233);
108
+ --rsp-editor-bg: var(--rsp-light, #ffffff) var(--rsp-dark, #1a2233);
43
109
 
44
110
  /* Lines */
45
- --rsp-border: light-dark(#e3e7ee, #2a3346);
46
- --rsp-corner-border: light-dark(#d7dce6, #2a3346);
47
- --rsp-gridline: light-dark(#e8ebf1, #232c3d);
111
+ --rsp-border: var(--rsp-light, #e3e7ee) var(--rsp-dark, #2a3346);
112
+ --rsp-corner-border: var(--rsp-light, #d7dce6) var(--rsp-dark, #2a3346);
113
+ --rsp-gridline: var(--rsp-light, #e8ebf1) var(--rsp-dark, #232c3d);
48
114
 
49
115
  /* Text */
50
- --rsp-text: light-dark(#101828, #e8ecf4);
51
- --rsp-header-text: light-dark(#5a6478, #99a4bb);
52
- --rsp-muted-text: light-dark(#6b7280, #8c97ad);
116
+ --rsp-text: var(--rsp-light, #101828) var(--rsp-dark, #e8ecf4);
117
+ --rsp-header-text: var(--rsp-light, #5a6478) var(--rsp-dark, #99a4bb);
118
+ --rsp-muted-text: var(--rsp-light, #6b7280) var(--rsp-dark, #8c97ad);
53
119
 
54
120
  /* Accent / selection.
55
121
  NOTE: `@ricsam/selection-manager` paints the selection *perimeter* as an
@@ -57,25 +123,25 @@
57
123
  The default accent stays in that blue family so the perimeter agrees with
58
124
  the rest of the chrome out of the box. Overriding `--rsp-accent` with a
59
125
  distant hue will make the perimeter read slightly differently. */
60
- --rsp-accent: light-dark(#2196f3, #58a6ff);
126
+ --rsp-accent: var(--rsp-light, #2196f3) var(--rsp-dark, #58a6ff);
61
127
  --rsp-accent-contrast: #ffffff;
62
- --rsp-selection-bg: light-dark(#e8f2fe, #17304f);
63
- --rsp-selection-range-bg: light-dark(#f1f7fe, #14263d);
64
- --rsp-hover-bg: light-dark(#f5f7fa, #1c2436);
65
- --rsp-focus-ring: light-dark(rgba(33, 150, 243, 0.22), rgba(88, 166, 255, 0.28));
128
+ --rsp-selection-bg: var(--rsp-light, #e8f2fe) var(--rsp-dark, #17304f);
129
+ --rsp-selection-range-bg: var(--rsp-light, #f1f7fe) var(--rsp-dark, #14263d);
130
+ --rsp-hover-bg: var(--rsp-light, #f5f7fa) var(--rsp-dark, #1c2436);
131
+ --rsp-focus-ring: var(--rsp-light, rgba(33, 150, 243, 0.22)) var(--rsp-dark, rgba(88, 166, 255, 0.28));
66
132
 
67
133
  /* Danger (delete buttons, invalid input) */
68
- --rsp-danger: light-dark(#d92d20, #ff8a80);
69
- --rsp-danger-bg: light-dark(#fef3f2, #3a1512);
134
+ --rsp-danger: var(--rsp-light, #d92d20) var(--rsp-dark, #ff8a80);
135
+ --rsp-danger-bg: var(--rsp-light, #fef3f2) var(--rsp-dark, #3a1512);
70
136
 
71
137
  /* Tables (consumed by the workbook's inline cell styles) */
72
- --rsp-table-header-bg: light-dark(#2196f3, #1c3a5e);
73
- --rsp-table-header-color: light-dark(#ffffff, #e8ecf4);
74
- --rsp-table-header-border: light-dark(#1877c9, #2a5384);
75
- --rsp-table-even-row-bg: light-dark(#f7f9fc, #161e2e);
76
- --rsp-table-odd-row-bg: light-dark(#ffffff, #131a28);
77
- --rsp-table-border-color: light-dark(#2196f3, #34405c);
78
- --rsp-table-border-light: light-dark(#dfe4ec, #2a3346);
138
+ --rsp-table-header-bg: var(--rsp-light, #2196f3) var(--rsp-dark, #1c3a5e);
139
+ --rsp-table-header-color: var(--rsp-light, #ffffff) var(--rsp-dark, #e8ecf4);
140
+ --rsp-table-header-border: var(--rsp-light, #1877c9) var(--rsp-dark, #2a5384);
141
+ --rsp-table-even-row-bg: var(--rsp-light, #f7f9fc) var(--rsp-dark, #161e2e);
142
+ --rsp-table-odd-row-bg: var(--rsp-light, #ffffff) var(--rsp-dark, #131a28);
143
+ --rsp-table-border-color: var(--rsp-light, #2196f3) var(--rsp-dark, #34405c);
144
+ --rsp-table-border-light: var(--rsp-light, #dfe4ec) var(--rsp-dark, #2a3346);
79
145
 
80
146
  /* Typography */
81
147
  --rsp-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
@@ -107,7 +173,8 @@
107
173
  }
108
174
 
109
175
  .rsp-root {
110
- /* No `color-scheme` here on purpose — see the file header. */
176
+ /* No `color-scheme` here on purpose: declaring it would override a pin set by
177
+ an ancestor. See the file header. */
111
178
  color: var(--rsp-text);
112
179
  font-family: var(--rsp-font-family);
113
180
  }
@@ -0,0 +1,16 @@
1
+ import { type ColorScheme } from "./use-color-scheme";
2
+ /**
3
+ * Props for a `.rsp-root` element so its light/dark tokens match the inherited
4
+ * `color-scheme`.
5
+ *
6
+ * A stylesheet cannot branch on an *ancestor's* `color-scheme`, and the
7
+ * `light-dark()` function is rewritten by some bundlers into switch variables
8
+ * that only exist next to a `color-scheme` declaration (see `styles.css`).
9
+ * Resolving the scheme from the mounted element and reflecting it as
10
+ * `data-rsp-scheme` keeps the tokens correct without the component declaring
11
+ * `color-scheme` itself, which would override a consumer's pin.
12
+ */
13
+ export declare function useSchemeRoot(): {
14
+ ref: (element: HTMLElement | null) => void;
15
+ "data-rsp-scheme": ColorScheme;
16
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/react-spreadsheets",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Headless-friendly React spreadsheet and workbook components: infinite virtualized grid, zoom, resizing, clipboard, fill handles and formula-engine bindings.",
5
5
  "type": "module",
6
6
  "module": "./dist/mjs/lib.mjs",