@pascal-app/editor 1.0.7 → 1.1.1

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 (336) 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 +101 -45
  5. package/src/components/editor/duplicate-node.ts +2 -1
  6. package/src/components/editor/editor-layout-v2.tsx +1 -1
  7. package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
  8. package/src/components/editor/first-person-controls.tsx +20 -1983
  9. package/src/components/editor/fit-scene-framing.test.ts +318 -0
  10. package/src/components/editor/fit-scene-framing.ts +142 -0
  11. package/src/components/editor/floating-action-menu.tsx +5 -3
  12. package/src/components/editor/floating-building-action-menu.tsx +1 -1
  13. package/src/components/editor/floor-openings-overlay.tsx +1 -1
  14. package/src/components/editor/floor-region-controls.tsx +8 -4
  15. package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
  16. package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
  17. package/src/components/editor/floorplan-panel.tsx +199 -30
  18. package/src/components/editor/floorplan-wall-typing-keys.test.tsx +152 -0
  19. package/src/components/editor/floorplan-wall-typing-keys.ts +79 -0
  20. package/src/components/editor/follow-pascal.test.tsx +1 -2
  21. package/src/components/editor/follow-pascal.tsx +1 -1
  22. package/src/components/editor/footprint-height-handle.tsx +2 -2
  23. package/src/components/editor/group-actions.ts +1 -2
  24. package/src/components/editor/group-floating-action-menu.tsx +1 -1
  25. package/src/components/editor/group-move-3d.ts +1 -2
  26. package/src/components/editor/group-rotate-handle.tsx +1 -2
  27. package/src/components/editor/group-transform-shared.ts +3 -1
  28. package/src/components/editor/handles/use-handle-drag.ts +1 -2
  29. package/src/components/editor/index.tsx +43 -13
  30. package/src/components/editor/inspector-extension-actions.tsx +1 -1
  31. package/src/components/editor/measurement-pill.tsx +1 -1
  32. package/src/components/editor/node-arrow-handles.tsx +2 -2
  33. package/src/components/editor/open-wall-ends-3d-layer.tsx +2 -3
  34. package/src/components/editor/open-wall-ends-hint.tsx +1 -1
  35. package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
  36. package/src/components/editor/quick-measurement-card.tsx +1 -1
  37. package/src/components/editor/room-controls.tsx +10 -6
  38. package/src/components/editor/room-handles-2d.tsx +3 -3
  39. package/src/components/editor/room-handles.tsx +4 -5
  40. package/src/components/editor/room-highlight.tsx +6 -105
  41. package/src/components/editor/room-labels.test.ts +8 -822
  42. package/src/components/editor/room-labels.tsx +41 -1670
  43. package/src/components/editor/room-webgpu-materials.test.ts +1 -1
  44. package/src/components/editor/selection-manager.tsx +5 -3
  45. package/src/components/editor/site-edge-labels.tsx +7 -3
  46. package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
  47. package/src/components/editor/use-floorplan-background-placement.ts +2 -1
  48. package/src/components/editor/views/plugins-view.tsx +1 -1
  49. package/src/components/editor/views/view-bar.tsx +9 -9
  50. package/src/components/editor/wall-measurement-label.tsx +31 -15
  51. package/src/components/editor/wall-move-side-handles.tsx +11 -7
  52. package/src/components/editor/wall-pull-grip.tsx +2 -2
  53. package/src/components/editor/wall-region-handles.tsx +2 -2
  54. package/src/components/editor/wall-snap-beacon-layer.tsx +53 -32
  55. package/src/components/editor-2d/floorplan-group-move.tsx +3 -4
  56. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +13 -13
  57. package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +2 -3
  58. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +2 -1
  59. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +23 -6
  60. package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
  61. package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
  62. package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
  63. package/src/components/editor-2d/renderers/floorplan-draft-measurement.tsx +7 -1
  64. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +14 -3
  65. package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.test.tsx +35 -0
  66. package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.tsx +65 -0
  67. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +30 -10
  68. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +39 -35
  69. package/src/components/systems/roof/roof-edit-system.test.tsx +15 -1
  70. package/src/components/systems/roof/roof-edit-system.tsx +33 -21
  71. package/src/components/tools/distribution/distribution-run-tool.test.tsx +371 -3
  72. package/src/components/tools/distribution/distribution-run-tool.tsx +151 -33
  73. package/src/components/tools/item/move-tool.tsx +1 -6
  74. package/src/components/tools/item/placement-history.test.tsx +1 -1
  75. package/src/components/tools/item/use-placement-coordinator.tsx +3 -4
  76. package/src/components/tools/paint-region/wall-paint-region-tool.tsx +7 -3
  77. package/src/components/tools/registry/move-registry-node-tool.test.ts +42 -1
  78. package/src/components/tools/registry/move-registry-node-tool.tsx +39 -16
  79. package/src/components/tools/shared/cursor-sphere.tsx +1 -1
  80. package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
  81. package/src/components/tools/shared/placement-box.tsx +2 -6
  82. package/src/components/tools/shared/placement-coordinate-input.tsx +94 -0
  83. package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
  84. package/src/components/tools/shared/segment-angle.ts +0 -4
  85. package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
  86. package/src/components/tools/tool-manager.tsx +1 -24
  87. package/src/components/tools/wall/wall-typed-entry.test.ts +99 -0
  88. package/src/components/tools/wall/wall-typed-entry.ts +70 -0
  89. package/src/components/ui/action-menu/camera-actions.tsx +2 -2
  90. package/src/components/ui/action-menu/control-modes.tsx +1 -1
  91. package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
  92. package/src/components/ui/action-menu/index.tsx +3 -3
  93. package/src/components/ui/action-menu/measurement-control.tsx +3 -3
  94. package/src/components/ui/action-menu/placement.ts +0 -18
  95. package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
  96. package/src/components/ui/action-menu/view-toggles.tsx +5 -5
  97. package/src/components/ui/controls/finish-swatch.tsx +1 -1
  98. package/src/components/ui/controls/material-paint-panel.tsx +2 -2
  99. package/src/components/ui/controls/scene-material-list.tsx +2 -2
  100. package/src/components/ui/controls/select-control.tsx +1 -1
  101. package/src/components/ui/controls/slider-control.tsx +18 -6
  102. package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
  103. package/src/components/ui/controls/tool-options-panel.tsx +74 -44
  104. package/src/components/ui/floating-level-selector.tsx +3 -3
  105. package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
  106. package/src/components/ui/helpers/helper-manager.test.tsx +54 -1
  107. package/src/components/ui/helpers/helper-manager.tsx +55 -1
  108. package/src/components/ui/level-duplicate-dialog.tsx +1 -1
  109. package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
  110. package/src/components/ui/panels/floor-foundation-panel.tsx +3 -3
  111. package/src/components/ui/panels/floor-opening-panel.tsx +5 -5
  112. package/src/components/ui/panels/mobile-selection-bar.tsx +28 -24
  113. package/src/components/ui/panels/multi-height-mode.tsx +3 -3
  114. package/src/components/ui/panels/multi-selection-panel.tsx +1 -1
  115. package/src/components/ui/panels/node-display.ts +1 -1
  116. package/src/components/ui/panels/panel-manager.tsx +5 -3
  117. package/src/components/ui/panels/panel-wrapper.tsx +42 -19
  118. package/src/components/ui/panels/parametric-inspector.tsx +1 -1
  119. package/src/components/ui/panels/room-construction-rows.tsx +7 -7
  120. package/src/components/ui/panels/room-name-options.ts +1 -5
  121. package/src/components/ui/panels/room-openings-field.tsx +1 -1
  122. package/src/components/ui/panels/room-panel.tsx +7 -9
  123. package/src/components/ui/primitives/color-dot.tsx +2 -2
  124. package/src/components/ui/primitives/opacity-control.tsx +2 -2
  125. package/src/components/ui/primitives/sidebar.tsx +3 -3
  126. package/src/components/ui/right-stack.test.ts +13 -6
  127. package/src/components/ui/right-stack.tsx +22 -11
  128. package/src/components/ui/sidebar/icon-rail.tsx +1 -1
  129. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
  130. package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
  131. package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
  132. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
  133. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
  134. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +2 -6
  135. package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
  136. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
  137. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +1 -1
  138. package/src/components/ui/sidebar/panels/site-panel/index.tsx +3 -10
  139. package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
  140. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
  141. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
  142. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +1 -1
  143. package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
  144. package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
  145. package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
  146. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +1 -1
  147. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
  148. package/src/components/ui/sidebar/tab-bar.tsx +1 -1
  149. package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +2 -2
  150. package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
  151. package/src/components/viewer-overlay.tsx +1 -2
  152. package/src/hooks/use-auto-frame.ts +1 -2
  153. package/src/hooks/use-keyboard.ts +1 -2
  154. package/src/hooks/use-selected-room.ts +5 -7
  155. package/src/i18n/floor-footprint-name.ts +1 -1
  156. package/src/i18n/locales/en/messages.po +1036 -306
  157. package/src/i18n/locales/en/messages.ts +1 -1
  158. package/src/i18n/locales/en-XA/messages.ts +1 -1
  159. package/src/i18n/locales/es/messages.po +2267 -439
  160. package/src/i18n/locales/fr/messages.po +2267 -439
  161. package/src/i18n/locales/ja/messages.po +2267 -439
  162. package/src/i18n/locales/zh-CN/messages.po +2267 -439
  163. package/src/i18n/locales.test.ts +1 -1
  164. package/src/index.tsx +183 -178
  165. package/src/lib/below-grade.test.tsx +4 -4
  166. package/src/lib/camera-facing.test.ts +1 -1
  167. package/src/lib/camera-facing.ts +2 -3
  168. package/src/lib/contextual-help.ts +6 -0
  169. package/src/lib/editor-level-display.ts +1 -1
  170. package/src/lib/elevation-guides.ts +21 -6
  171. package/src/lib/elevator-support.ts +1 -72
  172. package/src/lib/floor-footprints.test.ts +3 -3
  173. package/src/lib/floor-footprints.ts +1 -9
  174. package/src/lib/floor-foundation-support.test.ts +8 -3
  175. package/src/lib/floor-opening-draft.ts +2 -2
  176. package/src/lib/floor-region-session.ts +1 -1
  177. package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
  178. package/src/lib/floorplan/annotation-visibility.ts +1 -1
  179. package/src/lib/floorplan/floorplan-export.test.ts +1 -1
  180. package/src/lib/floorplan/floorplan-export.tsx +8 -11
  181. package/src/lib/floorplan/floorplan-extension.ts +4 -157
  182. package/src/lib/floorplan/floorplan-mode.ts +2 -1
  183. package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
  184. package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
  185. package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
  186. package/src/lib/floorplan/geometry.ts +2 -112
  187. package/src/lib/floorplan/index.ts +0 -9
  188. package/src/lib/floorplan/items.ts +2 -1
  189. package/src/lib/floorplan/open-wall-ends.ts +2 -1
  190. package/src/lib/floorplan/schedules.ts +6 -3
  191. package/src/lib/floorplan/sheet-export.ts +7 -3
  192. package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
  193. package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
  194. package/src/lib/follow-pascal-presentation.ts +1 -1
  195. package/src/lib/gesture-lifecycle.ts +3 -1
  196. package/src/lib/glb-export.ts +1 -1
  197. package/src/lib/interaction/scope.ts +1 -0
  198. package/src/lib/layer-thickness.ts +1 -1
  199. package/src/lib/level-selection.test.ts +18 -2
  200. package/src/lib/level-selection.ts +31 -8
  201. package/src/lib/linear-display.ts +1 -1
  202. package/src/lib/live-gesture-round-trip.test.ts +1 -1
  203. package/src/lib/material-paint.ts +1 -1
  204. package/src/lib/measurement-label.test.ts +1 -1
  205. package/src/lib/measurements.test.ts +7 -5
  206. package/src/lib/mezzanine-selection.test.ts +1 -1
  207. package/src/lib/node-action-movement.test.tsx +115 -0
  208. package/src/lib/node-action-movement.ts +2 -0
  209. package/src/lib/paint-region-mode.ts +1 -1
  210. package/src/lib/placement-metadata.ts +4 -0
  211. package/src/lib/point-ask/describe-target.ts +6 -8
  212. package/src/lib/point-ask/region.ts +1 -1
  213. package/src/lib/point-ask/session.ts +1 -2
  214. package/src/lib/print-shell-compiler.ts +12 -1
  215. package/src/lib/print-wall-solids.test.ts +11 -0
  216. package/src/lib/print-wall-solids.ts +9 -0
  217. package/src/lib/roof-duplication.test.ts +100 -0
  218. package/src/lib/roof-duplication.ts +30 -5
  219. package/src/lib/room-built-on.test.ts +2 -5
  220. package/src/lib/room-built-on.ts +1 -15
  221. package/src/lib/room-construction-commands.ts +3 -2
  222. package/src/lib/room-controls-phase6.test.ts +1 -1
  223. package/src/lib/room-handle-drag.ts +8 -37
  224. package/src/lib/room-name-catalog.test.ts +2 -1
  225. package/src/lib/room-name-messages.test.ts +2 -1
  226. package/src/lib/room-name-messages.ts +1 -118
  227. package/src/lib/room-name-storage.test.ts +2 -1
  228. package/src/lib/room-push-dimensions.test.ts +1 -1
  229. package/src/lib/room-selection-commands.ts +2 -2
  230. package/src/lib/room-selection.test.ts +6 -6
  231. package/src/lib/room-transform-session.ts +1 -2
  232. package/src/lib/room-zone-routing.ts +2 -2
  233. package/src/lib/scene-clipboard.ts +2 -1
  234. package/src/lib/selection-routing.test.ts +0 -28
  235. package/src/lib/selection-routing.ts +1 -40
  236. package/src/lib/sfx-bus.ts +8 -32
  237. package/src/lib/sfx-player.test.ts +72 -1
  238. package/src/lib/sfx-player.ts +49 -337
  239. package/src/lib/snapping-mode.test.ts +23 -1
  240. package/src/lib/viewer-selection.test.ts +38 -10
  241. package/src/lib/wall-pull.test.ts +1 -1
  242. package/src/lib/wall-pull.ts +1 -27
  243. package/src/lib/wall-region-list.ts +3 -1
  244. package/src/lib/window-interaction.test.ts +4 -2
  245. package/src/store/use-editor.tsx +22 -26
  246. package/src/store/use-floorplan-annotation-visibility.ts +5 -5
  247. package/src/store/use-placement-typing.test.ts +165 -0
  248. package/src/store/use-placement-typing.ts +186 -0
  249. package/src/store/use-wall-region-handles-selection.ts +1 -2
  250. package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
  251. package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
  252. package/src/components/editor/first-person/build-collider-world.ts +0 -549
  253. package/src/components/editor/first-person/ground-holes.test.ts +0 -128
  254. package/src/components/editor/first-person/ground-holes.ts +0 -130
  255. package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
  256. package/src/components/editor/first-person/mechanism-targets.ts +0 -88
  257. package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
  258. package/src/components/editor/first-person/terrain-collider.ts +0 -212
  259. package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
  260. package/src/components/editor/floorplan-camera-sync.ts +0 -213
  261. package/src/components/editor/localized-html.tsx +0 -22
  262. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
  263. package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
  264. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
  265. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
  266. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
  267. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
  268. package/src/components/editor-2d/svg-paths.ts +0 -124
  269. package/src/components/tools/elevator/elevator-defaults.ts +0 -8
  270. package/src/components/tools/elevator/elevator-tool.tsx +0 -372
  271. package/src/components/tools/elevator/move-elevator-tool.tsx +0 -262
  272. package/src/components/ui/action-menu/action-button.tsx +0 -89
  273. package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
  274. package/src/components/ui/primitives/button.tsx +0 -69
  275. package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
  276. package/src/components/ui/primitives/popover.tsx +0 -42
  277. package/src/components/ui/primitives/switch.tsx +0 -29
  278. package/src/components/ui/primitives/tooltip.tsx +0 -57
  279. package/src/components/ui/scene-loader.tsx +0 -73
  280. package/src/components/viewer/floorplan-compass-button.tsx +0 -67
  281. package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
  282. package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
  283. package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
  284. package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
  285. package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
  286. package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
  287. package/src/components/viewer/floorplan-preview.tsx +0 -1065
  288. package/src/components/viewer/render-settings-menu.tsx +0 -294
  289. package/src/components/viewer/sky-control.tsx +0 -710
  290. package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
  291. package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
  292. package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
  293. package/src/components/viewer/viewer-controls-bar.tsx +0 -496
  294. package/src/components/viewer/viewer-hover-label.tsx +0 -42
  295. package/src/components/viewer/viewer-rooms.tsx +0 -248
  296. package/src/components/viewer/viewer-scene-header.tsx +0 -286
  297. package/src/components/viewer/viewer-selection-manager.tsx +0 -124
  298. package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
  299. package/src/components/viewer/viewer-stage-modes.ts +0 -49
  300. package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
  301. package/src/components/viewer/viewer-stage.test.tsx +0 -47
  302. package/src/components/viewer/viewer-stage.tsx +0 -221
  303. package/src/components/walkthrough-hud.tsx +0 -193
  304. package/src/hooks/use-mobile.ts +0 -19
  305. package/src/i18n/level-name.ts +0 -39
  306. package/src/i18n/scene-theme-name.ts +0 -16
  307. package/src/lib/below-grade.ts +0 -133
  308. package/src/lib/camera-pose.test.ts +0 -237
  309. package/src/lib/camera-pose.ts +0 -172
  310. package/src/lib/door-interaction.ts +0 -102
  311. package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
  312. package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
  313. package/src/lib/floorplan/floorplan-readonly.ts +0 -95
  314. package/src/lib/floorplan/marks.test.ts +0 -213
  315. package/src/lib/floorplan/marks.ts +0 -238
  316. package/src/lib/measurement-label.ts +0 -68
  317. package/src/lib/measurements.ts +0 -225
  318. package/src/lib/node-display-label.ts +0 -37
  319. package/src/lib/room-assembly-overlay.test.ts +0 -275
  320. package/src/lib/room-assembly-overlay.ts +0 -265
  321. package/src/lib/room-selection.ts +0 -417
  322. package/src/lib/scene-bounds.test.ts +0 -183
  323. package/src/lib/scene-bounds.ts +0 -169
  324. package/src/lib/typing-target.ts +0 -9
  325. package/src/lib/viewer-selection.ts +0 -595
  326. package/src/lib/window-interaction.ts +0 -142
  327. package/src/lib/zone-content.ts +0 -133
  328. package/src/store/camera-pose-store.test.ts +0 -29
  329. package/src/store/camera-pose-store.ts +0 -27
  330. package/src/store/navigation-sync-pose-store.test.ts +0 -34
  331. package/src/store/navigation-sync-pose-store.ts +0 -27
  332. package/src/store/use-audio.test.ts +0 -146
  333. package/src/store/use-audio.tsx +0 -169
  334. package/src/store/use-first-person-hud.ts +0 -40
  335. package/src/store/use-follow-pascal.test.ts +0 -62
  336. package/src/store/use-follow-pascal.ts +0 -53
