@aloudata/aloudata-design 3.0.0-beta.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/dist/AProgress/index.d.ts +1 -1
  2. package/dist/AProgress/index.js +19 -5
  3. package/dist/AProgress/index.js.map +1 -1
  4. package/dist/Alert/index.d.ts +1 -1
  5. package/dist/Alert/index.js +22 -8
  6. package/dist/Alert/index.js.map +1 -1
  7. package/dist/Avatar/component/Avatar/index.d.ts +1 -1
  8. package/dist/Avatar/component/Avatar/index.js +4 -4
  9. package/dist/Avatar/component/Avatar/index.js.map +1 -1
  10. package/dist/Avatar/component/Avatar/type.d.ts +1 -1
  11. package/dist/Avatar/component/Avatar/type.js +6 -1
  12. package/dist/Avatar/component/Avatar/type.js.map +1 -1
  13. package/dist/Avatar/index.js +67 -8
  14. package/dist/Avatar/index.js.map +1 -1
  15. package/dist/Badge/index.d.ts +1 -0
  16. package/dist/Badge/index.js +32 -9
  17. package/dist/Badge/index.js.map +1 -1
  18. package/dist/Breadcrumb/index.js +21 -12
  19. package/dist/Breadcrumb/index.js.map +1 -1
  20. package/dist/Button/index.d.ts +2 -0
  21. package/dist/Button/index.js +39 -32
  22. package/dist/Button/index.js.map +1 -1
  23. package/dist/Card/index.js +5 -5
  24. package/dist/Card/index.js.map +1 -1
  25. package/dist/Checkbox/index.js +5 -12
  26. package/dist/Checkbox/index.js.map +1 -1
  27. package/dist/Checkbox/type.d.ts +3 -1
  28. package/dist/Collapse/index.js +40 -24
  29. package/dist/Collapse/index.js.map +1 -1
  30. package/dist/DataPreviewTable/components/Body/Cell.js +5 -4
  31. package/dist/DataPreviewTable/components/Body/Cell.js.map +1 -1
  32. package/dist/DataPreviewTable/components/Body/Error.js +1 -1
  33. package/dist/DataPreviewTable/components/Body/Error.js.map +1 -1
  34. package/dist/DataPreviewTable/components/Body/index.js +2 -1
  35. package/dist/DataPreviewTable/components/Body/index.js.map +1 -1
  36. package/dist/DataPreviewTable/components/DragBar/index.js +1 -1
  37. package/dist/DataPreviewTable/components/DragBar/index.js.map +1 -1
  38. package/dist/DataPreviewTable/components/Header/index.js +14 -12
  39. package/dist/DataPreviewTable/components/Header/index.js.map +1 -1
  40. package/dist/DataPreviewTable/index.js +5 -6
  41. package/dist/DataPreviewTable/index.js.map +1 -1
  42. package/dist/DatePicker/index.d.ts +4 -0
  43. package/dist/DatePicker/index.js +8 -6
  44. package/dist/DatePicker/index.js.map +1 -1
  45. package/dist/Drawer/index.d.ts +1 -0
  46. package/dist/Drawer/index.js +102 -47
  47. package/dist/Drawer/index.js.map +1 -1
  48. package/dist/Dropdown/index.d.ts +5 -0
  49. package/dist/Dropdown/index.js +155 -34
  50. package/dist/Dropdown/index.js.map +1 -1
  51. package/dist/Form/index.d.ts +45 -5
  52. package/dist/Form/index.js +59 -34
  53. package/dist/Form/index.js.map +1 -1
  54. package/dist/HighlightText/index.js +1 -1
  55. package/dist/HighlightText/index.js.map +1 -1
  56. package/dist/Input/components/Input/index.d.ts +5 -2
  57. package/dist/Input/components/Input/index.js +18 -6
  58. package/dist/Input/components/Input/index.js.map +1 -1
  59. package/dist/InputNumber/type.d.ts +2 -2
  60. package/dist/InputSearch/index.js +0 -1
  61. package/dist/InputSearch/index.js.map +1 -1
  62. package/dist/Layout/index.js +1 -1
  63. package/dist/Layout/index.js.map +1 -1
  64. package/dist/LogicTree/DisplayLogicTree.d.ts +1 -1
  65. package/dist/LogicTree/DisplayLogicTree.js.map +1 -1
  66. package/dist/LogicTree/components/DisplayLogicItem/index.d.ts +1 -1
  67. package/dist/LogicTree/components/DisplayLogicItem/index.js +1 -1
  68. package/dist/LogicTree/components/DisplayLogicItem/index.js.map +1 -1
  69. package/dist/LogicTree/components/LogicItem/index.js +2 -3
  70. package/dist/LogicTree/components/LogicItem/index.js.map +1 -1
  71. package/dist/LogicTree/index.d.ts +1 -1
  72. package/dist/LogicTree/index.js +26 -10
  73. package/dist/LogicTree/index.js.map +1 -1
  74. package/dist/MemberPicker/components/NickLabel.js +1 -1
  75. package/dist/MemberPicker/components/NickLabel.js.map +1 -1
  76. package/dist/MemberPicker/components/Panel.js +13 -14
  77. package/dist/MemberPicker/components/Panel.js.map +1 -1
  78. package/dist/MemberPicker/index.js +10 -5
  79. package/dist/MemberPicker/index.js.map +1 -1
  80. package/dist/Menu/index.d.ts +4 -0
  81. package/dist/Menu/index.js +35 -13
  82. package/dist/Menu/index.js.map +1 -1
  83. package/dist/Modal/index.d.ts +5 -2
  84. package/dist/Modal/index.js +119 -66
  85. package/dist/Modal/index.js.map +1 -1
  86. package/dist/Popconfirm/index.js +6 -1
  87. package/dist/Popconfirm/index.js.map +1 -1
  88. package/dist/Popover/index.js +5 -3
  89. package/dist/Popover/index.js.map +1 -1
  90. package/dist/Progress/index.d.ts +0 -3
  91. package/dist/Progress/index.js +0 -3
  92. package/dist/Progress/index.js.map +1 -1
  93. package/dist/Radio/components/Radio/index.js +14 -25
  94. package/dist/Radio/components/Radio/index.js.map +1 -1
  95. package/dist/RenameInput/index.js +0 -1
  96. package/dist/RenameInput/index.js.map +1 -1
  97. package/dist/Select/BaseSelect.js +12 -7
  98. package/dist/Select/BaseSelect.js.map +1 -1
  99. package/dist/Select/Selector/MultipleSelector.js +10 -6
  100. package/dist/Select/Selector/MultipleSelector.js.map +1 -1
  101. package/dist/Select/Selector/index.d.ts +2 -0
  102. package/dist/Select/Selector/index.js +1 -1
  103. package/dist/Select/Selector/index.js.map +1 -1
  104. package/dist/Select/components/Suffix.js +1 -1
  105. package/dist/Select/components/Suffix.js.map +1 -1
  106. package/dist/Select/interface.d.ts +4 -0
  107. package/dist/Select/utils/getWidthStyle.js.map +1 -1
  108. package/dist/Steps/index.js +6 -6
  109. package/dist/Steps/index.js.map +1 -1
  110. package/dist/Switch/index.js +21 -7
  111. package/dist/Switch/index.js.map +1 -1
  112. package/dist/Table/components/Footer/index.js +1 -1
  113. package/dist/Table/components/Footer/index.js.map +1 -1
  114. package/dist/Table/hooks/useRowDnd.js +2 -8
  115. package/dist/Table/hooks/useRowDnd.js.map +1 -1
  116. package/dist/Table/hooks/useRowSelection.d.ts +1 -1
  117. package/dist/Table/hooks/useRowSelection.js +7 -9
  118. package/dist/Table/hooks/useRowSelection.js.map +1 -1
  119. package/dist/Table/index.js +1 -1
  120. package/dist/Table/index.js.map +1 -1
  121. package/dist/Tabs/index.js +37 -30
  122. package/dist/Tabs/index.js.map +1 -1
  123. package/dist/Tooltip/index.js +5 -3
  124. package/dist/Tooltip/index.js.map +1 -1
  125. package/dist/Tour/index.js +48 -38
  126. package/dist/Tour/index.js.map +1 -1
  127. package/dist/Tree/DirectoryTree.d.ts +2 -2
  128. package/dist/Tree/DirectoryTree.js.map +1 -1
  129. package/dist/Tree/Tree.d.ts +2 -2
  130. package/dist/Tree/Tree2.js +2 -2
  131. package/dist/Tree/Tree2.js.map +1 -1
  132. package/dist/Upload/index.d.ts +15 -2
  133. package/dist/Upload/index.js +4 -2
  134. package/dist/Upload/index.js.map +1 -1
  135. package/dist/_utils/floatingLayer.d.ts +15 -0
  136. package/dist/_utils/floatingLayer.js +30 -0
  137. package/dist/_utils/floatingLayer.js.map +1 -0
  138. package/dist/_utils/storybookArgTypes.d.ts +11 -0
  139. package/dist/_utils/storybookArgTypes.js +2 -0
  140. package/dist/aloudata-design.css +1 -1
  141. package/dist/index.d.ts +15 -6
  142. package/dist/index.js +8 -3
  143. package/dist/theme/createTheme.d.ts +2 -0
  144. package/dist/theme/createTheme.js +46 -0
  145. package/dist/theme/createTheme.js.map +1 -0
  146. package/dist/theme/defaultTheme.d.ts +2 -0
  147. package/dist/theme/defaultTheme.js +19 -0
  148. package/dist/theme/defaultTheme.js.map +1 -0
  149. package/dist/theme/index.d.ts +5 -0
  150. package/dist/theme/index.js +4 -0
  151. package/dist/theme/initAldTheme.d.ts +2 -0
  152. package/dist/theme/initAldTheme.js +26 -0
  153. package/dist/theme/initAldTheme.js.map +1 -0
  154. package/dist/theme/themeToCssVars.d.ts +2 -0
  155. package/dist/theme/themeToCssVars.js +144 -0
  156. package/dist/theme/themeToCssVars.js.map +1 -0
  157. package/dist/theme/tokenMap.d.ts +5 -0
  158. package/dist/theme/tokenMap.js +12 -0
  159. package/dist/theme/tokenMap.js.map +1 -0
  160. package/dist/theme/types.d.ts +20 -0
  161. package/dist/theme/types.js +2 -0
  162. package/dist/theme.d.ts +2 -0
  163. package/package.json +8 -3
  164. package/dist/_utils/SimpleOverflow.d.ts +0 -14
  165. package/dist/_utils/SimpleOverflow.js +0 -61
  166. package/dist/_utils/SimpleOverflow.js.map +0 -1
@@ -28,10 +28,11 @@ function useRowSelection(props) {
28
28
  }, [getAllSelectedRows, rowSelection]);
29
29
  const checkboxAllStatus = getCheckboxAllStatus(allDataForSelection, selectedRowKeys, rowKey, rowSelection?.getCheckboxProps);
30
30
  const selectAll = useCallback(() => {
31
- changeSelectedRowKeys(allDataForSelection.map((record) => getRowKey(record, rowKey)));
31
+ changeSelectedRowKeys(getDataWithoutDisabled(allDataForSelection, rowSelection?.getCheckboxProps).map((record) => getRowKey(record, rowKey)));
32
32
  }, [
33
33
  allDataForSelection,
34
34
  rowKey,
35
+ rowSelection?.getCheckboxProps,
35
36
  changeSelectedRowKeys
36
37
  ]);
