@wordrhyme/auto-crud 1.2.3 → 1.2.5

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 CHANGED
@@ -277,7 +277,9 @@ interface AutoCrudTableProps<TSchema> {
277
277
  * - 只传 custom 项:内置保持默认,custom 追加到首/尾
278
278
  * - 包含任意内置 type:数组完全接管,未列出的内置项自动隐藏
279
279
  */
280
- toolbarActions?: ToolbarActionItem[];
280
+ toolbar?: ToolbarActionConfig;
281
+ /** @deprecated 新代码请使用 toolbar */
282
+ toolbarActions?: ToolbarActionConfig;
281
283
  /**
282
284
  * 行操作配置
283
285
  * - 只传 custom 项:内置保持默认,custom 追加到首/尾
@@ -304,6 +306,9 @@ interface UseAutoCrudResourceConfig<TData> {
304
306
 
305
307
  ```typescript
306
308
  interface UseAutoCrudResourceReturn<TSchema, TData> {
309
+ // 主键字段名;未提供时 AutoCrudTable 默认按 "id" 读取
310
+ idKey?: keyof TData & string;
311
+
307
312
  // 表格数据
308
313
  tableData: {
309
314
  data: TData[];
@@ -529,7 +534,7 @@ table={{
529
534
 
530
535
  ## 🔧 工具栏操作配置
531
536
 
532
- `toolbarActions` 数组控制页面顶部右侧工具栏的按钮,设计思路完全对齐行操作 `actions`。
537
+ `toolbar` 数组控制页面顶部右侧工具栏的按钮,设计思路完全对齐行操作 `actions`。旧 prop `toolbarActions` 仍兼容读取,但新代码请使用 `toolbar`。
533
538
 
534
539
  内置操作类型:`create`(新建)、`import`(导入)、`export`(导出)。
535
540
 
@@ -539,7 +544,7 @@ table={{
539
544
 
540
545
  ```tsx
541
546
  <AutoCrudTable
542
- toolbarActions={[
547
+ toolbar={[
543
548
  {
544
549
  type: 'custom',
545
550
  component: <Button variant="outline">分类管理</Button>,
@@ -557,7 +562,7 @@ table={{
557
562
 
558
563
  ```tsx
559
564
  <AutoCrudTable
560
- toolbarActions={[
565
+ toolbar={[
561
566
  { type: 'create' }, // 新建移到最前
562
567
  { type: 'export', label: '导出 CSV' }, // 覆盖文案
563
568
  // import 未列出 → 隐藏
@@ -570,7 +575,7 @@ table={{
570
575
 
571
576
  ```tsx
572
577
  <AutoCrudTable
573
- toolbarActions={[
578
+ toolbar={[
574
579
  { type: 'import' },
575
580
  { type: 'export' },
576
581
  {
@@ -586,7 +591,7 @@ table={{
586
591
 
587
592
  ```tsx
588
593
  <AutoCrudTable
589
- toolbarActions={[
594
+ toolbar={[
590
595
  { type: 'export' },
591
596
  {
592
597
  type: 'create',
@@ -614,7 +619,7 @@ table={{
614
619
 
615
620
  ```tsx
616
621
  <AutoCrudTable
617
- toolbarActions={[
622
+ toolbar={[
618
623
  { type: 'custom', component: <CategoryFilter onChange={setCategory} /> },
619
624
  { type: 'export' },
620
625
  { type: 'create', label: '发布', onClick: () => router.push('/products/new') },
@@ -625,7 +630,7 @@ table={{
625
630
 
626
631
  ### 与 `permissions` 的交互
627
632
 
628
- `toolbarActions` 与 `permissions` 的交互规则如下:
633
+ `toolbar` 与 `permissions` 的交互规则如下:
629
634
 
630
635
  - `permissions.can.create = false` → 即使配置了 `{ type: "create" }`,新建按钮仍不渲染
631
636
  - `permissions.can.export = false` → 即使配置了 `{ type: "export" }`,导出按钮仍不渲染
@@ -637,7 +642,7 @@ table={{
637
642
  permissions={{
638
643
  can: { create: isAdmin, export: true, delete: isAdmin },
639
644
  }}
640
- toolbarActions={[
645
+ toolbar={[
641
646
  { type: 'export' }, // ✅ 始终渲染
642
647
  { type: 'create', label: '发布商品' }, // 🔒 仅 isAdmin 时渲染
643
648
  {
@@ -648,14 +653,14 @@ table={{
648
653
  />
649
654
  ```
650
655
 
651
- ### `toolbarActions` 传参高级语法(函数式)
656
+ ### `toolbar` 传参高级语法(函数式)
652
657
 
653
658
  如果你的目标是拦截并修改基于原顺序的所有内容,你还可以传递一个函数:
654
659
 
655
660
  ```tsx
656
661
  <AutoCrudTable
657
662
  // defaults 即内置三个按钮的信息,在此数组里你可以随意 map、过滤或插值
658
- toolbarActions={(defaults) =>
663
+ toolbar={(defaults) =>
659
664
  defaults.map((btn) =>
660
665
  btn.type === 'create'
661
666
  ? { ...btn, label: '发布商品', onClick: () => router.push('/products/new') }
@@ -671,6 +676,10 @@ table={{
671
676
  ```typescript
672
677
  type ToolbarActionItem = ToolbarBuiltinActionItem | ToolbarCustomActionItem;
673
678
 
679
+ type ToolbarActionConfig =
680
+ | ToolbarActionItem[]
681
+ | ((defaults: ToolbarBuiltinActionItem[]) => ToolbarActionItem[]);
682
+
674
683
  type ToolbarBuiltinActionItem = {
675
684
  type: 'create' | 'import' | 'export';
676
685
  onClick?: () => void; // 覆盖默认行为
@@ -685,6 +694,29 @@ type ToolbarCustomActionItem = {
685
694
  };
686
695
  ```
687
696
 
697
+ ### 工具栏扩展 Resolver
698
+
699
+ 宿主应用可以通过 `setToolbarResolver` 为指定 CRUD 注入额外工具栏动作。resolver 是普通纯函数,不是 React Hook;不要在 resolver 内调用 `useRouter`、`useMemo` 等 React Hooks。
700
+
701
+ ```tsx
702
+ import { AutoCrudTable, setToolbarResolver } from '@wordrhyme/auto-crud';
703
+ import type { AutoCrudToolbarResolver } from '@wordrhyme/auto-crud';
704
+
705
+ const toolbarResolver: AutoCrudToolbarResolver = (targetId, ownerActions, context) => {
706
+ if (targetId !== 'com.wordrhyme.shop.products') return [...ownerActions];
707
+
708
+ return [
709
+ ...ownerActions,
710
+ {
711
+ type: 'custom',
712
+ component: <Button disabled={context.selectedCount === 0}>批量发布</Button>,
713
+ },
714
+ ];
715
+ };
716
+
717
+ setToolbarResolver(toolbarResolver);
718
+ ```
719
+
688
720
  ---
689
721
 
690
722
  ## 🎬 行操作配置
@@ -790,7 +822,7 @@ type ActionItem<T> =
790
822
 
791
823
  ### 批量悬浮栏操作顺序
792
824
 
793
- `table.batchActions` 控制多选后悬浮操作栏,设计思路对齐行操作 `actions` 和顶部 `toolbarActions`。
825
+ `table.batchActions` 控制多选后悬浮操作栏,设计思路对齐行操作 `actions` 和顶部 `toolbar`。
794
826
 
795
827
  内置操作类型:`batchUpdate`(批量更新字段下拉)、`export`(导出选中行)、`delete`(删除选中行)。
796
828
 
package/dist/index.cjs CHANGED
@@ -4907,7 +4907,7 @@ const filterModeConfig = {
4907
4907
  tooltip: "Linear-style command filters"
4908
4908
  }
4909
4909
  };
4910
- function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, getSelectedRows }) {
4910
+ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
4911
4911
  const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
4912
4912
  const [currentMode, setCurrentMode] = useQueryState("filterMode", parseAsStringEnum(modes).withDefault(modes[0] ?? "simple"));
4913
4913
  const showToggle = modes.length > 1;
@@ -4956,17 +4956,28 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4956
4956
  shallow: false,
4957
4957
  clearOnDefault: true
4958
4958
  });
4959
- const getSelectedRowsFn = (0, react.useCallback)(() => table.getFilteredSelectedRowModel().rows.map((row) => row.original), [table]);
4959
+ const rowSelection = table.getState().rowSelection;
4960
+ const columnFilters = table.getState().columnFilters;
4961
+ const selectedRows = (0, react.useMemo)(() => table.getFilteredSelectedRowModel().rows.map((row) => row.original), [
4962
+ table,
4963
+ rowSelection,
4964
+ columnFilters,
4965
+ data
4966
+ ]);
4967
+ const getSelectedRowsFn = (0, react.useCallback)(() => selectedRows, [selectedRows]);
4960
4968
  (0, react.useEffect)(() => {
4961
4969
  if (getSelectedRows) getSelectedRows.current = getSelectedRowsFn;
4962
4970
  return () => {
4963
4971
  if (getSelectedRows) getSelectedRows.current = null;
4964
4972
  };
4965
4973
  }, [getSelectedRows, getSelectedRowsFn]);
4966
- const selectedRowCount = table.getFilteredSelectedRowModel().rows.length;
4974
+ const selectedRowCount = selectedRows.length;
4967
4975
  (0, react.useEffect)(() => {
4968
4976
  onSelectedCountChange?.(selectedRowCount);
4969
4977
  }, [selectedRowCount, onSelectedCountChange]);
4978
+ (0, react.useEffect)(() => {
4979
+ onSelectedRowsChange?.(selectedRows);
4980
+ }, [selectedRows, onSelectedRowsChange]);
4970
4981
  const FilterModeSelect = showToggle ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(__pixpilot_shadcn.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.DropdownMenuTrigger, {
4971
4982
  asChild: true,
4972
4983
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(__pixpilot_shadcn.Button, {
@@ -6275,6 +6286,44 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
6275
6286
 
6276
6287
  //#endregion
6277
6288
  //#region src/components/auto-crud/auto-crud-table.tsx
6289
+ let autoCrudToolbarResolver = null;
6290
+ function setToolbarResolver(resolver) {
6291
+ autoCrudToolbarResolver = resolver;
6292
+ }
6293
+ function getDefaultToolbarActions() {
6294
+ return [
6295
+ { type: "import" },
6296
+ { type: "export" },
6297
+ { type: "create" }
6298
+ ];
6299
+ }
6300
+ function resolveOwnerToolbarActions(toolbar) {
6301
+ const resolved = typeof toolbar === "function" ? toolbar(getDefaultToolbarActions()) : toolbar;
6302
+ return resolved !== void 0 && resolved.length > 0 ? [...resolved] : getDefaultToolbarActions();
6303
+ }
6304
+ function readRowIds(rows, idKey) {
6305
+ return rows.flatMap((row) => {
6306
+ const value = row[idKey];
6307
+ return value === null || value === void 0 ? [] : [String(value)];
6308
+ });
6309
+ }
6310
+ function areStringArraysEqual(left, right) {
6311
+ return left.length === right.length && left.every((value, index) => value === right[index]);
6312
+ }
6313
+ function haveSameRowSelection(left, right, idKey) {
6314
+ if (left.length !== right.length) return false;
6315
+ const leftIds = readRowIds(left, idKey);
6316
+ const rightIds = readRowIds(right, idKey);
6317
+ if (leftIds.length === left.length && rightIds.length === right.length) return areStringArraysEqual(leftIds, rightIds);
6318
+ return left.every((row, index) => row === right[index]);
6319
+ }
6320
+ function readCreateAction(actions) {
6321
+ return actions.find((action) => action.type === "create");
6322
+ }
6323
+ function resolveToolbarActionsWithResolver(targetId, ownerActions, context) {
6324
+ const resolver = autoCrudToolbarResolver;
6325
+ return targetId !== void 0 && targetId.length > 0 && resolver !== null ? resolver(targetId, ownerActions, context) : ownerActions;
6326
+ }
6278
6327
  function mergeFieldPart(base, override) {
6279
6328
  if (override === void 0) return base;
6280
6329
  if (override === false || base === false || typeof base !== "object" || typeof override !== "object" || base === null || override === null || Array.isArray(base) || Array.isArray(override)) return override;
@@ -6725,7 +6774,7 @@ function resolveActions(actionsOrFn, defaults, rowActionsLocale) {
6725
6774
  *
6726
6775
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
6727
6776
  */
6728
- function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbarActions, locale: localeProp, onCreate }) {
6777
+ function AutoCrudTable({ id, title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbar, toolbarActions, locale: localeProp, onCreate }) {
6729
6778
  const locale = resolveLocale(localeProp);
6730
6779
  const resolvedSchema = resource.schema ?? schema;
6731
6780
  const resolvedFields = react.useMemo(() => mergeFields(resource.fields, fields) ?? {}, [fields, resource.fields]);
@@ -6740,10 +6789,35 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6740
6789
  const canImport = can.import && !!resource.handlers.import;
6741
6790
  const canExport = can.export;
6742
6791
  const [importOpen, setImportOpen] = react.useState(false);
6743
- const [selectedCount, setSelectedCount] = react.useState(0);
6792
+ const [selectedRows, setSelectedRows] = react.useState([]);
6744
6793
  const [exporting, setExporting] = react.useState(false);
6745
6794
  const getSelectedRowsRef = react.useRef(null);
6746
6795
  const dynamicFilterOptions = useDynamicFilterOptions(resolvedFields);
6796
+ const resourceIdKey = resource.idKey ?? "id";
6797
+ const ownerToolbarActions = react.useMemo(() => resolveOwnerToolbarActions(toolbar ?? toolbarActions), [toolbar, toolbarActions]);
6798
+ const selectedCount = selectedRows.length;
6799
+ const selectedRowIds = react.useMemo(() => readRowIds(selectedRows, resourceIdKey), [selectedRows, resourceIdKey]);
6800
+ const rowIds = react.useMemo(() => readRowIds(resource.tableData.data, resourceIdKey), [resource.tableData.data, resourceIdKey]);
6801
+ const handleSelectedRowsChange = react.useCallback((rows) => {
6802
+ setSelectedRows((currentRows) => haveSameRowSelection(currentRows, rows, resourceIdKey) ? currentRows : rows);
6803
+ }, [resourceIdKey]);
6804
+ const ownerCreateAction = react.useMemo(() => readCreateAction(ownerToolbarActions), [ownerToolbarActions]);
6805
+ const toolbarOpenCreate = can.create ? ownerCreateAction?.onClick ?? onCreate ?? resource.handlers.openCreate : void 0;
6806
+ const resolvedToolbarActions = resolveToolbarActionsWithResolver(id, ownerToolbarActions, react.useMemo(() => ({
6807
+ crudId: id ?? "",
6808
+ idKey: resourceIdKey,
6809
+ rowIds,
6810
+ selectedRowIds,
6811
+ selectedCount,
6812
+ ...toolbarOpenCreate ? { openCreate: toolbarOpenCreate } : {}
6813
+ }), [
6814
+ id,
6815
+ resourceIdKey,
6816
+ rowIds,
6817
+ selectedRowIds,
6818
+ selectedCount,
6819
+ toolbarOpenCreate
6820
+ ]));
6747
6821
  const importColumns = react.useMemo(() => {
6748
6822
  const shape = resolvedSchema.shape;
6749
6823
  const denySet = new Set(denyFields ?? []);
@@ -6753,9 +6827,9 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6753
6827
  const filename = title ?? "export";
6754
6828
  const excludeColumns = denyFields;
6755
6829
  if (mode === "selected") {
6756
- const selectedRows = getSelectedRowsRef.current?.();
6757
- if (!selectedRows || selectedRows.length === 0) return;
6758
- exportAllToCSV(selectedRows, {
6830
+ const selectedRows$1 = getSelectedRowsRef.current?.();
6831
+ if (!selectedRows$1 || selectedRows$1.length === 0) return;
6832
+ exportAllToCSV(selectedRows$1, {
6759
6833
  filename,
6760
6834
  excludeColumns
6761
6835
  });
@@ -6849,11 +6923,6 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6849
6923
  }, "create");
6850
6924
  return null;
6851
6925
  };
6852
- const resolvedToolbarActions = typeof toolbarActions === "function" ? toolbarActions([
6853
- { type: "import" },
6854
- { type: "export" },
6855
- { type: "create" }
6856
- ]) : toolbarActions;
6857
6926
  if (!resolvedToolbarActions || resolvedToolbarActions.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6858
6927
  className: "flex items-center gap-2",
6859
6928
  children: [
@@ -6911,7 +6980,7 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6911
6980
  enableExport: canExport,
6912
6981
  showDefaultExport: false,
6913
6982
  initialSorting: tableConfig?.defaultSort,
6914
- onSelectedCountChange: setSelectedCount,
6983
+ onSelectedRowsChange: handleSelectedRowsChange,
6915
6984
  getSelectedRows: getSelectedRowsRef
6916
6985
  }),
6917
6986
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CrudFormModal, {
@@ -7986,6 +8055,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7986
8055
  ]);
7987
8056
  const canExport = !!(exportFetcher || exportQuery);
7988
8057
  return {
8058
+ idKey,
7989
8059
  tableData: {
7990
8060
  data: tableRows,
7991
8061
  pageCount: listQuery.data?.pageCount ?? 0,
@@ -8381,6 +8451,7 @@ exports.parseJSON = parseJSON;
8381
8451
  exports.parseZodField = parseZodField;
8382
8452
  exports.resolveLocale = resolveLocale;
8383
8453
  exports.setSearchParams = setSearchParams;
8454
+ exports.setToolbarResolver = setToolbarResolver;
8384
8455
  exports.useAutoCrudResource = useAutoCrudResource;
8385
8456
  exports.useDataTable = useDataTable;
8386
8457
  exports.useQueryState = useQueryState;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime3 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
2
  import { z } from "zod";
3
3
  import * as _tanstack_react_table0 from "@tanstack/react-table";
4
4
  import { Column, ColumnDef, ColumnSort, Row, RowData, Table, TableOptions, TableState } from "@tanstack/react-table";
@@ -119,6 +119,8 @@ interface ImportResult {
119
119
  * Hook 返回值类型
120
120
  */
121
121
  interface UseAutoCrudResourceReturn<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
122
+ /** 主键字段名(默认: "id") */
123
+ idKey?: keyof TListItem & string;
122
124
  tableData: {
123
125
  data: TListItem[];
124
126
  pageCount: number;
@@ -362,7 +364,7 @@ declare function AutoTableActionBar<TData>({
362
364
  enableDelete,
363
365
  extraActions,
364
366
  actions
365
- }: AutoTableActionBarProps<TData>): react_jsx_runtime3.JSX.Element;
367
+ }: AutoTableActionBarProps<TData>): react_jsx_runtime1.JSX.Element;
366
368
  //#endregion
367
369
  //#region src/lib/schema-bridge/types.d.ts
368
370
  /**
@@ -506,6 +508,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> {
506
508
  showDefaultExport?: boolean;
507
509
  /** 选中行数变化回调(用于外层组件获知选中状态) */
508
510
  onSelectedCountChange?: (count: number) => void;
511
+ /** 选中行数据变化回调(用于外层组件获知选中行身份变化) */
512
+ onSelectedRowsChange?: (rows: z.infer<T>[]) => void;
509
513
  /** 获取选中行数据的回调(由外层组件调用) */
510
514
  getSelectedRows?: React.MutableRefObject<(() => z.infer<T>[]) | null>;
511
515
  }
@@ -529,8 +533,9 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
529
533
  enableExport,
530
534
  showDefaultExport,
531
535
  onSelectedCountChange,
536
+ onSelectedRowsChange,
532
537
  getSelectedRows
533
- }: AutoTableProps<T>): react_jsx_runtime3.JSX.Element;
538
+ }: AutoTableProps<T>): react_jsx_runtime1.JSX.Element;
534
539
  //#endregion
