I'm trying to make antd's table have resizable columns. It works good. But I can't make any column smaller than its inner text, when I'm resizing the column. I've tried to set a minimal width, but it doesn't work. At least in my case. I believe there should be some properties, that I can pass to resizable component in order to set a minimal width. I've found the example How antd table can work together with react-resizable library. Right here https://ant.design/components/table/ But even in this example it works the same as in my case.
import React, { useState } from "react";
import { Button, Icon } from "antd";
import { Resizable } from "react-resizable";
import moment from "moment";
import UniqIdsGenerator from "lib/uniqIdsGenerator";
import SearchData from "containers/SearchData";
import { StyledTable, LikeLink, Header, SearchWrapper } from "./style";
const ResizeableTitle = props => {
const { onResize, width, onClick, ...restProps } = props;
const [allowClick, setAllowClick] = useState(true);
if (!width) {
return <th {...restProps} />;
}
return (
<Resizable
width={width}
height={0}
onResize={onResize}
onMouseDown={e => {
setAllowClick(true);
}}
onResizeStart={e => {
setAllowClick(false);
}}
onClick={e => {
if (allowClick && typeof onClick === "function") {
onClick(e);
}
}}
>
<th {...restProps} />
</Resizable>
);
};
const RowActions = ({ actions, uniqId, onRowAction, record, user }) =>
actions.map(({ label, action }, fieldName) => {
let { status } = record;
return label === "log" && !statuses[status] ? null : (
<LikeLink
key={fieldName}
id={uniqId.getTableRowAction(action)}
onClick={e => {
e.preventDefault();
onRowAction({ record, action });
}}
>
{label}
</LikeLink>
);
});
const HeaderActions = ({ actions, handleClick, uniqId, isAllowed }) =>
actions.map(({ label, action, icon }, fieldName) => {
let button;
label == "Add Upload" && !isAllowed
? (button = (
<Button
key={fieldName}
id={uniqId.getHeaderButton(fieldName)}
onClick={() => handleClick(action)}
disabled={true}
id={"disabledButton"}
>
{icon && <Icon type={icon} />}
{label}
</Button>
))
: (button = (
<Button
key={fieldName}
id={uniqId.getHeaderButton(fieldName)}
onClick={() => handleClick(action)}
>
{icon && <Icon type={icon} />}
{label}
</Button>
));
return button;
});
class DataTable extends React.PureComponent {
state = {
columns: []
};
components = {
header: {
cell: ResizeableTitle
}
};
uniqId = new UniqIdsGenerator(this.props.prefixId);
componentDidMount() {
const { handleClickOnTableRowAction } = this.props;
this.getColumns({
onRowAction: data => handleClickOnTableRowAction(data)
});
}
handleResize = index => (e, { size }) => {
this.setState(({ columns }) => {
const nextColumns = [...columns];
nextColumns[index] = {
...nextColumns[index],
width: size.width
};
// console.log(size.width)
return { columns: nextColumns };
});
};
getColumns = ({ onRowAction }) => {
const { columnsSchema, user } = this.props;
const { uniqId } = this;
let totalColumnsWidth = 250;
const getTotalColumnWidth = column => {
if (column.width) {
totalColumnsWidth += column.width;
}
};
const checkForWidth = column =>
((column.width && totalColumnsWidth) || column.isWidthFixed) &&
column.width;
const prepareToTable = (column, fieldName) => {
return {
title: column.label,
dataIndex: column.fieldName,
orgIndex: (text, record) => column.fieldName,
key: column.key ? column.key : column.fieldName,
width: checkForWidth(column),
defaultSortOrder: column.defaultSortOrder,
sorter: column.sortAs
? (a, b) => sortAs[column.sortAs](a, b, column.fieldName)
: "",
// filters: column.filters && column.filters,
onFilter: (value, record) => record.traceType.match(value),
// onHeaderCell: () => ({ 'id': uniqId.getTableTheadTh(fieldName) }),
render: (text, record) => {
return {
props: {
id: uniqId.getTableTbodyTd(fieldName),
className: "classNameOfCell"
},
children: addChildren(column, record)
};
}
};
};
const addChildren = (column, record) => {
if (column.render) {
return column.render(record);
} else if (column.actions) {
return (
<RowActions
{...column}
user={user}
uniqId={this.uniqId}
onRowAction={onRowAction}
record={record}
/>
);
}
// }
else {
return record[column.fieldName];
}
};
columnsSchema && columnsSchema.forEach(getTotalColumnWidth);
const cols = columnsSchema.map(prepareToTable);
// columnsSchema && columnsSchema.forEach(getTotalColumnWidth);
const columns =
cols &&
cols.map((col, index) => ({
...col,
onHeaderCell: column => ({
width: column.width,
onResize: this.handleResize(index)
})
}));
columns && this.setState({ columns: columns });
};
render() {
const {
data,
staticData,
getRowKey,
onSearch,
loading,
handleClickOnTableRowAction,
handleClickOnHeaderButton,
headerActionsSchema,
isSearchDisabled,
isAllowed
} = this.props;
const { uniqId } = this;
const { columns } = this.state;
return (
<div id={uniqId.getComponentDivWrapper()}>
<Header id={uniqId.getHeaderDiv()}>
{!isSearchDisabled && (
<SearchWrapper>
<SearchData
id={uniqId.getHeaderInput()}
placeholder="Search"
onSearch={e => onSearch(e, staticData)}
/>
</SearchWrapper>
)}
<HeaderActions
actions={headerActionsSchema ? headerActionsSchema : []}
uniqId={uniqId}
handleClick={handleClickOnHeaderButton}
isAllowed={isAllowed}
/>
</Header>
<div id={uniqId.getTableDivWrapper()}>
<StyledTable
loading={loading}
dataSource={data}
bordered
rowKey={getRowKey}
size="small"
pagination={{ pageSize: 10 }}
onRow={(row, fieldName) => ({
id: uniqId.getTableTbodyTr(fieldName)
})}
onHeaderRow={(row, fieldName) => ({
id: uniqId.getTableTheadTr(fieldName)
})}
components={this.components}
columns={columns}
/>
</div>
</div>
);
}
}
export default DataTable;
To specify the minimum width of a column:
columns: [
{
title: 'Date',
dataIndex: 'date',
width: 200,
minWidth: 120
},
]
const columns = this.state.columns.map((col, index) => ({
...col,
onHeaderCell: column => ({
minWidth: column.minWidth,
width: column.width,
onResize: this.handleResize(index)
})
}));
minConstraints={[minWidth, 0]}
to <Resizable />
wrapperNOTE: The same will work for max width but we pass the maxWidth prop to maxConstraints={[maxWidth, 0]}
. Also about the property names we could use whatever name we want for minWidth or maxWidth. They are just variables that pass down the numbers we want.
Example on codesandbox: https://codesandbox.io/s/minwidthresizable-cp25n
The example was based on the official demo: https://ant.design/components/table/#components-table-demo-resizable-column
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With