@estiva-app/ui 0.12.1 → 0.12.2

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 (48) hide show
  1. package/dist/CollapsibleSection.d.ts +3 -1
  2. package/dist/CollapsibleSection.d.ts.map +1 -1
  3. package/dist/DialogShell.d.ts +14 -2
  4. package/dist/DialogShell.d.ts.map +1 -1
  5. package/dist/Field.d.ts +36 -0
  6. package/dist/Field.d.ts.map +1 -1
  7. package/dist/Popover.d.ts +11 -2
  8. package/dist/Popover.d.ts.map +1 -1
  9. package/dist/ScrollArea.d.ts +14 -2
  10. package/dist/ScrollArea.d.ts.map +1 -1
  11. package/dist/SectionHeader.d.ts +10 -1
  12. package/dist/SectionHeader.d.ts.map +1 -1
  13. package/dist/Toast.d.ts +17 -7
  14. package/dist/Toast.d.ts.map +1 -1
  15. package/dist/cn.d.ts.map +1 -1
  16. package/dist/index.d.ts +1 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +51 -14
  19. package/dist/index.js.map +2 -2
  20. package/package.json +1 -1
  21. package/src/CollapsibleSection.tsx +4 -2
  22. package/src/DialogShell.mdx +9 -3
  23. package/src/DialogShell.stories.tsx +29 -0
  24. package/src/DialogShell.test.tsx +35 -0
  25. package/src/DialogShell.tsx +31 -4
  26. package/src/Field.mdx +3 -2
  27. package/src/Field.tsx +57 -2
  28. package/src/FieldLine.mdx +57 -0
  29. package/src/FieldLine.stories.tsx +80 -0
  30. package/src/FieldLine.test.tsx +56 -0
  31. package/src/Popover.mdx +3 -1
  32. package/src/Popover.stories.tsx +15 -0
  33. package/src/Popover.test.tsx +20 -0
  34. package/src/Popover.tsx +12 -3
  35. package/src/ScrollArea.mdx +5 -0
  36. package/src/ScrollArea.test.tsx +27 -1
  37. package/src/ScrollArea.tsx +16 -2
  38. package/src/SectionHeader.mdx +4 -0
  39. package/src/SectionHeader.stories.tsx +10 -1
  40. package/src/SectionHeader.test.tsx +25 -0
  41. package/src/SectionHeader.tsx +14 -1
  42. package/src/Toast.mdx +8 -2
  43. package/src/Toast.stories.tsx +13 -3
  44. package/src/Toast.tsx +44 -11
  45. package/src/cn.ts +1 -1
  46. package/src/index.ts +1 -1
  47. package/stories/Choosing.mdx +2 -0
  48. package/tailwind-preset.js +4 -0
