@estiva-app/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 (151) hide show
  1. package/dist/Avatar.d.ts +13 -1
  2. package/dist/Avatar.d.ts.map +1 -1
  3. package/dist/AvatarGroup.d.ts.map +1 -1
  4. package/dist/Banner.d.ts +16 -1
  5. package/dist/Banner.d.ts.map +1 -1
  6. package/dist/Breadcrumb.d.ts +9 -0
  7. package/dist/Breadcrumb.d.ts.map +1 -1
  8. package/dist/Button.d.ts +12 -2
  9. package/dist/Button.d.ts.map +1 -1
  10. package/dist/Checkbox.d.ts +2 -0
  11. package/dist/Checkbox.d.ts.map +1 -1
  12. package/dist/Chip.d.ts +3 -2
  13. package/dist/Chip.d.ts.map +1 -1
  14. package/dist/ChipInput.d.ts +3 -1
  15. package/dist/ChipInput.d.ts.map +1 -1
  16. package/dist/ConfirmDialog.d.ts +5 -0
  17. package/dist/ConfirmDialog.d.ts.map +1 -1
  18. package/dist/DialogShell.d.ts +27 -3
  19. package/dist/DialogShell.d.ts.map +1 -1
  20. package/dist/EditableText.d.ts +6 -0
  21. package/dist/EditableText.d.ts.map +1 -1
  22. package/dist/Field.d.ts +42 -25
  23. package/dist/Field.d.ts.map +1 -1
  24. package/dist/IconButton.d.ts +3 -2
  25. package/dist/IconButton.d.ts.map +1 -1
  26. package/dist/IdentityMenu.d.ts +25 -13
  27. package/dist/IdentityMenu.d.ts.map +1 -1
  28. package/dist/Menu.d.ts +65 -82
  29. package/dist/Menu.d.ts.map +1 -1
  30. package/dist/PersonTrigger.d.ts.map +1 -1
  31. package/dist/Popover.d.ts +86 -0
  32. package/dist/Popover.d.ts.map +1 -0
  33. package/dist/PreviewCard.d.ts +39 -0
  34. package/dist/PreviewCard.d.ts.map +1 -0
  35. package/dist/Reaction.d.ts.map +1 -1
  36. package/dist/ReactionPicker.d.ts +55 -0
  37. package/dist/ReactionPicker.d.ts.map +1 -0
  38. package/dist/SearchInput.d.ts +5 -0
  39. package/dist/SearchInput.d.ts.map +1 -1
  40. package/dist/Select.d.ts +26 -16
  41. package/dist/Select.d.ts.map +1 -1
  42. package/dist/Tabs.d.ts +11 -1
  43. package/dist/Tabs.d.ts.map +1 -1
  44. package/dist/TextInput.d.ts +7 -1
  45. package/dist/TextInput.d.ts.map +1 -1
  46. package/dist/Textarea.d.ts +8 -1
  47. package/dist/Textarea.d.ts.map +1 -1
  48. package/dist/Toolbar.d.ts +95 -0
  49. package/dist/Toolbar.d.ts.map +1 -0
  50. package/dist/Tooltip.d.ts +36 -10
  51. package/dist/Tooltip.d.ts.map +1 -1
  52. package/dist/cn.d.ts.map +1 -1
  53. package/dist/fit.d.ts +7 -72
  54. package/dist/fit.d.ts.map +1 -1
  55. package/dist/index.d.ts +6 -3
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +882 -763
  58. package/dist/index.js.map +4 -4
  59. package/package.json +1 -1
  60. package/src/Avatar.mdx +17 -0
  61. package/src/Avatar.name.test.tsx +99 -0
  62. package/src/Avatar.tsx +25 -3
  63. package/src/AvatarGroup.tsx +4 -1
  64. package/src/Banner.mdx +10 -2
  65. package/src/Banner.stories.tsx +29 -0
  66. package/src/Banner.test.tsx +60 -0
  67. package/src/Banner.tsx +35 -3
  68. package/src/Breadcrumb.mdx +5 -2
  69. package/src/Breadcrumb.test.tsx +44 -0
  70. package/src/Breadcrumb.tsx +10 -2
  71. package/src/Button.compose.test.tsx +119 -0
  72. package/src/Button.mdx +7 -5
  73. package/src/Button.test.tsx +2 -1
  74. package/src/Button.tsx +21 -5
  75. package/src/Checkbox.tsx +3 -0
  76. package/src/Chip.tsx +3 -2
  77. package/src/ChipInput.tsx +4 -0
  78. package/src/ConfirmDialog.mdx +20 -1
  79. package/src/ConfirmDialog.test.tsx +109 -0
  80. package/src/ConfirmDialog.tsx +6 -0
  81. package/src/DialogShell.mdx +18 -4
  82. package/src/DialogShell.stories.tsx +56 -6
  83. package/src/DialogShell.test.tsx +184 -0
  84. package/src/DialogShell.tsx +108 -39
  85. package/src/EditableText.mdx +6 -1
  86. package/src/EditableText.test.tsx +156 -0
  87. package/src/EditableText.tsx +23 -5
  88. package/src/Field.mdx +23 -3
  89. package/src/Field.stories.tsx +35 -0
  90. package/src/Field.test.tsx +117 -27
  91. package/src/Field.tsx +86 -58
  92. package/src/IconButton.mdx +6 -2
  93. package/src/IconButton.test.tsx +5 -2
  94. package/src/IconButton.tsx +12 -6
  95. package/src/IdentityMenu.mdx +29 -6
  96. package/src/IdentityMenu.stories.tsx +41 -6
  97. package/src/IdentityMenu.tsx +74 -47
  98. package/src/Kbd.stories.tsx +3 -3
  99. package/src/Menu.mdx +88 -75
  100. package/src/Menu.stories.tsx +120 -52
  101. package/src/Menu.test.tsx +315 -0
  102. package/src/Menu.tsx +341 -251
  103. package/src/MenuItem.stories.tsx +135 -98
  104. package/src/NavItem.mdx +1 -1
  105. package/src/PersonTrigger.mdx +20 -14
  106. package/src/PersonTrigger.tsx +23 -1
  107. package/src/Popover.mdx +130 -0
  108. package/src/Popover.stories.tsx +222 -0
  109. package/src/Popover.test.tsx +188 -0
  110. package/src/Popover.tsx +153 -0
  111. package/src/PreviewCard.mdx +98 -0
  112. package/src/PreviewCard.stories.tsx +168 -0
  113. package/src/PreviewCard.test.tsx +83 -0
  114. package/src/PreviewCard.tsx +91 -0
  115. package/src/Rail.mdx +63 -0
  116. package/src/Rail.stories.tsx +81 -0
  117. package/src/Reaction.mdx +4 -2
  118. package/src/Reaction.tsx +4 -2
  119. package/src/ReactionPicker.mdx +85 -0
  120. package/src/ReactionPicker.stories.tsx +120 -0
  121. package/src/ReactionPicker.test.tsx +118 -0
  122. package/src/ReactionPicker.tsx +88 -0
  123. package/src/SearchInput.mdx +6 -2
  124. package/src/SearchInput.tsx +7 -1
  125. package/src/Select.mdx +16 -5
  126. package/src/Select.test.tsx +157 -0
  127. package/src/Select.tsx +89 -214
  128. package/src/Sidebar.mdx +6 -2
  129. package/src/Tabs.mdx +5 -0
  130. package/src/Tabs.test.tsx +15 -0
  131. package/src/Tabs.tsx +17 -2
  132. package/src/TextInput.mdx +8 -2
  133. package/src/TextInput.tsx +10 -7
  134. package/src/Textarea.mdx +6 -2
  135. package/src/Textarea.tsx +14 -9
  136. package/src/Toolbar.mdx +104 -0
  137. package/src/Toolbar.stories.tsx +142 -0
  138. package/src/Toolbar.test.tsx +198 -0
  139. package/src/Toolbar.tsx +158 -0
  140. package/src/Tooltip.mdx +43 -5
  141. package/src/Tooltip.stories.tsx +26 -0
  142. package/src/Tooltip.test.tsx +195 -0
  143. package/src/Tooltip.tsx +150 -48
  144. package/src/cn.ts +1 -1
  145. package/src/fit.test.ts +101 -0
  146. package/src/fit.ts +19 -63
  147. package/src/index.ts +6 -3
  148. package/stories/Choosing.mdx +8 -3
  149. package/tailwind-preset.js +7 -0
  150. package/src/Menu.fit.test.ts +0 -90
  151. package/src/Select.fit.test.ts +0 -101