535
540
  //#region src/i18n/locale.d.ts
536
541
  /**
@@ -823,6 +828,16 @@ type ToolbarCustomActionItem = {
823
828
  };
824
829
  type ToolbarActionItem = ToolbarBuiltinActionItem | ToolbarCustomActionItem;
825
830
  type ToolbarActionConfig = ToolbarActionItem[] | ((defaults: ToolbarBuiltinActionItem[]) => ToolbarActionItem[]);
831
+ interface AutoCrudToolbarContext {
832
+ crudId: string;
833
+ idKey: string;
834
+ rowIds: string[];
835
+ selectedRowIds: string[];
836
+ selectedCount: number;
837
+ openCreate?: () => void;
838
+ }
839
+ type AutoCrudToolbarResolver = (targetId: string, ownerActions: readonly ToolbarActionItem[], context: AutoCrudToolbarContext) => ToolbarActionItem[];
840
+ declare function setToolbarResolver(resolver: AutoCrudToolbarResolver | null): void;
826
841
  /**
827
842
  * AutoCrudTable Props 接口
828
843
  */
@@ -866,7 +881,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
866
881
  batchFields?: (string | BatchUpdateField)[];
867
882
  /**
868
883
  * 多选后悬浮批量操作栏配置
869
- * 用法类同 `actions` 行操作和 `toolbarActions` 顶部工具栏。
884
+ * 用法类同 `actions` 行操作和 `toolbar` 顶部工具栏。
870
885
  * 只传 custom 时保留默认批量操作;包含任意内置 type 时完全接管顺序。
871
886
  */
