hover seletion

This commit is contained in:
wass08
2026-01-26 09:02:10 +09:00
parent 63d3c1524f
commit d651cca79a
4 changed files with 36 additions and 1 deletions
@@ -254,11 +254,14 @@ function ZoneItem({ zone }: { zone: ZoneNode }) {
const deleteNode = useScene((state) => state.deleteNode); const deleteNode = useScene((state) => state.deleteNode);
const updateNode = useScene((state) => state.updateNode); const updateNode = useScene((state) => state.updateNode);
const selectedZoneId = useViewer((state) => state.selection.zoneId); const selectedZoneId = useViewer((state) => state.selection.zoneId);
const hoveredId = useViewer((state) => state.hoveredId);
const setSelection = useViewer((state) => state.setSelection); const setSelection = useViewer((state) => state.setSelection);
const setHoveredId = useViewer((state) => state.setHoveredId);
const setPhase = useEditor((state) => state.setPhase); const setPhase = useEditor((state) => state.setPhase);
const setMode = useEditor((state) => state.setMode); const setMode = useEditor((state) => state.setMode);
const isSelected = selectedZoneId === zone.id; const isSelected = selectedZoneId === zone.id;
const isHovered = hoveredId === zone.id;
const handleClick = () => { const handleClick = () => {
setSelection({ zoneId: zone.id }); setSelection({ zoneId: zone.id });
@@ -284,9 +287,13 @@ function ZoneItem({ zone }: { zone: ZoneNode }) {
"flex items-center h-7 cursor-pointer group/row text-sm px-3", "flex items-center h-7 cursor-pointer group/row text-sm px-3",
isSelected isSelected
? "text-primary-foreground bg-primary/80 hover:bg-primary/90" ? "text-primary-foreground bg-primary/80 hover:bg-primary/90"
: "text-muted-foreground hover:bg-accent/50" : isHovered
? "bg-accent/70 text-foreground"
: "text-muted-foreground hover:bg-accent/50"
)} )}
onClick={handleClick} onClick={handleClick}
onMouseEnter={() => setHoveredId(zone.id)}
onMouseLeave={() => setHoveredId(null)}
> >
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
@@ -13,11 +13,20 @@ export function ItemTreeNode({ node, depth }: ItemTreeNodeProps) {
const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id)); const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id));
const isHovered = useViewer((state) => state.hoveredId === node.id); const isHovered = useViewer((state) => state.hoveredId === node.id);
const setSelection = useViewer((state) => state.setSelection); const setSelection = useViewer((state) => state.setSelection);
const setHoveredId = useViewer((state) => state.setHoveredId);
const handleClick = () => { const handleClick = () => {
setSelection({ selectedIds: [node.id] }); setSelection({ selectedIds: [node.id] });
}; };
const handleMouseEnter = () => {
setHoveredId(node.id);
};
const handleMouseLeave = () => {
setHoveredId(null);
};
return ( return (
<TreeNodeWrapper <TreeNodeWrapper
icon={<Box className="w-3.5 h-3.5" />} icon={<Box className="w-3.5 h-3.5" />}
@@ -27,6 +36,8 @@ export function ItemTreeNode({ node, depth }: ItemTreeNodeProps) {
expanded={false} expanded={false}
onToggle={() => {}} onToggle={() => {}}
onClick={handleClick} onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
isSelected={isSelected} isSelected={isSelected}
isHovered={isHovered} isHovered={isHovered}
actions={<TreeNodeActions node={node} />} actions={<TreeNodeActions node={node} />}
@@ -38,6 +38,8 @@ interface TreeNodeWrapperProps {
expanded: boolean; expanded: boolean;
onToggle: () => void; onToggle: () => void;
onClick: () => void; onClick: () => void;
onMouseEnter?: () => void;
onMouseLeave?: () => void;
actions?: React.ReactNode; actions?: React.ReactNode;
children?: React.ReactNode; children?: React.ReactNode;
isSelected?: boolean; isSelected?: boolean;
@@ -52,6 +54,8 @@ export function TreeNodeWrapper({
expanded, expanded,
onToggle, onToggle,
onClick, onClick,
onMouseEnter,
onMouseLeave,
actions, actions,
children, children,
isSelected, isSelected,
@@ -69,6 +73,8 @@ export function TreeNodeWrapper({
: "text-muted-foreground hover:bg-accent/50" : "text-muted-foreground hover:bg-accent/50"
)} )}
style={{ paddingLeft: depth * 12 + 4 }} style={{ paddingLeft: depth * 12 + 4 }}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
> >
<button <button
className="w-4 h-4 flex items-center justify-center shrink-0" className="w-4 h-4 flex items-center justify-center shrink-0"
@@ -15,11 +15,20 @@ export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id)); const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id));
const isHovered = useViewer((state) => state.hoveredId === node.id); const isHovered = useViewer((state) => state.hoveredId === node.id);
const setSelection = useViewer((state) => state.setSelection); const setSelection = useViewer((state) => state.setSelection);
const setHoveredId = useViewer((state) => state.setHoveredId);
const handleClick = () => { const handleClick = () => {
setSelection({ selectedIds: [node.id] }); setSelection({ selectedIds: [node.id] });
}; };
const handleMouseEnter = () => {
setHoveredId(node.id);
};
const handleMouseLeave = () => {
setHoveredId(null);
};
const wallLength = Math.sqrt( const wallLength = Math.sqrt(
Math.pow(node.end[0] - node.start[0], 2) + Math.pow(node.end[0] - node.start[0], 2) +
Math.pow(node.end[1] - node.start[1], 2), Math.pow(node.end[1] - node.start[1], 2),
@@ -34,6 +43,8 @@ export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
expanded={expanded} expanded={expanded}
onToggle={() => setExpanded(!expanded)} onToggle={() => setExpanded(!expanded)}
onClick={handleClick} onClick={handleClick}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
isSelected={isSelected} isSelected={isSelected}
isHovered={isHovered} isHovered={isHovered}
actions={<TreeNodeActions node={node} />} actions={<TreeNodeActions node={node} />}