syncing sidebar
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import { BuildingNode, LevelNode, useScene } from "@pascal-app/core";
|
import { BuildingNode, LevelNode, useScene } from "@pascal-app/core";
|
||||||
|
import { useViewer } from "@pascal-app/viewer";
|
||||||
import { Building2, Plus } from "lucide-react";
|
import { Building2, Plus } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { TreeNode, TreeNodeWrapper } from "./tree-node";
|
import { TreeNode, TreeNodeWrapper } from "./tree-node";
|
||||||
@@ -16,9 +17,12 @@ interface BuildingTreeNodeProps {
|
|||||||
export function BuildingTreeNode({ node, depth }: BuildingTreeNodeProps) {
|
export function BuildingTreeNode({ node, depth }: BuildingTreeNodeProps) {
|
||||||
const [expanded, setExpanded] = useState(true);
|
const [expanded, setExpanded] = useState(true);
|
||||||
const createNode = useScene((state) => state.createNode);
|
const createNode = useScene((state) => state.createNode);
|
||||||
|
const isSelected = useViewer((state) => state.selection.buildingId === node.id);
|
||||||
|
const isHovered = useViewer((state) => state.hoveredId === node.id);
|
||||||
|
const setSelection = useViewer((state) => state.setSelection);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
// Handle building selection
|
setSelection({ buildingId: node.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddLevel = (e: React.MouseEvent) => {
|
const handleAddLevel = (e: React.MouseEvent) => {
|
||||||
@@ -40,6 +44,8 @@ export function BuildingTreeNode({ node, depth }: BuildingTreeNodeProps) {
|
|||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
onToggle={() => setExpanded(!expanded)}
|
onToggle={() => setExpanded(!expanded)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
isSelected={isSelected}
|
||||||
|
isHovered={isHovered}
|
||||||
actions={
|
actions={
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { ItemNode } from "@pascal-app/core";
|
import { ItemNode } from "@pascal-app/core";
|
||||||
|
import { useViewer } from "@pascal-app/viewer";
|
||||||
import { Box } from "lucide-react";
|
import { Box } from "lucide-react";
|
||||||
import { TreeNodeWrapper } from "./tree-node";
|
import { TreeNodeWrapper } from "./tree-node";
|
||||||
|
|
||||||
@@ -8,8 +9,12 @@ interface ItemTreeNodeProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ItemTreeNode({ node, depth }: ItemTreeNodeProps) {
|
export function ItemTreeNode({ node, depth }: ItemTreeNodeProps) {
|
||||||
|
const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id));
|
||||||
|
const isHovered = useViewer((state) => state.hoveredId === node.id);
|
||||||
|
const setSelection = useViewer((state) => state.setSelection);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
// Handle item selection
|
setSelection({ selectedIds: [node.id] });
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -21,6 +26,8 @@ export function ItemTreeNode({ node, depth }: ItemTreeNodeProps) {
|
|||||||
expanded={false}
|
expanded={false}
|
||||||
onToggle={() => {}}
|
onToggle={() => {}}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
isSelected={isSelected}
|
||||||
|
isHovered={isHovered}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,15 +11,14 @@ interface LevelTreeNodeProps {
|
|||||||
|
|
||||||
export function LevelTreeNode({ node, depth }: LevelTreeNodeProps) {
|
export function LevelTreeNode({ node, depth }: LevelTreeNodeProps) {
|
||||||
const [expanded, setExpanded] = useState(true);
|
const [expanded, setExpanded] = useState(true);
|
||||||
const currentLevelId = useViewer((state) => state.selection.levelId);
|
const isSelected = useViewer((state) => state.selection.levelId === node.id);
|
||||||
|
const isHovered = useViewer((state) => state.hoveredId === node.id);
|
||||||
const setSelection = useViewer((state) => state.setSelection);
|
const setSelection = useViewer((state) => state.setSelection);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
setSelection({ levelId: node.id });
|
setSelection({ levelId: node.id });
|
||||||
};
|
};
|
||||||
|
|
||||||
const isSelected = currentLevelId === node.id;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TreeNodeWrapper
|
<TreeNodeWrapper
|
||||||
icon={<Layers className="w-3.5 h-3.5" />}
|
icon={<Layers className="w-3.5 h-3.5" />}
|
||||||
@@ -30,6 +29,7 @@ export function LevelTreeNode({ node, depth }: LevelTreeNodeProps) {
|
|||||||
onToggle={() => setExpanded(!expanded)}
|
onToggle={() => setExpanded(!expanded)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
isSelected={isSelected}
|
isSelected={isSelected}
|
||||||
|
isHovered={isHovered}
|
||||||
>
|
>
|
||||||
{node.children.map((childId) => (
|
{node.children.map((childId) => (
|
||||||
<TreeNode key={childId} nodeId={childId} depth={depth + 1} />
|
<TreeNode key={childId} nodeId={childId} depth={depth + 1} />
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ interface TreeNodeWrapperProps {
|
|||||||
actions?: React.ReactNode;
|
actions?: React.ReactNode;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
isSelected?: boolean;
|
isSelected?: boolean;
|
||||||
|
isHovered?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TreeNodeWrapper({
|
export function TreeNodeWrapper({
|
||||||
@@ -54,6 +55,7 @@ export function TreeNodeWrapper({
|
|||||||
actions,
|
actions,
|
||||||
children,
|
children,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
isHovered,
|
||||||
}: TreeNodeWrapperProps) {
|
}: TreeNodeWrapperProps) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -61,7 +63,11 @@ export function TreeNodeWrapper({
|
|||||||
className={cn(
|
className={cn(
|
||||||
"flex items-center h-7 hover:bg-accent/50 cursor-pointer group",
|
"flex items-center h-7 hover:bg-accent/50 cursor-pointer group",
|
||||||
"text-sm",
|
"text-sm",
|
||||||
isSelected ? "text-primary-foreground bg-primary/80" : "text-muted-foreground"
|
isSelected
|
||||||
|
? "text-primary-foreground bg-primary/80"
|
||||||
|
: isHovered
|
||||||
|
? "bg-accent/70 text-foreground"
|
||||||
|
: "text-muted-foreground"
|
||||||
)}
|
)}
|
||||||
style={{ paddingLeft: depth * 12 + 4 }}
|
style={{ paddingLeft: depth * 12 + 4 }}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { WallNode, useScene } from "@pascal-app/core";
|
import { WallNode } from "@pascal-app/core";
|
||||||
|
import { useViewer } from "@pascal-app/viewer";
|
||||||
import { Square } from "lucide-react";
|
import { Square } from "lucide-react";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { TreeNode, TreeNodeWrapper } from "./tree-node";
|
import { TreeNode, TreeNodeWrapper } from "./tree-node";
|
||||||
@@ -10,10 +11,12 @@ interface WallTreeNodeProps {
|
|||||||
|
|
||||||
export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
|
export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
|
||||||
const [expanded, setExpanded] = useState(false);
|
const [expanded, setExpanded] = useState(false);
|
||||||
|
const isSelected = useViewer((state) => state.selection.selectedIds.includes(node.id));
|
||||||
|
const isHovered = useViewer((state) => state.hoveredId === node.id);
|
||||||
|
const setSelection = useViewer((state) => state.setSelection);
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
// Handle wall selection
|
setSelection({ selectedIds: [node.id] });
|
||||||
useScene.getState().markDirty(node.id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const wallLength = Math.sqrt(
|
const wallLength = Math.sqrt(
|
||||||
@@ -30,6 +33,8 @@ export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
|
|||||||
expanded={expanded}
|
expanded={expanded}
|
||||||
onToggle={() => setExpanded(!expanded)}
|
onToggle={() => setExpanded(!expanded)}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
isSelected={isSelected}
|
||||||
|
isHovered={isHovered}
|
||||||
>
|
>
|
||||||
{node.children.map((childId) => (
|
{node.children.map((childId) => (
|
||||||
<TreeNode key={childId} nodeId={childId} depth={depth + 1} />
|
<TreeNode key={childId} nodeId={childId} depth={depth + 1} />
|
||||||
|
|||||||
Reference in New Issue
Block a user