Replies: 3 comments 1 reply
-
I think I've managed to do it, but there's still a lot of work to be done to make it truly polished. FilterTreeInput.tsx import clsx from 'clsx';
import { Checkbox, getTreeExpandedState, Group, MultiSelect, Popover, RenderTreeNodePayload, Tree, TreeNodeData, useTree } from '@mantine/core'
import classes from './FilterTreeInput.module.css'
import { IconChevronDown } from '@tabler/icons-react';
const data: TreeNodeData[] = [
{
label: 'src',
value: 'src',
children: [
{
label: 'src/components',
value: 'src/components',
children: [
{ label: 'Accordion.tsx', value: 'src/components/Accordion.tsx' },
{ label: 'Tree.tsx', value: 'src/components/Tree.tsx' },
{ label: 'Button.tsx', value: 'src/components/Button.tsx' },
],
},
],
},
{
label: 'node_modules',
value: 'node_modules',
children: [
{
label: 'react',
value: 'node_modules/react',
children: [
{ label: 'index.d.ts', value: 'node_modules/react/index.d.ts' },
{ label: 'package.json', value: 'node_modules/react/package.json' },
],
},
],
}
];
export const FilterTreeInput = () => {
const tree = useTree({
initialExpandedState: getTreeExpandedState(data, '*'),
initialCheckedState: [
'node_modules',
'node_modules/@mantine/core/index.d.ts',
'node_modules/@mantine/form/package.json',
]
})
const renderTreeNode = ({
node,
expanded,
hasChildren,
elementProps,
tree,
}: RenderTreeNodePayload) => {
const checked = tree.isNodeChecked(node.value)
const indeterminate = tree.isNodeIndeterminate(node.value)
return (
<Group gap="xs" {...elementProps}>
<Checkbox.Indicator
checked={checked}
indeterminate={indeterminate}
onClick={() => {
console.log(checked, node.value)
if (checked) {
tree.uncheckNode(node.value)
} else {
tree.checkNode(node.value)
}
}}
/>
<Group gap={5} onClick={() => tree.toggleExpanded(node.value)}>
<span>{node.label}</span>
{hasChildren && (
<IconChevronDown
size={14}
style={{ transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)' }}
/>
)}
</Group>
</Group>
)
}
return (
<Popover width={230} position="bottom" offset={{ mainAxis: 15, crossAxis: 15 }}>
<Popover.Target>
<MultiSelect
placeholder='以 文档分类 过滤'
variant='unstyled'
className={clsx('mrt-filter-text-input', classes.root)}
/>
</Popover.Target>
<Popover.Dropdown>
<Tree
data={data}
tree={tree}
levelOffset={23}
expandOnClick={false}
renderNode={renderTreeNode}
/>
</Popover.Dropdown>
</Popover>
)
} FilterTreeInput.module.css (extract from .root {
font-weight: normal;
border-bottom: 2px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-gray-7));
min-width: auto;
width: 100%;
} |
Beta Was this translation helpful? Give feedback.
-
Hi @eastack , all of the components used in MRT are exported for use, you can import the |
Beta Was this translation helpful? Give feedback.
-
MRT currently supports the following filter variants: At first, I thought this should be straightforward—I could simply use |
Beta Was this translation helpful? Give feedback.
-
I'm a React beginner, so please forgive me if I ask any silly questions. I'm currently developing a simple CMS system, and for the table component, I'm using MRT (Material React Table) because I find it powerful, well-designed, and highly customizable. At the moment, I'm trying to create a custom column filter component. I want to display a tree component showing the document category tree for filtering when the input box is clicked. However, I'm unsure how to make my Input component's appearance consistent with MRT's. Right now, the interface looks a bit out of place.
Beta Was this translation helpful? Give feedback.
All reactions