diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index f3acc318..b6ff26f8 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -61,6 +61,7 @@ export { isOperationDoorType, SECTIONAL_GARAGE_RENDER_OPEN_SCALE, } from './lib/door-operation' +export { getDefaultLevelName, getLevelDisplayName } from './lib/level-name' export { type Point2D as PolygonPoint2D, pointInPolygon as pointInPolygon2D, diff --git a/packages/editor/src/lib/level-name.ts b/packages/core/src/lib/level-name.ts similarity index 86% rename from packages/editor/src/lib/level-name.ts rename to packages/core/src/lib/level-name.ts index 9476aa5b..dd4f904f 100644 --- a/packages/editor/src/lib/level-name.ts +++ b/packages/core/src/lib/level-name.ts @@ -1,4 +1,4 @@ -import type { LevelNode } from '@pascal-app/core' +import type { LevelNode } from '../schema' export function getDefaultLevelName(level: number): string { if (level === 0) return 'Ground Floor' diff --git a/packages/editor/src/components/tools/zone/zone-tool.tsx b/packages/editor/src/components/tools/zone/zone-tool.tsx index cf43f26c..7ce8f0ae 100644 --- a/packages/editor/src/components/tools/zone/zone-tool.tsx +++ b/packages/editor/src/components/tools/zone/zone-tool.tsx @@ -184,7 +184,7 @@ export const ZoneTool: React.FC = () => { const [gridX, gridZ] = snapWorldXZForActiveBuilding( event.position[0], event.position[2], - 0.5, + useEditor.getState().gridSnapStep, ).local cursorPosition = [gridX, gridZ] levelYRef.current = event.localPosition[1] @@ -217,7 +217,7 @@ export const ZoneTool: React.FC = () => { const [gridX, gridZ] = snapWorldXZForActiveBuilding( event.position[0], event.position[2], - 0.5, + useEditor.getState().gridSnapStep, ).local let clickPoint: [number, number] = [gridX, gridZ] diff --git a/packages/editor/src/components/ui/action-menu/view-toggles.tsx b/packages/editor/src/components/ui/action-menu/view-toggles.tsx index 1e461661..7b5c2a5b 100644 --- a/packages/editor/src/components/ui/action-menu/view-toggles.tsx +++ b/packages/editor/src/components/ui/action-menu/view-toggles.tsx @@ -13,7 +13,7 @@ import { useViewer } from '@pascal-app/viewer' import { Check, ChevronDown, Eye, EyeOff, Layers2, Plus, Trash2 } from 'lucide-react' import { useCallback, useRef, useState } from 'react' import { useShallow } from 'zustand/react/shallow' -import { getLevelDisplayName } from '../../../lib/level-name' +import { getLevelDisplayName } from '@pascal-app/core' import { createLocalGuideImage } from '../../../lib/local-guide-image' import { cn } from '../../../lib/utils' import useEditor, { type GridSnapStep } from '../../../store/use-editor' diff --git a/packages/editor/src/components/ui/command-palette/index.tsx b/packages/editor/src/components/ui/command-palette/index.tsx index 39b7e012..4f9d2964 100644 --- a/packages/editor/src/components/ui/command-palette/index.tsx +++ b/packages/editor/src/components/ui/command-palette/index.tsx @@ -10,7 +10,7 @@ import { useEffect, useState } from 'react' import { create } from 'zustand' import { useShallow } from 'zustand/shallow' import { Dialog, DialogContent, DialogTitle } from './../../../components/ui/primitives/dialog' -import { getLevelDisplayName } from '../../../lib/level-name' +import { getLevelDisplayName } from '@pascal-app/core' import { useCommandRegistry } from '../../../store/use-command-registry' import { usePaletteViewRegistry } from '../../../store/use-palette-view-registry' diff --git a/packages/editor/src/components/ui/floating-level-selector.tsx b/packages/editor/src/components/ui/floating-level-selector.tsx index 1faa7b0d..ef922dfa 100644 --- a/packages/editor/src/components/ui/floating-level-selector.tsx +++ b/packages/editor/src/components/ui/floating-level-selector.tsx @@ -41,7 +41,7 @@ import { buildLevelDuplicateCreateOps, type LevelDuplicatePreset, } from '../../lib/level-duplication' -import { getDefaultLevelName, getLevelDisplayName } from '../../lib/level-name' +import { getDefaultLevelName, getLevelDisplayName } from '@pascal-app/core' import { deleteLevelWithFallbackSelection } from '../../lib/level-selection' import { getEditorClipboardSnapshot, diff --git a/packages/editor/src/components/ui/item-catalog/item-catalog.tsx b/packages/editor/src/components/ui/item-catalog/item-catalog.tsx index 8d5206e8..77db922c 100644 --- a/packages/editor/src/components/ui/item-catalog/item-catalog.tsx +++ b/packages/editor/src/components/ui/item-catalog/item-catalog.tsx @@ -1,7 +1,7 @@ 'use client' import type { AssetInput } from '@pascal-app/core' -import { resolveCdnUrl } from '@pascal-app/viewer' +import { resolveCdnUrl, useViewer } from '@pascal-app/viewer' import Image from 'next/image' import { useEffect } from 'react' import { @@ -96,6 +96,10 @@ export function ItemCatalog({ key={index} onClick={() => { triggerSFX('sfx:menu-click') + // Drop the current selection before arming placement — keeping + // it would route shortcuts (rotate & co) to both the ghost and + // the selected node. + useViewer.getState().setSelection({ selectedIds: [], zoneId: null }) setSelectedItem(item) setTool('item') setMode('build') diff --git a/packages/editor/src/components/ui/level-duplicate-dialog.tsx b/packages/editor/src/components/ui/level-duplicate-dialog.tsx index 5b2b9f47..413f60bb 100644 --- a/packages/editor/src/components/ui/level-duplicate-dialog.tsx +++ b/packages/editor/src/components/ui/level-duplicate-dialog.tsx @@ -3,7 +3,7 @@ import type { LevelNode } from '@pascal-app/core' import { useEffect, useState } from 'react' import type { LevelDuplicatePreset } from '../../lib/level-duplication' -import { getLevelDisplayName } from '../../lib/level-name' +import { getLevelDisplayName } from '@pascal-app/core' import { cn } from '../../lib/utils' import { Dialog, diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx index 788054f2..7d02ab61 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/index.tsx @@ -36,7 +36,7 @@ import { buildLevelDuplicateCreateOps, type LevelDuplicatePreset, } from './../../../../../lib/level-duplication' -import { getDefaultLevelName } from './../../../../../lib/level-name' +import { getDefaultLevelName } from '@pascal-app/core' import { deleteLevelWithFallbackSelection } from './../../../../../lib/level-selection' import { createLocalGuideImage } from './../../../../../lib/local-guide-image' import { cn } from './../../../../../lib/utils' diff --git a/packages/editor/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx b/packages/editor/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx index 0047dd46..168c39d7 100644 --- a/packages/editor/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +++ b/packages/editor/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx @@ -3,7 +3,7 @@ import { useViewer } from '@pascal-app/viewer' import { Layers } from 'lucide-react' import { memo, useCallback, useState } from 'react' import { useShallow } from 'zustand/react/shallow' -import { getDefaultLevelName } from '../../../../../lib/level-name' +import { getDefaultLevelName } from '@pascal-app/core' import { InlineRenameInput } from './inline-rename-input' import { focusTreeNode, TreeNode, TreeNodeWrapper } from './tree-node' import { TreeNodeActions } from './tree-node-actions' diff --git a/packages/editor/src/components/viewer-overlay.tsx b/packages/editor/src/components/viewer-overlay.tsx index 7d60a23b..28f5f876 100644 --- a/packages/editor/src/components/viewer-overlay.tsx +++ b/packages/editor/src/components/viewer-overlay.tsx @@ -6,6 +6,7 @@ import { type AnyNodeId, type BuildingNode, emitter, + getLevelDisplayName, type LevelNode, useScene, type ZoneNode, @@ -30,7 +31,6 @@ import { } from 'lucide-react' import Link from 'next/link' import { useShallow } from 'zustand/react/shallow' -import { getLevelDisplayName } from '../lib/level-name' import { cn } from '../lib/utils' import { ActionButton } from './ui/action-menu/action-button' import { diff --git a/packages/nodes/src/shelf/parametrics.ts b/packages/nodes/src/shelf/parametrics.ts index cf19d743..0f4fdb62 100644 --- a/packages/nodes/src/shelf/parametrics.ts +++ b/packages/nodes/src/shelf/parametrics.ts @@ -76,5 +76,9 @@ export const shelfParametrics: ParametricDescriptor = { { key: 'height', kind: 'number', unit: 'm', min: 0.05, max: 2.5, step: 0.05 }, ], }, + { + label: 'Position', + fields: [{ key: 'position', kind: 'vec3' }], + }, ], }