@meta-1/design 0.0.168 → 0.0.170

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meta-1/design",
3
- "version": "0.0.168",
3
+ "version": "0.0.170",
4
4
  "keywords": [
5
5
  "easykit",
6
6
  "design",
@@ -52,7 +52,7 @@ function DialogContent({
52
52
  <DialogOverlay onClick={onOverlayClick} />
53
53
  <DialogPrimitive.Content
54
54
  className={cn(
55
- "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
55
+ "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 flex flex-col w-full max-w-[calc(100vw-2rem)] max-h-[calc(100vh-2rem)] translate-x-[-50%] translate-y-[-50%] rounded-lg border bg-background shadow-lg duration-200 data-[state=closed]:animate-out data-[state=open]:animate-in sm:max-w-lg",
56
56
  className,
57
57
  )}
58
58
  data-slot="dialog-content"
@@ -61,7 +61,7 @@ function DialogContent({
61
61
  {children}
62
62
  {showClose ? (
63
63
  <DialogPrimitive.Close
64
- className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0"
64
+ className="absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0 z-10"
65
65
  onClick={onCloseClick}
66
66
  >
67
67
  <XIcon />
@@ -76,7 +76,7 @@ function DialogContent({
76
76
  function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
77
77
  return (
78
78
  <div
79
- className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
79
+ className={cn("flex flex-col gap-2 text-center sm:text-left flex-shrink-0 p-6 pb-0", className)}
80
80
  data-slot="dialog-header"
81
81
  {...props}
82
82
  />
@@ -86,7 +86,7 @@ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
86
86
  function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
87
87
  return (
88
88
  <div
89
- className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
89
+ className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end flex-shrink-0 p-6 pt-0", className)}
90
90
  data-slot="dialog-footer"
91
91
  {...props}
92
92
  />
@@ -57,6 +57,7 @@ export interface DataTableProps<TData> {
57
57
  showColumnVisibility?: boolean;
58
58
  stickyColumns?: StickyColumnProps[];
59
59
  checkbox?: boolean;
60
+ onRowSelectionChange?: (selectedRows: TData[]) => void;
60
61
  rowActions?: DropdownMenuItemProps[] | ((cell: TData) => DropdownMenuItemProps[]);
61
62
  onRowActionClick?: (item: DropdownMenuItemProps, row: Row<TData>) => void;
62
63
  loading?: boolean;
@@ -161,6 +162,7 @@ export function DataTable<TData>(props: DataTableProps<TData>) {
161
162
  showColumnVisibility = true,
162
163
  rowActions,
163
164
  checkbox = false,
165
+ onRowSelectionChange,
164
166
  stickyColumns = [],
165
167
  onRowActionClick,
166
168
  filter,
@@ -284,6 +286,14 @@ export function DataTable<TData>(props: DataTableProps<TData>) {
284
286
  },
285
287
  });
286
288
 
289
+ // 当行选中状态改变时,通知外部
290
+ useEffect(() => {
291
+ if (checkbox && onRowSelectionChange) {
292
+ const selectedRows = table.getSelectedRowModel().rows.map((row) => row.original);
293
+ onRowSelectionChange(selectedRows);
294
+ }
295
+ }, [rowSelection, checkbox, onRowSelectionChange, table]);
296
+
287
297
  const leftStickyColumns = useMemo<StickyColumnProps[]>(() => {
288
298
  const columns: StickyColumnProps[] = [];
289
299
  if (checkbox) {
@@ -51,13 +51,11 @@ export const Dialog: FC<DialogProps> = (props) => {
51
51
  onOverlayClick={maskClosable ? onCancel : () => {}}
52
52
  showClose={closable}
53
53
  >
54
- {title || description ? (
55
- <DialogHeader>
56
- {title ? <DialogTitle>{title}</DialogTitle> : null}
57
- {description ? <DialogDescription>{description}</DialogDescription> : null}
58
- </DialogHeader>
59
- ) : null}
60
- <div className="my-2">{props.children}</div>
54
+ <DialogHeader className={cn(!title && !description && "sr-only")}>
55
+ <DialogTitle className={cn(!title && "sr-only")}>{title || "Dialog"}</DialogTitle>
56
+ {description ? <DialogDescription>{description}</DialogDescription> : null}
57
+ </DialogHeader>
58
+ <div className="min-h-0 flex-1 overflow-x-auto overflow-y-auto px-6 py-4">{props.children}</div>
61
59
  {footer ? <DialogFooter>{footer}</DialogFooter> : null}
62
60
  {loading ? (
63
61
  <div className={cn("absolute top-0 right-0 bottom-0 left-0 bg-white/50", "flex items-center justify-center")}>
@@ -21,6 +21,14 @@ export interface PaginationProps {
21
21
  onChange?: (page: number) => void;
22
22
  onSizeChange?: (size: number) => void;
23
23
  sizeOptions?: number[];
24
+ /** 简单模式:只显示上一页、当前页、下一页 */
25
+ simple?: boolean;
26
+ /** 是否显示总数信息 */
27
+ showTotal?: boolean;
28
+ /** 是否显示页面大小选择器 */
29
+ showSizeChanger?: boolean;
30
+ /** 是否显示快速跳转 */
31
+ showQuickJumper?: boolean;
24
32
  }
25
33
 
26
34
  export const SIZE_OPTIONS = [10, 20, 50, 100];
@@ -66,7 +74,18 @@ const generatePageNumbers = (currentPage: number, totalPages: number) => {
66
74
  };
67
75
 
68
76
  export const Pagination: FC<PaginationProps> = (props) => {
69
- const { total = 0, page = 1, size = 20, sizeOptions = SIZE_OPTIONS, onChange, onSizeChange } = props;
77
+ const {
78
+ total = 0,
79
+ page = 1,
80
+ size = 20,
81
+ sizeOptions = SIZE_OPTIONS,
82
+ onChange,
83
+ onSizeChange,
84
+ simple = false,
85
+ showTotal = true,
86
+ showSizeChanger = true,
87
+ showQuickJumper = true,
88
+ } = props;
70
89
 
71
90
  const config = useContext(UIXContext);
72
91
  const totalPageText = get(config.locale, "Pagination.totalPage");
@@ -101,14 +120,53 @@ export const Pagination: FC<PaginationProps> = (props) => {
101
120
 
102
121
  const pageNumbers = generatePageNumbers(page, totalPage);
103
122
 
123
+ if (simple) {
124
+ // 简单模式渲染
125
+ return (
126
+ <div className="flex items-center justify-center">
127
+ <ShadcnPagination>
128
+ <PaginationContent>
129
+ {/* 上一页 */}
130
+ <PaginationItem>
131
+ <PaginationPrevious
132
+ className={page === 1 ? "pointer-events-none opacity-50" : "cursor-pointer"}
133
+ onClick={page === 1 ? undefined : () => onChange?.(page - 1)}
134
+ size="default"
135
+ />
136
+ </PaginationItem>
137
+
138
+ {/* 当前页 */}
139
+ <PaginationItem>
140
+ <PaginationLink isActive size="default">
141
+ {page}
142
+ </PaginationLink>
143
+ </PaginationItem>
144
+
145
+ {/* 下一页 */}
146
+ <PaginationItem>
147
+ <PaginationNext
148
+ className={page === totalPage ? "pointer-events-none opacity-50" : "cursor-pointer"}
149
+ onClick={page === totalPage ? undefined : () => onChange?.(page + 1)}
150
+ size="default"
151
+ />
152
+ </PaginationItem>
153
+ </PaginationContent>
154
+ </ShadcnPagination>
155
+ </div>
156
+ );
157
+ }
158
+
159
+ // 标准模式渲染
104
160
  return (
105
161
  <div className="flex items-center justify-center space-x-6">
106
162
  <ShadcnPagination>
107
163
  {/* 总数信息 */}
108
- <div className="flex items-center space-x-2 text-muted-foreground text-sm">
109
- <span>{totalPageText?.replace("%total", `${total}`)}</span>
110
- <span>{totalText?.replace("%page", `${totalPage}`)}</span>
111
- </div>
164
+ {showTotal ? (
165
+ <div className="flex items-center space-x-2 text-muted-foreground text-sm">
166
+ <span>{totalPageText?.replace("%total", `${total}`)}</span>
167
+ <span>{totalText?.replace("%page", `${totalPage}`)}</span>
168
+ </div>
169
+ ) : null}
112
170
  {/* 分页导航 */}
113
171
  <PaginationContent>
114
172
  {/* 上一页 */}
@@ -148,32 +206,38 @@ export const Pagination: FC<PaginationProps> = (props) => {
148
206
  </PaginationItem>
149
207
  </PaginationContent>
150
208
  {/* 控制区域 */}
151
- <div className="flex items-center space-x-3">
152
- {/* 页面大小选择 */}
153
- <Select
154
- className="w-auto"
155
- onChange={(v) => onSizeChange?.(Number(v))}
156
- options={sizeOptions.map((v) => ({ label: sizeText?.replace("%size", `${v}`) || "", value: `${v}` }))}
157
- value={`${size}`}
158
- />
159
-
160
- {/* 跳转输入框 */}
161
- <div className="flex items-center space-x-1 text-sm">
162
- <span>{go}</span>
163
- <Input
164
- className="h-9 w-12 rounded px-2 text-center"
165
- onChange={handleChange}
166
- onKeyDown={(e) => {
167
- if (e.key === "Enter") {
168
- onChange?.(Number(pageValue));
169
- }
170
- }}
171
- type="text"
172
- value={pageValue}
173
- />
174
- <span>{goSuffix}</span>
209
+ {showSizeChanger || showQuickJumper ? (
210
+ <div className="flex items-center space-x-3">
211
+ {/* 页面大小选择 */}
212
+ {showSizeChanger ? (
213
+ <Select
214
+ className="w-auto"
215
+ onChange={(v) => onSizeChange?.(Number(v))}
216
+ options={sizeOptions.map((v) => ({ label: sizeText?.replace("%size", `${v}`) || "", value: `${v}` }))}
217
+ value={`${size}`}
218
+ />
219
+ ) : null}
220
+
221
+ {/* 跳转输入框 */}
222
+ {showQuickJumper ? (
223
+ <div className="flex items-center space-x-1 text-sm">
224
+ <span>{go}</span>
225
+ <Input
226
+ className="h-9 w-12 rounded px-2 text-center"
227
+ onChange={handleChange}
228
+ onKeyDown={(e) => {
229
+ if (e.key === "Enter") {
230
+ onChange?.(Number(pageValue));
231
+ }
232
+ }}
233
+ type="text"
234
+ value={pageValue}
235
+ />
236
+ <span>{goSuffix}</span>
237
+ </div>
238
+ ) : null}
175
239
  </div>
176
- </div>
240
+ ) : null}
177
241
  </ShadcnPagination>
178
242
  </div>
179
243
  );