@epilot/volt-ui-experimental-griffel 0.2.3 → 0.3.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.
- package/ADOPTING.md +416 -0
- package/README.md +32 -31
- package/dist/_virtual/jsx-dev-runtime.js +5 -0
- package/dist/_virtual/jsx-dev-runtime.js.map +1 -0
- package/dist/_virtual/react-jsx-dev-runtime.development.js +5 -0
- package/dist/_virtual/react-jsx-dev-runtime.development.js.map +1 -0
- package/dist/_virtual/react-jsx-dev-runtime.production.js +5 -0
- package/dist/_virtual/react-jsx-dev-runtime.production.js.map +1 -0
- package/dist/components/accordion/accordion.js +126 -66
- package/dist/components/accordion/accordion.js.map +1 -1
- package/dist/components/alert-dialog/alert-dialog.js +239 -137
- package/dist/components/alert-dialog/alert-dialog.js.map +1 -1
- package/dist/components/avatar/avatar-group.js +102 -47
- package/dist/components/avatar/avatar-group.js.map +1 -1
- package/dist/components/avatar/avatar.js +97 -73
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/badge/badge.js +53 -37
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js +97 -49
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button.js +88 -77
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/button-group/button-group.js +55 -31
- package/dist/components/button-group/button-group.js.map +1 -1
- package/dist/components/callout/callout.js +288 -164
- package/dist/components/callout/callout.js.map +1 -1
- package/dist/components/card/card.js +137 -81
- package/dist/components/card/card.js.map +1 -1
- package/dist/components/checkbox/checkbox.js +100 -49
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/collapsible-sidebar/collapsible-sidebar.js +155 -107
- package/dist/components/collapsible-sidebar/collapsible-sidebar.js.map +1 -1
- package/dist/components/command/command.js +297 -158
- package/dist/components/command/command.js.map +1 -1
- package/dist/components/data-table/data-table-body.js +114 -54
- package/dist/components/data-table/data-table-body.js.map +1 -1
- package/dist/components/data-table/data-table-column-header.js +117 -45
- package/dist/components/data-table/data-table-column-header.js.map +1 -1
- package/dist/components/data-table/data-table-column-visibility.js +98 -39
- package/dist/components/data-table/data-table-column-visibility.js.map +1 -1
- package/dist/components/data-table/data-table-content.js +90 -58
- package/dist/components/data-table/data-table-content.js.map +1 -1
- package/dist/components/data-table/data-table-error.js +83 -39
- package/dist/components/data-table/data-table-error.js.map +1 -1
- package/dist/components/data-table/data-table-header.js +88 -54
- package/dist/components/data-table/data-table-header.js.map +1 -1
- package/dist/components/data-table/data-table-loading.js +27 -15
- package/dist/components/data-table/data-table-loading.js.map +1 -1
- package/dist/components/data-table/data-table-pagination.js +27 -19
- package/dist/components/data-table/data-table-pagination.js.map +1 -1
- package/dist/components/data-table/data-table-row.js +87 -64
- package/dist/components/data-table/data-table-row.js.map +1 -1
- package/dist/components/data-table/data-table-toolbar.js +24 -16
- package/dist/components/data-table/data-table-toolbar.js.map +1 -1
- package/dist/components/data-table/data-table.js +182 -145
- package/dist/components/data-table/data-table.js.map +1 -1
- package/dist/components/date-range-picker/date-range-picker.js +342 -214
- package/dist/components/date-range-picker/date-range-picker.js.map +1 -1
- package/dist/components/date-range-picker/range-calendar.js +132 -92
- package/dist/components/date-range-picker/range-calendar.js.map +1 -1
- package/dist/components/date-time-picker/calendar.js +501 -317
- package/dist/components/date-time-picker/calendar.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-context.js +64 -60
- package/dist/components/date-time-picker/date-time-picker-context.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-input.js +249 -149
- package/dist/components/date-time-picker/date-time-picker-input.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-panel.js +273 -165
- package/dist/components/date-time-picker/date-time-picker-panel.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker-popover.js +22 -14
- package/dist/components/date-time-picker/date-time-picker-popover.js.map +1 -1
- package/dist/components/date-time-picker/date-time-picker.js +134 -90
- package/dist/components/date-time-picker/date-time-picker.js.map +1 -1
- package/dist/components/date-time-picker/time-picker.js +198 -132
- package/dist/components/date-time-picker/time-picker.js.map +1 -1
- package/dist/components/density-provider/density-provider.js +48 -0
- package/dist/components/density-provider/density-provider.js.map +1 -0
- package/dist/components/dialog/dialog.js +280 -150
- package/dist/components/dialog/dialog.js.map +1 -1
- package/dist/components/drawer/drawer.js +273 -163
- package/dist/components/drawer/drawer.js.map +1 -1
- package/dist/components/dropdown-menu/dropdown-menu.js +378 -195
- package/dist/components/dropdown-menu/dropdown-menu.js.map +1 -1
- package/dist/components/field/field-combobox.js +447 -240
- package/dist/components/field/field-combobox.js.map +1 -1
- package/dist/components/field/field-select.js +23 -19
- package/dist/components/field/field-select.js.map +1 -1
- package/dist/components/field/field.js +318 -209
- package/dist/components/field/field.js.map +1 -1
- package/dist/components/label/label.js +27 -19
- package/dist/components/label/label.js.map +1 -1
- package/dist/components/list/list.js +623 -369
- package/dist/components/list/list.js.map +1 -1
- package/dist/components/option-card/option-card.js +323 -159
- package/dist/components/option-card/option-card.js.map +1 -1
- package/dist/components/pill/pill.js +82 -64
- package/dist/components/pill/pill.js.map +1 -1
- package/dist/components/popover/popover.js +101 -56
- package/dist/components/popover/popover.js.map +1 -1
- package/dist/components/radio/radio.js +94 -51
- package/dist/components/radio/radio.js.map +1 -1
- package/dist/components/scroll-overflow/scroll-overflow.js +350 -198
- package/dist/components/scroll-overflow/scroll-overflow.js.map +1 -1
- package/dist/components/segmented-control/segmented-control.js +141 -97
- package/dist/components/segmented-control/segmented-control.js.map +1 -1
- package/dist/components/select/select.js +452 -227
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/separator/separator.js +24 -16
- package/dist/components/separator/separator.js.map +1 -1
- package/dist/components/skeleton/skeleton.js +83 -43
- package/dist/components/skeleton/skeleton.js.map +1 -1
- package/dist/components/spinner/spinner.js +44 -20
- package/dist/components/spinner/spinner.js.map +1 -1
- package/dist/components/switch/switch.js +163 -86
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/table/table-pagination.js +465 -205
- package/dist/components/table/table-pagination.js.map +1 -1
- package/dist/components/table/table.js +212 -144
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/tabs/tabs.js +94 -58
- package/dist/components/tabs/tabs.js.map +1 -1
- package/dist/components/text/text.js +40 -32
- package/dist/components/text/text.js.map +1 -1
- package/dist/components/toast/toast.js +187 -111
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toggle/toggle-group.js +40 -24
- package/dist/components/toggle/toggle-group.js.map +1 -1
- package/dist/components/toggle/toggle.js +48 -40
- package/dist/components/toggle/toggle.js.map +1 -1
- package/dist/components/tooltip/tooltip.js +101 -55
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/index.d.ts +600 -427
- package/dist/index.js +215 -212
- package/dist/index.js.map +1 -1
- package/dist/lib/clear-button.js +27 -15
- package/dist/lib/clear-button.js.map +1 -1
- package/dist/lib/icons.js +18 -6
- package/dist/lib/icons.js.map +1 -1
- package/dist/packages/volt-runtime/dist/sheet.js +27 -10
- package/dist/packages/volt-runtime/dist/sheet.js.map +1 -1
- package/dist/packages/volt-runtime/dist/styles/recipe.js +76 -0
- package/dist/packages/volt-runtime/dist/styles/recipe.js.map +1 -0
- package/dist/styles/document-context.js +12 -0
- package/dist/styles/document-context.js.map +1 -0
- package/dist/styles/make-styles.js +18 -10
- package/dist/styles/make-styles.js.map +1 -1
- package/dist/tokens/core.generated.js +1238 -1166
- package/dist/tokens/core.generated.js.map +1 -1
- package/dist/tokens/index.d.ts +442 -415
- package/dist/tokens/index.js +1105 -1078
- package/dist/tokens/index.js.map +1 -1
- package/dist/tokens/install.js +9 -5
- package/dist/tokens/install.js.map +1 -1
- package/dist/tokens/use-palette-tokens.js +20 -0
- package/dist/tokens/use-palette-tokens.js.map +1 -0
- package/dist/tokens.json +83 -2
- package/dist/vendor/react/cjs/react-jsx-dev-runtime.development.js +236 -0
- package/dist/vendor/react/cjs/react-jsx-dev-runtime.development.js.map +1 -0
- package/dist/vendor/react/cjs/react-jsx-dev-runtime.production.js +21 -0
- package/dist/vendor/react/cjs/react-jsx-dev-runtime.production.js.map +1 -0
- package/dist/vendor/react/jsx-dev-runtime.js +9 -0
- package/dist/vendor/react/jsx-dev-runtime.js.map +1 -0
- package/package.json +13 -5
- package/scripts/migration-diagnostics-core.mjs +859 -0
- package/scripts/migration-diagnostics.mjs +353 -0
- package/scripts/migration-sweep.mjs +179 -0
- package/AGENTS.md +0 -153
- package/AUTHORING.md +0 -292
- package/dist/packages/volt-runtime/dist/styles/make-styles.js +0 -22
- package/dist/packages/volt-runtime/dist/styles/make-styles.js.map +0 -1
package/ADOPTING.md
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
# Putting a micro-frontend on this package
|
|
2
|
+
|
|
3
|
+
For an agent doing the work in a **consumer repo**. `AGENTS.md` and `AUTHORING.md` govern files
|
|
4
|
+
inside this package and do not apply to you; the README is the reference for individual APIs. This
|
|
5
|
+
file is the procedure, and it exists because three pilot migrations — `variable-builder`,
|
|
6
|
+
`scheduler-capability`, `flows-sidebar` — each rediscovered the same traps at their own expense.
|
|
7
|
+
|
|
8
|
+
Every number below was measured on one of those three. Nothing here is inferred.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## The fast path
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
1 Toolchain: install, DO NOT externalize, prove an EMPTY tree builds. ← before any UI
|
|
16
|
+
2 Flag gate: parallel tree, flag off = byte-identical. Verify it turns ON.
|
|
17
|
+
3 Token layer: /tokens subpath, semantic families, read the treatment cell.
|
|
18
|
+
4 Components: five engine rules that fail silently.
|
|
19
|
+
5 Host cascade: the consumer's own CSS is the adversary, not this package.
|
|
20
|
+
6 Verify: typecheck, sweep, then a browser. In that order.
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Two things decide whether this takes a day or a week, and both are in steps 1 and 2. Do them first,
|
|
24
|
+
in full, and do not start writing UI until an empty tree builds and the flag demonstrably flips.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. Toolchain
|
|
29
|
+
|
|
30
|
+
**Bundled, not externalized.** The opposite of Volt UI v1. Never add this package to webpack
|
|
31
|
+
`externals` and never give it an import-map entry — it is an ordinary per-MFE dependency, and the
|
|
32
|
+
whole point of the architecture is that two MFEs can hold different versions. Externalizing it puts
|
|
33
|
+
you back on a shared singleton.
|
|
34
|
+
|
|
35
|
+
**`react/jsx-runtime` is the one to check.** String externals match the exact request, so `react`
|
|
36
|
+
being external does **not** cover `react/jsx-runtime`, which means it is bundled from local
|
|
37
|
+
`node_modules`. If your repo declares React 17 while the shell serves 18 — true in at least two
|
|
38
|
+
epilot MFEs — you are bundling 17's jsx factory against the host's 18. That works today (17's
|
|
39
|
+
factory produces `Symbol.for('react.element')` and reads the internals 18 still provides) and it is
|
|
40
|
+
what `origin/main` already ships in those repos, verified by building both and diffing the
|
|
41
|
+
`System.register` arrays. So it is pre-existing, not yours to fix, and worth a separate ticket
|
|
42
|
+
rather than a detour here.
|
|
43
|
+
|
|
44
|
+
**Tests.** Jest 26 and 27 ignore `exports`. Take the shipped preset:
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
const griffel = require("@epilot/volt-ui-experimental-griffel/testing/jest-preset.cjs")
|
|
48
|
+
module.exports = griffel.withGriffel(
|
|
49
|
+
{ preset: "ts-jest" },
|
|
50
|
+
{ alsoTransform: ["@xyflow"] }
|
|
51
|
+
)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
See the README's Testing section for why `withGriffel` replaces `transformIgnorePatterns` instead of
|
|
55
|
+
merging, and why there is no CommonJS build.
|
|
56
|
+
|
|
57
|
+
**Then stop and build.** `tsc`, lint, test and a production build must pass on a tree that contains
|
|
58
|
+
the dependency and no components. That run is what proves your TypeScript can parse the package's
|
|
59
|
+
declarations before you have written anything that would have to be rewritten. One pilot skipped it
|
|
60
|
+
and spent the afternoon on a resolution problem it mistook for a styling problem.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 2. The flag gate
|
|
65
|
+
|
|
66
|
+
**The shape.** A parallel tree behind a feature flag, with the legacy tree untouched, so flag-off is
|
|
67
|
+
byte-identical to today. All three pilots took this shape and none regretted it. It costs duplicated
|
|
68
|
+
logic — roughly 600 lines in the scheduler — which is the right trade while the flag is short-lived,
|
|
69
|
+
because the alternative is refactoring the renderer everyone currently depends on. Revisit if the
|
|
70
|
+
flag will live for months.
|
|
71
|
+
|
|
72
|
+
**Read the flag like this:**
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const enabled = useFeatureFlagEnabled("<mfe>-griffel") === true
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`=== true` matters: the hook returns `undefined` while PostHog resolves, and that must read as off
|
|
79
|
+
rather than flickering the new UI in and out. A missing flag is correctly off.
|
|
80
|
+
|
|
81
|
+
**The trap that cost the most time in this whole programme.** `useFeatureFlagEnabled` resolves its
|
|
82
|
+
client from `PostHogContext`. With no provider mounted, that context yields the MFE's **own bundled,
|
|
83
|
+
never-initialised** posthog-js instance — a different object from `window.posthog`. The hook then
|
|
84
|
+
never returns `true`, whatever you do to the flag. In the variable-builder this was verified from the
|
|
85
|
+
console: `window.posthog.isFeatureEnabled(flag)` was `true`, the override was persisted, the flag
|
|
86
|
+
count was 1, and the gated `React.lazy` chunk was still never fetched, across a reload.
|
|
87
|
+
|
|
88
|
+
So **prove the gate turns on before you build behind it.** Either mount the provider, or read
|
|
89
|
+
`window.posthog` directly in the gate, or force a constant during development — but whichever you
|
|
90
|
+
pick, watch the lazy chunk actually load in the network panel. A gate that cannot flip means every
|
|
91
|
+
line you write behind it is unexercised.
|
|
92
|
+
|
|
93
|
+
If you force a constant, that constant is item one on your pre-merge checklist. A `// REVERT BEFORE
|
|
94
|
+
MERGE` comment is not a mechanism; one pilot shipped exactly that comment to the end of a session.
|
|
95
|
+
|
|
96
|
+
**Lazy-load with exactly one dynamic import, and make it yours:**
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// Right: one module of your own, which reaches the package by static import.
|
|
100
|
+
const Tree = React.lazy(() => import("./components/mfe-griffel"))
|
|
101
|
+
|
|
102
|
+
// Wrong: a dynamic import of the barrel. Webpack cannot statically prove the property accesses on
|
|
103
|
+
// a namespace object, so tree-shaking is DISABLED for that module and the entire library lands in
|
|
104
|
+
// the chunk — @dnd-kit, @tanstack/table-core, sonner, cmdk, every unused component.
|
|
105
|
+
import("@epilot/volt-ui-experimental-griffel")
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
The scheduler measured that mistake at **846 KB**, falling to **29 KB** once the dynamic import
|
|
109
|
+
named one of its own modules. The build succeeds either way and nothing warns. Flag-off cost after
|
|
110
|
+
the fix: **5,227 bytes**, against 343,894 for an eager import.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 3. The token layer
|
|
115
|
+
|
|
116
|
+
**Import from the `/tokens` subpath, never the root `tokens` namespace.** A namespace object cannot
|
|
117
|
+
be tree-shaken. Measured on the sixteen bindings one real consumer needed: 9,138 bytes gzip through
|
|
118
|
+
the namespace, 207 through the subpath.
|
|
119
|
+
|
|
120
|
+
**Prefer the semantic intent families over the decorative ones.** Two sheets ship: core installs
|
|
121
|
+
itself on every use and carries `accent`, `gray`, `error`, `info`, `success`, `warning` and the whole
|
|
122
|
+
`sem*` layer; the fifteen decorative families (`blue`, `green`, `yellow`, `teal`, …) live in an
|
|
123
|
+
opt-in sheet. Name a decorative family without the sheet and you get a `var()` for a custom property
|
|
124
|
+
nothing declares: no throw, no warning, nothing painted. The scheduler's SCSS coloured every
|
|
125
|
+
schedule status from `--volt-blue-3`, `--volt-green-3` and `--volt-yellow-3`; ported literally, all
|
|
126
|
+
three status colours would have vanished silently.
|
|
127
|
+
|
|
128
|
+
The fix is almost never `ensurePaletteTokens()`. It is that status **is** semantic — pending is
|
|
129
|
+
`info`, triggered is `success`, a pending change is `warning` — and those are in core. Two of the
|
|
130
|
+
mappings are free:
|
|
131
|
+
|
|
132
|
+
| decorative | semantic | steps 3 and 6 |
|
|
133
|
+
| ---------- | --------- | ------------------------------------------------------------ |
|
|
134
|
+
| `blue` | `info` | byte-identical |
|
|
135
|
+
| `green` | `success` | byte-identical |
|
|
136
|
+
| `yellow` | `warning` | **not** identical — warning is amber, `#ffefd6` vs `#fffab8` |
|
|
137
|
+
|
|
138
|
+
If you genuinely need a decorative family, the package installs the sheet for you whenever a
|
|
139
|
+
`color`-prop component resolves to one. Call `ensurePaletteTokensFor(family)` yourself only if you
|
|
140
|
+
are building your own coloured component.
|
|
141
|
+
|
|
142
|
+
**Read the treatment cell before mapping roles.** Role names do not predict visual weight. In
|
|
143
|
+
`plain` — the `:root` default, which reproduces today's portal — an **Object paints nothing**:
|
|
144
|
+
`surfaceObject`, `borderObject` and `shadowObject` all resolve to transparent, while
|
|
145
|
+
`surfaceContainer` is white with a shadow. The scheduler mapped its visible card onto Object from
|
|
146
|
+
the role names, and every card would have disappeared with a clean typecheck, clean lint and a
|
|
147
|
+
successful build. Open `dist/tokens/core.generated.js` and read the cell, or read the role/treatment
|
|
148
|
+
table in the docs.
|
|
149
|
+
|
|
150
|
+
**Ink on a soft fill is `on-soft`, not step 11.** Step 11 is documented as the low-contrast text
|
|
151
|
+
step and is designed against steps 1–2. On step 3 — the natural fill for a tinted chip — it fails AA
|
|
152
|
+
in light mode: info 4.26, success 4.27, warning 3.99. `sem<Family>OnSoft` lands between 10.27 and
|
|
153
|
+
12.48 across every intent family in both modes.
|
|
154
|
+
|
|
155
|
+
**Focus rings are `semFocusRing`.** Not `accentA8`, which reads like the obvious choice and
|
|
156
|
+
composites to **2.36:1**, under the 3:1 that WCAG 2.1 SC 1.4.11 requires. Not `accent9` either: it
|
|
157
|
+
passes light at 6.29 and **fails dark at 2.92**. Only steps 11 and 12 clear the bar in both modes.
|
|
158
|
+
|
|
159
|
+
**Stamp treatments on `document.documentElement`.** Treatment blocks are bare attribute selectors,
|
|
160
|
+
so a stamp on your MFE root looks like it works — until a popover, select or tooltip portals to
|
|
161
|
+
`document.body`, leaves your subtree, and resolves against `:root` instead. See the README section.
|
|
162
|
+
|
|
163
|
+
**Density is `[data-density]`, CSS-only, opt-in, and partial today.** Stamp
|
|
164
|
+
`[data-density="compact"|"normal"|"comfortable"]` on `document.documentElement` (or any subtree
|
|
165
|
+
ancestor) and `Button` (`base`/`icon` sizes), `Field` (root padding, `FieldSet` gap, and
|
|
166
|
+
`FieldInput` height), `List`/`ListItemIndex`, and `Select` (`SelectItem`, `SelectContent` — see
|
|
167
|
+
below) pick it up through ordinary CSS custom-property inheritance — no provider, no
|
|
168
|
+
context, no JS density state to wire up, and an absent/invalid attribute is transparent (inherits
|
|
169
|
+
an ancestor, or falls back to `normal` at the root). `Button[size="base"]`'s compact tier keeps the
|
|
170
|
+
same 32px height as normal — the density lever there is horizontal padding, since a fixed
|
|
171
|
+
line-height plus fixed vertical padding already floors the box at 32px; only comfortable grows it,
|
|
172
|
+
the same way `lg` already does with an explicit `minHeight`. `Button`'s `xs`/`sm`/`lg`/`icon-xs`/
|
|
173
|
+
`icon-sm`/`icon-lg` sizes, `FieldLabel` (fixed 16px at every tier), standalone `SelectTrigger`
|
|
174
|
+
(Field-wrapped or not — a `SelectTrigger` inside a `Field` inherits the Field wrapper's now-bound
|
|
175
|
+
padding, never its own height), `FieldComboboxInput` (`field-combobox.tsx` has its own separate
|
|
176
|
+
`makeVoltStyles` call and its own unrelated `input` key with no height — this binding does not
|
|
177
|
+
reach it), and every other component do **not** respond yet — density binding lands
|
|
178
|
+
component-by-component; check `DENSITY-SPEC.md`'s matrix (§2) before assuming a given slot moves.
|
|
179
|
+
`Table`/`DataTable` (`TableHead`'s height, `TableCell`'s vertical padding) are density-bound the
|
|
180
|
+
same way as of TABLE-DENSITY-IMPLEMENTATION.md (2026-09-09) — see the dedicated paragraph below for
|
|
181
|
+
the migration this required.
|
|
182
|
+
|
|
183
|
+
**`List` is CSS-bound too, with two things worth knowing.** `ListItem`/`ListItemIndex` (min-height,
|
|
184
|
+
padding, gap, index min-width, index horizontal padding) inherit from `[data-density]` exactly like
|
|
185
|
+
Button/Field — omitted `density` writes no attribute at all (ambient CSS only); an explicit value
|
|
186
|
+
(including `"relaxed"`) stamps a canonical `data-density` boundary. `"relaxed"` is a **permanent**
|
|
187
|
+
alias for `"normal"` geometry — identical numbers, forever — but its **DOM representation** is
|
|
188
|
+
normalized to `data-density="normal"`, not the literal string `"relaxed"`: the generator's three
|
|
189
|
+
selector blocks only ever match `"compact"`/`"normal"`/`"comfortable"`, so a raw `"relaxed"`
|
|
190
|
+
attribute would match none of them. Read the attribute back with `getAttribute("data-density")` if
|
|
191
|
+
you need it, not the `density` prop value you passed. `List`'s `DragOverlay` (dnd-kit) is an
|
|
192
|
+
ordinary DOM sibling of the `<ol>`, not a portal (confirmed from the installed
|
|
193
|
+
`@dnd-kit/core` source) — an explicit `density` re-asserts the same canonical boundary directly on
|
|
194
|
+
the dragged row's overlay clone; an omitted one inherits ambient CSS through the page's real DOM
|
|
195
|
+
ancestors with no stamp at all, same rule as everywhere else. `ListGroupLabel`'s collapsible
|
|
196
|
+
trigger shares `ListItem`'s bound geometry; its standalone (non-collapsible) variant is unrelated,
|
|
197
|
+
unbound, unchanged.
|
|
198
|
+
|
|
199
|
+
**A raw `data-density` attribute spread directly onto `<ol>` still wins over the `density` prop —
|
|
200
|
+
same JSX spread order as always — but what that precedence now controls is new.** Before this
|
|
201
|
+
binding, an attribute the caller spread onto `<ol>` was decorative: nothing in the CSS read it, so
|
|
202
|
+
whichever one "won" was inert either way. Now it drives real geometry, so the same unchanged
|
|
203
|
+
precedence rule has a real, visible consequence for the first time. It is also **narrower than it
|
|
204
|
+
looks**: a raw attribute set only on the `<ol>` does not propagate to the sibling `DragOverlay` —
|
|
205
|
+
the overlay clone reads only the `density` **prop**, never a raw attribute a caller set by hand on
|
|
206
|
+
the list element. A caller who needs the dragged row's overlay to match a manually-overridden `<ol>`
|
|
207
|
+
should use the `density` prop (or an ancestor `[data-density]` boundary) instead of a raw
|
|
208
|
+
attribute — this gap is not closed in this pass, only documented.
|
|
209
|
+
|
|
210
|
+
**`DensityProvider` is the explicit-override mechanism DENSITY-SPEC.md §4.4 specifies — reach for
|
|
211
|
+
it only when the ambient CSS path above isn't enough.** Most callers never need it: an `<html
|
|
212
|
+
data-density="compact">` (or any DOM ancestor `[data-density]`) already reaches every non-portalled
|
|
213
|
+
element, and every portal-content component listed below, through ordinary CSS custom-property
|
|
214
|
+
inheritance — no JavaScript, no import. `DensityProvider` exists for the one case that mechanism
|
|
215
|
+
cannot cover: forcing a density onto content a Radix `Portal` moves to `document.body` (or a custom
|
|
216
|
+
`container`), which is a DOM **sibling** of wherever it was written in JSX, not a descendant of any
|
|
217
|
+
ancestor `[data-density]` boundary there. `<DensityProvider density="compact">` sets a real DOM
|
|
218
|
+
`data-density` boundary (for its non-portalled descendants) **and** a React context value (read via
|
|
219
|
+
`useDensity()`, `undefined` with no ancestor `DensityProvider` — never a JS reading of ambient CSS)
|
|
220
|
+
in one component, so a portal-content component nested anywhere inside it — even many React levels
|
|
221
|
+
deep, even past other portals — can re-stamp itself correctly. Ordinary `<div>` semantics: forwards
|
|
222
|
+
`ref`/`className`/`style`/every other div prop, no `asChild`, no new polymorphic API. Runtime input
|
|
223
|
+
outside `"compact"|"normal"|"comfortable"` normalizes to `"normal"`, matching the CSS fallback rule
|
|
224
|
+
above.
|
|
225
|
+
|
|
226
|
+
**Portal-content components stamp `data-density` themselves, from `useDensity()`, only when an
|
|
227
|
+
explicit override exists.** `DialogContent`, `AlertDialogContent`, `DrawerContent`,
|
|
228
|
+
`DropdownMenuContent`, `DropdownMenuSubContent`, `PopoverContent`, `SelectContent`, and
|
|
229
|
+
`TooltipContent` each read `useDensity()` at their own portal root and spread `data-density` only
|
|
230
|
+
when it is defined — omitted, they stamp nothing and inherit the ambient shell value through the
|
|
231
|
+
real DOM tree (the portal container is still a descendant of `<html>`), exactly `List`'s
|
|
232
|
+
`DragOverlay` rule extended to eight more components. A `Select` rendered inside a `Popover`'s
|
|
233
|
+
content (or a `Dialog`'s, or nested inside a `DropdownMenu`) is proof this works even through
|
|
234
|
+
**two** independent portals stacked in the React tree: both `PopoverContent`/`DialogContent` and
|
|
235
|
+
the nested `SelectContent` read the *same* `DensityProvider` context value and stamp it
|
|
236
|
+
independently, even though `SelectContent` is a DOM **sibling** of `PopoverContent`, not its
|
|
237
|
+
descendant — real-Chromium-verified in `vr/density-provider-portal-interaction.test.ts`.
|
|
238
|
+
`table-pagination.tsx`'s inline `SelectPrimitive.Portal`-based page-size menu (still built directly
|
|
239
|
+
from raw Radix primitives, not the shared `select.tsx` component) now reads `useDensity()` and
|
|
240
|
+
stamps `data-density` the same way as the eight components above — the gap this paragraph used to
|
|
241
|
+
describe is closed; see the dedicated paragraph below.
|
|
242
|
+
|
|
243
|
+
**`Table`/`DataTable` density (TABLE-DENSITY-IMPLEMENTATION.md, 2026-09-09) — resolves the
|
|
244
|
+
compatibility question `TABLE-LIST-DENSITY-COMPATIBILITY-NOTE.md` (density/'s own worktree) left
|
|
245
|
+
open, by user-approved decision: direct `TableDensityContext.Provider` consumers are no longer a
|
|
246
|
+
supported way to control geometry.** `TableHead`'s height and `TableCell`'s vertical padding now
|
|
247
|
+
read `tokens.tableHeadHeight`/`tokens.tableCellPaddingY` directly — the same `[data-density]`
|
|
248
|
+
CSS-cascade mechanism as everywhere else, not a JS class switch. `Table`'s and `DataTable`'s own
|
|
249
|
+
`density` prop is genuinely optional now (no more `= "normal"` default): omitted, no `data-density`
|
|
250
|
+
is stamped and ambient shell/`DensityProvider` density inherits through ordinary DOM/CSS; explicit —
|
|
251
|
+
including explicit `"normal"` under a non-normal ambient — always stamps its own value on the
|
|
252
|
+
`<table>`/root element, resetting the subtree. `TableHead`/`TableCell`'s own `density` prop works
|
|
253
|
+
the same way, stamped directly on that `<th>`/`<td>`, overriding locally; a nested, density-omitted
|
|
254
|
+
`<Table>` (e.g. inside a custom `DataTable` cell renderer) inherits its nearest real `[data-density]`
|
|
255
|
+
boundary exactly like any other nested content. A raw caller `data-density` attribute can never
|
|
256
|
+
override the normalized `density` prop, on `Table`, `DataTable`, `TableHead` or `TableCell` alike.
|
|
257
|
+
`table-pagination.tsx`'s portal calls `useDensity()` and stamps its own override the same way as the
|
|
258
|
+
other eight portal-content components, reading whatever explicit density the nearest `Table`/
|
|
259
|
+
`DataTable` ancestor established (via an internal, non-public context-only boundary — `Table` can't
|
|
260
|
+
use `DensityProvider` itself, since its wrapping `<div>` cannot be injected inside `<table>` markup).
|
|
261
|
+
`TableDensityContext` is still exported (its type and default are unchanged, so nothing to migrate
|
|
262
|
+
at the type level) but is now a **deprecated, inert** compatibility export: `Table`/`DataTable` no
|
|
263
|
+
longer provide a value into it, `TableHead`/`TableCell` no longer read it, and wrapping anything in
|
|
264
|
+
a raw `<TableDensityContext.Provider>` no longer has any effect on rendered geometry. Migrate to the
|
|
265
|
+
`density` prop on `Table`/`DataTable`/`TableHead`/`TableCell`, or wrap a subtree in
|
|
266
|
+
`DensityProvider`. No real consumer of `TableDensityContext` was found in this package, the already-
|
|
267
|
+
in-scope My Account app, or root-config (checked read-only) — if one exists elsewhere, it needs its
|
|
268
|
+
own separate, bounded migration.
|
|
269
|
+
|
|
270
|
+
**`Select`'s density bindings — `SelectItem` and `SelectContent` only.** `SelectItem`'s vertical
|
|
271
|
+
padding (`select.item-padding-y`, 4/6/10px) and left padding (`select.item-padding-left`,
|
|
272
|
+
4/8/12px; right padding stays a fixed 32px at every tier — it reserves the check-indicator's
|
|
273
|
+
space) and `SelectContent`'s popup padding (`select.content-padding`, 4/8/12px) and gap
|
|
274
|
+
(`select.content-gap`, 2/4/6px) now inherit from `[data-density]`. `SelectTrigger` (standalone or
|
|
275
|
+
Field-wrapped) is **unchanged** — still intrinsic sizing at every tier, per `DENSITY-SPEC.md` §2.3;
|
|
276
|
+
this pass did not invent new trigger geometry. `SelectContent`'s slide-in animation offsets reuse
|
|
277
|
+
the same plain (non-density) primitive `SelectContent`'s padding used before this binding —
|
|
278
|
+
deliberately left alone, since they are not in the approved matrix.
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## 4. Components: the rules that fail silently
|
|
283
|
+
|
|
284
|
+
Every one of these has already cost this library a real bug, and none is caught by a build, a
|
|
285
|
+
typecheck or a passing test suite.
|
|
286
|
+
|
|
287
|
+
1. **`&` must be the first token of a selector.** `"[data-open] &"` compiles to
|
|
288
|
+
`.hash[data-open] .hash` and can never match. Fifteen dead declarations were live when a gate
|
|
289
|
+
first caught it. Drive ancestor state through props instead.
|
|
290
|
+
2. **Declaration order inside a slot is the precedence rule**, not specificity and not Tailwind's
|
|
291
|
+
ordering. Transcribing a v1 class order inverts results — 17% and 44% pixel diffs on Checkbox and
|
|
292
|
+
Radio. The state that must win goes **last**.
|
|
293
|
+
3. **No CSS shorthands.** `padding: "8px"` paints nothing and breaks atom dedup; Griffel only warns,
|
|
294
|
+
at runtime, in dev. Use the re-exported `shorthands` — `import { shorthands } from
|
|
295
|
+
"@epilot/volt-ui-experimental-griffel"`. Do not add a direct `@griffel/core` dependency: that is
|
|
296
|
+
a second engine copy in your graph.
|
|
297
|
+
4. **Animations use the object form**, `animationName: { from, to }`. Keyframe names are
|
|
298
|
+
content-hashed but not salted, so a hand-written global `@keyframes` collides silently between
|
|
299
|
+
co-resident copies.
|
|
300
|
+
5. **No reset ships.** `box-sizing: border-box` exists in the portal only because root-config
|
|
301
|
+
imports Tailwind's preflight. Set it on your own root **and** on descendants
|
|
302
|
+
(`"& *": { boxSizing: "border-box" }`). Note it cannot reach portalled package components, which
|
|
303
|
+
are exactly the ones with padded internals.
|
|
304
|
+
|
|
305
|
+
**A typecheck catches less of this than it looks.** Before 0.2.1 the declarations imported types
|
|
306
|
+
from a package consumers do not install, so every style object was silently `any`. That is fixed and
|
|
307
|
+
`GriffelStyle` is real now — but measured against a real consumer's config, it catches invalid
|
|
308
|
+
keyword **values** (`borderTopStyle: "wobbly"`) and little else. It cannot catch rule 3: csstype
|
|
309
|
+
considers `padding` a perfectly ordinary property, and the value type is `string | 0`, so
|
|
310
|
+
`width: 0` is legal by construction. So the two rules that fail silently at runtime are also the two
|
|
311
|
+
a typecheck will not save you from. Both pilots ended up writing a small static gate for exactly
|
|
312
|
+
these, and that is the right instinct.
|
|
313
|
+
|
|
314
|
+
Dev-only noise to ignore: one `classNameHashSalt` console error per `makeStyles` call site. It is a
|
|
315
|
+
false positive, documented in the README, absent in production.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## 5. The host cascade is the adversary
|
|
320
|
+
|
|
321
|
+
Nothing in this package can beat a consumer's own stylesheet, and this is where flag-gated
|
|
322
|
+
migrations actually break.
|
|
323
|
+
|
|
324
|
+
**An ID-scoped Tailwind preflight outranks every Griffel atom.** `#mfe-root button { … }` carries
|
|
325
|
+
specificity (1,0,1); a Griffel atom is (0,1,0). `:where()` and `@layer` both lose to a bare element
|
|
326
|
+
reset, and an ID-scoped one is stronger still. The variable-builder's `variable-builder.css` nested
|
|
327
|
+
`@tailwind base` under an ID selector; the fix was moving that import out of the shared router and
|
|
328
|
+
into the legacy page chunks, so it loads with the legacy tree and never on the new path. Two lines,
|
|
329
|
+
and flag-off is unchanged.
|
|
330
|
+
|
|
331
|
+
**Global `!important` blocks keep applying.** The scheduler's `root.module.scss` ends ~90 lines of
|
|
332
|
+
`!important` neutralising the portal's MUI globals, including a `:global([data-slot="popover-content"])`
|
|
333
|
+
block that hits every popover in the document. It does not stop applying because your subtree
|
|
334
|
+
changed. Two consequences: your new tree has to survive it without answering in kind, and a focus
|
|
335
|
+
ring built from `boxShadow` is **erased** by `box-shadow: none !important` — under `:focus-visible`
|
|
336
|
+
too, so keyboard users get no indicator at all. Use `outline` longhands; that reset does not touch
|
|
337
|
+
them. Measured at 6.44:1 after the fix.
|
|
338
|
+
|
|
339
|
+
**Verify the insertion anchor early.** Griffel's whole override model rests on its sheet being first
|
|
340
|
+
in `<head>`, and the portal injects a lot. Call `assertAnchorIsFirstInHead()` at runtime and expect
|
|
341
|
+
`{ ok: true }`. It held 10/10 rounds in the real portal for flows, but it is the highest-risk
|
|
342
|
+
unknown in any new host.
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
## 6. Verifying, in the order that pays
|
|
347
|
+
|
|
348
|
+
**Cheapest first, and know what each one cannot see.**
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
tsc + lint + build resolution, and invalid keyword values. Not shorthands, not `0`.
|
|
352
|
+
migration-sweep catches the three defects nothing else can. Seconds.
|
|
353
|
+
unit tests catch logic. They cannot see any of section 4.
|
|
354
|
+
a browser the only thing that can see sections 3, 4 and 5.
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
**Run the sweep against your new tree**, not the repo:
|
|
358
|
+
|
|
359
|
+
```sh
|
|
360
|
+
node node_modules/@epilot/volt-ui-experimental-griffel/scripts/migration-sweep.mjs \
|
|
361
|
+
src/components/<name>-griffel src/surface
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
It finds orphaned `volt-`-prefixed classes, `var(--volt-*)` reads and unloaded token sheets — three
|
|
365
|
+
things that all still _work today_ because v1's singleton is loaded at the portal root and is quietly
|
|
366
|
+
supplying what you forgot to bring. They fail on the day that singleton retires, in several MFEs at
|
|
367
|
+
once, with no error. All four earlier migrations shipped at least one. Pointed at a repo root during
|
|
368
|
+
a flag-gated migration it will also report the legacy tree, which is correct and useless — scope it.
|
|
369
|
+
|
|
370
|
+
**The suite is not your regression net.** The scheduler had **zero test files** with
|
|
371
|
+
`passWithNoTests: true`, so a green vitest run said nothing at all. Check what your suite actually
|
|
372
|
+
covers before citing it. A feature walkthrough of the old UI against the new one is what catches
|
|
373
|
+
regressions here.
|
|
374
|
+
|
|
375
|
+
**In the browser, check both flag states.** Flag off: the legacy tree renders, `document.head`
|
|
376
|
+
carries zero Griffel sheets, and the gated chunk is never requested. Flag on: the chunk loads, tokens
|
|
377
|
+
resolve to the treatment cell you expect, and portalled content is not painted in a different
|
|
378
|
+
treatment from the tree that opened it. Capture at 1280×720 at `deviceScaleFactor: 1`, the platform
|
|
379
|
+
minimum.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## What not to spend time on
|
|
384
|
+
|
|
385
|
+
- **Don't fix pre-existing bugs.** Establish the baseline first — error counts, warning counts, test
|
|
386
|
+
counts — and hold your change to "no worse". The scheduler recorded two pre-existing lint warnings
|
|
387
|
+
and left them; that is the right instinct.
|
|
388
|
+
- **Don't port a v1 defect faithfully when it makes something non-functional**, but do check which
|
|
389
|
+
v1 you are comparing against. The scheduler filed the time picker's missing column labels as a
|
|
390
|
+
package regression; v1 had in fact deleted them itself in June, and the repo's v1 was four minor
|
|
391
|
+
versions ahead of the copy that repo had installed (1.7.0 against 1.3.14). Read the version, not the vibe.
|
|
392
|
+
- **Don't migrate a table to `DataTable` because it exists.** For a two-to-four-row price-tier table
|
|
393
|
+
it adds a TanStack column model and a context provider to render what `<table>` renders. Both
|
|
394
|
+
pilots kept the hand-built one and recorded the choice.
|
|
395
|
+
- **Don't reach for `Card` inside a role recipe.** It is already an opinionated surface, so you get
|
|
396
|
+
two borders and two shadows. The role recipe _is_ the card.
|
|
397
|
+
- **Don't trust a delegated report.** Grep the artifact. Every claim in this file that survived came
|
|
398
|
+
from reading a built bundle, a computed style or a pixel; several that did not survive came from
|
|
399
|
+
reading source and sounding right.
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## Owe it back
|
|
404
|
+
|
|
405
|
+
Keep two files in your tree as you go, because both pilots found them worth more than the commit
|
|
406
|
+
messages:
|
|
407
|
+
|
|
408
|
+
- **`LIBRARY.md`** — what you had to declare locally because the grammar does not express it, with
|
|
409
|
+
the literal values, so promoting it later is a move rather than a rediscovery.
|
|
410
|
+
- **`DIVERGENCES.md`** — where you departed from the design, and why. A static mock has no data
|
|
411
|
+
model, no interaction states and no error states; the departures are the interesting part of the
|
|
412
|
+
work, not an embarrassment to bury.
|
|
413
|
+
|
|
414
|
+
Anything that reads as a package defect goes to the package, not into a local workaround that the
|
|
415
|
+
next MFE will write again. Every improvement in 0.2.1 through 0.2.3 came from a pilot doing exactly
|
|
416
|
+
that.
|
package/README.md
CHANGED
|
@@ -140,12 +140,6 @@ fails on the insertion-point count and `gate:class-salt-skew` fails on atom-name
|
|
|
140
140
|
`Collapsible` has no equivalent here, and neither does v1 — depend on `@radix-ui/react-collapsible`
|
|
141
141
|
directly, as both pilot MFEs do.
|
|
142
142
|
|
|
143
|
-
**Corrected in 0.2.2:** this section used to say `DataTable` was unported and "the only component
|
|
144
|
-
still missing". It has shipped since 0.2.0 — `DataTable`, `DataTableBody`, `DataTableContent`,
|
|
145
|
-
`DataTableHeader`, `DataTableLoading`, `DataTableError` and `TablePagination` are all exported. The
|
|
146
|
-
stale sentence cost real work: the Variable Builder read it and hand-built its list page on the
|
|
147
|
-
`Table` primitives.
|
|
148
|
-
|
|
149
143
|
There is no `--volt-*` compatibility layer. Consumer CSS reading v1's variable names by hand needs
|
|
150
144
|
migrating to this package's exported token bindings — 217 references across six MFEs, two thirds of
|
|
151
145
|
them in `entity`.
|
|
@@ -188,12 +182,10 @@ keeps its mode inside a dark page.
|
|
|
188
182
|
|
|
189
183
|
## Testing
|
|
190
184
|
|
|
191
|
-
The package is ESM-only
|
|
192
|
-
|
|
193
|
-
suite that had been green only because no test rendered one of these components yet. 0.2.2 adds a
|
|
194
|
-
`main` field, so those resolvers find `dist/index.js` themselves.
|
|
185
|
+
The package is ESM-only. Jest 26 and 27 ignore the `exports` field, so they resolve through `main`,
|
|
186
|
+
which points at the same ESM entry.
|
|
195
187
|
|
|
196
|
-
What they
|
|
188
|
+
What they need is a transform, because that file is ESM and Jest's default
|
|
197
189
|
`transformIgnorePatterns` skips everything under `node_modules`. Take it from here:
|
|
198
190
|
|
|
199
191
|
```js
|
|
@@ -226,26 +218,35 @@ Every check below has a `GATE_NEGATIVE_CONTROL` mode that has been demonstrated
|
|
|
226
218
|
property it checks breaks, and to trip only the checks it should. `bun run gates` runs them
|
|
227
219
|
fail-fast. A green gate is evidence for that gate's own assertions and nothing wider:
|
|
228
220
|
|
|
229
|
-
| check
|
|
230
|
-
|
|
|
231
|
-
| `bun run gate:vr`
|
|
232
|
-
| `bun run gate:isolation`
|
|
233
|
-
| `bun run gate:token-value-skew`
|
|
234
|
-
| `bun run gate:class-salt-skew`
|
|
235
|
-
| `bun run gate:cascade`
|
|
236
|
-
| `bun run gate:griffel-contract`
|
|
237
|
-
| `
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
`
|
|
241
|
-
that
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this file
|
|
221
|
+
| check | what it proves |
|
|
222
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
223
|
+
| `bun run gate:vr` | 270 specimens rendered under v1 and v2 and diffed pixel by pixel |
|
|
224
|
+
| `bun run gate:isolation` | two copies mount separately, emit no global selectors, share one insertion point and one renderer |
|
|
225
|
+
| `bun run gate:token-value-skew` | two builds differing only in token VALUES paint independently |
|
|
226
|
+
| `bun run gate:class-salt-skew` | two builds differing only in CLASS SALT keep disjoint atom names |
|
|
227
|
+
| `bun run gate:cascade` | a consumer utility can still override a component, in a real browser |
|
|
228
|
+
| `bun run gate:griffel-contract` | `insertionCache` still dedups, and every copy resolves the same renderer |
|
|
229
|
+
| `bun run gate:dts-self-contained` | the published declarations resolve with nothing installed but this package and React |
|
|
230
|
+
| `bunx vitest run` | 494 tests, plus 495 under React 18 |
|
|
231
|
+
|
|
232
|
+
`gate:one-bare-specifier` exists but is **not** in `bun run gates`, and fails on purpose: it asserts
|
|
233
|
+
that `dist` externalises the engine, and this release bundles it. Externalising is deferred, so the
|
|
234
|
+
gate returns to the aggregate on the day that lands.
|
|
235
|
+
|
|
236
|
+
**Migrating a micro-frontend onto this package? Read `ADOPTING.md` first.** It is the procedure,
|
|
237
|
+
ordered so nothing gets written twice, with each pitfall attached to the step where it bites. Three
|
|
238
|
+
pilot migrations paid for it separately.
|
|
239
|
+
|
|
240
|
+
`ADOPTING.md` ships beside this file and is the only other document a consumer needs.
|
|
241
|
+
|
|
242
|
+
The rest govern editing the package itself, so they stay in the repository rather than in your
|
|
243
|
+
`node_modules`, on branch
|
|
244
|
+
[`experiment/griffel`](https://gitlab.com/e-pilot/product/frontend/volt-ui/-/tree/experiment/griffel).
|
|
245
|
+
`AGENTS.md` is the normative rule set for changing a component and `AUTHORING.md` gives the defect
|
|
246
|
+
behind each rule; both are about authoring this package, which is why they are not in the tarball.
|
|
247
|
+
`DECISIONS.md` at the repository root holds the architecture rationale, and `STATUS.md` and
|
|
248
|
+
`MEASUREMENT.md` are dated snapshots of measurement and provenance — more current than this file on
|
|
249
|
+
numbers, never authoritative on rules.
|
|
249
250
|
|
|
250
251
|
## Releasing
|
|
251
252
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx-dev-runtime.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-jsx-dev-runtime.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react-jsx-dev-runtime.production.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|