@godxjp/ui 20.0.0 → 20.2.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 (273) hide show
  1. package/README.md +8 -2
  2. package/dist/app/app-provider.js +37 -21
  3. package/dist/app/index.d.ts +2 -0
  4. package/dist/app/index.js +2 -0
  5. package/dist/app/storage.d.ts +17 -0
  6. package/dist/app/storage.js +28 -0
  7. package/dist/app/theme-axes.d.ts +2 -0
  8. package/dist/app/theme-axes.js +45 -0
  9. package/dist/components/charts/chart-cartesian.d.ts +2 -1
  10. package/dist/components/charts/chart-cartesian.js +52 -3
  11. package/dist/components/charts/chart-category-axis.d.ts +55 -0
  12. package/dist/components/charts/chart-category-axis.js +93 -0
  13. package/dist/components/charts/chart-frame.d.ts +10 -1
  14. package/dist/components/charts/chart-frame.js +19 -3
  15. package/dist/components/charts/compact-bar-trend.d.ts +1 -1
  16. package/dist/components/charts/compact-bar-trend.js +2 -0
  17. package/dist/components/charts/pie-chart.d.ts +1 -1
  18. package/dist/components/charts/pie-chart.js +12 -1
  19. package/dist/components/charts/recharts-peer.d.ts +49 -0
  20. package/dist/components/charts/recharts-peer.js +45 -0
  21. package/dist/components/data-display/card.d.ts +12 -1
  22. package/dist/components/data-display/card.js +22 -4
  23. package/dist/components/data-display/code-block.js +6 -2
  24. package/dist/components/data-display/data-table.d.ts +39 -4
  25. package/dist/components/data-display/data-table.js +802 -270
  26. package/dist/components/data-display/descriptions.d.ts +27 -6
  27. package/dist/components/data-display/descriptions.js +58 -17
  28. package/dist/components/data-display/index.d.ts +2 -0
  29. package/dist/components/data-display/index.js +2 -0
  30. package/dist/components/data-display/list-row.d.ts +10 -1
  31. package/dist/components/data-display/list-row.js +7 -1
  32. package/dist/components/data-display/popover.d.ts +9 -3
  33. package/dist/components/data-display/popover.js +65 -11
  34. package/dist/components/data-display/range-timeline.d.ts +38 -0
  35. package/dist/components/data-display/range-timeline.js +161 -0
  36. package/dist/components/data-display/scroll-area.js +13 -2
  37. package/dist/components/data-display/service-launcher-card.js +14 -12
  38. package/dist/components/data-display/table.d.ts +71 -3
  39. package/dist/components/data-display/table.js +56 -18
  40. package/dist/components/data-display/tree-list.js +4 -9
  41. package/dist/components/data-entry/calendar.d.ts +2 -2
  42. package/dist/components/data-entry/calendar.js +23 -3
  43. package/dist/components/data-entry/cascader.d.ts +1 -1
  44. package/dist/components/data-entry/cascader.js +188 -24
  45. package/dist/components/data-entry/color-picker.d.ts +1 -1
  46. package/dist/components/data-entry/color-picker.js +17 -5
  47. package/dist/components/data-entry/control-appearance.d.ts +64 -0
  48. package/dist/components/data-entry/control-appearance.js +39 -0
  49. package/dist/components/data-entry/control-surface.d.ts +61 -0
  50. package/dist/components/data-entry/control-surface.js +39 -0
  51. package/dist/components/data-entry/date-picker.d.ts +1 -1
  52. package/dist/components/data-entry/date-picker.js +344 -113
  53. package/dist/components/data-entry/date-range-picker.d.ts +1 -1
  54. package/dist/components/data-entry/date-range-picker.js +278 -140
  55. package/dist/components/data-entry/form-field.d.ts +1 -1
  56. package/dist/components/data-entry/form-field.js +39 -4
  57. package/dist/components/data-entry/form.d.ts +4 -0
  58. package/dist/components/data-entry/form.js +4 -2
  59. package/dist/components/data-entry/index.d.ts +7 -3
  60. package/dist/components/data-entry/index.js +10 -1
  61. package/dist/components/data-entry/input-otp.d.ts +1 -1
  62. package/dist/components/data-entry/input.d.ts +12 -34
  63. package/dist/components/data-entry/input.js +92 -24
  64. package/dist/components/data-entry/month-picker.d.ts +1 -1
  65. package/dist/components/data-entry/month-picker.js +47 -10
  66. package/dist/components/data-entry/month-range-picker.d.ts +1 -1
  67. package/dist/components/data-entry/month-range-picker.js +51 -11
  68. package/dist/components/data-entry/number-input.d.ts +7 -0
  69. package/dist/components/data-entry/number-input.js +147 -98
  70. package/dist/components/data-entry/password-input.d.ts +1 -1
  71. package/dist/components/data-entry/radio.d.ts +1 -1
  72. package/dist/components/data-entry/radio.js +61 -13
  73. package/dist/components/data-entry/search-input.d.ts +1 -1
  74. package/dist/components/data-entry/search-input.js +16 -2
  75. package/dist/components/data-entry/search-select.d.ts +2 -2
  76. package/dist/components/data-entry/search-select.js +209 -78
  77. package/dist/components/data-entry/select.d.ts +22 -4
  78. package/dist/components/data-entry/select.js +215 -163
  79. package/dist/components/data-entry/slider.d.ts +9 -1
  80. package/dist/components/data-entry/slider.js +87 -9
  81. package/dist/components/data-entry/switch.d.ts +3 -0
  82. package/dist/components/data-entry/switch.js +29 -3
  83. package/dist/components/data-entry/textarea.d.ts +14 -56
  84. package/dist/components/data-entry/textarea.js +80 -33
  85. package/dist/components/data-entry/time-picker.d.ts +2 -2
  86. package/dist/components/data-entry/time-picker.js +333 -109
  87. package/dist/components/data-entry/time-range-picker.d.ts +5 -0
  88. package/dist/components/data-entry/time-range-picker.js +89 -0
  89. package/dist/components/data-entry/transfer.d.ts +1 -1
  90. package/dist/components/data-entry/transfer.js +86 -28
  91. package/dist/components/data-entry/tree-select.d.ts +1 -1
  92. package/dist/components/data-entry/tree-select.js +201 -113
  93. package/dist/components/data-entry/tree-utils.js +7 -14
  94. package/dist/components/data-entry/upload-files.d.ts +2 -0
  95. package/dist/components/data-entry/upload-files.js +31 -0
  96. package/dist/components/data-entry/upload-request.d.ts +4 -0
  97. package/dist/components/data-entry/upload-request.js +53 -0
  98. package/dist/components/data-entry/upload-types.d.ts +28 -0
  99. package/dist/components/data-entry/upload-types.js +2 -0
  100. package/dist/components/data-entry/upload.d.ts +2 -2
  101. package/dist/components/data-entry/upload.js +475 -115
  102. package/dist/components/feedback/dialog.js +19 -19
  103. package/dist/components/feedback/sheet.js +3 -0
  104. package/dist/components/feedback/tooltip.js +3 -0
  105. package/dist/components/general/button.d.ts +2 -1
  106. package/dist/components/general/button.js +7 -1
  107. package/dist/components/general/index.d.ts +1 -0
  108. package/dist/components/general/index.js +2 -0
  109. package/dist/components/general/typography.d.ts +3 -0
  110. package/dist/components/general/typography.js +15 -1
  111. package/dist/components/general/visually-hidden.d.ts +3 -0
  112. package/dist/components/general/visually-hidden.js +9 -0
  113. package/dist/components/layout/app-launcher.d.ts +34 -0
  114. package/dist/components/layout/app-launcher.js +261 -0
  115. package/dist/components/layout/app-shell.d.ts +3 -1
  116. package/dist/components/layout/app-shell.js +34 -14
  117. package/dist/components/layout/auth-shell.d.ts +1 -1
  118. package/dist/components/layout/auth-shell.js +2 -0
  119. package/dist/components/layout/breadcrumb.d.ts +14 -2
  120. package/dist/components/layout/breadcrumb.js +46 -4
  121. package/dist/components/layout/flex.d.ts +1 -1
  122. package/dist/components/layout/flex.js +23 -2
  123. package/dist/components/layout/index.d.ts +3 -0
  124. package/dist/components/layout/index.js +5 -1
  125. package/dist/components/layout/org-switcher.js +20 -1
  126. package/dist/components/layout/page-container.d.ts +1 -1
  127. package/dist/components/layout/page-container.js +5 -3
  128. package/dist/components/layout/responsive-grid.d.ts +16 -2
  129. package/dist/components/layout/responsive-grid.js +29 -2
  130. package/dist/components/layout/sidebar.js +2 -1
  131. package/dist/components/layout/topbar-item.d.ts +3 -0
  132. package/dist/components/layout/topbar-item.js +18 -3
  133. package/dist/components/layout/topbar.d.ts +1 -1
  134. package/dist/components/layout/topbar.js +27 -6
  135. package/dist/components/navigation/dropdown-menu.d.ts +30 -2
  136. package/dist/components/navigation/dropdown-menu.js +73 -11
  137. package/dist/components/navigation/pagination.d.ts +2 -2
  138. package/dist/components/navigation/pagination.js +155 -83
  139. package/dist/components/navigation/steps.d.ts +2 -2
  140. package/dist/components/navigation/steps.js +29 -4
  141. package/dist/components/navigation/tabs.d.ts +5 -33
  142. package/dist/components/navigation/tabs.js +232 -64
  143. package/dist/components/ui/hover-card.js +3 -0
  144. package/dist/components/ui/input-otp.d.ts +26 -28
  145. package/dist/components/ui/input-otp.js +50 -7
  146. package/dist/components/ui/password-input.d.ts +36 -2
  147. package/dist/components/ui/password-input.js +27 -7
  148. package/dist/components/ui/rating.d.ts +25 -0
  149. package/dist/components/ui/rating.js +67 -27
  150. package/dist/components/ui/segmented.d.ts +9 -0
  151. package/dist/components/ui/segmented.js +17 -2
  152. package/dist/components/ui/separator.d.ts +4 -0
  153. package/dist/components/ui/separator.js +13 -0
  154. package/dist/components/ui/tag-input.d.ts +45 -0
  155. package/dist/components/ui/tag-input.js +109 -27
  156. package/dist/form/form-context.d.ts +29 -0
  157. package/dist/form/form-context.js +44 -4
  158. package/dist/form/form-field-array.d.ts +22 -0
  159. package/dist/form/form-field-array.js +50 -0
  160. package/dist/form/form-field-control.d.ts +2 -1
  161. package/dist/form/form-field-control.js +116 -40
  162. package/dist/form/form-root.d.ts +2 -1
  163. package/dist/form/form-root.js +142 -23
  164. package/dist/form/index.d.ts +3 -1
  165. package/dist/form/index.js +12 -1
  166. package/dist/i18n/index.d.ts +1 -1
  167. package/dist/i18n/index.js +3 -1
  168. package/dist/i18n/messages/en.json +59 -6
  169. package/dist/i18n/messages/ja.json +59 -6
  170. package/dist/i18n/messages/vi.json +59 -6
  171. package/dist/i18n/translate.d.ts +19 -0
  172. package/dist/i18n/translate.js +24 -0
  173. package/dist/inertia/index.d.ts +20 -0
  174. package/dist/inertia/index.js +60 -1
  175. package/dist/lib/control-styles.d.ts +25 -3
  176. package/dist/lib/control-styles.js +9 -3
  177. package/dist/lib/datetime/picker-format.d.ts +8 -0
  178. package/dist/lib/datetime/picker-format.js +54 -0
  179. package/dist/lib/overlay-portal.d.ts +18 -0
  180. package/dist/lib/overlay-portal.js +17 -0
  181. package/dist/props/components/app.prop.d.ts +13 -2
  182. package/dist/props/components/charts.prop.d.ts +21 -0
  183. package/dist/props/components/data-display.prop.d.ts +55 -4
  184. package/dist/props/components/data-entry.prop.d.ts +687 -43
  185. package/dist/props/components/form.prop.d.ts +142 -4
  186. package/dist/props/components/general.prop.d.ts +30 -1
  187. package/dist/props/components/index.d.ts +2 -2
  188. package/dist/props/components/layout.prop.d.ts +255 -8
  189. package/dist/props/components/navigation.prop.d.ts +113 -3
  190. package/dist/props/registry.d.ts +376 -10
  191. package/dist/props/registry.js +493 -9
  192. package/dist/props/vocabulary/data.prop.d.ts +179 -1
  193. package/dist/props/vocabulary/index.d.ts +4 -4
  194. package/dist/props/vocabulary/interaction.prop.d.ts +51 -2
  195. package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
  196. package/dist/props/vocabulary/shared.prop.d.ts +33 -0
  197. package/dist/styles/badge-layout.css +2 -1
  198. package/dist/styles/card-layout.css +36 -5
  199. package/dist/styles/chart-layout.css +17 -1
  200. package/dist/styles/control.css +520 -14
  201. package/dist/styles/data-display-layout.css +248 -7
  202. package/dist/styles/data-entry-layout.css +13 -0
  203. package/dist/styles/layout.css +221 -4
  204. package/dist/styles/navigation-layout.css +230 -1
  205. package/dist/styles/shell-layout.css +690 -21
  206. package/dist/styles/table-layout.css +95 -6
  207. package/dist/styles/text-layout.css +5 -0
  208. package/dist/tokens/base.css +1 -0
  209. package/dist/tokens/components/badge.css +1 -0
  210. package/dist/tokens/components/chart.css +6 -0
  211. package/dist/tokens/components/control.css +81 -3
  212. package/dist/tokens/components/data-display.css +9 -0
  213. package/dist/tokens/components/descriptions.css +11 -0
  214. package/dist/tokens/components/flex.css +8 -0
  215. package/dist/tokens/components/navigation.css +55 -0
  216. package/dist/tokens/components/shell.css +100 -5
  217. package/dist/tokens/components/table.css +14 -0
  218. package/dist/tokens/foundation.css +2 -0
  219. package/dist/tokens/semantic/layout.css +9 -0
  220. package/docs/CONSUMER-RULES.md +13 -0
  221. package/docs/DESIGN-AUTHORITY.md +43 -6
  222. package/docs/DEVELOPMENT.md +4 -3
  223. package/docs/FORMS.md +151 -6
  224. package/docs/FRAME-COVERAGE-REPORT.md +29 -16
  225. package/docs/README.md +1 -1
  226. package/docs/STANDARDS-vocabulary-tokens.md +1 -1
  227. package/docs/TESTING.md +15 -6
  228. package/docs/charts/cjk-category-axis.tsx +81 -0
  229. package/docs/data-display/card/index.tsx +22 -0
  230. package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
  231. package/docs/data-display/data-table/index.tsx +23 -0
  232. package/docs/data-display/descriptions.tsx +41 -0
  233. package/docs/data-display/list-row.tsx +6 -6
  234. package/docs/data-display/scroll-area.tsx +31 -25
  235. package/docs/data-display/table.tsx +104 -45
  236. package/docs/data-display/timeline.tsx +41 -0
  237. package/docs/data-entry/date-picker.tsx +85 -0
  238. package/docs/data-entry/date-range-picker.tsx +26 -0
  239. package/docs/data-entry/form-dynamic-fields.tsx +199 -0
  240. package/docs/data-entry/form.tsx +74 -4
  241. package/docs/data-entry/input-otp.tsx +24 -0
  242. package/docs/data-entry/input.tsx +46 -1
  243. package/docs/data-entry/month-range-picker.tsx +1 -1
  244. package/docs/data-entry/select.tsx +27 -0
  245. package/docs/data-entry/switch.tsx +41 -0
  246. package/docs/data-entry/textarea.tsx +38 -0
  247. package/docs/data-entry/time-picker.tsx +85 -1
  248. package/docs/data-entry/time-range-picker.tsx +55 -0
  249. package/docs/data-entry/transfer.tsx +17 -0
  250. package/docs/data-entry/upload.tsx +56 -12
  251. package/docs/feedback/tooltip.tsx +1 -1
  252. package/docs/general/activity.tsx +2 -2
  253. package/docs/general/button/index.tsx +14 -1
  254. package/docs/general/typography.tsx +14 -1
  255. package/docs/layout/app-launcher.tsx +195 -0
  256. package/docs/layout/app-shell-arrangements.tsx +5 -5
  257. package/docs/layout/app-shell.tsx +11 -0
  258. package/docs/layout/flex.tsx +50 -0
  259. package/docs/layout/responsive-grid.tsx +21 -1
  260. package/docs/layout/topbar.tsx +5 -9
  261. package/docs/navigation/app-setting-picker.tsx +11 -0
  262. package/docs/navigation/breadcrumb.tsx +48 -0
  263. package/docs/navigation/dropdown-menu.tsx +21 -0
  264. package/docs/navigation/pagination.tsx +52 -0
  265. package/docs/navigation/steps.tsx +37 -0
  266. package/docs/navigation/tabs.tsx +97 -1
  267. package/docs/query/button-refetch.tsx +1 -0
  268. package/docs/showcase/settings-security-mfa.tsx +3 -3
  269. package/package.json +24 -4
  270. package/scripts/_agent-setup.mjs +76 -9
  271. package/scripts/init-guinea-pig.mjs +26 -4
  272. package/scripts/ui-audit.mjs +243 -30
  273. package/scripts/visual-audit.mjs +45 -7
