@pascal-app/editor 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/package.json +9 -15
  2. package/src/components/editor/action-menu-button.tsx +1 -1
  3. package/src/components/editor/alignment-3d-guide-layer.tsx +1 -1
  4. package/src/components/editor/custom-camera-controls.tsx +11 -11
  5. package/src/components/editor/editor-layout-v2.tsx +1 -1
  6. package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
  7. package/src/components/editor/first-person-controls.tsx +20 -1981
  8. package/src/components/editor/floating-action-menu.tsx +1 -1
  9. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  10. package/src/components/editor/floor-region-controls.tsx +6 -2
  11. package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
  12. package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
  13. package/src/components/editor/floorplan-panel.tsx +26 -22
  14. package/src/components/editor/floorplan-wall-typing-keys.ts +1 -1
  15. package/src/components/editor/follow-pascal.test.tsx +1 -2
  16. package/src/components/editor/follow-pascal.tsx +1 -1
  17. package/src/components/editor/footprint-height-handle.tsx +1 -1
  18. package/src/components/editor/group-actions.ts +1 -2
  19. package/src/components/editor/group-floating-action-menu.tsx +1 -1
  20. package/src/components/editor/group-move-3d.ts +1 -2
  21. package/src/components/editor/group-rotate-handle.tsx +1 -2
  22. package/src/components/editor/handles/use-handle-drag.ts +1 -2
  23. package/src/components/editor/index.tsx +24 -14
  24. package/src/components/editor/inspector-extension-actions.tsx +1 -1
  25. package/src/components/editor/node-arrow-handles.tsx +1 -1
  26. package/src/components/editor/open-wall-ends-3d-layer.tsx +1 -1
  27. package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
  28. package/src/components/editor/room-controls.tsx +7 -4
  29. package/src/components/editor/room-handles-2d.tsx +2 -3
  30. package/src/components/editor/room-handles.tsx +1 -2
  31. package/src/components/editor/room-highlight.tsx +6 -105
  32. package/src/components/editor/room-labels.test.ts +8 -822
  33. package/src/components/editor/room-labels.tsx +40 -1671
  34. package/src/components/editor/room-webgpu-materials.test.ts +1 -1
  35. package/src/components/editor/selection-manager.tsx +5 -3
  36. package/src/components/editor/site-edge-labels.tsx +1 -1
  37. package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
  38. package/src/components/editor/use-floorplan-background-placement.ts +2 -1
  39. package/src/components/editor/views/plugins-view.tsx +1 -1
  40. package/src/components/editor/views/view-bar.tsx +9 -9
  41. package/src/components/editor/wall-measurement-label.tsx +1 -1
  42. package/src/components/editor/wall-move-side-handles.tsx +1 -1
  43. package/src/components/editor/wall-pull-grip.tsx +2 -2
  44. package/src/components/editor-2d/floorplan-group-move.tsx +2 -3
  45. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1 -1
  46. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +1 -1
  47. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +1 -2
  48. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
  49. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
  50. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
  51. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +1 -2
  52. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +8 -10
  53. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +25 -33
  54. package/src/components/systems/roof/roof-edit-system.tsx +4 -3
  55. package/src/components/tools/distribution/distribution-run-tool.tsx +1 -1
  56. package/src/components/tools/item/placement-history.test.tsx +1 -1
  57. package/src/components/tools/item/use-placement-coordinator.tsx +2 -3
  58. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +6 -2
  59. package/src/components/tools/registry/move-registry-node-tool.tsx +1 -2
  60. package/src/components/tools/shared/cursor-sphere.tsx +1 -1
  61. package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
  62. package/src/components/tools/shared/placement-box.tsx +1 -1
  63. package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
  64. package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
  65. package/src/components/ui/action-menu/camera-actions.tsx +2 -2
  66. package/src/components/ui/action-menu/control-modes.tsx +1 -1
  67. package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
  68. package/src/components/ui/action-menu/index.tsx +3 -3
  69. package/src/components/ui/action-menu/measurement-control.tsx +3 -3
  70. package/src/components/ui/action-menu/placement.ts +0 -18
  71. package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
  72. package/src/components/ui/action-menu/view-toggles.tsx +5 -5
  73. package/src/components/ui/controls/finish-swatch.tsx +1 -1
  74. package/src/components/ui/controls/material-paint-panel.tsx +2 -2
  75. package/src/components/ui/controls/scene-material-list.tsx +2 -2
  76. package/src/components/ui/controls/select-control.tsx +1 -1
  77. package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
  78. package/src/components/ui/floating-level-selector.tsx +3 -3
  79. package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
  80. package/src/components/ui/helpers/helper-manager.test.tsx +1 -1
  81. package/src/components/ui/helpers/helper-manager.tsx +1 -1
  82. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  83. package/src/components/ui/node-icon-image.test.tsx +46 -0
  84. package/src/components/ui/node-icon-image.tsx +33 -1
  85. package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
  86. package/src/components/ui/panels/floor-foundation-panel.tsx +2 -2
  87. package/src/components/ui/panels/floor-opening-panel.tsx +4 -4
  88. package/src/components/ui/panels/node-display.ts +1 -1
  89. package/src/components/ui/panels/panel-manager.tsx +1 -1
  90. package/src/components/ui/panels/panel-wrapper.tsx +1 -1
  91. package/src/components/ui/panels/parametric-inspector.tsx +1 -1
  92. package/src/components/ui/panels/room-construction-rows.tsx +6 -6
  93. package/src/components/ui/panels/room-name-options.ts +1 -5
  94. package/src/components/ui/panels/room-panel.tsx +6 -8
  95. package/src/components/ui/primitives/color-dot.tsx +2 -2
  96. package/src/components/ui/primitives/opacity-control.tsx +2 -2
  97. package/src/components/ui/primitives/sidebar.tsx +3 -3
  98. package/src/components/ui/right-stack.tsx +1 -1
  99. package/src/components/ui/sidebar/icon-rail.tsx +1 -1
  100. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
  101. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  102. package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
  103. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
  104. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
  105. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +1 -1
  106. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  107. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
  108. package/src/components/ui/sidebar/panels/site-panel/index.tsx +2 -2
  109. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
  110. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  111. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
  112. package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
  113. package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
  114. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
  115. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
  116. package/src/components/ui/sidebar/tab-bar.tsx +1 -1
  117. package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +1 -1
  118. package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
  119. package/src/components/viewer-overlay.tsx +1 -2
  120. package/src/hooks/use-auto-frame.ts +1 -2
  121. package/src/hooks/use-keyboard.ts +1 -2
  122. package/src/hooks/use-selected-room.ts +5 -7
  123. package/src/i18n/floor-footprint-name.ts +1 -1
  124. package/src/i18n/locales/en/messages.po +180 -182
  125. package/src/i18n/locales/es/messages.po +180 -182
  126. package/src/i18n/locales/fr/messages.po +180 -182
  127. package/src/i18n/locales/ja/messages.po +180 -182
  128. package/src/i18n/locales/zh-CN/messages.po +180 -182
  129. package/src/i18n/locales.test.ts +1 -1
  130. package/src/index.tsx +109 -131
  131. package/src/lib/below-grade.test.tsx +4 -4
  132. package/src/lib/camera-facing.test.ts +1 -1
  133. package/src/lib/camera-facing.ts +2 -3
  134. package/src/lib/editor-level-display.ts +1 -1
  135. package/src/lib/floor-footprints.test.ts +2 -2
  136. package/src/lib/floor-opening-draft.ts +1 -1
  137. package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
  138. package/src/lib/floorplan/annotation-visibility.ts +1 -1
  139. package/src/lib/floorplan/floorplan-export.test.ts +1 -1
  140. package/src/lib/floorplan/floorplan-export.tsx +8 -11
  141. package/src/lib/floorplan/floorplan-extension.ts +4 -157
  142. package/src/lib/floorplan/floorplan-mode.ts +2 -1
  143. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
  144. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
  145. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
  146. package/src/lib/floorplan/geometry.ts +2 -112
  147. package/src/lib/floorplan/index.ts +0 -9
  148. package/src/lib/floorplan/items.ts +2 -1
  149. package/src/lib/floorplan/schedules.ts +6 -3
  150. package/src/lib/floorplan/sheet-export.ts +7 -3
  151. package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
  152. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
  153. package/src/lib/follow-pascal-presentation.ts +1 -1
  154. package/src/lib/glb-export.ts +1 -1
  155. package/src/lib/material-paint.ts +1 -1
  156. package/src/lib/measurements.test.ts +2 -1
  157. package/src/lib/mezzanine-selection.test.ts +1 -1
  158. package/src/lib/paint-region-mode.ts +1 -1
  159. package/src/lib/point-ask/session.ts +1 -2
  160. package/src/lib/roof-duplication.test.ts +100 -0
  161. package/src/lib/roof-duplication.ts +30 -5
  162. package/src/lib/room-handle-drag.ts +2 -12
  163. package/src/lib/room-name-catalog.test.ts +2 -1
  164. package/src/lib/room-name-messages.test.ts +2 -1
  165. package/src/lib/room-name-messages.ts +1 -118
  166. package/src/lib/room-name-storage.test.ts +2 -1
  167. package/src/lib/room-selection-commands.ts +2 -2
  168. package/src/lib/room-selection.test.ts +6 -6
  169. package/src/lib/room-transform-session.ts +1 -2
  170. package/src/lib/room-zone-routing.ts +2 -2
  171. package/src/lib/selection-routing.test.ts +0 -28
  172. package/src/lib/selection-routing.ts +1 -40
  173. package/src/lib/sfx-bus.ts +8 -32
  174. package/src/lib/sfx-player.test.ts +72 -1
  175. package/src/lib/sfx-player.ts +49 -337
  176. package/src/lib/viewer-selection.test.ts +38 -10
  177. package/src/lib/wall-pull.test.ts +1 -1
  178. package/src/lib/wall-pull.ts +1 -27
  179. package/src/store/use-editor.tsx +17 -26
  180. package/src/store/use-floorplan-annotation-visibility.ts +5 -5
  181. package/src/store/use-wall-region-handles-selection.ts +1 -2
  182. package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
  183. package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
  184. package/src/components/editor/first-person/build-collider-world.ts +0 -549
  185. package/src/components/editor/first-person/ground-holes.test.ts +0 -128
  186. package/src/components/editor/first-person/ground-holes.ts +0 -130
  187. package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
  188. package/src/components/editor/first-person/mechanism-targets.ts +0 -88
  189. package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
  190. package/src/components/editor/first-person/terrain-collider.ts +0 -212
  191. package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
  192. package/src/components/editor/floorplan-camera-sync.ts +0 -213
  193. package/src/components/editor/localized-html.tsx +0 -22
  194. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
  195. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
  196. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
  197. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
  198. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
  199. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
  200. package/src/components/editor-2d/svg-paths.ts +0 -124
  201. package/src/components/ui/action-menu/action-button.tsx +0 -89
  202. package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
  203. package/src/components/ui/primitives/button.tsx +0 -69
  204. package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
  205. package/src/components/ui/primitives/popover.tsx +0 -42
  206. package/src/components/ui/primitives/switch.tsx +0 -29
  207. package/src/components/ui/primitives/tooltip.tsx +0 -57
  208. package/src/components/ui/scene-loader.tsx +0 -73
  209. package/src/components/viewer/floorplan-compass-button.tsx +0 -67
  210. package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
  211. package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
  212. package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
  213. package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
  214. package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
  215. package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
  216. package/src/components/viewer/floorplan-preview.tsx +0 -1065
  217. package/src/components/viewer/render-settings-menu.tsx +0 -294
  218. package/src/components/viewer/sky-control.tsx +0 -710
  219. package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
  220. package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
  221. package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
  222. package/src/components/viewer/viewer-controls-bar.tsx +0 -496
  223. package/src/components/viewer/viewer-hover-label.tsx +0 -42
  224. package/src/components/viewer/viewer-rooms.tsx +0 -248
  225. package/src/components/viewer/viewer-scene-header.tsx +0 -286
  226. package/src/components/viewer/viewer-selection-manager.tsx +0 -124
  227. package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
  228. package/src/components/viewer/viewer-stage-modes.ts +0 -49
  229. package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
  230. package/src/components/viewer/viewer-stage.test.tsx +0 -47
  231. package/src/components/viewer/viewer-stage.tsx +0 -221
  232. package/src/components/walkthrough-hud.tsx +0 -193
  233. package/src/hooks/use-mobile.ts +0 -19
  234. package/src/i18n/level-name.ts +0 -39
  235. package/src/i18n/scene-theme-name.ts +0 -16
  236. package/src/lib/below-grade.ts +0 -133
  237. package/src/lib/camera-pose.test.ts +0 -237
  238. package/src/lib/camera-pose.ts +0 -172
  239. package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
  240. package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
  241. package/src/lib/floorplan/floorplan-readonly.ts +0 -95
  242. package/src/lib/floorplan/marks.test.ts +0 -213
  243. package/src/lib/floorplan/marks.ts +0 -238
  244. package/src/lib/measurements.ts +0 -8
  245. package/src/lib/node-display-label.ts +0 -37
  246. package/src/lib/room-assembly-overlay.test.ts +0 -275
  247. package/src/lib/room-assembly-overlay.ts +0 -265
  248. package/src/lib/room-selection.ts +0 -417
  249. package/src/lib/scene-bounds.test.ts +0 -327
  250. package/src/lib/scene-bounds.ts +0 -233
  251. package/src/lib/typing-target.ts +0 -9
  252. package/src/lib/viewer-selection.ts +0 -595
  253. package/src/lib/zone-content.ts +0 -133
  254. package/src/store/camera-pose-store.test.ts +0 -29
  255. package/src/store/camera-pose-store.ts +0 -27
  256. package/src/store/navigation-sync-pose-store.test.ts +0 -34
  257. package/src/store/navigation-sync-pose-store.ts +0 -27
  258. package/src/store/use-audio.test.ts +0 -146
  259. package/src/store/use-audio.tsx +0 -169
  260. package/src/store/use-first-person-hud.ts +0 -40
  261. package/src/store/use-follow-pascal.test.ts +0 -62
  262. package/src/store/use-follow-pascal.ts +0 -53