872
887
  batchActions?: BatchActionConfig<z.output<TSchema>>;
@@ -888,6 +903,8 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
888
903
  * 顶层工具栏操作配置
889
904
  * 用法类同 `actions` 行操作。一旦配置了包含内置 `type` 的数组,它将完全接管右侧工具栏!
890
905
  */
906
+ toolbar?: ToolbarActionConfig;
907
+ /** @deprecated Use toolbar instead. */
891
908
  toolbarActions?: ToolbarActionConfig;
892
909
  /**
893
910
  * 权限配置
@@ -934,6 +951,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
934
951
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
935
952
  */
936
953
  declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
954
+ id,
937
955
  title,
938
956
  description,
939
957
  schema,
@@ -943,10 +961,11 @@ declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
943
961
  form: formConfig,
944
962
  permissions,
945
963
  actions: actionItems,
964
+ toolbar,
946
965
  toolbarActions,
947
966
  locale: localeProp,
948
967
  onCreate
949
- }: AutoCrudTableProps<TSchema>): react_jsx_runtime3.JSX.Element;
968
+ }: AutoCrudTableProps<TSchema>): react_jsx_runtime1.JSX.Element;
950
969
  //#endregion
951
970
  //#region src/components/auto-crud/auto-form.d.ts
952
971
  interface AutoFormProps<T extends z.ZodObject<z.ZodRawShape>> {
@@ -978,7 +997,7 @@ declare function AutoFormInner<T extends z.ZodObject<z.ZodRawShape>>({
978
997
  labelAlign,
979
998
  labelWidth,
980
999
  showSubmitButton
981
- }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime3.JSX.Element;
1000
+ }: AutoFormProps<T>, ref: React.Ref<AutoFormRef>): react_jsx_runtime1.JSX.Element;
982
1001
  declare const AutoForm: <T extends z.ZodObject<z.ZodRawShape>>(props: AutoFormProps<T> & {
983
1002
  ref?: React.Ref<AutoFormRef>;
984
1003
  }) => ReturnType<typeof AutoFormInner>;