@@ -1,5 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { type MenuItemRenderProps, type PopoverProps, type PopoverRenderProps } from "react-aria-components";
3
+ import type { DropdownMenuPlacementProp } from "../../props/components/navigation.prop.js";
4
+ export type { DropdownMenuPlacementProp } from "../../props/components/navigation.prop.js";
3
5
  /**
4
6
  * Dịch trạng thái item của RAC sang bộ `data-*` mà Radix phát ra và CSS của kho đang bám.
5
7
  *
@@ -98,7 +100,17 @@ type DropdownMenuSubProps = React.PropsWithChildren<DropdownMenuSubPropsOwn>;
98
100
  * popover — nên thứ tự `<SubTrigger/>` rồi `<SubContent/>` của Radix ánh xạ thẳng.
99
101
  */
100
102
  export declare function DropdownMenuSub({ children }: DropdownMenuSubProps): React.JSX.Element;
103
+ /**
104
+ * Width axis of the menu surface (gh#396) — the vocabulary `Select` already publishes, extended to
105
+ * the one member of the family that never got it. `"trigger"` matches the anchor, `"auto"` releases
106
+ * the floor and shrinks to the content, and `sm | md | lg` select the `--menu-content-width-*`
107
+ * ladder. Unset = today's `--dropdown-content-min-width`, so nothing moves.
108
+ */
109
+ type DropdownMenuContentWidth = "trigger" | "auto" | "sm" | "md" | "lg";
101
110
  interface DropdownMenuContentPropsOwn {
111
+ placement?: DropdownMenuPlacementProp;
112
+ arrow?: boolean;
113
+ width?: DropdownMenuContentWidth;
102
114
  className?: string;
103
115
  side?: "top" | "right" | "bottom" | "left";
104
116
  align?: "start" | "center" | "end";
@@ -125,7 +137,7 @@ type DropdownMenuContentProps = React.PropsWithChildren<DropdownMenuContentProps
125
137
  * NGAY ở ý định đóng: đúng lớp lỗi gh#385, đã sửa ở thượng nguồn. Phép đo là
126
138
  * `src/components/__tests__/overlay-inert-release-385.test.tsx`.
127
139
  */
128
- export declare function DropdownMenuContent({ children, className, side, align, sideOffset, alignOffset, avoidCollisions, collisionPadding, loop, hideWhenDetached, sticky, forceMount, }: DropdownMenuContentProps): React.JSX.Element;
140
+ export declare function DropdownMenuContent({ children, className, side, align, sideOffset, placement, arrow, width, alignOffset, avoidCollisions, collisionPadding, loop, hideWhenDetached, sticky, forceMount, }: DropdownMenuContentProps): React.JSX.Element;
129
141
  interface DropdownMenuItemPropsOwn {
130
142
  className?: string;
131
143
  inset?: boolean;
@@ -150,6 +162,17 @@ type DropdownMenuLabelProps = React.PropsWithChildren<DropdownMenuLabelPropsOwn>
150
162
  *
151
163
  * `Header` không đi qua `useRenderProps`, nên `props.children` trong `render` CHÍNH là children của
152
164
  * consumer — không có `Provider` chen vào như ở `MenuItem`. `Slot` vì thế nhận thẳng gói props.
165
+ *
166
+ * NHƯNG PHẢI RENDER RA `<div>`, KHÔNG PHẢI `<header>`. `<header>` mang vai trò ngầm `banner`, và
167
+ * `banner` không nằm trong danh sách con hợp lệ của `role="menu"` (axe: aria-required-children,
168
+ * ARIA 1.2 — menu chỉ nhận menuitem / menuitemcheckbox / menuitemradio / group / separator). Radix
169
+ * dựng `<div>`, vai trò `generic`, nên nó không bao giờ vấp lỗi này.
170
+ *
171
+ * `Header` vẫn được dùng chứ không thay bằng `<div>` trần: bộ dựng collection của RAC chỉ nhận các
172
+ * nút nó biết, một phần tử lạ đặt thẳng trong `Menu` sẽ bị nó bỏ. Nên giữ nút, đổi thẻ.
173
+ *
174
+ * Lỗi này ẩn suốt vì helper a11y dùng chung soi container của lần render, còn menu thì portal ra
175
+ * `document.body` — phép kiểm mang tên "open, fully-composed menu" thực chất soi một hộp rỗng.
153
176
  */
154
177
  export declare function DropdownMenuLabel({ children, className, inset, asChild }: DropdownMenuLabelProps): React.JSX.Element;
155
178
  interface DropdownMenuSeparatorProps {
@@ -166,6 +189,12 @@ interface DropdownMenuCheckboxItemPropsOwn {
166
189
  asChild?: boolean;
167
190
  }
168
191
  type DropdownMenuCheckboxItemProps = React.PropsWithChildren<DropdownMenuCheckboxItemPropsOwn>;
192
+ /**
193
+ * Ở Radix mỗi CheckboxItem tự giữ `checked`. Ở RAC không có `isSelected` trên item: `aria-checked`
194
+ * và `role="menuitemcheckbox"` chỉ xuất hiện khi collection BAO QUANH khai báo `selectionMode`.
195
+ * Nên mỗi hàng độc lập được bọc trong một `MenuSection` một-phần-tử — đó là cái giá để giữ đúng
196
+ * vai trò ARIA mà consumer đang test.
197
+ */
169
198
  export declare function DropdownMenuCheckboxItem({ children, className, checked, onCheckedChange, disabled, textValue, asChild, }: DropdownMenuCheckboxItemProps): React.JSX.Element;
170
199
  interface DropdownMenuRadioItemPropsOwn {
171
200
  className?: string;
@@ -202,4 +231,3 @@ interface DropdownMenuSubContentPropsOwn {
202
231
  type DropdownMenuSubContentProps = React.PropsWithChildren<DropdownMenuSubContentPropsOwn>;
203
232
  export declare function DropdownMenuSubContent({ children, className, align, alignOffset, sideOffset, avoidCollisions, collisionPadding, loop, forceMount, hideWhenDetached, sticky, }: DropdownMenuSubContentProps): React.JSX.Element;
204
233
  export declare const DropdownMenuShortcut: ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => React.JSX.Element;
205
- export {};
@@ -1,8 +1,10 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useOverlayPortalContainer } from "../../lib/overlay-portal.js";
3
4
  import * as React from "react";
4
5
  import {
5
6
  Header,
7
+ Button as AriaButton,
6
8
  Menu,
7
9
  MenuItem,
8
10
  MenuSection,
@@ -11,11 +13,20 @@ import {
11
13
  Popover,
12
14
  Pressable,
13
15
  Separator,
16
+ OverlayArrow,
14
17
  SubmenuTrigger
15
18
  } from "react-aria-components";
16
19
  import { Check, ChevronRight } from "lucide-react";
17
20
  import { cn } from "../../lib/utils.js";
18
21
  import { Slot } from "../../lib/slot.js";
22
+ const DROPDOWN_MENU_PLACEMENT = {
23
+ top: { side: "top", align: "center" },
24
+ topStart: { side: "top", align: "start" },
25
+ topEnd: { side: "top", align: "end" },
26
+ bottom: { side: "bottom", align: "center" },
27
+ bottomStart: { side: "bottom", align: "start" },
28
+ bottomEnd: { side: "bottom", align: "end" }
29
+ };
19
30
  function borrowedTag(children, asChild) {
20
31
  return asChild ? React.Children.only(children) : null;
21
32
  }
@@ -69,7 +80,16 @@ function DropdownMenuTrigger({ asChild, children, ...props }) {
69
80
  "data-state": dataState
70
81
  }) });
71
82
  }
72
- return /* @__PURE__ */ jsx(Pressable, { children: /* @__PURE__ */ jsx("button", { type: "button", "data-slot": "dropdown-menu-trigger", "data-state": dataState, ...props, children }) });
83
+ return /* @__PURE__ */ jsx(
84
+ AriaButton,
85
+ {
86
+ ...props,
87
+ isDisabled: props.disabled,
88
+ "data-slot": "dropdown-menu-trigger",
89
+ "data-state": dataState,
90
+ children
91
+ }
92
+ );
73
93
  }