37
38
  const unSelectAll = useCallback(() => {
@@ -143,14 +144,11 @@ function useRowSelection(props) {
143
144
  };
144
145
  }
145
146
  function getCheckboxAllStatus(data, selectedRowKeys, rowKey, getCheckboxProps) {
146
- const selectedKeysInData = data.map((record) => {
147
- const key = getRowKey(record, rowKey);
148
- if (selectedRowKeys.includes(key)) return key;
149
- return null;
150
- }).filter((key) => key !== null);
151
- if (selectedKeysInData.length === 0) return "none";
152
- const dataWithoutDisabled = getDataWithoutDisabled(data, getCheckboxProps);
153
- if (selectedKeysInData.length === dataWithoutDisabled.length) return "all";
147
+ const enabledData = getDataWithoutDisabled(data, getCheckboxProps);
148
+ if (enabledData.length === 0) return "none";
149
+ const selectedEnabledCount = enabledData.filter((record) => selectedRowKeys.includes(getRowKey(record, rowKey))).length;
150
+ if (selectedEnabledCount === 0) return "none";
151
+ if (selectedEnabledCount === enabledData.length) return "all";
154
152
  return "indeterminate";
155
153
  }
156
154
  function getDataWithoutDisabled(data, getCheckboxProps) {
@@ -1 +1 @@
1
- {"version":3,"file":"useRowSelection.js","names":[],"sources":["../../../src/Table/hooks/useRowSelection.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport Checkbox from '../../Checkbox';\nimport { getRowKey, hasFixedLeftColumn, prefixCls } from '../helper';\nimport { IRowSelection, ITableColumn, ITableProps } from '../types';\n\nexport default function useRowSelection<TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n isExpandable?: boolean;\n flattenData?: TDataItem[];\n },\n): IRowSelectionInfo<TDataItem> {\n const { columns, rowSelection, rowKey, data, isExpandable, flattenData } =\n props;\n\n const [selectedRowKeysState, setSelectedRowKeysState] = useState(\n rowSelection?.selectedRowKeys || rowSelection?.defaultSelectedRowKeys || [],\n );\n\n const selectedRowKeys = rowSelection?.selectedRowKeys || selectedRowKeysState;\n\n const getSelectedRows = useCallback(\n (rowKeys: string[]) => {\n return data.filter((record) =>\n rowKeys.includes(getRowKey(record, rowKey)),\n );\n },\n [data, rowKey],\n );\n\n // 获取用于全选状态计算和数据获取的完整数据\n const allDataForSelection = useMemo(() => {\n // 如果开启了 expandable,使用扁平化后的数据\n if (isExpandable && flattenData) {\n return flattenData;\n }\n // 否则使用原始数据\n return data;\n }, [isExpandable, flattenData, data]);\n\n // 从完整数据中获取选中的行\n const getAllSelectedRows = useCallback(\n (rowKeys: string[]) => {\n return allDataForSelection.filter((record) =>\n rowKeys.includes(getRowKey(record, rowKey)),\n );\n },\n [allDataForSelection, rowKey],\n );\n\n const changeSelectedRowKeys = useCallback(\n (newSelectedRowKeys: string[]) => {\n setSelectedRowKeysState(newSelectedRowKeys);\n\n // 获取所有选中的行数据(包括被折叠的子项)\n const allSelectedRows = getAllSelectedRows(newSelectedRowKeys);\n rowSelection?.onChange?.(newSelectedRowKeys, allSelectedRows);\n },\n [getAllSelectedRows, rowSelection],\n );\n\n const checkboxAllStatus = getCheckboxAllStatus(\n allDataForSelection,\n selectedRowKeys,\n rowKey,\n rowSelection?.getCheckboxProps,\n );\n\n const selectAll = useCallback(() => {\n const newKeys = allDataForSelection.map((record) =>\n getRowKey(record, rowKey),\n );\n\n changeSelectedRowKeys(newKeys);\n }, [allDataForSelection, rowKey, changeSelectedRowKeys]);\n\n const unSelectAll = useCallback(() => {\n changeSelectedRowKeys([]);\n }, [changeSelectedRowKeys]);\n\n const onClickAllCheckbox = useCallback<(e?: React.MouseEvent) => void>(() => {\n if (checkboxAllStatus === 'all') {\n unSelectAll();\n } else {\n selectAll();\n }\n }, [checkboxAllStatus, unSelectAll, selectAll]);\n\n // 获取节点的所有子孙节点keys\n const getDescendantKeys = useCallback(\n (parentKey: string): string[] => {\n return getNodeDescendants(parentKey, isExpandable, flattenData, rowKey);\n },\n [isExpandable, flattenData, rowKey],\n );\n\n // 获取节点的所有祖先节点keys\n const getAncestorKeys = useCallback(\n (targetKey: string): string[] => {\n return getNodeAncestors(targetKey, isExpandable, flattenData, rowKey);\n },\n [isExpandable, flattenData, rowKey],\n );\n\n // 获取节点的选择状态(考虑子节点状态)\n const getNodeCheckStatus = useCallback(\n (nodeKey: string): { checked: boolean; indeterminate: boolean } => {\n return calculateNodeCheckStatus(\n nodeKey,\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n );\n },\n [\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n ],\n );\n\n const onClickCheckbox = useCallback(\n (key: string, isChecked: boolean) => () => {\n const newKeys = calculateCascadeSelection(\n key,\n isChecked,\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n getAncestorKeys,\n );\n\n changeSelectedRowKeys(newKeys);\n },\n [\n selectedRowKeys,\n changeSelectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n getAncestorKeys,\n ],\n );\n\n // 全选按钮\n const getCheckboxAllNode = (children?: React.ReactNode) => (\n <div className={prefixCls('row-selection-all')}>\n <Checkbox\n onClick={onClickAllCheckbox}\n checked={checkboxAllStatus === 'all'}\n indeterminate={checkboxAllStatus === 'indeterminate'}\n >\n {children}\n </Checkbox>\n </div>\n );\n\n if (!rowSelection) {\n return {\n columns,\n isRowSelectionEnabled: false,\n getCheckboxAllNode,\n selectedRowKeys: [],\n selectedRowKeysInCurrPage: [],\n unSelectAll,\n isShowRowSelectionInFooter: false,\n items: [],\n onChange: () => {},\n };\n }\n\n if (!rowKey) {\n throw new Error('rowKey is required when rowSelection is enabled');\n }\n\n const fixed = !!rowSelection.fixed || hasFixedLeftColumn(columns);\n\n const rowSelectionColumn: ITableColumn<TDataItem> = {\n dataIndex: '',\n title: (\n <div className={prefixCls('row-selection-all-header-wrap')}>\n {getCheckboxAllNode()}\n </div>\n ),\n width: 48,\n render: (text: unknown, record: TDataItem) => {\n const key = getRowKey(record, rowKey);\n const nodeStatus = getNodeCheckStatus(key);\n const checkboxProps = rowSelection.getCheckboxProps?.(record) || {};\n\n return (\n <div className={prefixCls('row-selection-item')}>\n <Checkbox\n onClick={onClickCheckbox(\n key,\n nodeStatus.checked || nodeStatus.indeterminate,\n )}\n checked={nodeStatus.checked}\n indeterminate={nodeStatus.indeterminate}\n {...checkboxProps}\n />\n </div>\n );\n },\n fixed: fixed ? 'left' : undefined,\n };\n\n const selectedRowKeysInCurrPage = getDataWithoutDisabled(\n data,\n rowSelection.getCheckboxProps,\n )\n .map((record) => getRowKey(record, rowKey))\n .filter((key) => selectedRowKeys.includes(key));\n\n const isShowRowSelectionInFooter = selectedRowKeysInCurrPage.length > 0;\n\n const items =\n rowSelection.items?.map((operationItem) => ({\n ...operationItem,\n onClick: (e: React.MouseEvent) => {\n operationItem.onClick(\n selectedRowKeysInCurrPage,\n getSelectedRows(selectedRowKeysInCurrPage),\n e,\n );\n },\n })) || [];\n\n return {\n columns: [rowSelectionColumn, ...columns],\n isRowSelectionEnabled: true,\n getCheckboxAllNode,\n selectedRowKeys: selectedRowKeys, // 返回完整的选中项列表\n selectedRowKeysInCurrPage, // 当前页面可见的选中项\n unSelectAll,\n isShowRowSelectionInFooter,\n items,\n onChange: changeSelectedRowKeys,\n };\n}\n\nfunction getCheckboxAllStatus<TDataItem extends object>(\n data: TDataItem[],\n selectedRowKeys: string[],\n rowKey: ITableProps<TDataItem>['rowKey'],\n getCheckboxProps?: IRowSelection<TDataItem>['getCheckboxProps'],\n): 'all' | 'none' | 'indeterminate' {\n const selectedKeysInData = data\n .map((record) => {\n const key = getRowKey(record, rowKey);\n if (selectedRowKeys.includes(key)) {\n return key;\n }\n return null;\n })\n .filter((key) => key !== null);\n\n if (selectedKeysInData.length === 0) {\n return 'none';\n }\n const dataWithoutDisabled = getDataWithoutDisabled(data, getCheckboxProps);\n if (selectedKeysInData.length === dataWithoutDisabled.length) {\n return 'all';\n }\n return 'indeterminate';\n}\n\nfunction getDataWithoutDisabled<TDataItem extends object>(\n data: TDataItem[],\n getCheckboxProps?: IRowSelection<TDataItem>['getCheckboxProps'],\n) {\n return data.filter((record) => {\n const checkboxProps = getCheckboxProps?.(record) || {};\n const { disabled } = checkboxProps;\n return !disabled;\n });\n}\n\nexport interface IRowSelectionInfo<TDataItem extends object> {\n columns: ITableProps<TDataItem>['columns'];\n isRowSelectionEnabled: boolean;\n getCheckboxAllNode: ((children?: React.ReactNode) => React.ReactNode) | null;\n selectedRowKeys: string[]; // 完整的选中项列表\n selectedRowKeysInCurrPage: string[]; // 当前页面可见的选中项\n unSelectAll: (e: React.MouseEvent) => void;\n isShowRowSelectionInFooter: boolean;\n items: {\n key: string;\n label: React.ReactNode;\n onClick: (e: React.MouseEvent) => void;\n }[];\n onChange: (selectedRowKeys: string[]) => void;\n}\n\n/**\n * 获取节点的所有子孙节点keys\n * @param parentKey 父节点key\n * @param isExpandable 是否启用展开功能\n * @param flattenData 扁平化后的数据(包含所有节点,包括子节点)\n * @param rowKey 行key获取函数\n * @returns 子孙节点keys数组\n */\nexport function getNodeDescendants<TDataItem extends object>(\n parentKey: string,\n isExpandable?: boolean,\n flattenData?: TDataItem[],\n rowKey?: ITableProps<TDataItem>['rowKey'],\n): string[] {\n if (!isExpandable || !flattenData || !rowKey) return [];\n\n const descendants: string[] = [];\n\n // 找到父节点在flattenData中的记录\n const parentNode = flattenData.find(\n (item) => getRowKey(item, rowKey) === parentKey,\n );\n if (!parentNode) return [];\n\n // 从原始节点的children中收集所有子孙节点\n const collectDescendants = (node: any) => {\n const children = node.children || [];\n children.forEach((child: any) => {\n const childKey = getRowKey(child, rowKey);\n descendants.push(childKey);\n collectDescendants(child);\n });\n };\n\n collectDescendants(parentNode);\n return descendants;\n}\n\n/**\n * 获取节点的所有祖先节点keys\n * @param targetKey 目标节点key\n * @param isExpandable 是否启用展开功能\n * @param flattenData 扁平化后的数据\n * @param rowKey 行key获取函数\n * @returns 祖先节点keys数组(从直接父节点到根节点)\n */\nexport function getNodeAncestors<TDataItem extends object>(\n targetKey: string,\n isExpandable?: boolean,\n flattenData?: TDataItem[],\n rowKey?: ITableProps<TDataItem>['rowKey'],\n): string[] {\n if (!isExpandable || !flattenData || !rowKey) return [];\n\n const ancestors: string[] = [];\n\n // 找到目标节点的直接父节点\n const findDirectParent = (childKey: string): TDataItem | null => {\n for (const item of flattenData) {\n const children = (item as any).children || [];\n if (\n children.some((child: any) => getRowKey(child, rowKey) === childKey)\n ) {\n return item;\n }\n }\n return null;\n };\n\n let currentKey = targetKey;\n\n for (;;) {\n const parent = findDirectParent(currentKey);\n if (!parent) break;\n\n const parentKey = getRowKey(parent, rowKey);\n ancestors.push(parentKey);\n currentKey = parentKey;\n }\n\n return ancestors;\n}\n\n/**\n * 计算级联选择后的keys(包含向上级联)\n * @param targetKey 被操作的节点key\n * @param isChecked 当前是否选中\n * @param currentSelectedKeys 当前已选中的keys\n * @param checkStrictly 是否严格模式\n * @param isExpandable 是否启用展开功能\n * @param getDescendantKeys 获取子孙节点keys的函数\n * @param getAncestorKeys 获取祖先节点keys的函数\n * @returns 新的选中keys\n */\nexport function calculateCascadeSelection(\n targetKey: string,\n isChecked: boolean,\n currentSelectedKeys: string[],\n checkStrictly?: boolean,\n isExpandable?: boolean,\n getDescendantKeys?: (nodeKey: string) => string[],\n getAncestorKeys?: (nodeKey: string) => string[],\n): string[] {\n if (\n checkStrictly ||\n !isExpandable ||\n !getDescendantKeys ||\n !getAncestorKeys\n ) {\n // 严格模式,不进行级联\n return isChecked\n ? currentSelectedKeys.filter((key) => key !== targetKey)\n : [...currentSelectedKeys, targetKey];\n }\n\n let newKeys = [...currentSelectedKeys];\n\n if (isChecked) {\n // 取消选择:移除目标节点和所有子孙节点\n newKeys = newKeys.filter((key) => key !== targetKey);\n const descendants = getDescendantKeys(targetKey);\n newKeys = newKeys.filter((key) => !descendants.includes(key));\n\n // 向上级联:检查父节点是否需要取消选择\n const ancestors = getAncestorKeys(targetKey);\n ancestors.forEach((ancestorKey) => {\n const ancestorDescendants = getDescendantKeys(ancestorKey);\n const selectedDescendantsCount = ancestorDescendants.filter((key) =>\n newKeys.includes(key),\n ).length;\n\n // 如果子孙节点没有全部选中,则父节点也应该取消选择\n if (selectedDescendantsCount < ancestorDescendants.length) {\n newKeys = newKeys.filter((key) => key !== ancestorKey);\n }\n });\n } else {\n // 选择:添加目标节点和所有子孙节点\n if (!newKeys.includes(targetKey)) {\n newKeys.push(targetKey);\n }\n const descendants = getDescendantKeys(targetKey);\n descendants.forEach((descendantKey) => {\n if (!newKeys.includes(descendantKey)) {\n newKeys.push(descendantKey);\n }\n });\n\n // 向上级联:检查父节点是否需要选择\n const ancestors = getAncestorKeys(targetKey);\n ancestors.forEach((ancestorKey) => {\n const ancestorDescendants = getDescendantKeys(ancestorKey);\n const selectedDescendantsCount = ancestorDescendants.filter((key) =>\n newKeys.includes(key),\n ).length;\n\n // 如果所有子孙节点都被选中,则父节点也应该被选中\n if (\n selectedDescendantsCount === ancestorDescendants.length &&\n !newKeys.includes(ancestorKey)\n ) {\n newKeys.push(ancestorKey);\n }\n });\n }\n\n return newKeys;\n}\n\n/**\n * 计算节点的选择状态(考虑子节点状态)\n * @param nodeKey 节点key\n * @param selectedRowKeys 已选中的keys\n * @param checkStrictly 是否严格模式\n * @param isExpandable 是否启用展开功能\n * @param getDescendantKeys 获取子孙节点keys的函数\n * @returns 节点的选择状态\n */\nexport function calculateNodeCheckStatus(\n nodeKey: string,\n selectedRowKeys: string[],\n checkStrictly?: boolean,\n isExpandable?: boolean,\n getDescendantKeys?: (nodeKey: string) => string[],\n): { checked: boolean; indeterminate: boolean } {\n if (checkStrictly || !isExpandable || !getDescendantKeys) {\n // 严格模式下或非展开模式,直接返回节点本身的选择状态\n return {\n checked: selectedRowKeys.includes(nodeKey),\n indeterminate: false,\n };\n }\n\n const descendants = getDescendantKeys(nodeKey);\n\n // 如果没有子节点,直接返回本身状态\n if (descendants.length === 0) {\n return {\n checked: selectedRowKeys.includes(nodeKey),\n indeterminate: false,\n };\n }\n\n const selectedDescendants = descendants.filter((key) =>\n selectedRowKeys.includes(key),\n );\n const isNodeSelected = selectedRowKeys.includes(nodeKey);\n\n if (isNodeSelected && selectedDescendants.length === descendants.length) {\n // 节点本身选中且所有子节点都选中\n return { checked: true, indeterminate: false };\n } else if (!isNodeSelected && selectedDescendants.length === 0) {\n // 节点本身未选中且所有子节点都未选中\n return { checked: false, indeterminate: false };\n } else {\n // 部分选中的情况:节点选中但子节点未全选,或节点未选中但部分子节点选中\n return { checked: false, indeterminate: true };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useRowSelection.js","names":[],"sources":["../../../src/Table/hooks/useRowSelection.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport Checkbox from '../../Checkbox';\nimport { getRowKey, hasFixedLeftColumn, prefixCls } from '../helper';\nimport { IRowSelection, ITableColumn, ITableProps } from '../types';\n\nexport default function useRowSelection<TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n isExpandable?: boolean;\n flattenData?: TDataItem[];\n },\n): IRowSelectionInfo<TDataItem> {\n const { columns, rowSelection, rowKey, data, isExpandable, flattenData } =\n props;\n\n const [selectedRowKeysState, setSelectedRowKeysState] = useState(\n rowSelection?.selectedRowKeys || rowSelection?.defaultSelectedRowKeys || [],\n );\n\n const selectedRowKeys = rowSelection?.selectedRowKeys || selectedRowKeysState;\n\n const getSelectedRows = useCallback(\n (rowKeys: string[]) => {\n return data.filter((record) =>\n rowKeys.includes(getRowKey(record, rowKey)),\n );\n },\n [data, rowKey],\n );\n\n // 获取用于全选状态计算和数据获取的完整数据\n const allDataForSelection = useMemo(() => {\n // 如果开启了 expandable,使用扁平化后的数据\n if (isExpandable && flattenData) {\n return flattenData;\n }\n // 否则使用原始数据\n return data;\n }, [isExpandable, flattenData, data]);\n\n // 从完整数据中获取选中的行\n const getAllSelectedRows = useCallback(\n (rowKeys: string[]) => {\n return allDataForSelection.filter((record) =>\n rowKeys.includes(getRowKey(record, rowKey)),\n );\n },\n [allDataForSelection, rowKey],\n );\n\n const changeSelectedRowKeys = useCallback(\n (newSelectedRowKeys: string[]) => {\n setSelectedRowKeysState(newSelectedRowKeys);\n\n // 获取所有选中的行数据(包括被折叠的子项)\n const allSelectedRows = getAllSelectedRows(newSelectedRowKeys);\n rowSelection?.onChange?.(newSelectedRowKeys, allSelectedRows);\n },\n [getAllSelectedRows, rowSelection],\n );\n\n const checkboxAllStatus = getCheckboxAllStatus(\n allDataForSelection,\n selectedRowKeys,\n rowKey,\n rowSelection?.getCheckboxProps,\n );\n\n const selectAll = useCallback(() => {\n const newKeys = getDataWithoutDisabled(\n allDataForSelection,\n rowSelection?.getCheckboxProps,\n ).map((record) => getRowKey(record, rowKey));\n\n changeSelectedRowKeys(newKeys);\n }, [\n allDataForSelection,\n rowKey,\n rowSelection?.getCheckboxProps,\n changeSelectedRowKeys,\n ]);\n\n const unSelectAll = useCallback(() => {\n changeSelectedRowKeys([]);\n }, [changeSelectedRowKeys]);\n\n const onClickAllCheckbox = useCallback<(e?: React.MouseEvent) => void>(() => {\n if (checkboxAllStatus === 'all') {\n unSelectAll();\n } else {\n selectAll();\n }\n }, [checkboxAllStatus, unSelectAll, selectAll]);\n\n // 获取节点的所有子孙节点keys\n const getDescendantKeys = useCallback(\n (parentKey: string): string[] => {\n return getNodeDescendants(parentKey, isExpandable, flattenData, rowKey);\n },\n [isExpandable, flattenData, rowKey],\n );\n\n // 获取节点的所有祖先节点keys\n const getAncestorKeys = useCallback(\n (targetKey: string): string[] => {\n return getNodeAncestors(targetKey, isExpandable, flattenData, rowKey);\n },\n [isExpandable, flattenData, rowKey],\n );\n\n // 获取节点的选择状态(考虑子节点状态)\n const getNodeCheckStatus = useCallback(\n (nodeKey: string): { checked: boolean; indeterminate: boolean } => {\n return calculateNodeCheckStatus(\n nodeKey,\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n );\n },\n [\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n ],\n );\n\n const onClickCheckbox = useCallback(\n (key: string, isChecked: boolean) => () => {\n const newKeys = calculateCascadeSelection(\n key,\n isChecked,\n selectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n getAncestorKeys,\n );\n\n changeSelectedRowKeys(newKeys);\n },\n [\n selectedRowKeys,\n changeSelectedRowKeys,\n rowSelection?.checkStrictly,\n isExpandable,\n getDescendantKeys,\n getAncestorKeys,\n ],\n );\n\n // 全选按钮\n const getCheckboxAllNode = (children?: React.ReactNode) => (\n <div className={prefixCls('row-selection-all')}>\n <Checkbox\n onClick={onClickAllCheckbox}\n checked={checkboxAllStatus === 'all'}\n indeterminate={checkboxAllStatus === 'indeterminate'}\n >\n {children}\n </Checkbox>\n </div>\n );\n\n if (!rowSelection) {\n return {\n columns,\n isRowSelectionEnabled: false,\n getCheckboxAllNode,\n selectedRowKeys: [],\n selectedRowKeysInCurrPage: [],\n unSelectAll,\n isShowRowSelectionInFooter: false,\n items: [],\n onChange: () => {},\n };\n }\n\n if (!rowKey) {\n throw new Error('rowKey is required when rowSelection is enabled');\n }\n\n const fixed = !!rowSelection.fixed || hasFixedLeftColumn(columns);\n\n const rowSelectionColumn: ITableColumn<TDataItem> = {\n dataIndex: '',\n title: (\n <div className={prefixCls('row-selection-all-header-wrap')}>\n {getCheckboxAllNode()}\n </div>\n ),\n width: 48,\n render: (text: unknown, record: TDataItem) => {\n const key = getRowKey(record, rowKey);\n const nodeStatus = getNodeCheckStatus(key);\n const checkboxProps = rowSelection.getCheckboxProps?.(record) || {};\n\n return (\n <div className={prefixCls('row-selection-item')}>\n <Checkbox\n onClick={onClickCheckbox(\n key,\n nodeStatus.checked || nodeStatus.indeterminate,\n )}\n checked={nodeStatus.checked}\n indeterminate={nodeStatus.indeterminate}\n {...checkboxProps}\n />\n </div>\n );\n },\n fixed: fixed ? 'left' : undefined,\n };\n\n const selectedRowKeysInCurrPage = getDataWithoutDisabled(\n data,\n rowSelection.getCheckboxProps,\n )\n .map((record) => getRowKey(record, rowKey))\n .filter((key) => selectedRowKeys.includes(key));\n\n const isShowRowSelectionInFooter = selectedRowKeysInCurrPage.length > 0;\n\n const items =\n rowSelection.items?.map((operationItem) => ({\n ...operationItem,\n onClick: (e: React.MouseEvent) => {\n operationItem.onClick(\n selectedRowKeysInCurrPage,\n getSelectedRows(selectedRowKeysInCurrPage),\n e,\n );\n },\n })) || [];\n\n return {\n columns: [rowSelectionColumn, ...columns],\n isRowSelectionEnabled: true,\n getCheckboxAllNode,\n selectedRowKeys: selectedRowKeys, // 返回完整的选中项列表\n selectedRowKeysInCurrPage, // 当前页面可见的选中项\n unSelectAll,\n isShowRowSelectionInFooter,\n items,\n onChange: changeSelectedRowKeys,\n };\n}\n\nfunction getCheckboxAllStatus<TDataItem extends object>(\n data: TDataItem[],\n selectedRowKeys: string[],\n rowKey: ITableProps<TDataItem>['rowKey'],\n getCheckboxProps?: IRowSelection<TDataItem>['getCheckboxProps'],\n): 'all' | 'none' | 'indeterminate' {\n const enabledData = getDataWithoutDisabled(data, getCheckboxProps);\n\n if (enabledData.length === 0) {\n return 'none';\n }\n\n const selectedEnabledCount = enabledData.filter((record) =>\n selectedRowKeys.includes(getRowKey(record, rowKey)),\n ).length;\n\n if (selectedEnabledCount === 0) {\n return 'none';\n }\n if (selectedEnabledCount === enabledData.length) {\n return 'all';\n }\n return 'indeterminate';\n}\n\nfunction getDataWithoutDisabled<TDataItem extends object>(\n data: TDataItem[],\n getCheckboxProps?: IRowSelection<TDataItem>['getCheckboxProps'],\n) {\n return data.filter((record) => {\n const checkboxProps = getCheckboxProps?.(record) || {};\n const { disabled } = checkboxProps;\n return !disabled;\n });\n}\n\nexport interface IRowSelectionInfo<TDataItem extends object> {\n columns: ITableProps<TDataItem>['columns'];\n isRowSelectionEnabled: boolean;\n getCheckboxAllNode: ((children?: React.ReactNode) => React.ReactNode) | null;\n selectedRowKeys: string[]; // 完整的选中项列表\n selectedRowKeysInCurrPage: string[]; // 当前页面可见的选中项\n unSelectAll: () => void;\n isShowRowSelectionInFooter: boolean;\n items: {\n key: string;\n label: React.ReactNode;\n onClick: (e: React.MouseEvent) => void;\n }[];\n onChange: (selectedRowKeys: string[]) => void;\n}\n\n/**\n * 获取节点的所有子孙节点keys\n * @param parentKey 父节点key\n * @param isExpandable 是否启用展开功能\n * @param flattenData 扁平化后的数据(包含所有节点,包括子节点)\n * @param rowKey 行key获取函数\n * @returns 子孙节点keys数组\n */\nexport function getNodeDescendants<TDataItem extends object>(\n parentKey: string,\n isExpandable?: boolean,\n flattenData?: TDataItem[],\n rowKey?: ITableProps<TDataItem>['rowKey'],\n): string[] {\n if (!isExpandable || !flattenData || !rowKey) return [];\n\n const descendants: string[] = [];\n\n // 找到父节点在flattenData中的记录\n const parentNode = flattenData.find(\n (item) => getRowKey(item, rowKey) === parentKey,\n );\n if (!parentNode) return [];\n\n // 从原始节点的children中收集所有子孙节点\n const collectDescendants = (node: any) => {\n const children = node.children || [];\n children.forEach((child: any) => {\n const childKey = getRowKey(child, rowKey);\n descendants.push(childKey);\n collectDescendants(child);\n });\n };\n\n collectDescendants(parentNode);\n return descendants;\n}\n\n/**\n * 获取节点的所有祖先节点keys\n * @param targetKey 目标节点key\n * @param isExpandable 是否启用展开功能\n * @param flattenData 扁平化后的数据\n * @param rowKey 行key获取函数\n * @returns 祖先节点keys数组(从直接父节点到根节点)\n */\nexport function getNodeAncestors<TDataItem extends object>(\n targetKey: string,\n isExpandable?: boolean,\n flattenData?: TDataItem[],\n rowKey?: ITableProps<TDataItem>['rowKey'],\n): string[] {\n if (!isExpandable || !flattenData || !rowKey) return [];\n\n const ancestors: string[] = [];\n\n // 找到目标节点的直接父节点\n const findDirectParent = (childKey: string): TDataItem | null => {\n for (const item of flattenData) {\n const children = (item as any).children || [];\n if (\n children.some((child: any) => getRowKey(child, rowKey) === childKey)\n ) {\n return item;\n }\n }\n return null;\n };\n\n let currentKey = targetKey;\n\n for (;;) {\n const parent = findDirectParent(currentKey);\n if (!parent) break;\n\n const parentKey = getRowKey(parent, rowKey);\n ancestors.push(parentKey);\n currentKey = parentKey;\n }\n\n return ancestors;\n}\n\n/**\n * 计算级联选择后的keys(包含向上级联)\n * @param targetKey 被操作的节点key\n * @param isChecked 当前是否选中\n * @param currentSelectedKeys 当前已选中的keys\n * @param checkStrictly 是否严格模式\n * @param isExpandable 是否启用展开功能\n * @param getDescendantKeys 获取子孙节点keys的函数\n * @param getAncestorKeys 获取祖先节点keys的函数\n * @returns 新的选中keys\n */\nexport function calculateCascadeSelection(\n targetKey: string,\n isChecked: boolean,\n currentSelectedKeys: string[],\n checkStrictly?: boolean,\n isExpandable?: boolean,\n getDescendantKeys?: (nodeKey: string) => string[],\n getAncestorKeys?: (nodeKey: string) => string[],\n): string[] {\n if (\n checkStrictly ||\n !isExpandable ||\n !getDescendantKeys ||\n !getAncestorKeys\n ) {\n // 严格模式,不进行级联\n return isChecked\n ? currentSelectedKeys.filter((key) => key !== targetKey)\n : [...currentSelectedKeys, targetKey];\n }\n\n let newKeys = [...currentSelectedKeys];\n\n if (isChecked) {\n // 取消选择:移除目标节点和所有子孙节点\n newKeys = newKeys.filter((key) => key !== targetKey);\n const descendants = getDescendantKeys(targetKey);\n newKeys = newKeys.filter((key) => !descendants.includes(key));\n\n // 向上级联:检查父节点是否需要取消选择\n const ancestors = getAncestorKeys(targetKey);\n ancestors.forEach((ancestorKey) => {\n const ancestorDescendants = getDescendantKeys(ancestorKey);\n const selectedDescendantsCount = ancestorDescendants.filter((key) =>\n newKeys.includes(key),\n ).length;\n\n // 如果子孙节点没有全部选中,则父节点也应该取消选择\n if (selectedDescendantsCount < ancestorDescendants.length) {\n newKeys = newKeys.filter((key) => key !== ancestorKey);\n }\n });\n } else {\n // 选择:添加目标节点和所有子孙节点\n if (!newKeys.includes(targetKey)) {\n newKeys.push(targetKey);\n }\n const descendants = getDescendantKeys(targetKey);\n descendants.forEach((descendantKey) => {\n if (!newKeys.includes(descendantKey)) {\n newKeys.push(descendantKey);\n }\n });\n\n // 向上级联:检查父节点是否需要选择\n const ancestors = getAncestorKeys(targetKey);\n ancestors.forEach((ancestorKey) => {\n const ancestorDescendants = getDescendantKeys(ancestorKey);\n const selectedDescendantsCount = ancestorDescendants.filter((key) =>\n newKeys.includes(key),\n ).length;\n\n // 如果所有子孙节点都被选中,则父节点也应该被选中\n if (\n selectedDescendantsCount === ancestorDescendants.length &&\n !newKeys.includes(ancestorKey)\n ) {\n newKeys.push(ancestorKey);\n }\n });\n }\n\n return newKeys;\n}\n\n/**\n * 计算节点的选择状态(考虑子节点状态)\n * @param nodeKey 节点key\n * @param selectedRowKeys 已选中的keys\n * @param checkStrictly 是否严格模式\n * @param isExpandable 是否启用展开功能\n * @param getDescendantKeys 获取子孙节点keys的函数\n * @returns 节点的选择状态\n */\nexport function calculateNodeCheckStatus(\n nodeKey: string,\n selectedRowKeys: string[],\n checkStrictly?: boolean,\n isExpandable?: boolean,\n getDescendantKeys?: (nodeKey: string) => string[],\n): { checked: boolean; indeterminate: boolean } {\n if (checkStrictly || !isExpandable || !getDescendantKeys) {\n // 严格模式下或非展开模式,直接返回节点本身的选择状态\n return {\n checked: selectedRowKeys.includes(nodeKey),\n indeterminate: false,\n };\n }\n\n const descendants = getDescendantKeys(nodeKey);\n\n // 如果没有子节点,直接返回本身状态\n if (descendants.length === 0) {\n return {\n checked: selectedRowKeys.includes(nodeKey),\n indeterminate: false,\n };\n }\n\n const selectedDescendants = descendants.filter((key) =>\n selectedRowKeys.includes(key),\n );\n const isNodeSelected = selectedRowKeys.includes(nodeKey);\n\n if (isNodeSelected && selectedDescendants.length === descendants.length) {\n // 节点本身选中且所有子节点都选中\n return { checked: true, indeterminate: false };\n } else if (!isNodeSelected && selectedDescendants.length === 0) {\n // 节点本身未选中且所有子节点都未选中\n return { checked: false, indeterminate: false };\n } else {\n // 部分选中的情况:节点选中但子节点未全选,或节点未选中但部分子节点选中\n return { checked: false, indeterminate: true };\n }\n}\n"],"mappings":"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"}
@@ -258,7 +258,7 @@ function Table(props, ref) {
258
258
  className: prefixCls("body"),
259
259
  style: {
260
260
  width: totalColumnsWidth,
261
- height: virtual ? rowVirtualizer.getTotalSize() : "auto"
261
+ height: virtual ? totalSize ? rowVirtualizer.getTotalSize() : 0 : "auto"
262
262
  },
263
263
  children: isEmpty ? /* @__PURE__ */ jsxs("div", {
264
264
  style: { width: totalSize?.width },
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Table/index.tsx"],"sourcesContent":["import {\n Cell,\n Header,\n Row,\n flexRender,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table';\nimport { VirtualItem, useVirtualizer } from '@tanstack/react-virtual';\nimport { cn } from '../lib/utils';\nimport './table.css';\nimport _ from 'lodash';\nimport React, {\n CSSProperties,\n ForwardedRef,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Empty, Spin } from '..';\nimport ExpandCell from './components/ExpandCell';\nimport Footer from './components/Footer';\nimport DndWrapper from './components/DndWrapper';\nimport { getRowKey, getTableColumns, prefixCls } from './helper';\nimport useExpandable, { getExpandableConfig } from './hooks/useExpandable';\nimport useFixed from './hooks/useFixed';\nimport useRowSelection from './hooks/useRowSelection';\nimport useScroll from './hooks/useScroll';\nimport { ITableProps, ITableRef } from './types';\nimport useRowDnd from './hooks/useRowDnd';\n\nconst HEADER_HEIGHT = 41;\nconst FOOTER_HEIGHT = 52;\n\nfunction TableResizeWrapper({\n children,\n onResize,\n}: {\n children: React.ReactNode;\n onResize: (width: number, height: number) => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n let prevW = 0;\n let prevH = 0;\n const ro = new window.ResizeObserver(() => {\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n if (w === prevW && h === prevH) return;\n prevW = w;\n prevH = h;\n onResizeRef.current(w, h);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n return (\n <div ref={ref} style={{ height: '100%' }}>\n {children}\n </div>\n );\n}\n\nfunction Table<TDataItem extends object>(\n props: ITableProps<TDataItem>,\n ref: ForwardedRef<ITableRef>,\n) {\n const {\n data,\n bordered,\n rowKey,\n columnSizing,\n sticky,\n loading,\n pagination,\n scroll = {},\n empty: emptyComponent,\n virtual = false,\n rowClassName = () => '',\n onRowClick,\n onError,\n onSort,\n expandable,\n rowDnd,\n } = props;\n const [totalSize, setTotalSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const [hoverRowId, setHoverRowId] = useState<string | null>(null);\n\n const { y } = scroll;\n const {\n containerWidth,\n onBodyScroll,\n headerRef,\n bodyRef,\n isPingLeft,\n isPingRight,\n scrollbarWidth,\n changeIsPing,\n } = useScroll({\n totalSize,\n scroll,\n });\n\n const scrollToFirstRow = useCallback(() => {\n if (!bodyRef.current) {\n return;\n }\n bodyRef.current.scrollTop = 0;\n }, [bodyRef]);\n\n useImperativeHandle(ref, () => ({\n scrollToFirstRow,\n }));\n\n const expandableInfo = useExpandable({\n expandable,\n data,\n rowKey,\n });\n const expandableConfig = getExpandableConfig(expandable);\n\n const rowSelectionInfo = useRowSelection({\n ...props,\n data: expandableInfo.data,\n isExpandable: expandableInfo.isExpandable,\n flattenData: expandableInfo.flattenData,\n });\n\n const rowDndInfo = useRowDnd({\n ...props,\n columns: rowSelectionInfo.columns,\n data: expandableInfo.data,\n });\n\n const tableColumns = useMemo(() => {\n return getTableColumns<TDataItem>({\n columns: rowDndInfo.columns,\n containerWidth: containerWidth || 0,\n onError,\n onSort,\n });\n }, [containerWidth, onError, onSort, rowDndInfo.columns]);\n\n const tableInstance = useReactTable<TDataItem>({\n columns: tableColumns,\n // 排除掉被折叠的行\n data: rowDndInfo.tableData,\n getCoreRowModel: getCoreRowModel(),\n getRowId: (row, index) => {\n return getRowKey(row, rowKey, index);\n },\n columnResizeMode: 'onChange',\n });\n\n const headerGroups = tableInstance.getHeaderGroups();\n\n const columnWidths = headerGroups[0].headers.map((header) =>\n header.getSize(),\n );\n const getColumnFixedInfo = useFixed<TDataItem>({\n columnWidths,\n tableColumns,\n y,\n scrollbarWidth,\n });\n\n // 渲染 header\n const { rows } = tableInstance.getRowModel();\n\n const isStickyWork = !!sticky && y === undefined;\n const headerStyle: CSSProperties = {};\n if (isStickyWork && _.get(sticky, 'offsetHeader')) {\n headerStyle.top = _.get(sticky, 'offsetHeader', 0);\n }\n\n const totalColumnsWidth = _.sum(columnWidths);\n\n useEffect(() => {\n // 总列宽改变时,重新计算是否需要显示固定列的阴影\n changeIsPing(totalColumnsWidth);\n }, [changeIsPing, totalColumnsWidth]);\n\n const renderHeaderCell = useCallback(\n (header: Header<TDataItem, unknown>, index: number) => {\n // 选择行的列不能拖动宽度\n const showResizer =\n columnSizing &&\n !(!!rowSelectionInfo.isRowSelectionEnabled && index === 0);\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(index, true);\n return (\n <div\n className={cn(prefixCls('th'), fixedClassName)}\n style={{ width: header.getSize(), ...fixedStyle }}\n key={header.id}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {showResizer && (\n <div\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n className={cn(prefixCls('resizer'), {\n [prefixCls('self-resizing')]: header.column.getIsResizing(),\n })}\n />\n )}\n </div>\n );\n },\n [columnSizing, rowSelectionInfo, getColumnFixedInfo],\n );\n\n const visibleColumns = tableInstance.getVisibleLeafColumns();\n\n const columnVirtualizer = useVirtualizer({\n count: tableColumns.length,\n estimateSize: (index: number) => visibleColumns[index].getSize(),\n getScrollElement: () => bodyRef.current,\n horizontal: true,\n overscan: 5,\n });\n\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n //different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right\n let virtualPaddingLeft: number | undefined;\n let virtualPaddingRight: number | undefined;\n\n if (columnVirtualizer && virtualColumns?.length) {\n virtualPaddingLeft = virtualColumns[0]?.start ?? 0;\n virtualPaddingRight =\n columnVirtualizer.getTotalSize() -\n (virtualColumns[virtualColumns.length - 1]?.end ?? 0);\n }\n\n const headerContent = (\n <div\n className={cn(prefixCls('header'), {\n [prefixCls('overflow-x')]: true,\n [prefixCls('sticky')]: isStickyWork,\n [prefixCls('resizing')]:\n tableInstance.getState().columnSizingInfo.isResizingColumn,\n })}\n ref={headerRef}\n style={headerStyle}\n >\n {_.map(headerGroups, (headerGroup) => {\n const allHeaderCells = headerGroup.headers;\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n let content: React.ReactNode | null = null;\n if (virtual) {\n _.forEach(allHeaderCells, (header, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ header, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ header, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {_.map(middleVirtualColumns, (virtualColumn) => {\n const header = allHeaderCells[virtualColumn.index];\n return renderHeaderCell(header, virtualColumn.index);\n })}\n {rightFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = _.map(allHeaderCells, (header, index) =>\n renderHeaderCell(header, index),\n );\n }\n\n return (\n <div\n className={prefixCls('tr')}\n key={headerGroup.id}\n style={{ width: totalColumnsWidth }}\n >\n {content}\n {y !== undefined && (\n <div\n className={prefixCls('header-scroll-placeholder')}\n style={{ flexBasis: scrollbarWidth }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n\n const onClickRow = useCallback(\n (rowData: TDataItem, rowIndex: number) => () => {\n if (typeof onRowClick !== 'function') {\n return;\n }\n if (window.getSelection()?.toString().length !== 0) {\n // 防止选择文本时触发 onRowClick\n return;\n }\n onRowClick(rowData, rowIndex);\n },\n [onRowClick],\n );\n\n const isShowPagination = !!(\n pagination &&\n (pagination.total > pagination.pageSize || pagination.showSizeChanger)\n );\n const isShowRowSelection = rowSelectionInfo.isShowRowSelectionInFooter;\n\n const isShowFooter = isShowPagination || isShowRowSelection;\n\n // 空态切换 size 的阈值\n const EMPTY_SMALL_SIZE_HEIGHT = 436;\n const isSmallEmpty = totalSize && totalSize.height < EMPTY_SMALL_SIZE_HEIGHT;\n\n const isEmpty = rows.length === 0 && !loading;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n estimateSize: () => 48, // estimate row height for accurate scrollbar dragging\n // 没有测量出 bodyRef.current 的高度时,返回 null,避免虚拟化器从 DOM 获取异常高度\n getScrollElement: () => (totalSize ? bodyRef.current : null),\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n });\n\n const tableRows = virtual ? rowVirtualizer.getVirtualItems() : rows;\n\n const renderBodyCell = useCallback(\n (row: Row<TDataItem>, cell: Cell<TDataItem, unknown>, colIndex: number) => {\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(colIndex);\n const tdContent = flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n );\n return (\n <div\n className={cn(prefixCls('td'), fixedClassName)}\n key={cell.id}\n style={{ width: cell.column.getSize(), ...fixedStyle }}\n >\n {expandableInfo.isExpandable &&\n colIndex === (rowSelectionInfo.isRowSelectionEnabled ? 1 : 0) ? (\n <ExpandCell\n expandableInfo={expandableInfo}\n expandable={expandable}\n data={row.original}\n rowKey={rowKey}\n >\n {tdContent}\n </ExpandCell>\n ) : (\n tdContent\n )}\n </div>\n );\n },\n [\n expandableInfo,\n expandable,\n rowKey,\n getColumnFixedInfo,\n rowSelectionInfo.isRowSelectionEnabled,\n ],\n );\n\n // 渲染 body\n const bodyContent = (\n <div\n className={prefixCls('body')}\n style={{\n width: totalColumnsWidth,\n height: virtual ? rowVirtualizer.getTotalSize() : 'auto',\n }}\n >\n {isEmpty ? (\n <div style={{ width: totalSize?.width }}>\n <div style={{ visibility: 'hidden' }}>\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n <div\n aria-invalid=\"true\"\n style={{\n position: 'absolute',\n top: 40,\n left: 0,\n right: 0,\n bottom: 0,\n }}\n >\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n </div>\n ) : (\n _.reduce<Row<TDataItem> | VirtualItem, React.ReactNode[]>(\n tableRows,\n (rowList, rowData, rowIndex) => {\n const row = virtual\n ? rows[rowData.index]\n : (rowData as Row<TDataItem>);\n const allRowCells = row.getVisibleCells();\n\n let content: React.ReactNode | null = null;\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n\n if (virtual) {\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n\n _.forEach(allRowCells, (cell, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ cell, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ cell, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {middleVirtualColumns.map((virtualColumn) => {\n const colIndex = virtualColumn.index;\n const cell = allRowCells[colIndex];\n return renderBodyCell(row, cell, colIndex);\n })}\n {rightFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = allRowCells.map((cell, index) =>\n renderBodyCell(row, cell, index),\n );\n }\n const rowId = row.id;\n\n const rowNode = (\n <div\n key={rowId}\n data-index={virtual ? (rowData as VirtualItem).index : rowIndex}\n className={cn(\n prefixCls('tr'),\n {\n // 需要用 state 的原因是,存在固定列的情况,左右侧的固定列在 dom 结构上不在同一个 tr 上,所以不能用 css 的 :hover 来实现\n // 当拖拽行时,不显示 hover 状态\n [prefixCls('row-hover')]: rowDndInfo.draggingRowId\n ? undefined\n : hoverRowId === rowId,\n [prefixCls('row-dragging')]:\n rowDndInfo.draggingRowId === rowId,\n [prefixCls('no-border-tr')]:\n isShowPagination && rowIndex === rows.length - 1,\n },\n rowClassName(row.original, rowIndex),\n )}\n ref={(node) => {\n // 只在虚拟滚动模式下才测量行高度,避免非虚拟模式下的不必要重渲染\n if (virtual) {\n rowVirtualizer.measureElement(node);\n }\n\n // 如果启用了行拖拽,则设置行引用\n if (rowDnd && node) {\n const rowRef = rowDndInfo.getRowRef(row.original, rowIndex);\n if (rowRef) {\n rowRef.current = node;\n }\n }\n }}\n onClick={onClickRow(row.original, rowIndex)}\n onMouseEnter={() => setHoverRowId(rowId)}\n onMouseLeave={() => setHoverRowId(null)}\n style={\n virtual\n ? {\n position: 'absolute',\n transform: `translateY(${\n (rowData as VirtualItem).start\n }px)`,\n }\n : {}\n }\n >\n {content}\n </div>\n );\n rowList.push(rowNode);\n\n // 渲染额外展开的行\n const expandItem = expandableInfo.expandItemMap[rowId];\n const customExpandRowKey =\n expandableInfo.isExpandable && expandItem?.customExpandRowKey;\n const hasCustomExpandRowKey = !!customExpandRowKey;\n if (hasCustomExpandRowKey) {\n // 在该行的下面追加自定义展开行\n const expandedRowRender = expandableConfig.expandedRowRender;\n if (typeof expandedRowRender !== 'function') {\n console.error('expandedRowRender must be a function');\n return rowList;\n }\n if (expandItem?.isExpanded !== true) {\n return rowList;\n }\n const customRow = (\n <div\n key={customExpandRowKey}\n className={cn(prefixCls('tr'))}\n onClick={onClickRow(row.original, rowIndex)}\n >\n {expandedRowRender(row.original, expandItem.level + 1)}\n </div>\n );\n rowList.push(customRow);\n }\n return rowList;\n },\n [],\n )\n )}\n </div>\n );\n\n const tableContentHeight = useMemo(() => {\n return y && totalSize\n ? totalSize.height - HEADER_HEIGHT - (isShowFooter ? FOOTER_HEIGHT : 0)\n : 'auto';\n }, [y, totalSize, isShowFooter]);\n\n const tableContent = (\n <Spin spinning={!!loading}>\n <div className={prefixCls('content')}>\n {headerContent}\n <div\n style={{\n height: tableContentHeight,\n position: virtual ? 'relative' : undefined,\n }}\n className={cn(prefixCls('body-scroll'), {\n [prefixCls('scroll-y')]: y !== undefined,\n [prefixCls('scroll-hidden')]: isEmpty,\n })}\n ref={bodyRef}\n onScroll={onBodyScroll}\n >\n {bodyContent}\n </div>\n {isShowFooter && (\n <Footer\n rowSelectionInfo={rowSelectionInfo}\n isShowPagination={isShowPagination}\n pagination={pagination}\n scroll={scroll}\n scrollToFirstRow={scrollToFirstRow}\n />\n )}\n </div>\n </Spin>\n );\n\n const tableStyle: CSSProperties = {};\n if (y) {\n tableStyle.height = y;\n }\n\n return (\n <div\n className={cn(prefixCls('container'), {\n [prefixCls('bordered')]: bordered,\n })}\n style={tableStyle}\n >\n <TableResizeWrapper\n onResize={(w, h) =>\n setTotalSize((prev) => {\n if (prev && prev.width === w && prev.height === h) return prev;\n return { width: w, height: h };\n })\n }\n >\n <div\n className={cn(prefixCls('main'), {\n [prefixCls('overflow-hidden')]: !!y,\n [prefixCls('ping-left')]: isPingLeft,\n [prefixCls('ping-right')]: isPingRight,\n })}\n >\n {rowDnd ? <DndWrapper>{tableContent}</DndWrapper> : tableContent}\n </div>\n </TableResizeWrapper>\n </div>\n );\n}\n\nexport default forwardRef(Table) as <TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n ref?: React.ForwardedRef<ITableRef>;\n },\n) => ReturnType<typeof Table>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Table/index.tsx"],"sourcesContent":["import {\n Cell,\n Header,\n Row,\n flexRender,\n getCoreRowModel,\n useReactTable,\n} from '@tanstack/react-table';\nimport { VirtualItem, useVirtualizer } from '@tanstack/react-virtual';\nimport { cn } from '../lib/utils';\nimport './table.css';\nimport _ from 'lodash';\nimport React, {\n CSSProperties,\n ForwardedRef,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { Empty, Spin } from '..';\nimport ExpandCell from './components/ExpandCell';\nimport Footer from './components/Footer';\nimport DndWrapper from './components/DndWrapper';\nimport { getRowKey, getTableColumns, prefixCls } from './helper';\nimport useExpandable, { getExpandableConfig } from './hooks/useExpandable';\nimport useFixed from './hooks/useFixed';\nimport useRowSelection from './hooks/useRowSelection';\nimport useScroll from './hooks/useScroll';\nimport { ITableProps, ITableRef } from './types';\nimport useRowDnd from './hooks/useRowDnd';\n\nconst HEADER_HEIGHT = 41;\nconst FOOTER_HEIGHT = 52;\n\nfunction TableResizeWrapper({\n children,\n onResize,\n}: {\n children: React.ReactNode;\n onResize: (width: number, height: number) => void;\n}) {\n const ref = useRef<HTMLDivElement>(null);\n const onResizeRef = useRef(onResize);\n onResizeRef.current = onResize;\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n let prevW = 0;\n let prevH = 0;\n const ro = new window.ResizeObserver(() => {\n const w = el.offsetWidth;\n const h = el.offsetHeight;\n if (w === prevW && h === prevH) return;\n prevW = w;\n prevH = h;\n onResizeRef.current(w, h);\n });\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n return (\n <div ref={ref} style={{ height: '100%' }}>\n {children}\n </div>\n );\n}\n\nfunction Table<TDataItem extends object>(\n props: ITableProps<TDataItem>,\n ref: ForwardedRef<ITableRef>,\n) {\n const {\n data,\n bordered,\n rowKey,\n columnSizing,\n sticky,\n loading,\n pagination,\n scroll = {},\n empty: emptyComponent,\n virtual = false,\n rowClassName = () => '',\n onRowClick,\n onError,\n onSort,\n expandable,\n rowDnd,\n } = props;\n const [totalSize, setTotalSize] = useState<{\n width: number;\n height: number;\n } | null>(null);\n\n const [hoverRowId, setHoverRowId] = useState<string | null>(null);\n\n const { y } = scroll;\n const {\n containerWidth,\n onBodyScroll,\n headerRef,\n bodyRef,\n isPingLeft,\n isPingRight,\n scrollbarWidth,\n changeIsPing,\n } = useScroll({\n totalSize,\n scroll,\n });\n\n const scrollToFirstRow = useCallback(() => {\n if (!bodyRef.current) {\n return;\n }\n bodyRef.current.scrollTop = 0;\n }, [bodyRef]);\n\n useImperativeHandle(ref, () => ({\n scrollToFirstRow,\n }));\n\n const expandableInfo = useExpandable({\n expandable,\n data,\n rowKey,\n });\n const expandableConfig = getExpandableConfig(expandable);\n\n const rowSelectionInfo = useRowSelection({\n ...props,\n data: expandableInfo.data,\n isExpandable: expandableInfo.isExpandable,\n flattenData: expandableInfo.flattenData,\n });\n\n const rowDndInfo = useRowDnd({\n ...props,\n columns: rowSelectionInfo.columns,\n data: expandableInfo.data,\n });\n\n const tableColumns = useMemo(() => {\n return getTableColumns<TDataItem>({\n columns: rowDndInfo.columns,\n containerWidth: containerWidth || 0,\n onError,\n onSort,\n });\n }, [containerWidth, onError, onSort, rowDndInfo.columns]);\n\n const tableInstance = useReactTable<TDataItem>({\n columns: tableColumns,\n // 排除掉被折叠的行\n data: rowDndInfo.tableData,\n getCoreRowModel: getCoreRowModel(),\n getRowId: (row, index) => {\n return getRowKey(row, rowKey, index);\n },\n columnResizeMode: 'onChange',\n });\n\n const headerGroups = tableInstance.getHeaderGroups();\n\n const columnWidths = headerGroups[0].headers.map((header) =>\n header.getSize(),\n );\n const getColumnFixedInfo = useFixed<TDataItem>({\n columnWidths,\n tableColumns,\n y,\n scrollbarWidth,\n });\n\n // 渲染 header\n const { rows } = tableInstance.getRowModel();\n\n const isStickyWork = !!sticky && y === undefined;\n const headerStyle: CSSProperties = {};\n if (isStickyWork && _.get(sticky, 'offsetHeader')) {\n headerStyle.top = _.get(sticky, 'offsetHeader', 0);\n }\n\n const totalColumnsWidth = _.sum(columnWidths);\n\n useEffect(() => {\n // 总列宽改变时,重新计算是否需要显示固定列的阴影\n changeIsPing(totalColumnsWidth);\n }, [changeIsPing, totalColumnsWidth]);\n\n const renderHeaderCell = useCallback(\n (header: Header<TDataItem, unknown>, index: number) => {\n // 选择行的列不能拖动宽度\n const showResizer =\n columnSizing &&\n !(!!rowSelectionInfo.isRowSelectionEnabled && index === 0);\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(index, true);\n return (\n <div\n className={cn(prefixCls('th'), fixedClassName)}\n style={{ width: header.getSize(), ...fixedStyle }}\n key={header.id}\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n {showResizer && (\n <div\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n className={cn(prefixCls('resizer'), {\n [prefixCls('self-resizing')]: header.column.getIsResizing(),\n })}\n />\n )}\n </div>\n );\n },\n [columnSizing, rowSelectionInfo, getColumnFixedInfo],\n );\n\n const visibleColumns = tableInstance.getVisibleLeafColumns();\n\n const columnVirtualizer = useVirtualizer({\n count: tableColumns.length,\n estimateSize: (index: number) => visibleColumns[index].getSize(),\n getScrollElement: () => bodyRef.current,\n horizontal: true,\n overscan: 5,\n });\n\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n //different virtualization strategy for columns - instead of absolute and translateY, we add empty columns to the left and right\n let virtualPaddingLeft: number | undefined;\n let virtualPaddingRight: number | undefined;\n\n if (columnVirtualizer && virtualColumns?.length) {\n virtualPaddingLeft = virtualColumns[0]?.start ?? 0;\n virtualPaddingRight =\n columnVirtualizer.getTotalSize() -\n (virtualColumns[virtualColumns.length - 1]?.end ?? 0);\n }\n\n const headerContent = (\n <div\n className={cn(prefixCls('header'), {\n [prefixCls('overflow-x')]: true,\n [prefixCls('sticky')]: isStickyWork,\n [prefixCls('resizing')]:\n tableInstance.getState().columnSizingInfo.isResizingColumn,\n })}\n ref={headerRef}\n style={headerStyle}\n >\n {_.map(headerGroups, (headerGroup) => {\n const allHeaderCells = headerGroup.headers;\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n header: Header<TDataItem, unknown>;\n index: number;\n }[] = [];\n let content: React.ReactNode | null = null;\n if (virtual) {\n _.forEach(allHeaderCells, (header, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ header, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ header, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {_.map(middleVirtualColumns, (virtualColumn) => {\n const header = allHeaderCells[virtualColumn.index];\n return renderHeaderCell(header, virtualColumn.index);\n })}\n {rightFixedColumns.map(({ header, index }) => {\n return renderHeaderCell(header, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = _.map(allHeaderCells, (header, index) =>\n renderHeaderCell(header, index),\n );\n }\n\n return (\n <div\n className={prefixCls('tr')}\n key={headerGroup.id}\n style={{ width: totalColumnsWidth }}\n >\n {content}\n {y !== undefined && (\n <div\n className={prefixCls('header-scroll-placeholder')}\n style={{ flexBasis: scrollbarWidth }}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n\n const onClickRow = useCallback(\n (rowData: TDataItem, rowIndex: number) => () => {\n if (typeof onRowClick !== 'function') {\n return;\n }\n if (window.getSelection()?.toString().length !== 0) {\n // 防止选择文本时触发 onRowClick\n return;\n }\n onRowClick(rowData, rowIndex);\n },\n [onRowClick],\n );\n\n const isShowPagination = !!(\n pagination &&\n (pagination.total > pagination.pageSize || pagination.showSizeChanger)\n );\n const isShowRowSelection = rowSelectionInfo.isShowRowSelectionInFooter;\n\n const isShowFooter = isShowPagination || isShowRowSelection;\n\n // 空态切换 size 的阈值\n const EMPTY_SMALL_SIZE_HEIGHT = 436;\n const isSmallEmpty = totalSize && totalSize.height < EMPTY_SMALL_SIZE_HEIGHT;\n\n const isEmpty = rows.length === 0 && !loading;\n\n const rowVirtualizer = useVirtualizer({\n count: rows.length,\n estimateSize: () => 48, // estimate row height for accurate scrollbar dragging\n // 没有测量出 bodyRef.current 的高度时,返回 null,避免虚拟化器从 DOM 获取异常高度\n getScrollElement: () => (totalSize ? bodyRef.current : null),\n // measure dynamic row height, except in firefox because it measures table border height incorrectly\n measureElement:\n typeof window !== 'undefined' &&\n navigator.userAgent.indexOf('Firefox') === -1\n ? (element) => element?.getBoundingClientRect().height\n : undefined,\n overscan: 5,\n });\n\n const tableRows = virtual ? rowVirtualizer.getVirtualItems() : rows;\n\n const renderBodyCell = useCallback(\n (row: Row<TDataItem>, cell: Cell<TDataItem, unknown>, colIndex: number) => {\n const { className: fixedClassName, style: fixedStyle } =\n getColumnFixedInfo(colIndex);\n const tdContent = flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n );\n return (\n <div\n className={cn(prefixCls('td'), fixedClassName)}\n key={cell.id}\n style={{ width: cell.column.getSize(), ...fixedStyle }}\n >\n {expandableInfo.isExpandable &&\n colIndex === (rowSelectionInfo.isRowSelectionEnabled ? 1 : 0) ? (\n <ExpandCell\n expandableInfo={expandableInfo}\n expandable={expandable}\n data={row.original}\n rowKey={rowKey}\n >\n {tdContent}\n </ExpandCell>\n ) : (\n tdContent\n )}\n </div>\n );\n },\n [\n expandableInfo,\n expandable,\n rowKey,\n getColumnFixedInfo,\n rowSelectionInfo.isRowSelectionEnabled,\n ],\n );\n\n // 渲染 body\n const bodyContent = (\n <div\n className={prefixCls('body')}\n style={{\n width: totalColumnsWidth,\n height: virtual\n ? totalSize\n ? rowVirtualizer.getTotalSize()\n : 0\n : 'auto',\n }}\n >\n {isEmpty ? (\n <div style={{ width: totalSize?.width }}>\n <div style={{ visibility: 'hidden' }}>\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n <div\n aria-invalid=\"true\"\n style={{\n position: 'absolute',\n top: 40,\n left: 0,\n right: 0,\n bottom: 0,\n }}\n >\n {emptyComponent || (\n <div\n className={cn(prefixCls('empty'), {\n [prefixCls('empty-small')]: isSmallEmpty,\n })}\n >\n <Empty\n image={isSmallEmpty ? null : Empty.PRESENTED_IMAGE_SEARCH}\n size={isSmallEmpty ? 'small' : undefined}\n />\n </div>\n )}\n </div>\n </div>\n ) : (\n _.reduce<Row<TDataItem> | VirtualItem, React.ReactNode[]>(\n tableRows,\n (rowList, rowData, rowIndex) => {\n const row = virtual\n ? rows[rowData.index]\n : (rowData as Row<TDataItem>);\n const allRowCells = row.getVisibleCells();\n\n let content: React.ReactNode | null = null;\n // 将固定列单独拎出来,固定列不受列虚拟化影响,必须要渲染\n const leftFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n const rightFixedColumns: {\n cell: Cell<TDataItem, unknown>;\n index: number;\n }[] = [];\n\n if (virtual) {\n const virtualColumns = columnVirtualizer.getVirtualItems();\n\n const middleVirtualColumns: VirtualItem[] = [];\n\n _.forEach(allRowCells, (cell, index) => {\n const fixedInfo = getColumnFixedInfo(index);\n if (fixedInfo.fixed === 'left') {\n leftFixedColumns.push({ cell, index });\n }\n if (fixedInfo.fixed === 'right') {\n rightFixedColumns.push({ cell, index });\n }\n });\n\n _.forEach(virtualColumns, (virtualColumn) => {\n const colIndex = virtualColumn.index;\n const fixedInfo = getColumnFixedInfo(colIndex);\n if (fixedInfo.fixed !== 'left' && fixedInfo.fixed !== 'right') {\n middleVirtualColumns.push(virtualColumn);\n }\n });\n content = (\n <>\n {virtualPaddingLeft ? (\n //fake empty column to the left for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-left')}\n style={{ width: virtualPaddingLeft }}\n />\n ) : null}\n {leftFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {middleVirtualColumns.map((virtualColumn) => {\n const colIndex = virtualColumn.index;\n const cell = allRowCells[colIndex];\n return renderBodyCell(row, cell, colIndex);\n })}\n {rightFixedColumns.map(({ cell, index }) => {\n return renderBodyCell(row, cell, index);\n })}\n {virtualPaddingRight ? (\n //fake empty column to the right for virtualization scroll padding\n <div\n className={prefixCls('virtual-padding-right')}\n style={{ width: virtualPaddingRight }}\n />\n ) : null}\n </>\n );\n } else {\n content = allRowCells.map((cell, index) =>\n renderBodyCell(row, cell, index),\n );\n }\n const rowId = row.id;\n\n const rowNode = (\n <div\n key={rowId}\n data-index={virtual ? (rowData as VirtualItem).index : rowIndex}\n className={cn(\n prefixCls('tr'),\n {\n // 需要用 state 的原因是,存在固定列的情况,左右侧的固定列在 dom 结构上不在同一个 tr 上,所以不能用 css 的 :hover 来实现\n // 当拖拽行时,不显示 hover 状态\n [prefixCls('row-hover')]: rowDndInfo.draggingRowId\n ? undefined\n : hoverRowId === rowId,\n [prefixCls('row-dragging')]:\n rowDndInfo.draggingRowId === rowId,\n [prefixCls('no-border-tr')]:\n isShowPagination && rowIndex === rows.length - 1,\n },\n rowClassName(row.original, rowIndex),\n )}\n ref={(node) => {\n // 只在虚拟滚动模式下才测量行高度,避免非虚拟模式下的不必要重渲染\n if (virtual) {\n rowVirtualizer.measureElement(node);\n }\n\n // 如果启用了行拖拽,则设置行引用\n if (rowDnd && node) {\n const rowRef = rowDndInfo.getRowRef(row.original, rowIndex);\n if (rowRef) {\n rowRef.current = node;\n }\n }\n }}\n onClick={onClickRow(row.original, rowIndex)}\n onMouseEnter={() => setHoverRowId(rowId)}\n onMouseLeave={() => setHoverRowId(null)}\n style={\n virtual\n ? {\n position: 'absolute',\n transform: `translateY(${\n (rowData as VirtualItem).start\n }px)`,\n }\n : {}\n }\n >\n {content}\n </div>\n );\n rowList.push(rowNode);\n\n // 渲染额外展开的行\n const expandItem = expandableInfo.expandItemMap[rowId];\n const customExpandRowKey =\n expandableInfo.isExpandable && expandItem?.customExpandRowKey;\n const hasCustomExpandRowKey = !!customExpandRowKey;\n if (hasCustomExpandRowKey) {\n // 在该行的下面追加自定义展开行\n const expandedRowRender = expandableConfig.expandedRowRender;\n if (typeof expandedRowRender !== 'function') {\n console.error('expandedRowRender must be a function');\n return rowList;\n }\n if (expandItem?.isExpanded !== true) {\n return rowList;\n }\n const customRow = (\n <div\n key={customExpandRowKey}\n className={cn(prefixCls('tr'))}\n onClick={onClickRow(row.original, rowIndex)}\n >\n {expandedRowRender(row.original, expandItem.level + 1)}\n </div>\n );\n rowList.push(customRow);\n }\n return rowList;\n },\n [],\n )\n )}\n </div>\n );\n\n const tableContentHeight = useMemo(() => {\n return y && totalSize\n ? totalSize.height - HEADER_HEIGHT - (isShowFooter ? FOOTER_HEIGHT : 0)\n : 'auto';\n }, [y, totalSize, isShowFooter]);\n\n const tableContent = (\n <Spin spinning={!!loading}>\n <div className={prefixCls('content')}>\n {headerContent}\n <div\n style={{\n height: tableContentHeight,\n position: virtual ? 'relative' : undefined,\n }}\n className={cn(prefixCls('body-scroll'), {\n [prefixCls('scroll-y')]: y !== undefined,\n [prefixCls('scroll-hidden')]: isEmpty,\n })}\n ref={bodyRef}\n onScroll={onBodyScroll}\n >\n {bodyContent}\n </div>\n {isShowFooter && (\n <Footer\n rowSelectionInfo={rowSelectionInfo}\n isShowPagination={isShowPagination}\n pagination={pagination}\n scroll={scroll}\n scrollToFirstRow={scrollToFirstRow}\n />\n )}\n </div>\n </Spin>\n );\n\n const tableStyle: CSSProperties = {};\n if (y) {\n tableStyle.height = y;\n }\n\n return (\n <div\n className={cn(prefixCls('container'), {\n [prefixCls('bordered')]: bordered,\n })}\n style={tableStyle}\n >\n <TableResizeWrapper\n onResize={(w, h) =>\n setTotalSize((prev) => {\n if (prev && prev.width === w && prev.height === h) return prev;\n return { width: w, height: h };\n })\n }\n >\n <div\n className={cn(prefixCls('main'), {\n [prefixCls('overflow-hidden')]: !!y,\n [prefixCls('ping-left')]: isPingLeft,\n [prefixCls('ping-right')]: isPingRight,\n })}\n >\n {rowDnd ? <DndWrapper>{tableContent}</DndWrapper> : tableContent}\n </div>\n </TableResizeWrapper>\n </div>\n );\n}\n\nexport default forwardRef(Table) as <TDataItem extends object>(\n props: ITableProps<TDataItem> & {\n ref?: React.ForwardedRef<ITableRef>;\n },\n) => ReturnType<typeof Table>;\n"],"mappings":"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"}
@@ -23,7 +23,8 @@ function Tabs(props) {
23
23
  }, [items, children]);
24
24
  const firstKey = resolvedItems[0]?.key || "";
25
25
  const [innerActiveKey, setInnerActiveKey] = useState(defaultActiveKey || firstKey);
26
- const activeKey = controlledActiveKey !== void 0 ? controlledActiveKey : innerActiveKey;
26
+ const mergedActiveKey = controlledActiveKey !== void 0 ? controlledActiveKey : innerActiveKey;
27
+ const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey) ? mergedActiveKey : firstKey;
27
28
  const handleTabClick = (key, e) => {
28
29
  if (controlledActiveKey === void 0) setInnerActiveKey(key);
29
30
  onChange?.(key);
@@ -84,14 +85,14 @@ function Tabs(props) {
84
85
  };
85
86
  const showScrollButtons = canScrollLeft || canScrollRight;
86
87
  return /* @__PURE__ */ jsxs("div", {
87
- className: cn("ald-tabs tw-flex", isVertical ? "tw-flex-row" : "tw-flex-col", adaptHeight && "ald-adapt-height tw-h-full", size !== "small" && "ald-tabs-default", monospace && "ald-tabs-monospace", compact && "ald-tabs-compact", !hasDividing && "ald-tabs-no-dividing", className),
88
+ className: cn("ald-tabs ant-tabs tw-flex", isVertical ? "tw-flex-row" : "tw-flex-col", adaptHeight && "ald-adapt-height tw-h-full", size !== "small" && "ald-tabs-default", monospace && "ald-tabs-monospace", compact && "ald-tabs-compact", !hasDividing && "ald-tabs-no-dividing", className),
88
89
  style: {
89
90
  ...style,
90
91
  "--header-bg-color": headerBackgroundColor,
91
92
  "--tabs-padding": `${paddingVal}px`
92
93
  },
93
94
  children: [/* @__PURE__ */ jsxs("div", {
94
- className: cn("ald-tabs-nav tw-flex tw-items-center", !isVertical && hasDividing && "tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]", !isVertical && compact && "!tw-mb-0", isVertical && "tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]", paddingVal && `tw-px-[${paddingVal}px]`),
95
+ className: cn("ald-tabs-nav ant-tabs-nav tw-flex tw-items-center", !isVertical && hasDividing && "tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]", !isVertical && compact && "!tw-mb-0", isVertical && "tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]", paddingVal && `tw-px-[${paddingVal}px]`),
95
96
  style: headerBackgroundColor ? { backgroundColor: headerBackgroundColor } : void 0,
96
97
  children: [
97
98
  extraLeft,
@@ -103,31 +104,37 @@ function Tabs(props) {
103
104
  children: /* @__PURE__ */ jsx(Memo, { size: 16 })
104
105
  }),
105
106
  /* @__PURE__ */ jsx("div", {
106
- ref: navListRef,
107
- className: cn("ald-tabs-nav-list tw-flex tw-flex-1 tw-overflow-hidden", isVertical && "tw-flex-col", monospace && "[&>*]:tw-flex-1", isCard ? "tw-gap-1" : !monospace && "tw-gap-8"),
108
- style: !isVertical ? {
109
- scrollbarWidth: "none",
110
- msOverflowStyle: "none"
111
- } : void 0,
112
- children: resolvedItems.map((item) => {
113
- const isActive = activeKey === item.key;
114
- const showClose = isEditable && item.closable !== false;
115
- return /* @__PURE__ */ jsxs("div", {
116
- className: cn("ald-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors", isCard ? cn("tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5", "tw-gap-sp-75", isActive ? "tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]" : "tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit") : cn(size === "small" ? "tw-py-2 tw-text-xs tw-leading-4" : "tw-py-2.5 tw-text-sm tw-leading-5", monospace && "tw-justify-center", isActive ? "tw-font-medium tw-text-[var(--alias-colors-text-selected)]" : "tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit"), item.disabled && "tw-pointer-events-none tw-cursor-default tw-opacity-50"),
117
- onClick: item.disabled ? void 0 : (e) => handleTabClick(item.key, e),
118
- children: [
119
- item.icon,
120
- /* @__PURE__ */ jsx("span", { children: item.label }),
121
- showClose && /* @__PURE__ */ jsx("span", {
122
- className: "ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]",
123
- onClick: (e) => handleRemove(item.key, e),
124
- "aria-label": `Remove ${item.label}`,
125
- children: /* @__PURE__ */ jsx(Memo$2, { size: 12 })
126
- }),
127
- !isCard && isActive && !isVertical && /* @__PURE__ */ jsx("div", { className: "tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]" }),
128
- !isCard && isActive && isVertical && /* @__PURE__ */ jsx("div", { className: "tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]" })
129
- ]
130
- }, item.key);
107
+ className: "ald-tabs-nav-wrap ant-tabs-nav-wrap tw-min-w-0 tw-flex-1",
108
+ children: /* @__PURE__ */ jsx("div", {
109
+ ref: navListRef,
110
+ className: cn("ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden", isVertical && "tw-flex-col", monospace && "[&>*]:tw-flex-1", isCard ? "tw-gap-1" : !monospace && "tw-gap-8"),
111
+ style: !isVertical ? {
112
+ scrollbarWidth: "none",
113
+ msOverflowStyle: "none"
114
+ } : void 0,
115
+ children: resolvedItems.map((item) => {
116
+ const isActive = activeKey === item.key;
117
+ const showClose = isEditable && item.closable !== false;
118
+ return /* @__PURE__ */ jsxs("div", {
119
+ className: cn("ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors", isCard ? cn("tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5", "tw-gap-sp-75", isActive ? "tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]" : "tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit") : cn(size === "small" ? "tw-py-2 tw-text-xs tw-leading-4" : "tw-py-2.5 tw-text-sm tw-leading-5", monospace && "tw-justify-center", isActive ? "tw-font-medium tw-text-[var(--alias-colors-text-selected)]" : "tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit"), item.disabled && "tw-pointer-events-none tw-cursor-default tw-opacity-50"),
120
+ onClick: item.disabled ? void 0 : (e) => handleTabClick(item.key, e),
121
+ children: [
122
+ item.icon,
123
+ /* @__PURE__ */ jsx("span", {
124
+ className: "ant-tabs-tab-btn",
125
+ children: item.label
126
+ }),
127
+ showClose && /* @__PURE__ */ jsx("span", {
128
+ className: "ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]",
129
+ onClick: (e) => handleRemove(item.key, e),
130
+ "aria-label": `Remove ${item.label}`,
131
+ children: /* @__PURE__ */ jsx(Memo$2, { size: 12 })
132
+ }),
133
+ !isCard && isActive && !isVertical && /* @__PURE__ */ jsx("div", { className: "ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]" }),
134
+ !isCard && isActive && isVertical && /* @__PURE__ */ jsx("div", { className: "tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]" })
135
+ ]
136
+ }, item.key);
137
+ })
131
138
  })
132
139
  }),
133
140
  showScrollButtons && !isVertical && /* @__PURE__ */ jsx("button", {
@@ -168,12 +175,12 @@ function Tabs(props) {
168
175
  extraRight
169
176
  ]
170
177
  }), /* @__PURE__ */ jsx("div", {
171
- className: "ald-tabs-content tw-min-h-0 tw-flex-1",
178
+ className: cn("ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1", adaptHeight && "tw-h-full"),
172
179
  children: resolvedItems.map((item) => {
173
180
  const isActive = item.key === activeKey;
174
181
  if (!isActive && destroyInactiveTabPane && !item.forceRender) return null;
175
182
  return /* @__PURE__ */ jsx("div", {
176
- className: cn("ald-tabs-tabpane", isActive ? "tw-block" : "tw-hidden"),
183
+ className: cn("ald-tabs-tabpane ant-tabs-tabpane", adaptHeight && "tw-h-full tw-overflow-y-auto", isActive ? "ant-tabs-tabpane-active tw-block" : "tw-hidden"),
177
184
  role: "tabpanel",
178
185
  children: item.children
179
186
  }, item.key);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const activeKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(key, 'remove');\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n className={cn(\n 'ald-tabs tw-flex',\n isVertical ? 'tw-flex-row' : 'tw-flex-col',\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n 'ald-tabs-nav tw-flex tw-items-center',\n !isVertical &&\n hasDividing &&\n 'tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]',\n !isVertical && compact && '!tw-mb-0',\n isVertical &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]',\n paddingVal && `tw-px-[${paddingVal}px]`,\n )}\n style={\n headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div\n ref={navListRef}\n className={cn(\n 'ald-tabs-nav-list tw-flex tw-flex-1 tw-overflow-hidden',\n isVertical && 'tw-flex-col',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n )}\n onClick={\n item.disabled ? undefined : (e) => handleTabClick(item.key, e)\n }\n >\n {item.icon}\n <span>{item.label}</span>\n {/* Close button for editable-card */}\n {showClose && (\n <span\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={`Remove ${item.label}`}\n >\n <CloseLightLine size={12} />\n </span>\n )}\n {/* Active indicator for non-card line tabs */}\n {!isCard && isActive && !isVertical && (\n <div className=\"tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n {!isCard && isActive && isVertical && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n </div>\n );\n })}\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n <div className=\"ald-tabs-content tw-min-h-0 tw-flex-1\">\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n 'ald-tabs-tabpane',\n isActive ? 'tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":";;;;;;;;AAyDA,SAAwB,KAAK,OAAmB;CAC9C,MAAM,EACJ,MACA,WACA,aACA,QAAQ,EAAE,EACV,WAAW,gBACX,cAAc,OACd,SAAS,eAAe,OACxB,SACA,cAAc,MACd,OACA,WAAW,qBACX,kBACA,UACA,YACA,wBACA,oBACA,uBACA,UACA,MACA,QACA,YACE;CAEJ,MAAM,aAAa,SAAS;CAC5B,MAAM,SAAS,SAAS,UAAU,SAAS;CAG3C,MAAM,gBAA2B,cAAc;AAC7C,MAAI,MAAO,QAAO;AAClB,SAAO,MAAM,SAAS,QAAQ,SAAS,CACpC,OAAO,MAAM,eAAe,CAC5B,KAAK,WAAgB;GACpB,KAAK,MAAM,OAAO,MAAM,MAAM,OAAO;GACrC,OAAO,MAAM,MAAM;GACnB,UAAU,MAAM,MAAM;GACtB,UAAU,MAAM,MAAM;GACtB,UAAU,MAAM,MAAM;GACtB,aAAa,MAAM,MAAM;GAC1B,EAAE;IACJ,CAAC,OAAO,SAAS,CAAC;CAErB,MAAM,WAAW,cAAc,IAAI,OAAO;CAC1C,MAAM,CAAC,gBAAgB,qBAAqB,SAC1C,oBAAoB,SACrB;CACD,MAAM,YACJ,wBAAwB,SAAY,sBAAsB;CAE5D,MAAM,kBAAkB,KAAa,MAAwB;AAC3D,MAAI,wBAAwB,OAC1B,mBAAkB,IAAI;AAExB,aAAW,IAAI;AACf,eAAa,KAAK,EAAE;;CAGtB,MAAM,gBAAgB,KAAa,MAAwB;AACzD,IAAE,iBAAiB;AACnB,WAAS,KAAK,SAAS;;CAGzB,MAAM,aAAa,MAAwB;AACzC,WAAS,GAAG,MAAM;;CAGpB,MAAM,YAAY,gBAAgB,QAAQ,QAAQ;CAClD,MAAM,aAAa,cAAc;AAC/B,MAAI,gBAAgB,MAAO,QAAO;AAClC,MAAI,OAAO,iBAAiB,SAAU,QAAO;AAC7C,MAAI,OAAO,iBAAiB,aAAa,aAAc,QAAO;AAC9D,SAAO;IACN,CAAC,cAAc,YAAY,CAAC;CAE/B,MAAM,aAAa,gBAAgB,UAAU,gBAAgB;CAE7D,MAAM,YACJ,sBACA,OAAO,uBAAuB,YAC9B,UAAU,qBACN,mBAAmB,OACnB;CACN,MAAM,aAAa,qBACf,OAAO,uBAAuB,YAAY,WAAW,qBACnD,mBAAmB,QACnB,MAAM,eAAe,mBAAmB,GACxC,qBACA,OACF;CAGJ,MAAM,aAAa,OAAuB,KAAK;CAC/C,MAAM,CAAC,eAAe,oBAAoB,SAAS,MAAM;CACzD,MAAM,CAAC,gBAAgB,qBAAqB,SAAS,MAAM;CAE3D,MAAM,cAAc,kBAAkB;EACpC,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,MAAM,YAAY;AACrB,oBAAiB,MAAM;AACvB,qBAAkB,MAAM;AACxB;;EAEF,MAAM,EAAE,YAAY,aAAa,gBAAgB;AACjD,mBAAiB,aAAa,EAAE;AAChC,oBAAkB,aAAa,cAAc,cAAc,EAAE;IAC5D,CAAC,WAAW,CAAC;AAEhB,iBAAgB;AACd,eAAa;EACb,MAAM,KAAK,WAAW;AACtB,MAAI,CAAC,GAAI;EAET,IAAI;AACJ,MAAI,OAAO,mBAAmB,aAAa;AACzC,QAAK,IAAI,qBAAqB,aAAa,CAAC;AAC5C,MAAG,QAAQ,GAAG;;AAEhB,KAAG,iBAAiB,UAAU,aAAa,EAAE,SAAS,MAAM,CAAC;AAC7D,eAAa;AACX,MAAG,oBAAoB,UAAU,YAAY;AAC7C,OAAI,YAAY;;IAEjB,CAAC,aAAa,cAAc,OAAO,CAAC;CAEvC,MAAM,YAAY,UAAkB;EAClC,MAAM,KAAK,WAAW;AACtB,MAAI,GACF,IAAG,SAAS;GAAE,MAAM;GAAO,UAAU;GAAU,CAAC;;CAIpD,MAAM,oBAAoB,iBAAiB;AAE3C,QACE,qBAAC,OAAD;EACE,WAAW,GACT,oBACA,aAAa,gBAAgB,eAC7B,eAAe,8BACf,SAAS,WAAW,oBACpB,aAAa,sBACb,WAAW,oBACX,CAAC,eAAe,wBAChB,UACD;EACD,OACE;GACE,GAAG;GACH,qBAAqB;GACrB,kBAAkB,GAAG,WAAW;GACjC;YAhBL,CAoBE,qBAAC,OAAD;GACE,WAAW,GACT,wCACA,CAAC,cACC,eACA,6FACF,CAAC,cAAc,WAAW,YAC1B,cACE,iGACF,cAAc,UAAU,WAAW,KACpC;GACD,OACE,wBACI,EAAE,iBAAiB,uBAAuB,GAC1C;aAdR;IAiBG;IAGA,qBAAqB,CAAC,cACrB,oBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,oNACA,CAAC,iBAAiB,eACnB;KACD,eAAe,SAAS,KAAK;KAC7B,cAAW;eAEX,oBAAC,MAAD,EAAiB,MAAM,IAAM,CAAA;KACtB,CAAA;IAGX,oBAAC,OAAD;KACE,KAAK;KACL,WAAW,GACT,0DACA,cAAc,eACd,aAAa,mBACb,SAAS,aAAa,CAAC,aAAa,WACrC;KACD,OACE,CAAC,aACG;MAAE,gBAAgB;MAAQ,iBAAiB;MAAQ,GACnD;eAGL,cAAc,KAAK,SAAS;MAC3B,MAAM,WAAW,cAAc,KAAK;MAEpC,MAAM,YAAY,cAAc,KAAK,aAAa;AAElD,aACE,qBAAC,OAAD;OAEE,WAAW,GACT,qIAEA,SACI,GACE,sGACA,gBACA,WACI,gJACA,iKACL,GACD,GACE,SAAS,UACL,oCACA,qCACJ,aAAa,qBACb,WACI,+DACA,iFACL,EACL,KAAK,YACH,yDACH;OACD,SACE,KAAK,WAAW,UAAa,MAAM,eAAe,KAAK,KAAK,EAAE;iBA1BlE;QA6BG,KAAK;QACN,oBAAC,QAAD,EAAA,UAAO,KAAK,OAAa,CAAA;QAExB,aACC,oBAAC,QAAD;SACE,WAAU;SACV,UAAU,MAAM,aAAa,KAAK,KAAK,EAAE;SACzC,cAAY,UAAU,KAAK;mBAE3B,oBAAC,QAAD,EAAgB,MAAM,IAAM,CAAA;SACvB,CAAA;QAGR,CAAC,UAAU,YAAY,CAAC,cACvB,oBAAC,OAAD,EAAK,WAAU,kHAAmH,CAAA;QAEnI,CAAC,UAAU,YAAY,cACtB,oBAAC,OAAD,EAAK,WAAU,iHAAkH,CAAA;QAE/H;SA/CC,KAAK,IA+CN;OAER;KACE,CAAA;IAGL,qBAAqB,CAAC,cACrB,oBAAC,UAAD;KACE,MAAK;KACL,WAAW,GACT,oNACA,CAAC,kBAAkB,eACpB;KACD,eAAe,SAAS,IAAI;KAC5B,cAAW;eAEX,oBAAC,QAAD,EAAkB,MAAM,IAAM,CAAA;KACvB,CAAA;IAIV,cAAc,CAAC,WACd,oBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,SAAS;KACT,cAAW;eAEX,qBAAC,OAAD;MACE,OAAM;MACN,OAAM;MACN,QAAO;MACP,SAAQ;MACR,MAAK;MACL,QAAO;MACP,aAAY;MACZ,eAAc;MACd,gBAAe;gBATjB,CAWE,oBAAC,QAAD;OAAM,IAAG;OAAK,IAAG;OAAI,IAAG;OAAK,IAAG;OAAO,CAAA,EACvC,oBAAC,QAAD;OAAM,IAAG;OAAI,IAAG;OAAK,IAAG;OAAK,IAAG;OAAO,CAAA,CACnC;;KACC,CAAA;IAGV;IACG;MAGN,oBAAC,OAAD;GAAK,WAAU;aACZ,cAAc,KAAK,SAAS;IAC3B,MAAM,WAAW,KAAK,QAAQ;AAC9B,QAAI,CAAC,YAAY,0BAA0B,CAAC,KAAK,YAC/C,QAAO;AAET,WACE,oBAAC,OAAD;KAEE,WAAW,GACT,oBACA,WAAW,aAAa,YACzB;KACD,MAAK;eAEJ,KAAK;KACF,EARC,KAAK,IAQN;KAER;GACE,CAAA,CACF;;;AAIV,KAAK,UAAU"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Tabs/index.tsx"],"sourcesContent":["import React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { cn } from '../lib/utils';\nimport { ChevronLeftLine, ChevronRightLine, CloseLightLine } from '../Icon';\nimport TabPane from './TabPane';\n\nexport type TabsSize = 'default' | 'small';\n\ninterface TabItem {\n key: string;\n label: React.ReactNode;\n children?: React.ReactNode;\n disabled?: boolean;\n closable?: boolean;\n icon?: React.ReactNode;\n forceRender?: boolean;\n className?: string;\n}\n\nexport interface ITabsProps {\n size?: TabsSize;\n activeKey?: string;\n defaultActiveKey?: string;\n onChange?: (activeKey: string) => void;\n onTabClick?: (activeKey: string, e: React.MouseEvent) => void;\n destroyInactiveTabPane?: boolean;\n centered?: boolean;\n adaptHeight?: boolean;\n tabPosition?: 'left' | 'right' | 'top' | 'bottom';\n className?: string;\n children?: React.ReactNode;\n headerBackgroundColor?: string;\n monospace?: boolean;\n padding?: boolean | number;\n compact?: boolean;\n hasDividing?: boolean;\n items?: TabItem[];\n type?: 'line' | 'card' | 'editable-card';\n tabBarExtraContent?:\n | React.ReactNode\n | { left?: React.ReactNode; right?: React.ReactNode };\n onEdit?: (\n targetKey: string | React.MouseEvent | React.KeyboardEvent,\n action: 'add' | 'remove',\n ) => void;\n hideAdd?: boolean;\n style?: React.CSSProperties;\n popupClassName?: string;\n tabBarGutter?: number;\n moreIcon?: React.ReactNode;\n}\n\nexport default function Tabs(props: ITabsProps) {\n const {\n size,\n className,\n adaptHeight,\n style = {},\n monospace: propsMonospace,\n tabPosition = 'top',\n padding: propsPadding = false,\n compact,\n hasDividing = true,\n items,\n activeKey: controlledActiveKey,\n defaultActiveKey,\n onChange,\n onTabClick,\n destroyInactiveTabPane,\n tabBarExtraContent,\n headerBackgroundColor,\n children,\n type,\n onEdit,\n hideAdd,\n } = props;\n\n const isEditable = type === 'editable-card';\n const isCard = type === 'card' || type === 'editable-card';\n\n // Derive items from children if not provided\n const resolvedItems: TabItem[] = useMemo(() => {\n if (items) return items;\n return React.Children.toArray(children)\n .filter(React.isValidElement)\n .map((child: any) => ({\n key: child.key || child.props.key || '',\n label: child.props.tab,\n children: child.props.children,\n disabled: child.props.disabled,\n closable: child.props.closable,\n forceRender: child.props.forceRender,\n }));\n }, [items, children]);\n\n const firstKey = resolvedItems[0]?.key || '';\n const [innerActiveKey, setInnerActiveKey] = useState(\n defaultActiveKey || firstKey,\n );\n const mergedActiveKey =\n controlledActiveKey !== undefined ? controlledActiveKey : innerActiveKey;\n const activeKey = resolvedItems.some((item) => item.key === mergedActiveKey)\n ? mergedActiveKey\n : firstKey;\n\n const handleTabClick = (key: string, e: React.MouseEvent) => {\n if (controlledActiveKey === undefined) {\n setInnerActiveKey(key);\n }\n onChange?.(key);\n onTabClick?.(key, e);\n };\n\n const handleRemove = (key: string, e: React.MouseEvent) => {\n e.stopPropagation();\n onEdit?.(key, 'remove');\n };\n\n const handleAdd = (e: React.MouseEvent) => {\n onEdit?.(e, 'add');\n };\n\n const monospace = tabPosition !== 'top' ? false : propsMonospace;\n const paddingVal = useMemo(() => {\n if (tabPosition !== 'top') return 0;\n if (typeof propsPadding === 'number') return propsPadding;\n if (typeof propsPadding === 'boolean' && propsPadding) return 20;\n return 0;\n }, [propsPadding, tabPosition]);\n\n const isVertical = tabPosition === 'left' || tabPosition === 'right';\n\n const extraLeft =\n tabBarExtraContent &&\n typeof tabBarExtraContent === 'object' &&\n 'left' in tabBarExtraContent\n ? tabBarExtraContent.left\n : null;\n const extraRight = tabBarExtraContent\n ? typeof tabBarExtraContent === 'object' && 'right' in tabBarExtraContent\n ? tabBarExtraContent.right\n : React.isValidElement(tabBarExtraContent)\n ? tabBarExtraContent\n : null\n : null;\n\n // Scroll state for overflow\n const navListRef = useRef<HTMLDivElement>(null);\n const [canScrollLeft, setCanScrollLeft] = useState(false);\n const [canScrollRight, setCanScrollRight] = useState(false);\n\n const checkScroll = useCallback(() => {\n const el = navListRef.current;\n if (!el || isVertical) {\n setCanScrollLeft(false);\n setCanScrollRight(false);\n return;\n }\n const { scrollLeft, scrollWidth, clientWidth } = el;\n setCanScrollLeft(scrollLeft > 1);\n setCanScrollRight(scrollLeft + clientWidth < scrollWidth - 1);\n }, [isVertical]);\n\n useEffect(() => {\n checkScroll();\n const el = navListRef.current;\n if (!el) return;\n // Use ResizeObserver to detect size changes\n let ro: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n ro = new ResizeObserver(() => checkScroll());\n ro.observe(el);\n }\n el.addEventListener('scroll', checkScroll, { passive: true });\n return () => {\n el.removeEventListener('scroll', checkScroll);\n ro?.disconnect();\n };\n }, [checkScroll, resolvedItems.length]);\n\n const scrollBy = (delta: number) => {\n const el = navListRef.current;\n if (el) {\n el.scrollBy({ left: delta, behavior: 'smooth' });\n }\n };\n\n const showScrollButtons = canScrollLeft || canScrollRight;\n\n return (\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs ant-tabs tw-flex',\n isVertical ? 'tw-flex-row' : 'tw-flex-col',\n adaptHeight && 'ald-adapt-height tw-h-full',\n size !== 'small' && 'ald-tabs-default',\n monospace && 'ald-tabs-monospace',\n compact && 'ald-tabs-compact',\n !hasDividing && 'ald-tabs-no-dividing',\n className,\n )}\n style={\n {\n ...style,\n '--header-bg-color': headerBackgroundColor,\n '--tabs-padding': `${paddingVal}px`,\n } as React.CSSProperties\n }\n >\n {/* Tab nav */}\n <div\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav ant-tabs-nav tw-flex tw-items-center',\n !isVertical &&\n hasDividing &&\n 'tw-mb-5 tw-border-0 tw-border-b tw-border-solid tw-border-b-[var(--global-cool-grey-100)]',\n !isVertical && compact && '!tw-mb-0',\n isVertical &&\n 'tw-flex-col tw-border-0 tw-border-r tw-border-solid tw-border-r-[var(--global-cool-grey-100)]',\n paddingVal && `tw-px-[${paddingVal}px]`,\n )}\n style={\n headerBackgroundColor\n ? { backgroundColor: headerBackgroundColor }\n : undefined\n }\n >\n {extraLeft}\n\n {/* Scroll left button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollLeft && 'tw-invisible',\n )}\n onClick={() => scrollBy(-200)}\n aria-label=\"Scroll tabs left\"\n >\n <ChevronLeftLine size={16} />\n </button>\n )}\n\n <div className=\"ald-tabs-nav-wrap ant-tabs-nav-wrap tw-min-w-0 tw-flex-1\">\n <div\n ref={navListRef}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-nav-list ant-tabs-nav-list tw-flex tw-overflow-hidden',\n isVertical && 'tw-flex-col',\n monospace && '[&>*]:tw-flex-1',\n isCard ? 'tw-gap-1' : !monospace && 'tw-gap-8',\n )}\n style={\n !isVertical\n ? { scrollbarWidth: 'none', msOverflowStyle: 'none' }\n : undefined\n }\n >\n {resolvedItems.map((item) => {\n const isActive = activeKey === item.key;\n // For editable-card, closable defaults to true unless explicitly set to false\n const showClose = isEditable && item.closable !== false;\n\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tab ant-tabs-tab tw-relative tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-gap-2 tw-whitespace-nowrap tw-transition-colors',\n // Card / editable-card styling\n isCard\n ? cn(\n 'tw-h-10 tw-rounded-t-[6px] tw-border tw-border-b-0 tw-border-solid tw-px-4 tw-text-sm tw-leading-5',\n 'tw-gap-sp-75',\n isActive\n ? 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--background-default)] tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-border-[var(--alias-colors-border-default)] tw-bg-[var(--alias-colors-bg-skeleton-subtler)] tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n )\n : cn(\n size === 'small'\n ? 'tw-py-2 tw-text-xs tw-leading-4'\n : 'tw-py-2.5 tw-text-sm tw-leading-5',\n monospace && 'tw-justify-center',\n isActive\n ? 'tw-font-medium tw-text-[var(--alias-colors-text-selected)]'\n : 'tw-font-medium tw-text-[var(--alias-colors-text-subtle)] hover:tw-text-inherit',\n ),\n item.disabled &&\n 'tw-pointer-events-none tw-cursor-default tw-opacity-50',\n )}\n onClick={\n item.disabled\n ? undefined\n : (e) => handleTabClick(item.key, e)\n }\n >\n {item.icon}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <span className=\"ant-tabs-tab-btn\">{item.label}</span>\n {/* Close button for editable-card */}\n {showClose && (\n <span\n className=\"ald-tabs-tab-remove tw-m-0 tw-grid tw-size-4 tw-cursor-pointer tw-place-items-center tw-p-0 tw-text-[var(--alias-colors-icon-subtle)] tw-transition-colors hover:tw-text-[var(--alias-colors-text-default)]\"\n onClick={(e) => handleRemove(item.key, e)}\n aria-label={`Remove ${item.label}`}\n >\n <CloseLightLine size={12} />\n </span>\n )}\n {/* Active indicator for non-card line tabs */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n {!isCard && isActive && !isVertical && (\n <div className=\"ant-tabs-ink-bar tw-absolute tw-inset-x-0 tw--bottom-px tw-h-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n {!isCard && isActive && isVertical && (\n <div className=\"tw-absolute tw-inset-y-0 tw--right-px tw-w-[2px] tw-rounded-[2px] tw-bg-[var(--alias-colors-border-selected)]\" />\n )}\n </div>\n );\n })}\n </div>\n </div>\n\n {/* Scroll right button */}\n {showScrollButtons && !isVertical && (\n <button\n type=\"button\"\n className={cn(\n 'ald-tabs-scroll-btn tw-flex tw-shrink-0 tw-items-center tw-justify-center tw-border-none tw-bg-transparent tw-p-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]',\n !canScrollRight && 'tw-invisible',\n )}\n onClick={() => scrollBy(200)}\n aria-label=\"Scroll tabs right\"\n >\n <ChevronRightLine size={16} />\n </button>\n )}\n\n {/* Add button for editable-card */}\n {isEditable && !hideAdd && (\n <button\n type=\"button\"\n className=\"ald-tabs-nav-add tw-ml-1 tw-flex tw-shrink-0 tw-cursor-pointer tw-items-center tw-justify-center tw-rounded tw-border tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-2 tw-py-1 tw-text-[var(--content-secondary)] tw-transition-colors hover:tw-text-[var(--content-primary)]\"\n onClick={handleAdd}\n aria-label=\"Add tab\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n\n {extraRight}\n </div>\n\n {/* Tab content */}\n {/* antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器 */}\n <div\n className={cn(\n 'ald-tabs-content ant-tabs-content ant-tabs-content-holder tw-min-h-0 tw-flex-1',\n adaptHeight && 'tw-h-full',\n )}\n >\n {resolvedItems.map((item) => {\n const isActive = item.key === activeKey;\n if (!isActive && destroyInactiveTabPane && !item.forceRender) {\n return null;\n }\n return (\n <div\n key={item.key}\n className={cn(\n // antd 兼容:保留 ant-* class,消费方 CSS 可能依赖该选择器\n 'ald-tabs-tabpane ant-tabs-tabpane',\n // v2 行为:adaptHeight 时 tabpane 撑满内容区,子元素的百分比高度才能解析\n adaptHeight && 'tw-h-full tw-overflow-y-auto',\n isActive ? 'ant-tabs-tabpane-active tw-block' : 'tw-hidden',\n )}\n role=\"tabpanel\"\n >\n {item.children}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\nTabs.TabPane = TabPane;\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { cn } from "../lib/utils.js";
2
+ import { useFloatingPopupZIndex } from "../_utils/floatingLayer.js";
2
3
  import React from "react";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
5
  import * as PopoverPrimitive from "@radix-ui/react-popover";
@@ -68,7 +69,7 @@ function ClickTooltip({ children, title, open, onOpenChange, placement = "top",
68
69
  align,
69
70
  sideOffset: 4,
70
71
  className: cn(contentClasses, overlayClassName),
71
- style: zIndex !== null && zIndex !== void 0 ? { zIndex } : void 0,
72
+ style: { zIndex },
72
73
  children: [title, /* @__PURE__ */ jsx(PopoverPrimitive.Arrow, { className: "tw-fill-[var(--alias-colors-bg-skeleton-inverse-subtler)]" })]
73
74
  })
74
75
  })]
@@ -77,6 +78,7 @@ function ClickTooltip({ children, title, open, onOpenChange, placement = "top",
77
78
  function Tooltip(props) {
78
79
  const { children, title, open, onOpenChange, placement = "top", mouseEnterDelay = 0, mouseLeaveDelay = 0, overlayClassName, trigger, getPopupContainer, getTooltipContainer, zIndex } = props;
79
80
  const { triggerRef, container } = usePortalContainer(getPopupContainer, getTooltipContainer);
81
+ const resolvedZIndex = useFloatingPopupZIndex(zIndex);
80
82
  if (!title && title !== 0) return /* @__PURE__ */ jsx(Fragment, { children });
81
83
  if (isTriggerDisabled(trigger)) return /* @__PURE__ */ jsx(Fragment, { children });
82
84
  if (isClickTrigger(trigger)) return /* @__PURE__ */ jsx(ClickTooltip, {
@@ -85,7 +87,7 @@ function Tooltip(props) {
85
87
  onOpenChange,
86
88
  placement,
87
89
  overlayClassName,
88
- zIndex,
90
+ zIndex: resolvedZIndex,
89
91
  container,
90
92
  triggerRef,
91
93
  children
@@ -111,7 +113,7 @@ function Tooltip(props) {
111
113
  align,
112
114
  sideOffset: 4,
113
115
  className: cn(contentClasses, overlayClassName),
114
- style: zIndex !== null && zIndex !== void 0 ? { zIndex } : void 0,
116
+ style: { zIndex: resolvedZIndex },
115
117
  children: [title, /* @__PURE__ */ jsx(TooltipPrimitive.Arrow, { className: "tw-fill-[var(--alias-colors-bg-skeleton-inverse-subtler)]" })]
116
118
  })
117
119
  })]