@molecule/app-ui-react 1.1.0 → 1.2.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.
@@ -0,0 +1,71 @@
1
+ /**
2
+ * LoadErrorBanner component — the shared "load failed" banner with Retry.
3
+ *
4
+ * The fleet hand-rolled this in dozens of apps (an error line + a Retry
5
+ * button, each drifting in wording, styling, and pending behavior). Use it
6
+ * wherever a page/section fetch FAILS — it pairs with `Skeleton` for the
7
+ * loading state and `EmptyState` for the empty one. For form-submit errors
8
+ * use `<Alert status="error">` instead; this banner is specifically the
9
+ * load-failure-with-retry pattern, and its Retry button owns the
10
+ * pending/disabled state so the caller cannot double-fire it.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { LoadErrorBanner } from '@molecule/app-ui-react'
15
+ *
16
+ * {error ? (
17
+ * <LoadErrorBanner
18
+ * message={t('decks.loadFailed', {}, { defaultValue: 'Could not load decks.' })}
19
+ * onRetry={load} // return the promise — pending state is automatic
20
+ * />
21
+ * ) : (
22
+ * <DeckList decks={decks} />
23
+ * )}
24
+ * ```
25
+ *
26
+ * @remarks
27
+ * Pass `onRetry` as a promise-returning function; while it is pending the
28
+ * retry button is disabled and shows a localized "Retrying…" label, and a
29
+ * rejection is NOT swallowed silently — the banner stays (callers render
30
+ * persistent failure by keeping `error` set, which keeps this banner
31
+ * mounted). Omit `onRetry` and no retry button renders (display-only
32
+ * failure). `data-mol-id` on the ROOT goes through rest props (fleet
33
+ * locator convention); the retry button carries `retryMolId`
34
+ * (default `load-error-retry`) so e2e can click it without knowing the
35
+ * page. Announced politely (`role="status"` via the inner Alert's
36
+ * `live={false}`) — a load failure on initial render has nothing to
37
+ * interrupt.
38
+ *
39
+ * @module
40
+ */
41
+ import type { JSX } from 'react';
42
+ import React from 'react';
43
+ /**
44
+ * Props for {@link LoadErrorBanner}. Rest props are forwarded to the root
45
+ * `<div>`, so they are typed as its attributes.
46
+ */
47
+ export interface LoadErrorBannerProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
48
+ /** The primary error line (e.g. the localized "Could not load X."). */
49
+ message: React.ReactNode;
50
+ /** Secondary line under the message (status code, hint). */
51
+ detail?: React.ReactNode;
52
+ /**
53
+ * Called when Retry is clicked. Return the promise; while pending, the
54
+ * button is disabled and shows "Retrying…". Omit for a display-only
55
+ * banner.
56
+ */
57
+ onRetry?: () => void | Promise<void>;
58
+ /** Retry-button label. Falls back to a localized "Retry". */
59
+ retryLabel?: React.ReactNode;
60
+ /** `data-mol-id` for the retry button (default `load-error-retry`). */
61
+ retryMolId?: string;
62
+ /** Extra content between message and retry row (e.g. an error code). */
63
+ children?: React.ReactNode;
64
+ }
65
+ /**
66
+ * Error banner with an owned pending-state Retry button.
67
+ *
68
+ * @param props - Component props (see {@link LoadErrorBannerProps}).
69
+ */
70
+ export declare function LoadErrorBanner({ message, detail, onRetry, retryLabel, retryMolId, children, ...rest }: LoadErrorBannerProps): JSX.Element;
71
+ //# sourceMappingURL=LoadErrorBanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadErrorBanner.d.ts","sourceRoot":"","sources":["../../src/components/LoadErrorBanner.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,KAAmB,MAAM,OAAO,CAAA;AAQvC;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX;IACC,uEAAuE;IACvE,OAAO,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpC,6DAA6D;IAC7D,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAC9B,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,UAA+B,EAC/B,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CA4CpC"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { useTranslation } from '@molecule/app-react';
4
+ import { getClassMap } from '@molecule/app-ui';
5
+ import { Alert } from './Alert.js';
6
+ import { Button } from './Button.js';
7
+ /**
8
+ * Error banner with an owned pending-state Retry button.
9
+ *
10
+ * @param props - Component props (see {@link LoadErrorBannerProps}).
11
+ */
12
+ export function LoadErrorBanner({ message, detail, onRetry, retryLabel, retryMolId = 'load-error-retry', children, ...rest }) {
13
+ const cm = getClassMap();
14
+ const { t } = useTranslation();
15
+ const [pending, setPending] = useState(false);
16
+ const handleRetry = () => {
17
+ if (!onRetry || pending)
18
+ return;
19
+ setPending(true);
20
+ // A rejected retry means "still failing": the caller owns that error and
21
+ // keeps showing the banner, so ignoring it here only stops it becoming an
22
+ // unhandled rejection.
23
+ void Promise.resolve(onRetry())
24
+ .catch((_error) => undefined)
25
+ .finally(() => setPending(false));
26
+ };
27
+ return (_jsx("div", { ...rest, children: _jsx(Alert, { status: "error", live: false, children: _jsxs("div", { className: cm.stack(2), children: [_jsx("p", { className: cm.textSize('sm'), children: message }), detail ? (_jsx("p", { className: cm.cn(cm.textSize('xs'), 'text-on-surface-variant'), children: detail })) : null, children, onRetry ? (_jsx("div", { className: cm.flex({ justify: 'start' }), children: _jsx(Button, { variant: "outline", size: "sm", onClick: handleRetry, disabled: pending, "data-mol-id": retryMolId, children: pending
28
+ ? t('loadError.retrying', {}, { defaultValue: 'Retrying…' })
29
+ : (retryLabel ?? t('loadError.retry', {}, { defaultValue: 'Retry' })) }) })) : null] }) }) }));
30
+ }
31
+ //# sourceMappingURL=LoadErrorBanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadErrorBanner.js","sourceRoot":"","sources":["../../src/components/LoadErrorBanner.tsx"],"names":[],"mappings":";AA0CA,OAAc,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AA4BpC;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,UAAU,GAAG,kBAAkB,EAC/B,QAAQ,EACR,GAAG,IAAI,EACc;IACrB,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE7C,MAAM,WAAW,GAAG,GAAS,EAAE;QAC7B,IAAI,CAAC,OAAO,IAAI,OAAO;YAAE,OAAM;QAC/B,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,yEAAyE;QACzE,0EAA0E;QAC1E,uBAAuB;QACvB,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;aAC5B,KAAK,CAAC,CAAC,MAAe,EAAE,EAAE,CAAC,SAAS,CAAC;aACrC,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;IACrC,CAAC,CAAA;IAED,OAAO,CACL,iBAAS,IAAI,YACX,KAAC,KAAK,IAAC,MAAM,EAAC,OAAO,EAAC,IAAI,EAAE,KAAK,YAC/B,eAAK,SAAS,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,aACzB,YAAG,SAAS,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAG,OAAO,GAAK,EAC7C,MAAM,CAAC,CAAC,CAAC,CACR,YAAG,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,yBAAyB,CAAC,YAAG,MAAM,GAAK,CAChF,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,EACR,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,YAC3C,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,IAAI,EACT,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,OAAO,iBACJ,UAAU,YAEtB,OAAO;gCACN,CAAC,CAAC,CAAC,CAAC,oBAAoB,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;gCAC5D,CAAC,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,iBAAiB,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC,GAChE,GACL,CACP,CAAC,CAAC,CAAC,IAAI,IACJ,GACA,GACJ,CACP,CAAA;AACH,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * PromptDialog component — the shared "ask for a short string" modal.
3
+ *
4
+ * The shared home for what `window.prompt` used to do (renaming, renaming a
5
+ * board, creating a tag, "invite by email"). `window.prompt` is broken
6
+ * headless (it hangs e2e) and awkward on touch; this renders the same
7
+ * interaction as a real dialog built on {@link Modal}. For a confirm WITHOUT
8
+ * an input use {@link ConfirmDialog}; for an INLINE two-click arm/commit
9
+ * button use {@link ConfirmButton}.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { PromptDialog } from '@molecule/app-ui-react'
14
+ *
15
+ * <PromptDialog
16
+ * open={renameOpen}
17
+ * onClose={() => setRenameOpen(false)}
18
+ * title={t('board.renameTitle', {}, { defaultValue: 'Rename board' })}
19
+ * placeholder={t('board.namePlaceholder', {}, { defaultValue: 'Board name' })}
20
+ * initialValue={board.name}
21
+ * confirmLabel={t('common.save', {}, { defaultValue: 'Save' })}
22
+ * onSubmit={async (name) => {
23
+ * await renameBoard(board.id, name) // resolve → dialog closes
24
+ * }}
25
+ * />
26
+ * ```
27
+ *
28
+ * @remarks
29
+ * `onSubmit` receives the RAW entered value (no trimming — the caller owns
30
+ * validation). Resolve it and the dialog closes and resets; reject or throw
31
+ * and the dialog STAYS OPEN with the value intact — render your error
32
+ * message through `children` (e.g. an `<Alert status="error">`), since the
33
+ * rejection itself is deliberately swallowed here. While the promise is
34
+ * pending the input and both buttons are disabled, so the action cannot
35
+ * double-fire. Enter submits; Escape and the backdrop cancel exactly like a
36
+ * Modal. Optional `inputMolId` / `confirmMolId` / `cancelMolId` render as
37
+ * `data-mol-id` attributes for e2e locators; the buttons are also
38
+ * text-labeled so `getByRole('button', { name })` reaches them.
39
+ *
40
+ * WIZARD GOTCHA (learned the hard way, fleet migration 2026-09-24): a
41
+ * fulfilled submit calls `onClose()` — "close", not "cancel". A multi-stage
42
+ * flow that advances its stage INSIDE `onSubmit` gets clobbered if its
43
+ * `onClose` unconditionally resets to idle (the auto-close fires right
44
+ * after the stage advance). Make `onClose` stage-aware via functional
45
+ * state (`setStage((cur) => (cur === 'name' ? 'idle' : cur))`) so cancel
46
+ * still resets but the post-submit auto-close doesn't undo the advance.
47
+ *
48
+ * @module
49
+ */
50
+ import React, { type JSX } from 'react';
51
+ /** Props for {@link PromptDialog}. */
52
+ export interface PromptDialogProps {
53
+ /** Whether the dialog is open. */
54
+ open: boolean;
55
+ /** Called when the dialog should close (escape, backdrop, cancel, or a fulfilled {@link PromptDialogProps.onSubmit}). */
56
+ onClose: () => void;
57
+ /** Dialog heading. */
58
+ title: React.ReactNode;
59
+ /** Explanatory line under the title. */
60
+ description?: React.ReactNode;
61
+ /** Input placeholder. */
62
+ placeholder?: string;
63
+ /** Value the input starts from every time the dialog opens. */
64
+ initialValue?: string;
65
+ /**
66
+ * Called with the entered value on confirm. Resolve to close the dialog;
67
+ * reject or throw to keep it open (show the error via {@link PromptDialogProps.children}).
68
+ */
69
+ onSubmit: (value: string) => void | Promise<void>;
70
+ /** Confirm-button label. Falls back to a localized "Confirm". */
71
+ confirmLabel?: React.ReactNode;
72
+ /** Cancel-button label. Falls back to a localized "Cancel". */
73
+ cancelLabel?: React.ReactNode;
74
+ /** Render the confirm button in the error color (e.g. an irreversible reset). */
75
+ destructive?: boolean;
76
+ /** `data-mol-id` for the text input. */
77
+ inputMolId?: string;
78
+ /** `data-mol-id` for the confirm button. */
79
+ confirmMolId?: string;
80
+ /** `data-mol-id` for the cancel button. */
81
+ cancelMolId?: string;
82
+ /** Extra body content under the input (error banners, hints). */
83
+ children?: React.ReactNode;
84
+ }
85
+ /**
86
+ * Modal that asks the user for a short string, replacing `window.prompt`.
87
+ *
88
+ * @param props - Component props (see {@link PromptDialogProps}).
89
+ */
90
+ export declare function PromptDialog({ open, onClose, title, description, placeholder, initialValue, onSubmit, confirmLabel, cancelLabel, destructive, inputMolId, confirmMolId, cancelMolId, children, }: PromptDialogProps): JSX.Element;
91
+ //# sourceMappingURL=PromptDialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PromptDialog.d.ts","sourceRoot":"","sources":["../../src/components/PromptDialog.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,KAAK,EAAE,EAAE,KAAK,GAAG,EAAuB,MAAM,OAAO,CAAA;AAS5D,sCAAsC;AACtC,MAAM,WAAW,iBAAiB;IAChC,kCAAkC;IAClC,IAAI,EAAE,OAAO,CAAA;IACb,yHAAyH;IACzH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,sBAAsB;IACtB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAA;IACtB,wCAAwC;IACxC,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjD,iEAAiE;IACjE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC9B,+DAA+D;IAC/D,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC7B,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,OAAO,EACP,KAAK,EACL,WAAW,EACX,WAAW,EACX,YAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,WAAmB,EACnB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAoEjC"}
@@ -0,0 +1,90 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * PromptDialog component — the shared "ask for a short string" modal.
4
+ *
5
+ * The shared home for what `window.prompt` used to do (renaming, renaming a
6
+ * board, creating a tag, "invite by email"). `window.prompt` is broken
7
+ * headless (it hangs e2e) and awkward on touch; this renders the same
8
+ * interaction as a real dialog built on {@link Modal}. For a confirm WITHOUT
9
+ * an input use {@link ConfirmDialog}; for an INLINE two-click arm/commit
10
+ * button use {@link ConfirmButton}.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * import { PromptDialog } from '@molecule/app-ui-react'
15
+ *
16
+ * <PromptDialog
17
+ * open={renameOpen}
18
+ * onClose={() => setRenameOpen(false)}
19
+ * title={t('board.renameTitle', {}, { defaultValue: 'Rename board' })}
20
+ * placeholder={t('board.namePlaceholder', {}, { defaultValue: 'Board name' })}
21
+ * initialValue={board.name}
22
+ * confirmLabel={t('common.save', {}, { defaultValue: 'Save' })}
23
+ * onSubmit={async (name) => {
24
+ * await renameBoard(board.id, name) // resolve → dialog closes
25
+ * }}
26
+ * />
27
+ * ```
28
+ *
29
+ * @remarks
30
+ * `onSubmit` receives the RAW entered value (no trimming — the caller owns
31
+ * validation). Resolve it and the dialog closes and resets; reject or throw
32
+ * and the dialog STAYS OPEN with the value intact — render your error
33
+ * message through `children` (e.g. an `<Alert status="error">`), since the
34
+ * rejection itself is deliberately swallowed here. While the promise is
35
+ * pending the input and both buttons are disabled, so the action cannot
36
+ * double-fire. Enter submits; Escape and the backdrop cancel exactly like a
37
+ * Modal. Optional `inputMolId` / `confirmMolId` / `cancelMolId` render as
38
+ * `data-mol-id` attributes for e2e locators; the buttons are also
39
+ * text-labeled so `getByRole('button', { name })` reaches them.
40
+ *
41
+ * WIZARD GOTCHA (learned the hard way, fleet migration 2026-09-24): a
42
+ * fulfilled submit calls `onClose()` — "close", not "cancel". A multi-stage
43
+ * flow that advances its stage INSIDE `onSubmit` gets clobbered if its
44
+ * `onClose` unconditionally resets to idle (the auto-close fires right
45
+ * after the stage advance). Make `onClose` stage-aware via functional
46
+ * state (`setStage((cur) => (cur === 'name' ? 'idle' : cur))`) so cancel
47
+ * still resets but the post-submit auto-close doesn't undo the advance.
48
+ *
49
+ * @module
50
+ */
51
+ import { useEffect, useState } from 'react';
52
+ import { useTranslation } from '@molecule/app-react';
53
+ import { getClassMap } from '@molecule/app-ui';
54
+ import { Button } from './Button.js';
55
+ import { Input } from './Input.js';
56
+ import { Modal } from './Modal.js';
57
+ /**
58
+ * Modal that asks the user for a short string, replacing `window.prompt`.
59
+ *
60
+ * @param props - Component props (see {@link PromptDialogProps}).
61
+ */
62
+ export function PromptDialog({ open, onClose, title, description, placeholder, initialValue = '', onSubmit, confirmLabel, cancelLabel, destructive = false, inputMolId, confirmMolId, cancelMolId, children, }) {
63
+ const cm = getClassMap();
64
+ const { t } = useTranslation();
65
+ const [value, setValue] = useState(initialValue);
66
+ const [pending, setPending] = useState(false);
67
+ // Re-seed from initialValue each open so a reopened dialog shows the
68
+ // CURRENT value, not whatever the user typed last time.
69
+ useEffect(() => {
70
+ if (open) {
71
+ setValue(initialValue);
72
+ setPending(false);
73
+ }
74
+ }, [open, initialValue]);
75
+ const handleSubmit = (e) => {
76
+ e.preventDefault();
77
+ if (pending)
78
+ return;
79
+ setPending(true);
80
+ void Promise.resolve(onSubmit(value))
81
+ .then(() => onClose())
82
+ .catch(() => {
83
+ // Deliberate: a rejection keeps the dialog open (see @remarks);
84
+ // the caller renders the error through `children`.
85
+ setPending(false);
86
+ });
87
+ };
88
+ return (_jsx(Modal, { open: open, onClose: pending ? () => { } : onClose, children: _jsx("form", { onSubmit: handleSubmit, children: _jsxs("div", { className: cm.stack(3), children: [_jsx("h2", { className: cm.cn(cm.textSize('lg'), cm.fontWeight('bold')), children: title }), description ? _jsx("p", { className: cm.textSize('sm'), children: description }) : null, _jsx(Input, { value: value, onChange: (e) => setValue(e.target.value), placeholder: placeholder, "aria-label": typeof title === 'string' ? title : placeholder, disabled: pending, autoFocus: true, "data-mol-id": inputMolId }), children, _jsxs("div", { className: cm.flex({ justify: 'end', gap: 'sm' }), children: [_jsx(Button, { type: "button", variant: "ghost", onClick: onClose, disabled: pending, "data-mol-id": cancelMolId, children: cancelLabel ?? t('prompt.cancel', {}, { defaultValue: 'Cancel' }) }), _jsx(Button, { type: "submit", variant: "solid", color: destructive ? 'error' : 'primary', disabled: pending, "data-mol-id": confirmMolId, children: confirmLabel ?? t('prompt.confirm', {}, { defaultValue: 'Confirm' }) })] })] }) }) }));
89
+ }
90
+ //# sourceMappingURL=PromptDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PromptDialog.js","sourceRoot":"","sources":["../../src/components/PromptDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,327 @@
1
+ /**
2
+ * ResponsiveAppShell — the shared responsive app shell: a top bar, a desktop
3
+ * sidebar (≥768px) and a mobile nav drawer (<768px) around one content region.
4
+ *
5
+ * Roughly 89 flagship apps hand-roll this shell in ~15 drifting variants
6
+ * (inline-style panels, `max-width: 768px` fenceposts, CSS-hidden duplicate
7
+ * shells, hydration-spinner gates). This family is the fleet standard; it
8
+ * follows the QA-hardened shape the best templates converged on
9
+ * (`time-tracking`'s `useIsDesktop`, `blog`'s drawer, `weather-dashboard`'s
10
+ * one-shell-per-breakpoint doctrine).
11
+ *
12
+ * Compose it:
13
+ *
14
+ * ```tsx
15
+ * import { ResponsiveAppShell } from '@molecule/app-ui-react'
16
+ * import { NavLink, Outlet } from 'react-router'
17
+ *
18
+ * const nav = (
19
+ * <>
20
+ * <NavLink to="/dashboard">Dashboard</NavLink>
21
+ * <NavLink to="/projects">Projects</NavLink>
22
+ * <NavLink to="/reports">Reports</NavLink>
23
+ * </>
24
+ * )
25
+ *
26
+ * export function Shell() {
27
+ * return (
28
+ * <ResponsiveAppShell>
29
+ * <ResponsiveAppShell.TopBar
30
+ * brand={<NavLink to="/dashboard">Timetrack</NavLink>}
31
+ * actions={<UserMenu />}
32
+ * />
33
+ * <ResponsiveAppShell.Sidebar>{nav}</ResponsiveAppShell.Sidebar>
34
+ * <ResponsiveAppShell.Drawer>{nav}</ResponsiveAppShell.Drawer>
35
+ * <ResponsiveAppShell.Content>
36
+ * <Outlet />
37
+ * </ResponsiveAppShell.Content>
38
+ * </ResponsiveAppShell>
39
+ * )
40
+ * }
41
+ * ```
42
+ *
43
+ * @remarks
44
+ * - **Breakpoint: 768px** — the fleet-wide `md` breakpoint. Exactly ONE shell
45
+ * is MOUNTED per breakpoint: `Sidebar` renders only ≥768px, `Drawer` (and
46
+ * the menu trigger) only below. This is deliberate — rendering both and
47
+ * hiding one with CSS (`hidden md:block` style) leaves duplicate `<main>`/
48
+ * `<nav>` landmarks in the accessibility tree, double-mounts route content
49
+ * (double fetches, duplicate text matches for e2e locators). CSS-only
50
+ * responsive pairs remain available for NON-duplicating surface swaps via
51
+ * `hiddenBelow()` / `hiddenFrom()` on the UIClassMap. The `useIsDesktop`
52
+ * hook is exported for apps that need the same signal elsewhere: it reads
53
+ * `matchMedia` synchronously on first client render (no mounted-then-swap
54
+ * flicker in this CSR-only package) and subscribes to `change` events; the
55
+ * initializer is guarded (`typeof window`/`matchMedia`) so SSR and
56
+ * non-browser harnesses render the mobile shell instead of crashing.
57
+ * - **a11y contract.** `TopBar` renders the `<header>` landmark and its menu
58
+ * trigger carries `aria-label` + `aria-expanded` + `aria-controls` (the
59
+ * panel id comes from `useId()`). `Sidebar` renders `<aside>` with a
60
+ * `<nav aria-label>` landmark around its children. `Drawer` implements the
61
+ * WAI-ARIA APG dialog pattern on mobile: `role="dialog"` + `aria-modal`
62
+ * panel, focus moves into the panel on open and returns to the trigger on
63
+ * close, Tab/Shift+Tab are trapped inside, Escape and a backdrop click
64
+ * close, and body scroll is locked (reference-counted, so a `<Modal>`
65
+ * confirm stacked above the drawer never unlocks early). `Content` renders
66
+ * the `<main>` landmark. Marking the CURRENT nav item is the CONSUMER's job
67
+ * — pass `aria-current="page"` from your nav children (the shell renders
68
+ * them pass-through).
69
+ * - **Behavior.** The drawer auto-closes on SPA navigation (react-router
70
+ * location change) so it never sticks over the next page, and when the
71
+ * viewport crosses to desktop while it is open. Apps need an
72
+ * `I18nProvider` (all visible labels go through `t(key, {}, {
73
+ * defaultValue })`) and a react-router context; without the router the
74
+ * shell still renders — it just cannot auto-close on navigation.
75
+ * - **Locators.** Every fixed element carries a `data-mol-id` default,
76
+ * overridable per sub-component: `shell-topbar`, `shell-drawer-open`
77
+ * (trigger), `shell-sidebar`, `shell-drawer` (panel), `shell-drawer-close`,
78
+ * `shell-content`, and `shell-root` on the root `<div>`.
79
+ * - **ClassMap gaps routed around (Rule 5 inline-style exceptions, each
80
+ * commented at the call site).** The UIClassMap `drawer` token is a
81
+ * RIGHT-anchored settings-panel shape (`!right-0 … !max-w-sm`) and cannot
82
+ * serve a left nav drawer; there is no standalone `overflowY: auto`,
83
+ * `z-index`, or `left: 0` token. The shell therefore applies small
84
+ * documented inline styles for the drawer/sidebar geometry (pixel width à
85
+ * la `@molecule/app-sidebar-layout-react`, `max-width: 85vw`,
86
+ * `overflow-y: auto`, stacking `zIndex`) instead of widening UIClassMap —
87
+ * a `navDrawer()`-style token belongs in `@molecule/app-ui` + the ClassMap
88
+ * bond, both outside this package.
89
+ * - **Siblings.** `@molecule/app-sidebar-layout-react` `SidebarLayout` is the
90
+ * router-coupled DESKTOP-only sidebar (no mobile collapse);
91
+ * `@molecule/app-shell-layout-react` `AppShellLayout` is the marketing
92
+ * header/footer frame. THIS family is the responsive authenticated shell.
93
+ * Do not nest `SidebarLayout` inside it — pick one shell per app.
94
+ *
95
+ * @module
96
+ */
97
+ import { type JSX, type ReactNode } from 'react';
98
+ /**
99
+ * Whether the viewport is at least 768px wide (the fleet's `md` breakpoint).
100
+ *
101
+ * Reads `window.matchMedia` synchronously in the state initializer, so the
102
+ * FIRST client render is already correct — no mobile-then-desktop swap frame
103
+ * (this is time-tracking's QA-hardened version; the naive
104
+ * "state starts false, sync in an effect" variant mounts the wrong shell for
105
+ * one frame and double-fetches route data on desktop). Subscribes to
106
+ * `change` events afterwards. Guarded for non-browser environments
107
+ * (SSR/node): returns `false` (the mobile shell) when no `window.matchMedia`
108
+ * exists.
109
+ *
110
+ * @param query - Override the media query. Defaults to `(min-width: 768px)`.
111
+ * @returns Whether the desktop shell should mount.
112
+ */
113
+ export declare function useIsDesktop(query?: string): boolean;
114
+ /**
115
+ * Semantic sidebar width — the same stack-agnostic presets
116
+ * `@molecule/app-sidebar-layout-react` uses, so both shells render the same
117
+ * fleet geometry: `sm` → 208px, `md` → 240px (default), `lg` → 256px. A raw
118
+ * `number` is an exact pixel width. Applied via inline style (a specific
119
+ * pixel width is the documented "value a swappable ClassMap cannot express
120
+ * as a token" case).
121
+ */
122
+ export type ShellSidebarWidth = 'sm' | 'md' | 'lg' | number;
123
+ /**
124
+ * Props for the {@link ResponsiveAppShell} root.
125
+ */
126
+ export interface ResponsiveAppShellProps {
127
+ /**
128
+ * The shell sub-components — `<ResponsiveAppShell.TopBar />`,
129
+ * `<ResponsiveAppShell.Sidebar />`, `<ResponsiveAppShell.Drawer />` and
130
+ * `<ResponsiveAppShell.Content />`.
131
+ */
132
+ children: ReactNode;
133
+ /**
134
+ * Sidebar (and drawer) width: `'sm'` (208px), `'md'` (240px, default),
135
+ * `'lg'` (256px) or an exact pixel number.
136
+ */
137
+ sidebarWidth?: ShellSidebarWidth;
138
+ /** Extra classes on the root flex-row container. */
139
+ className?: string;
140
+ /**
141
+ * `data-mol-id` for the root container. Defaults to `'shell-root'`.
142
+ */
143
+ dataMolId?: string;
144
+ }
145
+ /**
146
+ * Root of the responsive app shell. Owns the breakpoint signal and the
147
+ * drawer open state, closes the drawer on SPA navigation and on
148
+ * desktop-crossing resizes, and provides both to the sub-components via
149
+ * context.
150
+ *
151
+ * Render the four sub-components inside it — see the module example for the
152
+ * canonical composition.
153
+ *
154
+ * @param props - The shell sub-components, sidebar width, and className.
155
+ * @returns The flex-row shell root.
156
+ */
157
+ declare function ResponsiveAppShellBase({ children, sidebarWidth, className, dataMolId, }: ResponsiveAppShellProps): JSX.Element;
158
+ /**
159
+ * Props for the {@link ResponsiveAppShellTopBar} sub-component.
160
+ */
161
+ export interface ResponsiveAppShellTopBarProps {
162
+ /**
163
+ * Brand/title node, rendered after the menu trigger — typically a
164
+ * `<Link to="/…">` with the app name or logo. The shell wraps it in a
165
+ * flex row; style the node itself.
166
+ */
167
+ brand?: ReactNode;
168
+ /** Trailing actions — user menu, theme toggle, search, etc. */
169
+ actions?: ReactNode;
170
+ /**
171
+ * Render the top bar only below the breakpoint (mount-conditioned, not
172
+ * CSS-hidden — no dead DOM on desktop). For apps whose desktop shell has
173
+ * no top bar (e.g. the sidebar carries everything). Default: `false`
174
+ * (top bar on every breakpoint).
175
+ */
176
+ mobileOnly?: boolean;
177
+ /** Extra classes on the `<header>`. */
178
+ className?: string;
179
+ /** `data-mol-id` override. Default: `'shell-topbar'`. */
180
+ dataMolId?: string;
181
+ /** `data-testid` override. */
182
+ testId?: string;
183
+ }
184
+ /**
185
+ * The shell's `<header>` landmark: menu trigger (mobile, when a Drawer is
186
+ * composed), brand, and trailing actions.
187
+ *
188
+ * Sticks to the top of the viewport by default. The menu trigger renders
189
+ * only while a `ResponsiveAppShell.Drawer` is part of the composition AND
190
+ * the viewport is below the breakpoint.
191
+ *
192
+ * @param props - Brand/actions slots, `mobileOnly`, and class/id overrides.
193
+ * @returns The header landmark, or `null` when `mobileOnly` is set on desktop.
194
+ */
195
+ export declare function ResponsiveAppShellTopBar({ brand, actions, mobileOnly, className, dataMolId, testId, }: ResponsiveAppShellTopBarProps): JSX.Element | null;
196
+ /**
197
+ * Props for the {@link ResponsiveAppShellSidebar} sub-component.
198
+ */
199
+ export interface ResponsiveAppShellSidebarProps {
200
+ /**
201
+ * Nav content — the links (they land inside the sidebar's `<nav>` landmark;
202
+ * pass `aria-current="page"` from the active one yourself). Typically the
203
+ * SAME element variable the Drawer receives, so only the mounted
204
+ * breakpoint's copy ever instantiates.
205
+ */
206
+ children: ReactNode;
207
+ /**
208
+ * Accessible name for the sidebar's `<nav>` landmark. Defaults to the
209
+ * `appShell.primaryNav` translation (English fallback `"Primary
210
+ * navigation"`).
211
+ */
212
+ navLabel?: string;
213
+ /**
214
+ * Below-nav content (user card, quick action) — rendered after the `<nav>`
215
+ * in a bordered footer row, so it does not sit inside the nav landmark.
216
+ */
217
+ footer?: ReactNode;
218
+ /** Extra classes on the `<aside>`. */
219
+ className?: string;
220
+ /** `data-mol-id` override. Default: `'shell-sidebar'`. */
221
+ dataMolId?: string;
222
+ /** `data-testid` override. */
223
+ testId?: string;
224
+ }
225
+ /**
226
+ * The desktop sidebar (`<aside>` + `<nav>` landmarks). Renders NOTHING below
227
+ * 768px — the {@link ResponsiveAppShellDrawer} carries the nav there.
228
+ *
229
+ * Full viewport height, sticky at the top edge, scrolls internally when its
230
+ * content outgrows the viewport.
231
+ *
232
+ * @param props - Nav children, nav label, footer slot, class/id overrides.
233
+ * @returns The sidebar landmarks, or `null` below the breakpoint.
234
+ */
235
+ export declare function ResponsiveAppShellSidebar({ children, navLabel, footer, className, dataMolId, testId, }: ResponsiveAppShellSidebarProps): JSX.Element | null;
236
+ /**
237
+ * Props for the {@link ResponsiveAppShellDrawer} sub-component.
238
+ */
239
+ export interface ResponsiveAppShellDrawerProps {
240
+ /**
241
+ * Nav content — the links, same as (or adapted from) the Sidebar's. Only
242
+ * mounted while the drawer is open on a below-breakpoint viewport.
243
+ */
244
+ children: ReactNode;
245
+ /**
246
+ * Header row content (typically the brand), rendered next to the close
247
+ * button.
248
+ */
249
+ header?: ReactNode;
250
+ /**
251
+ * Accessible name for the dialog and its `<nav>` landmark. Defaults to the
252
+ * `appShell.primaryNav` translation (English fallback `"Primary
253
+ * navigation"`).
254
+ */
255
+ navLabel?: string;
256
+ /** Below-nav content (user card, sign-out), after the `<nav>`. */
257
+ footer?: ReactNode;
258
+ /** Whether the panel shows a close (X) button. Default: `true`. */
259
+ showCloseButton?: boolean;
260
+ /** Extra classes on the dialog panel. */
261
+ className?: string;
262
+ /** `data-mol-id` override for the panel. Default: `'shell-drawer'`. */
263
+ dataMolId?: string;
264
+ /** `data-mol-id` override for the close button. Default: `'shell-drawer-close'`. */
265
+ closeDataMolId?: string;
266
+ /** `data-testid` override for the panel. */
267
+ testId?: string;
268
+ }
269
+ /**
270
+ * The mobile nav drawer (<768px): a left-anchored dialog panel over a
271
+ * backdrop, opened by the menu trigger the TopBar renders.
272
+ *
273
+ * Implements the WAI-ARIA APG dialog pattern — focus moves into the panel on
274
+ * open and returns to the previously focused element (the trigger) on close,
275
+ * Tab is trapped inside, Escape and backdrop clicks close, body scroll locks
276
+ * (reference-counted with any stacked `<Modal>`), and the shell closes it on
277
+ * SPA navigation. Renders nothing on desktop or while closed.
278
+ *
279
+ * @param props - Nav children, header/nav-label/footer slots, close-button
280
+ * and class/id overrides.
281
+ * @returns The drawer portal while open on mobile, otherwise `null`.
282
+ */
283
+ export declare function ResponsiveAppShellDrawer({ children, header, navLabel, footer, showCloseButton, className, dataMolId, closeDataMolId, testId, }: ResponsiveAppShellDrawerProps): JSX.Element | null;
284
+ /**
285
+ * Props for the {@link ResponsiveAppShellContent} sub-component.
286
+ */
287
+ export interface ResponsiveAppShellContentProps {
288
+ /** The routed page content — typically an `<Outlet />`. */
289
+ children: ReactNode;
290
+ /** Extra classes on the `<main>`. */
291
+ className?: string;
292
+ /** Inline styles on the `<main>` (rarely needed — layout is owned). */
293
+ style?: React.CSSProperties;
294
+ /** `data-mol-id` override. Default: `'shell-content'`. */
295
+ dataMolId?: string;
296
+ /** `data-testid` override. */
297
+ testId?: string;
298
+ }
299
+ /**
300
+ * The shell's `<main>` landmark. Grows to fill the row and may shrink below
301
+ * its content width, so page-level `overflow-x` strips scroll inside the
302
+ * page instead of widening the whole shell.
303
+ *
304
+ * @param props - The page content and class/id overrides.
305
+ * @returns The main landmark.
306
+ */
307
+ export declare function ResponsiveAppShellContent({ children, className, style, dataMolId, testId, }: ResponsiveAppShellContentProps): JSX.Element;
308
+ /**
309
+ * The responsive app shell family — see the {@link ResponsiveAppShellBase |
310
+ * root component} and the module docs for the full contract.
311
+ *
312
+ * Consumed as `<ResponsiveAppShell.TopBar />`, `.Sidebar`, `.Drawer` and
313
+ * `.Content` inside `<ResponsiveAppShell>`; each is also exported as a named
314
+ * component (`ResponsiveAppShellTopBar`, …) for star-import consumers.
315
+ */
316
+ export declare const ResponsiveAppShell: typeof ResponsiveAppShellBase & {
317
+ /** The `<header>` landmark — brand + actions + the drawer menu trigger. */
318
+ TopBar: typeof ResponsiveAppShellTopBar;
319
+ /** The desktop `<aside>`/`<nav>` landmarks (≥768px only). */
320
+ Sidebar: typeof ResponsiveAppShellSidebar;
321
+ /** The mobile dialog drawer (<768px only). */
322
+ Drawer: typeof ResponsiveAppShellDrawer;
323
+ /** The `<main>` landmark. */
324
+ Content: typeof ResponsiveAppShellContent;
325
+ };
326
+ export {};
327
+ //# sourceMappingURL=ResponsiveAppShell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResponsiveAppShell.d.ts","sourceRoot":"","sources":["../../src/components/ResponsiveAppShell.tsx"],"names":[],"mappings":"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"}