Skip to content

Commit

Permalink
Merge pull request #360 from yamadayutaka/feature/filter-tooltip-valu…
Browse files Browse the repository at this point in the history
…e-fn

feat: add filterTooltipValueFn option to transform the value of the filter tooltip
  • Loading branch information
alessandrojcm authored Jul 17, 2024
2 parents 638088e + 28f0125 commit de06f8a
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ export const columnOptions: ColumnOption[] = [
required: false,
type: 'MRT_FilterFn',
},
{
columnOption: 'filterTooltipValueFn',
defaultValue: '',
description: 'Specify to transform tooltip values to a readable format.',
link: '',
linkText: '',
source: 'MRT',
required: false,
type: 'MRT_FilterTooltipValueFn',
},
{
columnOption: 'filterVariant',
defaultValue: "'text'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ export const MRT_TableHeadCellFilterLabel = <TData extends MRT_RowData>({
columnDef._filterFn,
);
const currentFilterOption = columnDef._filterFn;
const filterValueFn =
columnDef.filterTooltipValueFn || ((value) => value as string);
type FilterValueType = Parameters<typeof filterValueFn>[0];
const filterTooltip =
columnFilterDisplayMode === 'popover' && !isFilterActive
? localization.filterByColumn?.replace(
Expand All @@ -70,10 +73,17 @@ export const MRT_TableHeadCellFilterLabel = <TData extends MRT_RowData>({
'{filterValue}',
`"${
Array.isArray(column.getFilterValue())
? (column.getFilterValue() as [string, string]).join(
`" ${isRangeFilter ? localization.and : localization.or} "`,
? (
column.getFilterValue() as [
FilterValueType,
FilterValueType,
]
)
: (column.getFilterValue() as string)
.map((v) => filterValueFn(v))
.join(
`" ${isRangeFilter ? localization.and : localization.or} "`,
)
: filterValueFn(column.getFilterValue())
}"`,
)
.replace('" "', '');
Expand Down
3 changes: 3 additions & 0 deletions packages/mantine-react-table/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,7 @@ export type MRT_ColumnDef<TData extends MRT_RowData, TValue = unknown> = Omit<
enableEditing?: ((row: MRT_Row<TData>) => boolean) | boolean;
enableFilterMatchHighlighting?: boolean;
filterFn?: MRT_FilterFn<TData>;
filterTooltipValueFn?: MRT_FilterTooltipValueFn;
filterVariant?:
| 'autocomplete'
| 'checkbox'
Expand Down Expand Up @@ -737,6 +738,8 @@ export type MRT_FilterFn<TData extends MRT_RowData> =
| FilterFn<TData>
| MRT_FilterOption;

export type MRT_FilterTooltipValueFn<TValue = any> = (value: TValue) => string;

export type MRT_InternalFilterOption = {
divider: boolean;
label: string;
Expand Down
135 changes: 134 additions & 1 deletion packages/mantine-react-table/stories/features/Filtering.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import { useEffect, useState } from 'react';
import { Button, Flex } from '@mantine/core';
import { Button, Checkbox, Flex, Group, SegmentedControl } from '@mantine/core';
import {
type MRT_ColumnDef,
type MRT_ColumnFiltersState,
type MRT_FilterTooltipValueFn,
MantineReactTable,
} from '../../src';
import { faker } from '@faker-js/faker';
import { type Meta } from '@storybook/react';

import { MRT_Localization_EN } from '../../src/locales/en';
import { MRT_Localization_JA } from '../../src/locales/ja';

import dayjs from 'dayjs';
import isBetween from 'dayjs/plugin/isBetween';
import localizedFormat from 'dayjs/plugin/localizedFormat';
dayjs.extend(isBetween);
dayjs.extend(localizedFormat);
import Dayjs_EN from 'dayjs/locale/en';
import Dayjs_JA from 'dayjs/locale/ja';

const meta: Meta = {
title: 'Features/Filtering Examples',
};
Expand Down Expand Up @@ -730,3 +742,124 @@ export const ExternalSetFilterValue = () => (
)}
/>
);

export const CustomTooltipValueFn = () => {
const [localization, setLocalization] = useState(MRT_Localization_EN);
const [locale, setLocale] = useState<string | undefined>('en');
const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>(
[],
);
const [isActiveValueFn, setIsActiveValueFn] = useState<
MRT_FilterTooltipValueFn<string> | undefined
>(undefined);
const [dateValueFn, setDateValueFn] = useState<
MRT_FilterTooltipValueFn<Date> | undefined
>(undefined);
const [enableValueFns, setEnableValueFns] = useState(true);

const formatDate = (date: any, format: string) => {
const d = dayjs(date || '');
return d.isValid() ? d.format(format) : '';
};
const formatIsActiveValue = () => (value: string) =>
value === 'true' ? 'Yes' : 'No';
const formatDateValue = () => (value: Date) => formatDate(value, 'L');

useEffect(() => {
switch (locale) {
case 'en':
setLocalization(MRT_Localization_EN);
dayjs.locale(Dayjs_EN);
break;
case 'ja':
setLocalization(MRT_Localization_JA);
dayjs.locale(Dayjs_JA);
break;
}
}, [locale]);

useEffect(() => {
if (enableValueFns) {
setIsActiveValueFn(formatIsActiveValue);
setDateValueFn(formatDateValue);
} else {
setIsActiveValueFn(undefined);
setDateValueFn(undefined);
}
}, [enableValueFns]);

return (
<>
<MantineReactTable
renderTopToolbarCustomActions={() => (
<Group>
<Checkbox
label="Enable Custom Tooltip Value Fn"
checked={enableValueFns}
onChange={(event) =>
setEnableValueFns(event.currentTarget.checked)
}
/>
<SegmentedControl
data={['en', 'ja']}
value={locale}
onChange={setLocale}
/>
</Group>
)}
localization={localization}
columns={[
{
Cell: ({ cell }) => (cell.getValue() === 'true' ? 'Yes' : 'No'),
accessorFn: (originalRow) =>
originalRow.isActive ? 'true' : 'false',
filterVariant: 'checkbox',
filterTooltipValueFn: isActiveValueFn, //transform data to readable format for tooltip
header: 'Is Active',
id: 'isActive',
size: 200,
},
{
accessorKey: 'firstName',
header: 'First Name',
},
{
accessorKey: 'lastName',
header: 'Last Name',
},
{
Cell: ({ cell }) => formatDate(cell.getValue<Date>(), 'L'), //transform data to readable format for cell render
mantineFilterDateInputProps: {
locale: locale,
valueFormat: 'L',
},
accessorFn: (row) => new Date(row.birthDate), //transform data before processing so sorting works
accessorKey: 'birthDate',
filterVariant: 'date',
filterTooltipValueFn: dateValueFn, //transform data to readable format for tooltip
header: 'Birth Date (date)',
sortingFn: 'datetime',
},
{
Cell: ({ cell }) => formatDate(cell.getValue<Date>(), 'L'), //transform data to readable format for cell render
mantineFilterDateInputProps: {
locale: locale,
valueFormat: 'L',
},
accessorFn: (row) => new Date(row.birthDate), //transform data before processing so sorting works
accessorKey: 'birthDateRange',
filterVariant: 'date-range',
filterTooltipValueFn: dateValueFn, //transform data to readable format for tooltip
header: 'Birth Date (date-range)',
sortingFn: 'datetime',
},
]}
data={data}
onColumnFiltersChange={setColumnFilters}
state={{
columnFilters,
}}
/>
</>
);
};

0 comments on commit de06f8a

Please sign in to comment.