chart-factory 0.1.2

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.
@@ -0,0 +1,107 @@
1
+ # Theming — the companion-theme contract
2
+
3
+ How to restyle chart-factory **from outside** — a theme is a stylesheet (plus,
4
+ optionally, a small SVG defs file), never a fork or a patch. The built-in dark
5
+ mode is one instance of this contract; external "companion themes" are the
6
+ general case. Reference implementation: a consumer app's *cardback* theme —
7
+ a vintage baseball-card look (warm stock, two-ink palette, halftone bar
8
+ fills, and a hand-drawn "sketch" variant) applied to an untouched dist
9
+ bundle.
10
+
11
+ A companion theme uses three hook points, in order of reach:
12
+
13
+ ## Hook 1 — token overrides + `setTheme()`
14
+
15
+ Builders resolve design tokens (CSS custom properties on `documentElement`)
16
+ at **render time** and stamp them into SVG attributes. A theme overrides
17
+ tokens under a `[data-theme="<name>"]` scope:
18
+
19
+ ```css
20
+ :root[data-theme="cardback"] {
21
+ --color-black: #243a5e; /* strongest ink, not literal black */
22
+ --color-bg-container: #f8f1dd; /* card stock */
23
+ --chart-primary: #243a5e;
24
+ --area-color-1: #243a5e; /* categorical series re-ink */
25
+ --font-family: 'Barlow Semi Condensed', sans-serif;
26
+ /* ... */
27
+ }
28
+ ```
29
+
30
+ and activates with one call:
31
+
32
+ ```js
33
+ ChartFactory.setTheme('cardback'); // sets <html data-theme>, rerenders all
34
+ ChartFactory.setTheme(null); // back to base tokens
35
+ ```
36
+
37
+ `setTheme()` is `rerenderAll()` plus the attribute flip and a
38
+ `d3t:themechange` event. Anything styled by `chart-factory.css` directly
39
+ (table chrome, tooltip shell, containers) re-themes instantly without the
40
+ rerender; only attribute-stamped values need it.
41
+
42
+ **The token surface** is `src/core/tokens.css` (chart tokens) and
43
+ `src/table/tokens.css` (table tokens). The `[data-theme="dark"]` blocks in
44
+ each are the working manifest of what a theme is expected to override —
45
+ color-bearing tokens only; spacing and sizing tokens carry over. Font tokens
46
+ (`--font-family`, `--font-size-*`) are theme-safe: text is re-measured on
47
+ rerender. That includes `--table-primary-font` — the key column's family;
48
+ column-width measurement resolves it, so a theme can retarget primary cells
49
+ (e.g. a condensed display face) without desyncing measured widths. Fonts a
50
+ theme applies through plain CSS rules instead of tokens are invisible to
51
+ measurement — always prefer the token.
52
+
53
+ ## Hook 2 — mark-class CSS (instant, no rerender)
54
+
55
+ Builders tag **marks** with stable classes — `bar`, `bar-fill`,
56
+ `bar-segment`, `line`, `area-fill`, `area-line`, `scatter-dot`, `dot`,
57
+ `slope-line`, `slope-dot`, `connector-line`, `grid-line`, `zero-line`,
58
+ `domain` — separately from **text** (`bar-value`, `bar-category`,
59
+ `axis-label`, `value-label`, `name-label`, …). Paint lands as presentation
60
+ *attributes*, and CSS rules beat presentation attributes, so a theme can
61
+ restyle marks with plain CSS — no `!important`, no rerender:
62
+
63
+ ```css
64
+ /* halftone texture on bars */
65
+ :root[data-theme="cardback"] svg rect.bar-fill {
66
+ fill: url(#cfb-halftone);
67
+ stroke: var(--cfb-ink);
68
+ stroke-width: 1.5;
69
+ }
70
+
71
+ /* hand-drawn wobble on marks only — text classes are never listed,
72
+ so type stays crisp */
73
+ :root[data-theme="cardback-sketch"] svg path.line,
74
+ :root[data-theme="cardback-sketch"] svg rect.bar-fill,
75
+ :root[data-theme="cardback-sketch"] svg circle.scatter-dot {
76
+ filter: url(#cfb-wobble);
77
+ }
78
+ ```
79
+
80
+ The mark/text class split is part of the public contract: renames are
81
+ breaking changes.
82
+
83
+ ## Hook 3 — defs injection + paint pass-through
84
+
85
+ Fill/stroke-bearing token values pass through **verbatim** — they are not
86
+ parsed or color-transformed — so `url(#pattern-id)` paint-server references
87
+ work anywhere a paint token or mark-class rule supplies paint (verified on
88
+ bars, area fills/lines, and line strokes). A theme may inject one hidden
89
+ `<svg><defs>` holding its patterns and filters:
90
+
91
+ - **Namespace your ids** (the cardback theme owns `cfb-*`); the factory
92
+ never generates ids matching `*-theme-*` or other themes' prefixes.
93
+ - Patterns may reference theme tokens (`stroke="var(--cfb-ink)"`), so
94
+ re-inking the theme re-inks its textures for free.
95
+
96
+ **The one hard caveat:** tokens that feed *interpolated* color scales —
97
+ `--temp-*`, `--scale-*`, sequential/diverging ramps — must remain real
98
+ colors. d3 interpolates them; a `url()` reference cannot be interpolated and
99
+ will produce garbage. Override paint tokens and text tokens freely; override
100
+ ramp tokens only with colors.
101
+
102
+ ## What stays application territory
103
+
104
+ Card frames, page chrome, headers, entity images (headshots/logos), and
105
+ layout belong to the consuming page, not to a theme and not to the factory —
106
+ same scope boundary as dashboards. A companion theme should style what the
107
+ factory draws and nothing else.