@setsquare/ui 0.9.0 → 0.10.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/README.md +4 -2
  3. package/dist/index.d.ts +2 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/rail-name.d.ts +3 -8
  7. package/dist/lib/rail-name.d.ts.map +1 -1
  8. package/dist/lib/rail-name.js +3 -19
  9. package/dist/lib/rail-name.js.map +1 -1
  10. package/dist/lib/soft-hyphen.d.ts +24 -0
  11. package/dist/lib/soft-hyphen.d.ts.map +1 -0
  12. package/dist/lib/soft-hyphen.js +67 -0
  13. package/dist/lib/soft-hyphen.js.map +1 -0
  14. package/dist/lib/use-hyphenated.d.ts +22 -0
  15. package/dist/lib/use-hyphenated.d.ts.map +1 -0
  16. package/dist/lib/use-hyphenated.js +81 -0
  17. package/dist/lib/use-hyphenated.js.map +1 -0
  18. package/dist/lib/use-scroll-tab-stop.d.ts +9 -0
  19. package/dist/lib/use-scroll-tab-stop.d.ts.map +1 -0
  20. package/dist/lib/use-scroll-tab-stop.js +46 -0
  21. package/dist/lib/use-scroll-tab-stop.js.map +1 -0
  22. package/dist/shell/dashboard-shell.d.ts +1 -0
  23. package/dist/shell/dashboard-shell.d.ts.map +1 -1
  24. package/dist/shell/dashboard-shell.js +2 -34
  25. package/dist/shell/dashboard-shell.js.map +1 -1
  26. package/dist/shell/page-header.d.ts +7 -1
  27. package/dist/shell/page-header.d.ts.map +1 -1
  28. package/dist/shell/page-header.js +3 -2
  29. package/dist/shell/page-header.js.map +1 -1
  30. package/dist/shell/right-panel.d.ts +21 -1
  31. package/dist/shell/right-panel.d.ts.map +1 -1
  32. package/dist/shell/right-panel.js +12 -4
  33. package/dist/shell/right-panel.js.map +1 -1
  34. package/dist/styles/theme.css +25 -2
  35. package/dist/styles/tokens.css +18 -0
  36. package/dist/tokens.json +80 -0
  37. package/dist/ui/button.d.ts +2 -1
  38. package/dist/ui/button.d.ts.map +1 -1
  39. package/dist/ui/button.js +9 -3
  40. package/dist/ui/button.js.map +1 -1
  41. package/dist/ui/dialog.d.ts +14 -2
  42. package/dist/ui/dialog.d.ts.map +1 -1
  43. package/dist/ui/dialog.js +19 -4
  44. package/dist/ui/dialog.js.map +1 -1
  45. package/dist/ui/disabled-reason.d.ts +36 -0
  46. package/dist/ui/disabled-reason.d.ts.map +1 -0
  47. package/dist/ui/disabled-reason.js +27 -0
  48. package/dist/ui/disabled-reason.js.map +1 -0
  49. package/dist/ui/file-upload.d.ts.map +1 -1
  50. package/dist/ui/file-upload.js +24 -2
  51. package/dist/ui/file-upload.js.map +1 -1
  52. package/dist/ui/icon-button.d.ts.map +1 -1
  53. package/dist/ui/icon-button.js +10 -6
  54. package/dist/ui/icon-button.js.map +1 -1
  55. package/dist/ui/menu.d.ts +9 -3
  56. package/dist/ui/menu.d.ts.map +1 -1
  57. package/dist/ui/menu.js +22 -4
  58. package/dist/ui/menu.js.map +1 -1
  59. package/dist/ui/tabs.d.ts.map +1 -1
  60. package/dist/ui/tabs.js +8 -1
  61. package/dist/ui/tabs.js.map +1 -1
  62. package/dist/ui/tree.d.ts.map +1 -1
  63. package/dist/ui/tree.js +8 -3
  64. package/dist/ui/tree.js.map +1 -1
  65. package/package.json +2 -2
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { createContext, useCallback, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
4
4
  import { cn } from '../lib/cn.js';
5
+ import { useScrollTabStop } from '../lib/use-scroll-tab-stop.js';
5
6
  import { SkipLink } from './landmarks.js';
6
7
  const ShellContext = createContext(null);
7
8
  export function useShell() {
@@ -113,7 +114,6 @@ export function ShellBody({ children, className }) {
113
114
  return _jsx("div", { className: cn('flex min-h-0 flex-1', className), children: children });
114
115
  }
115
116
  /** Content a keyboard can already reach inside a scroller, which then needs no tab stop of its own. */
116
- const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), summary, iframe, [contenteditable]:not([contenteditable="false"]), [tabindex]:not([tabindex="-1"])';
117
117
  /**
118
118
  * The main landmark and scroll container; the skip link lands here. `relative` so anything absolutely positioned
119
119
  * inside (sr-only text, React Aria's hidden inputs) scrolls with the page instead of being placed against the shell.
@@ -125,39 +125,7 @@ const FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]):not([t
125
125
  */
126
126
  export function ShellMain({ children, className, 'aria-labelledby': labelledBy, }) {
127
127
  const ref = useRef(null);
128
- const [tabbable, setTabbable] = useState(false);
129
- useEffect(() => {
130
- const main = ref.current;
131
- if (!main)
132
- return;
133
- let frame = 0;
134
- const resize = new ResizeObserver(() => measure());
135
- const measure = () => {
136
- cancelAnimationFrame(frame);
137
- frame = requestAnimationFrame(() => {
138
- // The content can grow without main resizing, so watch what is in it too.
139
- for (const child of main.children)
140
- resize.observe(child);
141
- const scrolls = main.scrollHeight > main.clientHeight + 1;
142
- const reachable = [...main.querySelectorAll(FOCUSABLE)].some((el) => !el.closest('[inert]') && el.getClientRects().length > 0);
143
- setTabbable(scrolls && !reachable);
144
- });
145
- };
146
- measure();
147
- resize.observe(main);
148
- const mutation = new MutationObserver(measure);
149
- mutation.observe(main, {
150
- childList: true,
151
- subtree: true,
152
- attributes: true,
153
- attributeFilter: ['href', 'disabled', 'tabindex', 'inert', 'hidden', 'contenteditable'],
154
- });
155
- return () => {
156
- cancelAnimationFrame(frame);
157
- resize.disconnect();
158
- mutation.disconnect();
159
- };
160
- }, []);
128
+ const tabbable = useScrollTabStop(ref);
161
129
  return (_jsx("main", { ref: ref, id: "main",
162
130
  // A scroller with nothing focusable in it has to take focus itself, or a keyboard can't scroll it.
163
131
  // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-shell.js","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dashboard-shell.js","sourceRoot":"","sources":["../../src/shell/dashboard-shell.tsx"],"names":[],"mappings":"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"}
@@ -1,6 +1,12 @@
1
1
  import type { ReactNode } from 'react';
2
+ import { type IconProp } from '../ui/icon.js';
2
3
  export interface PageHeaderProps {
3
4
  title: string;
5
+ /**
6
+ * An icon before the title, drawn in `muted-foreground` and hidden from assistive technology, so the h1 is named
7
+ * by its words alone. A component, or an element when a server component passes it.
8
+ */
9
+ icon?: IconProp;
4
10
  description?: string;
5
11
  /** Page actions: at most one primary. Wraps below the title when it runs out of room. */
6
12
  actions?: ReactNode;
@@ -10,7 +16,7 @@ export interface PageHeaderProps {
10
16
  className?: string;
11
17
  }
12
18
  /** The page's h1, one-line description and actions. */
13
- export declare function PageHeader({ title, description, actions, breadcrumbs, titleId, className, }: PageHeaderProps): import("react").JSX.Element;
19
+ export declare function PageHeader({ title, icon, description, actions, breadcrumbs, titleId, className, }: PageHeaderProps): import("react").JSX.Element;
14
20
  /** Padding for everything below the page header. */
15
21
  export declare function PageContent({ children, className }: {
16
22
  children: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.d.ts","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAsB,EACtB,SAAS,GACV,EAAE,eAAe,+BAoBjB;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAM/F"}
1
+ {"version":3,"file":"page-header.d.ts","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yFAAyF;IACzF,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAsB,EACtB,SAAS,GACV,EAAE,eAAe,+BAqBjB;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAM/F"}
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { cn } from '../lib/cn.js';
3
+ import { renderIcon } from '../ui/icon.js';
3
4
  /** The page's h1, one-line description and actions. */
4
- export function PageHeader({ title, description, actions, breadcrumbs, titleId = 'page-title', className, }) {
5
- return (_jsxs("div", { className: cn('flex flex-wrap items-end justify-between gap-4 px-(--gutter) pt-5 pb-4 @max-[40rem]/main:px-4', className), children: [_jsxs("div", { className: "min-w-0 flex-[1_1_20rem]", children: [breadcrumbs && _jsx("div", { className: "mb-1", children: breadcrumbs }), _jsx("h1", { id: titleId, className: "text-title", children: title }), description && (_jsx("p", { className: "mt-1 max-w-(--measure) text-sm text-muted-foreground", children: description }))] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-(--control-gap)", children: actions })] }));
5
+ export function PageHeader({ title, icon, description, actions, breadcrumbs, titleId = 'page-title', className, }) {
6
+ return (_jsxs("div", { className: cn('flex flex-wrap items-end justify-between gap-4 px-(--gutter) pt-5 pb-4 @max-[40rem]/main:px-4', className), children: [_jsxs("div", { className: "min-w-0 flex-[1_1_20rem]", children: [breadcrumbs && _jsx("div", { className: "mb-1", children: breadcrumbs }), _jsxs("h1", { id: titleId, className: cn('text-title', icon && 'flex items-center gap-3'), children: [icon && renderIcon(icon, 'size-7 shrink-0 text-muted-foreground'), icon ? _jsx("span", { className: "min-w-0", children: title }) : title] }), description && (_jsx("p", { className: "mt-1 max-w-(--measure) text-sm text-muted-foreground", children: description }))] }), actions && _jsx("div", { className: "flex flex-wrap items-center gap-(--control-gap)", children: actions })] }));
6
7
  }
7
8
  /** Padding for everything below the page header. */
8
9
  export function PageContent({ children, className }) {
@@ -1 +1 @@
1
- {"version":3,"file":"page-header.js","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAalC,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAO,GAAG,YAAY,EACtB,SAAS,GACO;IAChB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,+FAA+F,EAC/F,SAAS,CACV,aAED,eAAK,SAAS,EAAC,0BAA0B,aACtC,WAAW,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,WAAW,GAAO,EACzD,aAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,YAAY,YACpC,KAAK,GACH,EACJ,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sDAAsD,YAAE,WAAW,GAAK,CACtF,IACG,EACL,OAAO,IAAI,cAAK,SAAS,EAAC,iDAAiD,YAAE,OAAO,GAAO,IACxF,CACP,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC9F,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,oDAAoD,EAAE,SAAS,CAAC,YAChF,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"page-header.js","sourceRoot":"","sources":["../../src/shell/page-header.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAiB,MAAM,eAAe,CAAC;AAkB1D,uDAAuD;AACvD,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,IAAI,EACJ,WAAW,EACX,OAAO,EACP,WAAW,EACX,OAAO,GAAG,YAAY,EACtB,SAAS,GACO;IAChB,OAAO,CACL,eACE,SAAS,EAAE,EAAE,CACX,+FAA+F,EAC/F,SAAS,CACV,aAED,eAAK,SAAS,EAAC,0BAA0B,aACtC,WAAW,IAAI,cAAK,SAAS,EAAC,MAAM,YAAE,WAAW,GAAO,EACzD,cAAI,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,IAAI,IAAI,yBAAyB,CAAC,aAC5E,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,uCAAuC,CAAC,EACjE,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,SAAS,YAAE,KAAK,GAAQ,CAAC,CAAC,CAAC,KAAK,IACrD,EACJ,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,sDAAsD,YAAE,WAAW,GAAK,CACtF,IACG,EACL,OAAO,IAAI,cAAK,SAAS,EAAC,iDAAiD,YAAE,OAAO,GAAO,IACxF,CACP,CAAC;AACJ,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC9F,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,oDAAoD,EAAE,SAAS,CAAC,YAChF,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
@@ -13,6 +13,26 @@ export interface RightPanelProps {
13
13
  children: ReactNode;
14
14
  /** Actions pinned to the bottom. */
15
15
  footer?: ReactNode;
16
+ /**
17
+ * Its width beside main: `"default"`, `--panel-width` (320px; 360px at AAA); `"wide"`, `--panel-width-wide` (512px;
18
+ * 560px at AAA), for a panel that is a working surface such as a chat; or a number of px, kept between
19
+ * `--panel-width` and the smaller of `--panel-width-max` (720px) and half the shell, for a product that lets people
20
+ * set it. As a Sheet, below 1024px, it is the Sheet's width whatever this says.
21
+ */
22
+ width?: 'default' | 'wide' | number;
23
+ /**
24
+ * Hides the title bar beside main, for content with a header of its own (a chat's tabs and the scene's name). The
25
+ * panel stays named: by `title`, or by `aria-labelledby` pointing at that header's heading. As a Sheet the title
26
+ * bar stays, since it holds the Sheet's close button.
27
+ */
28
+ hideTitleBar?: boolean;
29
+ /** The id of the content's own heading, which then names the panel instead of `title`. */
30
+ 'aria-labelledby'?: string;
31
+ /**
32
+ * `false` for a panel that is the page's main working surface: beside main it has no close button and stays
33
+ * open. As a Sheet, below 1024px, it still opens and closes as before.
34
+ */
35
+ isDismissable?: boolean;
16
36
  labels?: Partial<RightPanelLabels>;
17
37
  className?: string;
18
38
  }
@@ -20,7 +40,7 @@ export interface RightPanelProps {
20
40
  * Extra information about the current selection. An <aside> beside main on wide shells,
21
41
  * a Sheet (modal dialog) on narrow ones. Closing returns focus to the PanelToggle.
22
42
  */
23
- export declare function RightPanel({ title, children, footer, labels: given, className }: RightPanelProps): import("react").JSX.Element | null;
43
+ export declare function RightPanel({ title, children, footer, width, hideTitleBar, 'aria-labelledby': labelledBy, isDismissable, labels: given, className, }: RightPanelProps): import("react").JSX.Element | null;
24
44
  /** Shows and hides the right panel. Put it in the page actions. */
25
45
  export declare function PanelToggle({ label, labels, }: {
26
46
  /** @deprecated Use `labels.toggle`. Kept for one release. */
@@ -1 +1 @@
1
- {"version":3,"file":"right-panel.d.ts","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAC;AAS9D,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,sCA6DhG;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,GACP,EAAE;IACD,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpC,+BAcA;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAOA"}
1
+ {"version":3,"file":"right-panel.d.ts","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAC;AAS9D,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,gBAAgB,EAAE,gBAG9B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0FAA0F;IAC1F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,KAAiB,EACjB,YAAY,EACZ,iBAAiB,EAAE,UAAU,EAC7B,aAAoB,EACpB,MAAM,EAAE,KAAK,EACb,SAAS,GACV,EAAE,eAAe,sCA0EjB;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,GACP,EAAE;IACD,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACpC,+BAcA;AAED,uCAAuC;AACvC,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAOA"}
@@ -12,11 +12,12 @@ export const rightPanelLabels = {
12
12
  close: 'Close {title}',
13
13
  toggle: 'Details panel',
14
14
  };
15
+ const panelWidths = { default: 'w-panel', wide: 'w-(--panel-width-wide)' };
15
16
  /**
16
17
  * Extra information about the current selection. An <aside> beside main on wide shells,
17
18
  * a Sheet (modal dialog) on narrow ones. Closing returns focus to the PanelToggle.
18
19
  */
19
- export function RightPanel({ title, children, footer, labels: given, className }) {
20
+ export function RightPanel({ title, children, footer, width = 'default', hideTitleBar, 'aria-labelledby': labelledBy, isDismissable = true, labels: given, className, }) {
20
21
  const t = useLabels('rightPanel', rightPanelLabels, given);
21
22
  const close = t('close', { title });
22
23
  const { panelOpen, setPanelOpen, panelMode, panelToggleRef, isSizeForced } = useShell();
@@ -26,12 +27,19 @@ export function RightPanel({ title, children, footer, labels: given, className }
26
27
  if (panelMode === 'sheet') {
27
28
  return (_jsx(Sheet, { side: "right", title: title, labels: { close: literal(close) }, isOpen: panelOpen, onOpenChange: setPanelOpen, footer: foot, children: body }));
28
29
  }
29
- if (!panelOpen)
30
+ // A panel that can't be closed stays open beside main, whatever the toggle state says.
31
+ if (!panelOpen && isDismissable)
30
32
  return null;
31
- return (_jsxs("aside", { "aria-labelledby": headingId, style: { viewTransitionName: 'shell-panel' }, className: cn('flex w-panel shrink-0 flex-col border-l border-border bg-card text-card-foreground', !isSizeForced && '@max-[64rem]/shell:hidden', className), children: [_jsxs("div", { className: "flex min-h-[calc(var(--control-height)+1rem)] items-center justify-between gap-2 border-b border-border py-2 pr-2 pl-4", children: [_jsx("h2", { id: headingId, className: "text-subheading", children: title }), _jsx(IconButton, { label: close, icon: X, visualSize: "icon-sm", tooltip: false, className: "justify-end", onPress: () => {
33
+ const named = labelledBy ?? (hideTitleBar ? undefined : headingId);
34
+ return (_jsxs("aside", { "aria-labelledby": named, "aria-label": named ? undefined : title, style: {
35
+ viewTransitionName: 'shell-panel',
36
+ ...(typeof width === 'number' && {
37
+ width: `clamp(var(--panel-width), ${width}px, min(var(--panel-width-max), 50%))`,
38
+ }),
39
+ }, className: cn('flex shrink-0 flex-col border-l border-border bg-card text-card-foreground', typeof width === 'number' ? 'max-w-[50%]' : panelWidths[width], !isSizeForced && '@max-[64rem]/shell:hidden', className), children: [!hideTitleBar && (_jsxs("div", { className: "flex min-h-[calc(var(--control-height)+1rem)] items-center justify-between gap-2 border-b border-border py-2 pr-2 pl-4", children: [_jsx("h2", { id: headingId, className: "text-subheading", children: title }), isDismissable && (_jsx(IconButton, { label: close, icon: X, visualSize: "icon-sm", tooltip: false, className: "justify-end", onPress: () => {
32
40
  setPanelOpen(false);
33
41
  requestAnimationFrame(() => panelToggleRef.current?.focus());
34
- } })] }), body, foot] }));
42
+ } }))] })), body, foot] }));
35
43
  }
36
44
  /** Shows and hides the right panel. Put it in the page actions. */
37
45
  export function PanelToggle({ label, labels, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"right-panel.js","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"right-panel.js","sourceRoot":"","sources":["../../src/shell/right-panel.tsx"],"names":[],"mappings":"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"}
@@ -685,14 +685,15 @@
685
685
  display: inline-flex;
686
686
  align-items: center;
687
687
  gap: 6px;
688
- /* In the rail, names wrap and hyphenate inside the tile (1.4.12). */
688
+ /* In the rail, names wrap inside the tile (1.4.12), and a word too wide for it breaks with a hyphen: the
689
+ browser's, or a soft hyphen the Tab adds (useHyphenated). Never overflow-wrap: anywhere, which breaks between
690
+ two letters with no hyphen: Chrome and Firefox don't hyphenate a capitalised English word. */
689
691
  [role='tablist'][data-orientation='vertical'] & {
690
692
  display: block;
691
693
  text-align: center;
692
694
  font-size: 13px;
693
695
  line-height: 16px;
694
696
  hyphens: auto;
695
- overflow-wrap: anywhere;
696
697
  }
697
698
  }
698
699
  /* The name, over a hidden bold copy that holds the bold width from the start. */
@@ -701,6 +702,14 @@
701
702
  & > * {
702
703
  grid-area: 1 / 1;
703
704
  }
705
+ /* In the rail, no wider than the tile: a word too wide then overflows its copy, where the Tab sees it and gives it
706
+ soft hyphens, rather than widening the grid past the tile. */
707
+ [role='tablist'][data-orientation='vertical'] & {
708
+ max-width: 100%;
709
+ }
710
+ [role='tablist'][data-orientation='vertical'] & > * {
711
+ min-width: 0;
712
+ }
704
713
  & > :last-child {
705
714
  font-weight: 700;
706
715
  visibility: hidden;
@@ -1313,3 +1322,17 @@
1313
1322
  @slot;
1314
1323
  }
1315
1324
  }
1325
+ /* data-density="compact" on a container: denser controls for a tool UI (a timeline, a transport bar), at AA only.
1326
+ Paint, padding, gaps and text tighten; every target stays at least --target-min (24px), and text at least 13px.
1327
+ At AAA it changes nothing: targets are 44px there, so smaller paint would leave the layout as it was. */
1328
+ /* AAA as products mark it (data-conformance) and as the design-system artifact does (data-theme). */
1329
+ :root:not([data-conformance="aaa"], [data-theme$="-aaa"]) [data-density="compact"] {
1330
+ --control-height: var(--control-height-compact);
1331
+ --control-height-sm: var(--control-height-sm-compact);
1332
+ --control-height-lg: var(--control-height-lg-compact);
1333
+ --control-pad-x: var(--control-pad-x-compact);
1334
+ --control-gap: var(--control-gap-compact);
1335
+ --nav-item-height: var(--nav-item-height-compact);
1336
+ --field-gap: var(--field-gap-compact);
1337
+ --text-sm: var(--text-sm-compact);
1338
+ }
@@ -48,6 +48,14 @@
48
48
  --measure-aaa: 64ch;
49
49
  --motion-distance-aa: 8px;
50
50
  --motion-distance-aaa: 0px;
51
+ --control-height-compact: 28px;
52
+ --control-height-sm-compact: 24px;
53
+ --control-height-lg-compact: 36px;
54
+ --control-pad-x-compact: 8px;
55
+ --control-gap-compact: 4px;
56
+ --nav-item-height-compact: 28px;
57
+ --field-gap-compact: 12px;
58
+ --text-sm-compact: 13px;
51
59
  --header-height-aa: 56px;
52
60
  --header-height-aaa: 56px;
53
61
  --sidebar-width-aa: 256px;
@@ -61,6 +69,14 @@
61
69
  --subnav-width-aaa: 240px;
62
70
  --panel-width-aa: 320px;
63
71
  --panel-width-aaa: 360px;
72
+ --panel-width-wide-aa: 512px;
73
+ --panel-width-wide-aaa: 560px;
74
+ --panel-width-max: 720px;
75
+ --dialog-width-sm: 26rem;
76
+ --dialog-width-md: 32rem;
77
+ --dialog-width-lg: 44rem;
78
+ --dialog-width-xl: 60rem;
79
+ --dialog-width-2xl: 77.5rem;
64
80
  --gutter: 24px;
65
81
  --content-max: 1440px;
66
82
  --site-max: 1180px;
@@ -106,6 +122,7 @@
106
122
  --rail-width: var(--rail-width-aa);
107
123
  --subnav-width: var(--subnav-width-aa);
108
124
  --panel-width: var(--panel-width-aa);
125
+ --panel-width-wide: var(--panel-width-wide-aa);
109
126
  }
110
127
  :root[data-conformance="aaa"] {
111
128
  --target-min: var(--target-min-aaa);
@@ -129,6 +146,7 @@
129
146
  --rail-width: var(--rail-width-aaa);
130
147
  --subnav-width: var(--subnav-width-aaa);
131
148
  --panel-width: var(--panel-width-aaa);
149
+ --panel-width-wide: var(--panel-width-wide-aaa);
132
150
  }
133
151
  @media (prefers-reduced-motion: reduce) { :root { --motion-distance: 0px; } }
134
152
 
package/dist/tokens.json CHANGED
@@ -837,6 +837,46 @@
837
837
  "name": "motion-distance-aaa",
838
838
  "value": "0px",
839
839
  "usage": "WCAG 2.3.3: at AAA transitions fade only — opacity is not motion — so no interaction moves content."
840
+ },
841
+ {
842
+ "name": "control-height-compact",
843
+ "value": "28px",
844
+ "usage": "data-density=\"compact\", at AA only: a control's painted height (resolved as --control-height). Its target stays at least --target-min."
845
+ },
846
+ {
847
+ "name": "control-height-sm-compact",
848
+ "value": "24px",
849
+ "usage": "Compact density's small controls: the AA target floor, so paint and target are one."
850
+ },
851
+ {
852
+ "name": "control-height-lg-compact",
853
+ "value": "36px",
854
+ "usage": "Compact density's large controls."
855
+ },
856
+ {
857
+ "name": "control-pad-x-compact",
858
+ "value": "8px",
859
+ "usage": "Compact density's padding either side of a control's content."
860
+ },
861
+ {
862
+ "name": "control-gap-compact",
863
+ "value": "4px",
864
+ "usage": "Compact density's gap between controls. Targets don't overlap: a control's target is its own box."
865
+ },
866
+ {
867
+ "name": "nav-item-height-compact",
868
+ "value": "28px",
869
+ "usage": "Compact density's menu and list rows."
870
+ },
871
+ {
872
+ "name": "field-gap-compact",
873
+ "value": "12px",
874
+ "usage": "Compact density's space between fields."
875
+ },
876
+ {
877
+ "name": "text-sm-compact",
878
+ "value": "13px",
879
+ "usage": "Compact density's interface text (Tailwind's text-sm): the system's 13px floor, never smaller."
840
880
  }
841
881
  ]
842
882
  },
@@ -908,6 +948,46 @@
908
948
  "value": "360px",
909
949
  "usage": "Right panel at AAA."
910
950
  },
951
+ {
952
+ "name": "panel-width-wide-aa",
953
+ "value": "512px",
954
+ "usage": "RightPanel width=\"wide\": a panel that is a working surface, such as a chat (resolved as --panel-width-wide)."
955
+ },
956
+ {
957
+ "name": "panel-width-wide-aaa",
958
+ "value": "560px",
959
+ "usage": "RightPanel width=\"wide\" at AAA."
960
+ },
961
+ {
962
+ "name": "panel-width-max",
963
+ "value": "720px",
964
+ "usage": "The widest a resizable RightPanel can be dragged; never more than half the shell either."
965
+ },
966
+ {
967
+ "name": "dialog-width-sm",
968
+ "value": "26rem",
969
+ "usage": "Dialog size=\"sm\": a confirmation."
970
+ },
971
+ {
972
+ "name": "dialog-width-md",
973
+ "value": "32rem",
974
+ "usage": "Dialog size=\"md\", the default: a short form."
975
+ },
976
+ {
977
+ "name": "dialog-width-lg",
978
+ "value": "44rem",
979
+ "usage": "Dialog size=\"lg\": a longer form, two columns."
980
+ },
981
+ {
982
+ "name": "dialog-width-xl",
983
+ "value": "60rem",
984
+ "usage": "Dialog size=\"xl\": a gallery of cards, a picker with a preview."
985
+ },
986
+ {
987
+ "name": "dialog-width-2xl",
988
+ "value": "77.5rem",
989
+ "usage": "Dialog size=\"2xl\": a library or a board, 1240px. size=\"full\" fills the viewport but its margins."
990
+ },
911
991
  {
912
992
  "name": "gutter",
913
993
  "value": "24px",
@@ -1,6 +1,7 @@
1
1
  import { composeRenderProps, type ButtonProps as RACButtonProps, type LinkProps as RACLinkProps } from 'react-aria-components';
2
2
  import { type ButtonVariant, type ButtonVisualSize } from './button-styles.js';
3
3
  import { type KeyshortcutsProps } from '../lib/keyshortcuts.js';
4
+ import { type DisabledReasonProps } from './disabled-reason.js';
4
5
  export type { ButtonVariant, ButtonVisualSize };
5
6
  interface LayerProps {
6
7
  variant?: ButtonVariant;
@@ -13,7 +14,7 @@ interface LayerProps {
13
14
  /** Layer 2, the painted box. */
14
15
  visualClassName?: string;
15
16
  }
16
- export interface ButtonProps extends Omit<RACButtonProps, 'className'>, LayerProps, KeyshortcutsProps {
17
+ export interface ButtonProps extends Omit<RACButtonProps, 'className'>, LayerProps, KeyshortcutsProps, DisabledReasonProps {
17
18
  }
18
19
  /**
19
20
  * React Aria Button. One `primary` per view; `outline` is the default.
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"AAGA,OAAO,EAGL,kBAAkB,EAClB,KAAK,WAAW,IAAI,cAAc,EAClC,KAAK,SAAS,IAAI,YAAY,EAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAEhD,UAAU,UAAU;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,mGAAmG;IACnG,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,iBAAiB;CAAG;AAE7E;;;GAGG;AACH,eAAO,MAAM,MAAM,2GAsCjB,CAAC;AAEH,MAAM,WAAW,eACf,SAAQ,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,iBAAiB;CAAG;AAE3E,wGAAwG;AACxG,eAAO,MAAM,UAAU,+GA8BrB,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"AAGA,OAAO,EAGL,kBAAkB,EAClB,KAAK,WAAW,IAAI,cAAc,EAClC,KAAK,SAAS,IAAI,YAAY,EAC/B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAmB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEjF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,CAAC;AAEhD,UAAU,UAAU;IAClB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,mGAAmG;IACnG,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,iBAAiB,EAAE,mBAAmB;CAAG;AAElG;;;GAGG;AACH,eAAO,MAAM,MAAM,2GAuDjB,CAAC;AAEH,MAAM,WAAW,eACf,SAAQ,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,EAAE,UAAU,EAAE,iBAAiB;CAAG;AAE3E,wGAAwG;AACxG,eAAO,MAAM,UAAU,+GA8BrB,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
package/dist/ui/button.js CHANGED
@@ -1,23 +1,29 @@
1
1
  'use client';
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { forwardRef } from 'react';
3
+ import { forwardRef, useId } from 'react';
4
4
  import { Button as RACButton, Link as RACLink, composeRenderProps, } from 'react-aria-components';
5
5
  import { buttonTargetStyles, buttonVisualStyles, } from './button-styles.js';
6
6
  import { SpinnerIcon } from './spinner.js';
7
7
  import { useKeyshortcuts } from '../lib/keyshortcuts.js';
8
+ import { Tooltip, TooltipTrigger } from './tooltip.js';
9
+ import { DisabledReasonText, disabledReasonProps, } from './disabled-reason.js';
8
10
  /**
9
11
  * React Aria Button. One `primary` per view; `outline` is the default.
10
12
  * `isPending` keeps it focusable, announces the wait and swaps any leading icon for a spinner.
11
13
  */
12
- export const Button = forwardRef(function Button({ variant = 'outline', visualSize = 'default', fullWidth, className, visualClassName, children, 'aria-keyshortcuts': keys, ...props }, ref) {
14
+ export const Button = forwardRef(function Button({ variant = 'outline', visualSize = 'default', fullWidth, className, visualClassName, children, 'aria-keyshortcuts': keys, disabledReason, ...props }, ref) {
13
15
  const iconOnly = visualSize === 'icon' || visualSize === 'icon-sm';
14
16
  const target = useKeyshortcuts(keys, ref);
15
- return (_jsx(RACButton, { ref: target, ...props, className: buttonTargetStyles({ fullWidth, className }), children: composeRenderProps(children, (kids, { isPending }) => (_jsx("span", { className: buttonVisualStyles({
17
+ const reasonId = useId();
18
+ const button = (_jsx(RACButton, { ref: target, ...props, ...disabledReasonProps(disabledReason, props['aria-describedby'], reasonId), className: buttonTargetStyles({ fullWidth, className }), children: composeRenderProps(children, (kids, { isPending }) => (_jsx("span", { className: buttonVisualStyles({
16
19
  variant,
17
20
  visualSize,
18
21
  fullWidth,
19
22
  className: visualClassName,
20
23
  }), children: isPending && iconOnly ? (_jsx(SpinnerIcon, {})) : (_jsxs(_Fragment, { children: [isPending && _jsx(SpinnerIcon, {}), kids] })) }))) }));
24
+ if (!disabledReason)
25
+ return button;
26
+ return (_jsxs(_Fragment, { children: [_jsxs(TooltipTrigger, { delay: 500, children: [button, _jsx(Tooltip, { children: disabledReason })] }), _jsx(DisabledReasonText, { reason: disabledReason, id: reasonId })] }));
21
27
  });
22
28
  /** A link that looks like a button — for navigation, never for actions. Same three layers as Button. */
23
29
  export const LinkButton = forwardRef(function LinkButton({ variant = 'outline', visualSize = 'default', fullWidth, className, visualClassName, children, 'aria-keyshortcuts': keys, ...props }, ref) {
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EACL,MAAM,IAAI,SAAS,EACnB,IAAI,IAAI,OAAO,EACf,kBAAkB,GAGnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAGnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,eAAe,EAA0B,MAAM,wBAAwB,CAAC;AAmBjF;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EACE,OAAO,GAAG,SAAS,EACnB,UAAU,GAAG,SAAS,EACtB,SAAS,EACT,SAAS,EACT,eAAe,EACf,QAAQ,EACR,mBAAmB,EAAE,IAAI,EACzB,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,QAAQ,GAAG,UAAU,KAAK,MAAM,IAAI,UAAU,KAAK,SAAS,CAAC;IACnE,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,CACL,KAAC,SAAS,IAAC,GAAG,EAAE,MAAM,KAAM,KAAK,EAAE,SAAS,EAAE,kBAAkB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,YACvF,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CACrD,eACE,SAAS,EAAE,kBAAkB,CAAC;gBAC5B,OAAO;gBACP,UAAU;gBACV,SAAS;gBACT,SAAS,EAAE,eAAe;aAC3B,CAAC,YAED,SAAS,IAAI,QAAQ,CAAC,CAAC,CAAC,CACvB,KAAC,WAAW,KAAG,CAChB,CAAC,CAAC,CAAC,CACF,8BACG,SAAS,IAAI,KAAC,WAAW,KAAG,EAC5B,IAAI,IACJ,CACJ,GACI,CACR,CAAC,GACQ,CACb,CAAC;AACJ,CAAC,CAAC,CAAC;AAKH,wGAAwG;AACxG,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAqC,SAAS,UAAU,CAC1F,EACE,OAAO,GAAG,SAAS,EACnB,UAAU,GAAG,SAAS,EACtB,SAAS,EACT,SAAS,EACT,eAAe,EACf,QAAQ,EACR,mBAAmB,EAAE,IAAI,EACzB,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,CACL,KAAC,OAAO,IAAC,GAAG,EAAE,MAAM,KAAM,KAAK,EAAE,SAAS,EAAE,kBAAkB,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,YACrF,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CACtC,eACE,SAAS,EAAE,kBAAkB,CAAC;gBAC5B,OAAO;gBACP,UAAU;gBACV,SAAS;gBACT,SAAS,EAAE,eAAe;aAC3B,CAAC,YAED,IAAI,GACA,CACR,CAAC,GACM,CACX,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
1
+ {"version":3,"file":"button.js","sourceRoot":"","sources":["../../src/ui/button.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { type IconProp } from './icon.js';
2
3
  /** A Dialog's words, for the `labels` prop. */
3
4
  export interface DialogLabels {
4
5
  close: string;
@@ -8,20 +9,31 @@ export interface DialogProps {
8
9
  isOpen: boolean;
9
10
  onOpenChange: (open: boolean) => void;
10
11
  title: string;
12
+ /**
13
+ * An icon before the title, in `muted-foreground` and hidden from assistive technology, so the dialog is named by
14
+ * the title's words alone.
15
+ */
16
+ icon?: IconProp;
11
17
  /** One or two sentences under the title; read as the dialog's description. */
12
18
  description?: ReactNode;
13
19
  children?: ReactNode;
20
+ /** Pinned to the bottom: only the content between the title and the footer scrolls. */
14
21
  footer?: ReactNode;
15
22
  /** 'alertdialog' for confirmations that interrupt. */
16
23
  role?: 'dialog' | 'alertdialog';
17
24
  /** Backdrop click and the × close it. Default true; false for confirmations. Escape always closes. */
18
25
  isDismissable?: boolean;
19
- size?: 'sm' | 'md' | 'lg';
26
+ /**
27
+ * Its widest, from the `dialog-width-*` tokens: sm 26rem, md 32rem (the default), lg 44rem, xl 60rem, 2xl 77.5rem
28
+ * (1240px). `full` fills the viewport but its margins. Never wider than the viewport.
29
+ */
30
+ size?: DialogSize;
20
31
  labels?: Partial<DialogLabels>;
21
32
  className?: string;
22
33
  }
34
+ export type DialogSize = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
23
35
  /** A centred modal: focus moves in and is trapped, Escape closes, focus returns to what opened it. */
24
- export declare function Dialog({ isOpen, onOpenChange, title, description, children, footer, role, isDismissable, size, labels, className, }: DialogProps): import("react").JSX.Element;
36
+ export declare function Dialog({ isOpen, onOpenChange, title, icon, description, children, footer, role, isDismissable, size, labels, className, }: DialogProps): import("react").JSX.Element;
25
37
  /** A ConfirmDialog's words, for the `labels` prop. */
26
38
  export interface ConfirmDialogLabels {
27
39
  /** The button that closes it without acting. */
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAUxD,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,YAAY,EAAE,YAAiC,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,sDAAsD;IACtD,IAAI,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IAChC,sGAAsG;IACtG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,sGAAsG;AACtG,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,KAAK,EACL,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAe,EACf,aAAoB,EACpB,IAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE,WAAW,+BAwDb;AAED,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAMjC,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qGAAqG;IACrG,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,IAAe,EACf,WAAW,EACX,SAAS,EACT,MAAM,EAAE,KAAK,GACd,EAAE,kBAAkB,+BAwFpB"}
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/ui/dialog.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA2B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQhE,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAItD,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,YAAY,EAAE,YAAiC,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,uFAAuF;IACvF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,sDAAsD;IACtD,IAAI,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IAChC,sGAAsG;IACtG,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,CAAC;AAWpE,sGAAsG;AACtG,wBAAgB,MAAM,CAAC,EACrB,MAAM,EACN,YAAY,EACZ,KAAK,EACL,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAe,EACf,aAAoB,EACpB,IAAW,EACX,MAAM,EACN,SAAS,GACV,EAAE,WAAW,+BAoEb;AAED,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAClC,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAMjC,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,QAAQ,EAAE,SAAS,CAAC;IACpB,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC5B,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qGAAqG;IACrG,SAAS,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;CACvC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,IAAe,EACf,WAAW,EACX,SAAS,EACT,MAAM,EAAE,KAAK,GACd,EAAE,kBAAkB,+BAwFpB"}
package/dist/ui/dialog.js CHANGED
@@ -1,21 +1,36 @@
1
1
  'use client';
2
2
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useId, useState } from 'react';
3
+ import { useId, useRef, useState } from 'react';
4
4
  import { Dialog as RACDialog, Heading, Modal, ModalOverlay } from 'react-aria-components';
5
5
  import { X } from 'lucide-react';
6
6
  import { cn } from '../lib/cn.js';
7
7
  import { useLabels } from '../lib/locale.js';
8
+ import { useScrollTabStop } from '../lib/use-scroll-tab-stop.js';
8
9
  import { Alert } from './alert.js';
9
10
  import { Button } from './button.js';
11
+ import { renderIcon } from './icon.js';
10
12
  import { IconButton } from './icon-button.js';
11
13
  import { TextField } from './text-field.js';
12
14
  export const dialogLabels = { close: 'Close' };
13
- const widths = { sm: 'max-w-[26rem]', md: 'max-w-[32rem]', lg: 'max-w-[44rem]' };
15
+ const widths = {
16
+ sm: 'max-w-(--dialog-width-sm)',
17
+ md: 'max-w-(--dialog-width-md)',
18
+ lg: 'max-w-(--dialog-width-lg)',
19
+ xl: 'max-w-(--dialog-width-xl)',
20
+ '2xl': 'max-w-(--dialog-width-2xl)',
21
+ full: 'max-w-none',
22
+ };
14
23
  /** A centred modal: focus moves in and is trapped, Escape closes, focus returns to what opened it. */
15
- export function Dialog({ isOpen, onOpenChange, title, description, children, footer, role = 'dialog', isDismissable = true, size = 'md', labels, className, }) {
24
+ export function Dialog({ isOpen, onOpenChange, title, icon, description, children, footer, role = 'dialog', isDismissable = true, size = 'md', labels, className, }) {
16
25
  const t = useLabels('dialog', dialogLabels, labels);
17
26
  const descId = useId();
18
- return (_jsx(ModalOverlay, { isOpen: isOpen, onOpenChange: onOpenChange, isDismissable: isDismissable, "data-overlay": true, className: "fixed inset-0 z-(--z-sheet) flex items-center justify-center bg-overlay p-4", children: _jsx(Modal, { "data-sheet": "top", className: cn('relative max-h-[calc(100dvh-2rem)] w-full overflow-auto rounded-xl border border-border bg-popover text-popover-foreground shadow-(--shadow-lg) outline-none', widths[size], className), children: _jsxs(RACDialog, { role: role, "aria-describedby": description ? descId : undefined, className: "flex flex-col outline-none", children: [_jsxs("div", { className: "flex items-start justify-between gap-3 px-5 pt-5", children: [_jsx(Heading, { slot: "title", className: "text-heading", children: title }), isDismissable && (_jsx(IconButton, { label: t('close'), icon: X, visualSize: "icon-sm", slot: "close", tooltip: false, className: "-mt-1 -mr-2 items-start justify-end" }))] }), _jsxs("div", { className: "flex flex-col gap-4 px-5 pt-2 pb-5 text-sm leading-6", children: [description && (_jsx("div", { id: descId, className: "max-w-(--measure) text-muted-foreground", children: description })), children] }), footer && (_jsx("div", { className: "flex flex-wrap items-center justify-end gap-(--control-gap) border-t border-border px-5 py-4", children: footer }))] }) }) }));
27
+ const body = useRef(null);
28
+ const bodyTabbable = useScrollTabStop(body);
29
+ return (_jsx(ModalOverlay, { isOpen: isOpen, onOpenChange: onOpenChange, isDismissable: isDismissable, "data-overlay": true, className: "fixed inset-0 z-(--z-sheet) flex items-center justify-center bg-overlay p-4", children: _jsx(Modal, { "data-sheet": "top", className: cn(
30
+ // A column the viewport's height at most: the title and the footer stay, and only the body scrolls.
31
+ 'relative flex max-h-[calc(100dvh-2rem)] w-full flex-col overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-(--shadow-lg) outline-none', widths[size], className), children: _jsxs(RACDialog, { role: role, "aria-describedby": description ? descId : undefined, className: "flex min-h-0 flex-1 flex-col outline-none", children: [_jsxs("div", { className: "flex shrink-0 items-start justify-between gap-3 px-5 pt-5", children: [_jsxs(Heading, { slot: "title", className: cn('text-heading', icon && 'flex items-center gap-2'), children: [icon && renderIcon(icon, 'size-5 shrink-0 text-muted-foreground'), icon ? _jsx("span", { className: "min-w-0", children: title }) : title] }), isDismissable && (_jsx(IconButton, { label: t('close'), icon: X, visualSize: "icon-sm", slot: "close", tooltip: false, className: "-mt-1 -mr-2 items-start justify-end" }))] }), _jsxs("div", { ref: body,
32
+ // oxlint-disable-next-line jsx-a11y/no-noninteractive-tabindex
33
+ tabIndex: bodyTabbable ? 0 : undefined, "data-tabbable": bodyTabbable || undefined, className: "relative flex min-h-0 flex-1 flex-col gap-4 overflow-y-auto px-5 pt-2 pb-5 text-sm leading-6 outline-none data-tabbable:focus-visible:focus-ring-inset", children: [description && (_jsx("div", { id: descId, className: "max-w-(--measure) text-muted-foreground", children: description })), children] }), footer && (_jsx("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-(--control-gap) border-t border-border px-5 py-4", children: footer }))] }) }) }));
19
34
  }
20
35
  export const confirmDialogLabels = {
21
36
  cancel: 'Cancel',