@@ -28,6 +28,8 @@ export interface CollapsibleSectionProps {
28
28
  onOpenChange?: (open: boolean) => void;
29
29
  /** Remember open or closed in this browser, under this key. The app prefixes it. */
30
30
  storageKey?: string;
31
+ /** Beside the title and always visible, before the actions — a count. `SectionHeader`'s. */
32
+ trailing?: ReactNode;
31
33
  /** Beside the title, revealed on hover or focus — `SectionHeader`'s. */
32
34
  actions?: SectionAction[];
33
35
  showActions?: 'hover' | 'always';
@@ -38,5 +40,5 @@ export interface CollapsibleSectionProps {
38
40
  /** On the box the rows sit in: the gap between them. */
39
41
  contentClassName?: string;
40
42
  }
41
- export declare function CollapsibleSection({ title, defaultOpen, open: openProp, onOpenChange, storageKey, actions, showActions, children, className, contentClassName }: CollapsibleSectionProps): import("react").JSX.Element;
43
+ export declare function CollapsibleSection({ title, defaultOpen, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }: CollapsibleSectionProps): import("react").JSX.Element;
42
44
  //# sourceMappingURL=CollapsibleSection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollapsibleSection.d.ts","sourceRoot":"","sources":["../src/CollapsibleSection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGhD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC,gBAAgB;IAChB,QAAQ,EAAE,SAAS,CAAA;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAwBD,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,+BAyB/L"}
1
+ {"version":3,"file":"CollapsibleSection.d.ts","sourceRoot":"","sources":["../src/CollapsibleSection.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGhD,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEnE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,iCAAiC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,4FAA4F;IAC5F,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wEAAwE;IACxE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC,gBAAgB;IAChB,QAAQ,EAAE,SAAS,CAAA;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAwBD,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAkB,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,+BAyBzM"}
@@ -35,8 +35,20 @@ export interface DialogShellProps {
35
35
  * (a roster that simply ends). */
36
36
  footer?: ReactNode;
37
37
  children: ReactNode;
38
- /** Extra classes on the body (e.g. `flex flex-col gap-6`, or a max height with `overflow-y-auto`). */
38
+ /** Extra classes on the body: its layout and any padding override (`flex flex-col gap-6`, `p-0 py-2`). */
39
39
  bodyClassName?: string;
40
+ /**
41
+ * How tall the body may get before it scrolls, as the cap class —
42
+ * `max-h-[400px]`, `max-h-[70vh]`. Setting it makes the body a `ScrollArea`,
43
+ * so a long roster or a tall form scrolls in the package's bar rather than
44
+ * the browser's (D40, ADOPTION B19).
45
+ *
46
+ * Without it the body is what it always was and grows to its content, so no
47
+ * dialog written before 0.12.2 moves a pixel. A `bodyClassName` carrying
48
+ * `overflow-y-auto` and no cap never scrolled anything — the box grew — and
49
+ * is the case this replaces.
50
+ */
51
+ bodyMaxHeight?: string;
40
52
  width?: number;
41
53
  /**
42
54
  * A question that has to be answered rather than clicked away: a press on
@@ -46,5 +58,5 @@ export interface DialogShellProps {
46
58
  */
47
59
  alert?: boolean;
48
60
  }
49
- export declare function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width, alert }: DialogShellProps): import("react").JSX.Element;
61
+ export declare function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width, alert }: DialogShellProps): import("react").JSX.Element;
50
62
  //# sourceMappingURL=DialogShell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DialogShell.d.ts","sourceRoot":"","sources":["../src/DialogShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAO9C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,gBAAgB;IAC/B;8CAC0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;yDACqD;IACrD,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB;uCACmC;IACnC,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,sGAAsG;IACtG,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAW,EAAE,KAAa,EAAE,EAAE,gBAAgB,+BAqF3I"}