@@ -1,4 +1,12 @@
1
- import { type AnyNodeId, type RoofNode, type RoofSegmentNode, useScene, usePascalI18n} from '@pascal-app/core'
1
+ import {
2
+ type AnyNodeId,
3
+ type RoofNode,
4
+ type RoofSegmentNode,
5
+ roofFaceOf,
6
+ useRegistryVersion,
7
+ useScene,
8
+ usePascalI18n,
9
+ } from '@pascal-app/core'
2
10
  import { useViewer } from '@pascal-app/viewer'
3
11
  import { AnimatePresence } from 'motion/react'
4
12
  import Image from 'next/image'
@@ -10,6 +18,7 @@ import { focusTreeNode, handleTreeSelection, TreeNode, TreeNodeWrapper } from '.
10
18
  import { TreeNodeActions } from './tree-node-actions'
11
19
  import { DropIndicatorLine, useTreeNodeDrag } from './tree-node-drag'
12
20
  import { roofDefaultName, roofSegmentDefaultName } from './default-names'
21
+ import { nodeLabelDescriptor } from '../../../../../i18n/node-messages'
13
22
 
14
23
  interface RoofTreeNodeProps {
15
24
  nodeId: AnyNodeId
@@ -42,10 +51,23 @@ export const RoofTreeNode = memo(function RoofTreeNode({
42
51
  .filter((n): n is RoofSegmentNode => n?.type === 'roof-segment')
43
52
  }),
44
53
  )
54
+ // Its faces of other kinds (`capabilities.roofs`: a plugin's roof planes), listed after its
55
+ // segments as the rows their kinds draw. A plugin registers its kinds after the first mount.
56
+ useRegistryVersion()
57
+ const faceIds = useScene(
58
+ useShallow(
59
+ (s) =>
60
+ ((s.nodes[nodeId] as RoofNode | undefined)?.children ?? []).filter((childId) =>
61
+ roofFaceOf(s.nodes[childId as AnyNodeId]),
62
+ ) as AnyNodeId[],
63
+ ),
64
+ )
45
65
 
46
- // Targeted selector — only re-renders when a segment of THIS roof is selected/deselected
47
- const hasSelectedChild = useViewer((state) =>
48
- segments.some((seg) => state.selection.selectedIds.includes(seg.id)),
66
+ // Targeted selector — only re-renders when a segment or face of THIS roof is selected/deselected
67
+ const hasSelectedChild = useViewer(
68
+ (state) =>
69
+ segments.some((seg) => state.selection.selectedIds.includes(seg.id)) ||
70
+ faceIds.some((id) => state.selection.selectedIds.includes(id)),
49
71
  )
50
72
 
51
73
  const handleClick = useCallback(
@@ -86,7 +108,11 @@ export const RoofTreeNode = memo(function RoofTreeNode({
86
108
  }, [isDropTarget, expanded])
87
109
 
88
110
  const segmentCount = segments.length
89
- const defaultName = roofDefaultName(i18n, segmentCount)
111
+ // A roof of faces alone reads as a roof, not as one of no segments.
112
+ const defaultName =
113
+ segmentCount === 0 && faceIds.length > 0
114
+ ? i18n._(nodeLabelDescriptor('roof', 'Roof'))
115
+ : roofDefaultName(i18n, segmentCount)
90
116
 
91
117
  // Hide the dragged segment from every roof while dragging
92
118
  const visibleSegments = drag ? segments.filter((seg) => seg.id !== drag.nodeId) : segments
@@ -99,7 +125,7 @@ export const RoofTreeNode = memo(function RoofTreeNode({
99
125
  actions={<TreeNodeActions nodeId={nodeId} />}
100
126
  depth={depth}
101
127
  expanded={expanded}
102
- hasChildren={segments.length > 0}
128
+ hasChildren={segments.length + faceIds.length > 0}
103
129
  icon={
104
130
  <Image alt="" className="object-contain" height={14} src="/icons/roof.webp" width={14} />
105
131
  }
@@ -139,7 +165,12 @@ export const RoofTreeNode = memo(function RoofTreeNode({
139
165
  </AnimatePresence>
140
166
  <RoofSegmentTreeNode
141
167
  depth={depth + 1}
142
- isLast={isLast && i === visibleSegments.length - 1 && !showIndicatorAfter}
168
+ isLast={
169
+ isLast &&
170
+ faceIds.length === 0 &&
171
+ i === visibleSegments.length - 1 &&
172
+ !showIndicatorAfter
173
+ }
143
174
  node={seg}
144
175
  />
145
176
  <AnimatePresence>
@@ -151,6 +182,14 @@ export const RoofTreeNode = memo(function RoofTreeNode({
151
182
  <AnimatePresence>
152
183
  {isDropTarget && visibleSegments.length === 0 && <DropIndicatorLine />}
153
184
  </AnimatePresence>
185
+ {faceIds.map((faceId, index) => (
186
+ <TreeNode
187
+ depth={depth + 1}
188
+ isLast={isLast && index === faceIds.length - 1}
189
+ key={faceId}
190
+ nodeId={faceId}
191
+ />
192
+ ))}
154
193
  </TreeNodeWrapper>
155
194
  </div>
156
195
  )
@@ -2,7 +2,7 @@ import { type AnyNodeId, type SlabNode, usePascalI18n, useScene } from '@pascal-
2
2
  import { useViewer } from '@pascal-app/viewer'
3
3
  import Image from 'next/image'
4
4
  import { memo, useCallback, useState } from 'react'
5
- import { formatAreaLabel } from './../../../../../lib/measurements'
5
+ import { formatAreaLabel } from '@pascal-app/core'
6
6
  import { InlineRenameInput } from './inline-rename-input'
7
7
  import { focusTreeNode, handleTreeSelection, TreeNodeWrapper } from './tree-node'
8
8
  import { TreeNodeActions } from './tree-node-actions'
@@ -6,7 +6,7 @@ import {
6
6
  Popover,
7
7
  PopoverContent,
8
8
  PopoverTrigger,
9
- } from './../../../../../components/ui/primitives/popover'
9
+ } from '@pascal-app/viewer/ui'
10
10
 
11
11
  interface TreeNodeActionsProps {
12
12
  nodeId: AnyNodeId
@@ -96,6 +96,11 @@ type DragState = {
96
96
  type DropTarget = {
97
97
  parentId: string
98
98
  insertIndex: number
99
+ /**
100
+ * The row the drop lands before; none at the end. The rows are not all of the parent's
101
+ * children (a roof's faces have no drop row), so the drop is placed by id.
102
+ */
103
+ beforeId?: string
99
104
  } | null
100
105
 
101
106
  type TreeNodeDragContextValue = {
@@ -143,6 +148,10 @@ export function TreeNodeDragProvider({ children }: { children: ReactNode }) {
143
148
  if (!(drag && dropTarget)) return
144
149
 
145
150
  const state = useScene.getState()
151
+ const place = (children: string[], id: string) => {
152
+ const before = dropTarget.beforeId ? children.indexOf(dropTarget.beforeId) : -1
153
+ children.splice(before === -1 ? children.length : before, 0, id)
154
+ }
146
155
 
147
156
  if (dropTarget.parentId === drag.sourceParentId) {
148
157
  // --- Reorder within same parent ---
@@ -152,8 +161,7 @@ export function TreeNodeDragProvider({ children }: { children: ReactNode }) {
152
161
  const fromIndex = currentChildren.indexOf(drag.nodeId)
153
162
  if (fromIndex === -1) return
154
163
  currentChildren.splice(fromIndex, 1)
155
- const toIndex = Math.min(dropTarget.insertIndex, currentChildren.length)
156
- currentChildren.splice(toIndex, 0, drag.nodeId)
164
+ place(currentChildren, drag.nodeId)
157
165
  state.updateNode(dropTarget.parentId as AnyNodeId, { children: currentChildren } as any)
158
166
  }
159
167
  } else {
@@ -185,8 +193,7 @@ export function TreeNodeDragProvider({ children }: { children: ReactNode }) {
185
193
  const idx = children.indexOf(drag.nodeId)
186
194
  if (idx !== -1) {
187
195
  children.splice(idx, 1)
188
- const toIndex = Math.min(dropTarget.insertIndex, children.length)
189
- children.splice(toIndex, 0, drag.nodeId)
196
+ place(children, drag.nodeId)
190
197
  state.updateNode(dropTarget.parentId as AnyNodeId, { children } as any)
191
198
  }
192
199
  }
@@ -259,6 +266,7 @@ export function TreeNodeDragProvider({ children }: { children: ReactNode }) {
259
266
  // Find child rows to determine insert index
260
267
  const childRows = targetEl.querySelectorAll<HTMLElement>('[data-drop-child]')
261
268
  let insertIndex = childRows.length
269
+ let beforeId: string | undefined
262
270
 
263
271
  for (let i = 0; i < childRows.length; i++) {
264
272
  const row = childRows[i]!
@@ -266,11 +274,12 @@ export function TreeNodeDragProvider({ children }: { children: ReactNode }) {
266
274
  const midY = rect.top + rect.height / 2
267
275
  if (e.clientY < midY) {
268
276
  insertIndex = i
277
+ beforeId = row.dataset.dropChild
269
278
  break
270
279
  }
271
280
  }
272
281
 
273
- foundTarget = { parentId, insertIndex }
282
+ foundTarget = { parentId, insertIndex, beforeId }
274
283
  break
275
284
  }
276
285
 
@@ -16,8 +16,8 @@ import { assignZoneToUnit, enterUnitFocus } from './../../../../../lib/units'
16
16
  import { InlineRenameInput } from './inline-rename-input'
17
17
  import { TreeNodeWrapper } from './tree-node'
18
18
  import { nodeLabelDescriptor } from '../../../../../i18n/node-messages'
19
- import { localizedLevelName } from '../../../../../i18n/level-name'
20
- import { displayRoomName } from '../../../../../lib/room-name-messages'
19
+ import { localizedLevelName } from '@pascal-app/viewer/ui'
20
+ import { displayRoomName } from '@pascal-app/viewer/ui'
21
21
 
22
22
  type UnitWarningCode = ReturnType<typeof unitWarnings>[number]['code']
23
23
 
@@ -2,7 +2,7 @@ import { useScene, type ZoneNode, usePascalI18n} from '@pascal-app/core'
2
2
  import { useViewer } from '@pascal-app/viewer'
3
3
  import { memo, useCallback, useState } from 'react'
4
4
  import { ColorDot } from './../../../../../components/ui/primitives/color-dot'
5
- import { formatAreaLabel } from './../../../../../lib/measurements'
5
+ import { formatAreaLabel } from '@pascal-app/core'
6
6
  import {
7
7
  selectZoneOrRoom,
8
8
  useZoneSelected,
@@ -8,18 +8,18 @@ import { useViewer } from '@pascal-app/viewer'
8
8
  import { Camera, Hexagon, Save, Trash2 } from 'lucide-react'
9
9
  import { useState } from 'react'
10
10
  import { sfxEmitter } from './../../../../../lib/sfx-bus'
11
- import { collectZoneContentIds } from './../../../../../lib/zone-content'
11
+ import { collectZoneContentIds } from '@pascal-app/viewer/ui'
12
12
  import { ColorDot } from './../../../../../components/ui/primitives/color-dot'
13
13
  import {
14
14
  Popover,
15
15
  PopoverContent,
16
16
  PopoverTrigger,
17
- } from './../../../../../components/ui/primitives/popover'
17
+ } from '@pascal-app/viewer/ui'
18
18
  import { cn } from './../../../../../lib/utils'
19
19
  import useEditor from './../../../../../store/use-editor'
20
20
  import { ActionButton } from '../../../controls/action-button'
21
21
  import { PanelSection } from '../../../controls/panel-section'
22
- import { displayRoomName } from '../../../../../lib/room-name-messages'
22
+ import { displayRoomName } from '@pascal-app/viewer/ui'
23
23
 
24
24
  function ZoneItem({ zone }: { zone: ZoneNode }) {
25
25
  const i18n = usePascalI18n()
@@ -4,7 +4,7 @@ import type { ReactNode } from 'react'
4
4
  import { editorHostPanelRegistry } from '../../../lib/plugin-panels'
5
5
  import { triggerSFX } from './../../../lib/sfx-bus'
6
6
  import { cn } from './../../../lib/utils'
7
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../primitives/tooltip'
7
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@pascal-app/viewer/ui'
8
8
 
9
9
  export type SidebarTab = {
10
10
  id: string
@@ -27,7 +27,7 @@ import { useViewer } from '@pascal-app/viewer'
27
27
  import { ArrowDown, ArrowUp, Plus, X } from 'lucide-react'
28
28
  import { useEffect, useState } from 'react'
29
29
  import { formatLayerThickness, parseLayerThickness } from '../../../lib/layer-thickness'
30
- import type { LinearUnit } from '../../../lib/measurements'
30
+ import type { LinearUnit } from '@pascal-app/core'
31
31
  import { cn } from '../../../lib/utils'
32
32
  import {
33
33
  saveProjectWallType,
@@ -36,7 +36,7 @@ import {
36
36
  type WallTypePlacement,
37
37
  type WallTypeSaveResult,
38
38
  } from '../../../lib/wall-type'
39
- import { Button } from '../primitives/button'
39
+ import { Button } from '@pascal-app/viewer/ui'
40
40
  import {
41
41
  Dialog,
42
42
  DialogContent,
@@ -23,7 +23,7 @@ import {
23
23
  DropdownMenuLabel,
24
24
  DropdownMenuSeparator,
25
25
  DropdownMenuTrigger,
26
- } from '../primitives/dropdown-menu'
26
+ } from '@pascal-app/viewer/ui'
27
27
  import { type WallTypeEditorRequest, WallTypeEditorDialog } from './wall-type-editor-dialog'
28
28
 
29
29
  /**
@@ -1,10 +1,9 @@
1
1
  'use client'
2
2
 
3
+ import { ViewerControlsBar, ViewerSceneHeader } from '@pascal-app/viewer/ui'
3
4
  import { flushSync } from 'react-dom'
4
5
  import { requestWalkthroughPointerLock } from '../lib/walkthrough-pointer-lock'
5
6
  import useEditor from '../store/use-editor'
6
- import { ViewerControlsBar } from './viewer/viewer-controls-bar'
7
- import { ViewerSceneHeader } from './viewer/viewer-scene-header'
8
7
 
9
8
  type ProjectOwner = {
10
9
  id: string
@@ -1,8 +1,7 @@
1
1
  'use client'
2
2
 
3
- import { emitter, useScene } from '@pascal-app/core'
3
+ import { computeSceneBoundsXZ, emitter, useScene } from '@pascal-app/core'
4
4
  import { useEffect, useRef } from 'react'
5
- import { computeSceneBoundsXZ } from '../lib/scene-bounds'
6
5
 
7
6
  /**
8
7
  * Auto-frame the camera onto a freshly loaded scene.
@@ -9,7 +9,7 @@ import {
9
9
  toggleNodeMechanism,
10
10
  useScene,
11
11
  } from '@pascal-app/core'
12
- import { cancelPerfAction, markPerfAction, useViewer } from '@pascal-app/viewer'
12
+ import { cancelPerfAction, isTypingTarget, markPerfAction, useViewer } from '@pascal-app/viewer'
13
13
  import { useEffect } from 'react'
14
14
  import {
15
15
  cutSelectionToEditorClipboard,
@@ -40,7 +40,6 @@ import { sfxEmitter } from '../lib/sfx-bus'
40
40
  import { openSidebarPanel } from '../lib/sidebar-panel'
41
41
  import { activeSiteNode, clampBrushRadius } from '../lib/terrain-sculpt'
42
42
  import { armToolShortcut, toolShortcutForKey } from '../lib/tool-shortcuts'
43
- import { isTypingTarget } from '../lib/typing-target'
44
43
  import { leaveUnitFocus } from '../lib/units'
45
44
  import { subscribeWallKindReset } from '../lib/wall-draw-variant'
46
45
  import { isWallNudgeKey, nudgeSelectedWall } from '../lib/wall-nudge'
@@ -2,17 +2,17 @@
2
2
 
3
3
  import { type AnyNode, type AnyNodeId, nodeRegistry, useScene } from '@pascal-app/core'
4
4
  import { useViewer } from '@pascal-app/viewer'
5
- import { useCallback, useSyncExternalStore } from 'react'
6
- import { getFloorplanNodeExtension } from '../lib/floorplan/floorplan-extension'
7
- import { selectionEnabled } from '../lib/interaction/scope'
5
+ import type { SelectionModifierKeys } from '@pascal-app/viewer/ui'
8
6
  import {
9
7
  type RoomKey,
10
8
  RoomSelectionIndex,
11
9
  type RoomSelectionRecord,
12
10
  resolveRoomHit,
13
- } from '../lib/room-selection'
11
+ } from '@pascal-app/viewer/ui'
12
+ import { useCallback, useSyncExternalStore } from 'react'
13
+ import { getFloorplanNodeExtension } from '../lib/floorplan/floorplan-extension'
14
+ import { selectionEnabled } from '../lib/interaction/scope'
14
15
  import { shouldInterceptRoom } from '../lib/room-selection-commands'
15
- import { type SelectionModifierKeys, selectionModifiersFromEvent } from '../lib/selection-routing'
16
16
  import useEditor from '../store/use-editor'
17
17
  import useInteractionScope from '../store/use-interaction-scope'
18
18
 
@@ -150,5 +150,3 @@ export function resolvePlanRoomHit(nodeId: string | null, point: readonly [numbe
150
150
  const levelId = node?.parentId ?? useViewer.getState().selection.levelId
151
151
  return levelId ? resolveEditorRoomHit(node ?? null, levelId, point, '2d') : null
152
152
  }
153
-
154
- export { selectionModifiersFromEvent }
@@ -4,7 +4,7 @@ import {
4
4
  type PascalI18n,
5
5
  type SlabNode,
6
6
  } from '@pascal-app/core'
7
- import { displayRoomName } from '../lib/room-name-messages'
7
+ import { displayRoomName } from '@pascal-app/viewer/ui'
8
8
 
9
9
  /** `floorFootprintName` in the UI language; MCP and agents keep core's English. */
10
10
  export function localizedFloorFootprintName(