@hideyukimori/nene2-ui 0.8.0 → 0.11.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/README.md +55 -4
- package/dist/data/DataTable.js +1 -1
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/DetailList.js +1 -1
- package/dist/data/DetailList.js.map +1 -1
- package/dist/data/Pagination.js +1 -1
- package/dist/data/Pagination.js.map +1 -1
- package/dist/feedback/Badge.js +3 -3
- package/dist/feedback/Badge.js.map +1 -1
- package/dist/feedback/ToastProvider.js +2 -2
- package/dist/feedback/ToastProvider.js.map +1 -1
- package/dist/forms/FormField.js +1 -1
- package/dist/forms/FormField.js.map +1 -1
- package/dist/layout/Card.js +1 -1
- package/dist/layout/Card.js.map +1 -1
- package/dist/layout/PageHeader.js +1 -1
- package/dist/layout/PageHeader.js.map +1 -1
- package/dist/lib/states.d.ts +3 -3
- package/dist/lib/states.js +1 -1
- package/dist/lib/states.js.map +1 -1
- package/dist/overlay/Modal.js +1 -1
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/primitives/Button.js +16 -5
- package/dist/primitives/Button.js.map +1 -1
- package/dist/primitives/Checkbox.d.ts +21 -6
- package/dist/primitives/Checkbox.js +19 -9
- package/dist/primitives/Checkbox.js.map +1 -1
- package/dist/primitives/Input.js +1 -1
- package/dist/primitives/Input.js.map +1 -1
- package/dist/primitives/Radio.d.ts +20 -6
- package/dist/primitives/Radio.js +18 -9
- package/dist/primitives/Radio.js.map +1 -1
- package/dist/primitives/Select.js +1 -1
- package/dist/primitives/Select.js.map +1 -1
- package/dist/primitives/Spinner.js +1 -1
- package/dist/primitives/Spinner.js.map +1 -1
- package/dist/primitives/Switch.js +3 -1
- package/dist/primitives/Switch.js.map +1 -1
- package/dist/primitives/Text.js +1 -1
- package/dist/primitives/Text.js.map +1 -1
- package/dist/primitives/Textarea.js +1 -1
- package/dist/primitives/Textarea.js.map +1 -1
- package/dist/states/EmptyState.js +1 -1
- package/dist/states/EmptyState.js.map +1 -1
- package/dist/states/ErrorState.js +1 -1
- package/dist/states/ErrorState.js.map +1 -1
- package/package.json +1 -1
- package/themes/default.css +127 -0
package/README.md
CHANGED
|
@@ -193,11 +193,11 @@ into `0`, because 2px is a 2px error — but nene-records ships nine themes at 0
|
|
|
193
193
|
2–3px as separate product themes, so that error deletes a distinction rather than rounding
|
|
194
194
|
one.
|
|
195
195
|
|
|
196
|
-
| radius scale
|
|
197
|
-
|
|
|
198
|
-
| **the kit's nine + pill**
|
|
196
|
+
| radius scale | exact match | within 2px | designed values collapsed |
|
|
197
|
+
| ---------------------------- | ----------: | ---------: | ------------------------: |
|
|
198
|
+
| **the kit's nine + pill** | **69.9%** | **97.7%** | **3** (all 1px apart) |
|
|
199
199
|
| eight, without a `10px` step | 64.3% | 97.7% | 4 |
|
|
200
|
-
| seven, without `2px`
|
|
200
|
+
| seven, without `2px` | 43.2% | 97.7% | 4 |
|
|
201
201
|
|
|
202
202
|
🔑 **A scale is judged by what it can still tell apart, not only by how far it moves things.**
|
|
203
203
|
|
|
@@ -243,6 +243,38 @@ it can be checked with a regular expression exactly as written.
|
|
|
243
243
|
| `--color-*` | scale (palette) references | same |
|
|
244
244
|
| `--brightness-*` `--opacity-*` | literals are fine | **there is no scale to reference.** A hover darkening of 95% is not a step in a series; inventing a "brightness scale" so the rule could cover it would be a scale with one real user |
|
|
245
245
|
|
|
246
|
+
### 🔴 `className` lands on the root
|
|
247
|
+
|
|
248
|
+
Every component puts the caller's `className` on its **outermost** element. For `Checkbox`
|
|
249
|
+
and `Radio` that root is the `<label>`, not the `<input>` — use `inputClassName` to reach
|
|
250
|
+
the box itself.
|
|
251
|
+
|
|
252
|
+
Until 0.10.0 those two were the exception, and the exception was invisible: `className` was
|
|
253
|
+
accepted, applied, and landed somewhere the caller could not have wanted. Layout properties
|
|
254
|
+
— `self-start` in a flex row, a width, a margin — belong to the root, so a product had to
|
|
255
|
+
wrap every choice in a `<div>` to say them.
|
|
256
|
+
|
|
257
|
+
🔑 The kit had already answered a symptom of this in wave 2 (`cursor-pointer` belongs to the
|
|
258
|
+
label, so the kit carries it). That was right and it left the reason in place. **Fixing what
|
|
259
|
+
a report names is not the same as fixing what it is about.**
|
|
260
|
+
|
|
261
|
+
### 🔴 What a slot check must cover
|
|
262
|
+
|
|
263
|
+
The rule above — _every design value a component uses comes from a slot_ — was false in 26 of
|
|
264
|
+
28 components until 0.9.0, and the check meant to enforce it was green throughout. It listed
|
|
265
|
+
the utility prefixes it knew about (`p px py … rounded`), so **colour and weight were never
|
|
266
|
+
inspected**: 59 palette reaches across 20 files, plus four inline `font-medium`.
|
|
267
|
+
|
|
268
|
+
It surfaced when nene-vault compared its production screens against the migrated build in a
|
|
269
|
+
real browser — Playwright, computed styles, element by element (2026-08-23). 73 elements
|
|
270
|
+
matched and 21 differed, and **every difference was inside a kit component**; the product's
|
|
271
|
+
own markup matched on every property. A product cannot make its controls darker than its body
|
|
272
|
+
text while the component writes `text-text-primary` itself.
|
|
273
|
+
|
|
274
|
+
🔑 **A check written as an enumeration passes everything the enumeration omits.** So the
|
|
275
|
+
colour half of that check is not enumerated: it reads the palette out of the theme. A colour
|
|
276
|
+
added tomorrow is covered today.
|
|
277
|
+
|
|
246
278
|
🔴 **Check the three namespaces that have scales, not every slot.** Until 0.6.0 this section
|
|
247
279
|
said "and nothing else", while the kit's own theme held `--text-x-slot-field-label-size:
|
|
248
280
|
0.75rem` and `--brightness-x-slot-hover: 95%` — so a product implementing the rule as written
|
|
@@ -263,6 +295,25 @@ a missing component — open an issue, so every product gets the answer.
|
|
|
263
295
|
**Products: apply the same check to your own theme.** The kit can only police its own file;
|
|
264
296
|
the rule is the same one, and the regular expression above is the whole implementation.
|
|
265
297
|
|
|
298
|
+
## 🔴 Migrating a screen to the kit
|
|
299
|
+
|
|
300
|
+
**`<div>` → `<Stack>` is not a no-op.** The wrapper changes from block flow to flex, and
|
|
301
|
+
inline-level children — `Button`, `<label>`, `<span>` — change size because of it:
|
|
302
|
+
|
|
303
|
+
| what you see | why |
|
|
304
|
+
| -------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
305
|
+
| a button suddenly spans the row | `Stack` is `align-items: stretch`, so an inline-block child is stretched |
|
|
306
|
+
| a choice label goes from 112px wide to 582px | the same stretch |
|
|
307
|
+
| an icon becomes a tall rectangle | an `<svg>` with no width/height attribute has no intrinsic size and lays out at 300×150 |
|
|
308
|
+
|
|
309
|
+
The first two are flexbox working as specified; reach for `self-start` (which now lands on
|
|
310
|
+
the root — see above) or `items-start` on the `Stack`. The third was the kit's fault and is
|
|
311
|
+
bounded from 0.10.0, but only inside `Button` — **use `Icon` for artwork anywhere else**, or
|
|
312
|
+
give the `<svg>` a size of its own.
|
|
313
|
+
|
|
314
|
+
🔑 Three regressions in one migration, all from one wrapper swap, all of them visible only
|
|
315
|
+
on screen: **nothing in a diff says that a child used to be inline** (nene-vault, 2026-08-23).
|
|
316
|
+
|
|
266
317
|
## What is in scope
|
|
267
318
|
|
|
268
319
|
**In:** admin console and business-screen UI, page layout scaffolding, form field structure, the
|
package/dist/data/DataTable.js
CHANGED
|
@@ -12,6 +12,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
12
12
|
* page. It is visually hidden, not absent.
|
|
13
13
|
*/
|
|
14
14
|
export function DataTable({ columns, rows, rowKey, caption }) {
|
|
15
|
-
return (_jsxs("table", { className: "w-full border-collapse font-sans text-
|
|
15
|
+
return (_jsxs("table", { className: "w-full border-collapse font-sans text-x-slot-table-fg", children: [_jsx("caption", { className: "sr-only", children: caption }), _jsx("thead", { children: _jsx("tr", { children: columns.map((col) => (_jsx("th", { scope: "col", className: `border-b border-x-slot-table-border px-x-slot-table-cell-pad-x py-x-slot-table-cell-pad-y font-x-slot-table-header text-x-slot-table-header-fg ${col.align === 'end' ? 'text-right' : 'text-left'}`, children: col.header }, col.key))) }) }), _jsx("tbody", { children: rows.map((row) => (_jsx("tr", { children: columns.map((col) => (_jsx("td", { className: `border-b border-x-slot-table-border px-x-slot-table-cell-pad-x py-x-slot-table-cell-pad-y ${col.align === 'end' ? 'text-right' : 'text-left'}`, children: col.cell(row) }, col.key))) }, rowKey(row)))) })] }));
|
|
16
16
|
}
|
|
17
17
|
//# sourceMappingURL=DataTable.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../src/data/DataTable.tsx"],"names":[],"mappings":";AAsBA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAuB;IACpF,OAAO,CACL,iBAAO,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"DataTable.js","sourceRoot":"","sources":["../../src/data/DataTable.tsx"],"names":[],"mappings":";AAsBA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,SAAS,CAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAuB;IACpF,OAAO,CACL,iBAAO,SAAS,EAAC,uDAAuD,aACtE,kBAAS,SAAS,EAAC,SAAS,YAAE,OAAO,GAAW,EAChD,0BACE,uBACG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,aAEE,KAAK,EAAC,KAAK,EACX,SAAS,EAAE,kJACT,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WACvC,EAAE,YAED,GAAG,CAAC,MAAM,IANN,GAAG,CAAC,GAAG,CAOT,CACN,CAAC,GACC,GACC,EACR,0BACG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,uBACG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACpB,aAEE,SAAS,EAAE,6FACT,GAAG,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WACvC,EAAE,YAED,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IALT,GAAG,CAAC,GAAG,CAMT,CACN,CAAC,IAVK,MAAM,CAAC,GAAG,CAAC,CAWf,CACN,CAAC,GACI,IACF,CACT,CAAC;AACJ,CAAC"}
|
package/dist/data/DetailList.js
CHANGED
|
@@ -5,6 +5,6 @@ import { cx } from '../lib/cx.js';
|
|
|
5
5
|
* label/value relationship is conveyed to assistive technology.
|
|
6
6
|
*/
|
|
7
7
|
export function DetailList({ rows, className }) {
|
|
8
|
-
return (_jsx("dl", { className: cx('flex flex-col gap-x-slot-detail-gap', className), children: rows.map((row) => (_jsxs("div", { className: "flex flex-col gap-x-slot-detail-row-gap border-b border-border py-x-slot-detail-row-pad-y", children: [_jsx("dt", { className: "font-sans font-
|
|
8
|
+
return (_jsx("dl", { className: cx('flex flex-col gap-x-slot-detail-gap', className), children: rows.map((row) => (_jsxs("div", { className: "flex flex-col gap-x-slot-detail-row-gap border-b border-x-slot-detail-border py-x-slot-detail-row-pad-y", children: [_jsx("dt", { className: "font-sans font-x-slot-detail-term text-x-slot-detail-term-fg", children: row.label }), _jsx("dd", { className: "font-sans text-x-slot-detail-description-fg", children: row.value })] }, row.label))) }));
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=DetailList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DetailList.js","sourceRoot":"","sources":["../../src/data/DetailList.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAclC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAmB;IAC7D,OAAO,CACL,aAAI,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YAChE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,eAEE,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"DetailList.js","sourceRoot":"","sources":["../../src/data/DetailList.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAclC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,EAAmB;IAC7D,OAAO,CACL,aAAI,SAAS,EAAE,EAAE,CAAC,qCAAqC,EAAE,SAAS,CAAC,YAChE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,eAEE,SAAS,EAAC,yGAAyG,aAEnH,aAAI,SAAS,EAAC,8DAA8D,YACzE,GAAG,CAAC,KAAK,GACP,EACL,aAAI,SAAS,EAAC,6CAA6C,YAAE,GAAG,CAAC,KAAK,GAAM,KANvE,GAAG,CAAC,KAAK,CAOV,CACP,CAAC,GACC,CACN,CAAC;AACJ,CAAC"}
|
package/dist/data/Pagination.js
CHANGED
|
@@ -27,6 +27,6 @@ export function Pagination(props) {
|
|
|
27
27
|
const atEnd = props.page === undefined ? !props.canNext : props.page >= props.pageCount;
|
|
28
28
|
const goPrev = () => props.page === undefined ? props.onPrev() : props.onPageChange(props.page - 1);
|
|
29
29
|
const goNext = () => props.page === undefined ? props.onNext() : props.onPageChange(props.page + 1);
|
|
30
|
-
return (_jsx("nav", { "aria-label": label, children: _jsxs(Stack, { direction: "horizontal", gap: "2xs", align: "center", children: [_jsx(Button, { variant: "secondary", disabled: atStart, onClick: goPrev, "aria-label": previousLabel, children: previousLabel }), _jsx("span", { "aria-current": "page", className: "font-sans text-
|
|
30
|
+
return (_jsx("nav", { "aria-label": label, children: _jsxs(Stack, { direction: "horizontal", gap: "2xs", align: "center", children: [_jsx(Button, { variant: "secondary", disabled: atStart, onClick: goPrev, "aria-label": previousLabel, children: previousLabel }), _jsx("span", { "aria-current": "page", className: "font-sans text-x-slot-pagination-fg", children: status }), _jsx(Button, { variant: "secondary", disabled: atEnd, onClick: goNext, "aria-label": nextLabel, children: nextLabel })] }) }));
|
|
31
31
|
}
|
|
32
32
|
//# sourceMappingURL=Pagination.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../../src/data/Pagination.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAyC3C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE1D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC;IAExF,MAAM,MAAM,GAAG,GAAG,EAAE,CAClB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,GAAG,EAAE,CAClB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAEjF,OAAO,CACL,4BAAiB,KAAK,YACpB,MAAC,KAAK,IAAC,SAAS,EAAC,YAAY,EAAC,GAAG,EAAC,KAAK,EAAC,KAAK,EAAC,QAAQ,aACpD,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAc,aAAa,YACtF,aAAa,GACP,EACT,+BAAmB,MAAM,EAAC,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"Pagination.js","sourceRoot":"","sources":["../../src/data/Pagination.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAyC3C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE1D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,CAAC;IAExF,MAAM,MAAM,GAAG,GAAG,EAAE,CAClB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IACjF,MAAM,MAAM,GAAG,GAAG,EAAE,CAClB,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAEjF,OAAO,CACL,4BAAiB,KAAK,YACpB,MAAC,KAAK,IAAC,SAAS,EAAC,YAAY,EAAC,GAAG,EAAC,KAAK,EAAC,KAAK,EAAC,QAAQ,aACpD,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAc,aAAa,YACtF,aAAa,GACP,EACT,+BAAmB,MAAM,EAAC,SAAS,EAAC,qCAAqC,YACtE,MAAM,GACF,EACP,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAc,SAAS,YAChF,SAAS,GACH,IACH,GACJ,CACP,CAAC;AACJ,CAAC"}
|
package/dist/feedback/Badge.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
const TONE_CLASS = {
|
|
4
|
-
neutral: 'bg-
|
|
5
|
-
accent: 'bg-accent text-
|
|
6
|
-
danger: 'bg-danger text-
|
|
4
|
+
neutral: 'bg-x-slot-badge-neutral-bg text-x-slot-badge-neutral-fg border-x-slot-badge-neutral-border',
|
|
5
|
+
accent: 'bg-x-slot-badge-accent-bg text-x-slot-badge-accent-fg border-x-slot-badge-accent-border',
|
|
6
|
+
danger: 'bg-x-slot-badge-danger-bg text-x-slot-badge-danger-fg border-x-slot-badge-danger-border',
|
|
7
7
|
};
|
|
8
8
|
/**
|
|
9
9
|
* A small status marker.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../src/feedback/Badge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,MAAM,UAAU,GAAoD;IAClE,OAAO,
|
|
1
|
+
{"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../src/feedback/Badge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,MAAM,UAAU,GAAoD;IAClE,OAAO,EACL,4FAA4F;IAC9F,MAAM,EAAE,yFAAyF;IACjG,MAAM,EAAE,yFAAyF;CAClG,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAc;IAC9D,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,4GAA4G,EAC5G,UAAU,CAAC,IAAI,CAAC,CACjB,YAEA,QAAQ,GACJ,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -4,8 +4,8 @@ import { cx } from '../lib/cx.js';
|
|
|
4
4
|
import { CLICKABLE_CLASS } from '../lib/states.js';
|
|
5
5
|
import { ToastContext } from './toast-context.js';
|
|
6
6
|
const TONE_CLASS = {
|
|
7
|
-
info: 'bg-
|
|
8
|
-
danger: 'bg-
|
|
7
|
+
info: 'bg-x-slot-toast-bg text-x-slot-toast-fg border-x-slot-toast-border',
|
|
8
|
+
danger: 'bg-x-slot-toast-bg text-x-slot-toast-danger-fg border-x-slot-toast-danger-border',
|
|
9
9
|
};
|
|
10
10
|
/**
|
|
11
11
|
* Hosts the toast queue and the live regions that announce it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/feedback/ToastProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC1F,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAoD,MAAM,oBAAoB,CAAC;AAyBpG,MAAM,UAAU,GAA8B;IAC5C,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/feedback/ToastProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AAC1F,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAoD,MAAM,oBAAoB,CAAC;AAyBpG,MAAM,UAAU,GAA8B;IAC5C,IAAI,EAAE,oEAAoE;IAC1E,MAAM,EAAE,kFAAkF;CAC3F,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,WAAW,EACX,YAAY,EACZ,iBAAiB,GAAG,IAAI,EACxB,QAAQ,GACW;IACnB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAU,EAAE,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,EAAyC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAEzB,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,EAAU,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;IACrE,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,IAAI,GAAG,WAAW,CACtB,CAAC,OAAe,EAAE,OAAsB,EAAE,EAAE;QAC1C,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC;QAC5C,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC,CAAC;QACrF,MAAM,CAAC,OAAO,CAAC,GAAG,CAChB,EAAE,EACF,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,IAAI,iBAAiB,CAAC,CACxE,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC,EACD,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAC7B,CAAC;IAEF,kFAAkF;IAClF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAC/B,OAAO,GAAG,EAAE;YACV,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YAC1D,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,GAAG,GAAG,OAAO,CAAW,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAE1E,MAAM,MAAM,GAAG,CAAC,IAAe,EAAE,IAA4B,EAAE,EAAE,CAAC,CAChE,2BACa,IAAI,gBACH,WAAW,EACvB,IAAI,EAAC,QAAQ,EACb,SAAS,EAAC,oCAAoC,YAE7C,MAAM;aACJ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;aACtC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CACd,eAEE,SAAS,EAAE,EAAE,CACX,0GAA0G,EAC1G,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CACvB,aAED,yBAAO,KAAK,CAAC,OAAO,GAAQ,EAC5B,iBACE,IAAI,EAAC,QAAQ,gBACD,YAAY,EACxB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAChC,SAAS,EAAE,EAAE,CAAC,oDAAoD,EAAE,eAAe,CAAC,YAEnF,YAAY,GACN,KAdJ,KAAK,CAAC,EAAE,CAeT,CACP,CAAC,GACA,CACP,CAAC;IAEF,OAAO,CACL,MAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,GAAG,aAC9B,QAAQ,EACR,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACxB,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IACR,CACzB,CAAC;AACJ,CAAC"}
|
package/dist/forms/FormField.js
CHANGED
|
@@ -20,6 +20,6 @@ export function FormField({ id, label, error = null, hint, labelAdornment, requi
|
|
|
20
20
|
const errorId = error === null ? null : `${id}-error`;
|
|
21
21
|
const hintId = hint === undefined || hint === null ? null : `${id}-hint`;
|
|
22
22
|
const value = useMemo(() => ({ id, errorId, hintId, required }), [id, errorId, hintId, required]);
|
|
23
|
-
return (_jsx(FieldContext.Provider, { value: value, children: _jsxs("div", { className: "flex flex-col gap-x-slot-field-gap", children: [_jsxs("label", { htmlFor: id, className: "font-sans font-x-slot-field-label text-x-slot-field-label-size text-x-slot-field-label", children: [label, required && requiredMarker !== undefined && requiredMarker !== null ? (_jsx("span", { className: "text-
|
|
23
|
+
return (_jsx(FieldContext.Provider, { value: value, children: _jsxs("div", { className: "flex flex-col gap-x-slot-field-gap", children: [_jsxs("label", { htmlFor: id, className: "font-sans font-x-slot-field-label text-x-slot-field-label-size text-x-slot-field-label", children: [label, required && requiredMarker !== undefined && requiredMarker !== null ? (_jsx("span", { className: "text-x-slot-field-error-fg", children: requiredMarker })) : null, labelAdornment] }), children, hintId === null ? null : (_jsx("span", { id: hintId, className: "font-sans text-x-slot-field-hint-size text-x-slot-field-hint", children: hint })), errorId === null ? null : (_jsx("p", { id: errorId, role: "alert", className: "font-sans text-x-slot-field-error-size text-x-slot-field-error", children: error }))] }) }));
|
|
24
24
|
}
|
|
25
25
|
//# sourceMappingURL=FormField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormField.js","sourceRoot":"","sources":["../../src/forms/FormField.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAiClD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,EAAE,EACF,KAAK,EACL,KAAK,GAAG,IAAI,EACZ,IAAI,EACJ,cAAc,EACd,QAAQ,GAAG,KAAK,EAChB,cAAc,EACd,QAAQ,GACO;IACf,MAAM,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC;IACzE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAElG,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACjC,eAAK,SAAS,EAAC,oCAAoC,aACjD,iBACE,OAAO,EAAE,EAAE,EACX,SAAS,EAAC,wFAAwF,aAEjG,KAAK,EACL,QAAQ,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,CACrE,eAAM,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"FormField.js","sourceRoot":"","sources":["../../src/forms/FormField.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAkB,MAAM,OAAO,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAiClD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,EAAE,EACF,KAAK,EACL,KAAK,GAAG,IAAI,EACZ,IAAI,EACJ,cAAc,EACd,QAAQ,GAAG,KAAK,EAChB,cAAc,EACd,QAAQ,GACO;IACf,MAAM,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,QAAQ,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC;IACzE,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAElG,OAAO,CACL,KAAC,YAAY,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YACjC,eAAK,SAAS,EAAC,oCAAoC,aACjD,iBACE,OAAO,EAAE,EAAE,EACX,SAAS,EAAC,wFAAwF,aAEjG,KAAK,EACL,QAAQ,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,CACrE,eAAM,SAAS,EAAC,4BAA4B,YAAE,cAAc,GAAQ,CACrE,CAAC,CAAC,CAAC,IAAI,EACP,cAAc,IACT,EACP,QAAQ,EACR,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACxB,eACE,EAAE,EAAE,MAAM,EACV,SAAS,EAAC,8DAA8D,YAEvE,IAAI,GACA,CACR,EACA,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CACzB,YACE,EAAE,EAAE,OAAO,EACX,IAAI,EAAC,OAAO,EACZ,SAAS,EAAC,gEAAgE,YAEzE,KAAK,GACJ,CACL,IACG,GACgB,CACzB,CAAC;AACJ,CAAC"}
|
package/dist/layout/Card.js
CHANGED
|
@@ -8,6 +8,6 @@ import { GAP, PAD, resolve } from '../lib/spacing.js';
|
|
|
8
8
|
* given its own colour would be a `div` with extra steps.
|
|
9
9
|
*/
|
|
10
10
|
export function Card({ pad = 'sm', gap, raised = false, children, className, ...rest }) {
|
|
11
|
-
return (_jsx("div", { className: cx('flex flex-col bg-
|
|
11
|
+
return (_jsx("div", { className: cx('flex flex-col bg-x-slot-card-bg border border-x-slot-card-border rounded-x-slot-card', raised && 'shadow-sm', resolve(pad, PAD), resolve(gap, GAP), className), ...rest, children: children }));
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=Card.js.map
|
package/dist/layout/Card.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.js","sourceRoot":"","sources":["../../src/layout/Card.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAA+B,MAAM,mBAAmB,CAAC;AAUnF;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAa;IAC/F,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,
|
|
1
|
+
{"version":3,"file":"Card.js","sourceRoot":"","sources":["../../src/layout/Card.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAA+B,MAAM,mBAAmB,CAAC;AAUnF;;;;;GAKG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAa;IAC/F,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,sFAAsF,EACtF,MAAM,IAAI,WAAW,EACrB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EACjB,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EACjB,SAAS,CACV,KACG,IAAI,YAEP,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
export function PageHeader({ title, actions, className }) {
|
|
4
|
-
return (_jsxs("header", { className: cx('flex items-center justify-between py-x-slot-page-header-pad-y', className), children: [_jsx("h1", { className: "font-sans font-
|
|
4
|
+
return (_jsxs("header", { className: cx('flex items-center justify-between py-x-slot-page-header-pad-y', className), children: [_jsx("h1", { className: "font-sans font-x-slot-page-header text-x-slot-page-header-fg", children: title }), actions] }));
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=PageHeader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/layout/PageHeader.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAUlC,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAmB;IACvE,OAAO,CACL,kBACE,SAAS,EAAE,EAAE,CAAC,+DAA+D,EAAE,SAAS,CAAC,aAEzF,aAAI,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/layout/PageHeader.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAUlC,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAmB;IACvE,OAAO,CACL,kBACE,SAAS,EAAE,EAAE,CAAC,+DAA+D,EAAE,SAAS,CAAC,aAEzF,aAAI,SAAS,EAAC,8DAA8D,YAAE,KAAK,GAAM,EACxF,OAAO,IACD,CACV,CAAC;AACJ,CAAC"}
|
package/dist/lib/states.d.ts
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* 🔴 `outline-offset` is therefore load-bearing, not decoration. Do not set it to 0.
|
|
45
45
|
*/
|
|
46
46
|
/** Keyboard focus indicator. Colour comes from the theme, never from a caller. */
|
|
47
|
-
export declare const FOCUS_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-
|
|
47
|
+
export declare const FOCUS_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-x-slot-focus-ring";
|
|
48
48
|
/**
|
|
49
49
|
* Disabled appearance. The opacity is a theme token (`--opacity-x-disabled`) because a
|
|
50
50
|
* literal here would be a design value living outside themes/default.css.
|
|
@@ -64,6 +64,6 @@ export declare const DISABLED_CLASS = "disabled:opacity-x-disabled disabled:curs
|
|
|
64
64
|
*/
|
|
65
65
|
export declare const HOVER_CLASS = "hover:brightness-x-slot-hover active:brightness-x-slot-press disabled:hover:brightness-100 disabled:active:brightness-100";
|
|
66
66
|
/** Controls that can be focused and disabled — every interactive primitive in the kit. */
|
|
67
|
-
export declare const CONTROL_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-
|
|
67
|
+
export declare const CONTROL_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-x-slot-focus-ring disabled:opacity-x-disabled disabled:cursor-not-allowed";
|
|
68
68
|
/** Controls that are also clicked: buttons, switches, the toast dismiss. */
|
|
69
|
-
export declare const CLICKABLE_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-
|
|
69
|
+
export declare const CLICKABLE_CLASS = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-x-slot-focus-ring disabled:opacity-x-disabled disabled:cursor-not-allowed hover:brightness-x-slot-hover active:brightness-x-slot-press disabled:hover:brightness-100 disabled:active:brightness-100";
|
package/dist/lib/states.js
CHANGED
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* 🔴 `outline-offset` is therefore load-bearing, not decoration. Do not set it to 0.
|
|
45
45
|
*/
|
|
46
46
|
/** Keyboard focus indicator. Colour comes from the theme, never from a caller. */
|
|
47
|
-
export const FOCUS_CLASS = 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-
|
|
47
|
+
export const FOCUS_CLASS = 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-x-slot-focus-ring';
|
|
48
48
|
/**
|
|
49
49
|
* Disabled appearance. The opacity is a theme token (`--opacity-x-disabled`) because a
|
|
50
50
|
* literal here would be a design value living outside themes/default.css.
|
package/dist/lib/states.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"states.js","sourceRoot":"","sources":["../../src/lib/states.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,kFAAkF;AAClF,MAAM,CAAC,MAAM,WAAW,GACtB,
|
|
1
|
+
{"version":3,"file":"states.js","sourceRoot":"","sources":["../../src/lib/states.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH,kFAAkF;AAClF,MAAM,CAAC,MAAM,WAAW,GACtB,gGAAgG,CAAC;AAEnG;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAExF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,WAAW,GACtB,2HAA2H,CAAC;AAE9H,0FAA0F;AAC1F,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,WAAW,IAAI,cAAc,EAAE,CAAC;AAEhE,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,aAAa,IAAI,WAAW,EAAE,CAAC"}
|
package/dist/overlay/Modal.js
CHANGED
|
@@ -42,6 +42,6 @@ export function Modal({ open, onClose, title, children }) {
|
|
|
42
42
|
return (_jsx("dialog", { ref: ref, "aria-label": title,
|
|
43
43
|
// The browser fires `close` for Esc as well as for close(); routing both through the
|
|
44
44
|
// caller keeps `open` from drifting out of sync with what is on screen.
|
|
45
|
-
onClose: onClose, onCancel: onClose, className: cx('bg-
|
|
45
|
+
onClose: onClose, onCancel: onClose, className: cx('bg-x-slot-modal-bg text-x-slot-modal-fg border border-x-slot-modal-border rounded-x-slot-modal', 'p-x-slot-modal-pad font-sans backdrop:bg-x-slot-modal-scrim/50'), children: children }));
|
|
46
46
|
}
|
|
47
47
|
//# sourceMappingURL=Modal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/overlay/Modal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAWlC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAc;IAClE,MAAM,GAAG,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAE5C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO;QAExB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;gBACvC,IAAI,CAAC,EAAE,CAAC,IAAI;oBAAE,EAAE,CAAC,SAAS,EAAE,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC,IAAI;gBAAE,EAAE,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,gBACI,KAAK;QACjB,qFAAqF;QACrF,wEAAwE;QACxE,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,EAAE,CACX
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/overlay/Modal.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AAC1D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAWlC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAc;IAClE,MAAM,GAAG,GAAG,MAAM,CAAoB,IAAI,CAAC,CAAC;IAE5C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,EAAE,KAAK,IAAI;YAAE,OAAO;QAExB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,OAAO,EAAE,CAAC,SAAS,KAAK,UAAU,EAAE,CAAC;gBACvC,IAAI,CAAC,EAAE,CAAC,IAAI;oBAAE,EAAE,CAAC,SAAS,EAAE,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC9B,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,OAAO,EAAE,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACnC,IAAI,EAAE,CAAC,IAAI;gBAAE,EAAE,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,gBACI,KAAK;QACjB,qFAAqF;QACrF,wEAAwE;QACxE,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,OAAO,EACjB,SAAS,EAAE,EAAE,CACX,gGAAgG,EAChG,gEAAgE,CACjE,YAEA,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -2,12 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
import { CLICKABLE_CLASS } from '../lib/states.js';
|
|
4
4
|
const VARIANT_CLASS = {
|
|
5
|
-
primary: 'bg-
|
|
6
|
-
secondary: 'bg-
|
|
7
|
-
danger: 'bg-danger text-
|
|
5
|
+
primary: 'bg-x-slot-button-primary-bg text-x-slot-button-primary-fg',
|
|
6
|
+
secondary: 'bg-x-slot-button-secondary-bg text-x-slot-button-secondary-fg border-x-slot-button-secondary-border',
|
|
7
|
+
danger: 'bg-x-slot-button-danger-bg text-x-slot-button-danger-fg',
|
|
8
8
|
// No fill and no border: for the third action in a row, where two framed buttons would
|
|
9
9
|
// compete with each other. nene-vault ships this variant already.
|
|
10
|
-
ghost: 'bg-transparent text-
|
|
10
|
+
ghost: 'bg-transparent text-x-slot-button-ghost-fg',
|
|
11
11
|
};
|
|
12
12
|
const SIZE_CLASS = {
|
|
13
13
|
md: 'px-x-slot-button-pad-x py-x-slot-button-pad-y',
|
|
@@ -18,7 +18,18 @@ const SIZE_CLASS = {
|
|
|
18
18
|
// taller than the others. nene-vault puts a primary and a secondary side by side in seven
|
|
19
19
|
// modal footers, where that shows up as a step (measured 2026-08-23); its own Button carries
|
|
20
20
|
// the same transparent border for the same reason.
|
|
21
|
-
|
|
21
|
+
// 🔴 `[&_svg]:max-*` bounds a raw `<svg>` child without sizing it. An svg with no width or
|
|
22
|
+
// height attribute lays out at the replaced-element default of 300x150; a `max-height` pulls
|
|
23
|
+
// it back and, because a `viewBox` gives the element an intrinsic ratio, the width follows.
|
|
24
|
+
// `max-width` covers the svg that has no viewBox either.
|
|
25
|
+
//
|
|
26
|
+
// 🔴 Not `[&_svg]:size-*`. That would outrank the plain `h-5 w-5` an `Icon` sets on itself
|
|
27
|
+
// — an arbitrary variant compiles to a descendant selector, which is more specific than a
|
|
28
|
+
// single class — so `<Icon size="sm">` inside a button would render at the button's size
|
|
29
|
+
// instead of its own. A maximum cannot collide with a height: different property, and it
|
|
30
|
+
// leaves anything already smaller alone.
|
|
31
|
+
const SVG_BOUND = '[&_svg]:max-h-x-slot-button-icon [&_svg]:max-w-x-slot-button-icon';
|
|
32
|
+
const BASE_CLASS = `rounded-x-slot-button border border-transparent font-sans text-x-slot-button-size font-x-slot-button ${SVG_BOUND} ${CLICKABLE_CLASS}`;
|
|
22
33
|
export function Button({ variant = 'primary', size = 'md', children, type = 'button', className, ...rest }) {
|
|
23
34
|
return (_jsx("button", { type: type, className: cx(BASE_CLASS, SIZE_CLASS[size], VARIANT_CLASS[variant], className), ...rest, children: children }));
|
|
24
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/primitives/Button.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAcnD,MAAM,aAAa,GAAwD;IACzE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../src/primitives/Button.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAcnD,MAAM,aAAa,GAAwD;IACzE,OAAO,EAAE,2DAA2D;IACpE,SAAS,EACP,qGAAqG;IACvG,MAAM,EAAE,yDAAyD;IACjE,uFAAuF;IACvF,kEAAkE;IAClE,KAAK,EAAE,4CAA4C;CACpD,CAAC;AAEF,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,+CAA+C;IACnD,EAAE,EAAE,qDAAqD;CAC1D,CAAC;AAEF,wFAAwF;AACxF,uFAAuF;AACvF,0FAA0F;AAC1F,6FAA6F;AAC7F,mDAAmD;AACnD,2FAA2F;AAC3F,6FAA6F;AAC7F,4FAA4F;AAC5F,yDAAyD;AACzD,EAAE;AACF,2FAA2F;AAC3F,0FAA0F;AAC1F,yFAAyF;AACzF,yFAAyF;AACzF,yCAAyC;AACzC,MAAM,SAAS,GAAG,mEAAmE,CAAC;AAEtF,MAAM,UAAU,GAAG,wGAAwG,SAAS,IAAI,eAAe,EAAE,CAAC;AAE1J,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,SAAS,EACT,GAAG,IAAI,EACK;IACZ,OAAO,CACL,iBACE,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,KAC1E,IAAI,YAEP,QAAQ,GACF,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -2,6 +2,11 @@ import { type InputHTMLAttributes, type ReactNode } from 'react';
|
|
|
2
2
|
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
3
3
|
/** Localized label. Rendered inside the control's own `<label>`. */
|
|
4
4
|
label: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* Classes for the `<input>` itself. `className` goes to the `<label>`, which is this
|
|
7
|
+
* part's root — see the note below.
|
|
8
|
+
*/
|
|
9
|
+
inputClassName?: string;
|
|
5
10
|
}
|
|
6
11
|
/**
|
|
7
12
|
* A checkbox and its label, as one part.
|
|
@@ -11,11 +16,21 @@ export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement
|
|
|
11
16
|
* visible, and loses the ability to click the text to toggle the box, plus the name the
|
|
12
17
|
* control is announced by. Making the label a prop means it cannot be forgotten.
|
|
13
18
|
*
|
|
14
|
-
* 🔴 `
|
|
15
|
-
* the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* 🔴 `className` lands on the `<label>`, which is this part's root — the same place it
|
|
20
|
+
* lands in every other component the kit ships. Until 0.10.0 it went to the `<input>`
|
|
21
|
+
* instead, so nothing the caller wrote could reach the root: `self-start` inside a flex
|
|
22
|
+
* row, a width, a margin. nene-vault had to wrap each choice in a `<div>` to say them
|
|
23
|
+
* (found while migrating, 2026-08-23). Use `inputClassName` for the box itself.
|
|
24
|
+
*
|
|
25
|
+
* 🔑 This is the cause behind a symptom the kit already answered once. In wave 2 the
|
|
26
|
+
* report was that `cursor-pointer` could not be set, because it belongs to the label; the
|
|
27
|
+
* kit took `cursor-pointer` and the gap on itself. That was right as far as it went, and
|
|
28
|
+
* it left the reason intact — every other label-level property stayed unreachable.
|
|
29
|
+
* Fixing what a report names is not the same as fixing what it is about.
|
|
30
|
+
*
|
|
31
|
+
* `cursor-pointer` and the gap still live here: they are not decisions a product should
|
|
32
|
+
* have to repeat at every call site. nene-vault carries them on the label in its own
|
|
33
|
+
* implementation (measured 2026-08-23), so a migration that could not set them would lose
|
|
34
|
+
* the pointer cursor on every choice — visible to a mouse user, invisible in a diff.
|
|
20
35
|
*/
|
|
21
36
|
export declare const Checkbox: import("react").ForwardRefExoticComponent<CheckboxProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -3,7 +3,7 @@ import { forwardRef } from 'react';
|
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
import { CONTROL_CLASS } from '../lib/states.js';
|
|
5
5
|
import { useFieldWiring } from '../forms/field-context.js';
|
|
6
|
-
const BOX_CLASS = `size-x-slot-choice-box shrink-0 rounded-x-slot-control border border-border accent-x-slot-choice-accent ${CONTROL_CLASS}`;
|
|
6
|
+
const BOX_CLASS = `size-x-slot-choice-box shrink-0 rounded-x-slot-control border border-x-slot-choice-border accent-x-slot-choice-accent ${CONTROL_CLASS}`;
|
|
7
7
|
/**
|
|
8
8
|
* A checkbox and its label, as one part.
|
|
9
9
|
*
|
|
@@ -12,15 +12,25 @@ const BOX_CLASS = `size-x-slot-choice-box shrink-0 rounded-x-slot-control border
|
|
|
12
12
|
* visible, and loses the ability to click the text to toggle the box, plus the name the
|
|
13
13
|
* control is announced by. Making the label a prop means it cannot be forgotten.
|
|
14
14
|
*
|
|
15
|
-
* 🔴 `
|
|
16
|
-
* the
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
15
|
+
* 🔴 `className` lands on the `<label>`, which is this part's root — the same place it
|
|
16
|
+
* lands in every other component the kit ships. Until 0.10.0 it went to the `<input>`
|
|
17
|
+
* instead, so nothing the caller wrote could reach the root: `self-start` inside a flex
|
|
18
|
+
* row, a width, a margin. nene-vault had to wrap each choice in a `<div>` to say them
|
|
19
|
+
* (found while migrating, 2026-08-23). Use `inputClassName` for the box itself.
|
|
20
|
+
*
|
|
21
|
+
* 🔑 This is the cause behind a symptom the kit already answered once. In wave 2 the
|
|
22
|
+
* report was that `cursor-pointer` could not be set, because it belongs to the label; the
|
|
23
|
+
* kit took `cursor-pointer` and the gap on itself. That was right as far as it went, and
|
|
24
|
+
* it left the reason intact — every other label-level property stayed unreachable.
|
|
25
|
+
* Fixing what a report names is not the same as fixing what it is about.
|
|
26
|
+
*
|
|
27
|
+
* `cursor-pointer` and the gap still live here: they are not decisions a product should
|
|
28
|
+
* have to repeat at every call site. nene-vault carries them on the label in its own
|
|
29
|
+
* implementation (measured 2026-08-23), so a migration that could not set them would lose
|
|
30
|
+
* the pointer cursor on every choice — visible to a mouse user, invisible in a diff.
|
|
21
31
|
*/
|
|
22
|
-
export const Checkbox = forwardRef(function Checkbox({ label, className, id, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, 'aria-required': ariaRequired, ...rest }, ref) {
|
|
32
|
+
export const Checkbox = forwardRef(function Checkbox({ label, className, inputClassName, id, 'aria-invalid': ariaInvalid, 'aria-describedby': ariaDescribedBy, 'aria-required': ariaRequired, ...rest }, ref) {
|
|
23
33
|
const wiring = useFieldWiring({ id, ariaInvalid, ariaDescribedBy, ariaRequired });
|
|
24
|
-
return (_jsxs("label", { className:
|
|
34
|
+
return (_jsxs("label", { className: cx('inline-flex cursor-pointer items-center gap-x-slot-choice-gap font-sans text-x-slot-choice-size text-x-slot-choice-fg', className), children: [_jsx("input", { ref: ref, type: "checkbox", className: cx(BOX_CLASS, inputClassName), ...wiring, ...rest }), label] }));
|
|
25
35
|
});
|
|
26
36
|
//# sourceMappingURL=Checkbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/primitives/Checkbox.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4C,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../src/primitives/Checkbox.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4C,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAY3D,MAAM,SAAS,GAAG,yHAAyH,aAAa,EAAE,CAAC;AAE3J;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAkC,SAAS,QAAQ,CACnF,EACE,KAAK,EACL,SAAS,EACT,cAAc,EACd,EAAE,EACF,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,YAAY,EAC7B,GAAG,IAAI,EACR,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;IAElF,OAAO,CACL,iBACE,SAAS,EAAE,EAAE,CACX,uHAAuH,EACvH,SAAS,CACV,aAED,gBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,UAAU,EACf,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,KACpC,MAAM,KACN,IAAI,GACR,EACD,KAAK,IACA,CACT,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
package/dist/primitives/Input.js
CHANGED
|
@@ -3,7 +3,7 @@ import { forwardRef } from 'react';
|
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
import { CONTROL_CLASS } from '../lib/states.js';
|
|
5
5
|
import { useFieldWiring } from '../forms/field-context.js';
|
|
6
|
-
const BASE_CLASS = `w-full rounded-x-slot-control border border-border bg-
|
|
6
|
+
const BASE_CLASS = `w-full rounded-x-slot-control border border-x-slot-control-border bg-x-slot-control-bg px-x-slot-control-pad-x py-x-slot-control-pad-y font-sans text-x-slot-control-size pointer-coarse:text-x-slot-control-touch-size text-x-slot-control-fg placeholder:text-x-slot-control-placeholder ${CONTROL_CLASS}`;
|
|
7
7
|
/**
|
|
8
8
|
* Text input primitive. forwardRef so it works directly with react-hook-form `register`.
|
|
9
9
|
* Visual values come from theme tokens only.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../src/primitives/Input.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"Input.js","sourceRoot":"","sources":["../../src/primitives/Input.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4B,MAAM,OAAO,CAAC;AAC7D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,MAAM,UAAU,GAAG,8RAA8R,aAAa,EAAE,CAAC;AAEjU;;;GAGG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA+B,SAAS,KAAK,CAC1E,EACE,SAAS,EACT,EAAE,EACF,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,YAAY,EAC7B,GAAG,IAAI,EACR,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;IAElF,OAAO,gBAAO,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,KAAM,MAAM,KAAM,IAAI,GAAI,CAAC;AACzF,CAAC,CAAC,CAAC"}
|
|
@@ -2,6 +2,11 @@ import { type InputHTMLAttributes, type ReactNode } from 'react';
|
|
|
2
2
|
export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
3
3
|
/** Localized label. Rendered inside the control's own `<label>`. */
|
|
4
4
|
label: ReactNode;
|
|
5
|
+
/**
|
|
6
|
+
* Classes for the `<input>` itself. `className` goes to the `<label>`, which is this
|
|
7
|
+
* part's root — see the note below.
|
|
8
|
+
*/
|
|
9
|
+
inputClassName?: string;
|
|
5
10
|
/** Radios only mean anything in a group; `name` is what makes them one. */
|
|
6
11
|
name: string;
|
|
7
12
|
}
|
|
@@ -12,12 +17,21 @@ export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>,
|
|
|
12
17
|
* its own group of one: it can be checked but never unchecked, and arrow keys do not move
|
|
13
18
|
* between the options. Nothing about the rendered page shows this, so it survives review.
|
|
14
19
|
*
|
|
15
|
-
* 🔴 `
|
|
16
|
-
*
|
|
17
|
-
*
|
|
20
|
+
* 🔴 `className` lands on the `<label>`, which is this part's root — the same place it
|
|
21
|
+
* lands in every other component the kit ships. Until 0.10.0 it went to the `<input>`
|
|
22
|
+
* instead, so nothing the caller wrote could reach the root: `self-start` inside a flex
|
|
23
|
+
* row, a width, a margin. nene-vault had to wrap each choice in a `<div>` to say them
|
|
24
|
+
* (found while migrating, 2026-08-23). Use `inputClassName` for the box itself.
|
|
18
25
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
26
|
+
* 🔑 This is the cause behind a symptom the kit already answered once. In wave 2 the
|
|
27
|
+
* report was that `cursor-pointer` could not be set, because it belongs to the label; the
|
|
28
|
+
* kit took `cursor-pointer` and the gap on itself. That was right as far as it went, and
|
|
29
|
+
* it left the reason intact — every other label-level property stayed unreachable.
|
|
30
|
+
* Fixing what a report names is not the same as fixing what it is about.
|
|
31
|
+
*
|
|
32
|
+
* `cursor-pointer` and the gap still live here: they are not decisions a product should
|
|
33
|
+
* have to repeat at every call site. nene-vault carries them on the label in its own
|
|
34
|
+
* implementation (measured 2026-08-23), so a migration that could not set them would lose
|
|
35
|
+
* the pointer cursor on every choice — visible to a mouse user, invisible in a diff.
|
|
22
36
|
*/
|
|
23
37
|
export declare const Radio: import("react").ForwardRefExoticComponent<RadioProps & import("react").RefAttributes<HTMLInputElement>>;
|
package/dist/primitives/Radio.js
CHANGED
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
import { CONTROL_CLASS } from '../lib/states.js';
|
|
5
|
-
const DOT_CLASS = `size-x-slot-choice-box shrink-0 border border-border accent-x-slot-choice-accent ${CONTROL_CLASS}`;
|
|
5
|
+
const DOT_CLASS = `size-x-slot-choice-box shrink-0 border border-x-slot-choice-border accent-x-slot-choice-accent ${CONTROL_CLASS}`;
|
|
6
6
|
/**
|
|
7
7
|
* One option in a radio group, with its label.
|
|
8
8
|
*
|
|
@@ -10,15 +10,24 @@ const DOT_CLASS = `size-x-slot-choice-box shrink-0 border border-border accent-x
|
|
|
10
10
|
* its own group of one: it can be checked but never unchecked, and arrow keys do not move
|
|
11
11
|
* between the options. Nothing about the rendered page shows this, so it survives review.
|
|
12
12
|
*
|
|
13
|
-
* 🔴 `
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* 🔴 `className` lands on the `<label>`, which is this part's root — the same place it
|
|
14
|
+
* lands in every other component the kit ships. Until 0.10.0 it went to the `<input>`
|
|
15
|
+
* instead, so nothing the caller wrote could reach the root: `self-start` inside a flex
|
|
16
|
+
* row, a width, a margin. nene-vault had to wrap each choice in a `<div>` to say them
|
|
17
|
+
* (found while migrating, 2026-08-23). Use `inputClassName` for the box itself.
|
|
16
18
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
19
|
+
* 🔑 This is the cause behind a symptom the kit already answered once. In wave 2 the
|
|
20
|
+
* report was that `cursor-pointer` could not be set, because it belongs to the label; the
|
|
21
|
+
* kit took `cursor-pointer` and the gap on itself. That was right as far as it went, and
|
|
22
|
+
* it left the reason intact — every other label-level property stayed unreachable.
|
|
23
|
+
* Fixing what a report names is not the same as fixing what it is about.
|
|
24
|
+
*
|
|
25
|
+
* `cursor-pointer` and the gap still live here: they are not decisions a product should
|
|
26
|
+
* have to repeat at every call site. nene-vault carries them on the label in its own
|
|
27
|
+
* implementation (measured 2026-08-23), so a migration that could not set them would lose
|
|
28
|
+
* the pointer cursor on every choice — visible to a mouse user, invisible in a diff.
|
|
20
29
|
*/
|
|
21
|
-
export const Radio = forwardRef(function Radio({ label, name, className, ...rest }, ref) {
|
|
22
|
-
return (_jsxs("label", { className:
|
|
30
|
+
export const Radio = forwardRef(function Radio({ label, name, className, inputClassName, ...rest }, ref) {
|
|
31
|
+
return (_jsxs("label", { className: cx('inline-flex cursor-pointer items-center gap-x-slot-choice-gap font-sans text-x-slot-choice-size text-x-slot-choice-fg', className), children: [_jsx("input", { ref: ref, type: "radio", name: name, className: cx(DOT_CLASS, inputClassName), ...rest }), label] }));
|
|
23
32
|
});
|
|
24
33
|
//# sourceMappingURL=Radio.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Radio.js","sourceRoot":"","sources":["../../src/primitives/Radio.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4C,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Radio.js","sourceRoot":"","sources":["../../src/primitives/Radio.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA4C,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAcjD,MAAM,SAAS,GAAG,kGAAkG,aAAa,EAAE,CAAC;AAEpI;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA+B,SAAS,KAAK,CAC1E,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,EACnD,GAAG;IAEH,OAAO,CACL,iBACE,SAAS,EAAE,EAAE,CACX,uHAAuH,EACvH,SAAS,CACV,aAED,gBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,OAAO,EACZ,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,KACpC,IAAI,GACR,EACD,KAAK,IACA,CACT,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { forwardRef } from 'react';
|
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
import { CONTROL_CLASS } from '../lib/states.js';
|
|
5
5
|
import { useFieldWiring } from '../forms/field-context.js';
|
|
6
|
-
const BASE_CLASS = `w-full rounded-x-slot-control border border-border bg-
|
|
6
|
+
const BASE_CLASS = `w-full rounded-x-slot-control border border-x-slot-control-border bg-x-slot-control-bg px-x-slot-control-pad-x py-x-slot-control-pad-y font-sans text-x-slot-control-size pointer-coarse:text-x-slot-control-touch-size text-x-slot-control-fg ${CONTROL_CLASS}`;
|
|
7
7
|
/**
|
|
8
8
|
* Select primitive. forwardRef so it works directly with react-hook-form `register`.
|
|
9
9
|
* Visual values come from theme tokens only.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/primitives/Select.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA6C,MAAM,OAAO,CAAC;AAC9E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAM3D,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/primitives/Select.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA6C,MAAM,OAAO,CAAC;AAC9E,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAM3D,MAAM,UAAU,GAAG,kPAAkP,aAAa,EAAE,CAAC;AAErR;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EACE,QAAQ,EACR,SAAS,EACT,EAAE,EACF,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,YAAY,EAC7B,GAAG,IAAI,EACR,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;IAElF,OAAO,CACL,iBAAQ,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,KAAM,MAAM,KAAM,IAAI,YACzE,QAAQ,GACF,CACV,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
export function Spinner({ label, className }) {
|
|
4
|
-
return (_jsx("output", { className: cx('font-sans text-
|
|
4
|
+
return (_jsx("output", { className: cx('font-sans text-x-slot-spinner-fg', className), "aria-live": "polite", children: label }));
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=Spinner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/primitives/Spinner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAgB;IACxD,OAAO,CACL,iBAAQ,SAAS,EAAE,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/primitives/Spinner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAgB;IACxD,OAAO,CACL,iBAAQ,SAAS,EAAE,EAAE,CAAC,kCAAkC,EAAE,SAAS,CAAC,eAAY,QAAQ,YACrF,KAAK,GACC,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -14,6 +14,8 @@ import { CLICKABLE_CLASS } from '../lib/states.js';
|
|
|
14
14
|
* `aria-checked` carries the state; the visible track is decoration on top of it.
|
|
15
15
|
*/
|
|
16
16
|
export const Switch = forwardRef(function Switch({ checked, onCheckedChange, label, className, ...rest }, ref) {
|
|
17
|
-
return (_jsx("button", { ref: ref, type: "button", role: "switch", "aria-checked": checked, "aria-label": label, onClick: () => onCheckedChange(!checked), className: cx('inline-flex items-center rounded-x-slot-switch border border-border px-x-slot-switch-pad-x py-x-slot-switch-pad-y font-sans', checked
|
|
17
|
+
return (_jsx("button", { ref: ref, type: "button", role: "switch", "aria-checked": checked, "aria-label": label, onClick: () => onCheckedChange(!checked), className: cx('inline-flex items-center rounded-x-slot-switch border border-x-slot-switch-border px-x-slot-switch-pad-x py-x-slot-switch-pad-y font-sans', checked
|
|
18
|
+
? 'bg-x-slot-switch-on-bg text-x-slot-switch-on-fg'
|
|
19
|
+
: 'bg-x-slot-switch-off-bg text-x-slot-switch-off-fg', CLICKABLE_CLASS, className), ...rest, children: label }));
|
|
18
20
|
});
|
|
19
21
|
//# sourceMappingURL=Switch.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/primitives/Switch.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA6B,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAUnD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EACvD,GAAG;IAEH,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,kBACC,OAAO,gBACT,KAAK,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,EACxC,SAAS,EAAE,EAAE,CACX,
|
|
1
|
+
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/primitives/Switch.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA6B,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAUnD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EACvD,GAAG;IAEH,OAAO,CACL,iBACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,QAAQ,kBACC,OAAO,gBACT,KAAK,EACjB,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,EACxC,SAAS,EAAE,EAAE,CACX,2IAA2I,EAC3I,OAAO;YACL,CAAC,CAAC,iDAAiD;YACnD,CAAC,CAAC,mDAAmD,EACvD,eAAe,EACf,SAAS,CACV,KACG,IAAI,YAEP,KAAK,GACC,CACV,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
package/dist/primitives/Text.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
export function Text({ as = 'p', tone = 'primary', children, className }) {
|
|
4
|
-
const merged = cx('font-sans', tone === 'muted' ? 'text-text-muted' : 'text-text-
|
|
4
|
+
const merged = cx('font-sans', tone === 'muted' ? 'text-x-slot-text-muted-fg' : 'text-x-slot-text-fg', className);
|
|
5
5
|
return as === 'span' ? (_jsx("span", { className: merged, children: children })) : (_jsx("p", { className: merged, children: children }));
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=Text.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Text.js","sourceRoot":"","sources":["../../src/primitives/Text.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAUlC,MAAM,UAAU,IAAI,CAAC,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAa;IACjF,MAAM,MAAM,GAAG,EAAE,CACf,WAAW,EACX,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"Text.js","sourceRoot":"","sources":["../../src/primitives/Text.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAUlC,MAAM,UAAU,IAAI,CAAC,EAAE,EAAE,GAAG,GAAG,EAAE,IAAI,GAAG,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAa;IACjF,MAAM,MAAM,GAAG,EAAE,CACf,WAAW,EACX,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,qBAAqB,EACtE,SAAS,CACV,CAAC;IAEF,OAAO,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CACrB,eAAM,SAAS,EAAE,MAAM,YAAG,QAAQ,GAAQ,CAC3C,CAAC,CAAC,CAAC,CACF,YAAG,SAAS,EAAE,MAAM,YAAG,QAAQ,GAAK,CACrC,CAAC;AACJ,CAAC"}
|
|
@@ -3,7 +3,7 @@ import { forwardRef } from 'react';
|
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
import { CONTROL_CLASS } from '../lib/states.js';
|
|
5
5
|
import { useFieldWiring } from '../forms/field-context.js';
|
|
6
|
-
const BASE_CLASS = `w-full rounded-x-slot-control border border-border bg-
|
|
6
|
+
const BASE_CLASS = `w-full rounded-x-slot-control border border-x-slot-control-border bg-x-slot-control-bg px-x-slot-control-pad-x py-x-slot-control-pad-y font-sans text-x-slot-control-size pointer-coarse:text-x-slot-control-touch-size text-x-slot-control-fg placeholder:text-x-slot-control-placeholder ${CONTROL_CLASS}`;
|
|
7
7
|
/**
|
|
8
8
|
* Multi-line text input. Deliberately identical to `Input` apart from the element, so the
|
|
9
9
|
* two never drift: five ships wrote their own `Textarea.tsx` and the kit shipped without
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../src/primitives/Textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA+B,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,MAAM,UAAU,GAAG,
|
|
1
|
+
{"version":3,"file":"Textarea.js","sourceRoot":"","sources":["../../src/primitives/Textarea.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAA+B,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAI3D,MAAM,UAAU,GAAG,8RAA8R,aAAa,EAAE,CAAC;AAEjU;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAqC,SAAS,QAAQ,CACtF,EACE,SAAS,EACT,EAAE,EACF,cAAc,EAAE,WAAW,EAC3B,kBAAkB,EAAE,eAAe,EACnC,eAAe,EAAE,YAAY,EAC7B,GAAG,IAAI,EACR,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,YAAY,EAAE,CAAC,CAAC;IAElF,OAAO,mBAAU,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,KAAM,MAAM,KAAM,IAAI,GAAI,CAAC;AAC5F,CAAC,CAAC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cx } from '../lib/cx.js';
|
|
3
3
|
export function EmptyState({ message, align = 'center', className }) {
|
|
4
|
-
return (_jsx("div", { className: cx('py-x-slot-state-pad-y font-sans text-
|
|
4
|
+
return (_jsx("div", { className: cx('py-x-slot-state-pad-y font-sans text-x-slot-empty-state-fg', align === 'center' && 'text-center', className), role: "status", children: message }));
|
|
5
5
|
}
|
|
6
6
|
//# sourceMappingURL=EmptyState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.js","sourceRoot":"","sources":["../../src/states/EmptyState.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAgBlC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAmB;IAClF,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,
|
|
1
|
+
{"version":3,"file":"EmptyState.js","sourceRoot":"","sources":["../../src/states/EmptyState.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAgBlC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAmB;IAClF,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,4DAA4D,EAC5D,KAAK,KAAK,QAAQ,IAAI,aAAa,EACnC,SAAS,CACV,EACD,IAAI,EAAC,QAAQ,YAEZ,OAAO,GACJ,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -2,6 +2,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from '../primitives/Button.js';
|
|
3
3
|
import { cx } from '../lib/cx.js';
|
|
4
4
|
export function ErrorState({ message, retryLabel, onRetry, className }) {
|
|
5
|
-
return (_jsxs("div", { className: cx('py-x-slot-state-pad-y', className), role: "alert", children: [_jsx("p", { className: "font-sans text-
|
|
5
|
+
return (_jsxs("div", { className: cx('py-x-slot-state-pad-y', className), role: "alert", children: [_jsx("p", { className: "font-sans text-x-slot-error-state-fg", children: message }), _jsx("div", { className: "py-x-slot-state-action-pad-y", children: _jsx(Button, { variant: "secondary", onClick: onRetry, children: retryLabel }) })] }));
|
|
6
6
|
}
|
|
7
7
|
//# sourceMappingURL=ErrorState.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ErrorState.js","sourceRoot":"","sources":["../../src/states/ErrorState.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAmB;IACrF,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,OAAO,aAClE,YAAG,SAAS,EAAC,
|
|
1
|
+
{"version":3,"file":"ErrorState.js","sourceRoot":"","sources":["../../src/states/ErrorState.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAmB;IACrF,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,uBAAuB,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,OAAO,aAClE,YAAG,SAAS,EAAC,sCAAsC,YAAE,OAAO,GAAK,EACjE,cAAK,SAAS,EAAC,8BAA8B,YAC3C,KAAC,MAAM,IAAC,OAAO,EAAC,WAAW,EAAC,OAAO,EAAE,OAAO,YACzC,UAAU,GACJ,GACL,IACF,CACP,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hideyukimori/nene2-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "NeNe fleet shared React UI kit — token-driven primitives on Tailwind v4 @theme. Components carry no design of their own; themes do.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/themes/default.css
CHANGED
|
@@ -157,6 +157,133 @@
|
|
|
157
157
|
--text-x-slot-control-size: var(--text-x-md);
|
|
158
158
|
--text-x-slot-control-touch-size: var(--text-x-ios-floor);
|
|
159
159
|
|
|
160
|
+
/* ── Colour slots ─────────────────────────────────────────────────────────────
|
|
161
|
+
* Every colour a component paints comes from here.
|
|
162
|
+
*
|
|
163
|
+
* 🔴 Until 0.9.0 only `FormField` and `InlineAlert` had any, and the other 26 components
|
|
164
|
+
* reached straight into the palette (`text-text-primary`, `bg-surface-raised`) — 59 places
|
|
165
|
+
* in 20 files. The README said "every design value a component uses comes from a slot"
|
|
166
|
+
* the whole time. The check that was supposed to enforce it listed the utility prefixes
|
|
167
|
+
* it knew about — `p px py … rounded` — so colour and weight were never inspected at all.
|
|
168
|
+
*
|
|
169
|
+
* Found by nene-vault comparing its production screens against the migrated build in a
|
|
170
|
+
* real browser (Playwright, computed styles, element by element, 2026-08-23): 73 elements
|
|
171
|
+
* matched, 21 differed, and every difference was inside a kit component. Its own markup —
|
|
172
|
+
* side nav, tables, headings — matched on every property. A product cannot make a control
|
|
173
|
+
* darker than its body text while the kit writes the colour itself.
|
|
174
|
+
*
|
|
175
|
+
* Defaults are palette references, so nothing renders differently. What changes is that
|
|
176
|
+
* there is now an opening. */
|
|
177
|
+
--color-x-slot-focus-ring: var(--color-text-primary);
|
|
178
|
+
|
|
179
|
+
--color-x-slot-button-primary-bg: var(--color-accent);
|
|
180
|
+
--color-x-slot-button-primary-fg: var(--color-on-accent);
|
|
181
|
+
--color-x-slot-button-secondary-bg: var(--color-surface-raised);
|
|
182
|
+
--color-x-slot-button-secondary-fg: var(--color-text-primary);
|
|
183
|
+
--color-x-slot-button-secondary-border: var(--color-border);
|
|
184
|
+
--color-x-slot-button-danger-bg: var(--color-danger);
|
|
185
|
+
--color-x-slot-button-danger-fg: var(--color-on-accent);
|
|
186
|
+
--color-x-slot-button-ghost-fg: var(--color-text-primary);
|
|
187
|
+
|
|
188
|
+
/* Shared by Input, Select and Textarea — they are one control with three shapes, and a
|
|
189
|
+
* product that darkens one and not the others has a bug, not a design. */
|
|
190
|
+
--color-x-slot-control-fg: var(--color-text-primary);
|
|
191
|
+
--color-x-slot-control-bg: var(--color-surface-raised);
|
|
192
|
+
--color-x-slot-control-border: var(--color-border);
|
|
193
|
+
--color-x-slot-control-placeholder: var(--color-text-muted);
|
|
194
|
+
|
|
195
|
+
--color-x-slot-choice-fg: var(--color-text-primary);
|
|
196
|
+
--color-x-slot-choice-border: var(--color-border);
|
|
197
|
+
|
|
198
|
+
--color-x-slot-switch-on-bg: var(--color-accent);
|
|
199
|
+
--color-x-slot-switch-on-fg: var(--color-on-accent);
|
|
200
|
+
--color-x-slot-switch-off-bg: var(--color-surface);
|
|
201
|
+
--color-x-slot-switch-off-fg: var(--color-text-muted);
|
|
202
|
+
--color-x-slot-switch-border: var(--color-border);
|
|
203
|
+
|
|
204
|
+
--color-x-slot-badge-neutral-bg: var(--color-surface);
|
|
205
|
+
--color-x-slot-badge-neutral-fg: var(--color-text-muted);
|
|
206
|
+
--color-x-slot-badge-neutral-border: var(--color-border);
|
|
207
|
+
--color-x-slot-badge-accent-bg: var(--color-accent);
|
|
208
|
+
--color-x-slot-badge-accent-fg: var(--color-on-accent);
|
|
209
|
+
--color-x-slot-badge-accent-border: var(--color-accent);
|
|
210
|
+
--color-x-slot-badge-danger-bg: var(--color-danger);
|
|
211
|
+
--color-x-slot-badge-danger-fg: var(--color-on-accent);
|
|
212
|
+
--color-x-slot-badge-danger-border: var(--color-danger);
|
|
213
|
+
|
|
214
|
+
--color-x-slot-toast-bg: var(--color-surface-raised);
|
|
215
|
+
--color-x-slot-toast-fg: var(--color-text-primary);
|
|
216
|
+
--color-x-slot-toast-border: var(--color-border);
|
|
217
|
+
--color-x-slot-toast-danger-fg: var(--color-danger);
|
|
218
|
+
--color-x-slot-toast-danger-border: var(--color-danger);
|
|
219
|
+
|
|
220
|
+
--color-x-slot-card-bg: var(--color-surface-raised);
|
|
221
|
+
--color-x-slot-card-border: var(--color-border);
|
|
222
|
+
|
|
223
|
+
--color-x-slot-modal-bg: var(--color-surface-raised);
|
|
224
|
+
--color-x-slot-modal-fg: var(--color-text-primary);
|
|
225
|
+
--color-x-slot-modal-border: var(--color-border);
|
|
226
|
+
/* The dim behind a modal. A colour, so it belongs here — the opacity that goes with it is
|
|
227
|
+
* applied by the component, since it is not a palette entry. */
|
|
228
|
+
--color-x-slot-modal-scrim: var(--color-text-primary);
|
|
229
|
+
|
|
230
|
+
--color-x-slot-table-fg: var(--color-text-primary);
|
|
231
|
+
--color-x-slot-table-header-fg: var(--color-text-muted);
|
|
232
|
+
--color-x-slot-table-border: var(--color-border);
|
|
233
|
+
|
|
234
|
+
--color-x-slot-detail-term-fg: var(--color-text-muted);
|
|
235
|
+
--color-x-slot-detail-description-fg: var(--color-text-primary);
|
|
236
|
+
--color-x-slot-detail-border: var(--color-border);
|
|
237
|
+
|
|
238
|
+
--color-x-slot-pagination-fg: var(--color-text-muted);
|
|
239
|
+
--color-x-slot-page-header-fg: var(--color-text-primary);
|
|
240
|
+
--color-x-slot-text-fg: var(--color-text-primary);
|
|
241
|
+
--color-x-slot-text-muted-fg: var(--color-text-muted);
|
|
242
|
+
--color-x-slot-spinner-fg: var(--color-text-muted);
|
|
243
|
+
--color-x-slot-empty-state-fg: var(--color-text-muted);
|
|
244
|
+
--color-x-slot-error-state-fg: var(--color-danger);
|
|
245
|
+
--color-x-slot-field-error-fg: var(--color-danger);
|
|
246
|
+
|
|
247
|
+
/* An upper bound for an `<svg>` written directly inside a `Button`.
|
|
248
|
+
*
|
|
249
|
+
* 🔴 `max-*`, deliberately not `size-*`. An `<svg>` with no width/height attributes and no
|
|
250
|
+
* CSS size is a replaced element with no intrinsic size, so it lays out at 300x150 — which
|
|
251
|
+
* is how a nene-vault upload button became a 230px-tall rectangle the moment its wrapper
|
|
252
|
+
* changed from a `<div>` to a `<Stack>` (2026-08-23).
|
|
253
|
+
*
|
|
254
|
+
* Sizing it outright would fix that and break something else: a class produced by an
|
|
255
|
+
* arbitrary variant (`[&_svg]:size-6`) outranks the plain `h-6 w-6` that `Icon` puts on
|
|
256
|
+
* itself, so `<Icon size="sm">` inside a button would silently render at the button's
|
|
257
|
+
* size. A maximum has no such conflict — it constrains nothing that is already smaller,
|
|
258
|
+
* and there is no specificity contest because the two properties are different.
|
|
259
|
+
*
|
|
260
|
+
* The bound is `--spacing-x-lg`, which is 1.5rem — `Icon size="lg"` exactly — so no icon
|
|
261
|
+
* the kit ships is clamped by it. */
|
|
262
|
+
--spacing-x-slot-button-icon: var(--spacing-x-lg);
|
|
263
|
+
|
|
264
|
+
/* ── Weight slots ─────────────────────────────────────────────────────────────
|
|
265
|
+
* `font-medium` appeared inline in four components. Same rule, same reason as colour. */
|
|
266
|
+
--font-weight-x-slot-button: var(--font-weight-medium);
|
|
267
|
+
--font-weight-x-slot-table-header: var(--font-weight-medium);
|
|
268
|
+
--font-weight-x-slot-detail-term: var(--font-weight-medium);
|
|
269
|
+
--font-weight-x-slot-page-header: var(--font-weight-medium);
|
|
270
|
+
|
|
271
|
+
/* ── Size slots that decline to choose ────────────────────────────────────────
|
|
272
|
+
* 🔴 `inherit`, not a step. Button and the choice controls set no font-size today, so
|
|
273
|
+
* they take the page's — and picking a step here would change how every product already
|
|
274
|
+
* renders, which is the one thing this release must not do. `inherit` is not a design
|
|
275
|
+
* value the kit invented; it is the kit saying it has no opinion, in a place a product
|
|
276
|
+
* can now answer. nene-vault's production buttons are 13px against a 14px body, which is
|
|
277
|
+
* exactly the distinction that had nowhere to live.
|
|
278
|
+
*
|
|
279
|
+
* ⚠️ 13px is not on the type scale (0.6875 / 0.75 / 0.875 / 1 / 1.125 / 1.5rem). The
|
|
280
|
+
* scale was measured from what the fleet writes in Tailwind classes, which cannot express
|
|
281
|
+
* a value it has no step for — so that measurement could not have seen it. Recorded here
|
|
282
|
+
* rather than acted on: changing the type scale is its own decision, with its own
|
|
283
|
+
* measurement, and it is not this release's. */
|
|
284
|
+
--text-x-slot-button-size: inherit;
|
|
285
|
+
--text-x-slot-choice-size: inherit;
|
|
286
|
+
|
|
160
287
|
/* Sentinel for the consumer's build (#316). Zero-width, so applying it does nothing.
|
|
161
288
|
* Its only job is to exist: `p-x-source-probe` appears nowhere except this kit's `dist`,
|
|
162
289
|
* so a build that generates it has the kit in its `@source`, and a build that does not
|