1
+ {"version":3,"file":"DialogShell.d.ts","sourceRoot":"","sources":["../src/DialogShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAQ9C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,gBAAgB;IAC/B;8CAC0C;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;yDACqD;IACrD,aAAa,CAAC,EAAE,SAAS,CAAA;IACzB;uCACmC;IACnC,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,0GAA0G;IAC1G,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,KAAW,EAAE,KAAa,EAAE,EAAE,gBAAgB,+BAmG1J"}
package/dist/Field.d.ts CHANGED
@@ -54,4 +54,40 @@ export interface FieldProps {
54
54
  children: ReactNode;
55
55
  }
56
56
  export declare function Field({ label, required, helper, error, children }: FieldProps): import("react").JSX.Element;
57
+ /**
58
+ * The line on its own — the same small line `Field` draws under a control,
59
+ * for the places where there is no single control to draw it under.
60
+ *
61
+ * **Why it is not a `Field`.** Three surfaces in Peek put this line under a
62
+ * *group*: the rename row (a field and two buttons), a Folder's action
63
+ * controls, another app's action controls. Each already has a section heading
64
+ * above it, and `Field` comes with a label of its own — so wrapping the group
65
+ * in one would either say the heading twice or restyle it. Found at step 4 of
66
+ * Peek's adoption (`ADOPTION.md` B24); until this existed, all three spelled
67
+ * `text-xs text-error-default` by hand.
68
+ *
69
+ * **It announces itself**, which is the half the hand-written spans never had.
70
+ * These lines appear *after* something was done — a rename that the relay
71
+ * refused, an action that failed — so a reader who cannot see them is told:
72
+ * `role="alert"` for an error, `role="status"` for the rest. That is `Banner`'s
73
+ * rule (2026-09-02), kept here so the two agree.
74
+ *
75
+ * **`warning` is the tone `Field` has not got**, and deliberately: `Field`'s
76
+ * `error` also marks its control invalid, and a warning is not invalid — the
77
+ * rename went through, and something about it needs saying. A group has no
78
+ * single control to mark, so the distinction is free here and would not be
79
+ * there.
80
+ *
81
+ * When the line belongs to one control, it is `Field`'s `helper` or `error`:
82
+ * those are wired to the control with `aria-describedby` and `aria-invalid`,
83
+ * which this cannot be.
84
+ */
85
+ export type FieldLineTone = 'helper' | 'warning' | 'error';
86
+ export interface FieldLineProps {
87
+ /** `helper` (muted) is a hint; `warning` (amber) and `error` (red) are outcomes. Default `helper`. */
88
+ tone?: FieldLineTone;
89
+ children: ReactNode;
90
+ className?: string;
91
+ }
92
+ export declare function FieldLine({ tone, children, className }: FieldLineProps): import("react").JSX.Element;
57
93
  //# sourceMappingURL=Field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,+BAqDrF"}
1
+ {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIvF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,SAAS,CAAA;CACpB;AAYD,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAgB,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,UAAU,+BAqDrF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,cAAc;IAC7B,sGAAsG;IACtG,IAAI,CAAC,EAAE,aAAa,CAAA;IACpB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAMjF"}
package/dist/Popover.d.ts CHANGED
@@ -45,8 +45,17 @@ export interface PopoverProps {
45
45
  * Render it always and toggle `open`; do not mount it only while it is open.
46
46
  */
47
47
  anchor?: HTMLElement | DOMRect | null;
48
- /** Which of the panel's edges hangs from the trigger's. Default left. */
49
- align?: 'left' | 'right';
48
+ /**
49
+ * Which of the panel's edges hangs from the trigger's, or `center` to put
50
+ * the panel's middle over the anchor's. Default left.
51
+ *
52
+ * **`center` is what a toolbar over a text selection wants** (Katerina,
53
+ * PEE-19, after Linear): the panel sits over the middle of what you
54
+ * selected, wherever in the line that is. Until 0.12.2 only the two edges
55
+ * were mapped, so Peek's selection toolbar kept the placement arithmetic
56
+ * the move onto this component was meant to delete (ADOPTION B21).
57
+ */
58
+ align?: 'left' | 'center' | 'right';
50
59
  /**
51
60
  * Which side of the trigger, or of the anchor, the panel prefers. Default
52
61
  * `bottom`.
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../src/Popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOlF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAAA;IACrC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACxB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACvB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC1C;kEAC8D;IAC9D,UAAU,CAAC,EAAE,SAAS,CAAC;QAAE,KAAK,EAAE,MAAM,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IACzE;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAOD,wBAAgB,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAc,EAAE,IAAe,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,YAAY,+BAkErK"}
1
+ {"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../src/Popover.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOlF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,GAAG,IAAI,CAAA;IACrC;;;;;;;;;OASG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;IACnC;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACvB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACtC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC1C;kEAC8D;IAC9D,UAAU,CAAC,EAAE,SAAS,CAAC;QAAE,KAAK,EAAE,MAAM,IAAI,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;IACzE;uDACmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAOD,wBAAgB,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,KAAc,EAAE,IAAe,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,YAAY,+BAkErK"}
@@ -1,4 +1,4 @@
1
- import type { ReactNode } from 'react';
1
+ import type { ReactNode, Ref, UIEventHandler } from 'react';
2
2
  /**
3
3
  * A region that scrolls without taking width for its scrollbar.
4
4
  *
@@ -40,7 +40,19 @@ export interface ScrollAreaProps {
40
40
  viewportClassName?: string;
41
41
  /** On the content, the box the children sit in: padding, gap, layout. */
42
42
  contentClassName?: string;
43
+ /**
44
+ * The scrolling box itself, for a region that reads or drives its own
45
+ * scrolling: `ref.current.scrollTop`, `scrollTo`, `scrollHeight`.
46
+ *
47
+ * A conversation is the case this exists for (ADOPTION B20): it arrives at
48
+ * the newest message, keeps its place when older ones load above, and jumps
49
+ * to the bottom when a reply is sent — none of which the region can do for
50
+ * the caller, and all of which the caller cannot do without the box.
51
+ */
52
+ viewportRef?: Ref<HTMLDivElement>;
53
+ /** Fires as the viewport scrolls — the unread policy's input, beside `viewportRef`. */
54
+ onScroll?: UIEventHandler<HTMLDivElement>;
43
55
  children: ReactNode;
44
56
  }
45
- export declare function ScrollArea({ orientation, className, viewportClassName, contentClassName, children }: ScrollAreaProps): import("react").JSX.Element;
57
+ export declare function ScrollArea({ orientation, className, viewportClassName, contentClassName, viewportRef, onScroll, children }: ScrollAreaProps): import("react").JSX.Element;
46
58
  //# sourceMappingURL=ScrollArea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../src/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAItC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAA;IAChD,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAKD,wBAAgB,UAAU,CAAC,EAAE,WAAwB,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,EAAE,eAAe,+BA0CjI"}
1
+ {"version":3,"file":"ScrollArea.d.ts","sourceRoot":"","sources":["../src/ScrollArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAI3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,MAAM,CAAA;IAChD,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,cAAc,CAAC,CAAA;IACjC,uFAAuF;IACvF,QAAQ,CAAC,EAAE,cAAc,CAAC,cAAc,CAAC,CAAA;IACzC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAKD,wBAAgB,UAAU,CAAC,EAAE,WAAwB,EAAE,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,eAAe,+BA4CxJ"}
@@ -40,6 +40,15 @@ export interface SectionHeaderProps {
40
40
  chevron?: boolean;
41
41
  isExpanded?: boolean;
42
42
  onToggle?: () => void;
43
+ /**
44
+ * Beside the title and always visible, before the actions — a count.
45
+ *
46
+ * The actions come and go with the hover; this does not, because a count is
47
+ * information rather than an affordance. Peek's Screener header carries its
48
+ * number as a `Chip` here, and was the last hand-drawn folding header in the
49
+ * app for want of the slot (ADOPTION B23).
50
+ */
51
+ trailing?: ReactNode;
43
52
  /** Right-aligned, in the order given. */
44
53
  actions?: SectionAction[];
45
54
  /** `hover` reveals the actions while the row is hovered or focused; `always` keeps them. */
@@ -51,5 +60,5 @@ export interface SectionHeaderProps {
51
60
  render?: useRender.RenderProp;
52
61
  className?: string;
53
62
  }
54
- export declare function SectionHeader({ title, chevron, isExpanded, onToggle, actions, showActions, render, className }: SectionHeaderProps): import("react").JSX.Element;
63
+ export declare function SectionHeader({ title, chevron, isExpanded, onToggle, trailing, actions, showActions, render, className }: SectionHeaderProps): import("react").JSX.Element;
55
64
  //# sourceMappingURL=SectionHeader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SectionHeader.d.ts","sourceRoot":"","sources":["../src/SectionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,yCAAyC;IACzC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC,UAAU,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,OAAe,EAAE,UAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAqB,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BAuD3J"}
1
+ {"version":3,"file":"SectionHeader.d.ts","sourceRoot":"","sources":["../src/SectionHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAKrD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,WAAW,aAAa;IAC5B,wBAAwB;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,yCAAyC;IACzC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;IACzB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;IAChC;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC,UAAU,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,OAAe,EAAE,UAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAqB,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,+BA2DrK"}
package/dist/Toast.d.ts CHANGED
@@ -2,8 +2,9 @@ import { type ReactNode } from 'react';
2
2
  /**
3
3
  * Peek's Toast (Figma: Alert) and its provider (2026-09-01), verbatim.
4
4
  *
5
- * The pill: three types — `success`, `brand`, `neutral` — an optional leading
6
- * circle-check, an optional action on the right. Under Signal every toast is
5
+ * The pill: five types — `success`, `brand`, `neutral`, `warning`, `error`
6
+ * a leading icon that says which (a check, a `!`, an `×`), an optional action
7
+ * on the right. Under Signal every toast is
7
8
  * the same dark overlay pill; the type lives in the icon's colour and glow,
8
9
  * not the surface.
9
10
  *
@@ -11,12 +12,21 @@ import { type ReactNode } from 'react';
11
12
  * (5 s; pass `durationMs: 0` to keep one up). One toast at a time — a new
12
13
  * one replaces the standing one, it does not queue.
13
14
  */
14
- export type ToastType = 'success' | 'brand' | 'neutral';
15
+ export type ToastType = 'success' | 'brand' | 'neutral' | 'warning' | 'error';
15
16
  export interface ToastProps {
16
17
  label: string;
17
- /** Visual variant per Figma (Alert component): success, brand, or neutral. */
18
+ /**
19
+ * Which of the five this is. It decides the surface in the light themes,
20
+ * and under Signal — where every pill is the same dark overlay — the icon
21
+ * and its colour.
22
+ *
23
+ * `warning` and `error` arrived at 0.12.2, for a notice that has to stay up
24
+ * and for one that reports a failure. Until then the set had no way to say
25
+ * either, so a caller with bad news passed `leadingIcon: false` rather than
26
+ * put a tick beside it.
27
+ */
18
28
  type?: ToastType;
19
- /** Show the leading circle-check icon. Defaults to true. */
29
+ /** Show the leading icon — a check, a `!` or an `×`, per `type`. Defaults to true. */
20
30
  leadingIcon?: boolean;
21
31
  /** When set together with onAction, renders a clickable action on the right side. */
22
32
  actionLabel?: string;
@@ -26,12 +36,12 @@ export interface ToastProps {
26
36
  export declare function Toast({ label, type, leadingIcon, actionLabel, onAction, className }: ToastProps): import("react").JSX.Element;
27
37
  export interface ToastOptions {
28
38
  label: string;
29
- /** Visual variant per Figma (Alert component). Defaults to 'neutral'. */
39
+ /** Which of the five this is — it decides the surface and the leading icon. Defaults to 'neutral'. */
30
40
  type?: ToastType;
31
41
  /** When set, renders a clickable action on the right side. */
32
42
  actionLabel?: string;
33
43
  onAction?: () => void;
34
- /** Show the leading circle-check icon. Defaults to true. */
44
+ /** Show the leading icon — a check, a `!` or an `×`, per `type`. Defaults to true. */
35
45
  leadingIcon?: boolean;
36
46
  /** Auto-dismiss after this many ms. Defaults to 5000. Pass 0 to disable. */
37
47
  durationMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../src/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5G;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAA;AAEvD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAsBD,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAgB,EAAE,WAAkB,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,UAAU,+BAkClH;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAMD,UAAU,UAAU;IAClB,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB;AAMD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAiDlE;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAIrC"}
1
+ {"version":3,"file":"Toast.d.ts","sourceRoot":"","sources":["../src/Toast.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAwE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5G;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAE7E,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;;OASG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,sFAAsF;IACtF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA8CD,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAgB,EAAE,WAAkB,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,UAAU,+BAiClH;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,sGAAsG;IACtG,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,sFAAsF;IACtF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAMD,UAAU,UAAU;IAClB,SAAS,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IACvC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB;AAMD,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BAiDlE;AAED,wBAAgB,QAAQ,IAAI,UAAU,CAIrC"}
package/dist/cn.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB,UAIrB,CAAA;AAED;;;;;;GAMG;AACH,QAAA,MAAM,iBAAiB,UAAqG,CAAA;AAC5H,QAAA,MAAM,kBAAkB,UAAkC,CAAA;AAY1D,0EAA0E;AAC1E,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,iBAAiB,IAAI,gBAAgB,EAAE,kBAAkB,IAAI,iBAAiB,EAAE,CAAA"}
1
+ {"version":3,"file":"cn.d.ts","sourceRoot":"","sources":["../src/cn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,gBAAgB,UAIrB,CAAA;AAED;;;;;;GAMG;AACH,QAAA,MAAM,iBAAiB,UAAqG,CAAA;AAC5H,QAAA,MAAM,kBAAkB,UAAkD,CAAA;AAY1E,0EAA0E;AAC1E,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,OAAO,EAAE,gBAAgB,IAAI,eAAe,EAAE,iBAAiB,IAAI,gBAAgB,EAAE,kBAAkB,IAAI,iBAAiB,EAAE,CAAA"}
package/dist/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export { IconButton, type IconButtonProps, type IconButtonVariant } from './Icon
21
21
  export { Kbd, type KbdProps } from './Kbd';
22
22
  export { IdentityMenu, IdentityPanel, type Identity, type IdentityMenuProps, type IdentityPanelProps } from './IdentityMenu';
23
23
  export { Tooltip, TooltipProvider, WithTooltip, type TooltipProps, type TooltipProviderProps, type WithTooltipProps } from './Tooltip';
24
- export { Field, type FieldProps } from './Field';
24
+ export { Field, FieldLine, type FieldLineProps, type FieldLineTone, type FieldProps } from './Field';
25
25
  export { Select, type SelectOption, type SelectProps } from './Select';
26
26
  export { TextInput, type TextInputProps } from './TextInput';
27
27
  export { Textarea, type TextareaProps } from './Textarea';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAC1F,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAA;AACxF,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAA;AACvF,OAAO,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAC5H,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,YAAY,EAAE,KAAK,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAA;AACtI,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACtE,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACrE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACnE,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,KAAK,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAA;AACxK,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAC/D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAChG,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AACtJ,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAC5F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC1D,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AAC5G,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -20,7 +20,7 @@ var FONT_SIZE_TOKENS = [
20
20
  "chip"
21
21
  ];
22
22
  var BOX_SHADOW_TOKENS = ["sm", "md", "lg", "focus-ring", "glow-warning", "glow-success", "glow-accent", "highlight-inset"];
23
- var DROP_SHADOW_TOKENS = ["glow-success", "glow-accent"];
23
+ var DROP_SHADOW_TOKENS = ["glow-success", "glow-accent", "glow-warning"];
24
24
  var twMerge = extendTailwindMerge({
25
25
  extend: {
26
26
  classGroups: {
@@ -39,13 +39,15 @@ import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
39
39
  import { jsx, jsxs } from "react/jsx-runtime";
40
40
  var BAR = "flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
41
41
  var THUMB = "rounded-full bg-border-strong";
42
- function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, children }) {
42
+ function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, viewportRef, onScroll, children }) {
43
43
  const vertical = orientation !== "horizontal";
44
44
  const horizontal = orientation !== "vertical";
45
45
  return /* @__PURE__ */ jsxs(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
46
46
  /* @__PURE__ */ jsx(
47
47
  BaseScrollArea.Viewport,
48
48
  {
49
+ ref: viewportRef,
50
+ onScroll,
49
51
  className: cn(
50
52
  "h-full w-full outline-none data-[has-overflow-x]:overscroll-x-contain data-[has-overflow-y]:overscroll-y-contain",
51
53
  viewportClassName
@@ -1090,6 +1092,11 @@ function Note({ children }) {
1090
1092
  import { cloneElement, isValidElement } from "react";
1091
1093
  import { Field as BaseField } from "@base-ui/react/field";
1092
1094
  import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
1095
+ var LINE_STYLES = {
1096
+ helper: "text-caption text-text-muted",
1097
+ warning: "text-caption text-warning-default",
1098
+ error: "text-caption text-error-default"
1099
+ };
1093
1100
  function Field({ label, required = false, helper, error, children }) {
1094
1101
  const control = required && isValidElement(children) ? cloneElement(children, {
1095
1102
  "aria-required": children.props["aria-required"] ?? true
@@ -1101,10 +1108,13 @@ function Field({ label, required = false, helper, error, children }) {
1101
1108
  ] }),
1102
1109
  /* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1.5", children: [
1103
1110
  control,
1104
- error != null ? /* @__PURE__ */ jsx20(BaseField.Error, { match: true, className: "text-caption text-error-default", children: error }) : helper != null ? /* @__PURE__ */ jsx20(BaseField.Description, { className: "text-caption text-text-muted", children: helper }) : null
1111
+ error != null ? /* @__PURE__ */ jsx20(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx20(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
1105
1112
  ] })
1106
1113
  ] });
1107
1114
  }
1115
+ function FieldLine({ tone = "helper", children, className }) {
1116
+ return /* @__PURE__ */ jsx20("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
1117
+ }
1108
1118
 
1109
1119
  // src/Select.tsx
1110
1120
  import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
@@ -1259,7 +1269,7 @@ import { Dialog } from "@base-ui/react/dialog";
1259
1269
  import { AlertDialog } from "@base-ui/react/alert-dialog";
1260
1270
  import { IconX as IconX3 } from "@tabler/icons-react";
1261
1271
  import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
1262
- function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width = 502, alert = false }) {
1272
+ function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
1263
1273
  const Parts = alert ? AlertDialog : Dialog;
1264
1274
  const popupRef = useRef3(null);
1265
1275
  return /* @__PURE__ */ jsx24(
@@ -1289,7 +1299,15 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
1289
1299
  }
1290
1300
  )
1291
1301
  ] }),
1292
- /* @__PURE__ */ jsx24("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1302
+ bodyMaxHeight ? /* @__PURE__ */ jsx24(
1303
+ ScrollArea,
1304
+ {
1305
+ className: cn(footer != null && "border-b border-border-subtle"),
1306
+ viewportClassName: bodyMaxHeight,
1307
+ contentClassName: cn("pl-5 pr-4 py-4", bodyClassName),
1308
+ children
1309
+ }
1310
+ ) : /* @__PURE__ */ jsx24("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
1293
1311
  footer != null && /* @__PURE__ */ jsx24("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
1294
1312
  ]
1295
1313
  }
@@ -1575,7 +1593,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
1575
1593
  {
1576
1594
  anchor: anchorTarget,
1577
1595
  side,
1578
- align: align === "right" ? "end" : "start",
1596
+ align: align === "right" ? "end" : align === "center" ? "center" : "start",
1579
1597
  sideOffset: GAP5,
1580
1598
  collisionPadding: VIEWPORT_PAD4,
1581
1599
  className: "z-50 data-[anchor-hidden]:hidden",
@@ -1845,7 +1863,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
1845
1863
  import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
1846
1864
  import { useRender } from "@base-ui/react/use-render";
1847
1865
  import { Fragment as Fragment5, jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
1848
- function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, actions, showActions = "hover", render, className }) {
1866
+ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", render, className }) {
1849
1867
  const titleElement = useRender({
1850
1868
  render: render ?? (chevron ? /* @__PURE__ */ jsx41("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx41("span", {})),
1851
1869
  props: {
@@ -1879,6 +1897,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, ac
1879
1897
  ),
1880
1898
  children: [
1881
1899
  titleElement,
1900
+ trailing != null && /* @__PURE__ */ jsx41("div", { className: "flex shrink-0 items-center", children: trailing }),
1882
1901
  actions && actions.length > 0 && /* @__PURE__ */ jsx41(
1883
1902
  "div",
1884
1903
  {
@@ -1916,7 +1935,7 @@ function writeStored(key, open) {
1916
1935
  } catch {
1917
1936
  }
1918
1937
  }
1919
- function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, actions, showActions, children, className, contentClassName }) {
1938
+ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }) {
1920
1939
  const [openState, setOpenState] = useState6(() => readStored(storageKey) ?? defaultOpen);
1921
1940
  const open = openProp ?? openState;
1922
1941
  const setOpen = (next) => {
@@ -1925,7 +1944,7 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
1925
1944
  onOpenChange?.(next);
1926
1945
  };
1927
1946
  return /* @__PURE__ */ jsxs29(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
1928
- /* @__PURE__ */ jsx42(SectionHeader, { title, chevron: true, isExpanded: open, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx42(Collapsible.Trigger, {}) }),
1947
+ /* @__PURE__ */ jsx42(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx42(Collapsible.Trigger, {}) }),
1929
1948
  /* @__PURE__ */ jsx42(
1930
1949
  Collapsible.Panel,
1931
1950
  {
@@ -1986,25 +2005,42 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
1986
2005
  // src/Toast.tsx
1987
2006
  import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo3, useState as useState7 } from "react";
1988
2007
  import { createPortal as createPortal2 } from "react-dom";
1989
- import { IconCircleCheck } from "@tabler/icons-react";
2008
+ import { IconAlertCircle, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
1990
2009
  import { jsx as jsx44, jsxs as jsxs31 } from "react/jsx-runtime";
1991
2010
  var SURFACE_STYLES = {
1992
2011
  success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
1993
2012
  brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
1994
- neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]"
2013
+ neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
2014
+ warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
2015
+ error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]"
2016
+ };
2017
+ var ICONS = {
2018
+ success: IconCircleCheck,
2019
+ brand: IconCircleCheck,
2020
+ neutral: IconCircleCheck,
2021
+ warning: IconAlertCircle,
2022
+ error: IconCircleX
1995
2023
  };
1996
2024
  var ICON_STYLES = {
1997
2025
  success: "signal:text-success-default signal:drop-shadow-glow-success",
1998
2026
  brand: "signal:text-text-interactive signal:drop-shadow-glow-accent",
1999
- neutral: "signal:text-text-secondary"
2027
+ neutral: "signal:text-text-secondary",
2028
+ warning: "signal:text-warning-default signal:drop-shadow-glow-warning",
2029
+ // No glow: the theme defines `--glow-warning`, `--glow-success` and
2030
+ // `--glow-accent` and no error glow, and a colour with no token is not
2031
+ // approximated here (D16).
2032
+ error: "signal:text-error-default"
2000
2033
  };
2001
2034
  var ACTION_BORDER_STYLES = {
2002
2035
  success: "signal:border signal:border-border-default signal:hover:border-border-strong",
2003
2036
  brand: "signal:border signal:border-border-default signal:hover:border-border-strong",
2004
- neutral: "border border-border-default"
2037
+ neutral: "border border-border-default",
2038
+ warning: "signal:border signal:border-border-default signal:hover:border-border-strong",
2039
+ error: "signal:border signal:border-border-default signal:hover:border-border-strong"
2005
2040
  };
2006
2041
  function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
2007
2042
  const hasAction = !!(actionLabel && onAction);
2043
+ const LeadingIcon = ICONS[type];
2008
2044
  return /* @__PURE__ */ jsxs31(
2009
2045
  "div",
2010
2046
  {
@@ -2018,7 +2054,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
2018
2054
  ),
2019
2055
  children: [
2020
2056
  /* @__PURE__ */ jsxs31("div", { className: "flex items-center gap-2 shrink-0", children: [
2021
- leadingIcon && /* @__PURE__ */ jsx44(IconCircleCheck, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
2057
+ leadingIcon && /* @__PURE__ */ jsx44(LeadingIcon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
2022
2058
  /* @__PURE__ */ jsx44("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
2023
2059
  ] }),
2024
2060
  hasAction && /* @__PURE__ */ jsx44(
@@ -2102,6 +2138,7 @@ export {
2102
2138
  EmptyState,
2103
2139
  EnterHint,
2104
2140
  Field,
2141
+ FieldLine,
2105
2142
  IconButton,
2106
2143
  IdentityMenu,
2107
2144
  IdentityPanel,