@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.
- package/README.md +8 -2
- package/dist/app/app-provider.js +37 -21
- package/dist/app/index.d.ts +2 -0
- package/dist/app/index.js +2 -0
- package/dist/app/storage.d.ts +17 -0
- package/dist/app/storage.js +28 -0
- package/dist/app/theme-axes.d.ts +2 -0
- package/dist/app/theme-axes.js +45 -0
- package/dist/components/charts/chart-cartesian.d.ts +2 -1
- package/dist/components/charts/chart-cartesian.js +52 -3
- package/dist/components/charts/chart-category-axis.d.ts +55 -0
- package/dist/components/charts/chart-category-axis.js +93 -0
- package/dist/components/charts/chart-frame.d.ts +10 -1
- package/dist/components/charts/chart-frame.js +19 -3
- package/dist/components/charts/compact-bar-trend.d.ts +1 -1
- package/dist/components/charts/compact-bar-trend.js +2 -0
- package/dist/components/charts/pie-chart.d.ts +1 -1
- package/dist/components/charts/pie-chart.js +12 -1
- package/dist/components/charts/recharts-peer.d.ts +49 -0
- package/dist/components/charts/recharts-peer.js +45 -0
- package/dist/components/data-display/card.d.ts +12 -1
- package/dist/components/data-display/card.js +22 -4
- package/dist/components/data-display/code-block.js +6 -2
- package/dist/components/data-display/data-table.d.ts +39 -4
- package/dist/components/data-display/data-table.js +802 -270
- package/dist/components/data-display/descriptions.d.ts +27 -6
- package/dist/components/data-display/descriptions.js +58 -17
- package/dist/components/data-display/index.d.ts +2 -0
- package/dist/components/data-display/index.js +2 -0
- package/dist/components/data-display/list-row.d.ts +10 -1
- package/dist/components/data-display/list-row.js +7 -1
- package/dist/components/data-display/popover.d.ts +9 -3
- package/dist/components/data-display/popover.js +65 -11
- package/dist/components/data-display/range-timeline.d.ts +38 -0
- package/dist/components/data-display/range-timeline.js +161 -0
- package/dist/components/data-display/scroll-area.js +13 -2
- package/dist/components/data-display/service-launcher-card.js +14 -12
- package/dist/components/data-display/table.d.ts +71 -3
- package/dist/components/data-display/table.js +56 -18
- package/dist/components/data-display/tree-list.js +4 -9
- package/dist/components/data-entry/calendar.d.ts +2 -2
- package/dist/components/data-entry/calendar.js +23 -3
- package/dist/components/data-entry/cascader.d.ts +1 -1
- package/dist/components/data-entry/cascader.js +188 -24
- package/dist/components/data-entry/color-picker.d.ts +1 -1
- package/dist/components/data-entry/color-picker.js +17 -5
- package/dist/components/data-entry/control-appearance.d.ts +64 -0
- package/dist/components/data-entry/control-appearance.js +39 -0
- package/dist/components/data-entry/control-surface.d.ts +61 -0
- package/dist/components/data-entry/control-surface.js +39 -0
- package/dist/components/data-entry/date-picker.d.ts +1 -1
- package/dist/components/data-entry/date-picker.js +344 -113
- package/dist/components/data-entry/date-range-picker.d.ts +1 -1
- package/dist/components/data-entry/date-range-picker.js +278 -140
- package/dist/components/data-entry/form-field.d.ts +1 -1
- package/dist/components/data-entry/form-field.js +39 -4
- package/dist/components/data-entry/form.d.ts +4 -0
- package/dist/components/data-entry/form.js +4 -2
- package/dist/components/data-entry/index.d.ts +7 -3
- package/dist/components/data-entry/index.js +10 -1
- package/dist/components/data-entry/input-otp.d.ts +1 -1
- package/dist/components/data-entry/input.d.ts +12 -34
- package/dist/components/data-entry/input.js +92 -24
- package/dist/components/data-entry/month-picker.d.ts +1 -1
- package/dist/components/data-entry/month-picker.js +47 -10
- package/dist/components/data-entry/month-range-picker.d.ts +1 -1
- package/dist/components/data-entry/month-range-picker.js +51 -11
- package/dist/components/data-entry/number-input.d.ts +7 -0
- package/dist/components/data-entry/number-input.js +147 -98
- package/dist/components/data-entry/password-input.d.ts +1 -1
- package/dist/components/data-entry/radio.d.ts +1 -1
- package/dist/components/data-entry/radio.js +61 -13
- package/dist/components/data-entry/search-input.d.ts +1 -1
- package/dist/components/data-entry/search-input.js +16 -2
- package/dist/components/data-entry/search-select.d.ts +2 -2
- package/dist/components/data-entry/search-select.js +209 -78
- package/dist/components/data-entry/select.d.ts +22 -4
- package/dist/components/data-entry/select.js +215 -163
- package/dist/components/data-entry/slider.d.ts +9 -1
- package/dist/components/data-entry/slider.js +87 -9
- package/dist/components/data-entry/switch.d.ts +3 -0
- package/dist/components/data-entry/switch.js +29 -3
- package/dist/components/data-entry/textarea.d.ts +14 -56
- package/dist/components/data-entry/textarea.js +80 -33
- package/dist/components/data-entry/time-picker.d.ts +2 -2
- package/dist/components/data-entry/time-picker.js +333 -109
- package/dist/components/data-entry/time-range-picker.d.ts +5 -0
- package/dist/components/data-entry/time-range-picker.js +89 -0
- package/dist/components/data-entry/transfer.d.ts +1 -1
- package/dist/components/data-entry/transfer.js +86 -28
- package/dist/components/data-entry/tree-select.d.ts +1 -1
- package/dist/components/data-entry/tree-select.js +201 -113
- package/dist/components/data-entry/tree-utils.js +7 -14
- package/dist/components/data-entry/upload-files.d.ts +2 -0
- package/dist/components/data-entry/upload-files.js +31 -0
- package/dist/components/data-entry/upload-request.d.ts +4 -0
- package/dist/components/data-entry/upload-request.js +53 -0
- package/dist/components/data-entry/upload-types.d.ts +28 -0
- package/dist/components/data-entry/upload-types.js +2 -0
- package/dist/components/data-entry/upload.d.ts +2 -2
- package/dist/components/data-entry/upload.js +475 -115
- package/dist/components/feedback/dialog.js +19 -19
- package/dist/components/feedback/sheet.js +3 -0
- package/dist/components/feedback/tooltip.js +3 -0
- package/dist/components/general/button.d.ts +2 -1
- package/dist/components/general/button.js +7 -1
- package/dist/components/general/index.d.ts +1 -0
- package/dist/components/general/index.js +2 -0
- package/dist/components/general/typography.d.ts +3 -0
- package/dist/components/general/typography.js +15 -1
- package/dist/components/general/visually-hidden.d.ts +3 -0
- package/dist/components/general/visually-hidden.js +9 -0
- package/dist/components/layout/app-launcher.d.ts +34 -0
- package/dist/components/layout/app-launcher.js +261 -0
- package/dist/components/layout/app-shell.d.ts +3 -1
- package/dist/components/layout/app-shell.js +34 -14
- package/dist/components/layout/auth-shell.d.ts +1 -1
- package/dist/components/layout/auth-shell.js +2 -0
- package/dist/components/layout/breadcrumb.d.ts +14 -2
- package/dist/components/layout/breadcrumb.js +46 -4
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/flex.js +23 -2
- package/dist/components/layout/index.d.ts +3 -0
- package/dist/components/layout/index.js +5 -1
- package/dist/components/layout/org-switcher.js +20 -1
- package/dist/components/layout/page-container.d.ts +1 -1
- package/dist/components/layout/page-container.js +5 -3
- package/dist/components/layout/responsive-grid.d.ts +16 -2
- package/dist/components/layout/responsive-grid.js +29 -2
- package/dist/components/layout/sidebar.js +2 -1
- package/dist/components/layout/topbar-item.d.ts +3 -0
- package/dist/components/layout/topbar-item.js +18 -3
- package/dist/components/layout/topbar.d.ts +1 -1
- package/dist/components/layout/topbar.js +27 -6
- package/dist/components/navigation/dropdown-menu.d.ts +30 -2
- package/dist/components/navigation/dropdown-menu.js +73 -11
- package/dist/components/navigation/pagination.d.ts +2 -2
- package/dist/components/navigation/pagination.js +155 -83
- package/dist/components/navigation/steps.d.ts +2 -2
- package/dist/components/navigation/steps.js +29 -4
- package/dist/components/navigation/tabs.d.ts +5 -33
- package/dist/components/navigation/tabs.js +232 -64
- package/dist/components/ui/hover-card.js +3 -0
- package/dist/components/ui/input-otp.d.ts +26 -28
- package/dist/components/ui/input-otp.js +50 -7
- package/dist/components/ui/password-input.d.ts +36 -2
- package/dist/components/ui/password-input.js +27 -7
- package/dist/components/ui/rating.d.ts +25 -0
- package/dist/components/ui/rating.js +67 -27
- package/dist/components/ui/segmented.d.ts +9 -0
- package/dist/components/ui/segmented.js +17 -2
- package/dist/components/ui/separator.d.ts +4 -0
- package/dist/components/ui/separator.js +13 -0
- package/dist/components/ui/tag-input.d.ts +45 -0
- package/dist/components/ui/tag-input.js +109 -27
- package/dist/form/form-context.d.ts +29 -0
- package/dist/form/form-context.js +44 -4
- package/dist/form/form-field-array.d.ts +22 -0
- package/dist/form/form-field-array.js +50 -0
- package/dist/form/form-field-control.d.ts +2 -1
- package/dist/form/form-field-control.js +116 -40
- package/dist/form/form-root.d.ts +2 -1
- package/dist/form/form-root.js +142 -23
- package/dist/form/index.d.ts +3 -1
- package/dist/form/index.js +12 -1
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +3 -1
- package/dist/i18n/messages/en.json +59 -6
- package/dist/i18n/messages/ja.json +59 -6
- package/dist/i18n/messages/vi.json +59 -6
- package/dist/i18n/translate.d.ts +19 -0
- package/dist/i18n/translate.js +24 -0
- package/dist/inertia/index.d.ts +20 -0
- package/dist/inertia/index.js +60 -1
- package/dist/lib/control-styles.d.ts +25 -3
- package/dist/lib/control-styles.js +9 -3
- package/dist/lib/datetime/picker-format.d.ts +8 -0
- package/dist/lib/datetime/picker-format.js +54 -0
- package/dist/lib/overlay-portal.d.ts +18 -0
- package/dist/lib/overlay-portal.js +17 -0
- package/dist/props/components/app.prop.d.ts +13 -2
- package/dist/props/components/charts.prop.d.ts +21 -0
- package/dist/props/components/data-display.prop.d.ts +55 -4
- package/dist/props/components/data-entry.prop.d.ts +687 -43
- package/dist/props/components/form.prop.d.ts +142 -4
- package/dist/props/components/general.prop.d.ts +30 -1
- package/dist/props/components/index.d.ts +2 -2
- package/dist/props/components/layout.prop.d.ts +255 -8
- package/dist/props/components/navigation.prop.d.ts +113 -3
- package/dist/props/registry.d.ts +376 -10
- package/dist/props/registry.js +493 -9
- package/dist/props/vocabulary/data.prop.d.ts +179 -1
- package/dist/props/vocabulary/index.d.ts +4 -4
- package/dist/props/vocabulary/interaction.prop.d.ts +51 -2
- package/dist/props/vocabulary/navigation.prop.d.ts +40 -0
- package/dist/props/vocabulary/shared.prop.d.ts +33 -0
- package/dist/styles/badge-layout.css +2 -1
- package/dist/styles/card-layout.css +36 -5
- package/dist/styles/chart-layout.css +17 -1
- package/dist/styles/control.css +520 -14
- package/dist/styles/data-display-layout.css +248 -7
- package/dist/styles/data-entry-layout.css +13 -0
- package/dist/styles/layout.css +221 -4
- package/dist/styles/navigation-layout.css +230 -1
- package/dist/styles/shell-layout.css +690 -21
- package/dist/styles/table-layout.css +95 -6
- package/dist/styles/text-layout.css +5 -0
- package/dist/tokens/base.css +1 -0
- package/dist/tokens/components/badge.css +1 -0
- package/dist/tokens/components/chart.css +6 -0
- package/dist/tokens/components/control.css +81 -3
- package/dist/tokens/components/data-display.css +9 -0
- package/dist/tokens/components/descriptions.css +11 -0
- package/dist/tokens/components/flex.css +8 -0
- package/dist/tokens/components/navigation.css +55 -0
- package/dist/tokens/components/shell.css +100 -5
- package/dist/tokens/components/table.css +14 -0
- package/dist/tokens/foundation.css +2 -0
- package/dist/tokens/semantic/layout.css +9 -0
- package/docs/CONSUMER-RULES.md +13 -0
- package/docs/DESIGN-AUTHORITY.md +43 -6
- package/docs/DEVELOPMENT.md +4 -3
- package/docs/FORMS.md +151 -6
- package/docs/FRAME-COVERAGE-REPORT.md +29 -16
- package/docs/README.md +1 -1
- package/docs/STANDARDS-vocabulary-tokens.md +1 -1
- package/docs/TESTING.md +15 -6
- package/docs/charts/cjk-category-axis.tsx +81 -0
- package/docs/data-display/card/index.tsx +22 -0
- package/docs/data-display/data-table/examples/antd-parity.tsx +257 -0
- package/docs/data-display/data-table/index.tsx +23 -0
- package/docs/data-display/descriptions.tsx +41 -0
- package/docs/data-display/list-row.tsx +6 -6
- package/docs/data-display/scroll-area.tsx +31 -25
- package/docs/data-display/table.tsx +104 -45
- package/docs/data-display/timeline.tsx +41 -0
- package/docs/data-entry/date-picker.tsx +85 -0
- package/docs/data-entry/date-range-picker.tsx +26 -0
- package/docs/data-entry/form-dynamic-fields.tsx +199 -0
- package/docs/data-entry/form.tsx +74 -4
- package/docs/data-entry/input-otp.tsx +24 -0
- package/docs/data-entry/input.tsx +46 -1
- package/docs/data-entry/month-range-picker.tsx +1 -1
- package/docs/data-entry/select.tsx +27 -0
- package/docs/data-entry/switch.tsx +41 -0
- package/docs/data-entry/textarea.tsx +38 -0
- package/docs/data-entry/time-picker.tsx +85 -1
- package/docs/data-entry/time-range-picker.tsx +55 -0
- package/docs/data-entry/transfer.tsx +17 -0
- package/docs/data-entry/upload.tsx +56 -12
- package/docs/feedback/tooltip.tsx +1 -1
- package/docs/general/activity.tsx +2 -2
- package/docs/general/button/index.tsx +14 -1
- package/docs/general/typography.tsx +14 -1
- package/docs/layout/app-launcher.tsx +195 -0
- package/docs/layout/app-shell-arrangements.tsx +5 -5
- package/docs/layout/app-shell.tsx +11 -0
- package/docs/layout/flex.tsx +50 -0
- package/docs/layout/responsive-grid.tsx +21 -1
- package/docs/layout/topbar.tsx +5 -9
- package/docs/navigation/app-setting-picker.tsx +11 -0
- package/docs/navigation/breadcrumb.tsx +48 -0
- package/docs/navigation/dropdown-menu.tsx +21 -0
- package/docs/navigation/pagination.tsx +52 -0
- package/docs/navigation/steps.tsx +37 -0
- package/docs/navigation/tabs.tsx +97 -1
- package/docs/query/button-refetch.tsx +1 -0
- package/docs/showcase/settings-security-mfa.tsx +3 -3
- package/package.json +24 -4
- package/scripts/_agent-setup.mjs +76 -9
- package/scripts/init-guinea-pig.mjs +26 -4
- package/scripts/ui-audit.mjs +243 -30
- 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(
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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
|
-
) :
|
|
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 ? [
|
|
280
|
+
selectedKeys: checked ? [checkboxKey] : [],
|
|
229
281
|
onSelectionChange: (keys) => {
|
|
230
|
-
onCheckedChange?.(keys === "all" ? true : keys.has(
|
|
282
|
+
onCheckedChange?.(keys === "all" ? true : keys.has(checkboxKey));
|
|
231
283
|
},
|
|
232
284
|
children: /* @__PURE__ */ jsx(
|
|
233
285
|
MenuItem,
|
|
234
286
|
{
|
|
235
|
-
id:
|
|
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(
|
|
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
|
|
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 /
|
|
125
|
-
onValueChange?.(nextPage,
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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
|
-
|
|
196
|
+
Button,
|
|
178
197
|
{
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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__ */
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
onClick: () => {
|
|
205
|
-
if (!disabled) go(page);
|
|
206
|
-
},
|
|
241
|
+
value: String(pageSize),
|
|
242
|
+
onValueChange: (v) => go(1, Number(v)),
|
|
207
243
|
disabled,
|
|
208
|
-
children:
|
|
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
|
-
)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
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(
|
|
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:
|
|
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
|