resizable-pro-table 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +6 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,7 +50,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// src/style.css
|
|
53
|
-
styleInject('.ant-table-thead > tr > th:not(.ant-table-cell-fix) {\n position: relative;\n}\n.ant-table-thead > tr > th {\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 1;\n pointer-events: auto;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
53
|
+
styleInject('.ant-table-thead > tr > th:not(.ant-table-cell-fix) {\n position: relative;\n}\n.ant-table-thead > tr > th {\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 1;\n pointer-events: auto;\n}\n.ant-table-thead > tr > th:last-child .resizable-handle {\n right: 0 !important;\n}\n.ant-table-thead > tr > th:last-child .resizable-handle::after {\n left: 10px;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
54
54
|
|
|
55
55
|
// src/ResizableProTable.tsx
|
|
56
56
|
var import_pro_components = require("@ant-design/pro-components");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["import './style.css';\n\nexport { default } from './ResizableProTable';\nexport { default as ResizableProTable } from './ResizableProTable';\nexport type { ResizableProTableProps } from './ResizableProTable';\n\nexport { default as ResizableTable } from './ResizableTable';\nexport type { ResizableTableProps } from './ResizableTable';\n\nexport { default as useResizableColumns } from './useResizableColumns';\nexport type { ResizableConfig, ColumnWidthMap, ResizableTitleProps } from './types';\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th:not(.ant-table-cell-fix) {\\n position: relative;\\n}\\n.ant-table-thead > tr > th {\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 1;\\n pointer-events: auto;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n const isFixedCell = String(restProps.className ?? '').includes('ant-table-cell-fix');\n const relativeStyle: React.CSSProperties = { position: 'relative', ...restProps.style };\n const mergedStyle = isFixedCell ? restProps.style : relativeStyle;\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={mergedStyle}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 1,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["import './style.css';\n\nexport { default } from './ResizableProTable';\nexport { default as ResizableProTable } from './ResizableProTable';\nexport type { ResizableProTableProps } from './ResizableProTable';\n\nexport { default as ResizableTable } from './ResizableTable';\nexport type { ResizableTableProps } from './ResizableTable';\n\nexport { default as useResizableColumns } from './useResizableColumns';\nexport type { ResizableConfig, ColumnWidthMap, ResizableTitleProps } from './types';\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th:not(.ant-table-cell-fix) {\\n position: relative;\\n}\\n.ant-table-thead > tr > th {\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 1;\\n pointer-events: auto;\\n}\\n.ant-table-thead > tr > th:last-child .resizable-handle {\\n right: 0 !important;\\n}\\n.ant-table-thead > tr > th:last-child .resizable-handle::after {\\n left: 10px;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n const isFixedCell = String(restProps.className ?? '').includes('ant-table-cell-fix');\n const relativeStyle: React.CSSProperties = { position: 'relative', ...restProps.style };\n const mergedStyle = isFixedCell ? restProps.style : relativeStyle;\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={mergedStyle}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 1,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -21,7 +21,7 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
// src/style.css
|
|
24
|
-
styleInject('.ant-table-thead > tr > th:not(.ant-table-cell-fix) {\n position: relative;\n}\n.ant-table-thead > tr > th {\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 1;\n pointer-events: auto;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
24
|
+
styleInject('.ant-table-thead > tr > th:not(.ant-table-cell-fix) {\n position: relative;\n}\n.ant-table-thead > tr > th {\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 1;\n pointer-events: auto;\n}\n.ant-table-thead > tr > th:last-child .resizable-handle {\n right: 0 !important;\n}\n.ant-table-thead > tr > th:last-child .resizable-handle::after {\n left: 10px;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
25
25
|
|
|
26
26
|
// src/ResizableProTable.tsx
|
|
27
27
|
import { ProTable } from "@ant-design/pro-components";
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th:not(.ant-table-cell-fix) {\\n position: relative;\\n}\\n.ant-table-thead > tr > th {\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 1;\\n pointer-events: auto;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n const isFixedCell = String(restProps.className ?? '').includes('ant-table-cell-fix');\n const relativeStyle: React.CSSProperties = { position: 'relative', ...restProps.style };\n const mergedStyle = isFixedCell ? restProps.style : relativeStyle;\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={mergedStyle}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 1,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["jsx","jsx"]}
|
|
1
|
+
{"version":3,"sources":["#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th:not(.ant-table-cell-fix) {\\n position: relative;\\n}\\n.ant-table-thead > tr > th {\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 1;\\n pointer-events: auto;\\n}\\n.ant-table-thead > tr > th:last-child .resizable-handle {\\n right: 0 !important;\\n}\\n.ant-table-thead > tr > th:last-child .resizable-handle::after {\\n left: 10px;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n const isFixedCell = String(restProps.className ?? '').includes('ant-table-cell-fix');\n const relativeStyle: React.CSSProperties = { position: 'relative', ...restProps.style };\n const mergedStyle = isFixedCell ? restProps.style : relativeStyle;\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={mergedStyle}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 1,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, tableLayout, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n tableLayout={tableLayout ?? 'fixed'}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["jsx","jsx"]}
|
package/dist/style.css
CHANGED
|
@@ -20,6 +20,12 @@
|
|
|
20
20
|
z-index: 10;
|
|
21
21
|
pointer-events: auto;
|
|
22
22
|
}
|
|
23
|
+
.ant-table-thead > tr > th:last-child .resizable-handle {
|
|
24
|
+
right: 0 !important;
|
|
25
|
+
}
|
|
26
|
+
.ant-table-thead > tr > th:last-child .resizable-handle::after {
|
|
27
|
+
left: 10px;
|
|
28
|
+
}
|
|
23
29
|
.resizable-handle::after {
|
|
24
30
|
content: '';
|
|
25
31
|
position: absolute;
|