@pascal-app/editor 0.8.0 → 0.9.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 (350) hide show
  1. package/package.json +15 -13
  2. package/src/components/editor/alignment-3d-guide-layer.tsx +168 -0
  3. package/src/components/editor/bake-exporter.tsx +47 -0
  4. package/src/components/editor/custom-camera-controls.tsx +795 -28
  5. package/src/components/editor/editor-layout-mobile.tsx +8 -3
  6. package/src/components/editor/editor-layout-v2.tsx +76 -51
  7. package/src/components/editor/export-manager.tsx +69 -32
  8. package/src/components/editor/fence-tangent-lines-3d.tsx +87 -0
  9. package/src/components/editor/first-person/build-collider-world.test.ts +182 -0
  10. package/src/components/editor/first-person/build-collider-world.ts +228 -83
  11. package/src/components/editor/first-person-controls.tsx +943 -27
  12. package/src/components/editor/floating-action-menu.tsx +676 -208
  13. package/src/components/editor/floating-building-action-menu.tsx +2 -2
  14. package/src/components/editor/floorplan-background-selection.test.ts +58 -0
  15. package/src/components/editor/floorplan-background-selection.ts +3 -2
  16. package/src/components/editor/floorplan-panel.tsx +6916 -12137
  17. package/src/components/editor/grid.tsx +197 -36
  18. package/src/components/editor/group-actions.ts +457 -0
  19. package/src/components/editor/group-floating-action-menu.tsx +130 -0
  20. package/src/components/editor/group-move-3d.ts +397 -0
  21. package/src/components/editor/group-rotate-handle.tsx +420 -0
  22. package/src/components/editor/group-selection-box-3d.tsx +173 -0
  23. package/src/components/editor/group-transform-shared.test.ts +396 -0
  24. package/src/components/editor/group-transform-shared.ts +489 -0
  25. package/src/components/editor/handles/handle-arrow.tsx +581 -0
  26. package/src/components/editor/handles/use-handle-drag.ts +246 -0
  27. package/src/components/editor/index.tsx +412 -162
  28. package/src/components/editor/measurement-pill.tsx +115 -0
  29. package/src/components/editor/node-action-menu.tsx +14 -1
  30. package/src/components/editor/node-arrow-handles.tsx +1646 -0
  31. package/src/components/editor/opening-guides-3d-layer.tsx +144 -0
  32. package/src/components/editor/quick-measurement-card.tsx +70 -0
  33. package/src/components/editor/quick-measurement-hud.tsx +28 -0
  34. package/src/components/editor/riser-diagram-panel.tsx +137 -0
  35. package/src/components/editor/selection-manager.tsx +1106 -483
  36. package/src/components/editor/site-edge-labels.tsx +45 -21
  37. package/src/components/editor/slab-hole-highlights.tsx +474 -0
  38. package/src/components/editor/snapshot-capture-overlay.tsx +369 -155
  39. package/src/components/editor/three-context-bridge.ts +22 -0
  40. package/src/components/editor/thumbnail-generator.tsx +140 -41
  41. package/src/components/editor/use-floorplan-background-placement.ts +190 -35
  42. package/src/components/editor/use-floorplan-hit-testing.ts +24 -0
  43. package/src/components/editor/use-floorplan-scene-data.ts +19 -7
  44. package/src/components/editor/use-mesh-settle-epoch.ts +26 -0
  45. package/src/components/editor/wall-measurement-label.tsx +14 -19
  46. package/src/components/editor/wall-move-side-handles.tsx +870 -0
  47. package/src/components/editor/wall-opening-highlights.tsx +181 -0
  48. package/src/components/editor/wall-snap-beacon-layer.tsx +304 -0
  49. package/src/components/editor-2d/floorplan-action-menu-layer.tsx +15 -6
  50. package/src/components/editor-2d/floorplan-alignment-guide-layer.tsx +142 -0
  51. package/src/components/editor-2d/floorplan-cursor-indicator-overlay.tsx +5 -3
  52. package/src/components/editor-2d/floorplan-group-action-menu.tsx +87 -0
  53. package/src/components/editor-2d/floorplan-group-move.tsx +701 -0
  54. package/src/components/editor-2d/floorplan-measurement-tool-layer.test.ts +113 -0
  55. package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +1656 -0
  56. package/src/components/editor-2d/floorplan-quick-measure-layer.tsx +212 -0
  57. package/src/components/editor-2d/floorplan-registry-action-menu.tsx +392 -0
  58. package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +857 -0
  59. package/src/components/editor-2d/floorplan-render-context.tsx +62 -0
  60. package/src/components/editor-2d/floorplan-snap-beacon-layer.tsx +77 -0
  61. package/src/components/editor-2d/floorplan-wall-move-ghost-layer.tsx +47 -0
  62. package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +266 -0
  63. package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +15 -0
  64. package/src/components/editor-2d/renderers/floorplan-label-angle.ts +14 -0
  65. package/src/components/editor-2d/renderers/floorplan-measurements-layer.tsx +108 -66
  66. package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +62 -0
  67. package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +308 -0
  68. package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +3325 -0
  69. package/src/components/editor-2d/renderers/floorplan-stair-layer.tsx +24 -9
  70. package/src/components/editor-2d/renderers/floorplan-voronoi-layer.tsx +128 -0
  71. package/src/components/editor-2d/svg-paths.ts +10 -2
  72. package/src/components/systems/ceiling/ceiling-selection-affordance-system.tsx +439 -57
  73. package/src/components/systems/ceiling/ceiling-system.tsx +109 -12
  74. package/src/components/systems/roof/roof-edit-system.tsx +1851 -22
  75. package/src/components/systems/selection-affordance-manager.tsx +38 -0
  76. package/src/components/systems/stair/stair-edit-system.tsx +1 -1
  77. package/src/components/systems/zone/zone-label-editor-system.tsx +14 -1
  78. package/src/components/systems/zone/zone-system.tsx +42 -13
  79. package/src/components/tools/elevator/elevator-defaults.ts +8 -0
  80. package/src/components/tools/elevator/elevator-tool.tsx +375 -0
  81. package/src/components/tools/elevator/move-elevator-tool.tsx +263 -0
  82. package/src/components/tools/fence/fence-drafting.ts +141 -27
  83. package/src/components/tools/item/move-tool.tsx +45 -105
  84. package/src/components/tools/item/placement-math.test.ts +22 -0
  85. package/src/components/tools/item/placement-math.ts +59 -7
  86. package/src/components/tools/item/placement-strategies.ts +432 -16
  87. package/src/components/tools/item/placement-types.ts +22 -1
  88. package/src/components/tools/item/use-draft-node.ts +51 -2
  89. package/src/components/tools/item/use-placement-coordinator.tsx +1399 -256
  90. package/src/components/tools/registry/move-registry-node-tool.tsx +1064 -0
  91. package/src/components/tools/roof/roof-tool.tsx +350 -28
  92. package/src/components/tools/select/box-select-state.ts +88 -0
  93. package/src/components/tools/select/box-select-tool.tsx +442 -520
  94. package/src/components/tools/select/marquee-geometry.test.ts +161 -0
  95. package/src/components/tools/select/marquee-geometry.ts +155 -0
  96. package/src/components/tools/select/plane-box-select-tool.tsx +570 -0
  97. package/src/components/tools/select/screen-rectangle-selection.ts +84 -0
  98. package/src/components/tools/select/select-candidates.test.ts +109 -0
  99. package/src/components/tools/select/select-candidates.ts +85 -0
  100. package/src/components/tools/shared/affordance-dispatch.ts +30 -0
  101. package/src/components/tools/shared/cursor-sphere.tsx +62 -26
  102. package/src/components/tools/shared/drag-bounding-box.tsx +195 -0
  103. package/src/components/tools/shared/facing-indicator.tsx +87 -0
  104. package/src/components/tools/shared/facing-pose-indicator.tsx +54 -0
  105. package/src/components/tools/shared/floor-stack-preview.ts +25 -0
  106. package/src/components/tools/shared/fresh-placement-visibility.ts +61 -0
  107. package/src/components/tools/shared/placement-box-geometry.ts +123 -0
  108. package/src/components/tools/shared/placement-box.tsx +305 -0
  109. package/src/components/tools/shared/polygon-editor.tsx +866 -175
  110. package/src/components/tools/shared/segment-angle.ts +56 -0
  111. package/src/components/tools/site/site-boundary-editor.tsx +520 -16
  112. package/src/components/tools/site/site-flag-model.ts +18 -0
  113. package/src/components/tools/stair/stair-defaults.ts +2 -1
  114. package/src/components/tools/stair/stair-tool.tsx +342 -37
  115. package/src/components/tools/tool-manager.tsx +239 -62
  116. package/src/components/tools/wall/wall-drafting.test.ts +330 -0
  117. package/src/components/tools/wall/wall-drafting.ts +248 -171
  118. package/src/components/tools/wall/wall-snap-geometry.test.ts +123 -0
  119. package/src/components/tools/wall/wall-snap-geometry.ts +331 -0
  120. package/src/components/tools/zone/zone-boundary-editor.tsx +5 -1
  121. package/src/components/tools/zone/zone-tool.tsx +86 -82
  122. package/src/components/ui/action-menu/action-button.tsx +21 -1
  123. package/src/components/ui/action-menu/camera-actions.tsx +24 -17
  124. package/src/components/ui/action-menu/control-modes.tsx +40 -170
  125. package/src/components/ui/action-menu/furnish-tools.tsx +5 -5
  126. package/src/components/ui/action-menu/index.tsx +3 -117
  127. package/src/components/ui/action-menu/measurement-control.tsx +188 -0
  128. package/src/components/ui/action-menu/structure-tools.tsx +27 -93
  129. package/src/components/ui/action-menu/view-toggles.tsx +279 -90
  130. package/src/components/ui/command-palette/editor-commands.tsx +20 -15
  131. package/src/components/ui/command-palette/index.tsx +5 -3
  132. package/src/components/ui/controls/material-paint-panel.tsx +152 -0
  133. package/src/components/ui/controls/material-picker.tsx +87 -177
  134. package/src/components/ui/controls/material-properties-editor.tsx +108 -0
  135. package/src/components/ui/controls/metric-control.tsx +142 -46
  136. package/src/components/ui/controls/scene-material-list.tsx +247 -0
  137. package/src/components/ui/controls/slider-control.tsx +88 -38
  138. package/src/components/ui/floating-level-selector.tsx +47 -10
  139. package/src/components/ui/helpers/building-helper.tsx +10 -23
  140. package/src/components/ui/helpers/contextual-helper-panel.tsx +428 -0
  141. package/src/components/ui/helpers/helper-manager.tsx +235 -23
  142. package/src/components/ui/helpers/item-helper.tsx +28 -32
  143. package/src/components/ui/helpers/registered-tool-helper.tsx +59 -0
  144. package/src/components/ui/helpers/roof-helper.tsx +10 -12
  145. package/src/components/ui/icon-ref.tsx +47 -0
  146. package/src/components/ui/item-catalog/catalog-items.tsx +40 -1
  147. package/src/components/ui/item-catalog/item-catalog.tsx +16 -36
  148. package/src/components/ui/level-duplicate-dialog.tsx +2 -1
  149. package/src/components/ui/panels/node-display.ts +17 -16
  150. package/src/components/ui/panels/panel-manager.tsx +55 -58
  151. package/src/components/ui/panels/panel-wrapper.tsx +238 -12
  152. package/src/components/ui/panels/parametric-inspector.tsx +482 -0
  153. package/src/components/ui/panels/reference-panel.tsx +54 -19
  154. package/src/components/ui/primitives/dropdown-menu.tsx +12 -8
  155. package/src/components/ui/primitives/shortcut-token.tsx +39 -3
  156. package/src/components/ui/primitives/sidebar.tsx +1 -0
  157. package/src/components/ui/scene-loader.tsx +1 -3
  158. package/src/components/ui/sidebar/app-sidebar.tsx +5 -1
  159. package/src/components/ui/sidebar/icon-rail.tsx +50 -31
  160. package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +263 -0
  161. package/src/components/ui/sidebar/panels/items-panel/index.tsx +82 -8
  162. package/src/components/ui/sidebar/panels/plugins-panel.tsx +218 -0
  163. package/src/components/ui/sidebar/panels/settings-panel/index.tsx +122 -41
  164. package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +66 -7
  165. package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +267 -0
  166. package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +3 -1
  167. package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +9 -5
  168. package/src/components/ui/sidebar/panels/site-panel/chimney-tree-node.tsx +86 -0
  169. package/src/components/ui/sidebar/panels/site-panel/column-tree-node.tsx +1 -1
  170. package/src/components/ui/sidebar/panels/site-panel/door-tree-node.tsx +7 -2
  171. package/src/components/ui/sidebar/panels/site-panel/dormer-tree-node.tsx +92 -0
  172. package/src/components/ui/sidebar/panels/site-panel/elevator-tree-node.tsx +75 -0
  173. package/src/components/ui/sidebar/panels/site-panel/fence-tree-node.tsx +3 -3
  174. package/src/components/ui/sidebar/panels/site-panel/gutter-tree-node.tsx +86 -0
  175. package/src/components/ui/sidebar/panels/site-panel/index.tsx +42 -21
  176. package/src/components/ui/sidebar/panels/site-panel/item-tree-node.tsx +31 -17
  177. package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +2 -1
  178. package/src/components/ui/sidebar/panels/site-panel/registry-tree-node.tsx +140 -0
  179. package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +48 -8
  180. package/src/components/ui/sidebar/panels/site-panel/shelf-tree-node.tsx +132 -0
  181. package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +9 -5
  182. package/src/components/ui/sidebar/panels/site-panel/solar-panel-tree-node.tsx +86 -0
  183. package/src/components/ui/sidebar/panels/site-panel/spawn-tree-node.tsx +7 -1
  184. package/src/components/ui/sidebar/panels/site-panel/stair-tree-node.tsx +2 -2
  185. package/src/components/ui/sidebar/panels/site-panel/tree-node.tsx +112 -39
  186. package/src/components/ui/sidebar/panels/site-panel/tree-structure.ts +36 -0
  187. package/src/components/ui/sidebar/panels/site-panel/wall-tree-node.tsx +1 -1
  188. package/src/components/ui/sidebar/panels/site-panel/window-tree-node.tsx +7 -2
  189. package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +3 -3
  190. package/src/components/ui/sidebar/panels/zone-panel/index.tsx +51 -2
  191. package/src/components/ui/sidebar/tab-bar.tsx +75 -1
  192. package/src/components/ui/sidebar/use-plugin-panels.tsx +132 -0
  193. package/src/components/ui/snap-target-badge.test.tsx +40 -0
  194. package/src/components/ui/snap-target-badge.tsx +88 -0
  195. package/src/components/viewer-overlay.tsx +253 -61
  196. package/src/components/viewer-zone-system.tsx +7 -2
  197. package/src/hooks/use-auto-save.test.ts +14 -0
  198. package/src/hooks/use-auto-save.ts +64 -10
  199. package/src/hooks/use-ceiling-events.ts +176 -0
  200. package/src/hooks/use-drag-action.ts +127 -0
  201. package/src/hooks/use-keyboard.ts +493 -95
  202. package/src/hooks/use-selection.ts +64 -0
  203. package/src/index.tsx +451 -6
  204. package/src/lib/active-placement-surface.ts +35 -0
  205. package/src/lib/ceiling-plan-snap.ts +24 -0
  206. package/src/lib/constants.ts +6 -2
  207. package/src/lib/contextual-help.test.ts +112 -0
  208. package/src/lib/contextual-help.ts +144 -0
  209. package/src/lib/continuation.ts +64 -0
  210. package/src/lib/direct-manipulation.test.ts +192 -0
  211. package/src/lib/direct-manipulation.ts +109 -0
  212. package/src/lib/editor-api.ts +50 -0
  213. package/src/lib/elevator-support.ts +96 -0
  214. package/src/lib/floorplan/apply-alignment.test.ts +25 -0
  215. package/src/lib/floorplan/apply-alignment.ts +117 -0
  216. package/src/lib/floorplan/floorplan-export.tsx +364 -0
  217. package/src/lib/floorplan/geometry.ts +53 -0
  218. package/src/lib/floorplan/index.ts +10 -0
  219. package/src/lib/floorplan/items.ts +5 -2
  220. package/src/lib/floorplan/plan-coords.ts +21 -0
  221. package/src/lib/floorplan/selection-tool.ts +40 -0
  222. package/src/lib/floorplan/stairs.ts +12 -1
  223. package/src/lib/fresh-planar-placement.test.ts +339 -0
  224. package/src/lib/fresh-planar-placement.ts +130 -0
  225. package/src/lib/glb-export.test.ts +441 -0
  226. package/src/lib/glb-export.ts +874 -0
  227. package/src/lib/history.ts +11 -1
  228. package/src/lib/interaction/hot-set.test.ts +133 -0
  229. package/src/lib/interaction/hot-set.ts +67 -0
  230. package/src/lib/interaction/overlay-policy.test.ts +51 -0
  231. package/src/lib/interaction/overlay-policy.ts +59 -0
  232. package/src/lib/interaction/scope.ts +211 -0
  233. package/src/lib/level-duplication.ts +54 -42
  234. package/src/lib/level-selection.ts +2 -2
  235. package/src/lib/material-paint.ts +227 -48
  236. package/src/lib/measurement-kind.test.ts +30 -0
  237. package/src/lib/measurement-kind.ts +19 -0
  238. package/src/lib/measurement-label.test.ts +47 -0
  239. package/src/lib/measurement-label.ts +68 -0
  240. package/src/lib/measurement-parser.ts +116 -0
  241. package/src/lib/measurements.test.ts +183 -0
  242. package/src/lib/measurements.ts +199 -0
  243. package/src/lib/paint-scope.test.ts +454 -0
  244. package/src/lib/paint-scope.ts +461 -0
  245. package/src/lib/placement-drag-release.ts +23 -0
  246. package/src/lib/placement-metadata.ts +29 -0
  247. package/src/lib/planar-cursor-placement.test.ts +100 -0
  248. package/src/lib/planar-cursor-placement.ts +42 -0
  249. package/src/lib/plugin-panels.test.ts +19 -0
  250. package/src/lib/plugin-panels.ts +91 -0
  251. package/src/lib/quick-measurement.test.ts +77 -0
  252. package/src/lib/quick-measurement.ts +109 -0
  253. package/src/lib/roof-duplication.ts +7 -7
  254. package/src/lib/roof-hover-outline-proxy.ts +22 -0
  255. package/src/lib/roof-wall-hit.ts +164 -0
  256. package/src/lib/scene-clipboard.test.ts +196 -0
  257. package/src/lib/scene-clipboard.ts +332 -0
  258. package/src/lib/scene.ts +40 -8
  259. package/src/lib/selection-routing.test.ts +298 -0
  260. package/src/lib/selection-routing.ts +175 -0
  261. package/src/lib/sfx/index.ts +1 -0
  262. package/src/lib/sfx/movement-tick.test.ts +65 -0
  263. package/src/lib/sfx/movement-tick.ts +18 -0
  264. package/src/lib/sfx-bus.ts +69 -10
  265. package/src/lib/sfx-player.test.ts +124 -0
  266. package/src/lib/sfx-player.ts +148 -55
  267. package/src/lib/site-boundary.ts +1 -0
  268. package/src/lib/slab-plan-snap.test.ts +93 -0
  269. package/src/lib/slab-plan-snap.ts +108 -0
  270. package/src/lib/snapping-mode.test.ts +138 -0
  271. package/src/lib/snapping-mode.ts +179 -0
  272. package/src/lib/stair-duplication.ts +4 -4
  273. package/src/lib/stair-levels.test.ts +146 -0
  274. package/src/lib/stair-levels.ts +177 -0
  275. package/src/lib/surface-plan-snap.test.ts +71 -0
  276. package/src/lib/surface-plan-snap.ts +256 -0
  277. package/src/lib/use-linear-display.ts +40 -0
  278. package/src/lib/world-grid-snap.ts +231 -0
  279. package/src/lib/zone-content.ts +130 -0
  280. package/src/store/use-alignment-guides.ts +21 -0
  281. package/src/store/use-direct-manipulation-feedback.ts +20 -0
  282. package/src/store/use-editor.tsx +767 -114
  283. package/src/store/use-facing-pose.ts +44 -0
  284. package/src/store/use-fence-curve-draft.ts +21 -0
  285. package/src/store/use-floorplan-draft-preview.ts +101 -0
  286. package/src/store/use-floorplan-marquee.ts +50 -0
  287. package/src/store/use-interaction-scope.test.ts +186 -0
  288. package/src/store/use-interaction-scope.ts +132 -0
  289. package/src/store/use-measurement-draft.test.ts +530 -0
  290. package/src/store/use-measurement-draft.ts +543 -0
  291. package/src/store/use-opening-guides.ts +41 -0
  292. package/src/store/use-placement-preview.ts +39 -0
  293. package/src/store/use-quick-measurement-hud.test.ts +53 -0
  294. package/src/store/use-quick-measurement-hud.ts +77 -0
  295. package/src/store/use-segment-draft-chain.ts +28 -0
  296. package/src/store/use-stair-build-preview.ts +43 -0
  297. package/src/store/use-wall-move-ghosts.ts +36 -0
  298. package/src/store/use-wall-snap-indicator.ts +34 -0
  299. package/src/components/editor/first-person/bvh-ecctrl.tsx +0 -860
  300. package/src/components/editor/preset-thumbnail-generator.tsx +0 -125
  301. package/src/components/editor-2d/renderers/floorplan-roof-layer.tsx +0 -113
  302. package/src/components/tools/building/move-building-tool.tsx +0 -157
  303. package/src/components/tools/ceiling/ceiling-boundary-editor.tsx +0 -43
  304. package/src/components/tools/ceiling/ceiling-hole-editor.tsx +0 -49
  305. package/src/components/tools/ceiling/ceiling-tool.tsx +0 -465
  306. package/src/components/tools/ceiling/move-ceiling-tool.tsx +0 -264
  307. package/src/components/tools/column/column-tool.tsx +0 -97
  308. package/src/components/tools/column/move-column-tool.tsx +0 -105
  309. package/src/components/tools/door/door-math.ts +0 -110
  310. package/src/components/tools/door/door-tool.tsx +0 -324
  311. package/src/components/tools/door/move-door-tool.tsx +0 -412
  312. package/src/components/tools/fence/curve-fence-tool.tsx +0 -178
  313. package/src/components/tools/fence/fence-tool.tsx +0 -346
  314. package/src/components/tools/fence/move-fence-endpoint-tool.tsx +0 -441
  315. package/src/components/tools/fence/move-fence-tool.tsx +0 -302
  316. package/src/components/tools/item/item-tool.tsx +0 -26
  317. package/src/components/tools/roof/move-roof-tool.tsx +0 -364
  318. package/src/components/tools/slab/move-slab-tool.tsx +0 -182
  319. package/src/components/tools/slab/slab-boundary-editor.tsx +0 -43
  320. package/src/components/tools/slab/slab-hole-editor.tsx +0 -49
  321. package/src/components/tools/slab/slab-tool.tsx +0 -322
  322. package/src/components/tools/spawn/move-spawn-tool.tsx +0 -101
  323. package/src/components/tools/spawn/spawn-tool.tsx +0 -130
  324. package/src/components/tools/wall/curve-wall-tool.tsx +0 -178
  325. package/src/components/tools/wall/move-wall-endpoint-tool.tsx +0 -426
  326. package/src/components/tools/wall/move-wall-tool.tsx +0 -358
  327. package/src/components/tools/wall/wall-tool.tsx +0 -332
  328. package/src/components/tools/window/move-window-tool.tsx +0 -447
  329. package/src/components/tools/window/window-math.ts +0 -117
  330. package/src/components/tools/window/window-tool.tsx +0 -332
  331. package/src/components/ui/helpers/ceiling-helper.tsx +0 -20
  332. package/src/components/ui/helpers/slab-helper.tsx +0 -20
  333. package/src/components/ui/helpers/wall-helper.tsx +0 -20
  334. package/src/components/ui/panels/ceiling-panel.tsx +0 -249
  335. package/src/components/ui/panels/column-panel.tsx +0 -759
  336. package/src/components/ui/panels/door-panel.tsx +0 -1299
  337. package/src/components/ui/panels/fence-panel.tsx +0 -222
  338. package/src/components/ui/panels/item-panel.tsx +0 -306
  339. package/src/components/ui/panels/paint-panel.tsx +0 -163
  340. package/src/components/ui/panels/presets/presets-popover.tsx +0 -511
  341. package/src/components/ui/panels/roof-panel.tsx +0 -280
  342. package/src/components/ui/panels/roof-segment-panel.tsx +0 -311
  343. package/src/components/ui/panels/slab-panel.tsx +0 -250
  344. package/src/components/ui/panels/spawn-panel.tsx +0 -161
  345. package/src/components/ui/panels/stair-panel.tsx +0 -577
  346. package/src/components/ui/panels/stair-segment-panel.tsx +0 -325
  347. package/src/components/ui/panels/wall-panel.tsx +0 -273
  348. package/src/components/ui/panels/window-panel.tsx +0 -968
  349. package/src/contexts/presets-context.tsx +0 -121
  350. package/src/hooks/use-contextual-tools.ts +0 -61
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pascal-app/editor",
3
- "version": "0.8.0",
3
+ "version": "0.9.2",
4
4
  "description": "Pascal building editor component",