package/dist/Avatar.d.ts CHANGED
@@ -15,7 +15,19 @@ export interface AvatarProps {
15
15
  alt?: string;
16
16
  /** Pixels. The scale: 16 · 24 · 32 · 36 (default). */
17
17
  size?: number;
18
+ /**
19
+ * **Say the person's name out loud**, for a face that stands on its own —
20
+ * `PersonTrigger`'s compact shape, a stack of members.
21
+ *
22
+ * A face is silent by default, because almost every face in the suite sits
23
+ * beside the name it belongs to: `Person`, a `MenuItem`'s `leading`, a row.
24
+ * A picture that spoke there would double the name — measured 2026-09-08,
25
+ * before this existed: a `Person` in a button announced **"AD Ana Duarte"**,
26
+ * and with a picture **"Ana Duarte Ana Duarte"**. The initials are a drawing
27
+ * of a name, not text, and a screen reader was reading them as text.
28
+ */
29
+ label?: string;
18
30
  className?: string;
19
31
  }
20
- export declare function Avatar({ src, name, alt, size, className }: AvatarProps): import("react").JSX.Element;
32
+ export declare function Avatar({ src, name, alt, size, label: spoken, className }: AvatarProps): import("react").JSX.Element;
21
33
  //# sourceMappingURL=Avatar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../src/Avatar.tsx"],"names":[],"mappings":"AA2BA,eAAO,MAAM,MAAM,GAAI,KAAK,MAAM,WAIjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,WAIvC,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,wGAAwG;IACxG,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uGAAuG;IACvG,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAQ,EAAE,IAAS,EAAE,SAAS,EAAE,EAAE,WAAW,+BAuChF"}
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../src/Avatar.tsx"],"names":[],"mappings":"AA2BA,eAAO,MAAM,MAAM,GAAI,KAAK,MAAM,WAIjC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,MAAM,WAIvC,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,wGAAwG;IACxG,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uGAAuG;IACvG,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;OAUG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAQ,EAAE,IAAS,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,WAAW,+BAiD/F"}
@@ -1 +1 @@
1
- {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../src/AvatarGroup.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,IAAS,EAAE,EAAE,gBAAgB,+BA8BnE"}
1
+ {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../src/AvatarGroup.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,iBAAiB,EAAE,CAAA;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,IAAS,EAAE,EAAE,gBAAgB,+BAiCnE"}
package/dist/Banner.d.ts CHANGED
@@ -8,12 +8,27 @@
8
8
  * rendered, so 14px is what it has always been and what she kept.
9
9
  * An `error` announces itself (`role="alert"`); the other tones are
10
10
  * polite (`role="status"`).
11
+ *
12
+ * `onDismiss` adds an `✕` at the right-hand end (Katerina, D21,
13
+ * 2026-09-07). Without it the strip is exactly what it was — a banner an
14
+ * app removes by not rendering it. With it the row is 40px rather than
15
+ * 36px, because the button is taller than the line of text.
16
+ *
17
+ * **A banner is not a toast.** This is the strip under the header, at the
18
+ * app's full width, for something that stays true. Transient feedback is
19
+ * `Toast`, and something that floats over the page and must not fade is a
20
+ * `Toast` with `durationMs: 0` — which is what Peek's "topic deleted"
21
+ * notice is (D21), not this.
11
22
  */
12
23
  export type BannerTone = 'ok' | 'error' | 'info' | 'warning';
13
24
  export interface BannerProps {
14
25
  tone: BannerTone;
15
26
  children: string;
27
+ /** Adds an `✕` at the right-hand end. Absent: the app removes the banner. */
28
+ onDismiss?: () => void;
29
+ /** The dismiss button's accessible name. Defaults to "Dismiss". */
30
+ dismissLabel?: string;
16
31
  className?: string;
17
32
  }
18
- export declare function Banner({ tone, children, className }: BannerProps): import("react").JSX.Element;
33
+ export declare function Banner({ tone, children, onDismiss, dismissLabel, className }: BannerProps): import("react").JSX.Element;
19
34
  //# sourceMappingURL=Banner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../src/Banner.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AASD,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,WAAW,+BAMhE"}
1
+ {"version":3,"file":"Banner.d.ts","sourceRoot":"","sources":["../src/Banner.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;AAE5D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AASD,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAwB,EAAE,SAAS,EAAE,EAAE,WAAW,+BAqBrG"}
@@ -1,3 +1,4 @@
1
+ import { type MouseEventHandler } from 'react';
1
2
  /**
2
3
  * A trail: "Documents / Quarterly plan / DOC-12". Ship's Breadcrumb
3
4
  * (2026-09-01), which knows nothing about what the places are.
@@ -11,10 +12,18 @@
11
12
  * (Katerina, 2026-09-01); one that fits shows nothing extra. Truncation is
12
13
  * re-measured when the trail resizes, so the tooltip appears and disappears
13
14
  * with the room the trail actually has.
15
+ *
16
+ * A crumb with an `href` is a plain anchor, so in a router app a click on it
17
+ * reloads the page. Such an app passes `onClick` per crumb and navigates in
18
+ * place there — NavItem's rule — and the `href` stays a real address so the
19
+ * link can still be copied or opened in a new tab. Ship's breadcrumbs were
20
+ * the last links reloading the whole app (ADOPTION S15, 2026-09-08).
14
21
  */
15
22
  export interface Crumb {
16
23
  label: string;
17
24
  href?: string;
25
+ /** A router app intercepts the click here. Called only on a crumb with an `href`. */
26
+ onClick?: MouseEventHandler<HTMLAnchorElement>;
18
27
  /** Set the item in the mono face — a ref, an id. */
19
28
  mono?: boolean;
20
29
  /** Quieter — a label that is not a place. */
@@ -1 +1 @@
1
- {"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../src/Breadcrumb.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,EAAE,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,+BAyE/D"}
1
+ {"version":3,"file":"Breadcrumb.d.ts","sourceRoot":"","sources":["../src/Breadcrumb.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4D,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAIxG;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,OAAO,CAAC,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAA;IAC9C,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,EAAE,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,+BAyE/D"}
package/dist/Button.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ButtonHTMLAttributes, ReactNode } from 'react';
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  /**
3
3
  * Peek's Button (2026-08-28), verbatim, plus what Ship added and Peek should
4
4
  * adopt: a `destructive` variant — the muted button in the error colour, for
@@ -21,7 +21,17 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
21
21
  */
22
22
  export type ButtonVariant = 'primary' | 'outlined' | 'muted' | 'destructive';
23
23
  export type ButtonSize = 'default' | 'small';
24
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
24
+ /**
25
+ * `ComponentPropsWithRef`, not `ButtonHTMLAttributes`, so a `ref` reaches the
26
+ * element. React 19 passes `ref` to a function component as an ordinary prop,
27
+ * so nothing here forwards it by hand — it rides in on the spread below. What
28
+ * was missing was only the *type* saying so, which is enough to stop a caller.
29
+ *
30
+ * It matters because a Base UI part composes through `render`: at stage 4 a
31
+ * `Menu.Trigger` or a `Dialog.Close` **is** this Button rather than wrapping
32
+ * one, and a trigger that cannot be measured or focused is not a trigger.
33
+ */
34
+ export interface ButtonProps extends ComponentPropsWithRef<'button'> {
25
35
  variant?: ButtonVariant;
26
36
  size?: ButtonSize;
27
37
  /** 16px, stroke 1.5 on the default size; 14px on small. */
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AAE5C,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;6EACyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAiB,EACjB,IAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,IAAe,EACf,GAAG,KAAK,EACT,EAAE,WAAW,+BA+Bb"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../src/Button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,aAAa,CAAA;AAC5E,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;AAE5C;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAY,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IAClE,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB;6EACyE;IACzE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAiB,EACjB,IAAgB,EAChB,WAAW,EACX,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,IAAe,EACf,GAAG,KAAK,EACT,EAAE,WAAW,+BAqCb"}
@@ -26,6 +26,8 @@ export interface CheckboxProps {
26
26
  onChange?: (checked: boolean) => void;
27
27
  disabled?: boolean;
28
28
  'aria-label'?: string;
29
+ /** Set by a `Field` with `required`; a caller inside one owes nothing. */
30
+ 'aria-required'?: boolean | 'true' | 'false';
29
31
  className?: string;
30
32
  }
31
33
  export declare function Checkbox({ checked, onChange, disabled, className, ...aria }: CheckboxProps): import("react").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../src/Checkbox.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAeD,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BAwBlG"}
1
+ {"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../src/Checkbox.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAeD,wBAAgB,QAAQ,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAgB,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BAyBlG"}
package/dist/Chip.d.ts CHANGED
@@ -6,8 +6,9 @@ import type { ReactNode } from 'react';
6
6
  * slots centre their icon (Ship's addition — an icon beside text otherwise
7
7
  * rides on the baseline).
8
8
  *
9
- * The label is the `chip` type token, 11px / 500; it is a plain class here,
10
- * never merged, so tailwind-merge cannot drop it.
9
+ * The label is the `chip` type token, 11px / 500. It used to be spelled as a
10
+ * plain class under a note that it must never be merged; `cn()` knows the ramp
11
+ * now, so a token size survives beside a colour and the note is retired.
11
12
  */
12
13
  export type ChipType = 'neutral' | 'brand' | 'info' | 'warning' | 'success' | 'error';
13
14
  export interface ChipProps {
@@ -1 +1 @@
1
- {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../src/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAErF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAWD,wBAAgB,IAAI,CAAC,EAAE,IAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,SAAS,+BAUhG"}
1
+ {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../src/Chip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAA;AAErF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAWD,wBAAgB,IAAI,CAAC,EAAE,IAAgB,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,SAAS,+BAUhG"}
@@ -52,6 +52,8 @@ export interface ChipInputProps<T extends ChipInputOption = ChipInputOption> {
52
52
  chipLeading?: (option: T) => ReactNode;
53
53
  /** Before a suggestion row's label, 32px. */
54
54
  rowLeading?: (option: T) => ReactNode;
55
+ /** Set by a `Field` with `required`; a caller inside one owes nothing. */
56
+ 'aria-required'?: boolean | 'true' | 'false';
55
57
  }
56
- export declare function ChipInput<T extends ChipInputOption = ChipInputOption>({ value, onChange, options, placeholder, autoFocus, excludeIds, chipLeading, rowLeading, }: ChipInputProps<T>): import("react").JSX.Element;
58
+ export declare function ChipInput<T extends ChipInputOption = ChipInputOption>({ value, onChange, options, placeholder, autoFocus, excludeIds, chipLeading, rowLeading, ...aria }: ChipInputProps<T>): import("react").JSX.Element;
57
59
  //# sourceMappingURL=ChipInput.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ChipInput.d.ts","sourceRoot":"","sources":["../src/ChipInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6E,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOjH;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAiChF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe;IACzE,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAA;IAC7B,4CAA4C;IAC5C,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,qDAAqD;IACrD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAA;IACtC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAA;CACtC;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,EACrE,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAuB,EACvB,SAAS,EACT,UAAe,EACf,WAAW,EACX,UAAU,GACX,EAAE,cAAc,CAAC,CAAC,CAAC,+BAuJnB"}
1
+ {"version":3,"file":"ChipInput.d.ts","sourceRoot":"","sources":["../src/ChipInput.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6E,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOjH;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,cAAc,+BAiChF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe;IACzE,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI,CAAA;IAC7B,4CAA4C;IAC5C,OAAO,EAAE,CAAC,EAAE,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,qDAAqD;IACrD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAA;IACtC,6CAA6C;IAC7C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,SAAS,CAAA;IACrC,0EAA0E;IAC1E,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;CAC7C;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,EACrE,KAAK,EACL,QAAQ,EACR,OAAO,EACP,WAAuB,EACvB,SAAS,EACT,UAAe,EACf,WAAW,EACX,UAAU,EACV,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,CAAC,CAAC,+BAwJnB"}
@@ -8,6 +8,11 @@ import { type ReactNode } from 'react';
8
8
  * archive); `primary` otherwise. While the action runs the buttons wait;
9
9
  * an action that resolves `false` keeps the dialog open, so the caller's
10
10
  * banner can say why.
11
+ *
12
+ * On Base UI's `AlertDialog` since stage 3 of the migration (2026-09-07),
13
+ * through `DialogShell`'s `alert`. **A press on the backdrop no longer
14
+ * closes it** (Katerina, D20): a destructive question is answered, not
15
+ * clicked away. Escape and the close button still cancel, as they did.
11
16
  */
12
17
  export interface ConfirmDialogProps {
13
18
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../src/ConfirmDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhD;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,QAAQ,EAAE,SAAS,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAA;IACzD,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAmB,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,kBAAkB,+BA8B3H"}
1
+ {"version":3,"file":"ConfirmDialog.d.ts","sourceRoot":"","sources":["../src/ConfirmDialog.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAIhD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,QAAQ,EAAE,SAAS,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAA;IACzD,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAmB,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,kBAAkB,+BA+B3H"}
@@ -3,8 +3,25 @@ import { type ReactNode } from 'react';
3
3
  * Peek's DialogShell (2026-08-28), verbatim: the portal, the backdrop, the
4
4
  * 502px card and its chrome — a 48px header with the title and a close
5
5
  * button, a body, a 48px footer for the buttons. A dialog is just what goes
6
- * in the three slots. Plus what Ship added: Escape closes it, and the card
7
- * says what it is to assistive tech.
6
+ * in the three slots. On Base UI's `Dialog` since stage 3 of the migration
7
+ * (2026-09-07).
8
+ *
9
+ * **What that fixed, and this page used to say it did not:** focus is trapped
10
+ * inside the card, so Tab cannot walk out into the page behind it, and it
11
+ * returns to whatever opened the dialog when it closes. Both were missing and
12
+ * both were written down as missing. The portal, the outside press and the
13
+ * Escape key are Base UI's too — the `keydown` listener this file kept on
14
+ * `document` is gone, and with it the bug where two open dialogs both closed
15
+ * on one Escape.
16
+ *
17
+ * The card is mounted only while it is open, as before: this component has no
18
+ * `open` prop, and a caller renders it or does not. So `open` is `true` and
19
+ * `onOpenChange` reports the ways Base UI closes it — Escape, a press outside,
20
+ * the close button — through the one `onClose` the callers already pass.
21
+ *
22
+ * The DOM is the same shape it was, deliberately: a backdrop, then a
23
+ * full-screen flex layer that centres the card. Base UI positions nothing for
24
+ * a dialog, so keeping the layer is what keeps the pixels.
8
25
  */
9
26
  export interface DialogShellProps {
10
27
  /** Labels the dialog for assistive tech, and renders as the header text
@@ -21,6 +38,13 @@ export interface DialogShellProps {
21
38
  /** Extra classes on the body (e.g. `flex flex-col gap-6`, or a max height with `overflow-y-auto`). */
22
39
  bodyClassName?: string;
23
40
  width?: number;
41
+ /**
42
+ * A question that has to be answered rather than clicked away: a press on
43
+ * the backdrop no longer closes it, and it announces itself as an alert.
44
+ * Escape and the close button still work. `ConfirmDialog` is this
45
+ * (Katerina, D20, 2026-09-07); a form or a roster is not.
46
+ */
47
+ alert?: boolean;
24
48
  }
25
- export declare function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width }: DialogShellProps): import("react").ReactPortal;
49
+ export declare function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width, alert }: DialogShellProps): import("react").JSX.Element;
26
50
  //# sourceMappingURL=DialogShell.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DialogShell.d.ts","sourceRoot":"","sources":["../src/DialogShell.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAMjD;;;;;;GAMG;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;CACf;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAW,EAAE,EAAE,gBAAgB,+BAyC5H"}
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"}
@@ -4,6 +4,12 @@ import { type ReactNode } from 'react';
4
4
  * own comment always called it a package candidate: nothing here knows what
5
5
  * is being edited.
6
6
  *
7
+ * The editing state is Base UI's `Input` — or `Field.Control` as a
8
+ * `<textarea>` when multiline — since stage 3 of the migration (2026-09-07).
9
+ * The read state, the draft, and every rule about committing stay here:
10
+ * Base UI has no opinion about what an edit means, and this component is
11
+ * nothing but that opinion.
12
+ *
7
13
  * Reads as text until clicked; then it is a field. Enter commits (Shift+Enter
8
14
  * is a new line when multiline), Escape cancels, blur commits. A commit that
9
15
  * fails keeps the field open with the text in it, so an edit is never
@@ -1 +1 @@
1
- {"version":3,"file":"EditableText.d.ts","sourceRoot":"","sources":["../src/EditableText.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAA;AAGvG;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,wFAAwF;IACxF,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE,iBAAiB,+BA+G5J"}
1
+ {"version":3,"file":"EditableText.d.ts","sourceRoot":"","sources":["../src/EditableText.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAmD,KAAK,SAAS,EAAkB,MAAM,OAAO,CAAA;AAKvG;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,wFAAwF;IACxF,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAA;IACb;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE,iBAAiB,+BAyH5J"}
package/dist/Field.d.ts CHANGED
@@ -1,40 +1,57 @@
1
1
  import { type ReactNode } from 'react';
2
- /**
3
- * The id a surrounding `Field` wants this control to have, falling back to the
4
- * caller's own outside one.
5
- *
6
- * **Inside a Field, the Field wins**, which is the opposite of what I wrote
7
- * first and the test caught within the minute. Letting a control's own `id`
8
- * take precedence leaves the label's `htmlFor` pointing at the id the Field
9
- * generated and the control answering to a different one — which is this
10
- * ticket's defect exactly, reproduced by the fix for it, and it fails with the
11
- * same message: *"Found a label with the text of: Title, however no form
12
- * control was found associated to that label."*
13
- *
14
- * A caller who needs to choose the id names it on the Field (`htmlFor`), which
15
- * is the one place that can set both halves. Outside a Field there is nothing
16
- * to disagree with, so the caller's id is used.
17
- */
18
- export declare function useFieldControlId(ownId?: string): string | undefined;
19
2
  /**
20
3
  * Peek's Field (2026-08-28): a label over a control, 8px apart, with a red
21
- * asterisk when required. The label is the `input-label` type token as a plain
22
- * class, never merged.
4
+ * asterisk when required. The label is the `input-label` type token, merged
5
+ * with `cn()` like every other class list here. On Base UI's `Field` since
6
+ * stage 3 of the migration (2026-09-07).
23
7
  *
24
- * The label names its control (SHA-17). It did not, and the control was a
8
+ * The label names its control. It did not once, and the control was a
25
9
  * *sibling* of the label with no `htmlFor`, so there was neither an explicit
26
10
  * nor an implicit association: a screen reader announced an unlabelled edit
27
- * box and clicking the label focused nothing.
11
+ * box and clicking the label focused nothing (SHA-17). That fix used to be
12
+ * ours — a context carrying a generated id, which every control had to opt
13
+ * into by calling `useFieldControlId`. **Base UI does it now**, for its own
14
+ * `Input`, `Checkbox`, `Select` and anything rendered through `Field.Control`,
15
+ * so a new control is labelled by construction rather than by remembering.
16
+ *
17
+ * `helper` and `error` are the line under the control, which Ship built by
18
+ * hand in two dialogs (`COMPONENTS-SHIP.md` F14) and Peek in four
19
+ * (`COMPONENTS-PEEK.md` F14), always the same two class lists. **An error
20
+ * replaces the helper rather than joining it** — that is what those callers
21
+ * did (`pairError ?? 'Leave empty and…'`), and a field that says both at once
22
+ * is asking the reader to work out which one is live.
23
+ *
24
+ * The line is announced: Base UI wires `aria-describedby` for the helper and
25
+ * `aria-invalid` + the error's id for the error, which the hand-built spans
26
+ * never did.
27
+ *
28
+ * `required` is announced too, since 2026-09-08. It drew the asterisk and
29
+ * nothing else — measured, the control carried neither `required` nor
30
+ * `aria-required`, so the one thing the mark means never reached anybody who
31
+ * could not see it. Base UI's `Field` has no `required` of its own, so this
32
+ * puts `aria-required` on the control itself.
28
33
  */
29
34
  export interface FieldProps {
30
35
  label: string;
36
+ /**
37
+ * Draws the asterisk **and** marks the control `aria-required`, so the mark
38
+ * means something to a reader who cannot see it. It reaches a single control
39
+ * element; a `children` of several elements keeps the asterisk and owes its
40
+ * own `aria-required`.
41
+ */
31
42
  required?: boolean;
32
43
  /**
33
- * Override the generated id. Only needed when something outside has to name
34
- * the control an `aria-describedby` elsewhere, or a form library.
44
+ * A hint under the control what the format is, what happens if it is left
45
+ * empty. `caption`, muted. Hidden while `error` is set.
46
+ */
47
+ helper?: string;
48
+ /**
49
+ * What is wrong, in the same place as the helper and in the error colour.
50
+ * Setting it also marks the control invalid, so the caller no longer passes
51
+ * `aria-invalid` itself.
35
52
  */
36
- htmlFor?: string;
53
+ error?: string;
37
54
  children: ReactNode;
38
55
  }
39
- export declare function Field({ label, required, htmlFor, children }: FieldProps): import("react").JSX.Element;
56
+ export declare function Field({ label, required, helper, error, children }: FieldProps): import("react").JSX.Element;
40
57
  //# sourceMappingURL=Field.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Field.d.ts","sourceRoot":"","sources":["../src/Field.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAoBxE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,KAAK,CAAC,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,UAAU,+BAe/E"}
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,+BA8CrF"}
@@ -1,4 +1,4 @@
1
- import type { ButtonHTMLAttributes, ReactNode } from 'react';
1
+ import type { ComponentPropsWithRef, ReactNode } from 'react';
2
2
  /**
3
3
  * Peek's IconButton (2026-08-28), verbatim: a square 4px-padded button
4
4
  * around a 16px icon, 8px radius, three variants, an optional tooltip that
@@ -10,7 +10,8 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
10
10
  * the reason in place of the tooltip — see Button.
11
11
  */
12
12
  export type IconButtonVariant = 'muted' | 'outlined' | 'primary';
13
- export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
13
+ /** `ComponentPropsWithRef` so a `ref` reaches the element — see Button. */
14
+ export interface IconButtonProps extends ComponentPropsWithRef<'button'> {
14
15
  variant?: IconButtonVariant;
15
16
  tooltip?: string;
16
17
  /** A key hint drawn as the `Kbd` chip inside the tooltip — for a button
@@ -1 +1 @@
1
- {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK5D;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhE,MAAM,WAAW,eAAgB,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC9E,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;8DAC0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAiB,EACjB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,IAAe,EACf,GAAG,KAAK,EACT,EAAE,eAAe,+BAkCjB"}
1
+ {"version":3,"file":"IconButton.d.ts","sourceRoot":"","sources":["../src/IconButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAK7D;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,CAAA;AAEhE,2EAA2E;AAC3E,MAAM,WAAW,eAAgB,SAAQ,qBAAqB,CAAC,QAAQ,CAAC;IACtE,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;8DAC0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAA;IACnC;sEACkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,QAAQ,EAAE,SAAS,CAAA;CACpB;AAED,wBAAgB,UAAU,CAAC,EACzB,OAAiB,EACjB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,cAAc,EACd,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,IAAe,EACf,GAAG,KAAK,EACT,EAAE,eAAe,+BAuCjB"}
@@ -45,19 +45,31 @@ export interface IdentityMenuProps {
45
45
  */
46
46
  children?: ReactNode | ((close: () => void) => ReactNode);
47
47
  }
48
- export interface IdentityPanelProps extends Omit<IdentityMenuProps, 'compact' | 'className'> {
49
- onClose: () => void;
50
- /** The trigger to hang from the panel portals to the body and fits the
51
- * viewport, so no header, sidebar or scroll container can cover it (the
52
- * z-10 floating top bar trapped the old in-flow panel under a z-20 panel
53
- * header, 2026-09-03). Absent, the panel stands in flow the stories. */
54
- anchor?: HTMLElement | null;
55
- /** On the Menu surface — the stories pass `static` to stand it in flow. */
56
- className?: string;
48
+ /**
49
+ * The menu alone, as a plain surface — what the docs canvases draw, and what
50
+ * a surface that wants the rows without the menu can use.
51
+ */
52
+ export interface IdentityPanelProps extends Omit<IdentityMenuProps, 'compact'> {
53
+ /** Called when a row asks the menu to close. */
54
+ onClose?: () => void;
57
55
  }
58
- /** The menu alone what `IdentityMenu` opens. Exported so the stories show
59
- * the designed artifact rather than a closed trigger, and for any surface
60
- * that wants the panel without the trigger. */
61
- export declare function IdentityPanel({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, anchor, className, children }: IdentityPanelProps): import("react").JSX.Element;
56
+ export declare function IdentityPanel({ className, onClose, ...rest }: IdentityPanelProps): import("react").JSX.Element;
57
+ /** The old name for the same thing. */
58
+ export declare const IdentityPanelSurface: typeof IdentityPanel;
59
+ /**
60
+ * The panel's contents, without the menu around them.
61
+ *
62
+ * Split out at stage 4 for the same reason `MenuPanel` was split out of
63
+ * `Menu`: a real menu portals and places itself against a trigger, so it
64
+ * cannot stand in a docs page, and the canvases must still show the artifact
65
+ * (Katerina, D25). The stories draw these rows on a `MenuPanel`; the app gets
66
+ * them inside a `Menu`. One definition either way.
67
+ *
68
+ * Not exported from the package — `IdentityMenu` and `IdentityPanel` are the
69
+ * API; this is how they are built.
70
+ */
71
+ export declare function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }: Omit<IdentityPanelProps, 'className'> & {
72
+ onClose: () => void;
73
+ }): import("react").JSX.Element;
62
74
  export declare function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact, className, children }: IdentityMenuProps): import("react").JSX.Element;
63
75
  //# sourceMappingURL=IdentityMenu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityMenu.d.ts","sourceRoot":"","sources":["../src/IdentityMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAOxD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,QAAQ,CAAA;IACZ,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAA;IACjB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,WAAW,CAAC;IAC1F,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB;;;+EAG2E;IAC3E,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI,CAAA;IAC3B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;gDAEgD;AAChD,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,kBAAkB,+BAmD/I;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BA0C7I"}
1
+ {"version":3,"file":"IdentityMenu.d.ts","sourceRoot":"","sources":["../src/IdentityMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAO3D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,QAAQ;IACvB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,QAAQ,CAAA;IACZ,qEAAqE;IACrE,QAAQ,EAAE,OAAO,CAAA;IACjB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAC,CAAA;CAC1D;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC;IAC5E,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,OAAkB,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,+BAM3F;AAED,uCAAuC;AACvC,eAAO,MAAM,oBAAoB,sBAAgB,CAAA;AAEjD;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,GAAG;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,+BAmDxK;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,OAAe,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BAmD7I"}