= {
+ up: { icon: '/icons/room.png', label: 'Full height' },
+ cutaway: { icon: '/icons/wallcut.png', label: 'Cutaway' },
+ down: { icon: '/icons/walllow.png', label: 'Low' },
+}
+
+function ViewModeControl() {
+ const viewMode = useEditor((state) => state.viewMode)
+ const setViewMode = useEditor((state) => state.setViewMode)
+
+ return (
+
+ {VIEW_MODES.map((mode) => {
+ const isActive = viewMode === mode.id
+ return (
+
+
+
+ )
+ })}
+
+ )
+}
+
+function CollapseSidebarButton() {
+ const isCollapsed = useSidebarStore((state) => state.isCollapsed)
+ const setIsCollapsed = useSidebarStore((state) => state.setIsCollapsed)
+
+ const toggle = useCallback(() => {
+ setIsCollapsed(!isCollapsed)
+ }, [isCollapsed, setIsCollapsed])
+
+ return (
+
+
+
+
+
+ )
+}
+
+function LevelModeToggle() {
+ const levelMode = useViewer((state) => state.levelMode)
+ const setLevelMode = useViewer((state) => state.setLevelMode)
+ const isDefault = levelMode === 'stacked' || levelMode === 'manual'
+
+ const cycle = () => {
+ if (levelMode === 'manual') {
+ setLevelMode('stacked')
+ return
+ }
+
+ const index = levelModeOrder.indexOf(levelMode as (typeof levelModeOrder)[number])
+ const next = levelModeOrder[(index + 1) % levelModeOrder.length]
+ if (next) setLevelMode(next)
+ }
+
+ const label = `Levels: ${levelMode === 'manual' ? 'Manual' : (levelModeLabels[levelMode] ?? 'Stack')}`
+
+ return (
+
+
+
+ )
+}
+
+function WallModeToggle() {
+ const wallMode = useViewer((state) => state.wallMode)
+ const setWallMode = useViewer((state) => state.setWallMode)
+ const config = wallModeConfig[wallMode] ?? wallModeConfig.cutaway!
+
+ const cycle = () => {
+ const index = wallModeOrder.indexOf(wallMode as (typeof wallModeOrder)[number])
+ const next = wallModeOrder[(index + 1) % wallModeOrder.length]
+ if (next) setWallMode(next)
+ }
+
+ return (
+
+
+
+ )
+}
+
+function GridVisibilityToggle() {
+ const showGrid = useViewer((state) => state.showGrid)
+ const setShowGrid = useViewer((state) => state.setShowGrid)
+
+ return (
+
+
+
+ )
+}
+
+function UnitToggle() {
+ const unit = useViewer((state) => state.unit)
+ const setUnit = useViewer((state) => state.setUnit)
+
+ return (
+
+
+
+ )
+}
+
+function ThemeToggle() {
+ const theme = useViewer((state) => state.theme)
+ const setTheme = useViewer((state) => state.setTheme)
+
+ return (
+
+
+
+ )
+}
+
+function CameraModeToggle() {
+ const cameraMode = useViewer((state) => state.cameraMode)
+ const setCameraMode = useViewer((state) => state.setCameraMode)
+
+ return (
+
+
+
+ )
+}
+
+function WalkthroughButton() {
+ const isFirstPersonMode = useEditor((state) => state.isFirstPersonMode)
+ const setFirstPersonMode = useEditor((state) => state.setFirstPersonMode)
+
+ return (
+
+
+
+ )
+}
+
+function PreviewButton() {
+ return (
+
+
+
+ )
+}
+
+export function CommunityViewerToolbarLeft() {
+ return (
+ <>
+
+
+ >
+ )
+}
+
+export function CommunityViewerToolbarRight() {
+ return (
+
+ )
+}
diff --git a/apps/editor/package.json b/apps/editor/package.json
index 21e8dad8..f2c00a2e 100644
--- a/apps/editor/package.json
+++ b/apps/editor/package.json
@@ -11,11 +11,13 @@
"check-types": "next typegen && tsc --noEmit"
},
"dependencies": {
+ "@iconify/react": "^6.0.2",
"@number-flow/react": "^0.5.14",
"@pascal-app/core": "*",
"@pascal-app/editor": "*",
"@pascal-app/mcp": "*",
"@pascal-app/viewer": "*",
+ "@radix-ui/react-tooltip": "^1.2.8",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@tailwindcss/postcss": "^4.2.1",
diff --git a/bun.lock b/bun.lock
index 8a11d1a7..1e21227a 100644
--- a/bun.lock
+++ b/bun.lock
@@ -26,11 +26,13 @@
"name": "editor",
"version": "0.1.0",
"dependencies": {
+ "@iconify/react": "^6.0.2",
"@number-flow/react": "^0.5.14",
"@pascal-app/core": "*",
"@pascal-app/editor": "*",
"@pascal-app/mcp": "*",
"@pascal-app/viewer": "*",
+ "@radix-ui/react-tooltip": "^1.2.8",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@tailwindcss/postcss": "^4.2.1",