@hideyukimori/nene2-ui 0.20.0 â 0.21.1
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 +14 -0
- package/dist/feedback/InlineAlert.d.ts +11 -5
- package/dist/feedback/InlineAlert.js +10 -3
- package/dist/feedback/InlineAlert.js.map +1 -1
- package/dist/feedback/ToastProvider.d.ts +6 -1
- package/dist/feedback/ToastProvider.js +8 -3
- package/dist/feedback/ToastProvider.js.map +1 -1
- package/dist/overlay/Modal.d.ts +27 -0
- package/dist/overlay/Modal.js +12 -2
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/primitives/Button.js +13 -1
- package/dist/primitives/Button.js.map +1 -1
- package/package.json +1 -1
- package/themes/default.css +16 -2
package/README.md
CHANGED
|
@@ -418,6 +418,20 @@ a component list that lags the code is how a product ends up writing a part that
|
|
|
418
418
|
`react-hook-form`'s `register`, and pick up their `id` / `aria-describedby` from the
|
|
419
419
|
`FormField` around them.
|
|
420
420
|
|
|
421
|
+
### ðī Testing that a Modal closed
|
|
422
|
+
|
|
423
|
+
A closed `Modal` is still in the DOM: it is a native `<dialog>` closed with `close()`, not
|
|
424
|
+
unmounted. Testing Library's `getByLabelText` and `getByText` find hidden elements too, so they
|
|
425
|
+
pass whether the dialog is open or not. Assert on the role instead â `getByRole` skips what is
|
|
426
|
+
not in the accessibility tree:
|
|
427
|
+
|
|
428
|
+
```tsx
|
|
429
|
+
expect(screen.queryByRole('dialog', { name: 'Edit' })).toBeNull();
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
jsdom computes no styles, so it cannot tell you a closed dialog is _visible_ either (#533 was
|
|
433
|
+
found from a screenshot). That check needs a real browser.
|
|
434
|
+
|
|
421
435
|
### Not yet here
|
|
422
436
|
|
|
423
437
|
`BrandMark` â measured as recurring
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
export interface InlineAlertProps {
|
|
3
|
-
/** What the message means. `danger` is announced assertively;
|
|
4
|
-
tone?: 'info' | 'warn' | 'danger';
|
|
3
|
+
/** What the message means. `danger` is announced assertively; the rest politely. */
|
|
4
|
+
tone?: 'info' | 'warn' | 'danger' | 'success';
|
|
5
5
|
/**
|
|
6
6
|
* ðī Needed to point an `aria-describedby` at this message. Without it a product that
|
|
7
7
|
* wants the alert read out with a control has nowhere to put an id, and nene-vault
|
|
@@ -22,8 +22,14 @@ export interface InlineAlertProps {
|
|
|
22
22
|
* someone listening and no one looking. The palette now carries `warn` of its own.
|
|
23
23
|
*
|
|
24
24
|
* ðī The tone decides the ARIA role, not just the colour. `danger` becomes `role="alert"`,
|
|
25
|
-
* which interrupts a screen reader;
|
|
26
|
-
* Six ships wrote this component (three as `InlineAlert`, three as `Alert`) and
|
|
27
|
-
* of role is precisely the part that is easy to get wrong and invisible when you
|
|
25
|
+
* which interrupts a screen reader; every other tone becomes `role="status"`, which waits
|
|
26
|
+
* its turn. Six ships wrote this component (three as `InlineAlert`, three as `Alert`) and
|
|
27
|
+
* the choice of role is precisely the part that is easy to get wrong and invisible when you
|
|
28
|
+
* do.
|
|
29
|
+
*
|
|
30
|
+
* ðī `success` (#486) is deliberately **polite**, not assertive. Good news does not earn an
|
|
31
|
+
* interruption, and `ToastProvider` already settled the same question the same way
|
|
32
|
+
* (`POLITE_TONES = ['info', 'success']`). Announcing a success assertively would cut off
|
|
33
|
+
* whatever the person was reading to tell them nothing went wrong.
|
|
28
34
|
*/
|
|
29
35
|
export declare function InlineAlert({ tone, id, className, children }: InlineAlertProps): import("react").JSX.Element;
|
|
@@ -4,6 +4,7 @@ const TONE_CLASS = {
|
|
|
4
4
|
info: 'bg-x-slot-alert-info-bg text-x-slot-alert-info-fg border-x-slot-alert-info-border',
|
|
5
5
|
warn: 'bg-x-slot-alert-warn-bg text-x-slot-alert-warn-fg border-x-slot-alert-warn-border',
|
|
6
6
|
danger: 'bg-x-slot-alert-danger-bg text-x-slot-alert-danger-fg border-x-slot-alert-danger-border',
|
|
7
|
+
success: 'bg-x-slot-alert-success-bg text-x-slot-alert-success-fg border-x-slot-alert-success-border',
|
|
7
8
|
};
|
|
8
9
|
/**
|
|
9
10
|
* A message attached to the thing it is about, rather than to the page.
|
|
@@ -14,9 +15,15 @@ const TONE_CLASS = {
|
|
|
14
15
|
* someone listening and no one looking. The palette now carries `warn` of its own.
|
|
15
16
|
*
|
|
16
17
|
* ðī The tone decides the ARIA role, not just the colour. `danger` becomes `role="alert"`,
|
|
17
|
-
* which interrupts a screen reader;
|
|
18
|
-
* Six ships wrote this component (three as `InlineAlert`, three as `Alert`) and
|
|
19
|
-
* of role is precisely the part that is easy to get wrong and invisible when you
|
|
18
|
+
* which interrupts a screen reader; every other tone becomes `role="status"`, which waits
|
|
19
|
+
* its turn. Six ships wrote this component (three as `InlineAlert`, three as `Alert`) and
|
|
20
|
+
* the choice of role is precisely the part that is easy to get wrong and invisible when you
|
|
21
|
+
* do.
|
|
22
|
+
*
|
|
23
|
+
* ðī `success` (#486) is deliberately **polite**, not assertive. Good news does not earn an
|
|
24
|
+
* interruption, and `ToastProvider` already settled the same question the same way
|
|
25
|
+
* (`POLITE_TONES = ['info', 'success']`). Announcing a success assertively would cut off
|
|
26
|
+
* whatever the person was reading to tell them nothing went wrong.
|
|
20
27
|
*/
|
|
21
28
|
export function InlineAlert({ tone = 'info', id, className, children }) {
|
|
22
29
|
return (_jsx("div", { id: id, role: tone === 'danger' ? 'alert' : 'status', className: cx('rounded-x-slot-alert border p-x-slot-alert-pad font-sans', TONE_CLASS[tone], className), children: children }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InlineAlert.js","sourceRoot":"","sources":["../../src/feedback/InlineAlert.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAiBlC,MAAM,UAAU,GAA0D;IACxE,IAAI,EAAE,mFAAmF;IACzF,IAAI,EAAE,mFAAmF;IACzF,MAAM,EAAE,yFAAyF;
|
|
1
|
+
{"version":3,"file":"InlineAlert.js","sourceRoot":"","sources":["../../src/feedback/InlineAlert.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAiBlC,MAAM,UAAU,GAA0D;IACxE,IAAI,EAAE,mFAAmF;IACzF,IAAI,EAAE,mFAAmF;IACzF,MAAM,EAAE,yFAAyF;IACjG,OAAO,EACL,4FAA4F;CAC/F,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAoB;IACtF,OAAO,CACL,cACE,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,EAC5C,SAAS,EAAE,EAAE,CACX,0DAA0D,EAC1D,UAAU,CAAC,IAAI,CAAC,EAChB,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -25,7 +25,12 @@ export interface ToastProviderProps {
|
|
|
25
25
|
* assistive technology has nothing to have been watching. The toast is on screen, looks
|
|
26
26
|
* right, and is silent â which is why this survived four independent implementations.
|
|
27
27
|
*
|
|
28
|
-
* ðī Two regions, not one. `polite` waits for a pause; `danger` needs `assertive`, which
|
|
28
|
+
* ðī Two live regions, not one. `polite` waits for a pause; `danger` needs `assertive`, which
|
|
29
29
|
* interrupts. Both must pre-exist for the same reason, so both are rendered empty.
|
|
30
|
+
*
|
|
31
|
+
* ðī One landmark, not two (#532). Both live regions used to carry `role="region"` and the
|
|
32
|
+
* same `regionLabel`, which is two landmarks with one name: axe `landmark-unique` fired even
|
|
33
|
+
* with no toast on screen, and a screen reader's landmark list showed "Notifications" twice.
|
|
34
|
+
* The label lives on a single wrapping region; the live regions inside are unnamed.
|
|
30
35
|
*/
|
|
31
36
|
export declare function ToastProvider({ regionLabel, dismissLabel, defaultDurationMs, children, }: ToastProviderProps): import("react").JSX.Element;
|
|
@@ -23,8 +23,13 @@ const ASSERTIVE_TONES = ['danger'];
|
|
|
23
23
|
* assistive technology has nothing to have been watching. The toast is on screen, looks
|
|
24
24
|
* right, and is silent â which is why this survived four independent implementations.
|
|
25
25
|
*
|
|
26
|
-
* ðī Two regions, not one. `polite` waits for a pause; `danger` needs `assertive`, which
|
|
26
|
+
* ðī Two live regions, not one. `polite` waits for a pause; `danger` needs `assertive`, which
|
|
27
27
|
* interrupts. Both must pre-exist for the same reason, so both are rendered empty.
|
|
28
|
+
*
|
|
29
|
+
* ðī One landmark, not two (#532). Both live regions used to carry `role="region"` and the
|
|
30
|
+
* same `regionLabel`, which is two landmarks with one name: axe `landmark-unique` fired even
|
|
31
|
+
* with no toast on screen, and a screen reader's landmark list showed "Notifications" twice.
|
|
32
|
+
* The label lives on a single wrapping region; the live regions inside are unnamed.
|
|
28
33
|
*/
|
|
29
34
|
export function ToastProvider({ regionLabel, dismissLabel, defaultDurationMs = 5000, children, }) {
|
|
30
35
|
const [toasts, setToasts] = useState([]);
|
|
@@ -65,11 +70,11 @@ export function ToastProvider({ regionLabel, dismissLabel, defaultDurationMs = 5
|
|
|
65
70
|
};
|
|
66
71
|
}, []);
|
|
67
72
|
const api = useMemo(() => ({ show, dismiss }), [show, dismiss]);
|
|
68
|
-
const region = (tones, live) => (_jsx("div", { "aria-live": live,
|
|
73
|
+
const region = (tones, live) => (_jsx("div", { "aria-live": live, className: "flex flex-col gap-x-slot-toast-gap", children: toasts
|
|
69
74
|
// čĪæ°ããžãģã1ãĪãŪãŠãžãļã§ãģãļãå
ãŪé
åã filter ãããŪã§ãåããŠãžãļã§ãģãŦ
|
|
70
75
|
// å
ĨãããžãđãååĢŦãŪ**čĄĻįĪšé ãŊ push ãããé ãŪãūãū**ãŦãŠãã
|
|
71
76
|
.filter((toast) => tones.includes(toast.tone))
|
|
72
77
|
.map((toast) => (_jsxs("div", { className: cx('flex items-start gap-x-slot-toast-gap rounded-x-slot-toast border p-x-slot-toast-pad font-sans shadow-x-slot-toast', TONE_CLASS[toast.tone]), children: [toast.description === undefined ? (_jsx("span", { children: toast.message })) : (_jsxs("span", { className: "flex flex-col gap-x-slot-toast-description-gap", children: [_jsx("span", { children: toast.message }), _jsx("span", { className: "text-x-slot-toast-description-fg", children: toast.description })] })), _jsx("button", { type: "button", "aria-label": dismissLabel, onClick: () => dismiss(toast.id), className: cx('rounded-x-slot-toast px-x-slot-toast-dismiss-pad-x', CLICKABLE_CLASS), children: dismissLabel })] }, toast.id))) }));
|
|
73
|
-
return (_jsxs(ToastContext.Provider, { value: api, children: [children, region(POLITE_TONES, 'polite'), region(ASSERTIVE_TONES, 'assertive')] }));
|
|
78
|
+
return (_jsxs(ToastContext.Provider, { value: api, children: [children, _jsxs("div", { role: "region", "aria-label": regionLabel, children: [region(POLITE_TONES, 'polite'), region(ASSERTIVE_TONES, 'assertive')] })] }));
|
|
74
79
|
}
|
|
75
80
|
//# sourceMappingURL=ToastProvider.js.map
|
|
@@ -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;AA0BpG,MAAM,UAAU,GAA8B;IAC5C,IAAI,EAAE,oEAAoE;IAC1E,OAAO,EAAE,oFAAoF;IAC7F,MAAM,EAAE,kFAAkF;CAC3F,CAAC;AAEF,8DAA8D;AAC9D,kDAAkD;AAClD,qCAAqC;AACrC,MAAM,YAAY,GAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACtD,MAAM,eAAe,GAAgB,CAAC,QAAQ,CAAC,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/feedback/ToastProvider.tsx"],"names":[],"mappings":"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"}
|
package/dist/overlay/Modal.d.ts
CHANGED
|
@@ -28,6 +28,20 @@ interface ModalBase {
|
|
|
28
28
|
* `showModal`, so it can only be verified in a real browser (see #392, live lane).
|
|
29
29
|
*/
|
|
30
30
|
scrollable?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The dialog's actions, laid out below the body and **outside its scroll area**.
|
|
33
|
+
*
|
|
34
|
+
* ðī Not a matter of layout â a matter of structure. Pushed into `children`, the action row
|
|
35
|
+
* joins the body's scroll region, so with `scrollable` it slides off the bottom of a tall
|
|
36
|
+
* dialog and the person cannot reach "Confirm". nene-clear uses a footer in **11 of 11**
|
|
37
|
+
* dialogs and makes it a required prop (#493); eight ships wrote a modal and every one of
|
|
38
|
+
* them drew this row.
|
|
39
|
+
*
|
|
40
|
+
* The kit lays the row out end-aligned with a gap, which is what those eleven do. A product
|
|
41
|
+
* that wants another arrangement composes it inside â `footer={<div className="flex w-full
|
|
42
|
+
* justify-between">âĶ</div>}` â rather than the kit growing an alignment prop.
|
|
43
|
+
*/
|
|
44
|
+
footer?: ReactNode;
|
|
31
45
|
children: ReactNode;
|
|
32
46
|
}
|
|
33
47
|
interface PlainModal extends ModalBase {
|
|
@@ -37,6 +51,19 @@ interface PlainModal extends ModalBase {
|
|
|
37
51
|
interface HeaderModal extends ModalBase {
|
|
38
52
|
/** Draw a header: the title, and a control that closes the dialog. */
|
|
39
53
|
header: true;
|
|
54
|
+
/**
|
|
55
|
+
* Localized one-line description, under the title.
|
|
56
|
+
*
|
|
57
|
+
* ðī On `HeaderModal` only, and deliberately. Without a header the title is never drawn â
|
|
58
|
+
* it becomes the dialog's `aria-label` â so a description would have nothing to sit under
|
|
59
|
+
* and would be dropped in silence. The same reasoning `closeLabel` uses below: let the
|
|
60
|
+
* compiler ask for it exactly where it is going to be rendered.
|
|
61
|
+
*
|
|
62
|
+
* ðī Named `description`, matching `PageHeader` (#492/#497) and `EmptyState` (#456), not
|
|
63
|
+
* clear's local `sub`. Nine of clear's eleven dialogs carry this line (#493). One word for
|
|
64
|
+
* one thing across the kit â the rule `Badge`'s tone vocabulary states, applied to a prop.
|
|
65
|
+
*/
|
|
66
|
+
description?: string;
|
|
40
67
|
/**
|
|
41
68
|
* Localized name for the close control.
|
|
42
69
|
*
|
package/dist/overlay/Modal.js
CHANGED
|
@@ -33,7 +33,7 @@ const SHEET_CLASS = 'max-sm:mt-auto max-sm:mb-0 max-sm:w-full max-sm:max-w-none
|
|
|
33
33
|
* up until a consumer overrode one side of a pair.
|
|
34
34
|
*/
|
|
35
35
|
export function Modal(props) {
|
|
36
|
-
const { open, onClose, title, size, sheetOnMobile, scrollable, children } = props;
|
|
36
|
+
const { open, onClose, title, size, sheetOnMobile, scrollable, footer, children } = props;
|
|
37
37
|
const ref = useRef(null);
|
|
38
38
|
const titleId = useId();
|
|
39
39
|
useEffect(() => {
|
|
@@ -72,6 +72,16 @@ export function Modal(props) {
|
|
|
72
72
|
// The sheet classes below (`max-sm:mt-auto max-sm:mb-0`) always assumed this margin was
|
|
73
73
|
// there; saying it explicitly is the kit owning an assumption it had been borrowing.
|
|
74
74
|
// jsdom does not implement `showModal`, so the position itself is a live-lane check.
|
|
75
|
-
'm-auto 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', size !== undefined && SIZE_CLASS[size], sheetOnMobile === true && SHEET_CLASS,
|
|
75
|
+
'm-auto 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', size !== undefined && SIZE_CLASS[size], sheetOnMobile === true && SHEET_CLASS,
|
|
76
|
+
// The column is what keeps the footer out of the scroll region: the body flexes and
|
|
77
|
+
// scrolls, the footer keeps its height. Without `scrollable` there is nothing to
|
|
78
|
+
// scroll, so the dialog keeps the block layout every caller has had until now.
|
|
79
|
+
// ðī Only while open. A bare `flex` is author-origin `display: flex`, which beats the
|
|
80
|
+
// UA's `dialog:not([open]) { display: none }` â a closed scrollable Modal stayed on
|
|
81
|
+
// screen (#533, found from a screenshot; jsdom computes no styles, so no test saw it).
|
|
82
|
+
scrollable === true && 'open:flex open:flex-col'), children: [props.header === true && (_jsxs("header", { className: "mb-x-slot-modal-header-gap flex items-start justify-between gap-x-slot-modal-header-gap", children: [props.description === undefined ? (_jsx("h2", { id: titleId, className: "font-x-slot-modal-title text-x-slot-modal-title-size", children: title })) : (_jsxs("div", { children: [_jsx("h2", { id: titleId, className: "font-x-slot-modal-title text-x-slot-modal-title-size", children: title }), _jsx("p", { className: "mt-x-slot-modal-description-gap font-sans text-x-slot-modal-description-fg", children: props.description })] })), _jsx("button", { type: "button", "aria-label": props.closeLabel, onClick: onClose, className: "rounded-x-slot-control text-x-slot-modal-close-fg leading-none hover:brightness-x-slot-hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-x-slot-focus-ring", children: _jsx("span", { "aria-hidden": "true", children: "\u00D7" }) })] })), scrollable === true ? _jsx("div", { className: "min-h-0 overflow-y-auto", children: children }) : children, footer !== undefined && (
|
|
83
|
+
// `shrink-0` matters only in the scrollable column, where the body would otherwise
|
|
84
|
+
// take the footer's height with it; it is inert in the block layout.
|
|
85
|
+
_jsx("footer", { className: "mt-x-slot-modal-footer-gap flex shrink-0 justify-end gap-x-slot-modal-footer-gap", children: footer }))] }));
|
|
76
86
|
}
|
|
77
87
|
//# 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,KAAK,EAAE,MAAM,EAAkB,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/overlay/Modal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -106,7 +106,19 @@ const LINK_UNBOX = 'border-0 rounded-none';
|
|
|
106
106
|
// instead of its own. A maximum cannot collide with a height: different property, and it
|
|
107
107
|
// leaves anything already smaller alone.
|
|
108
108
|
const SVG_BOUND = '[&_svg]:max-h-x-slot-button-icon [&_svg]:max-w-x-slot-button-icon';
|
|
109
|
-
|
|
109
|
+
// ðī `whitespace-nowrap` is load-bearing (#501). A button's label is a command, not body
|
|
110
|
+
// copy: it names one action, and a wrapped command reads as two. nene-clear measured 15
|
|
111
|
+
// buttons wrapping on its SP layout (PC 1440x900: zero) â "įĢäŋãéäŋĄ" became four lines at
|
|
112
|
+
// 70px, and "æķčūžãįĒšåŪ" broke *inside* a word as "æķčūžã / įĒšåŪ".
|
|
113
|
+
//
|
|
114
|
+
// ðī CJK breaks at any character and Latin breaks at word boundaries, so fixing one is not
|
|
115
|
+
// evidence about the other (nene-vault, #477). `nowrap` stops both.
|
|
116
|
+
//
|
|
117
|
+
// This is the same property `Badge` got in #477. It was added there by naming the component
|
|
118
|
+
// rather than by deriving which components need it, so `Button` was simply not on the list â
|
|
119
|
+
// the third instance of that shape (#486 / #501 / #503). The inventory that would have
|
|
120
|
+
// caught all of them at once is a separate, larger piece of work; this line is the stanch.
|
|
121
|
+
const BASE_CLASS = `whitespace-nowrap rounded-x-slot-button border border-transparent inline-flex items-center justify-center gap-x-slot-button-gap font-sans font-x-slot-button ${SVG_BOUND} ${TOUCH_CLASS} ${CLICKABLE_CLASS}`;
|
|
110
122
|
export function Button({ variant = 'solid', tone = 'accent', size = 'md', children, type = 'button', className, ...rest }) {
|
|
111
123
|
const isLink = variant === 'link';
|
|
112
124
|
return (_jsx("button", { type: type, className: cx(BASE_CLASS, isLink ? LINK_UNBOX : PAD_CLASS[size], TEXT_CLASS[size], SHAPE_TONE_CLASS[variant][tone], className), ...rest, children: children }));
|
|
@@ -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,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA6ChE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,gBAAgB,GAGlB;IACF,KAAK,EAAE;QACL,OAAO,EAAE,sFAAsF;QAC/F,MAAM,EAAE,oFAAoF;QAC5F,MAAM,EAAE,oFAAoF;QAC5F,OAAO,EAAE,sFAAsF;QAC/F,IAAI,EAAE,gFAAgF;QACtF,IAAI,EAAE,gFAAgF;KACvF;IACD,OAAO,EAAE;QACP,OAAO,EACL,gGAAgG;QAClG,MAAM,EACJ,8FAA8F;QAChG,MAAM,EACJ,8FAA8F;QAChG,OAAO,EACL,gGAAgG;QAClG,IAAI,EAAE,0FAA0F;QAChG,IAAI,EAAE,0FAA0F;KACjG;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,+CAA+C;QACxD,MAAM,EAAE,8CAA8C;QACtD,MAAM,EAAE,8CAA8C;QACtD,OAAO,EAAE,+CAA+C;QACxD,IAAI,EAAE,4CAA4C;QAClD,IAAI,EAAE,4CAA4C;KACnD;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,kFAAkF;QAC3F,MAAM,EAAE,iFAAiF;QACzF,MAAM,EAAE,iFAAiF;QACzF,OAAO,EAAE,kFAAkF;QAC3F,IAAI,EAAE,+EAA+E;QACrF,IAAI,EAAE,+EAA+E;KACtF;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,SAAS,GAAqD;IAClE,EAAE,EAAE,+CAA+C;IACnD,EAAE,EAAE,qDAAqD;CAC1D,CAAC;AAEF,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,yBAAyB;IAC7B,EAAE,EAAE,4BAA4B;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C,2FAA2F;AAC3F,4FAA4F;AAC5F,0FAA0F;AAC1F,wFAAwF;AACxF,6FAA6F;AAC7F,yFAAyF;AACzF,kCAAkC;AAClC,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,8FAA8F;AAC9F,0FAA0F;AAC1F,EAAE;AACF,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,
|
|
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,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA6ChE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,gBAAgB,GAGlB;IACF,KAAK,EAAE;QACL,OAAO,EAAE,sFAAsF;QAC/F,MAAM,EAAE,oFAAoF;QAC5F,MAAM,EAAE,oFAAoF;QAC5F,OAAO,EAAE,sFAAsF;QAC/F,IAAI,EAAE,gFAAgF;QACtF,IAAI,EAAE,gFAAgF;KACvF;IACD,OAAO,EAAE;QACP,OAAO,EACL,gGAAgG;QAClG,MAAM,EACJ,8FAA8F;QAChG,MAAM,EACJ,8FAA8F;QAChG,OAAO,EACL,gGAAgG;QAClG,IAAI,EAAE,0FAA0F;QAChG,IAAI,EAAE,0FAA0F;KACjG;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,+CAA+C;QACxD,MAAM,EAAE,8CAA8C;QACtD,MAAM,EAAE,8CAA8C;QACtD,OAAO,EAAE,+CAA+C;QACxD,IAAI,EAAE,4CAA4C;QAClD,IAAI,EAAE,4CAA4C;KACnD;IACD,IAAI,EAAE;QACJ,OAAO,EAAE,kFAAkF;QAC3F,MAAM,EAAE,iFAAiF;QACzF,MAAM,EAAE,iFAAiF;QACzF,OAAO,EAAE,kFAAkF;QAC3F,IAAI,EAAE,+EAA+E;QACrF,IAAI,EAAE,+EAA+E;KACtF;CACF,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,SAAS,GAAqD;IAClE,EAAE,EAAE,+CAA+C;IACnD,EAAE,EAAE,qDAAqD;CAC1D,CAAC;AAEF,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,yBAAyB;IAC7B,EAAE,EAAE,4BAA4B;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C,2FAA2F;AAC3F,4FAA4F;AAC5F,0FAA0F;AAC1F,wFAAwF;AACxF,6FAA6F;AAC7F,yFAAyF;AACzF,kCAAkC;AAClC,EAAE;AACF,0FAA0F;AAC1F,8FAA8F;AAC9F,8FAA8F;AAC9F,0FAA0F;AAC1F,EAAE;AACF,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,yFAAyF;AACzF,wFAAwF;AACxF,uFAAuF;AACvF,yDAAyD;AACzD,EAAE;AACF,2FAA2F;AAC3F,oEAAoE;AACpE,EAAE;AACF,4FAA4F;AAC5F,6FAA6F;AAC7F,uFAAuF;AACvF,2FAA2F;AAC3F,MAAM,UAAU,GAAG,gKAAgK,SAAS,IAAI,WAAW,IAAI,eAAe,EAAE,CAAC;AAEjO,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,GAAG,OAAO,EACjB,IAAI,GAAG,QAAQ,EACf,IAAI,GAAG,IAAI,EACX,QAAQ,EACR,IAAI,GAAG,QAAQ,EACf,SAAS,EACT,GAAG,IAAI,EACK;IACZ,MAAM,MAAM,GAAG,OAAO,KAAK,MAAM,CAAC;IAClC,OAAO,CACL,iBACE,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,EAAE,CACX,UAAU,EACV,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,EACrC,UAAU,CAAC,IAAI,CAAC,EAChB,gBAAgB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAC/B,SAAS,CACV,KACG,IAAI,YAEP,QAAQ,GACF,CACV,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.21.1",
|
|
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
|
@@ -237,6 +237,11 @@
|
|
|
237
237
|
--color-x-slot-alert-danger-bg: var(--color-surface);
|
|
238
238
|
--color-x-slot-alert-danger-fg: var(--color-danger);
|
|
239
239
|
--color-x-slot-alert-danger-border: var(--color-danger);
|
|
240
|
+
/* `success` (#486). Shaped like `danger`: the surface stays the page's, and the meaning is
|
|
241
|
+
* carried by the border and the text â an alert is read, not filled. */
|
|
242
|
+
--color-x-slot-alert-success-bg: var(--color-surface);
|
|
243
|
+
--color-x-slot-alert-success-fg: var(--color-success);
|
|
244
|
+
--color-x-slot-alert-success-border: var(--color-success);
|
|
240
245
|
--color-x-slot-field-label: var(--color-text-muted);
|
|
241
246
|
--color-x-slot-field-hint: var(--color-text-muted);
|
|
242
247
|
--text-x-slot-field-hint-size: var(--text-x-2xs);
|
|
@@ -410,8 +415,10 @@
|
|
|
410
415
|
--color-x-slot-toast-border: var(--color-border);
|
|
411
416
|
--color-x-slot-toast-danger-fg: var(--color-danger);
|
|
412
417
|
--color-x-slot-toast-danger-border: var(--color-danger);
|
|
413
|
-
/* `success` tone (#457).
|
|
414
|
-
* the
|
|
418
|
+
/* `success` tone (#457). â ïļ This comment claimed InlineAlert already carried the meaning.
|
|
419
|
+
* It did not, and would not until #486 â the sentence was written from the enumeration in
|
|
420
|
+
* the issue rather than from the component. Corrected here rather than deleted: a note
|
|
421
|
+
* that was wrong about a neighbour is the exact shape #486 is about. */
|
|
415
422
|
--color-x-slot-toast-success-fg: var(--color-success);
|
|
416
423
|
--color-x-slot-toast-success-border: var(--color-success);
|
|
417
424
|
/* The toast's second line (#457). Only read when `description` is passed. */
|
|
@@ -524,12 +531,19 @@
|
|
|
524
531
|
--container-x-slot-modal-lg: var(--container-xl);
|
|
525
532
|
|
|
526
533
|
--spacing-x-slot-modal-header-gap: var(--spacing-x-xs);
|
|
534
|
+
/* The action row (#493). One slot for both the space above it and the space between the
|
|
535
|
+
* buttons: they are the same rhythm, and a product that wants them apart can say so. */
|
|
536
|
+
--spacing-x-slot-modal-footer-gap: var(--spacing-x-xs);
|
|
537
|
+
/* The dialog's second line (#493). Only read when `description` is passed. Same value as
|
|
538
|
+
* PageHeader's and EmptyState's â one word, one look. */
|
|
539
|
+
--spacing-x-slot-modal-description-gap: var(--spacing-x-3xs);
|
|
527
540
|
--font-weight-x-slot-modal-title: var(--font-weight-medium);
|
|
528
541
|
/* `inherit`, so the header title takes the dialog's own size unless a product says
|
|
529
542
|
* otherwise. There is no previous rendering to copy â the header is new â and picking a
|
|
530
543
|
* step here would decide type for every product that turns the header on. */
|
|
531
544
|
--text-x-slot-modal-title-size: inherit;
|
|
532
545
|
--color-x-slot-modal-close-fg: var(--color-text-muted);
|
|
546
|
+
--color-x-slot-modal-description-fg: var(--color-text-muted);
|
|
533
547
|
|
|
534
548
|
/* ââ Shadow slots âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
|
|
535
549
|
* ðī Shadow was the one dimension that never got slots (#386). 0.9.0 moved "colour, weight
|