74
94
  function DropdownMenuPortal({ children }) {
75
95
  return /* @__PURE__ */ jsx(Fragment, { children });
@@ -110,6 +130,9 @@ function DropdownMenuContent({
110
130
  side,
111
131
  align,
112
132
  sideOffset = 4,
133
+ placement,
134
+ arrow,
135
+ width,
113
136
  alignOffset,
114
137
  avoidCollisions,
115
138
  collisionPadding,
@@ -122,12 +145,15 @@ function DropdownMenuContent({
122
145
  void sticky;
123
146
  void forceMount;
124
147
  const { modal } = React.useContext(DropdownMenuModalContext);
125
- return /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsx(
148
+ const anchor = placement ? DROPDOWN_MENU_PLACEMENT[placement] : void 0;
149
+ const overlayPortalContainer = useOverlayPortalContainer();
150
+ return /* @__PURE__ */ jsx(DropdownMenuPortal, { children: /* @__PURE__ */ jsxs(
126
151
  Popover,
127
152
  {
153
+ UNSTABLE_portalContainer: overlayPortalContainer,
128
154
  "data-slot": "dropdown-menu-content",
129
155
  isNonModal: !modal,
130
- placement: toPlacement(side, align),
156
+ placement: toPlacement(side ?? anchor?.side, align ?? anchor?.align),
131
157
  offset: sideOffset,
132
158
  crossOffset: alignOffset,
133
159
  shouldFlip: avoidCollisions,
@@ -138,9 +164,30 @@ function DropdownMenuContent({
138
164
  ),
139
165
  render: (props, state) => (
140
166
  // `role={undefined}`: một menu không phải một dialog — xem radixSurfaceState.
141
- /* @__PURE__ */ jsx("div", { ...props, role: void 0, ...radixSurfaceState(state) })
167
+ /* @__PURE__ */ jsx(
168
+ "div",
169
+ {
170
+ ...props,
171
+ role: void 0,
172
+ ...radixSurfaceState(state),
173
+ "data-align": align ?? anchor?.align ?? "center",
174
+ "data-width": width
175
+ }
176
+ )
142
177
  ),
143
- children: /* @__PURE__ */ jsx(Menu, { shouldFocusWrap: loop, children })
178
+ children: [
179
+ /* @__PURE__ */ jsx(Menu, { shouldFocusWrap: loop, children }),
180
+ arrow ? /* @__PURE__ */ jsx(OverlayArrow, { children: /* @__PURE__ */ jsx(
181
+ "svg",
182
+ {
183
+ "data-slot": "dropdown-menu-arrow",
184
+ className: "ui-dropdown-menu-arrow",
185
+ viewBox: "0 0 10 5",
186
+ "aria-hidden": "true",
187
+ children: /* @__PURE__ */ jsx("path", { d: "M0 0 L5 5 L10 0 Z" })
188
+ }
189
+ ) }) : null
190
+ ]
144
191
  }
145
192
  ) });
146
193
  }
@@ -195,7 +242,12 @@ function DropdownMenuLabel({ children, className, inset, asChild }) {
195
242
  {
196
243
  ...props
197
244
  }
198
- ) : void 0,
245
+ ) : (props) => /* @__PURE__ */ jsx(
246
+ "div",
247
+ {
248
+ ...props
249
+ }
250
+ ),
199
251
  children
200
252
  }
201
253
  );
@@ -209,7 +261,6 @@ function DropdownMenuSeparator({ className }) {
209
261
  }
210
262
  );
211
263
  }
212
- const CHECKBOX_KEY = "checked-item";
213
264
  function DropdownMenuCheckboxItem({
214
265
  children,
215
266
  className,
@@ -219,20 +270,21 @@ function DropdownMenuCheckboxItem({
219
270
  textValue,
220
271
  asChild
221
272
  }) {
273
+ const checkboxKey = React.useId();
222
274
  const tag = borrowedTag(children, asChild);
223
275
  return /* @__PURE__ */ jsx(
224
276
  MenuSection,
225
277
  {
226
278
  selectionMode: "multiple",
227
279
  shouldCloseOnSelect: true,
228
- selectedKeys: checked ? [CHECKBOX_KEY] : [],
280
+ selectedKeys: checked ? [checkboxKey] : [],
229
281
  onSelectionChange: (keys) => {
230
- onCheckedChange?.(keys === "all" ? true : keys.has(CHECKBOX_KEY));
282
+ onCheckedChange?.(keys === "all" ? true : keys.has(checkboxKey));
231
283
  },
232
284
  children: /* @__PURE__ */ jsx(
233
285
  MenuItem,
234
286
  {
235
- id: CHECKBOX_KEY,
287
+ id: checkboxKey,
236
288
  isDisabled: disabled,
237
289
  textValue,
238
290
  className: cn("ui-dropdown-menu-checkbox-item", className),
@@ -335,9 +387,11 @@ function DropdownMenuSubContent({
335
387
  void forceMount;
336
388
  void hideWhenDetached;
337
389
  void sticky;
390
+ const overlayPortalContainer = useOverlayPortalContainer();
338
391
  return /* @__PURE__ */ jsx(
339
392
  Popover,
340
393
  {
394
+ UNSTABLE_portalContainer: overlayPortalContainer,
341
395
  "data-slot": "dropdown-menu-sub-content",
342
396
  placement: align ? toPlacement("right", align) : void 0,
343
397
  offset: sideOffset,
@@ -350,7 +404,15 @@ function DropdownMenuSubContent({
350
404
  ),
351
405
  render: (props, state) => (
352
406
  // `role={undefined}`: một menu không phải một dialog — xem radixSurfaceState.
353
- /* @__PURE__ */ jsx("div", { ...props, role: void 0, ...radixSurfaceState(state) })
407
+ /* @__PURE__ */ jsx(
408
+ "div",
409
+ {
410
+ ...props,
411
+ role: void 0,
412
+ ...radixSurfaceState(state),
413
+ "data-align": align ?? "center"
414
+ }
415
+ )
354
416
  ),
355
417
  children: /* @__PURE__ */ jsx(Menu, { shouldFocusWrap: loop, children })
356
418
  }
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import type { PaginationProp } from "../../props/components/navigation.prop.js";
3
- export type { PaginationProp, PaginationProp as PaginationProps, } from "../../props/components/navigation.prop.js";
3
+ export type { PaginationProp, PaginationProp as PaginationProps, PaginationSizeProp, PaginationAlignProp, } from "../../props/components/navigation.prop.js";
4
4
  declare const PaginationContent: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLUListElement> & React.RefAttributes<HTMLUListElement>>;
5
5
  declare const PaginationItem: React.ForwardRefExoticComponent<React.LiHTMLAttributes<HTMLLIElement> & React.RefAttributes<HTMLLIElement>>;
6
6
  declare const PaginationLink: React.ForwardRefExoticComponent<Omit<Omit<React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, "ref">, "type"> & {
@@ -22,5 +22,5 @@ declare const PaginationNext: React.ForwardRefExoticComponent<Omit<Omit<React.De
22
22
  disabled?: boolean;
23
23
  href?: string;
24
24
  } & React.RefAttributes<HTMLButtonElement>>;
25
- export declare function Pagination({ ariaLabel, value, total, pageSize, pageSizeOptions, showSizeChanger, showTotal, hideOnSinglePage, simple, disabled, className, onValueChange, }: PaginationProp): React.JSX.Element | null;
25
+ export declare function Pagination({ ariaLabel, value, total, pageSize, pageSizeOptions, showSizeChanger, showTotal, hideOnSinglePage, simple, showQuickJumper, size, align, responsive, disabled, className, onValueChange, }: PaginationProp): React.JSX.Element | null;
26
26
  export { PaginationContent, PaginationItem, PaginationLink, PaginationEllipsis, PaginationPrevious, PaginationNext, };
@@ -3,9 +3,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
5
5
  import { useTranslation } from "../../i18n/use-translation.js";
6
- import { useScrollableRegionTabIndex } from "../../lib/hooks.js";
6
+ import { useIsMobile, useScrollableRegionTabIndex } from "../../lib/hooks.js";
7
7
  import { cn } from "../../lib/utils.js";
8
8
  import { Button } from "../general/button.js";
9
+ import { Form } from "../data-entry/form.js";
10
+ import { FormField } from "../data-entry/form-field.js";
11
+ import { Input } from "../data-entry/input.js";
9
12
  import {
10
13
  Select,
11
14
  SelectContent,
@@ -110,19 +113,33 @@ function Pagination({
110
113
  showTotal,
111
114
  hideOnSinglePage = true,
112
115
  simple,
116
+ showQuickJumper,
117
+ size = "md",
118
+ align = "end",
119
+ responsive = true,
113
120
  disabled,
114
121
  className,
115
122
  onValueChange
116
123
  }) {
117
124
  const { t } = useTranslation();
125
+ const jumperId = React.useId();
126
+ const [jumperDraft, setJumperDraft] = React.useState("");
127
+ const isNarrowViewport = useIsMobile();
118
128
  const navLabel = ariaLabel ?? t("navigation.pagination.ariaLabel");
119
129
  const totalPages = Math.max(1, Math.ceil(total / pageSize));
120
130
  const safeCurrent = Math.min(Math.max(1, value), totalPages);
121
131
  const pages = buildPageRange(safeCurrent, totalPages);
122
- const go = (page, size = pageSize) => {
132
+ const compact = Boolean(simple) || responsive && isNarrowViewport;
133
+ const go = (page, size2 = pageSize) => {
123
134
  if (disabled) return;
124
- const nextPage = Math.min(Math.max(1, page), Math.max(1, Math.ceil(total / size)));
125
- onValueChange?.(nextPage, size);
135
+ const nextPage = Math.min(Math.max(1, page), Math.max(1, Math.ceil(total / size2)));
136
+ onValueChange?.(nextPage, size2);
137
+ };
138
+ const commitJump = () => {
139
+ const parsed = Number.parseInt(jumperDraft, 10);
140
+ setJumperDraft("");
141
+ if (!Number.isFinite(parsed)) return;
142
+ go(parsed);
126
143
  };
127
144
  const totalLabel = typeof showTotal === "function" ? showTotal(total, [
128
145
  total === 0 ? 0 : (safeCurrent - 1) * pageSize + 1,
@@ -130,96 +147,151 @@ function Pagination({
130
147
  ]) : showTotal ? t("navigation.pagination.total", { total }) : null;
131
148
  if (total <= 0) return null;
132
149
  if (hideOnSinglePage && totalPages <= 1) return null;
133
- if (simple) {
134
- return /* @__PURE__ */ jsxs("nav", { "aria-label": navLabel, "data-simple": "true", className: cn("ui-pagination", className), children: [
135
- totalLabel && /* @__PURE__ */ jsx("span", { className: "ui-pagination-total", children: totalLabel }),
136
- /* @__PURE__ */ jsx(
137
- Button,
138
- {
139
- type: "button",
140
- variant: "outline",
141
- size: "sm",
142
- disabled: Boolean(disabled) || safeCurrent <= 1,
143
- "aria-label": t("navigation.pagination.prev"),
144
- onClick: () => go(safeCurrent - 1),
145
- children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
146
- }
147
- ),
148
- /* @__PURE__ */ jsxs("span", { className: "ui-pagination-count", children: [
149
- safeCurrent,
150
- " / ",
151
- totalPages
152
- ] }),
153
- /* @__PURE__ */ jsx(
154
- Button,
155
- {
156
- type: "button",
157
- variant: "outline",
158
- size: "sm",
159
- disabled: Boolean(disabled) || safeCurrent >= totalPages,
160
- "aria-label": t("navigation.pagination.next"),
161
- onClick: () => go(safeCurrent + 1),
162
- children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
163
- }
164
- )
165
- ] });
166
- }
167
- return /* @__PURE__ */ jsxs("nav", { "aria-label": navLabel, className: cn("ui-pagination", className), children: [
168
- totalLabel && /* @__PURE__ */ jsx("span", { className: "ui-pagination-total", children: totalLabel }),
169
- showSizeChanger && /* @__PURE__ */ jsxs(
170
- Select,
150
+ const goButton = showQuickJumper && typeof showQuickJumper === "object" ? showQuickJumper.goButton : void 0;
151
+ const quickJumper = showQuickJumper ? /* @__PURE__ */ jsxs("div", { className: "ui-pagination-jumper", "data-slot": "pagination-jumper", children: [
152
+ /* @__PURE__ */ jsx(Form, { asChild: true, layout: "horizontal", collapseBelow: false, children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
153
+ FormField,
154
+ {
155
+ id: jumperId,
156
+ label: t("navigation.pagination.jumpTo"),
157
+ layout: "horizontal",
158
+ labelWidth: "auto",
159
+ controlWidth: "auto",
160
+ children: /* @__PURE__ */ jsx(
161
+ Input,
162
+ {
163
+ id: jumperId,
164
+ size,
165
+ type: "number",
166
+ inputMode: "numeric",
167
+ min: 1,
168
+ max: totalPages,
169
+ disabled,
170
+ className: "ui-pagination-jumper-input w-[var(--pagination-jumper-width)]",
171
+ value: jumperDraft,
172
+ onChange: (event) => setJumperDraft(event.target.value),
173
+ onKeyDown: (event) => {
174
+ if (event.key !== "Enter") return;
175
+ event.preventDefault();
176
+ commitJump();
177
+ }
178
+ }
179
+ )
180
+ }
181
+ ) }) }),
182
+ goButton ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", disabled, onClick: commitJump, children: goButton }) : null
183
+ ] }) : null;
184
+ if (compact) {
185
+ return /* @__PURE__ */ jsxs(
186
+ "nav",
171
187
  {
172
- value: String(pageSize),
173
- onValueChange: (v) => go(1, Number(v)),
174
- disabled,
188
+ "aria-label": navLabel,
189
+ "data-simple": "true",
190
+ "data-size": size,
191
+ "data-align": align,
192
+ className: cn("ui-pagination", className),
175
193
  children: [
194
+ totalLabel && /* @__PURE__ */ jsx("span", { className: "ui-pagination-total", children: totalLabel }),
176
195
  /* @__PURE__ */ jsx(
177
- SelectTrigger,
196
+ Button,
178
197
  {
179
- className: "ui-pagination-size-trigger w-max min-w-[var(--pagination-size-width)]",
180
- "aria-label": t("navigation.pagination.pageSize"),
181
- children: /* @__PURE__ */ jsx(SelectValue, { children: t("navigation.pagination.pageSizeTrigger", { size: pageSize }) })
198
+ type: "button",
199
+ variant: "outline",
200
+ size: "sm",
201
+ disabled: Boolean(disabled) || safeCurrent <= 1,
202
+ "aria-label": t("navigation.pagination.prev"),
203
+ onClick: () => go(safeCurrent - 1),
204
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
182
205
  }
183
206
  ),
184
- /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((size) => /* @__PURE__ */ jsx(SelectItem, { value: String(size), children: size }, size)) })
207
+ /* @__PURE__ */ jsxs("span", { className: "ui-pagination-count", children: [
208
+ safeCurrent,
209
+ " / ",
210
+ totalPages
211
+ ] }),
212
+ /* @__PURE__ */ jsx(
213
+ Button,
214
+ {
215
+ type: "button",
216
+ variant: "outline",
217
+ size: "sm",
218
+ disabled: Boolean(disabled) || safeCurrent >= totalPages,
219
+ "aria-label": t("navigation.pagination.next"),
220
+ onClick: () => go(safeCurrent + 1),
221
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
222
+ }
223
+ ),
224
+ quickJumper
185
225
  ]
186
226
  }
187
- ),
188
- /* @__PURE__ */ jsxs(PaginationContent, { children: [
189
- /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
190
- PaginationPrevious,
191
- {
192
- "aria-label": t("navigation.pagination.prev"),
193
- onClick: () => go(safeCurrent - 1),
194
- disabled: Boolean(disabled) || safeCurrent <= 1,
195
- children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
196
- }
197
- ) }),
198
- pages.map(
199
- (page, index) => page === "ellipsis" ? /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, `e-${index}`) : /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
200
- PaginationLink,
227
+ );
228
+ }
229
+ return /* @__PURE__ */ jsxs(
230
+ "nav",
231
+ {
232
+ "aria-label": navLabel,
233
+ "data-size": size,
234
+ "data-align": align,
235
+ className: cn("ui-pagination", className),
236
+ children: [
237
+ totalLabel && /* @__PURE__ */ jsx("span", { className: "ui-pagination-total", children: totalLabel }),
238
+ showSizeChanger && /* @__PURE__ */ jsxs(
239
+ Select,
201
240
  {
202
- isActive: page === safeCurrent,
203
- "aria-label": t("navigation.pagination.page", { page }),
204
- onClick: () => {
205
- if (!disabled) go(page);
206
- },
241
+ value: String(pageSize),
242
+ onValueChange: (v) => go(1, Number(v)),
207
243
  disabled,
208
- children: page
244
+ children: [
245
+ /* @__PURE__ */ jsx(
246
+ SelectTrigger,
247
+ {
248
+ className: "ui-pagination-size-trigger w-max min-w-[var(--pagination-size-width)]",
249
+ "aria-label": t("navigation.pagination.pageSize"),
250
+ children: /* @__PURE__ */ jsx(SelectValue, { children: t("navigation.pagination.pageSizeTrigger", { size: pageSize }) })
251
+ }
252
+ ),
253
+ /* @__PURE__ */ jsx(SelectContent, { children: pageSizeOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: String(option), children: option }, option)) })
254
+ ]
209
255
  }
210
- ) }, page)
211
- ),
212
- /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
213
- PaginationNext,
214
- {
215
- "aria-label": t("navigation.pagination.next"),
216
- onClick: () => go(safeCurrent + 1),
217
- disabled: Boolean(disabled) || safeCurrent >= totalPages,
218
- children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
219
- }
220
- ) })
221
- ] })
222
- ] });
256
+ ),
257
+ /* @__PURE__ */ jsxs(PaginationContent, { children: [
258
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
259
+ PaginationPrevious,
260
+ {
261
+ "aria-label": t("navigation.pagination.prev"),
262
+ onClick: () => go(safeCurrent - 1),
263
+ disabled: Boolean(disabled) || safeCurrent <= 1,
264
+ children: /* @__PURE__ */ jsx(ChevronLeft, { "aria-hidden": "true" })
265
+ }
266
+ ) }),
267
+ pages.map(
268
+ (page, index) => page === "ellipsis" ? /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(PaginationEllipsis, {}) }, `e-${index}`) : /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
269
+ PaginationLink,
270
+ {
271
+ isActive: page === safeCurrent,
272
+ "aria-label": t("navigation.pagination.page", { page }),
273
+ onClick: () => {
274
+ if (!disabled) go(page);
275
+ },
276
+ disabled,
277
+ children: page
278
+ }
279
+ ) }, page)
280
+ ),
281
+ /* @__PURE__ */ jsx(PaginationItem, { children: /* @__PURE__ */ jsx(
282
+ PaginationNext,
283
+ {
284
+ "aria-label": t("navigation.pagination.next"),
285
+ onClick: () => go(safeCurrent + 1),
286
+ disabled: Boolean(disabled) || safeCurrent >= totalPages,
287
+ children: /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" })
288
+ }
289
+ ) })
290
+ ] }),
291
+ quickJumper
292
+ ]
293
+ }
294
+ );
223
295
  }
