Files
oranguru/src/Griddy/features/tree/TreeExpandButton.tsx
2026-02-16 22:48:48 +02:00

70 lines
1.5 KiB
TypeScript

import { Loader } from '@mantine/core';
import type { ReactNode } from 'react';
import styles from '../../styles/griddy.module.css';
interface TreeExpandButtonProps {
canExpand: boolean;
isExpanded: boolean;
isLoading?: boolean;
onToggle: () => void;
icons?: {
collapsed?: ReactNode;
expanded?: ReactNode;
leaf?: ReactNode;
};
}
const DEFAULT_ICONS = {
collapsed: '\u25B6', // ►
expanded: '\u25BC', // ▼
leaf: null,
};
export function TreeExpandButton({
canExpand,
isExpanded,
isLoading = false,
onToggle,
icons = DEFAULT_ICONS,
}: TreeExpandButtonProps) {
const displayIcons = { ...DEFAULT_ICONS, ...icons };
// If loading, show spinner
if (isLoading) {
return (
<button
className={styles['griddy-tree-expand-button']}
disabled
style={{ cursor: 'wait' }}
type="button"
>
<Loader size="xs" />
</button>
);
}
// If can't expand (leaf node), show leaf icon or empty space
if (!canExpand) {
return (
<span className={styles['griddy-tree-expand-button']} style={{ cursor: 'default' }}>
{displayIcons.leaf || <span style={{ width: 20 }} />}
</span>
);
}
// Show expand/collapse icon
return (
<button
className={styles['griddy-tree-expand-button']}
onClick={(e) => {
e.stopPropagation();
onToggle();
}}
type="button"
>
{isExpanded ? displayIcons.expanded : displayIcons.collapsed}
</button>
);
}