5
5
  "type": "module",
6
6
  "exports": {
@@ -8,24 +8,25 @@
8
8
  "./catalog": "./src/components/ui/item-catalog/catalog-items.tsx"
9
9
  },
10
10
  "scripts": {
11
- "check-types": "tsc --noEmit"
11
+ "check-types": "tsgo --noEmit"
12
12
  },
13
13
  "peerDependencies": {
14
- "@pascal-app/core": "^0.7.0",
15
- "@pascal-app/viewer": "^0.7.0",
14
+ "@pascal-app/core": "^0.9.2",
15
+ "@pascal-app/viewer": "^0.9.2",
16
16
  "@react-three/drei": "^10",
17
17
  "@react-three/fiber": "^9",
18
18
  "next": ">=15",
19
19
  "react": "^18 || ^19",
20
20
  "react-dom": "^18 || ^19",
21
- "three": "^0.184"
21
+ "three": "^0.185"
22
22
  },
23
23
  "dependencies": {
24
24
  "@dnd-kit/core": "^6.3.1",
25
25
  "@dnd-kit/sortable": "^10.0.0",
26
26
  "@dnd-kit/utilities": "^3.2.2",
27
27
  "@iconify/react": "^6.0.2",
28
- "@number-flow/react": "^0.5.14",
28
+ "@number-flow/react": "^0.6.0",
29
+ "@pascal-app/lingo": "^0.2.0",
29
30
  "@radix-ui/react-alert-dialog": "^1.1.15",
30
31
  "@radix-ui/react-context-menu": "^2.2.16",
31
32
  "@radix-ui/react-dialog": "^1.1.15",
@@ -38,30 +39,31 @@
38
39
  "@radix-ui/react-switch": "^1.2.6",
39
40
  "@radix-ui/react-tabs": "^1.1.13",
40
41
  "@radix-ui/react-tooltip": "^1.2.8",
41
- "@react-three/uikit-lucide": "^1.0.62",
42
- "@visual-json/react": "latest",
42
+ "@visual-json/react": "^0.4.0",
43
43
  "class-variance-authority": "^0.7.1",
44
44
  "clsx": "^2.1.1",
45
45
  "cmdk": "^1.1.1",
46
46
  "howler": "^2.2.4",
47
+ "jspdf": "^4.2.1",
47
48
  "lucide-react": "^1.7.0",
48
49
  "mitt": "^3.0.1",
49
50
  "motion": "^12.34.3",
50
51
  "nanoid": "^5.1.6",
52
+ "svg2pdf.js": "^2.7.0",
51
53
  "tailwind-merge": "^3.5.0",
54
+ "three-mesh-bvh": "~0.9.8",
52
55
  "zod": "^4.3.6",
53
- "zustand": "^5.0.11",
54
- "three-mesh-bvh": "~0.9.8"
56
+ "zustand": "^5.0.11"
55
57
  },
