@hideyukimori/nene2-ui 0.7.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 +76 -1
- 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 +176 -1
package/README.md
CHANGED
|
@@ -153,7 +153,16 @@ component follows.
|
|
|
153
153
|
|
|
154
154
|
### ① The scale — 🔒 do not redefine
|
|
155
155
|
|
|
156
|
-
`--spacing-x-3xs` … `--spacing-x-2xl`,
|
|
156
|
+
`--spacing-x-3xs` … `--spacing-x-2xl`, `--radius-x-none` … `--radius-x-3xl` plus
|
|
157
|
+
`--radius-x-pill`, `--text-x-2xs` … `--text-x-xl`, and the colour palette.
|
|
158
|
+
|
|
159
|
+
🔴 **A namespace with one step has no slots, only aliases.** Until 0.8.0 the radius
|
|
160
|
+
namespace held a single value and eight slots pointed at it, so a product following the
|
|
161
|
+
rules could render exactly one rounding — and every structural check passed, because the
|
|
162
|
+
slots existed and their defaults referenced the scale. The scale had been promoted verbatim
|
|
163
|
+
from the one product with the fewest conformance violations, which turned out to be the
|
|
164
|
+
product with the fewest choices. **A component implementation may come from one ship; the
|
|
165
|
+
set of choices may only come from the fleet's distribution.**
|
|
157
166
|
|
|
158
167
|
```css
|
|
159
168
|
--spacing-x-slot-card-pad: 1.375rem; /* 🔴 no */
|
|
@@ -177,6 +186,21 @@ to match it also fits _worse_, not better:
|
|
|
177
186
|
More exact matches, five times the worst error — a scale bent toward one histogram drops its
|
|
178
187
|
own ends.
|
|
179
188
|
|
|
189
|
+
The radius scale was measured the same way, across the 266 radius values ten products apply
|
|
190
|
+
(2026-08-23). Candidates were scored on a second axis as well: whether two values that exist
|
|
191
|
+
**by design** land on the same step. Average error alone would have accepted folding `2px`
|
|
192
|
+
into `0`, because 2px is a 2px error — but nene-records ships nine themes at 0px and three at
|
|
193
|
+
2–3px as separate product themes, so that error deletes a distinction rather than rounding
|
|
194
|
+
one.
|
|
195
|
+
|
|
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
|
+
| eight, without a `10px` step | 64.3% | 97.7% | 4 |
|
|
200
|
+
| seven, without `2px` | 43.2% | 97.7% | 4 |
|
|
201
|
+
|
|
202
|
+
🔑 **A scale is judged by what it can still tell apart, not only by how far it moves things.**
|
|
203
|
+
|
|
180
204
|
🔑 **The scale is the set you keep to. The slots are what your brand looks like.**
|
|
181
205
|
|
|
182
206
|
### 🔴 One slot is not yours to tune
|
|
@@ -219,6 +243,38 @@ it can be checked with a regular expression exactly as written.
|
|
|
219
243
|
| `--color-*` | scale (palette) references | same |
|
|
220
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 |
|
|
221
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
|
+
|
|
222
278
|
🔴 **Check the three namespaces that have scales, not every slot.** Until 0.6.0 this section
|
|
223
279
|
said "and nothing else", while the kit's own theme held `--text-x-slot-field-label-size:
|
|
224
280
|
0.75rem` and `--brightness-x-slot-hover: 95%` — so a product implementing the rule as written
|
|
@@ -239,6 +295,25 @@ a missing component — open an issue, so every product gets the answer.
|
|
|
239
295
|
**Products: apply the same check to your own theme.** The kit can only police its own file;
|
|
240
296
|
the rule is the same one, and the regular expression above is the whole implementation.
|
|
241
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
|
+
|
|
242
317
|
## What is in scope
|
|
243
318
|
|
|
244
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
|
@@ -138,7 +138,12 @@
|
|
|
138
138
|
--color-x-slot-field-error: var(--color-danger);
|
|
139
139
|
--text-x-slot-field-error-size: var(--text-x-2xs);
|
|
140
140
|
--text-x-slot-field-label-size: var(--text-x-xs);
|
|
141
|
-
--font-weight-
|
|
141
|
+
/* 🔴 `var(--font-weight-medium)`, not `500`. Identical output — Tailwind defines that
|
|
142
|
+
* step as 500 — but a literal here is a weight the kit invented, and the namespace has a
|
|
143
|
+
* nine-step scale already (thin…black). This one escaped the "slot defaults are scale
|
|
144
|
+
* references only" check because that check listed the namespaces it knew about; found
|
|
145
|
+
* while adding the radius scale (#348). */
|
|
146
|
+
--font-weight-x-slot-field-label: var(--font-weight-medium);
|
|
142
147
|
/* Control text. Two slots, because one value cannot answer "how is this being pointed at".
|
|
143
148
|
*
|
|
144
149
|
* 0.6.0 used `max(var(--text-x-md), var(--text-x-ios-floor))`, which raised every control
|
|
@@ -152,6 +157,133 @@
|
|
|
152
157
|
--text-x-slot-control-size: var(--text-x-md);
|
|
153
158
|
--text-x-slot-control-touch-size: var(--text-x-ios-floor);
|
|
154
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
|
+
|
|
155
287
|
/* Sentinel for the consumer's build (#316). Zero-width, so applying it does nothing.
|
|
156
288
|
* Its only job is to exist: `p-x-source-probe` appears nowhere except this kit's `dist`,
|
|
157
289
|
* so a build that generates it has the kit in its `@source`, and a build that does not
|
|
@@ -163,7 +295,50 @@
|
|
|
163
295
|
* gave them nothing (50 x10, 40 x4, 30 x6, measured 2026-08-23 across 20 uses). */
|
|
164
296
|
--opacity-x-disabled: 50%;
|
|
165
297
|
|
|
298
|
+
/* The radius scale. Nine steps plus pill, chosen the same way the spacing scale was —
|
|
299
|
+
* by measuring the fleet, not by taste. Snapping the 266 radius values the fleet actually
|
|
300
|
+
* applies (`border-radius` declarations and `--radius-*` theme tokens across ten products,
|
|
301
|
+
* 2026-08-23, #348) onto these nine puts 69.9% exactly on a step and 97.7% within 2px.
|
|
302
|
+
*
|
|
303
|
+
* 🔴 This replaces a scale that had ONE step. Eight slots all pointed at `--radius-x-md`,
|
|
304
|
+
* so a product following the rules could only ever render 8px — and a slot whose value set
|
|
305
|
+
* has one member is not a slot. The cause is recorded because it generalizes: the kit's
|
|
306
|
+
* theme was promoted verbatim from nene-payout, and payout is the fleet's only product
|
|
307
|
+
* with a single radius. Promoting from the product with the fewest conformance violations
|
|
308
|
+
* exported its poverty as the norm — having no choices is not the same as choosing well.
|
|
309
|
+
* A component implementation may come from one ship; the SET OF CHOICES may not.
|
|
310
|
+
*
|
|
311
|
+
* 🔴 `2px` is its own step because it is the single most common radius in the fleet
|
|
312
|
+
* (56 of 266). nene-records ships 9 themes at 0px and 3 at 2-3px as separate product
|
|
313
|
+
* themes — so folding 2px into 0 would not be a rounding error, it would delete a
|
|
314
|
+
* distinction somebody drew on purpose. Candidate scales were therefore scored on a
|
|
315
|
+
* second axis besides average error: whether two values that exist by design collapse
|
|
316
|
+
* onto one step (vault's proposal). The steps kept apart here are 0/2, 6/8 and 10/12;
|
|
317
|
+
* what still collapses (3-4, 5-6, 9-10) is 1px apart, below a scale's resolution.
|
|
318
|
+
*
|
|
319
|
+
* `--radius-x-md` keeps the value it had. Every slot points at it, so changing it would
|
|
320
|
+
* move every product's appearance silently — the scale gains steps, the default does not
|
|
321
|
+
* move. */
|
|
322
|
+
--radius-x-none: 0;
|
|
323
|
+
--radius-x-2xs: 2px;
|
|
324
|
+
--radius-x-xs: 4px;
|
|
325
|
+
--radius-x-sm: 6px;
|
|
166
326
|
--radius-x-md: 0.5rem;
|
|
327
|
+
--radius-x-lg: 10px;
|
|
328
|
+
--radius-x-xl: 12px;
|
|
329
|
+
--radius-x-2xl: 16px;
|
|
330
|
+
--radius-x-3xl: 24px;
|
|
331
|
+
|
|
332
|
+
/* Fully round. A step, not a footnote: `rounded-x-pill` is the most-used radius in
|
|
333
|
+
* nene-field (48 uses) and appears in five products (64 uses total).
|
|
334
|
+
*
|
|
335
|
+
* 🔴 A product whose design language has no rounding does NOT redefine this step — it
|
|
336
|
+
* points its slots at `--radius-x-none`. nene-records reaches the same end today by
|
|
337
|
+
* setting its own `--radius-full: 0px`, which works only because its components hard-code
|
|
338
|
+
* `rounded-full`. Overriding a scale step changes what a name means fleet-wide; overriding
|
|
339
|
+
* a slot changes one product's choice. The second is the mechanism; the first is the drift
|
|
340
|
+
* the scale exists to prevent. */
|
|
341
|
+
--radius-x-pill: 9999px;
|
|
167
342
|
|
|
168
343
|
/* The spacing scale. Nine steps, chosen by measurement rather than taste: snapping the
|
|
169
344
|
* 944 spacing utilities the fleet writes by hand onto these nine moves 98.2% of them by
|