Skip to content

Commit

Permalink
Merge pull request #486 from icflorescu/next
Browse files Browse the repository at this point in the history
Release 7.3
  • Loading branch information
icflorescu committed Dec 7, 2023
2 parents dfa9c52 + a7b1b37 commit 3ed7c50
Show file tree
Hide file tree
Showing 34 changed files with 1,553 additions and 718 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
The following is a list of notable changes to the Mantine DataTable component.
Minor versions that are not listed in the changelog are bug fixes and small improvements.

## 7.3.0 (2023-12-07)

- Implement column dragging and toggling (see [#483](https://github.com/icflorescu/mantine-datatable/pull/483));
- Implement `selectionColumnClassName` and `selectionColumnStyle` properties;
- Update deps to ensure compatibility with Mantine 7.3.0

## 7.1.7 (2023-11-13)

- Make sure to omit `stickyHeader` and `stickyHeaderOffset` properties from inherited Table component props to avoid confusion, since Mantine DataTable header is sticky "as needed"
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The lightweight, dependency-free, **dark-theme aware** table component for your

[![Mantine DataTable](https://user-images.githubusercontent.com/581999/279479387-525bb797-cb15-4739-85c6-94ceded94bc1.png)](https://icflorescu.github.io/mantine-datatable/)

**⚠️ Mantine DataTable V7.1 is compatible with Mantine V7.1.**
**⚠️ Mantine DataTable V7 is compatible with Mantine V7.**
**💡 If you're looking for the old version that works with [Mantine V6](https://v6.mantine.dev), head over to [Mantine DataTable V6](https://icflorescu.github.io/mantine-datatable-v6).**

## Features
Expand All @@ -32,6 +32,7 @@ The lightweight, dependency-free, **dark-theme aware** table component for your
- **[Additive batch rows selection](https://icflorescu.github.io/mantine-datatable/examples/records-selection)** - select or deselect ranges of rows using the Shift key
- **[Automatically-scrollable](https://icflorescu.github.io/mantine-datatable/examples/scrollable-vs-auto-height)** - automatically scrollable or auto-height
- **[AutoAnimate support](https://icflorescu.github.io/mantine-datatable/examples/using-with-auto-animate)** - animate row sorting, addition and removal
- **[Column dragging and toggling](https://icflorescu.github.io/mantine-datatable/examples/column-dragging-and-toggling)** - drag and drop columns to reorder them, toggle column visibility (thanks to [Giovambattista Fazioli](https://github.com/gfazioli))
- **More** - check out the [full documentation](https://icflorescu.github.io/mantine-datatable/)

## Trusted by the community
Expand Down
5 changes: 5 additions & 0 deletions app/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ export const ROUTES: RouteInfo[] = [
title: 'Sorting',
description: `Example: sorting data with ${PRODUCT_NAME}`,
},
{
href: '/examples/column-dragging-and-toggling',
title: 'Column dragging and toggling',
description: `Example: dragging & toggling ${PRODUCT_NAME} columns`,
},
{
href: '/examples/infinite-scrolling',
title: 'Infinite scrolling',
Expand Down
34 changes: 34 additions & 0 deletions app/examples/column-dragging-and-toggling/DraggingExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';

import { Button, Group, Stack } from '@mantine/core';
import { DataTable, useDragToggleColumns } from '__PACKAGE__';
import { companies, type Company } from '~/data';

export default function DraggingExample() {
const key = 'draggable-example';

const { effectiveColumns, resetColumnsOrder } = useDragToggleColumns<Company>({
key,
columns: [
{ accessor: 'name', width: '40%', draggable: true },
{ accessor: 'streetAddress', width: '60%', draggable: true },
{ accessor: 'city', width: 160, draggable: true },
{ accessor: 'state', textAlign: 'right' },
],
});

return (
<Stack>
<DataTable
withTableBorder
withColumnBorders
storeColumnsKey={key}
records={companies}
columns={effectiveColumns}
/>
<Group justify="right">
<Button onClick={resetColumnsOrder}>Reset Column Order</Button>
</Group>
</Stack>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use client';

import { IconColumnRemove, IconColumns1 } from '@tabler/icons-react';
import { DataTable, useDragToggleColumns, type DataTableSortStatus } from '__PACKAGE__';
import sortBy from 'lodash/sortBy';
import { useContextMenu } from 'mantine-contextmenu';
import { useEffect, useState } from 'react';
import { companies, type Company } from '~/data';

export default function DraggingTogglingComplexExample() {
const { showContextMenu } = useContextMenu();

const [sortStatus, setSortStatus] = useState<DataTableSortStatus<Company>>({
columnAccessor: 'name',
direction: 'asc',
});

const [records, setRecords] = useState(sortBy(companies, 'name'));

useEffect(() => {
const data = sortBy(companies, sortStatus.columnAccessor) as Company[];
setRecords(sortStatus.direction === 'desc' ? data.reverse() : data);
}, [sortStatus]);

const key = 'toggleable-reset-example';

const { effectiveColumns, resetColumnsOrder, resetColumnsToggle } = useDragToggleColumns({
key,
columns: [
{ accessor: 'name', width: '40%', toggleable: true, draggable: true, sortable: true },
{ accessor: 'streetAddress', width: '60%', toggleable: true, draggable: true },
{ accessor: 'city', width: 160, toggleable: true, draggable: true },
{ accessor: 'state', textAlign: 'right' },
],
});

return (
<DataTable
withTableBorder
withColumnBorders
storeColumnsKey={key}
records={records}
columns={effectiveColumns}
sortStatus={sortStatus}
onSortStatusChange={setSortStatus}
onRowContextMenu={({ event }) =>
showContextMenu([
{
key: 'reset-columns.toggled',
icon: <IconColumnRemove size={16} />,
onClick: resetColumnsToggle,
},
{
key: 'reset-columns-order',
icon: <IconColumns1 size={16} />,
onClick: resetColumnsOrder,
},
])(event)
}
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use client';

import { IconColumnRemove, IconColumns1 } from '@tabler/icons-react';
import { DataTable, useDragToggleColumns } from '__PACKAGE__';
import { useContextMenu } from 'mantine-contextmenu';
import { companies } from '~/data';

export default function DraggingTogglingResetExample() {
const { showContextMenu } = useContextMenu();

const key = 'toggleable-reset-example';

const { effectiveColumns, resetColumnsOrder, resetColumnsToggle } = useDragToggleColumns({
key,
columns: [
{ accessor: 'name', width: '40%', toggleable: true, draggable: true },
{ accessor: 'streetAddress', width: '60%', toggleable: true, draggable: true },
{ accessor: 'city', width: 160, toggleable: true, draggable: true },
{ accessor: 'state', textAlign: 'right' },
],
});

return (
<DataTable
withTableBorder
withColumnBorders
storeColumnsKey={key}
records={companies}
columns={effectiveColumns}
onRowContextMenu={({ event }) =>
showContextMenu([
{
key: 'reset-columns.toggled',
icon: <IconColumnRemove size={16} />,
onClick: resetColumnsToggle,
},
{
key: 'reset-columns-order',
icon: <IconColumns1 size={16} />,
onClick: resetColumnsOrder,
},
])(event)
}
/>
);
}
34 changes: 34 additions & 0 deletions app/examples/column-dragging-and-toggling/TogglingExample.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';

import { Button, Group, Stack } from '@mantine/core';
import { DataTable, useDragToggleColumns } from '__PACKAGE__';
import { companies } from '~/data';

export default function TogglingExample() {
const key = 'toggleable-example';

const { effectiveColumns, resetColumnsToggle } = useDragToggleColumns({
key,
columns: [
{ accessor: 'name', width: '40%', toggleable: true },
{ accessor: 'streetAddress', width: '60%', toggleable: true },
{ accessor: 'city', width: 160, toggleable: true },
{ accessor: 'state', textAlign: 'right' },
],
});

return (
<Stack>
<DataTable
withTableBorder
withColumnBorders
storeColumnsKey={key}
records={companies}
columns={effectiveColumns}
/>
<Group justify="right">
<Button onClick={resetColumnsToggle}>Reset Column Toggled</Button>
</Group>
</Stack>
);
}
90 changes: 90 additions & 0 deletions app/examples/column-dragging-and-toggling/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Code } from '@mantine/core';
import type { Route } from 'next';
import { REPO_LINK } from '~/app/config';
import { CodeBlock } from '~/components/CodeBlock';
import { ExternalLink } from '~/components/ExternalLink';
import { PageNavigation } from '~/components/PageNavigation';
import { PageSubtitle } from '~/components/PageSubtitle';
import { PageTitle } from '~/components/PageTitle';
import { Txt } from '~/components/Txt';
import { UnorderedList } from '~/components/UnorderedList';
import { readCodeFile } from '~/lib/code';
import { allPromiseProps, getRouteMetadata } from '~/lib/utils';
import DraggingExample from './DraggingExample';
import DraggingTogglingComplexExample from './DraggingTogglingComplexExample';
import DraggingTogglingResetExample from './DraggingTogglingResetExample';
import TogglingExample from './TogglingExample';

const PATH: Route = '/examples/column-dragging-and-toggling';

export const metadata = getRouteMetadata(PATH);

export default async function DraggingExamplePage() {
const code = await allPromiseProps({
'DraggingExample.tsx': readCodeFile<string>(`${PATH}/DraggingExample.tsx`),
'DraggingTogglingResetExample.tsx': readCodeFile<string>(`${PATH}/DraggingTogglingResetExample.tsx`),
'TogglingExample.tsx': readCodeFile<string>(`${PATH}/TogglingExample.tsx`),
'DraggingTogglingComplexExample.tsx': readCodeFile<string>(`${PATH}/DraggingTogglingComplexExample.tsx`),
});

return (
<>
<PageTitle of={PATH} />
<Txt>
Starting with <Code>v7.3</Code>, Mantine DataTable supports column toggling and drag-and-drop reordering, thanks
to the <ExternalLink to={`${REPO_LINK}/pull/483`}>outstanding work</ExternalLink> of{' '}
<ExternalLink to="https://github.com/gfazioli">Giovambattista Fazioli</ExternalLink>.
</Txt>
<PageSubtitle value="Column drag-and-drop reordering" />
<DraggingExample />
<Txt>
In order to enable <strong>column dragging</strong> you’ll have to:
</Txt>
<UnorderedList compact>
<li>
add a <Code>storeColumnsKey: your_key</Code> property to the DataTable (since the order of the columns is
persisted in the local storage);
</li>
<li>
add a <Code>draggable: true</Code> property to each <strong>dragging candidate</strong> column;
</li>
<li>
use <Code>useDragToggleColumns()</Code> hook to get the sorted columns.
</li>
</UnorderedList>
<CodeBlock code={code['DraggingExample.tsx']} />
<Txt idea>
The default order of the columns is the order in which they are defined in the <Code>columns</Code> prop.
</Txt>

<PageSubtitle value="Column toggling" />
<TogglingExample />
<Txt>
In order to enable <strong>column toggling</strong> you’ll have to:
</Txt>
<UnorderedList compact>
<li>
add a <Code>storeColumnsKey: your_key</Code> property to the DataTable (since the order of the columns is
persisted in the local storage);
</li>
<li>
add a <Code>toggleable: true</Code> property to each <strong>toggling candidate</strong> column;
</li>
<li>
use <Code>useDragToggleColumns()</Code> hook to get the sorted columns.
</li>
</UnorderedList>
<CodeBlock code={code['TogglingExample.tsx']} />
<Txt idea>
The default toggled columns are the ones with <Code>defaultToggle: true</Code> property.
</Txt>
<PageSubtitle value="Dragging and toggling with context menu reset" />
<DraggingTogglingResetExample />
<CodeBlock code={code['DraggingTogglingResetExample.tsx']} />
<PageSubtitle value="Complex usage" />
<DraggingTogglingComplexExample />
<CodeBlock code={code['DraggingTogglingComplexExample.tsx']} />
<PageNavigation of={PATH} />
</>
);
}
20 changes: 20 additions & 0 deletions app/examples/records-selection/RecordsSelectionExamples.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,26 @@ export function DisabledRecordsExample() {
// example-end
}

export function CustomColumnStyleExample() {
// example-start CustomColumnStyleExample.tsx
const [selectedRecords, setSelectedRecords] = useState<Company[]>([]);

return (
<DataTable
// example-skip other props
withTableBorder
withColumnBorders
records={companies}
columns={columns}
selectedRecords={selectedRecords}
onSelectedRecordsChange={setSelectedRecords}
// example-resume
selectionColumnStyle={{ minWidth: 100 }}
/>
);
// example-end
}

export function CheckboxPropsExample() {
// example-start CheckboxPropsExample.tsx
const [selectedRecords, setSelectedRecords] = useState<Company[]>([]);
Expand Down
11 changes: 11 additions & 0 deletions app/examples/records-selection/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { getRouteMetadata } from '~/lib/utils';
import {
CellTriggerRecordsSelectionExample,
CheckboxPropsExample,
CustomColumnStyleExample,
DisabledRecordsExample,
RecordsSelectionExample,
RecordsSelectionHorizontalScrollingBehaviorExample,
Expand All @@ -30,6 +31,7 @@ export default async function RecordsSelectionExamplePage() {
| 'RecordsSelectionExample.tsx'
| 'CellTriggerRecordsSelectionExample.tsx'
| 'DisabledRecordsExample.tsx'
| 'CustomColumnStyleExample.tsx'
| 'CheckboxPropsExample.tsx'
| 'SelectAllRecordsOnAllPagesExample.tsx'
| 'RecordsSelectionHorizontalScrollingBehaviorExample.tsx',
Expand Down Expand Up @@ -90,6 +92,15 @@ export default async function RecordsSelectionExamplePage() {
<CodeBlock tabs={{ code, keys: ['DisabledRecordsExample.tsx', 'columns.ts'] }} />
<Txt>The above code will result in the following behavior:</Txt>
<DisabledRecordsExample />
<PageSubtitle value="Customizing the selection column className and style" />
<Txt>
By default, the selection column has an absolute width of <Code>0</Code>, to that it only takes up the space
required by the selection checkboxes. If you’re not happy with this behavior, or you have other reasons to
customize the column’s properties, you can do so by providing the <Code>selectionColumnClassName</Code> and/or{' '}
<Code>selectionColumnStyle</Code> properties:
</Txt>
<CodeBlock code={code['CustomColumnStyleExample.tsx']} />
<CustomColumnStyleExample />
<PageSubtitle value="Additional selection checkbox props" />
<Txt>
You can pass additional props to the selection checkboxes by providing the{' '}
Expand Down
8 changes: 4 additions & 4 deletions app/layout.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@import '@mantine/core/esm/index.css' layer(mantine-core);
@import '@mantine/dates/esm/index.css' layer(mantine-dates);
@import '@mantine/notifications/esm/index.css' layer(mantine-notifications);
@import '@mantine/code-highlight/esm/index.css' layer(mantine-code-highlight);
@import '@mantine/core/styles.css' layer(mantine-core);
@import '@mantine/dates/styles.css' layer(mantine-dates);
@import '@mantine/notifications/styles.css' layer(mantine-notifications);
@import '@mantine/code-highlight/styles.css' layer(mantine-code-highlight);
@import 'mantine-contextmenu/dist/styles.css' layer(mantine-contextmenu);
@import '../package/styles.css' layer(mantine-datatable);
@import '@docsearch/css';
Expand Down
2 changes: 1 addition & 1 deletion app/styling/examples/fine-grained/layout.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* 👇 Expressly import the mantine core styles into mantine-core layer */
@import '@mantine/core/esm/index.css' layer(mantine-core);
@import '@mantine/core/styles.css' layer(mantine-core);

/* 👇 Expressly import the mantine-datatable styles into mantine-datatable layer */
@import '__PACKAGE__/dist/styles.css' layer(mantine-datatable);
Expand Down
Loading

0 comments on commit 3ed7c50

Please sign in to comment.