@hideyukimori/nene2-ui 0.17.1 → 0.18.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.
@@ -5,8 +5,14 @@ import { CLICKABLE_CLASS } from '../lib/states.js';
5
5
  import { ToastContext } from './toast-context.js';
6
6
  const TONE_CLASS = {
7
7
  info: 'bg-x-slot-toast-bg text-x-slot-toast-fg border-x-slot-toast-border',
8
+ success: 'bg-x-slot-toast-bg text-x-slot-toast-success-fg border-x-slot-toast-success-border',
8
9
  danger: 'bg-x-slot-toast-bg text-x-slot-toast-danger-fg border-x-slot-toast-danger-border',
9
10
  };
11
+ // 🔴 `success` は polite 側。`assertive` は読み上げを中断させるので、成功の報告に使うと
12
+ // 利用者の作業を割り込みで止める。中断してよいのは danger だけ、というのが2リージョンに
13
+ // 分けた元の理由なので、語彙が増えてもその線は動かさない(#457)。
14
+ const POLITE_TONES = ['info', 'success'];
15
+ const ASSERTIVE_TONES = ['danger'];
10
16
  /**
11
17
  * Hosts the toast queue and the live regions that announce it.
12
18
  *
@@ -34,7 +40,18 @@ export function ToastProvider({ regionLabel, dismissLabel, defaultDurationMs = 5
34
40
  }, []);
35
41
  const show = useCallback((message, options) => {
36
42
  const id = `toast-${(nextId.current += 1)}`;
37
- setToasts((current) => [...current, { id, message, tone: options?.tone ?? 'info' }]);
43
+ const description = options?.description;
44
+ setToasts((current) => [
45
+ ...current,
46
+ {
47
+ id,
48
+ message,
49
+ tone: options?.tone ?? 'info',
50
+ // exactOptionalPropertyTypes: 省略と `undefined` を渡すことは別物なので、
51
+ // 渡されなかった場合はキーごと作らない。
52
+ ...(description === undefined ? {} : { description }),
53
+ },
54
+ ]);
38
55
  timers.current.set(id, setTimeout(() => dismiss(id), options?.durationMs ?? defaultDurationMs));
39
56
  return id;
40
57
  }, [defaultDurationMs, dismiss]);
@@ -48,9 +65,11 @@ export function ToastProvider({ regionLabel, dismissLabel, defaultDurationMs = 5
48
65
  };
49
66
  }, []);
50
67
  const api = useMemo(() => ({ show, dismiss }), [show, dismiss]);
51
- const region = (tone, live) => (_jsx("div", { "aria-live": live, "aria-label": regionLabel, role: "region", className: "flex flex-col gap-x-slot-toast-gap", children: toasts
52
- .filter((toast) => toast.tone === tone)
53
- .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: [_jsx("span", { children: toast.message }), _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))) }));
54
- return (_jsxs(ToastContext.Provider, { value: api, children: [children, region('info', 'polite'), region('danger', 'assertive')] }));
68
+ const region = (tones, live) => (_jsx("div", { "aria-live": live, "aria-label": regionLabel, role: "region", className: "flex flex-col gap-x-slot-toast-gap", children: toasts
69
+ // 複数トーンを1つのリージョンへ。元の配列を filter するので、同じリージョンに
70
+ // 入るトースト同士の**表示順は push された順のまま**になる。
71
+ .filter((toast) => tones.includes(toast.tone))
72
+ .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')] }));
55
74
  }
56
75
  //# sourceMappingURL=ToastProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/feedback/ToastProvider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ToastProvider.js","sourceRoot":"","sources":["../../src/feedback/ToastProvider.tsx"],"names":[],"mappings":"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"}
@@ -1,8 +1,27 @@
1
- export type ToastTone = 'info' | 'danger';
1
+ /**
2
+ * 🔴 `success` は 0.17.x まで無く、`info | danger` の2語彙だった。`Badge` と `InlineAlert`
3
+ * は既に `success` を持っており(Badge は neutral|accent|danger|success|warn|info)、
4
+ * **トーストだけ語彙が2つ**という状態は 0.17.0 #422 の「一つの語彙をキット全体で」と
5
+ * 噛み合わない。nene-deal は完了を緑で伝えており、`info` に寄せると保存・移動・削除の
6
+ * 完了が中立色になって、エラーとの差が「赤かどうか」だけになる(#457)。
7
+ */
8
+ export type ToastTone = 'info' | 'success' | 'danger';
2
9
  export interface ToastOptions {
3
10
  tone?: ToastTone;
4
11
  /** Overrides the provider's default. */
5
12
  durationMs?: number;
13
+ /**
14
+ * Localized second line: what the action applied to.
15
+ *
16
+ * 🔴 Not decoration. nene-deal's success toasts carry one at **7 of 7** call sites — the
17
+ * deal that moved, the stage it moved to, the range that was exported. `show(message)`
18
+ * alone drops that text, and joining the two halves is not available to the ship: they are
19
+ * separate catalog keys, so the separator would be a string owned by the ship, against
20
+ * principle 4 (#457).
21
+ *
22
+ * Omit it and the render is what it was before this prop existed.
23
+ */
24
+ description?: string;
6
25
  }