@@ -1192,12 +1211,12 @@ declare const filterItemSchema: z.ZodObject<{
1192
1211
  variant: z.ZodEnum<{
1193
1212
  number: "number";
1194
1213
  boolean: "boolean";
1195
- text: "text";
1196
- range: "range";
1197
1214
  date: "date";
1198
- dateRange: "dateRange";
1215
+ text: "text";
1199
1216
  select: "select";
1200
1217
  multiSelect: "multiSelect";
1218
+ dateRange: "dateRange";
1219
+ range: "range";
1201
1220
  }>;
1202
1221
  operator: z.ZodEnum<{
1203
1222
  iLike: "iLike";
@@ -1280,7 +1299,7 @@ declare function AutoTableSimpleFilters<TData>({
1280
1299
  filters: externalFilters,
1281
1300
  onFiltersChange,
1282
1301
  leading
1283
- }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime3.JSX.Element | null;
1302
+ }: AutoTableSimpleFiltersProps<TData>): react_jsx_runtime1.JSX.Element | null;
1284
1303
  //#endregion
1285
1304
  //#region src/components/auto-crud/form-modal.d.ts
1286
1305
  type ModalVariant = "dialog" | "sheet";
@@ -1322,7 +1341,7 @@ declare function CrudFormModal<T extends z.ZodObject<z.ZodRawShape>>({
1322
1341
  labelAlign,
1323
1342
  labelWidth,
1324
1343
  className
1325
- }: CrudFormModalProps<T>): react_jsx_runtime3.JSX.Element;
1344
+ }: CrudFormModalProps<T>): react_jsx_runtime1.JSX.Element;
1326
1345
  //#endregion
1327
1346
  //#region src/components/auto-crud/import-dialog.d.ts
1328
1347
  interface ImportDialogProps {
@@ -1344,7 +1363,7 @@ declare function ImportDialog({
1344
1363
  columns,
1345
1364
  title,
1346
1365
  locale
1347
- }: ImportDialogProps): react_jsx_runtime3.JSX.Element;
1366
+ }: ImportDialogProps): react_jsx_runtime1.JSX.Element;
1348
1367
  //#endregion
1349
1368
  //#region src/components/auto-crud/export-dialog.d.ts
1350
1369
  type ExportMode = "selected" | "filtered";
@@ -1364,7 +1383,7 @@ declare function ExportDialog({
1364
1383
  selectedCount,
1365
1384
  onExport,
1366
1385
  canExportFiltered
1367
- }: ExportDialogProps): react_jsx_runtime3.JSX.Element;
1386
+ }: ExportDialogProps): react_jsx_runtime1.JSX.Element;
1368
1387
  //#endregion
1369
1388
  //#region src/components/data-table/data-table.d.ts
1370
1389
  interface DataTableProps<TData> extends React$1.ComponentProps<"div"> {
@@ -1377,7 +1396,7 @@ declare function DataTable<TData>({
1377
1396
  children,
1378
1397
  className,
1379
1398
  ...props
1380
- }: DataTableProps<TData>): react_jsx_runtime3.JSX.Element;
1399
+ }: DataTableProps<TData>): react_jsx_runtime1.JSX.Element;
1381
1400
  //#endregion
1382
1401
  //#region src/components/data-table/data-table-advanced-toolbar.d.ts
1383
1402
  interface DataTableAdvancedToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -1388,7 +1407,7 @@ declare function DataTableAdvancedToolbar<TData>({
1388
1407
  children,
1389
1408
  className,
1390
1409
  ...props
1391
- }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime3.JSX.Element;
1410
+ }: DataTableAdvancedToolbarProps<TData>): react_jsx_runtime1.JSX.Element;
1392
1411
  //#endregion
1393
1412
  //#region src/components/data-table/data-table-column-header.d.ts