224
296
  export {
225
297
  Pagination,
@@ -1,4 +1,4 @@
1
1
  import * as React from "react";
2
2
  import type { StepsProp } from "../../props/components/navigation.prop.js";
3
- export type { StepsProp, StepsProp as StepsProps, StepItemProp, StepStatusProp, StepsSeparatorProp, } from "../../props/components/navigation.prop.js";
4
- export declare function Steps({ items, value: current, defaultValue, status: currentStatus, orientation, type, size, titlePlacement, separator, onValueChange, className, }: StepsProp): React.JSX.Element;
3
+ export type { StepsProp, StepsProp as StepsProps, StepItemProp, StepStatusProp, StepsSeparatorProp, StepsTypeProp, } from "../../props/components/navigation.prop.js";
4
+ export declare function Steps({ items, value: current, defaultValue, status: currentStatus, orientation, type, size, titlePlacement, separator, percent, onValueChange, className, }: StepsProp): React.JSX.Element;
@@ -4,6 +4,10 @@ import { ArrowRight, Check, ChevronRight, Circle, Loader2, X } from "lucide-reac
4
4
  import { useTranslation } from "../../i18n/use-translation.js";
5
5
  import { cn } from "../../lib/utils.js";
6
6
  import { controlIconClass } from "../../lib/control-styles.js";
7
+ function boundStepPercent(percent) {
8
+ if (!Number.isFinite(percent)) return 0;
9
+ return Math.min(100, Math.max(0, percent));
10
+ }
7
11
  function resolveStepStatus(index, current, itemStatus, currentStatus) {
8
12
  if (itemStatus) return itemStatus;
9
13
  if (index < current) return "finish";
@@ -44,6 +48,7 @@ function Steps({
44
48
  size = "md",
45
49
  titlePlacement = "horizontal",
46
50
  separator = "chevron",
51
+ percent,
47
52
  onValueChange,
48
53
  className
49
54
  }) {
@@ -52,11 +57,16 @@ function Steps({
52
57
  const isVertical = orientation === "vertical";
53
58
  const compact = size === "sm";
54
59
  const inline = type === "inline";
60
+ const navigation = type === "navigation";
55
61
  const SeparatorIcon = separator === "arrow" ? ArrowRight : ChevronRight;
62
+ const showPercent = percent !== void 0 && !inline;
63
+ const boundedPercent = boundStepPercent(percent ?? 0);
64
+ const progressRatio = boundedPercent / 100;
56
65
  return /* @__PURE__ */ jsx(
57
66
  "ol",
58
67
  {
59
68
  "data-direction": inline ? void 0 : isVertical ? "vertical" : "horizontal",
69
+ "data-type": type,
60
70
  className: cn("flex w-full", inline ? "ui-steps-inline" : "ui-steps-list", className),
61
71
  "aria-label": t("navigation.steps.ariaLabel"),
62
72
  children: items.map((item, index) => {
@@ -80,7 +90,19 @@ function Steps({
80
90
  /* @__PURE__ */ jsx("span", { className: "ui-steps-inline-title", children: item.title }),
81
91
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: statusLabel })
82
92
  ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
83
- /* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type }),
93
+ showPercent && absoluteIndex === current ? /* @__PURE__ */ jsx(
94
+ "span",
95
+ {
96
+ className: "ui-steps-progress",
97
+ role: "progressbar",
98
+ "aria-valuenow": boundedPercent,
99
+ "aria-valuemin": 0,
100
+ "aria-valuemax": 100,
101
+ "aria-label": t("navigation.steps.percentLabel"),
102
+ style: { "--steps-progress-ratio": progressRatio },
103
+ children: /* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type })
104
+ }
105
+ ) : /* @__PURE__ */ jsx(StepIcon, { status: stepStatus, icon: item.icon, type }),
84
106
  /* @__PURE__ */ jsxs("div", { className: "ui-steps-text", children: [
85
107
  /* @__PURE__ */ jsx(
86
108
  "div",
@@ -101,7 +123,7 @@ function Steps({
101
123
  "aria-current": isCurrent ? "step" : void 0,
102
124
  "data-direction": inline ? void 0 : isVertical ? "vertical" : "horizontal",
103
125
  "data-title-placement": titlePlacement,
104
- "data-connector": !isVertical && !inline && index < items.length - 1 ? "" : void 0,
126
+ "data-connector": !isVertical && !inline && !navigation && index < items.length - 1 ? "" : void 0,
105
127
  className: cn(!inline && "flex-1", inline ? "ui-steps-inline-item" : "ui-steps-item"),
106
128
  "data-status": stepStatus,
107
129
  children: [
@@ -116,10 +138,13 @@ function Steps({
116
138
  children: stepInner
117
139
  }
118
140
  ) : /* @__PURE__ */ jsx("span", { "data-direction": stepDirection, className: stepClassName, children: stepInner }),
119
- inline && index < items.length - 1 ? /* @__PURE__ */ jsx(
141
+ (inline || navigation && !isVertical) && index < items.length - 1 ? /* @__PURE__ */ jsx(
120
142
  SeparatorIcon,
121
143
  {
122
- className: "ui-steps-inline-separator rtl:rotate-180",
144
+ className: cn(
145
+ inline ? "ui-steps-inline-separator" : "ui-steps-nav-separator",
146
+ "rtl:rotate-180"
147
+ ),
123
148
  "aria-hidden": "true"
124
149
  }
125
150
  ) : null