@ngrok/mantle 0.84.0 → 0.84.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 (219) hide show
  1. package/dist/accordion.d.ts +14 -10
  2. package/dist/accordion.js +1 -1
  3. package/dist/agent.json +1 -1
  4. package/dist/{alert-Blmunr_D.d.ts → alert-DCVfviBx.d.ts} +18 -3
  5. package/dist/alert-DtBQuuuP.js +1 -0
  6. package/dist/alert-center.d.ts +15 -6
  7. package/dist/alert-center.js +1 -1
  8. package/dist/alert-dialog.d.ts +58 -37
  9. package/dist/alert-dialog.js +1 -1
  10. package/dist/alert.d.ts +1 -1
  11. package/dist/alert.js +1 -1
  12. package/dist/alternate-announcement-BkH4bOKp.js +1 -0
  13. package/dist/anchor-Cqu4GPPV.js +1 -0
  14. package/dist/anchor.d.ts +15 -15
  15. package/dist/anchor.js +1 -1
  16. package/dist/app-layout.js +1 -1
  17. package/dist/area-chart.js +1 -1
  18. package/dist/avatar.js +1 -1
  19. package/dist/badge.d.ts +3 -1
  20. package/dist/badge.js +1 -1
  21. package/dist/bar-chart.d.ts +17 -8
  22. package/dist/bar-chart.js +1 -1
  23. package/dist/breadcrumb.js +1 -1
  24. package/dist/button-B52_vczK.js +1 -0
  25. package/dist/{button-DjsmeoJ2.d.ts → button-B5i9n7Qp.d.ts} +19 -7
  26. package/dist/button-CaM-ZAH5.js +1 -0
  27. package/dist/{button-Bc0lEOJ2.js → button-DGsTE3P2.js} +1 -1
  28. package/dist/{button-CRCNRnk6.d.ts → button-DO53OA70.d.ts} +2 -2
  29. package/dist/{button-DmJkYfyl.js → button-Wn-yt0c_.js} +1 -1
  30. package/dist/{button-C39M5h4K.d.ts → button-crUf0hbR.d.ts} +19 -2
  31. package/dist/button.d.ts +3 -3
  32. package/dist/button.js +1 -1
  33. package/dist/calendar.d.ts +20 -4
  34. package/dist/calendar.js +1 -1
  35. package/dist/card.d.ts +10 -6
  36. package/dist/card.js +1 -1
  37. package/dist/centered-layout.js +1 -1
  38. package/dist/chart-B_rZqf8a.js +2 -0
  39. package/dist/checkbox-Gg6nGUnR.js +1 -0
  40. package/dist/checkbox.js +1 -1
  41. package/dist/choice-CT_AdesL.js +1 -0
  42. package/dist/{choice-CVdQrs-m.d.ts → choice-PESu-9s8.d.ts} +46 -12
  43. package/dist/choice.d.ts +1 -1
  44. package/dist/choice.js +1 -1
  45. package/dist/{code-block-Dj9otiLi.js → code-block-BE3Q0iAo.js} +2 -2
  46. package/dist/code-block.d.ts +26 -2
  47. package/dist/code-block.js +6 -6
  48. package/dist/code-block_highlight-utils.js +1 -1
  49. package/dist/code.js +1 -1
  50. package/dist/combobox.d.ts +19 -2
  51. package/dist/combobox.js +1 -1
  52. package/dist/command.d.ts +32 -13
  53. package/dist/command.js +1 -1
  54. package/dist/compose-refs-DdUwopIY.js +1 -0
  55. package/dist/{cx-IiQEAKf5.js → cx-0HCjnNv1.js} +1 -1
  56. package/dist/cx.d.ts +3 -3
  57. package/dist/cx.js +1 -1
  58. package/dist/data-table.d.ts +114 -61
  59. package/dist/data-table.js +1 -1
  60. package/dist/description-list.d.ts +43 -9
  61. package/dist/description-list.js +1 -1
  62. package/dist/{dialog-u8PtHYES.d.ts → dialog-B8YvfyIo.d.ts} +5 -3
  63. package/dist/{dialog-CnlaqHNh.js → dialog-CA-1Z0Np.js} +1 -1
  64. package/dist/{dialog-CEk0L7M7.d.ts → dialog-CtLI_uex.d.ts} +5 -3
  65. package/dist/dialog.d.ts +2 -2
  66. package/dist/dialog.js +1 -1
  67. package/dist/{dropdown-menu-CpsUJGbn.d.ts → dropdown-menu-BYapTV0f.d.ts} +8 -5
  68. package/dist/dropdown-menu-BkPBh_8y.d.ts +1 -0
  69. package/dist/{dropdown-menu-DJDrRzDU.js → dropdown-menu-lxHsgLiw.js} +1 -1
  70. package/dist/dropdown-menu.d.ts +2 -2
  71. package/dist/dropdown-menu.js +1 -1
  72. package/dist/empty.d.ts +4 -4
  73. package/dist/empty.js +1 -1
  74. package/dist/field.d.ts +91 -38
  75. package/dist/field.js +1 -1
  76. package/dist/flag.d.ts +9 -1
  77. package/dist/flag.js +1 -1
  78. package/dist/hooks.d.ts +28 -19
  79. package/dist/hooks.js +1 -1
  80. package/dist/hover-card.d.ts +11 -3
  81. package/dist/hover-card.js +1 -1
  82. package/dist/{icon-k4E9yNWD.d.ts → icon-BmJ57Tgh.d.ts} +10 -0
  83. package/dist/icon-CGKaq_tV.js +1 -0
  84. package/dist/icon-U24NfYv7.js +1 -0
  85. package/dist/icon-w0HUe7tr.d.ts +42 -0
  86. package/dist/icon.d.ts +2 -2
  87. package/dist/icon.js +1 -1
  88. package/dist/{icons-DEVx1oP9.js → icons-Cie4gcrm.js} +1 -1
  89. package/dist/icons.d.ts +7 -13
  90. package/dist/icons.js +1 -1
  91. package/dist/{in-view-gxyc9Q1_.d.ts → in-view-Ch5vJtWo.d.ts} +10 -5
  92. package/dist/input-BhykQSvJ.js +1 -0
  93. package/dist/input-DQyN6gN0.js +1 -0
  94. package/dist/input.d.ts +22 -10
  95. package/dist/input.js +1 -1
  96. package/dist/interactive-target-BXScNeOr.js +1 -0
  97. package/dist/{kbd-B9qmYaW8.js → kbd-4_0Y_8rx.js} +1 -1
  98. package/dist/kbd.d.ts +15 -9
  99. package/dist/kbd.js +1 -1
  100. package/dist/{label-C6YH9skg.d.ts → label-Bnfe9YJ6.d.ts} +3 -1
  101. package/dist/label-BqIp6kFx.js +1 -0
  102. package/dist/label.d.ts +1 -1
  103. package/dist/label.js +1 -1
  104. package/dist/layer-container-BTcQpd4K.js +1 -0
  105. package/dist/layer-container.js +1 -1
  106. package/dist/line-chart.js +1 -1
  107. package/dist/list-Bo1mExIg.js +1 -0
  108. package/dist/list.d.ts +37 -14
  109. package/dist/list.js +1 -1
  110. package/dist/live-region-CV7kykeo.js +1 -0
  111. package/dist/live-region.js +1 -1
  112. package/dist/llms.txt +1 -1
  113. package/dist/main.d.ts +4 -2
  114. package/dist/main.js +1 -1
  115. package/dist/media-object.d.ts +5 -12
  116. package/dist/media-object.js +1 -1
  117. package/dist/multi-select.d.ts +45 -13
  118. package/dist/multi-select.js +1 -1
  119. package/dist/otp-input.d.ts +9 -3
  120. package/dist/otp-input.js +1 -1
  121. package/dist/pagination.d.ts +165 -19
  122. package/dist/pagination.js +1 -1
  123. package/dist/{popover-D6x6Bq-G.js → popover-Bp-9B3GR.js} +1 -1
  124. package/dist/{popover-DDuw1UaJ.d.ts → popover-s2LhmzfQ.d.ts} +8 -4
  125. package/dist/popover.d.ts +1 -1
  126. package/dist/popover.js +1 -1
  127. package/dist/primitive-CejGAoGb.js +1 -0
  128. package/dist/progress.d.ts +65 -31
  129. package/dist/progress.js +1 -1
  130. package/dist/qr-code.d.ts +10 -4
  131. package/dist/qr-code.js +1 -1
  132. package/dist/radio-group-HDVxTNPi.js +1 -0
  133. package/dist/radio-group.d.ts +50 -25
  134. package/dist/radio-group.js +1 -1
  135. package/dist/sandbar.d.ts +1 -1
  136. package/dist/sandbar.js +1 -1
  137. package/dist/sandboxed-on-click-UagMFl_U.js +1 -0
  138. package/dist/sandboxed-on-click.d.ts +8 -0
  139. package/dist/sandboxed-on-click.js +1 -1
  140. package/dist/scatter-plot.js +1 -1
  141. package/dist/select-Dov9H2CX.js +1 -0
  142. package/dist/{select-DkFkSYBP.d.ts → select-ouAW88jx.d.ts} +30 -9
  143. package/dist/select.d.ts +1 -1
  144. package/dist/select.js +1 -1
  145. package/dist/selectable-list.d.ts +64 -20
  146. package/dist/selectable-list.js +1 -1
  147. package/dist/{separator-CNDs98Dv.d.ts → separator-Bo4nY_3M.d.ts} +13 -2
  148. package/dist/{separator-D0D6VyyM.js → separator-Da8lDnio.js} +1 -1
  149. package/dist/separator.d.ts +1 -1
  150. package/dist/separator.js +1 -1
  151. package/dist/{sheet-BcfnKUit.js → sheet-C6UGAvRk.js} +1 -1
  152. package/dist/sheet.d.ts +5 -5
  153. package/dist/sheet.js +1 -1
  154. package/dist/sidebar.d.ts +7 -6
  155. package/dist/sidebar.js +1 -1
  156. package/dist/skeleton-paJOgf-f.js +1 -0
  157. package/dist/skeleton.d.ts +5 -4
  158. package/dist/skeleton.js +1 -1
  159. package/dist/skip-to-main-link.d.ts +9 -6
  160. package/dist/skip-to-main-link.js +1 -1
  161. package/dist/slider.d.ts +7 -3
  162. package/dist/slider.js +1 -1
  163. package/dist/{slot-DpNWVci8.js → slot-C3gII_9c.js} +1 -1
  164. package/dist/slot.js +1 -1
  165. package/dist/split-button.d.ts +8 -3
  166. package/dist/split-button.js +1 -1
  167. package/dist/switch.js +1 -1
  168. package/dist/{table-D51ZtV4U.d.ts → table-DEI-qvSC.d.ts} +25 -12
  169. package/dist/table-EZNW3nFk.js +1 -0
  170. package/dist/table.d.ts +1 -1
  171. package/dist/table.js +1 -1
  172. package/dist/tabs.js +1 -1
  173. package/dist/text-area.js +1 -1
  174. package/dist/theme-DN-Et3A_.js +1 -0
  175. package/dist/theme-switcher.d.ts +24 -12
  176. package/dist/theme-switcher.js +1 -1
  177. package/dist/theme.d.ts +18 -4
  178. package/dist/theme.js +1 -1
  179. package/dist/toast.d.ts +8 -3
  180. package/dist/toast.js +1 -1
  181. package/dist/tooltip-CkAibjBb.js +1 -0
  182. package/dist/{tooltip-BKWK5c7_.d.ts → tooltip-DA41fxe5.d.ts} +7 -1
  183. package/dist/tooltip.d.ts +1 -1
  184. package/dist/tooltip.js +1 -1
  185. package/dist/{use-breakpoint-Dqu12Szq.js → use-breakpoint-BhJ_3El2.js} +1 -1
  186. package/dist/use-is-apple-platform-CMPzIYjz.js +1 -0
  187. package/dist/use-matches-media-query-DCBT6iNA.js +1 -0
  188. package/dist/use-prefers-reduced-motion-DHYDQk1h.js +1 -0
  189. package/dist/utils.d.ts +1 -1
  190. package/dist/utils.js +1 -1
  191. package/dist/visually-hidden.js +1 -1
  192. package/dist/well.js +1 -1
  193. package/package.json +3 -3
  194. package/dist/alert-DDjzRuGa.js +0 -1
  195. package/dist/anchor-D2So_zuy.js +0 -1
  196. package/dist/button-CC10rP6X.js +0 -1
  197. package/dist/button-DiDlvAOp.js +0 -1
  198. package/dist/chart-BDxpXPfo.js +0 -2
  199. package/dist/checkbox-0EoxOyMA.js +0 -1
  200. package/dist/choice-CnwfjSEu.js +0 -1
  201. package/dist/compose-refs-BdBMM9ga.js +0 -1
  202. package/dist/dropdown-menu-CNaaABck.d.ts +0 -1
  203. package/dist/icon-CX_gj6sW.d.ts +0 -25
  204. package/dist/icon-d-nMCfAI.js +0 -1
  205. package/dist/icon-lZ48P8Nn.js +0 -1
  206. package/dist/input-BnlpQF0c.js +0 -1
  207. package/dist/input-CXmS0OFN.js +0 -1
  208. package/dist/label-D-D11mlp.js +0 -1
  209. package/dist/layer-container-CglTh9-6.js +0 -1
  210. package/dist/list-CwL23L_B.js +0 -1
  211. package/dist/primitive-BWyxJnXn.js +0 -1
  212. package/dist/select-BK6n6OIK.js +0 -1
  213. package/dist/skeleton-BhcJMpem.js +0 -1
  214. package/dist/table-C_Nm_RSV.js +0 -1
  215. package/dist/theme-CVfq037P.js +0 -1
  216. package/dist/tooltip-BZRRJgpm.js +0 -1
  217. package/dist/use-is-apple-platform-Cxwrb86L.js +0 -1
  218. package/dist/use-matches-media-query-Bd_GhhVd.js +0 -1
  219. package/dist/use-prefers-reduced-motion-Bk5zAfHY.js +0 -1
