Untitled
unknown
plain_text
9 months ago
7.7 kB
3
Indexable
.rct-tree-item-li {
list-style: none;
border-radius: 4px;
margin: 2px 0;
}
.rct-tree-item-title-container {
display: flex;
align-items: center;
min-height: var(--rct-item-height, 32px);
padding-right: 8px;
border-radius: 4px;
}
.rct-tree-item-button-container {
display: flex;
align-items: center;
flex: 1;
min-width: 0; /* Prevents flex items from overflowing */
}
.rct-tree-item-button {
display: flex;
align-items: center;
background: none;
border: none;
padding: 4px 8px;
font: inherit;
cursor: pointer;
text-align: left;
min-width: 0;
}
.rct-tree-item-title-container .rct-tree-item-arrow {
margin-right: 4px;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useState } from 'react';
import { observer } from 'mobx-react-lite';
import { useRootStore } from '../../providers/root-store-provider';
import { ControlledTreeEnvironment, Tree, TreeItem, TreeItemIndex, TreeItemRenderContext } from 'react-complex-tree';
import { VisibilityOff, Visibility, Edit } from '@mui/icons-material';
import { IconButton, Link, Paper } from '@mui/material';
import 'react-complex-tree/lib/style-modern.css';
import { CategoryNodeData } from 'models/stores/category-store';
import {
TreeItemContainer,
ItemTitle,
ActionsContainer,
ShowProductsLink,
ProductCount,
TreeContainer,
} from './categories-tree.styled';
const combineClasses = (...classes: (string | boolean | undefined)[]) => {
return classes.filter(Boolean).join(' ');
};
export const CategoriesTree: React.FC = observer(() => {
const rootStore = useRootStore();
const { categoryStore } = rootStore;
console.log(categoryStore.treeData);
const renderItem = ({
item,
depth,
children,
arrow,
context,
}: {
item: TreeItem<CategoryNodeData | null>;
depth: number;
children: React.ReactNode;
arrow: React.ReactNode;
context: TreeItemRenderContext;
}) => {
const category = item.data;
if (!category) return null;
const InteractiveComponent = context.isRenaming ? 'div' : 'button';
const type = context.isRenaming ? undefined : 'button';
return (
<li
{...context.itemContainerWithChildrenProps}
className={combineClasses(
'rct-tree-item-li',
context.isSelected && 'rct-tree-item-li-selected',
context.isFocused && 'rct-tree-item-li-focused',
context.isDraggingOver && 'rct-tree-item-li-dragging-over',
)}
style={{ '--rct-item-height': '32px' } as React.CSSProperties}
>
<div
{...context.itemContainerWithoutChildrenProps}
className={combineClasses(
'rct-tree-item-title-container',
context.isSelected && 'rct-tree-item-title-container-selected',
context.isFocused && 'rct-tree-item-title-container-focused',
context.isDraggingOver && 'rct-tree-item-title-container-dragging-over',
)}
// This maintains proper indentation
style={{ paddingLeft: `${depth * 20}px` }}
>
<div className="rct-tree-item-button-container">
{arrow}
<InteractiveComponent
{...context.interactiveElementProps}
type={type}
className={combineClasses(
'rct-tree-item-button',
context.isSelected && 'rct-tree-item-button-selected',
context.isFocused && 'rct-tree-item-button-focused',
)}
>
<ItemTitle>{category.name}</ItemTitle>
<ProductCount>({category.productIds.length})</ProductCount>
</InteractiveComponent>
</div>
<ActionsContainer>
<ShowProductsLink as={Link} href={''}>
Zobrazit produkty
</ShowProductsLink>
<IconButton size="small" disabled={!category.parentId}>
{category.isActive ? <Visibility /> : <VisibilityOff />}
</IconButton>
<IconButton size="small" disabled={!category.parentId}>
<Edit />
</IconButton>
</ActionsContainer>
</div>
{children}
</li>
);
};
return (
<Paper>
<ControlledTreeEnvironment
items={categoryStore.treeData}
getItemTitle={(item) => item.data?.name ?? 'Root'}
viewState={{
categories: {
focusedItem: categoryStore.focusedItem,
expandedItems: categoryStore.expandedItems,
selectedItems: categoryStore.selectedItems,
},
}}
onFocusItem={(item) => categoryStore.setFocusedItem(item.index)}
onExpandItem={(item) => categoryStore.toggleExpandedItem(item.index)}
onCollapseItem={(item) => categoryStore.toggleExpandedItem(item.index)}
onSelectItems={(items) => categoryStore.setSelectedItems(items)}
renderItem={renderItem}
>
<Tree treeId="categories" rootItem="root" />
</ControlledTreeEnvironment>
</Paper>
);
});
import { styled } from '@mui/material/styles';
import { alpha } from '@mui/material';
export const TreeContainer = styled('div')(({ theme }) => ({
height: 500,
'& .rct-tree-item-arrow': {
color: theme.palette.grey[500],
transition: 'transform 0.2s',
marginRight: 8,
'& svg': {
width: '14px',
height: '14px',
},
},
'& .rct-tree-item-title-container': {
display: 'flex',
alignItems: 'center',
width: '100%',
padding: theme.spacing(1),
'&:hover': {
backgroundColor: alpha(theme.palette.warning.light, 0.1),
},
},
}));
export const TreeItemContainer = styled('div')<{ depth: number }>(({ theme, depth }) => ({
display: 'flex',
alignItems: 'center',
margin: `8px 8px 8px ${depth * 20}px`,
width: `calc(100% - ${depth * 20}px)`,
transition: 'background-color 0.2s',
'&:hover': {
backgroundColor: alpha(theme.palette.warning.light, 0.1),
},
}));
export const ItemTitle = styled('span')({
display: 'inline-block',
marginRight: 8,
});
export const ProductCount = styled('span')(({ theme }) => ({
color: theme.palette.primary.main,
fontWeight: 'bold',
display: 'inline-block',
}));
export const ActionsContainer = styled('div')({
display: 'flex',
gap: 10,
alignItems: 'center',
marginLeft: 'auto',
flexShrink: 0,
});
export const ShowProductsLink = styled('a')(({ theme }) => ({
color: theme.palette.primary.main,
fontSize: '0.75rem',
textDecoration: 'underline',
'&:hover': {
color: theme.palette.primary.dark,
},
}));
Editor is loading...
Leave a Comment