1394
1413
  interface DataTableColumnHeaderProps<TData, TValue> extends React.ComponentProps<typeof DropdownMenuTrigger> {
@@ -1400,7 +1419,7 @@ declare function DataTableColumnHeader<TData, TValue>({
1400
1419
  label,
1401
1420
  className,
1402
1421
  ...props
1403
- }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime3.JSX.Element;
1422
+ }: DataTableColumnHeaderProps<TData, TValue>): react_jsx_runtime1.JSX.Element;
1404
1423
  //#endregion
1405
1424
  //#region src/components/data-table/data-table-faceted-filter.d.ts
1406
1425
  interface DataTableFacetedFilterProps<TData, TValue> {
@@ -1414,7 +1433,7 @@ declare function DataTableFacetedFilter<TData, TValue>({
1414
1433
  title,
1415
1434
  options,
1416
1435
  multiple
1417
- }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime3.JSX.Element;
1436
+ }: DataTableFacetedFilterProps<TData, TValue>): react_jsx_runtime1.JSX.Element;
1418
1437
  //#endregion
1419
1438
  //#region src/components/data-table/data-table-pagination.d.ts
1420
1439
  interface DataTablePaginationProps<TData> extends React.ComponentProps<"div"> {
@@ -1426,7 +1445,7 @@ declare function DataTablePagination<TData>({
1426
1445
  pageSizeOptions,
1427
1446
  className,
1428
1447
  ...props
1429
- }: DataTablePaginationProps<TData>): react_jsx_runtime3.JSX.Element;
1448
+ }: DataTablePaginationProps<TData>): react_jsx_runtime1.JSX.Element;
1430
1449
  //#endregion
1431
1450
  //#region src/components/data-table/data-table-toolbar.d.ts
1432
1451
  interface DataTableToolbarProps<TData> extends React$1.ComponentProps<"div"> {
@@ -1437,7 +1456,7 @@ declare function DataTableToolbar<TData>({
1437
1456
  children,
1438
1457
  className,
1439
1458
  ...props
1440
- }: DataTableToolbarProps<TData>): react_jsx_runtime3.JSX.Element;
1459
+ }: DataTableToolbarProps<TData>): react_jsx_runtime1.JSX.Element;
1441
1460
  //#endregion
1442
1461
  //#region src/components/data-table/data-table-view-options.d.ts
1443
1462
  interface DataTableViewOptionsProps<TData> extends React$1.ComponentProps<typeof PopoverContent> {
@@ -1448,7 +1467,7 @@ declare function DataTableViewOptions<TData>({
1448
1467
  table,
1449
1468
  disabled,
1450
1469
  ...props
1451
- }: DataTableViewOptionsProps<TData>): react_jsx_runtime3.JSX.Element;
1470
+ }: DataTableViewOptionsProps<TData>): react_jsx_runtime1.JSX.Element;
1452
1471
  //#endregion
1453
1472
  //#region src/components/ui/multi-combobox.d.ts