@@ -1,21 +1,50 @@
1
- import { t as ButtonGroup } from "./button-CRCNRnk6.js";
2
- import { t as Select } from "./select-DkFkSYBP.js";
1
+ import { t as ButtonGroup } from "./button-DO53OA70.js";
2
+ import { t as Select } from "./select-ouAW88jx.js";
3
3
  import { ComponentProps } from "react";
4
4
  //#region src/components/pagination/cursor-pagination.d.ts
5
- type CursorPaginationProps = ComponentProps<"div"> & {
5
+ /**
6
+ * The page size owner: either the root, seeded by `defaultPageSize`, or the
7
+ * consumer, through `pageSize`. A union, so a call site passes exactly one.
8
+ */
9
+ type CursorPaginationPageSizeProps = {
6
10
  /**
7
- * The default number of items per page.
11
+ * The initial number of items per page. The root owns the value after
12
+ * mount, and `PageSizeSelect` changes it. Read the changes back through
13
+ * `onChangePageSize`.
8
14
  */
9
15
  defaultPageSize: number;
16
+ pageSize?: never;
17
+ } | {
18
+ defaultPageSize?: never;
19
+ /**
20
+ * The controlled number of items per page. Pair it with
21
+ * `onChangePageSize`: `PageSizeSelect` calls that with the next value, and
22
+ * the select shows this prop until you change it. An external change, such
23
+ * as a browser history move that rewrites a URL param, updates the select.
24
+ */
25
+ pageSize: number;
26
+ };
27
+ type CursorPaginationProps = ComponentProps<"div"> & CursorPaginationPageSizeProps & {
28
+ /**
29
+ * Called with the next number of items per page when `PageSizeSelect`
30
+ * changes it. Required to change a controlled `pageSize`.
31
+ */
32
+ onChangePageSize?: (pageSize: number) => void;
10
33
  };
11
34
  /**
12
- * A pagination component for use with cursor-based pagination.
35
+ * The root container for cursor-based pagination. It owns the page size that
36
+ * `PageSizeSelect` and `PageSizeValue` read.
13
37
  *
14
- * Cursor-based pagination is a way of loading data in chunks by using a cursor
15
- * from the last item on the current page to know where to start the next set,
16
- * making sure nothing is missed or repeated. Like a linked list, but for chunks
17
- * of data. It doesn't let you jump to a specific page or know how many total pages
18
- * there are, but it's more efficient for large or real-time data sets.
38
+ * Pass `defaultPageSize` to let the root own the page size, or pass `pageSize`
39
+ * with `onChangePageSize` to own it yourself. The select shows the owner's
40
+ * value in both modes, so an external change to a controlled `pageSize` updates
41
+ * the select.
42
+ *
43
+ * Cursor-based pagination loads data in chunks. A cursor from the last item on
44
+ * the current page marks where the next chunk starts, so no item is missed or
45
+ * repeated. It cannot jump to a page or count the pages, but it stays efficient
46
+ * for large or real-time data sets. For a page count and jumps, use
47
+ * `useOffsetPagination`.
19
48
  *
20
49
  * @see https://mantle.ngrok.com/components/navigation/pagination#cursorpaginationroot
21
50
  *
@@ -31,8 +60,37 @@ type CursorPaginationProps = ComponentProps<"div"> & {
31
60
  * <CursorPagination.PageSizeSelect />
32
61
  * </CursorPagination.Root>
33
62
  * ```
63
+ *
64
+ * @example
65
+ * Controlled page size, kept in the URL:
66
+ * ```tsx
67
+ * const pageSizes = [10, 20, 50, 100];
68
+ * const [searchParams, setSearchParams] = useSearchParams();
69
+ * const requestedPageSize = Number(searchParams.get("pageSize"));
70
+ * // A hand-edited URL can carry a size the select does not list, and
71
+ * // `PageSizeSelect` throws for one. Fall back to the default.
72
+ * const pageSize = pageSizes.includes(requestedPageSize) ? requestedPageSize : 10;
73
+ *
74
+ * <CursorPagination.Root
75
+ * pageSize={pageSize}
76
+ * onChangePageSize={(size) =>
77
+ * setSearchParams((params) => {
78
+ * params.set("pageSize", String(size));
79
+ * return params;
80
+ * })
81
+ * }
82
+ * >
83
+ * <CursorPagination.Buttons
84
+ * hasNextPage={hasNext}
85
+ * hasPreviousPage={hasPrevious}
86
+ * onNextPage={handleNext}
87
+ * onPreviousPage={handlePrevious}
88
+ * />
89
+ * <CursorPagination.PageSizeSelect pageSizes={pageSizes} />
90
+ * </CursorPagination.Root>
91
+ * ```
34
92
  */
35
- declare const Root: ({ className, children, defaultPageSize, ref, ...props }: CursorPaginationProps) => import("react").JSX.Element;
93
+ declare const Root: ({ className, children, defaultPageSize, onChangePageSize, pageSize: pageSizeProp, ref, ...props }: CursorPaginationProps) => import("react").JSX.Element;
36
94
  type CursorButtonsProps = Omit<ComponentProps<typeof ButtonGroup>, "appearance"> & {
37
95
  /**
38
96
  * Whether there is a next page of data to load.
@@ -70,13 +128,16 @@ declare const Buttons: ({ hasNextPage, hasPreviousPage, onNextPage, onPreviousPa
70
128
  declare const defaultPageSizes: readonly [5, 10, 20, 50, 100];
71
129
  type CursorPageSizeSelectProps = Omit<ComponentProps<typeof Select.Trigger>, "children"> & {
72
130
  /**
73
- * A list of page sizes to choose from. The default page size must be included in this list.
131
+ * The page sizes to choose from. The current page size must be in this list.
132
+ *
133
+ * @default [5, 10, 20, 50, 100]
74
134
  */
75
135
  pageSizes?: typeof defaultPageSizes | readonly number[];
76
136
  /**
77
- * A callback that is called when the page size is changed.
137
+ * Called with the next number of items per page when the user picks one.
138
+ * `Root`'s `onChangePageSize` runs first with the same value.
78
139
  */
79
- onChangePageSize?: (value: number) => void;
140
+ onChangePageSize?: (pageSize: number) => void;
80
141
  };
81
142
  /**
82
143
  * A select input for changing the number of items per page when using cursor-based pagination.
@@ -142,7 +203,13 @@ declare function PageSizeValue({ className, ...props }: CursorPageSizeValueProps
142
203
  */
143
204
  declare const CursorPagination: {
144
205
  /**
145
- * The root container of the cursor pagination component.
206
+ * The root container for cursor-based pagination. It owns the page size that
207
+ * `PageSizeSelect` and `PageSizeValue` read.
208
+ *
209
+ * Pass `defaultPageSize` to let the root own the page size, or pass `pageSize`
210
+ * with `onChangePageSize` to own it yourself. The select shows the owner's
211
+ * value in both modes, so an external change to a controlled `pageSize` updates
212
+ * the select.
146
213
  *
147
214
  * @see https://mantle.ngrok.com/components/navigation/pagination#cursorpaginationroot
148
215
  *
@@ -158,6 +225,35 @@ declare const CursorPagination: {
158
225
  * <CursorPagination.PageSizeSelect />
159
226
  * </CursorPagination.Root>
160
227
  * ```
228
+ *
229
+ * @example
230
+ * Controlled page size, kept in the URL:
231
+ * ```tsx
232
+ * const pageSizes = [10, 20, 50, 100];
233
+ * const [searchParams, setSearchParams] = useSearchParams();
234
+ * const requestedPageSize = Number(searchParams.get("pageSize"));
235
+ * // A hand-edited URL can carry a size the select does not list, and
236
+ * // `PageSizeSelect` throws for one. Fall back to the default.
237
+ * const pageSize = pageSizes.includes(requestedPageSize) ? requestedPageSize : 10;
238
+ *
239
+ * <CursorPagination.Root
240
+ * pageSize={pageSize}
241
+ * onChangePageSize={(size) =>
242
+ * setSearchParams((params) => {
243
+ * params.set("pageSize", String(size));
244
+ * return params;
245
+ * })
246
+ * }
247
+ * >
248
+ * <CursorPagination.Buttons
249
+ * hasNextPage={hasNext}
250
+ * hasPreviousPage={hasPrevious}
251
+ * onNextPage={handleNext}
252
+ * onPreviousPage={handlePrevious}
253
+ * />
254
+ * <CursorPagination.PageSizeSelect pageSizes={pageSizes} />
255
+ * </CursorPagination.Root>
256
+ * ```
161
257
  */
162
258
  readonly Root: typeof Root;
163
259
  /**
@@ -209,13 +305,44 @@ declare const CursorPagination: {
209
305
  //#region src/components/pagination/use-offset-pagination.d.ts
210
306
  type UseOffsetPaginationProps = {
211
307
  /**
212
- * The total number of items in the list to be paginated.
308
+ * The total number of items in the list to paginate. A change resets the
309
+ * page to 1 unless `resetPageOnListSizeChange` is `false`.
213
310
  */
214
311
  listSize: number;
215
312
  /**
216
- * The number of items per page.
313
+ * The number of items per page. A change resets the page to 1.
217
314
  */
218
315
  pageSize: number;
316
+ /**
317
+ * The 1-indexed page to start on when uncontrolled. The hook owns the page
318
+ * after mount.
319
+ *
320
+ * @default 1
321
+ */
322
+ defaultPage?: number;
323
+ /**
324
+ * The controlled 1-indexed page. Pair it with `onPageChange`: the hook calls
325
+ * that with the next page and reads the page back from this prop. The hook
326
+ * normalizes the value in `currentPage` without a callback: a page past the
327
+ * end clamps to the last page, a fraction rounds down, and `NaN` reads as 1.
328
+ */
329
+ page?: number;
330
+ /**
331
+ * Called with the next 1-indexed page when the hook changes it: a navigation
332
+ * call, `setPageSize`, a `pageSize` change, or a `listSize` reset. Not called
333
+ * when the next page equals the stored page (`page` or the internal page).
334
+ * A move that lands on a normalized `currentPage` still calls it, so a stale
335
+ * `page` catches up.
336
+ */
337
+ onPageChange?: (page: number) => void;
338
+ /**
339
+ * Whether a `listSize` change resets the page to 1. Set `false` to stay on
340
+ * the current page: `currentPage` clamps to the new `totalPages`, so a
341
+ * refetch that shrinks the list lands on its last page instead of page 1.
342
+ *
343
+ * @default true
344
+ */
345
+ resetPageOnListSizeChange?: boolean;
219
346
  };
220
347
  type OffsetPaginationState = {
221
348
  /**
@@ -268,7 +395,9 @@ type OffsetPaginationState = {
268
395
  totalPages: number;
269
396
  };
270
397
  /**
271
- * A headless hook for managing offset-based pagination state
398
+ * A headless hook for offset-based pagination state. It owns the page by
399
+ * default; pass `page` with `onPageChange` to own it yourself, for example in
400
+ * the URL.
272
401
  *
273
402
  * @example
274
403
  * ```tsx
@@ -289,8 +418,25 @@ type OffsetPaginationState = {
289
418
  * </div>
290
419
  * );
291
420
  * ```
421
+ *
422
+ * @example
423
+ * Controlled page, kept in the URL, that survives a refetch:
424
+ * ```tsx
425
+ * const [searchParams, setSearchParams] = useSearchParams();
426
+ * const pagination = useOffsetPagination({
427
+ * listSize: items.length,
428
+ * pageSize: 10,
429
+ * page: Number(searchParams.get("page") ?? 1),
430
+ * onPageChange: (page) =>
431
+ * setSearchParams((params) => {
432
+ * params.set("page", String(page));
433
+ * return params;
434
+ * }),
435
+ * resetPageOnListSizeChange: false,
436
+ * });
437
+ * ```
292
438
  */
293
- declare function useOffsetPagination({ listSize, pageSize }: UseOffsetPaginationProps): OffsetPaginationState;
439
+ declare function useOffsetPagination({ defaultPage, listSize, onPageChange, page: pageProp, pageSize, resetPageOnListSizeChange }: UseOffsetPaginationProps): OffsetPaginationState;
294
440
  /**
295
441
  * Get a paginated slice of a list based on the current offset pagination state.
296
442
  *
@@ -1 +1 @@
1
- import{t as e}from"./cx-IiQEAKf5.js";import{t}from"./button-CC10rP6X.js";import{t as n}from"./button-DmJkYfyl.js";import{n as r}from"./separator-D0D6VyyM.js";import{t as i}from"./select-BK6n6OIK.js";import{createContext as a,useContext as o,useEffect as s,useMemo as c,useState as l}from"react";import u from"tiny-invariant";import{jsx as d,jsxs as f}from"react/jsx-runtime";import{CaretRightIcon as p}from"@phosphor-icons/react/CaretRight";import{CaretLeftIcon as m}from"@phosphor-icons/react/CaretLeft";const h=a(void 0),g=({className:t,children:n,defaultPageSize:r,ref:i,...a})=>{let[o,s]=l(r),u=c(()=>({defaultPageSize:r,pageSize:o,setPageSize:s}),[r,o]);return d(h.Provider,{value:u,children:d(`div`,{"data-slot":`cursor-pagination`,className:e(`inline-flex items-center justify-between gap-2`,t),ref:i,...a,children:n})})},_=({hasNextPage:e,hasPreviousPage:i,onNextPage:a,onPreviousPage:o,ref:s,...c})=>f(n,{"data-slot":`cursor-pagination-buttons`,appearance:`panel`,ref:s,...c,children:[d(t,{"data-slot":`cursor-pagination-previous`,appearance:`ghost`,disabled:!i,icon:d(m,{}),intent:`neutral`,label:`Previous page`,onClick:o,size:`sm`,type:`button`}),d(r,{"data-slot":`cursor-pagination-separator`,orientation:`vertical`,className:`min-h-5`}),d(t,{"data-slot":`cursor-pagination-next`,appearance:`ghost`,disabled:!e,icon:d(p,{}),intent:`neutral`,label:`Next page`,onClick:a,size:`sm`,type:`button`})]}),v=[5,10,20,50,100],y=({className:t,pageSizes:n=v,onChangePageSize:r,ref:a,...s})=>{let c=o(h);return u(c,`CursorPageSizeSelect must be used as a child of a CursorPagination component`),u(n.includes(c.defaultPageSize),`CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes`),u(n.includes(c.pageSize),`CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes`),f(i.Root,{defaultValue:`${c.pageSize}`,onValueChange:e=>{let t=Number.parseInt(e,10);Number.isNaN(t)&&(t=c.defaultPageSize),c.setPageSize(t),r?.(t)},children:[d(i.Trigger,{ref:a,"data-slot":`cursor-pagination-page-size-select`,className:e(`w-auto min-w-36`,t),value:c.pageSize,...s,children:d(i.Value,{})}),d(i.Content,{width:`trigger`,children:n.map(e=>f(i.Item,{value:`${e}`,children:[e,` per page`]},e))})]})};function b({className:t,...n}){let r=o(h);return u(r,`CursorPageSizeValue must be used as a child of a CursorPagination component`),f(`span`,{"data-slot":`cursor-pagination-page-size-value`,className:e(`text-muted text-sm font-normal`,t),...n,children:[r.pageSize,` per page`]})}const x={Root:g,Buttons:_,PageSizeSelect:y,PageSizeValue:b};function S({listSize:e,pageSize:t}){let[n,r]=l(1),[i,a]=l(t);s(()=>{a(t),r(1)},[t]),s(()=>{r(1)},[e]);let o=Math.ceil(e/i),c=(n-1)*i,u=n>1,d=n<o;function f(e){r(Math.max(1,Math.min(e,o)))}function p(){d&&r(e=>Math.min(e+1,o))}function m(){u&&r(e=>Math.max(e-1,1))}function h(e){a(e),r(1)}function g(){r(o)}function _(){r(1)}return{currentPage:n,goToFirstPage:_,goToLastPage:g,goToPage:f,hasNextPage:d,hasPreviousPage:u,nextPage:p,offset:c,pageSize:i,previousPage:m,setPageSize:h,totalPages:o}}function C(e,t){return e.slice(t.offset,t.offset+t.pageSize)}export{x as CursorPagination,C as getOffsetPaginatedSlice,S as useOffsetPagination};
1
+ import{t as e}from"./cx-0HCjnNv1.js";import{t}from"./button-CaM-ZAH5.js";import{t as n}from"./button-Wn-yt0c_.js";import{n as r}from"./separator-Da8lDnio.js";import{t as i}from"./select-Dov9H2CX.js";import{createContext as a,useCallback as o,useContext as s,useEffect as c,useMemo as l,useRef as u,useState as d}from"react";import f from"tiny-invariant";import{jsx as p,jsxs as m}from"react/jsx-runtime";import{CaretRightIcon as h}from"@phosphor-icons/react/CaretRight";import{CaretLeftIcon as g}from"@phosphor-icons/react/CaretLeft";const _=a(void 0),v=({className:t,children:n,defaultPageSize:r,onChangePageSize:i,pageSize:a,ref:o,...s})=>{let c=a!=null,[u,m]=d(r),h=c?a:u;f(h!=null,"CursorPagination.Root requires either `defaultPageSize` or `pageSize`");let g=l(()=>({pageSize:h,setPageSize:e=>{c||m(e),i?.(e)}}),[c,i,h]);return p(_.Provider,{value:g,children:p(`div`,{"data-slot":`cursor-pagination`,className:e(`inline-flex items-center justify-between gap-2`,t),ref:o,...s,children:n})})},y=({hasNextPage:e,hasPreviousPage:i,onNextPage:a,onPreviousPage:o,ref:s,...c})=>m(n,{"data-slot":`cursor-pagination-buttons`,appearance:`panel`,ref:s,...c,children:[p(t,{"data-slot":`cursor-pagination-previous`,appearance:`ghost`,disabled:!i,icon:p(g,{}),intent:`neutral`,label:`Previous page`,onClick:o,size:`sm`,type:`button`}),p(r,{"data-slot":`cursor-pagination-separator`,orientation:`vertical`,className:`min-h-5`}),p(t,{"data-slot":`cursor-pagination-next`,appearance:`ghost`,disabled:!e,icon:p(h,{}),intent:`neutral`,label:`Next page`,onClick:a,size:`sm`,type:`button`})]}),b=[5,10,20,50,100],x=({className:t,pageSizes:n=b,onChangePageSize:r,ref:a,...o})=>{let c=s(_);return f(c,`CursorPageSizeSelect must be used as a child of a CursorPagination component`),f(n.includes(c.pageSize),`CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes`),m(i.Root,{value:`${c.pageSize}`,onValueChange:e=>{let t=Number.parseInt(e,10);f(!Number.isNaN(t),`CursorPageSizeSelect.pageSizes must contain only numbers`),c.setPageSize(t),r?.(t)},children:[p(i.Trigger,{ref:a,"aria-label":`Items per page`,"data-slot":`cursor-pagination-page-size-select`,className:e(`w-auto min-w-36`,t),...o,children:m(i.Value,{children:[c.pageSize,` per page`]})}),p(i.Content,{width:`trigger`,children:n.map(e=>m(i.Item,{value:`${e}`,children:[e,` per page`]},e))})]})};function S({className:t,...n}){let r=s(_);return f(r,`CursorPageSizeValue must be used as a child of a CursorPagination component`),m(`span`,{"data-slot":`cursor-pagination-page-size-value`,className:e(`text-muted text-sm font-normal`,t),...n,children:[r.pageSize,` per page`]})}const C={Root:v,Buttons:y,PageSizeSelect:x,PageSizeValue:S};function w(e,t){return Math.max(1,Math.min(Number.isNaN(e)?1:Math.floor(e),t))}function T({defaultPage:e=1,listSize:t,onPageChange:n,page:r,pageSize:i,resetPageOnListSizeChange:a=!0}){let s=r!=null,[l,f]=d(e),[p,m]=d(i),h=Math.ceil(t/p),g=s?r:l,_=w(g,h),v=(_-1)*p,y=_>1,b=_<h,x=o(e=>{e!==g&&(s||f(e),n?.(e))},[s,n,g]),S=u(i),C=u(t);c(()=>{let e=S.current!==i,n=C.current!==t;S.current=i,C.current=t,e&&m(i),(e||n&&a)&&x(1)},[t,i,a,x]);function T(e){x(w(e,h))}function E(){b&&x(_+1)}function D(){y&&x(_-1)}function O(e){m(e),x(1)}function k(){x(w(h,h))}function A(){x(1)}return{currentPage:_,goToFirstPage:A,goToLastPage:k,goToPage:T,hasNextPage:b,hasPreviousPage:y,nextPage:E,offset:v,pageSize:p,previousPage:D,setPageSize:O,totalPages:h}}function E(e,t){return e.slice(t.offset,t.offset+t.pageSize)}export{C as CursorPagination,E as getOffsetPaginatedSlice,T as useOffsetPagination};
@@ -1 +1 @@
1
- import{t as e}from"./cx-IiQEAKf5.js";import{r as t}from"./layer-container-CglTh9-6.js";import{jsx as n,jsxs as r}from"react/jsx-runtime";import*as i from"@radix-ui/react-popover";const a=i.Root,o=i.Trigger,s={Root:a,Anchor:i.Anchor,Arrow:({className:t,height:a=7,width:o=14,...s})=>n(i.Arrow,{"aria-hidden":`true`,asChild:!0,"data-slot":`popover-arrow`,height:a,width:o,...s,children:r(`svg`,{className:e(`fill-[var(--background-color-popover)]`,`[clip-path:inset(0_-200%_-200%_-200%)]`,`[filter:drop-shadow(0_0_4px_color-mix(in_oklab,var(--shadow-color)_var(--shadow-first-opacity),transparent))]`,t),children:[n(`polygon`,{points:`0,0 30,0 15,10`}),n(`polyline`,{className:`stroke-[color:var(--border-color-popover)]`,fill:`none`,points:`0,0 15,10 30,0`,strokeWidth:1.5,vectorEffect:`non-scaling-stroke`})]})}),Close:i.Close,Content:({align:r=`center`,className:a,onClick:o,preferredWidth:s=`max-w-72`,ref:c,sideOffset:l=4,...u})=>{let d=t();return n(i.Portal,{container:d,children:n(i.Content,{align:r,"data-slot":`popover-content`,className:e(`relative`,`text-popover-foreground border-popover bg-popover data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95 z-50 rounded-md border p-4 shadow-md outline-hidden`,s,a),onClick:e=>{e.stopPropagation(),o?.(e)},ref:c,sideOffset:l,...u})})},Trigger:o};export{s as t};
1
+ import{t as e}from"./cx-0HCjnNv1.js";import{r as t}from"./layer-container-BTcQpd4K.js";import{jsx as n,jsxs as r}from"react/jsx-runtime";import*as i from"@radix-ui/react-popover";const a=i.Root,o=i.Trigger,s={Root:a,Anchor:i.Anchor,Arrow:({className:t,height:a=7,width:o=14,...s})=>n(i.Arrow,{"aria-hidden":`true`,asChild:!0,"data-slot":`popover-arrow`,height:a,width:o,...s,children:r(`svg`,{className:e(`fill-[var(--background-color-popover)]`,`[clip-path:inset(0_-200%_-200%_-200%)]`,`[filter:drop-shadow(0_0_4px_color-mix(in_oklab,var(--shadow-color)_var(--shadow-first-opacity),transparent))]`,t),children:[n(`polygon`,{points:`0,0 30,0 15,10`}),n(`polyline`,{className:`stroke-[color:var(--border-color-popover)]`,fill:`none`,points:`0,0 15,10 30,0`,strokeWidth:1.5,vectorEffect:`non-scaling-stroke`})]})}),Close:i.Close,Content:({align:r=`center`,className:a,onClick:o,preferredWidth:s=`max-w-72`,ref:c,sideOffset:l=4,...u})=>{let d=t();return n(i.Portal,{container:d,children:n(i.Content,{align:r,"data-slot":`popover-content`,className:e(`relative`,`text-popover-foreground border-popover bg-popover data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95 z-50 rounded-md border p-4 shadow-md outline-hidden`,s,a),onClick:e=>{e.stopPropagation(),o?.(e)},ref:c,sideOffset:l,...u})})},Trigger:o};export{s as t};
@@ -148,7 +148,7 @@ declare const Popover: {
148
148
  */
149
149
  readonly Root: import("react").FC<PopoverPrimitive.PopoverProps>;
150
150
  /**
151
- * An optional element to position the PopoverContent against. If not used, content positions alongside the trigger.
151
+ * An optional element to position the PopoverContent against. If this part is not used, the content will position alongside the PopoverTrigger.
152
152
  *
153
153
  * @see https://mantle.ngrok.com/components/overlays/popover#popoveranchor
154
154
  *
@@ -199,7 +199,7 @@ declare const Popover: {
199
199
  */
200
200
  readonly Arrow: typeof Arrow;
201
201
  /**
202
- * A button that closes an open popover. Can be placed anywhere within the popover content.
202
+ * A button that closes an open popover.
203
203
  *
204
204
  * @see https://mantle.ngrok.com/components/overlays/popover#popoverclose
205
205
  *
@@ -223,7 +223,7 @@ declare const Popover: {
223
223
  */
224
224
  readonly Close: import("react").ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & import("react").RefAttributes<HTMLButtonElement>>;
225
225
  /**
226
- * The content to render inside the popover. Appears in a portal with rich styling and animations.
226
+ * The content to render inside the popover.
227
227
  *
228
228
  * `Popover.Content` renders at Tailwind `z-50`, Mantle's float tier. When
229
229
  * composed inside an open `Dialog`, `AlertDialog`, or `Sheet`, it portals into
@@ -232,6 +232,10 @@ declare const Popover: {
232
232
  * (`z-60`). When sibling floats share a container, the most recently mounted
233
233
  * float paints on top.
234
234
  *
235
+ * It sets `position: relative`, so `Popover.Arrow`'s absolutely-positioned
236
+ * wrapper keeps one containing block through the open animation. An
237
+ * absolutely-positioned child of the content therefore anchors to the content.
238
+ *
235
239
  * @see https://mantle.ngrok.com/components/overlays/popover#popovercontent
236
240
  *
237
241
  * @example
@@ -252,7 +256,7 @@ declare const Popover: {
252
256
  */
253
257
  readonly Content: typeof Content;
254
258
  /**
255
- * The trigger button that opens the popover when clicked or focused.
259
+ * The trigger button that opens the popover.
256
260
  *
257
261
  * @see https://mantle.ngrok.com/components/overlays/popover#popovertrigger
258
262
  *
package/dist/popover.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as Popover } from "./popover-DDuw1UaJ.js";
1
+ import { t as Popover } from "./popover-s2LhmzfQ.js";
2
2
  export { Popover };
package/dist/popover.js CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./popover-D6x6Bq-G.js";export{e as Popover};
1
+ import{t as e}from"./popover-Bp-9B3GR.js";export{e as Popover};
@@ -0,0 +1 @@
1
+ import{t as e}from"./slot-C3gII_9c.js";import{t}from"./booleanish-BfvnW6vy.js";import{n,r}from"./layer-container-BTcQpd4K.js";import{jsx as i}from"react/jsx-runtime";import*as a from"@radix-ui/react-dialog";function o(e){e.target instanceof Element&&e.target.closest(`.overlay-prompt`)&&e.preventDefault()}const s=a.Root,c=a.Trigger,l=({container:e,...t})=>{let o=r(),s=e??o;return i(n.Provider,{value:s,children:i(a.Portal,{container:s,...t})})},u=a.Close,d=e=>i(a.Overlay,{"data-overlay":!0,...e}),f=({onEscapeKeyDown:e,onInteractOutside:t,onPointerDownOutside:n,ref:r,...s})=>i(a.Content,{ref:r,onEscapeKeyDown:t=>{g(t),e?.(t)},onInteractOutside:e=>{o(e),t?.(e)},onPointerDownOutside:e=>{o(e),n?.(e)},...s}),p=a.Title,m=({asChild:t,children:n,ref:r,...o})=>{let s=t?e:`div`;return i(a.Description,{ref:r,asChild:!0,children:i(s,{...o,children:n})})};function h(e){return e instanceof HTMLElement&&e.hasAttribute(`data-overlay`)}function g(e){if(!b(e.currentTarget))return;let n=e.currentTarget,r=n instanceof Document?n.activeElement:n.ownerDocument?.activeElement??null,i=_(e.target)??_(r),a=i?v(i):null;i!=null&&t(i.getAttribute(`aria-expanded`))&&a!=null&&n.contains(i)&&n.contains(a)&&(a.getAttribute(`data-open`)===`true`||a.getAttribute(`data-state`)===`open`)&&e.preventDefault()}function _(e){return y(e)?e.closest(`[aria-expanded='true'][aria-controls]`):null}function v(e){let t=e.getAttribute(`aria-controls`);if(!t)return null;let n=e.ownerDocument.getElementById(t);return n instanceof HTMLElement?n:null}function y(e){return e instanceof HTMLElement}function b(e){return e instanceof Node&&`querySelector`in e}export{l as a,c,d as i,h as l,f as n,s as o,m as r,p as s,u as t};
@@ -17,9 +17,7 @@ type Props = SvgAttributes & {
17
17
  */
18
18
  max?: number | undefined;
19
19
  /**
20
- * The width of the progress bar stroke.
21
- * Note, we clamp the stroke width to a minimum of 1px and max of 12px since
22
- * it is proportional to the viewbox size (0 0 32 32).
20
+ * The width of the progress bar stroke, clamped between 1px and 12px.
23
21
  *
24
22
  * @default 0.25rem (4px)
25
23
  */
@@ -29,6 +27,7 @@ type Props = SvgAttributes & {
29
27
  * This attribute specifies how much of the task is complete.
30
28
  * It must be a valid floating point number between 0 and `max`, or, when `max` is omitted, between 0 and 100.
31
29
  * If set to `"indeterminate"`, the progress bar is considered indeterminate.
30
+ * A value outside `0..max` also renders as indeterminate.
32
31
  *
33
32
  * @default 0
34
33
  */
@@ -49,16 +48,28 @@ type Props = SvgAttributes & {
49
48
  * The indicator color is inherited via `currentColor`. Override the default
50
49
  * (`accent-600`) by setting the `ProgressDonut.Indicator`'s text color.
51
50
  *
51
+ * **Accessibility.** Renders `role="progressbar"` with `aria-valuemin`,
52
+ * `aria-valuemax`, and `aria-valuenow` (omitted while indeterminate). The role
53
+ * needs a name: pass `aria-label`, or `aria-labelledby` that points at a visible
54
+ * label.
55
+ *
56
+ * | Data Attribute | Value | Description |
57
+ * | -------------- | ------------------- | --------------------------- |
58
+ * | `data-slot` | `"progress-donut"` | The root `<svg>`. |
59
+ * | `data-value` | the current value | Absent while indeterminate. |
60
+ * | `data-min` | `0` | |
61
+ * | `data-max` | the maximum | |
62
+ *
52
63
  * @see https://mantle.ngrok.com/components/feedback/progress-donut#progressdonutroot
53
64
  *
54
65
  * @example
55
66
  * ```tsx
56
- * <ProgressDonut.Root value={60}>
67
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
57
68
  * <ProgressDonut.Indicator />
58
69
  * </ProgressDonut.Root>
59
70
  *
60
- * <ProgressDonut.Root value={60}>
61
- * <ProgressDonut.Indicator color="text-danger-600" />
71
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
72
+ * <ProgressDonut.Indicator className="text-danger-600" />
62
73
  * </ProgressDonut.Root>
63
74
  * ```
64
75
  */
@@ -71,12 +82,12 @@ type ProgressDonutIndicatorProps = Omit<ComponentProps<"g">, "children">;
71
82
  *
72
83
  * @example
73
84
  * ```tsx
74
- * <ProgressDonut.Root value={60}>
85
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
75
86
  * <ProgressDonut.Indicator />
76
87
  * </ProgressDonut.Root>
77
88
  *
78
- * <ProgressDonut.Root value={60}>
79
- * <ProgressDonut.Indicator color="text-danger-600" />
89
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
90
+ * <ProgressDonut.Indicator className="text-danger-600" />
80
91
  * </ProgressDonut.Root>
81
92
  * ```
82
93
  */
@@ -98,12 +109,12 @@ declare const Indicator$1: ({ className, ...props }: ProgressDonutIndicatorProps
98
109
  *
99
110
  * @example
100
111
  * ```tsx
101
- * <ProgressDonut.Root value={60}>
112
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
102
113
  * <ProgressDonut.Indicator />
103
114
  * </ProgressDonut.Root>
104
115
  *
105
- * <ProgressDonut.Root value={60}>
106
- * <ProgressDonut.Indicator color="text-danger-600" />
116
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
117
+ * <ProgressDonut.Indicator className="text-danger-600" />
107
118
  * </ProgressDonut.Root>
108
119
  * ```
109
120
  */
@@ -114,16 +125,21 @@ declare const ProgressDonut: {
114
125
  * The indicator color is inherited via `currentColor`. Override the default
115
126
  * (`accent-600`) by setting the `ProgressDonut.Indicator`'s text color.
116
127
  *
128
+ * **Accessibility.** Renders `role="progressbar"` with `aria-valuemin`,
129
+ * `aria-valuemax`, and `aria-valuenow` (omitted while indeterminate). The role
130
+ * needs a name: pass `aria-label`, or `aria-labelledby` that points at a visible
131
+ * label.
132
+ *
117
133
  * @see https://mantle.ngrok.com/components/feedback/progress-donut#progressdonutroot
118
134
  *
119
135
  * @example
120
136
  * ```tsx
121
- * <ProgressDonut.Root value={60}>
137
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
122
138
  * <ProgressDonut.Indicator />
123
139
  * </ProgressDonut.Root>
124
140
  *
125
- * <ProgressDonut.Root value={60}>
126
- * <ProgressDonut.Indicator color="text-danger-600" />
141
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
142
+ * <ProgressDonut.Indicator className="text-danger-600" />
127
143
  * </ProgressDonut.Root>
128
144
  * ```
129
145
  */
@@ -135,12 +151,12 @@ declare const ProgressDonut: {
135
151
  *
136
152
  * @example
137
153
  * ```tsx
138
- * <ProgressDonut.Root value={60}>
154
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
139
155
  * <ProgressDonut.Indicator />
140
156
  * </ProgressDonut.Root>
141
157
  *
142
- * <ProgressDonut.Root value={60}>
143
- * <ProgressDonut.Indicator color="text-danger-600" />
158
+ * <ProgressDonut.Root aria-label="Data transfer out" value={60}>
159
+ * <ProgressDonut.Indicator className="text-danger-600" />
144
160
  * </ProgressDonut.Root>
145
161
  * ```
146
162
  */
@@ -162,6 +178,7 @@ type RootProps = ComponentProps<"div"> & {
162
178
  * This attribute specifies how much of the task is complete.
163
179
  * It must be a valid floating point number between 0 and `max`, or, when `max` is omitted, between 0 and 100.
164
180
  * If set to `"indeterminate"`, the progress bar is considered indeterminate. (for now there is no visual difference than 0)
181
+ * A value outside `0..max` also renders as indeterminate.
165
182
  *
166
183
  * @default 0
167
184
  */
@@ -173,20 +190,32 @@ type RootProps = ComponentProps<"div"> & {
173
190
  * A horizontal progress bar that shows the completion progress of a task.
174
191
  * Use this component for linear progress indication.
175
192
  *
193
+ * **Accessibility.** Renders `role="progressbar"` with `aria-valuemin`,
194
+ * `aria-valuemax`, and `aria-valuenow` (omitted while indeterminate). The role
195
+ * needs a name: pass `aria-label`, or `aria-labelledby` that points at a visible
196
+ * label.
197
+ *
198
+ * | Data Attribute | Value | Description |
199
+ * | -------------- | ------------------------------------------------------ | -------------------------------------------- |
200
+ * | `data-slot` | `"progress-bar"` | The root element. |
201
+ * | `data-state` | `"complete"` \| `"indeterminate"` \| `"loading"` | Set by Radix from `value` and `max`. |
202
+ * | `data-value` | the current value | Absent while indeterminate. |
203
+ * | `data-max` | the maximum | |
204
+ *
176
205
  * @see https://mantle.ngrok.com/components/feedback/progress-bar#progressbarroot
177
206
  *
178
207
  * @example
179
208
  * ```tsx
180
- * <ProgressBar.Root value={60}>
209
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
181
210
  * <ProgressBar.Indicator />
182
211
  * </ProgressBar.Root>
183
212
  *
184
- * <ProgressBar.Root value={75} max={100}>
213
+ * <ProgressBar.Root aria-label="Upload progress" value={75} max={100}>
185
214
  * <ProgressBar.Indicator />
186
215
  * </ProgressBar.Root>
187
216
  *
188
217
  * // Indeterminate progress
189
- * <ProgressBar.Root value="indeterminate">
218
+ * <ProgressBar.Root aria-label="Upload progress" value="indeterminate">
190
219
  * <ProgressBar.Indicator />
191
220
  * </ProgressBar.Root>
192
221
  * ```
@@ -203,12 +232,12 @@ type IndicatorProps = ComponentProps<typeof ProgressPrimitive.Indicator>;
203
232
  *
204
233
  * @example
205
234
  * ```tsx
206
- * <ProgressBar.Root value={60}>
235
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
207
236
  * <ProgressBar.Indicator />
208
237
  * </ProgressBar.Root>
209
238
  *
210
239
  * // Custom styled indicator
211
- * <ProgressBar.Root value={60}>
240
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
212
241
  * <ProgressBar.Indicator className="bg-success-600" />
213
242
  * </ProgressBar.Root>
214
243
  * ```
@@ -231,16 +260,16 @@ declare function Indicator({ className, style, ...props }: IndicatorProps): impo
231
260
  *
232
261
  * @example
233
262
  * ```tsx
234
- * <ProgressBar.Root value={60}>
263
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
235
264
  * <ProgressBar.Indicator />
236
265
  * </ProgressBar.Root>
237
266
  *
238
- * <ProgressBar.Root value={75} max={100}>
267
+ * <ProgressBar.Root aria-label="Upload progress" value={75} max={100}>
239
268
  * <ProgressBar.Indicator />
240
269
  * </ProgressBar.Root>
241
270
  *
242
271
  * // Indeterminate progress
243
- * <ProgressBar.Root value="indeterminate">
272
+ * <ProgressBar.Root aria-label="Upload progress" value="indeterminate">
244
273
  * <ProgressBar.Indicator />
245
274
  * </ProgressBar.Root>
246
275
  * ```
@@ -252,20 +281,25 @@ declare const ProgressBar: {
252
281
  * A horizontal progress bar that shows the completion progress of a task.
253
282
  * Use this component for linear progress indication.
254
283
  *
284
+ * **Accessibility.** Renders `role="progressbar"` with `aria-valuemin`,
285
+ * `aria-valuemax`, and `aria-valuenow` (omitted while indeterminate). The role
286
+ * needs a name: pass `aria-label`, or `aria-labelledby` that points at a visible
287
+ * label.
288
+ *
255
289
  * @see https://mantle.ngrok.com/components/feedback/progress-bar#progressbarroot
256
290
  *
257
291
  * @example
258
292
  * ```tsx
259
- * <ProgressBar.Root value={60}>
293
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
260
294
  * <ProgressBar.Indicator />
261
295
  * </ProgressBar.Root>
262
296
  *
263
- * <ProgressBar.Root value={75} max={100}>
297
+ * <ProgressBar.Root aria-label="Upload progress" value={75} max={100}>
264
298
  * <ProgressBar.Indicator />
265
299
  * </ProgressBar.Root>
266
300
  *
267
301
  * // Indeterminate progress
268
- * <ProgressBar.Root value="indeterminate">
302
+ * <ProgressBar.Root aria-label="Upload progress" value="indeterminate">
269
303
  * <ProgressBar.Indicator />
270
304
  * </ProgressBar.Root>
271
305
  * ```
@@ -281,12 +315,12 @@ declare const ProgressBar: {
281
315
  *
282
316
  * @example
283
317
  * ```tsx
284
- * <ProgressBar.Root value={60}>
318
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
285
319
  * <ProgressBar.Indicator />
286
320
  * </ProgressBar.Root>
287
321
  *
288
322
  * // Custom styled indicator
289
- * <ProgressBar.Root value={60}>
323
+ * <ProgressBar.Root aria-label="Upload progress" value={60}>
290
324
  * <ProgressBar.Indicator className="bg-success-600" />
291
325
  * </ProgressBar.Root>
292
326
  * ```
package/dist/progress.js CHANGED
@@ -1 +1 @@
1
- import{t as e}from"./cx-IiQEAKf5.js";import{t}from"./types-D85fCNV3.js";import{t as n}from"./clsx-DUGZgXfJ.js";import{createContext as r,useContext as i,useId as a,useMemo as o}from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import*as l from"@radix-ui/react-progress";function u(e,{min:t,max:n}){return Math.min(n,Math.max(t,e))}function d(e){return typeof e==`number`}function f(e,t){return d(e)&&!Number.isNaN(e)&&e<=t&&e>=0}function p(e){return d(e)&&!Number.isNaN(e)&&e>0}const m={max:100,strokeWidth:`0.25rem`,value:0},h=r(m),g={Root:({children:n,className:r,max:i=100,strokeWidth:a=4,value:l,indeterminateRotationSpeed:u,...g})=>{let y=p(i)?i:100,b=f(l,y)?l:l==null?0:`indeterminate`,x=_(a??m.strokeWidth),S=d(b)?b:void 0,C=v(x),w=o(()=>({max:y,strokeWidth:x,value:b}),[y,x,b]);return s(h.Provider,{value:w,children:c(`svg`,{"data-slot":`progress-donut`,"aria-valuemax":y,"aria-valuemin":0,"aria-valuenow":S,className:e(`size-6 text-gray-200 dark:text-gray-300`,b===`indeterminate`&&[`animate-spin`,u??`animation-duration-[15s]`],r),"data-max":y,"data-min":0,"data-value":S,height:`100%`,role:`progressbar`,width:`100%`,...g,children:[s(`circle`,{className:`[r:var(--radius)]`,cx:`50%`,cy:`50%`,fill:`transparent`,stroke:`currentColor`,strokeWidth:x,style:t({"--radius":C})}),n]})})},Indicator:({className:r,...o})=>{let l=a(),u=i(h)??m,d=(u.value===`indeterminate`?.6:u.value/u.max)*100,f=_(u.strokeWidth),p=v(f);return c(`g`,{"data-slot":`progress-donut-indicator`,className:e(`text-accent-600`,r),...o,children:[u.value===`indeterminate`&&s(`defs`,{children:c(`linearGradient`,{id:l,children:[s(`stop`,{className:`stop-opacity-100 stop-color-current`,offset:`0%`}),s(`stop`,{className:`stop-opacity-0 stop-color-current`,offset:`95%`})]})}),s(`circle`,{className:n(`[r:var(--radius)]`,`origin-center`),cx:`50%`,cy:`50%`,fill:`transparent`,pathLength:100,stroke:u.value===`indeterminate`?`url(#${l})`:`currentColor`,strokeDasharray:100,strokeDashoffset:100-d,strokeLinecap:`round`,strokeWidth:f,style:t({"--radius":p}),transform:`rotate(-90)`})]})}};function _(e){let t=4;return e==null?t:(t=typeof e==`number`?e:e.endsWith(`rem`)?Number(e.replace(`rem`,``))*16:Number(e),u(Number.isNaN(t)?4:t,{min:1,max:12}))}function v(e){return`calc(50% - ${e/2}px)`}const y=r({max:100,value:0});function b({className:t,children:n,max:r=100,value:i,...a}){let c=p(r)?r:100,u=f(i,c)?i:i==null?0:`indeterminate`,m=d(u)?u:void 0,h=o(()=>({max:c,value:u}),[c,u]);return s(y.Provider,{value:h,children:s(l.Root,{"data-slot":`progress-bar`,className:e(`bg-base-hover dark:bg-base shadow-inner relative h-3 w-full overflow-hidden rounded-md`,t),value:m,max:c,...a,children:n})})}function x({className:t,style:n,...r}){let a=i(y),{max:o}=a,c=(o-(a.value===`indeterminate`?0:a.value))/o*100;return s(l.Indicator,{"data-slot":`progress-bar-indicator`,className:e(`bg-accent-600 h-full w-full flex-1 transition-all`,t),style:{...n,transform:`translateX(-${c}%)`},...r})}const S={Root:b,Indicator:x};export{S as ProgressBar,g as ProgressDonut};
1
+ import{t as e}from"./cx-0HCjnNv1.js";import{t}from"./types-D85fCNV3.js";import{t as n}from"./clsx-DUGZgXfJ.js";import{createContext as r,useContext as i,useId as a,useMemo as o}from"react";import{jsx as s,jsxs as c}from"react/jsx-runtime";import*as l from"@radix-ui/react-progress";function u(e,{min:t,max:n}){return Math.min(n,Math.max(t,e))}function d(e){return typeof e==`number`}function f(e,t){return d(e)&&!Number.isNaN(e)&&e<=t&&e>=0}function p(e){return d(e)&&!Number.isNaN(e)&&e>0}const m={max:100,strokeWidth:`0.25rem`,value:0},h=r(m),g={Root:({children:n,className:r,max:i=100,strokeWidth:a=4,value:l,indeterminateRotationSpeed:u,...g})=>{let y=p(i)?i:100,b=f(l,y)?l:l==null?0:`indeterminate`,x=_(a??m.strokeWidth),S=d(b)?b:void 0,C=v(x),w=t({"--radius":C}),T=o(()=>({max:y,strokeWidth:x,value:b}),[y,x,b]);return s(h.Provider,{value:T,children:c(`svg`,{"data-slot":`progress-donut`,"aria-valuemax":y,"aria-valuemin":0,"aria-valuenow":S,className:e(`size-6 text-gray-200 dark:text-gray-300`,b===`indeterminate`&&[`animate-spin`,u??`animation-duration-[15s]`],r),"data-max":y,"data-min":0,"data-value":S,height:`100%`,role:`progressbar`,width:`100%`,...g,children:[s(`circle`,{className:`[r:var(--radius)]`,cx:`50%`,cy:`50%`,fill:`transparent`,stroke:`currentColor`,strokeWidth:x,style:w}),n]})})},Indicator:({className:r,...o})=>{let l=a(),u=i(h)??m,d=(u.value===`indeterminate`?.6:u.value/u.max)*100,f=_(u.strokeWidth),p=v(f);return c(`g`,{"data-slot":`progress-donut-indicator`,className:e(`text-accent-600`,r),...o,children:[u.value===`indeterminate`&&s(`defs`,{children:c(`linearGradient`,{id:l,children:[s(`stop`,{className:`stop-opacity-100 stop-color-current`,offset:`0%`}),s(`stop`,{className:`stop-opacity-0 stop-color-current`,offset:`95%`})]})}),s(`circle`,{className:n(`[r:var(--radius)]`,`origin-center`),cx:`50%`,cy:`50%`,fill:`transparent`,pathLength:100,stroke:u.value===`indeterminate`?`url(#${l})`:`currentColor`,strokeDasharray:100,strokeDashoffset:100-d,strokeLinecap:`round`,strokeWidth:f,style:t({"--radius":p}),transform:`rotate(-90)`})]})}};function _(e){let t=4;return e==null?t:(t=typeof e==`number`?e:e.endsWith(`rem`)?Number(e.replace(`rem`,``))*16:Number(e),u(Number.isNaN(t)?4:t,{min:1,max:12}))}function v(e){return`calc(50% - ${e/2}px)`}const y=r({max:100,value:0});function b({className:t,children:n,max:r=100,value:i,...a}){let c=p(r)?r:100,u=f(i,c)?i:i==null?0:`indeterminate`,m=d(u)?u:void 0,h=o(()=>({max:c,value:u}),[c,u]);return s(y.Provider,{value:h,children:s(l.Root,{"data-slot":`progress-bar`,className:e(`bg-base-hover dark:bg-base shadow-inner relative h-3 w-full overflow-hidden rounded-md`,t),value:m,max:c,...a,children:n})})}function x({className:t,style:n,...r}){let a=i(y),{max:o}=a,c=(o-(a.value===`indeterminate`?0:a.value))/o*100;return s(l.Indicator,{"data-slot":`progress-bar-indicator`,className:e(`bg-accent-600 h-full w-full flex-1 transition-all`,t),style:{...n,transform:`translateX(-${c}%)`},...r})}const S={Root:b,Indicator:x};export{S as ProgressBar,g as ProgressDonut};
package/dist/qr-code.d.ts CHANGED
@@ -60,14 +60,19 @@ type QrCodeRootProps = ComponentProps<"div"> & WithAsChild & {
60
60
  declare const Root: ({ value, ecc, pixelSize, quietZone, asChild, className, children, ref, ...props }: QrCodeRootProps) => import("react").JSX.Element;
61
61
  /**
62
62
  * Props for `QrCode.Frame`, the fixed SVG element that sizes the encoded QR
63
- * pattern with its `viewBox`.
63
+ * pattern with its `viewBox`. `role` is locked to `"img"`.
64
64
  */
65
- type QrCodeFrameProps = ComponentProps<"svg">;
65
+ type QrCodeFrameProps = Omit<ComponentProps<"svg">, "role">;
66
66
  /**
67
67
  * The `svg` frame that holds the QR `Pattern`. Defaults to a square `size-48`
68
68
  * and scales the encoded pattern to fit via its `viewBox`, so resize the whole
69
69
  * code by passing a different size to `className` (e.g. `className="size-64"`).
70
70
  *
71
+ * The frame is the image a screen reader meets: it always carries
72
+ * `role="img"`. Pass `aria-label` (or `aria-labelledby`) that says what the
73
+ * code encodes, such as "QR code for the ngrok dashboard". When neither is
74
+ * set, the name falls back to "QR code".
75
+ *
71
76
  * Does not support `asChild`: the QR pattern must live inside an `svg`, so the
72
77
  * frame element is fixed and cannot be swapped.
73
78
  *
@@ -85,7 +90,7 @@ type QrCodeFrameProps = ComponentProps<"svg">;
85
90
  * </QrCode.Root>
86
91
  * ```
87
92
  */
88
- declare const Frame: ({ className, children, ref, ...props }: QrCodeFrameProps) => import("react").JSX.Element;
93
+ declare const Frame: ({ "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, className, children, ref, ...props }: QrCodeFrameProps) => import("react").JSX.Element;
89
94
  /**
90
95
  * Props for `QrCode.Pattern`, the fixed SVG `path` element that renders the
91
96
  * encoded dark modules.
@@ -94,7 +99,8 @@ type QrCodePatternProps = ComponentProps<"path">;
94
99
  /**
95
100
  * The encoded QR modules, rendered as a single `path` inside the `Frame`.
96
101
  * Defaults to black fill (`fill-static-black`) so the code stays scannable in
97
- * every theme.
102
+ * every theme. A consumer `className` can override the fill, but a light or
103
+ * inverted fill makes the code unreliable for many scanners.
98
104
  *
99
105
  * Does not support `asChild`: the modules are a fixed `path` and cannot be
100
106
  * swapped for another element.