@@ -6,7 +6,7 @@ import { readFileSync } from 'node:fs'
6
6
  // draft instead, so it only has to stay clear of drei fat lines.
7
7
  for (const [file, drawsLines] of [
8
8
  ['./room-controls.tsx', false],
9
- ['./room-highlight.tsx', true],
9
+ ['../../../../viewer/src/ui/components/rooms/room-highlight.tsx', true],
10
10
  ['../../../../nodes/src/separator/renderer.tsx', true],
11
11
  ] as const) {
12
12
  test(`${file} uses WebGPU node materials instead of drei fat lines`, () => {
@@ -35,6 +35,11 @@ import {
35
35
  tintEmissive,
36
36
  useViewer,
37
37
  } from '@pascal-app/viewer'
38
+ import {
39
+ type SelectionModifierKeys,
40
+ sameRoom,
41
+ selectionModifiersFromEvent,
42
+ } from '@pascal-app/viewer/ui'
38
43
  import { useThree } from '@react-three/fiber'
39
44
  import { useCallback, useEffect, useRef } from 'react'
40
45
  import { type BufferGeometry, Color, type Material, type Mesh, type Object3D, Vector3 } from 'three'
@@ -105,7 +110,6 @@ import {
105
110
  usePaintOutline,
106
111
  } from '../../lib/plate-paint-affected'
107
112
  import { getHoveredRoofSegmentOutlineProxy } from '../../lib/roof-hover-outline-proxy'
108
- import { sameRoom } from '../../lib/room-selection'
109
113
  import { selectRoom, shouldInterceptRoom } from '../../lib/room-selection-commands'
110
114
  import { roomKeyForZone } from '../../lib/room-zone-routing'
111
115
  import {
@@ -114,8 +118,6 @@ import {
114
118
  resolveCanvasBuildingId,
115
119
  resolveCanvasSelectionNode,
116
120
  resolveSelectedIdsForNodeClick,
117
- type SelectionModifierKeys,
118
- selectionModifiersFromEvent,
119
121
  shouldPreserveSelectedRoofHostTarget,
120
122
  } from '../../lib/selection-routing'
121
123
  import { emitDeleteSFX, sfxEmitter } from '../../lib/sfx-bus'
@@ -8,13 +8,13 @@ import {
8
8
  useScene,
9
9
  } from '@pascal-app/core'
10
10
  import { getSceneTheme, useViewer } from '@pascal-app/viewer'
11
+ import { LocalizedHtml as Html } from '@pascal-app/viewer/ui'
11
12
  import { createPortal, useFrame, useThree } from '@react-three/fiber'
12
13
  import { useCallback, useMemo, useRef, useState } from 'react'
13
14
  import { type Camera, type Object3D, Vector3 } from 'three'
14
15
  import { groundHeightAt } from '../../lib/ground-surface'
15
16
  import { SITE_BOUNDARY_DRAG_LABEL } from '../../lib/site-boundary'
16
17
  import { useActiveHandleDrag } from '../../store/use-interaction-scope'
17
- import { Html } from './localized-html'
18
18
 
19
19
  type ViewportSize = {
20
20
  width: number
@@ -1,7 +1,8 @@
1
1
  'use client'
2
2
 
3
3
  import { emitter, type SnapshotSavedEvent } from '@pascal-app/core'
4
- import { SNAPSHOT_MAX_EDGE } from '@pascal-app/viewer'
4
+ import { isTypingTarget, SNAPSHOT_MAX_EDGE } from '@pascal-app/viewer'
5
+ import { useFirstPersonHud, useIsMobile, WalkthroughCrosshair } from '@pascal-app/viewer/ui'
5
6
  import {
6
7
  Check,
7
8
  Crop,
@@ -16,9 +17,7 @@ import {
16
17
  } from 'lucide-react'
17
18
  import { useCallback, useEffect, useRef, useState } from 'react'
18
19
  import { flushSync } from 'react-dom'
19
- import { useIsMobile } from '../../hooks/use-mobile'
20
20
  import { triggerSFX } from '../../lib/sfx-bus'
21
- import { isTypingTarget } from '../../lib/typing-target'
22
21
  import { requestWalkthroughPointerLock } from '../../lib/walkthrough-pointer-lock'
23
22
  import useEditor, {
24
23
  CAPTURE_FOV_MAX,
@@ -27,9 +26,7 @@ import useEditor, {
27
26
  type SnapshotCropMode,
28
27
  type SnapshotStandardAspect,
29
28
  } from '../../store/use-editor'
30
- import { useFirstPersonHud } from '../../store/use-first-person-hud'
31
29
  import { Slider } from '../ui/slider'
32
- import { WalkthroughCrosshair } from '../walkthrough-hud'
33
30
  import { CaptureLevelPicker } from './capture-level-picker'
34
31
  import { isOverlaySnapshotSave } from './snapshot-capture'
35
32
 
@@ -3,6 +3,7 @@
3
3
  import {
4
4
  emitter,
5
5
  type FenceNode,
6
+ getPlanPointDistance,
6
7
  isCurvedWall,
7
8
  nodeRegistry,
8
9
  type WallNode,
@@ -14,7 +15,7 @@ import {
14
15
  useSyncExternalStore,
15
16
  } from 'react'
16
17
  import { resolveCeilingPlanPointSnap } from '../../lib/ceiling-plan-snap'
17
- import { alignFloorplanDraftPoint, getPlanPointDistance } from '../../lib/floorplan'
18
+ import { alignFloorplanDraftPoint } from '../../lib/floorplan'
18
19
  import { resolveGenericFloorplanGridEventPoint } from '../../lib/floorplan-grid-event-point'
19
20
  import { snapRegisteredDraftPoint } from '../../lib/registered-draft-snap'
20
21
  import { resolveSlabPlanPointSnap } from '../../lib/slab-plan-snap'
@@ -1,6 +1,7 @@
1
1
  'use client'
2
2
 
3
3
  import { useScene } from '@pascal-app/core'
4
+ import { Button } from '@pascal-app/viewer/ui'
4
5
  import {
5
6
  Check,
6
7
  ChevronRight,
@@ -31,7 +32,6 @@ import { cn } from '../../../lib/utils'
31
32
  import useEditor from '../../../store/use-editor'
32
33
  import { IconRefGlyph } from '../../ui/icon-ref'
33
34
  import { Badge } from '../../ui/primitives/badge'
34
- import { Button } from '../../ui/primitives/button'
35
35
  import { PLUGINS_VIEW_ID } from './use-editor-views'
36
36
 
37
37
  const PLUGIN_AUTHORING_URL = 'https://editor.pascal.app/docs/developers/plugins'
@@ -2,14 +2,6 @@
2
2
 
3
3
  import { type MessageDescriptor, type PascalI18n, usePascalI18n } from '@pascal-app/core'
4
4
  import { type GroundMode, useViewer } from '@pascal-app/viewer'
5
- import { ArrowLeftRight, Check, Columns2, MoreHorizontal, Pin, PinOff, X } from 'lucide-react'
6
- import { type ReactNode, useEffect, useRef } from 'react'
7
- import { useIsMobile } from '../../../hooks/use-mobile'
8
- import { type EditorViewDescriptor, isSceneView, isViewPinned } from '../../../lib/editor-views'
9
- import { cn } from '../../../lib/utils'
10
- import useEditor from '../../../store/use-editor'
11
- import { VIEW_2D, VIEW_3D, type ViewPaneIndex } from '../../../store/view-layout'
12
- import { IconRefGlyph } from '../../ui/icon-ref'
13
5
  import {
14
6
  DropdownMenu,
15
7
  DropdownMenuContent,
@@ -17,7 +9,15 @@ import {
17
9
  DropdownMenuLabel,
18
10
  DropdownMenuSeparator,
19
11
  DropdownMenuTrigger,
20
- } from '../../ui/primitives/dropdown-menu'
12
+ useIsMobile,
13
+ } from '@pascal-app/viewer/ui'
14
+ import { ArrowLeftRight, Check, Columns2, MoreHorizontal, Pin, PinOff, X } from 'lucide-react'
15
+ import { type ReactNode, useEffect, useRef } from 'react'
16
+ import { type EditorViewDescriptor, isSceneView, isViewPinned } from '../../../lib/editor-views'
17
+ import { cn } from '../../../lib/utils'
18
+ import useEditor from '../../../store/use-editor'
19
+ import { VIEW_2D, VIEW_3D, type ViewPaneIndex } from '../../../store/view-layout'
20
+ import { IconRefGlyph } from '../../ui/icon-ref'
21
21
  import { PLUGINS_VIEW_ID, useActiveViewLayout, useEditorViews } from './use-editor-views'
22
22
 
23
23
  const GROUP = cn(
@@ -21,10 +21,10 @@ import {
21
21
  type WallNode,
22
22
  } from '@pascal-app/core'
23
23
  import { getSceneTheme, useViewer } from '@pascal-app/viewer'
24
+ import { LocalizedHtml as Html } from '@pascal-app/viewer/ui'
24
25
  import { createPortal, useFrame } from '@react-three/fiber'
25
26
  import { useMemo, useState } from 'react'
26
27
  import * as THREE from 'three'
27
- import { Html } from './localized-html'
28
28
 
29
29
  const GUIDE_Y_OFFSET = 0.08
30
30
  const LABEL_LIFT = 0.08
@@ -19,6 +19,7 @@ import {
19
19
  type WallNode,
20
20
  } from '@pascal-app/core'
21
21
  import { useViewer } from '@pascal-app/viewer'
22
+ import { LocalizedHtml as Html } from '@pascal-app/viewer/ui'
22
23
  import { createPortal, type ThreeEvent, useFrame, useThree } from '@react-three/fiber'
23
24
  import { useEffect, useMemo, useRef, useState } from 'react'
24
25
  import {
@@ -60,7 +61,6 @@ import useInteractionScope, {
60
61
  import { suppressBoxSelectForPointer } from '../tools/select/box-select-state'
61
62
  import { resolveResizeSnapValue } from './handles/resize-snap'
62
63
  import { type HandleDragControls, useHandleDrag } from './handles/use-handle-drag'
63
- import { Html } from './localized-html'
64
64
  import { MeasurementPill } from './measurement-pill'
65
65
  import {
66
66
  createArrowHitAreaGeometry,
@@ -1,13 +1,13 @@
1
1
  'use client'
2
2
 
3
- import { nodeRegistry, type WallNode } from '@pascal-app/core'
3
+ import { nodeRegistry, WALL_PULL_GRIP_TITLE, type WallNode, wallPullSeed } from '@pascal-app/core'
4
4
  import { type ThreeEvent, useThree } from '@react-three/fiber'
5
5
  import { useEffect, useMemo, useState } from 'react'
6
6
  import { Color, DoubleSide, ExtrudeGeometry, OrthographicCamera, Shape } from 'three'
7
7
  import { MeshBasicNodeMaterial } from 'three/webgpu'
8
8
  import { EDITOR_LAYER } from '../../lib/constants'
9
9
  import { sfxEmitter } from '../../lib/sfx-bus'
10
- import { startWallPull, WALL_PULL_GRIP_TITLE, wallPullSeed } from '../../lib/wall-pull'
10
+ import { startWallPull } from '../../lib/wall-pull'
11
11
  import { suppressBoxSelectForPointer } from '../tools/select/box-select-state'
12
12
  import {
13
13
  createEndpointHitAreaGeometry,
@@ -17,7 +17,8 @@ import {
17
17
  useLiveTransforms,
18
18
  useScene,
19
19
  } from '@pascal-app/core'
20
- import { useViewer } from '@pascal-app/viewer'
20
+ import { isTypingTarget, useViewer } from '@pascal-app/viewer'
21
+ import { FloorplanDimensionRenderer } from '@pascal-app/viewer/ui'
21
22
  import { memo, type PointerEvent as ReactPointerEvent, useEffect, useMemo, useState } from 'react'
22
23
  import { create } from 'zustand'
23
24
  import { GROUP_MOVE_DRAG_LABEL, GROUP_ROTATE_DRAG_LABEL } from '../../lib/contextual-help'
@@ -27,7 +28,6 @@ import { isHistoryShortcut } from '../../lib/history'
27
28
  import type { WallGroupPush } from '../../lib/room-handle-drag'
28
29
  import { useRoomHandleDrag } from '../../lib/room-handle-drag'
29
30
  import { sfxEmitter } from '../../lib/sfx-bus'
30
- import { isTypingTarget } from '../../lib/typing-target'
31
31
  import useAlignmentGuides from '../../store/use-alignment-guides'
32
32
  import useEditor, {
33
33
  isAlignmentGuideActive,
@@ -55,7 +55,6 @@ import {
55
55
  import { swallowNextClick } from '../editor/handles/use-handle-drag'
56
56
  import { useMeshSettleEpoch } from '../editor/use-mesh-settle-epoch'
57
57
  import { useFloorplanSceneRotation } from './floorplan-render-context'
58
- import { FloorplanDimensionRenderer } from './renderers/floorplan-dimension-renderer'
59
58
 
60
59
  // 2D sibling of the 3D body-drag group move (`group-move-3d.ts`): dragging
61
60
  // any selected element of a multi-selection slides the whole selection
@@ -33,6 +33,7 @@ import {
33
33
  measurementPolygonLabelAnchor,
34
34
  useViewer,
35
35
  } from '@pascal-app/viewer'
36
+ import { resolveFloorplanLabelAngle } from '@pascal-app/viewer/ui'
36
37
  import { useEffect, useMemo, useRef, useState } from 'react'
37
38
  import {
38
39
  clearSurfacePlanSnapFeedback,
@@ -48,7 +49,6 @@ import {
48
49
  } from '../../store/use-measurement-draft'
49
50
  import { FloorplanQuickMeasureLayer } from './floorplan-quick-measure-layer'
50
51
  import { useFloorplanRender } from './floorplan-render-context'
51
- import { resolveFloorplanLabelAngle } from './renderers/floorplan-label-angle'
52
52
 
53
53
  const DRAFT_COLOR = MEASUREMENT_ACTIVE_COLOR
54
54
  const X_AXIS_COLOR = '#ef4444'
@@ -2,6 +2,7 @@
2
2
 
3
3
  import type { AnyNodeId, OpenWallEnd } from '@pascal-app/core'
4
4
  import { MEASUREMENT_DANGLING_COLOR, useViewer } from '@pascal-app/viewer'
5
+ import { resolveFloorplanLabelAngle } from '@pascal-app/viewer/ui'
5
6
  import { memo, useEffect, useState } from 'react'
6
7
  import { createPortal } from 'react-dom'
7
8
  import {
@@ -15,7 +16,6 @@ import { isViewVisible, VIEW_2D } from '../../store/view-layout'
15
16
  import { JoinWallsPill } from '../editor/join-walls-pill'
16
17
  import { OpenWallEndsHint } from '../editor/open-wall-ends-hint'
17
18
  import { useFloorplanRender } from './floorplan-render-context'
18
- import { resolveFloorplanLabelAngle } from './renderers/floorplan-label-angle'
19
19
 
20
20
  function sceneScreenPoint(point: [number, number]): { left: number; top: number } | null {
21
21
  const scene = document.querySelector<SVGGElement>('[data-floorplan-scene]')
@@ -26,7 +26,7 @@ import {
26
26
  useScene,
27
27
  } from '@pascal-app/core'
28
28
  import { nodeLevelFrame } from '@pascal-app/core/procedural-items'
29
- import { useViewer } from '@pascal-app/viewer'
29
+ import { isTypingTarget, useViewer } from '@pascal-app/viewer'
30
30
  import { useEffect, useMemo } from 'react'
31
31
  import { commitFreshPlacementSubtree } from '../../lib/fresh-planar-placement'
32
32
  import { isHistoryShortcut } from '../../lib/history'
@@ -39,7 +39,6 @@ import {
39
39
  import { movementSfxStepKey } from '../../lib/sfx/movement-tick'
40
40
  import { sfxEmitter } from '../../lib/sfx-bus'
41
41
  import { surfaceAttachmentId } from '../../lib/surface-attachment'
42
- import { isTypingTarget } from '../../lib/typing-target'
43
42
  import { resolveAlignmentForFloorplanView } from '../../lib/world-grid-snap'
44
43
  import useAlignmentGuides from '../../store/use-alignment-guides'
45
44
  import useEditor, {
@@ -1,47 +1,10 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
- import { floorplanGeometryMetadata } from '../../../lib/floorplan/floorplan-extension'
3
2
  import {
4
- floorplanAnnotationObstacleMode,
5
3
  polylineObstacleRectangles,
6
4
  resolveAnnotationLabelRectangles,
7
5
  resolveSvgAnnotationCollisions,
8
6
  } from './floorplan-annotation-layout'
9
7
 
10
- describe('floorplanAnnotationObstacleMode', () => {
11
- test('treats fixed annotation categories as layout obstacles', () => {
12
- expect(
13
- floorplanAnnotationObstacleMode({
14
- kind: 'text',
15
- x: 0,
16
- y: 0,
17
- text: 'BEDROOM',
18
- fontSize: 0.18,
19
- metadata: floorplanGeometryMetadata({ annotationRole: 'room-label' }),
20
- }),
21
- ).toBe('bounds')
22
- expect(
23
- floorplanAnnotationObstacleMode({
24
- kind: 'line',
25
- x1: 0,
26
- y1: 0,
27
- x2: 1,
28
- y2: 0,
29
- metadata: floorplanGeometryMetadata({ annotationRole: 'column-center' }),
30
- }),
31
- ).toBe('bounds')
32
- expect(
33
- floorplanAnnotationObstacleMode({
34
- kind: 'polyline',
35
- points: [
36
- [0, 0],
37
- [1, 0],
38
- ],
39
- metadata: floorplanGeometryMetadata({ annotationRole: 'stair-annotation' }),
40
- }),
41
- ).toBe('outline')
42
- })
43
- })
44
-
45
8
  describe('resolveAnnotationLabelRectangles', () => {
46
9
  test('keeps the higher-priority label and moves the conflicting label', () => {
47
10
  const shifts = resolveAnnotationLabelRectangles([
@@ -1,6 +1,3 @@
1
- import type { FloorplanGeometry } from '@pascal-app/core'
2
- import { readFloorplanGeometryMetadata } from '../../../lib/floorplan/floorplan-extension'
3
-
4
1
  export type AnnotationLabelRectangle = {
5
2
  id: string
6
3
  x: number
@@ -467,33 +464,6 @@ function candidateCost(
467
464
  return preference + distance + perpendicularMovement * 4
468
465
  }
469
466
 
470
- export function isFloorplanAnnotationObstacleGeometry(geometry: FloorplanGeometry): boolean {
471
- if (floorplanAnnotationObstacleMode(geometry)) return true
472
- if (geometry.kind !== 'group') return false
473
- const hasPlate = geometry.children.some(
474
- (child) => child.kind === 'rect' || child.kind === 'circle',
475
- )
476
- const hasUprightText = geometry.children.some((child) => child.kind === 'text' && child.upright)
477
- return hasPlate && hasUprightText
478
- }
479
-
480
- export function floorplanAnnotationObstacleMode(
481
- geometry: FloorplanGeometry,
482
- ): 'bounds' | 'outline' | '' | undefined {
483
- const metadata = readFloorplanGeometryMetadata(geometry)
484
- if (metadata.annotationObstacle) return metadata.annotationObstacle
485
- switch (metadata.annotationRole) {
486
- case 'room-label':
487
- return geometry.kind === 'text' ? 'bounds' : undefined
488
- case 'column-center':
489
- return geometry.kind === 'line' || geometry.kind === 'text' ? 'bounds' : undefined
490
- case 'stair-annotation':
491
- return geometry.kind === 'polyline' || geometry.kind === 'line' ? 'outline' : 'bounds'
492
- default:
493
- return undefined
494
- }
495
- }
496
-
497
467
  function rectanglesOverlap(
498
468
  left: Pick<AnnotationLabelRectangle, 'x' | 'y' | 'width' | 'height'>,
499
469
  right: Pick<AnnotationLabelRectangle, 'x' | 'y' | 'width' | 'height'>,
@@ -3,7 +3,8 @@
3
3
  import type { AnyNode, AnyNodeId } from '@pascal-app/core'
4
4
  import { useLocale, useScene } from '@pascal-app/core'
5
5
  import { useViewer } from '@pascal-app/viewer'
6
- import { useCallback, useEffect, useRef, useState } from 'react'
6
+ import { FloorplanDimensionHitsProvider } from '@pascal-app/viewer/ui'
7
+ import { type ReactNode, useCallback, useEffect, useRef, useState } from 'react'
7
8
  import { createPortal } from 'react-dom'
8
9
  import {
9
10
  parseDimensionInput,
@@ -26,8 +27,8 @@ import useEditor from '../../../store/use-editor'
26
27
  * anchor the value is written as `textOverride` on a construction-dimension
27
28
  * node instead, and the label renders an "override" badge.
28
29
  *
29
- * The label is found by DOM delegation on the attributes
30
- * `floorplan-dimension-renderer.tsx` emits, so this works identically for
30
+ * The label is found by DOM delegation on the attributes the viewer's
31
+ * dimension renderer emits under `FloorplanDimensionHitsGate`, so this works identically for
31
32
  * `dimension` and `dimension-string` geometry, for automatic wall dimensions,
32
33
  * contextual dimensions and manual construction-dimension nodes — and on
33
34
  * sheets, which mount the same renderer.
@@ -62,6 +63,15 @@ export function useDimensionEditAllowed(): boolean {
62
63
  return useEditor((state) => isDimensionEditAllowed(state, { readOnly }))
63
64
  }
64
65
 
66
+ /** Plan dimension labels under the editor carry their typeable hit rects while typing is allowed. */
67
+ export function FloorplanDimensionHitsGate({ children }: { children: ReactNode }) {
68
+ return (
69
+ <FloorplanDimensionHitsProvider value={useDimensionEditAllowed()}>
70
+ {children}
71
+ </FloorplanDimensionHitsProvider>
72
+ )
73
+ }
74
+
65
75
  /**
66
76
  * The typeable dimension value under a press, with the node typing it drives:
67
77
  * the pressed element's or, when the plan's dashed group box lies over it, the
@@ -10,12 +10,11 @@ import {
10
10
  useScene,
11
11
  } from '@pascal-app/core'
12
12
  import { useViewer } from '@pascal-app/viewer'
13
+ import { FloorplanDimensionRenderer, FloorplanGeometryRenderer } from '@pascal-app/viewer/ui'
13
14
  import { memo, useMemo } from 'react'
14
15
  import usePlacementPreview from '../../../store/use-placement-preview'
15
16
  import { usePlacementTyping } from '../../../store/use-placement-typing'
16
17
  import { useFloorplanRender, useFloorplanSceneRotation } from '../floorplan-render-context'
17
- import { FloorplanDimensionRenderer } from './floorplan-dimension-renderer'
18
- import { FloorplanGeometryRenderer } from './floorplan-geometry-renderer'
19
18
  import { FloorplanPlacementTypingHud } from './floorplan-placement-typing-hud'
20
19
 
21
20
  export interface FloorplanNodePreviewProps {
@@ -7,15 +7,17 @@ import type {
7
7
  FloorplanPalette,
8
8
  LiveNodeOverrides,
9
9
  } from '@pascal-app/core'
10
- import { type AnyNodeDefinition, emitter, nodeRegistry, registerNode } from '@pascal-app/core'
10
+ import {
11
+ type AnyNodeDefinition,
12
+ emitter,
13
+ floorplanGeometryMetadata,
14
+ nodeRegistry,
15
+ registerNode,
16
+ } from '@pascal-app/core'
11
17
  import { createElement } from 'react'
12
18
  import { renderToStaticMarkup } from 'react-dom/server'
13
19
  import { z } from 'zod'
14
20
  import { AXIS_MOVE_DRAG_LABEL, PATH_POINT_DRAG_LABEL } from '../../../lib/contextual-help'
15
- import {
16
- FLOORPLAN_NODE_EXTENSION_KEY,
17
- floorplanGeometryMetadata,
18
- } from '../../../lib/floorplan/floorplan-extension'
19
21
  import type { SessionWrites } from '../../../lib/session-writes'
20
22
  import { snapContextOf } from '../../../lib/snapping-mode'
21
23
  import {
@@ -776,11 +778,7 @@ describe('collectFloorplanLinkedLevelNodes', () => {
776
778
  category: 'structure',
777
779
  defaults: () => ({}) as never,
778
780
  floorplan: () => null,
779
- extensions: {
780
- [FLOORPLAN_NODE_EXTENSION_KEY]: {
781
- linkedLevelIds: () => ['level_upper' as AnyNodeId],
782
- },
783
- },
781
+ floorplanLinkedLevelIds: () => ['level_upper' as AnyNodeId],
784
782
  } as unknown as AnyNodeDefinition)
785
783
  const child = {
786
784
  id: 'linked_child',
@@ -4,15 +4,22 @@ import {
4
4
  type AnyNode,
5
5
  type AnyNodeDefinition,
6
6
  type AnyNodeId,
7
+ buildFloorplanContext,
8
+ createFloorplanContextExtensions,
7
9
  createSceneApi,
8
10
  emitter,
9
11
  type FloorplanAffordanceSession,
12
+ type FloorplanAnnotationRole,
10
13
  type FloorplanGeometry,
11
14
  type FloorplanPalette,
12
15
  type FloorplanPoint,
13
16
  type FloorplanScope,
17
+ type FloorplanWallDimensionFaces,
18
+ floorplanAnnotationObstacleMode,
19
+ floorplanLayerRank,
14
20
  type GeometryContext,
15
21
  hidesDescendants,
22
+ isFloorplanAnnotationObstacleGeometry,
16
23
  isNodeKindEnabled,
17
24
  isRegistryMovable,
18
25
  kindsWithFloorplanScope,
@@ -20,6 +27,7 @@ import {
20
27
  type LiveTransform,
21
28
  nodeRegistry,
22
29
  pauseSceneHistory,
30
+ readFloorplanGeometryMetadata,
23
31
  resolveBuildingForLevel,
24
32
  resolveSelectionProxyId,
25
33
  resumeSceneHistory,
@@ -28,6 +36,10 @@ import {
28
36
  useLiveNodeOverrides,
29
37
  useLiveTransforms,
30
38
  useScene,
39
+ WALL_PULL_AFFORDANCE,
40
+ WALL_PUSH_AFFORDANCE,
41
+ type WallPullGripPayload,
42
+ withFloorplanGeometryMetadata,
31
43
  } from '@pascal-app/core'
32
44
  import {
33
45
  beginPerfAction,
@@ -37,6 +49,14 @@ import {
37
49
  useRevealWaiting,
38
50
  useViewer,
39
51
  } from '@pascal-app/viewer'
52
+ import {
53
+ FloorplanDimensionRenderer,
54
+ FloorplanGeometryRenderer,
55
+ resolveFloorplanAnnotationUpdate,
56
+ resolveFloorplanLabelAngle,
57
+ selectionModifiersFromEvent,
58
+ updateSvgFloorplanLabelOrientations,
59
+ } from '@pascal-app/viewer/ui'
40
60
  import {
41
61
  type ComponentProps,
42
62
  memo,
@@ -55,7 +75,6 @@ import {
55
75
  hoverRoomFromHit,
56
76
  resolvePlanRoomHit,
57
77
  roomPickingEnabled,
58
- selectionModifiersFromEvent,
59
78
  useRoomRecords,
60
79
  } from '../../../hooks/use-selected-room'
61
80
  import { useCeilingEditSession } from '../../../lib/ceiling-edit-session'
@@ -79,22 +98,11 @@ import {
79
98
  filterFloorplanAnnotationGeometry,
80
99
  } from '../../../lib/floorplan/annotation-visibility'
81
100
  import { resolveNodeForDrawingType } from '../../../lib/floorplan/drawing-coordination'
82
- import {
83
- createFloorplanContextExtensions,
84
- type FloorplanAnnotationRole,
85
- type FloorplanWallDimensionFaces,
86
- getFloorplanNodeExtension,
87
- readFloorplanGeometryMetadata,
88
- withFloorplanGeometryMetadata,
89
- } from '../../../lib/floorplan/floorplan-extension'
101
+ import { getFloorplanNodeExtension } from '../../../lib/floorplan/floorplan-extension'
90
102
  import {
91
103
  type FloorplanMode,
92
104
  resolveFloorplanAnnotationVisibility,
93
105
  } from '../../../lib/floorplan/floorplan-mode'
94
- import {
95
- buildFloorplanContext,
96
- floorplanLayerRank,
97
- } from '../../../lib/floorplan/floorplan-readonly'
98
106
  import { clientToPlan } from '../../../lib/floorplan/plan-coords'
99
107
  import {
100
108
  type ActiveInteractionScope,
@@ -106,7 +114,7 @@ import {
106
114
  isIdle,
107
115
  tangentReshapeScope,
108
116
  } from '../../../lib/interaction/scope'
109
- import { runFloorplanWallPush, WALL_PUSH_AFFORDANCE } from '../../../lib/room-handle-drag'
117
+ import { runFloorplanWallPush } from '../../../lib/room-handle-drag'
110
118
  import { selectRoom, selectRoomFromHit } from '../../../lib/room-selection-commands'
111
119
  import { clickZoneArea, hoverZoneArea } from '../../../lib/room-zone-routing'
112
120
  import {
@@ -118,11 +126,7 @@ import { createSessionWrites, type SessionWrites } from '../../../lib/session-wr
118
126
  import { sfxEmitter } from '../../../lib/sfx-bus'
119
127
  import { clearSurfacePlanSnapFeedback } from '../../../lib/surface-plan-snap'
120
128
  import { paintZoneMembership } from '../../../lib/units'
121
- import {
122
- startWallPull,
123
- WALL_PULL_AFFORDANCE,
124
- type WallPullGripPayload,
125
- } from '../../../lib/wall-pull'
129
+ import { startWallPull } from '../../../lib/wall-pull'
126
130
  import useDirectManipulationFeedback from '../../../store/use-direct-manipulation-feedback'
127
131
  import useDrawingView from '../../../store/use-drawing-view'
128
132
  import useEditor, { isAngleSnapActive, type Mode } from '../../../store/use-editor'
@@ -157,23 +161,11 @@ import {
157
161
  useFloorplanStaticRender,
158
162
  useFloorplanStaticUnitsPerPixel,
159
163
  } from '../floorplan-render-context'
160
- import {
161
- floorplanAnnotationObstacleMode,
162
- isFloorplanAnnotationObstacleGeometry,
163
- resolveSvgAnnotationCollisions,
164
- svgAnnotationLabelId,
165
- } from './floorplan-annotation-layout'
164
+ import { resolveSvgAnnotationCollisions, svgAnnotationLabelId } from './floorplan-annotation-layout'
166
165
  import {
167
166
  FloorplanDimensionEditOverlay,
168
167
  typeableDimensionAt,
169
168
  } from './floorplan-dimension-edit-overlay'
170
- import { FloorplanDimensionRenderer } from './floorplan-dimension-renderer'
171
- import { FloorplanGeometryRenderer } from './floorplan-geometry-renderer'
172
- import {
173
- resolveFloorplanAnnotationUpdate,
174
- resolveFloorplanLabelAngle,
175
- updateSvgFloorplanLabelOrientations,
176
- } from './floorplan-label-angle'
177
169
  import { useFloorplanReveal } from './floorplan-reveal'
178
170
 
179
171
  /**
@@ -3645,7 +3637,7 @@ export function collectFloorplanLinkedLevelNodes(
3645
3637
  for (const [rawId, node] of Object.entries(nodes)) {
3646
3638
  if (!node) continue
3647
3639
  const definition = nodeRegistry.get(node.type)
3648
- const linkedLevelIds = getFloorplanNodeExtension(definition)?.linkedLevelIds
3640
+ const linkedLevelIds = definition?.floorplanLinkedLevelIds
3649
3641
  if (!definition?.floorplan || !linkedLevelIds) continue
3650
3642
  const id = rawId as AnyNodeId
3651
3643
  if (excludedIds.has(id)) continue
@@ -22,6 +22,7 @@ import {
22
22
  csgEvaluator,
23
23
  generateRoofSegmentGeometry,
24
24
  INTERSECTION,
25
+ isTypingTarget,
25
26
  markPureRaycast,
26
27
  prepareBrushForCSG,
27
28
  useViewer,
@@ -34,7 +35,6 @@ import { LineBasicNodeMaterial, MeshBasicNodeMaterial } from 'three/webgpu'
34
35
  import { EDITOR_LAYER } from '../../../lib/constants'
35
36
  import { isHistoryShortcut } from '../../../lib/history'
36
37
  import { getHoveredRoofSegmentOutlineProxyName } from '../../../lib/roof-hover-outline-proxy'
37
- import { isTypingTarget } from '../../../lib/typing-target'
38
38
  import useInteractionScope, { useMovingNode } from '../../../store/use-interaction-scope'
39
39
  import { swallowNextClick } from '../../editor/handles/use-handle-drag'
40
40
 
@@ -1863,10 +1863,11 @@ export const RoofEditSystem = () => {
1863
1863
  const wasReveal = prevRevealRoofIds.current.has(roofId)
1864
1864
  if (isActive !== wasActive || isMoving !== wasMoving) {
1865
1865
  // Entering or exiting edit and move modes rebuilds the merged shell
1866
- // from the current segment values.
1866
+ // from the current segment values (its faces of other kinds are no part of it).
1867
1867
  const { markDirty } = useScene.getState()
1868
1868
  for (const childId of roofNode.children) {
1869
- markDirty(childId as AnyNodeId)
1869
+ if (nodes[childId as AnyNodeId]?.type === 'roof-segment')
1870
+ markDirty(childId as AnyNodeId)
1870
1871
  }
1871
1872
  }
1872
1873
  // Entering reveal mode (and NOT also full-edit, which already
@@ -26,12 +26,12 @@ import {
26
26
  useEditor,
27
27
  useInteractionScope,
28
28
  } from '@pascal-app/editor'
29
+ import { LocalizedHtml as Html } from '@pascal-app/viewer/ui'
29
30
  import { useThree } from '@react-three/fiber'
30
31
  import { type RefObject, useCallback, useEffect, useRef, useState } from 'react'
31
32
  import { createPortal } from 'react-dom'
32
33
  import { type Group, Vector3 } from 'three'
33
34
  import { messageWithSlot } from '../../../i18n/message-slot'
34
- import { Html } from '../../editor/localized-html'
35
35
  import type { RunSurfaceBounds, RunSurfaceTarget } from './distribution-run-contract'
36
36
  import { clearDrawAlignment } from './draw-alignment'
37
37
  import type { RunBodyHit, ScenePort } from './ports'
@@ -22,12 +22,12 @@ import {
22
22
  WallNode,
23
23
  } from '@pascal-app/core'
24
24
  import { useViewer } from '@pascal-app/viewer'
25
+ import { LocalizedHtml as Html } from '@pascal-app/viewer/ui'
25
26
  import { act, create } from '@react-three/test-renderer'
26
27
  import { Children, Component, cloneElement, isValidElement, type ReactNode } from 'react'
27
28
  import { Group } from 'three'
28
29
  import useEditor from '../../../store/use-editor'
29
30
  import useInteractionScope from '../../../store/use-interaction-scope'
30
- import { Html } from '../../editor/localized-html'
31
31
  import { useDraftNode } from './use-draft-node'
32
32
  import { usePlacementCoordinator } from './use-placement-coordinator'
33
33