56
58
  "devDependencies": {
57
- "@pascal-app/core": "^0.7.0",
58
- "@pascal-app/viewer": "^0.7.0",
59
+ "@pascal-app/core": "^0.9.2",
60
+ "@pascal-app/viewer": "^0.9.2",
59
61
  "@pascal/typescript-config": "*",
60
62
  "@types/bun": "^1.3.0",
61
63
  "@types/howler": "^2.2.12",
62
64
  "@types/react": "19.2.2",
63
65
  "@types/react-dom": "19.2.2",
64
66
  "@types/three": "^0.184.0",
65
- "typescript": "6.0.2"
67
+ "typescript": "6.0.3"
66
68
  }
67
69
  }
@@ -0,0 +1,168 @@
1
+ 'use client'
2
+
3
+ import { type AlignmentGuide, sceneRegistry } from '@pascal-app/core'
4
+ import { useViewer } from '@pascal-app/viewer'
5
+ import { Html } from '@react-three/drei'
6
+ import { useFrame } from '@react-three/fiber'
7
+ import { memo, useMemo, useRef } from 'react'
8
+ import { BoxGeometry, CircleGeometry, type Group, Vector3 } from 'three'
9
+ import { MeshBasicNodeMaterial } from 'three/webgpu'
10
+ import { EDITOR_LAYER } from '../../lib/constants'
11
+ import useAlignmentGuides from '../../store/use-alignment-guides'
12
+ import { formatMeasurement } from './measurement-pill'
13
+
14
+ /**
15
+ * Figma-style alignment guides for the 3D editor — the spatial twin of
16
+ * `FloorplanAlignmentGuideLayer`. Subscribes to the shared
17
+ * `useAlignmentGuides` store (published by the move / placement / wall tools
18
+ * during a drag) and draws each guide as a dashed ribbon on the floor with a
19
+ * flat circular marker at each endpoint and a distance pill.
20
+ *
21
+ * The dashes + dots lie flat on the floor plane (XZ) — a ground ribbon, like
22
+ * the design reference — so they're real 3D geometry, not screen billboards.
23
+ * Only the distance pill is screen-space (`<Html>`).
24
+ *
25
+ * Guide coordinates are XZ meters in the WORLD frame — alignment now resolves
26
+ * on the world axes (via `resolveAlignmentForActiveBuilding`) so the guides
27
+ * stay parallel to the visible world grid even when the active building is
28
+ * rotated. This layer is mounted OUTSIDE the building-local ToolManager group
29
+ * for the same reason. The whole ribbon is lifted to the active level's WORLD
30
+ * Y each frame so it lies on the floor being edited — not the building base —
31
+ * when floors are stacked.
32
+ */
33
+
34
+ const LINE_COLOR = 0x81_8c_f8 // indigo-400 — matches the editor's selection accent (box-select / wall highlights)
35
+ const PILL_COLOR = '#6366f1' // indigo-500 — same hue, darker for white-text contrast
36
+ const GUIDE_Y = 0.03 // small lift so guides read above the floor grid
37
+ const DASH_LEN = 0.18 // world-meter dash length
38
+ const DASH_GAP = 0.12 // world-meter gap between dashes
39
+ const LINE_WIDTH = 0.06 // world-meter ribbon thickness
40
+ const DOT_RADIUS = 0.11 // world-meter radius of the endpoint markers
41
+ const MAX_DASHES = 80 // cap so a very long guide can't spawn thousands of quads
42
+
43
+ // Shared resources — one violet material + unit geometries scaled per
44
+ // instance, so guide churn during a drag doesn't rebuild GPU buffers.
45
+ const guideMaterial = new MeshBasicNodeMaterial({
46
+ color: LINE_COLOR,
47
+ depthTest: false,
48
+ depthWrite: false,
49
+ toneMapped: false,
50
+ transparent: true,
51
+ })
52
+ const DOT_COLOR = 0x22_c5_5e // green-500 — matches the wall-snap marker
53
+ const dotMaterial = new MeshBasicNodeMaterial({
54
+ color: DOT_COLOR,
55
+ depthTest: false,
56
+ depthWrite: false,
57
+ toneMapped: false,
58
+ transparent: true,
59
+ })
60
+ const DASH_GEOMETRY = new BoxGeometry(1, 1, 1)
61
+ const DOT_GEOMETRY = new CircleGeometry(1, 24)
62
+
63
+ type Vec3 = [number, number, number]
64
+
65
+ export const Alignment3DGuideLayer = memo(function Alignment3DGuideLayer() {
66
+ const guides = useAlignmentGuides((s) => s.guides)
67
+ const levelId = useViewer((s) => s.selection.levelId)
68
+ const unit = useViewer((s) => s.unit)
69
+ const groupRef = useRef<Group>(null)
70
+
71
+ // Guides carry only XZ in WORLD coords; their Y has to track the active
72
+ // level's world Y so the ground ribbon lies on the floor being edited,
73
+ // not the building base. `getWorldPosition` walks the level mesh's
74
+ // parents (building / site) so it stays correct even if the building has
75
+ // a Y offset.
76
+ const worldYWork = useMemo(() => new Vector3(), [])
77
+ useFrame(() => {
78
+ const group = groupRef.current
79
+ if (!group) return
80
+ const levelMesh = levelId ? sceneRegistry.nodes.get(levelId) : null
81
+ group.position.y = levelMesh ? levelMesh.getWorldPosition(worldYWork).y : 0
82
+ })
83
+
84
+ if (guides.length === 0) return null
85
+ return (
86
+ <group ref={groupRef}>
87
+ {guides.map((guide, i) => (
88
+ <GuideLine guide={guide} key={i} unit={unit} />
89
+ ))}
90
+ </group>
91
+ )
92
+ })
93
+
94
+ function GuideLine({ guide, unit }: { guide: AlignmentGuide; unit: 'metric' | 'imperial' }) {
95
+ const { x: fx, z: fz } = guide.from
96
+ const { x: tx, z: tz } = guide.to
97
+ const distLabel = formatMeasurement(guide.distance, unit)
98
+
99
+ // Lay out the dash centres along the from→to direction. The ribbon
100
+ // stretches the dash period up if the line is long enough to exceed the
101
+ // dash cap, so it always reads as a continuous dashed line.
102
+ const { dashes, angleY } = useMemo(() => {
103
+ const dx = tx - fx
104
+ const dz = tz - fz
105
+ const length = Math.hypot(dx, dz)
106
+ const angle = -Math.atan2(dz, dx)
107
+ if (length < 1e-4) return { dashes: [] as Vec3[], angleY: angle }
108
+ const ux = dx / length
109
+ const uz = dz / length
110
+ const period = Math.max(DASH_LEN + DASH_GAP, length / MAX_DASHES)
111
+ const centres: Vec3[] = []
112
+ for (let d = period / 2; d - DASH_LEN / 2 <= length; d += period) {
113
+ centres.push([fx + ux * d, GUIDE_Y, fz + uz * d])
114
+ }
115
+ return { dashes: centres, angleY: angle }
116
+ }, [fx, fz, tx, tz])
117
+
118
+ const mid: Vec3 = [(fx + tx) / 2, GUIDE_Y, (fz + tz) / 2]
119
+
120
+ return (
121
+ <>
122
+ {dashes.map((centre, i) => (
123
+ <mesh
124
+ geometry={DASH_GEOMETRY}
125
+ key={i}
126
+ layers={EDITOR_LAYER}
127
+ material={guideMaterial}
128
+ position={centre}
129
+ renderOrder={1000}
130
+ rotation={[0, angleY, 0]}
131
+ scale={[DASH_LEN, 0.002, LINE_WIDTH]}
132
+ />
133
+ ))}
134
+ <Dot position={[fx, GUIDE_Y + 0.001, fz]} />
135
+ <Dot position={[tx, GUIDE_Y + 0.001, tz]} />
136
+ {guide.distance > 1e-4 && (
137
+ <Html
138
+ center
139
+ position={mid}
140
+ style={{ pointerEvents: 'none', userSelect: 'none' }}
141
+ zIndexRange={[20, 0]}
142
+ >
143
+ <div
144
+ className="whitespace-nowrap rounded-[3px] px-[5px] py-[2px] font-medium font-sans text-[11px] text-white"
145
+ style={{ backgroundColor: PILL_COLOR }}
146
+ >
147
+ {distLabel}
148
+ </div>
149
+ </Html>
150
+ )}
151
+ </>
152
+ )
153
+ }
154
+
155
+ /** Flat circular marker lying on the floor plane at a guide endpoint. */
156
+ function Dot({ position }: { position: Vec3 }) {
157
+ return (
158
+ <mesh
159
+ geometry={DOT_GEOMETRY}
160
+ layers={EDITOR_LAYER}
161
+ material={dotMaterial}
162
+ position={position}
163
+ renderOrder={1001}
164
+ rotation={[-Math.PI / 2, 0, 0]}
165
+ scale={[DOT_RADIUS, DOT_RADIUS, DOT_RADIUS]}
166
+ />
167
+ )
168
+ }
@@ -0,0 +1,47 @@
1
+ 'use client'
2
+
3
+ import { useScene } from '@pascal-app/core'
4
+ import { useViewer } from '@pascal-app/viewer'
5
+ import { useThree } from '@react-three/fiber'
6
+ import { useEffect, useRef } from 'react'
7
+ import { exportSceneToGlb, nextFrames } from '../../lib/glb-export'
8
+
9
+ export function BakeExporter({
10
+ active,
11
+ onComplete,
12
+ onError,
13
+ }: {
14
+ active: boolean
15
+ onComplete: (buffer: ArrayBuffer) => void
16
+ onError: (message: string) => void
17
+ }) {
18
+ const scene = useThree((s) => s.scene)
19
+ const doneRef = useRef(false)
20
+ useEffect(() => {
21
+ if (!(active && !doneRef.current)) return
22
+ doneRef.current = true
23
+ const run = async () => {
24
+ try {
25
+ // Signal export so instanced kinds (trees/flowers/grass) swap their
26
+ // invisible proxy for real, exportable geometry, then wait for the
27
+ // commit before cloning the scene graph.
28
+ useViewer.getState().setExporting(true)
29
+ await nextFrames()
30
+ const sceneGroup = scene.getObjectByName('scene-renderer')
31
+ if (!sceneGroup) throw new Error('scene-renderer group not found')
32
+ const buffer = await exportSceneToGlb(sceneGroup, useScene.getState().nodes)
33
+ onComplete(buffer)
34
+ } catch (err) {
35
+ // The bake worker relays page console output into the job's error
36
+ // trail; the message alone rarely localises an exporter crash, so
37
+ // surface the full stack here.
38
+ console.error('[bake-exporter]', err instanceof Error ? (err.stack ?? err.message) : err)
39
+ onError(err instanceof Error ? err.message : String(err))
40
+ } finally {
41
+ useViewer.getState().setExporting(false)
42
+ }
43
+ }
44
+ void run()
45
+ }, [active, scene, onComplete, onError])
46
+ return null
47
+ }