7
26
  export interface ToastApi {
8
27
  /** Shows a toast and returns its id, so a caller can dismiss it early. */
@@ -1 +1 @@
1
- {"version":3,"file":"toast-context.js","sourceRoot":"","sources":["../../src/feedback/toast-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAgBlD,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAkB,IAAI,CAAC,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"toast-context.js","sourceRoot":"","sources":["../../src/feedback/toast-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAmClD,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAkB,IAAI,CAAC,CAAC;AAEjE;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,GAAG,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACrC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -4,7 +4,7 @@ import { CLICKABLE_CLASS, TOUCH_CLASS } from '../lib/states.js';
4
4
  const VARIANT_CLASS = {
5
5
  primary: 'bg-x-slot-button-primary-bg text-x-slot-button-primary-fg shadow-x-slot-button-primary',
6
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',
7
+ danger: 'bg-x-slot-button-danger-bg text-x-slot-button-danger-fg border-x-slot-button-danger-border',
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
10
  ghost: 'bg-transparent text-x-slot-button-ghost-fg',
@@ -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;AAchE,MAAM,aAAa,GAAwD;IACzE,OAAO,EAAE,wFAAwF;IACjG,SAAS,EACP,qGAAqG;IACvG,MAAM,EAAE,yDAAyD;IACjE,uFAAuF;IACvF,kEAAkE;IAClE,KAAK,EAAE,4CAA4C;CACpD,CAAC;AAEF,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,uEAAuE;IAC3E,EAAE,EAAE,gFAAgF;CACrF,CAAC;AAEF,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,8IAA8I,SAAS,IAAI,WAAW,IAAI,eAAe,EAAE,CAAC;AAE/M,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"}
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;AAchE,MAAM,aAAa,GAAwD;IACzE,OAAO,EAAE,wFAAwF;IACjG,SAAS,EACP,qGAAqG;IACvG,MAAM,EACJ,4FAA4F;IAC9F,uFAAuF;IACvF,kEAAkE;IAClE,KAAK,EAAE,4CAA4C;CACpD,CAAC;AAEF,MAAM,UAAU,GAAqD;IACnE,EAAE,EAAE,uEAAuE;IAC3E,EAAE,EAAE,gFAAgF;CACrF,CAAC;AAEF,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,8IAA8I,SAAS,IAAI,WAAW,IAAI,eAAe,EAAE,CAAC;AAE/M,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"}
@@ -11,5 +11,18 @@ export interface EmptyStateProps {
11
11
  align?: 'center' | 'start';
12
12
  /** Localized message. The kit never ships strings — see README. */
13
13
  message: string;
14
+ /**
15
+ * Localized second line: what the empty area would hold, or how to fill it.
16
+ *
17
+ * 🔴 Not decoration. nene-deal's empty states carry two lines at three of their four call
18
+ * sites ("No deals yet" / "Create one from the board"), and folding them into `message`
19
+ * is not available to it: the two halves are separate catalog keys (`*.empty.title` and
20
+ * `*.empty.description`), so joining them would put the separator — a string — in the
21
+ * ship, against principle 4. Without this prop the second line has nowhere to go and the
22
+ * text is simply dropped (#456).
23
+ *
24
+ * Omit it and the render is byte-for-byte what it was before this prop existed.
25
+ */
26
+ description?: string;
14
27
  }
15
- export declare function EmptyState({ message, align, className }: EmptyStateProps): import("react").JSX.Element;
28
+ export declare function EmptyState({ message, description, align, className }: EmptyStateProps): import("react").JSX.Element;
@@ -1,6 +1,6 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cx } from '../lib/cx.js';
3
- export function EmptyState({ message, align = 'center', className }) {
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 }));
3
+ export function EmptyState({ message, description, align = 'center', className }) {
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: description === undefined ? (message) : (_jsxs(_Fragment, { children: [_jsx("p", { children: message }), _jsx("p", { className: "mt-x-slot-empty-state-gap text-x-slot-empty-state-description-fg", children: description })] })) }));
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,4DAA4D,EAC5D,KAAK,KAAK,QAAQ,IAAI,aAAa,EACnC,SAAS,CACV,EACD,IAAI,EAAC,QAAQ,YAEZ,OAAO,GACJ,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"EmptyState.js","sourceRoot":"","sources":["../../src/states/EmptyState.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AA6BlC,MAAM,UAAU,UAAU,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAmB;IAC/F,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CACX,4DAA4D,EAC5D,KAAK,KAAK,QAAQ,IAAI,aAAa,EACnC,SAAS,CACV,EACD,IAAI,EAAC,QAAQ,YAKZ,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,CAC3B,OAAO,CACR,CAAC,CAAC,CAAC,CACF,8BACE,sBAAI,OAAO,GAAK,EAChB,YAAG,SAAS,EAAC,kEAAkE,YAC5E,WAAW,GACV,IACH,CACJ,GACG,CACP,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hideyukimori/nene2-ui",
3
- "version": "0.17.1",
3
+ "version": "0.18.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",
@@ -173,6 +173,8 @@
173
173
  --spacing-x-slot-detail-row-pad-y: var(--spacing-x-xs);
174
174
  --spacing-x-slot-state-pad-y: var(--spacing-x-xl);
175
175
  --spacing-x-slot-state-action-pad-y: var(--spacing-x-xs);
176
+ /* Between an EmptyState's two lines (#456). Only read when `description` is passed. */
177
+ --spacing-x-slot-empty-state-gap: var(--spacing-x-3xs);
176
178
  --spacing-x-slot-page-header-pad-y: var(--spacing-x-md);
177
179
 
178
180
  --radius-x-slot-button: var(--radius-x-md);
@@ -273,6 +275,13 @@
273
275
  --color-x-slot-button-secondary-border: var(--color-border);
274
276
  --color-x-slot-button-danger-bg: var(--color-danger);
275
277
  --color-x-slot-button-danger-fg: var(--color-on-accent);
278
+ /* 🔴 Defaults to the fill, so a filled danger button looks exactly as it did: the border
279
+ * and the background are the same colour, which is what `border-transparent` over a filled
280
+ * background already rendered. The slot exists for the ships whose danger button is an
281
+ * outline rather than a fill — nene-deal's is `background: transparent` with a tinted
282
+ * border (#455), and it could not express that: the variant emitted no border class at
283
+ * all, so `border-transparent` from BASE_CLASS won and no slot value could reach it. */
284
+ --color-x-slot-button-danger-border: var(--color-danger);
276
285
  --color-x-slot-button-ghost-fg: var(--color-text-primary);
277
286
 
278
287
  /* Shared by Input, Select and Textarea — they are one control with three shapes, and a
@@ -336,6 +345,13 @@
336
345
  --color-x-slot-toast-border: var(--color-border);
337
346
  --color-x-slot-toast-danger-fg: var(--color-danger);
338
347
  --color-x-slot-toast-danger-border: var(--color-danger);
348
+ /* `success` tone (#457). Badge and InlineAlert already carry this meaning; the toast is
349
+ * the one surface that had only two. */
350
+ --color-x-slot-toast-success-fg: var(--color-success);
351
+ --color-x-slot-toast-success-border: var(--color-success);
352
+ /* The toast's second line (#457). Only read when `description` is passed. */
353
+ --color-x-slot-toast-description-fg: var(--color-text-muted);
354
+ --spacing-x-slot-toast-description-gap: var(--spacing-x-3xs);
339
355
 
340
356
  --color-x-slot-card-bg: var(--color-surface-raised);
341
357
  --color-x-slot-card-border: var(--color-border);
@@ -361,6 +377,10 @@
361
377
  --color-x-slot-text-muted-fg: var(--color-text-muted);
362
378
  --color-x-slot-spinner-fg: var(--color-text-muted);
363
379
  --color-x-slot-empty-state-fg: var(--color-text-muted);
380
+ /* The second line of an EmptyState (#456). Same value as the first by default, so a ship
381
+ * that adopts `description` gets one uniform block until it decides otherwise; a ship that
382
+ * wants the hierarchy overrides one of the two. No existing render reads this. */
383
+ --color-x-slot-empty-state-description-fg: var(--color-text-muted);
364
384
  --color-x-slot-error-state-fg: var(--color-danger);
365
385
  /* 🔴 The required marker, not the error message — that one is `--color-x-slot-field-error`.
366
386
  * Named `-error-fg` when the colour slots were swept in (0.9.0, same day), which reads as