1454
1473
  interface MultiComboboxOption {
@@ -1825,4 +1844,4 @@ declare function exportAllToCSV<T extends Record<string, unknown>>(data: T[], op
1825
1844
  */
1826
1845
  declare function downloadCSVTemplate(headers: string[], filename?: string): void;
1827
1846
  //#endregion
1828
- export { type ActionItem, type ActionsColumnConfig, type AutoCrudDataSourceConfig, type AutoCrudDataSourceContext, type AutoCrudDataSourceEntry, type AutoCrudDataSourceLoader, type AutoCrudDataSourceRegistration, type AutoCrudFormComponentConfig, type AutoCrudLocale, type AutoCrudOption, AutoCrudTable, type AutoCrudTableProps, AutoForm, type AutoQueryParams, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type BatchActionConfig, type BatchActionContext, type BatchActionItem, type BatchBuiltinActionItem, type BatchBuiltinActionType, type BatchCustomActionItem, type BatchUpdateField, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExportDialog, type ExportDialogProps, type ExportMode, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldOption, type FieldType, type Fields, type FilterConfig, FilterOperator, type FilterVariant, type FormSchemaOverrides, ImportDialog, type ImportDialogProps, type ImportResult, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, type LocaleProp, MultiCombobox, type MultiComboboxOption, type MultiComboboxProps, type MultiComboboxTriggerRenderProps, Option, type ParsedImportData, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type ToolbarActionItem, type ToolbarBuiltinActionItem, type ToolbarCustomActionItem, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, type UseAutoCrudResourceParams, type UseAutoCrudResourceReturn, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
1847
+ export { type ActionItem, type ActionsColumnConfig, type AutoCrudDataSourceConfig, type AutoCrudDataSourceContext, type AutoCrudDataSourceEntry, type AutoCrudDataSourceLoader, type AutoCrudDataSourceRegistration, type AutoCrudFormComponentConfig, type AutoCrudLocale, type AutoCrudOption, AutoCrudTable, type AutoCrudTableProps, type AutoCrudToolbarContext, type AutoCrudToolbarResolver, AutoForm, type AutoQueryParams, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type BatchActionConfig, type BatchActionContext, type BatchActionItem, type BatchBuiltinActionItem, type BatchBuiltinActionType, type BatchCustomActionItem, type BatchUpdateField, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExportDialog, type ExportDialogProps, type ExportMode, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldOption, type FieldType, type Fields, type FilterConfig, FilterOperator, type FilterVariant, type FormSchemaOverrides, ImportDialog, type ImportDialogProps, type ImportResult, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, type LocaleProp, MultiCombobox, type MultiComboboxOption, type MultiComboboxProps, type MultiComboboxTriggerRenderProps, Option, type ParsedImportData, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type ToolbarActionConfig, type ToolbarActionItem, type ToolbarBuiltinActionItem, type ToolbarCustomActionItem, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, type UseAutoCrudResourceParams, type UseAutoCrudResourceReturn, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, setToolbarResolver, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
package/dist/index.d.ts CHANGED
@@ -119,6 +119,8 @@ interface ImportResult {
119
119
  * Hook 返回值类型
120
120
  */
121
121
  interface UseAutoCrudResourceReturn<TSchema extends z.ZodObject<z.ZodRawShape>, TListItem> {
122
+ /** 主键字段名(默认: "id") */
123
+ idKey?: keyof TListItem & string;
122
124
  tableData: {
123
125
  data: TListItem[];
124
126
  pageCount: number;
@@ -506,6 +508,8 @@ interface AutoTableProps<T extends z.ZodObject<z.ZodRawShape>> {
506
508
  showDefaultExport?: boolean;
507
509
  /** 选中行数变化回调(用于外层组件获知选中状态) */
508
510
  onSelectedCountChange?: (count: number) => void;
511
+ /** 选中行数据变化回调(用于外层组件获知选中行身份变化) */
512
+ onSelectedRowsChange?: (rows: z.infer<T>[]) => void;
509
513
  /** 获取选中行数据的回调(由外层组件调用) */
510
514
  getSelectedRows?: React.MutableRefObject<(() => z.infer<T>[]) | null>;
511
515
  }
@@ -529,6 +533,7 @@ declare function AutoTable<T extends z.ZodObject<z.ZodRawShape>>({
529
533
  enableExport,
530
534
  showDefaultExport,
531
535
  onSelectedCountChange,
536
+ onSelectedRowsChange,
532
537
  getSelectedRows
533
538
  }: AutoTableProps<T>): react_jsx_runtime2.JSX.Element;
534
539
  //#endregion
@@ -823,6 +828,16 @@ type ToolbarCustomActionItem = {
823
828
  };
824
829
  type ToolbarActionItem = ToolbarBuiltinActionItem | ToolbarCustomActionItem;
825
830
  type ToolbarActionConfig = ToolbarActionItem[] | ((defaults: ToolbarBuiltinActionItem[]) => ToolbarActionItem[]);
831
+ interface AutoCrudToolbarContext {
832
+ crudId: string;
833
+ idKey: string;
834
+ rowIds: string[];
835
+ selectedRowIds: string[];
836
+ selectedCount: number;
837
+ openCreate?: () => void;
838
+ }
839
+ type AutoCrudToolbarResolver = (targetId: string, ownerActions: readonly ToolbarActionItem[], context: AutoCrudToolbarContext) => ToolbarActionItem[];
840
+ declare function setToolbarResolver(resolver: AutoCrudToolbarResolver | null): void;
826
841
  /**
827
842
  * AutoCrudTable Props 接口
828
843
  */
@@ -866,7 +881,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
866
881
  batchFields?: (string | BatchUpdateField)[];
867
882
  /**
868
883
  * 多选后悬浮批量操作栏配置
869
- * 用法类同 `actions` 行操作和 `toolbarActions` 顶部工具栏。
884
+ * 用法类同 `actions` 行操作和 `toolbar` 顶部工具栏。
870
885
  * 只传 custom 时保留默认批量操作;包含任意内置 type 时完全接管顺序。
871
886
  */
872
887
  batchActions?: BatchActionConfig<z.output<TSchema>>;
@@ -888,6 +903,8 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
888
903
  * 顶层工具栏操作配置
889
904
  * 用法类同 `actions` 行操作。一旦配置了包含内置 `type` 的数组,它将完全接管右侧工具栏!
890
905
  */
906
+ toolbar?: ToolbarActionConfig;
907
+ /** @deprecated Use toolbar instead. */
891
908
  toolbarActions?: ToolbarActionConfig;
892
909
  /**
893
910
  * 权限配置
@@ -934,6 +951,7 @@ interface AutoCrudTableProps<TSchema extends z.ZodObject<z.ZodRawShape>> {
934
951
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
935
952
  */
936
953
  declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
954
+ id,
937
955
  title,
938
956
  description,
939
957
  schema,
@@ -943,6 +961,7 @@ declare function AutoCrudTable<TSchema extends z.ZodObject<z.ZodRawShape>>({
943
961
  form: formConfig,
944
962
  permissions,
945
963
  actions: actionItems,
964
+ toolbar,
946
965
  toolbarActions,
947
966
  locale: localeProp,
948
967
  onCreate
@@ -1192,12 +1211,12 @@ declare const filterItemSchema: z.ZodObject<{
1192
1211
  variant: z.ZodEnum<{
1193
1212
  number: "number";
1194
1213
  boolean: "boolean";
1195
- text: "text";
1196
- range: "range";
1197
1214
  date: "date";
1198
- dateRange: "dateRange";
1215
+ text: "text";
1199
1216
  select: "select";
1200
1217
  multiSelect: "multiSelect";
1218
+ dateRange: "dateRange";
1219
+ range: "range";
1201
1220
  }>;
1202
1221
  operator: z.ZodEnum<{
1203
1222
  iLike: "iLike";
@@ -1825,4 +1844,4 @@ declare function exportAllToCSV<T extends Record<string, unknown>>(data: T[], op
1825
1844
  */
1826
1845
  declare function downloadCSVTemplate(headers: string[], filename?: string): void;
1827
1846
  //#endregion
1828
- export { type ActionItem, type ActionsColumnConfig, type AutoCrudDataSourceConfig, type AutoCrudDataSourceContext, type AutoCrudDataSourceEntry, type AutoCrudDataSourceLoader, type AutoCrudDataSourceRegistration, type AutoCrudFormComponentConfig, type AutoCrudLocale, type AutoCrudOption, AutoCrudTable, type AutoCrudTableProps, AutoForm, type AutoQueryParams, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type BatchActionConfig, type BatchActionContext, type BatchActionItem, type BatchBuiltinActionItem, type BatchBuiltinActionType, type BatchCustomActionItem, type BatchUpdateField, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExportDialog, type ExportDialogProps, type ExportMode, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldOption, type FieldType, type Fields, type FilterConfig, FilterOperator, type FilterVariant, type FormSchemaOverrides, ImportDialog, type ImportDialogProps, type ImportResult, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, type LocaleProp, MultiCombobox, type MultiComboboxOption, type MultiComboboxProps, type MultiComboboxTriggerRenderProps, Option, type ParsedImportData, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type ToolbarActionItem, type ToolbarBuiltinActionItem, type ToolbarCustomActionItem, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, type UseAutoCrudResourceParams, type UseAutoCrudResourceReturn, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
1847
+ export { type ActionItem, type ActionsColumnConfig, type AutoCrudDataSourceConfig, type AutoCrudDataSourceContext, type AutoCrudDataSourceEntry, type AutoCrudDataSourceLoader, type AutoCrudDataSourceRegistration, type AutoCrudFormComponentConfig, type AutoCrudLocale, type AutoCrudOption, AutoCrudTable, type AutoCrudTableProps, type AutoCrudToolbarContext, type AutoCrudToolbarResolver, AutoForm, type AutoQueryParams, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, type BatchActionConfig, type BatchActionContext, type BatchActionItem, type BatchBuiltinActionItem, type BatchBuiltinActionType, type BatchCustomActionItem, type BatchUpdateField, type ColumnOverrides, type CreateFormSchemaOptions, type CreateTableSchemaOptions, CrudFormModal, type CrudHooks, type CrudOperationPermissions, type CrudPermissions, type DataSource, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableRowAction, DataTableToolbar, DataTableViewOptions, type EnumOption, ExportDialog, type ExportDialogProps, type ExportMode, ExtendedColumnFilter, ExtendedColumnSort, type Field, type FieldOption, type FieldType, type Fields, type FilterConfig, FilterOperator, type FilterVariant, type FormSchemaOverrides, ImportDialog, type ImportDialogProps, type ImportResult, type JSONSchema, type JSONSchemaProperty, JoinOperator, type ListParams, type ListResult, type LocaleProp, MultiCombobox, type MultiComboboxOption, type MultiComboboxProps, type MultiComboboxTriggerRenderProps, Option, type ParsedImportData, type ParsedZodField, type Parser, QueryKeys, SchemaAdapter, type SimpleFieldConfig, type SimpleFieldsConfig, type ToastAdapter, type ToolbarActionConfig, type ToolbarActionItem, type ToolbarBuiltinActionItem, type ToolbarCustomActionItem, type UnifiedField, type UnifiedSchema, type UrlStateOptions, type UseAutoCrudResourceOptions, type UseAutoCrudResourceParams, type UseAutoCrudResourceReturn, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, setToolbarResolver, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
package/dist/index.js CHANGED
@@ -4864,7 +4864,7 @@ const filterModeConfig = {
4864
4864
  tooltip: "Linear-style command filters"
4865
4865
  }
4866
4866
  };
4867
- function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, getSelectedRows }) {
4867
+ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection = true, exclude, actions, pinnedColumns, filterMode = "simple", search = false, onDeleteSelected, onUpdateSelected, batchUpdateFields, actionBarExtra, actionBarActions, initialSorting, enableExport = true, showDefaultExport = true, onSelectedCountChange, onSelectedRowsChange, getSelectedRows }) {
4868
4868
  const modes = filterMode ? Array.isArray(filterMode) ? filterMode : [filterMode] : DEFAULT_MODES;
4869
4869
  const [currentMode, setCurrentMode] = useQueryState("filterMode", parseAsStringEnum(modes).withDefault(modes[0] ?? "simple"));
4870
4870
  const showToggle = modes.length > 1;
@@ -4913,17 +4913,28 @@ function AutoTable({ schema, data, pageCount = 1, overrides, enableRowSelection
4913
4913
  shallow: false,
4914
4914
  clearOnDefault: true
4915
4915
  });
4916
- const getSelectedRowsFn = useCallback(() => table.getFilteredSelectedRowModel().rows.map((row) => row.original), [table]);
4916
+ const rowSelection = table.getState().rowSelection;
4917
+ const columnFilters = table.getState().columnFilters;
4918
+ const selectedRows = useMemo(() => table.getFilteredSelectedRowModel().rows.map((row) => row.original), [
4919
+ table,
4920
+ rowSelection,
4921
+ columnFilters,
4922
+ data
4923
+ ]);
4924
+ const getSelectedRowsFn = useCallback(() => selectedRows, [selectedRows]);
4917
4925
  useEffect(() => {
4918
4926
  if (getSelectedRows) getSelectedRows.current = getSelectedRowsFn;
4919
4927
  return () => {
4920
4928
  if (getSelectedRows) getSelectedRows.current = null;
4921
4929
  };
4922
4930
  }, [getSelectedRows, getSelectedRowsFn]);
4923
- const selectedRowCount = table.getFilteredSelectedRowModel().rows.length;
4931
+ const selectedRowCount = selectedRows.length;
4924
4932
  useEffect(() => {
4925
4933
  onSelectedCountChange?.(selectedRowCount);
4926
4934
  }, [selectedRowCount, onSelectedCountChange]);
4935
+ useEffect(() => {
4936
+ onSelectedRowsChange?.(selectedRows);
4937
+ }, [selectedRows, onSelectedRowsChange]);
4927
4938
  const FilterModeSelect = showToggle ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
4928
4939
  asChild: true,
4929
4940
  children: /* @__PURE__ */ jsx(Button, {
@@ -6232,6 +6243,44 @@ function ImportDialog({ open, onOpenChange, onImport, columns = [], title, local
6232
6243
 
6233
6244
  //#endregion
6234
6245
  //#region src/components/auto-crud/auto-crud-table.tsx
6246
+ let autoCrudToolbarResolver = null;
6247
+ function setToolbarResolver(resolver) {
6248
+ autoCrudToolbarResolver = resolver;
6249
+ }
6250
+ function getDefaultToolbarActions() {
6251
+ return [
6252
+ { type: "import" },
6253
+ { type: "export" },
6254
+ { type: "create" }
6255
+ ];
6256
+ }
6257
+ function resolveOwnerToolbarActions(toolbar) {
6258
+ const resolved = typeof toolbar === "function" ? toolbar(getDefaultToolbarActions()) : toolbar;
6259
+ return resolved !== void 0 && resolved.length > 0 ? [...resolved] : getDefaultToolbarActions();
6260
+ }
6261
+ function readRowIds(rows, idKey) {
6262
+ return rows.flatMap((row) => {
6263
+ const value = row[idKey];
6264
+ return value === null || value === void 0 ? [] : [String(value)];
6265
+ });
6266
+ }
6267
+ function areStringArraysEqual(left, right) {
6268
+ return left.length === right.length && left.every((value, index) => value === right[index]);
6269
+ }
6270
+ function haveSameRowSelection(left, right, idKey) {
6271
+ if (left.length !== right.length) return false;
6272
+ const leftIds = readRowIds(left, idKey);
6273
+ const rightIds = readRowIds(right, idKey);
6274
+ if (leftIds.length === left.length && rightIds.length === right.length) return areStringArraysEqual(leftIds, rightIds);
6275
+ return left.every((row, index) => row === right[index]);
6276
+ }
6277
+ function readCreateAction(actions) {
6278
+ return actions.find((action) => action.type === "create");
6279
+ }
6280
+ function resolveToolbarActionsWithResolver(targetId, ownerActions, context) {
6281
+ const resolver = autoCrudToolbarResolver;
6282
+ return targetId !== void 0 && targetId.length > 0 && resolver !== null ? resolver(targetId, ownerActions, context) : ownerActions;
6283
+ }
6235
6284
  function mergeFieldPart(base, override) {
6236
6285
  if (override === void 0) return base;
6237
6286
  if (override === false || base === false || typeof base !== "object" || typeof override !== "object" || base === null || override === null || Array.isArray(base) || Array.isArray(override)) return override;
@@ -6682,7 +6731,7 @@ function resolveActions(actionsOrFn, defaults, rowActionsLocale) {
6682
6731
  *
6683
6732
  * 高级 CRUD 表格组件,封装了完整的增删改查流程
6684
6733
  */
6685
- function AutoCrudTable({ title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbarActions, locale: localeProp, onCreate }) {
6734
+ function AutoCrudTable({ id, title, description, schema, resource, fields, table: tableConfig, form: formConfig, permissions, actions: actionItems, toolbar, toolbarActions, locale: localeProp, onCreate }) {
6686
6735
  const locale = resolveLocale(localeProp);
6687
6736
  const resolvedSchema = resource.schema ?? schema;
6688
6737
  const resolvedFields = React.useMemo(() => mergeFields(resource.fields, fields) ?? {}, [fields, resource.fields]);
@@ -6697,10 +6746,35 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6697
6746
  const canImport = can.import && !!resource.handlers.import;
6698
6747
  const canExport = can.export;
6699
6748
  const [importOpen, setImportOpen] = React.useState(false);
6700
- const [selectedCount, setSelectedCount] = React.useState(0);
6749
+ const [selectedRows, setSelectedRows] = React.useState([]);
6701
6750
  const [exporting, setExporting] = React.useState(false);
6702
6751
  const getSelectedRowsRef = React.useRef(null);
6703
6752
  const dynamicFilterOptions = useDynamicFilterOptions(resolvedFields);
6753
+ const resourceIdKey = resource.idKey ?? "id";
6754
+ const ownerToolbarActions = React.useMemo(() => resolveOwnerToolbarActions(toolbar ?? toolbarActions), [toolbar, toolbarActions]);
6755
+ const selectedCount = selectedRows.length;
6756
+ const selectedRowIds = React.useMemo(() => readRowIds(selectedRows, resourceIdKey), [selectedRows, resourceIdKey]);
6757
+ const rowIds = React.useMemo(() => readRowIds(resource.tableData.data, resourceIdKey), [resource.tableData.data, resourceIdKey]);
6758
+ const handleSelectedRowsChange = React.useCallback((rows) => {
6759
+ setSelectedRows((currentRows) => haveSameRowSelection(currentRows, rows, resourceIdKey) ? currentRows : rows);
6760
+ }, [resourceIdKey]);
6761
+ const ownerCreateAction = React.useMemo(() => readCreateAction(ownerToolbarActions), [ownerToolbarActions]);
6762
+ const toolbarOpenCreate = can.create ? ownerCreateAction?.onClick ?? onCreate ?? resource.handlers.openCreate : void 0;
6763
+ const resolvedToolbarActions = resolveToolbarActionsWithResolver(id, ownerToolbarActions, React.useMemo(() => ({
6764
+ crudId: id ?? "",
6765
+ idKey: resourceIdKey,
6766
+ rowIds,
6767
+ selectedRowIds,
6768
+ selectedCount,
6769
+ ...toolbarOpenCreate ? { openCreate: toolbarOpenCreate } : {}
6770
+ }), [
6771
+ id,
6772
+ resourceIdKey,
6773
+ rowIds,
6774
+ selectedRowIds,
6775
+ selectedCount,
6776
+ toolbarOpenCreate
6777
+ ]));
6704
6778
  const importColumns = React.useMemo(() => {
6705
6779
  const shape = resolvedSchema.shape;
6706
6780
  const denySet = new Set(denyFields ?? []);
@@ -6710,9 +6784,9 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6710
6784
  const filename = title ?? "export";
6711
6785
  const excludeColumns = denyFields;
6712
6786
  if (mode === "selected") {
6713
- const selectedRows = getSelectedRowsRef.current?.();
6714
- if (!selectedRows || selectedRows.length === 0) return;
6715
- exportAllToCSV(selectedRows, {
6787
+ const selectedRows$1 = getSelectedRowsRef.current?.();
6788
+ if (!selectedRows$1 || selectedRows$1.length === 0) return;
6789
+ exportAllToCSV(selectedRows$1, {
6716
6790
  filename,
6717
6791
  excludeColumns
6718
6792
  });
@@ -6806,11 +6880,6 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6806
6880
  }, "create");
6807
6881
  return null;
6808
6882
  };
6809
- const resolvedToolbarActions = typeof toolbarActions === "function" ? toolbarActions([
6810
- { type: "import" },
6811
- { type: "export" },
6812
- { type: "create" }
6813
- ]) : toolbarActions;
6814
6883
  if (!resolvedToolbarActions || resolvedToolbarActions.length === 0) return /* @__PURE__ */ jsxs("div", {
6815
6884
  className: "flex items-center gap-2",
6816
6885
  children: [
@@ -6868,7 +6937,7 @@ function AutoCrudTable({ title, description, schema, resource, fields, table: ta
6868
6937
  enableExport: canExport,
6869
6938
  showDefaultExport: false,
6870
6939
  initialSorting: tableConfig?.defaultSort,
6871
- onSelectedCountChange: setSelectedCount,
6940
+ onSelectedRowsChange: handleSelectedRowsChange,
6872
6941
  getSelectedRows: getSelectedRowsRef
6873
6942
  }),
6874
6943
  /* @__PURE__ */ jsx(CrudFormModal, {
@@ -7943,6 +8012,7 @@ function useAutoCrudResource({ router, schema, query: queryTransform, options =
7943
8012
  ]);
7944
8013
  const canExport = !!(exportFetcher || exportQuery);
7945
8014
  return {
8015
+ idKey,
7946
8016
  tableData: {
7947
8017
  data: tableRows,
7948
8018
  pageCount: listQuery.data?.pageCount ?? 0,
@@ -8282,4 +8352,4 @@ function createMemoryDataSource(initialData = []) {
8282
8352
  }
8283
8353
 
8284
8354
  //#endregion
8285
- export { AutoCrudTable, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, CrudFormModal, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, ExportDialog, ImportDialog, MultiCombobox, SchemaAdapter, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
8355
+ export { AutoCrudTable, AutoForm, AutoTable, AutoTableActionBar, AutoTableSimpleFilters, CrudFormModal, DataTable, DataTableAdvancedToolbar, DataTableColumnHeader, DataTableFacetedFilter, DataTablePagination, DataTableToolbar, DataTableViewOptions, ExportDialog, ImportDialog, MultiCombobox, SchemaAdapter, cn, coerceRowValues, components, createActionsColumn, createEditFormSchema, createFormSchema, createMemoryDataSource, createSelectColumn, createTRPCDataSource, createTableSchema, dataSources, dataToCSV, deDE, downloadCSVTemplate, enUS, esES, exportAllToCSV, exportTableToCSV, formComponents, formatDate, frFR, generateCSVTemplate, getUrlParams, humanize, jaJP, koKR, noopToastAdapter, normalizeDataSourceConfig, normalizeOptions, parseAsArrayOf, parseAsInteger, parseAsString, parseAsStringEnum, parseCSV, parseImportFile, parseJSON, parseZodField, resolveLocale, setSearchParams, setToolbarResolver, useAutoCrudResource, useDataTable, useQueryState, useQueryStates, useReadableFilters, useUrlState, useUrlStates, zhCN };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wordrhyme/auto-crud",
3
3
  "type": "module",
4
- "version": "1.2.3",
4
+ "version": "1.2.5",
5
5
  "description": "Schema-first CRUD components with auto-generated tables and forms",
6
6
  "author": "wordrhyme",
7
7
  "license": "MIT",
@@ -86,8 +86,8 @@
86
86
  "tsdown": "^0.15.12",
87
87
  "typescript": "^5.9.3",
88
88
  "vitest": "^3.2.4",
89
- "@internal/eslint-config": "0.3.0",
90
89
  "@internal/prettier-config": "0.0.1",
90
+ "@internal/eslint-config": "0.3.0",
91
91
  "@internal/tsconfig": "0.1.0",
92
92
  "@internal/tsdown-config": "0.1.0",
93
93
  "@internal/vitest-config": "0.1.0"