@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.
- package/package.json +9 -15
- package/src/components/editor/action-menu-button.tsx +1 -1
- package/src/components/editor/alignment-3d-guide-layer.tsx +1 -1
- package/src/components/editor/custom-camera-controls.tsx +101 -45
- package/src/components/editor/duplicate-node.ts +2 -1
- package/src/components/editor/editor-layout-v2.tsx +1 -1
- package/src/components/editor/elevation-3d-guide-layer.tsx +1 -1
- package/src/components/editor/first-person-controls.tsx +20 -1983
- package/src/components/editor/fit-scene-framing.test.ts +318 -0
- package/src/components/editor/fit-scene-framing.ts +142 -0
- package/src/components/editor/floating-action-menu.tsx +5 -3
- package/src/components/editor/floating-building-action-menu.tsx +1 -1
- package/src/components/editor/floor-openings-overlay.tsx +1 -1
- package/src/components/editor/floor-region-controls.tsx +8 -4
- package/src/components/editor/floorplan-navigation-presentation.test.ts +0 -40
- package/src/components/editor/floorplan-navigation-presentation.ts +0 -66
- package/src/components/editor/floorplan-panel.tsx +199 -30
- package/src/components/editor/floorplan-wall-typing-keys.test.tsx +152 -0
- package/src/components/editor/floorplan-wall-typing-keys.ts +79 -0
- package/src/components/editor/follow-pascal.test.tsx +1 -2
- package/src/components/editor/follow-pascal.tsx +1 -1
- package/src/components/editor/footprint-height-handle.tsx +2 -2
- package/src/components/editor/group-actions.ts +1 -2
- package/src/components/editor/group-floating-action-menu.tsx +1 -1
- package/src/components/editor/group-move-3d.ts +1 -2
- package/src/components/editor/group-rotate-handle.tsx +1 -2
- package/src/components/editor/group-transform-shared.ts +3 -1
- package/src/components/editor/handles/use-handle-drag.ts +1 -2
- package/src/components/editor/index.tsx +43 -13
- package/src/components/editor/inspector-extension-actions.tsx +1 -1
- package/src/components/editor/measurement-pill.tsx +1 -1
- package/src/components/editor/node-arrow-handles.tsx +2 -2
- package/src/components/editor/open-wall-ends-3d-layer.tsx +2 -3
- package/src/components/editor/open-wall-ends-hint.tsx +1 -1
- package/src/components/editor/opening-guides-3d-layer.tsx +1 -1
- package/src/components/editor/quick-measurement-card.tsx +1 -1
- package/src/components/editor/room-controls.tsx +10 -6
- package/src/components/editor/room-handles-2d.tsx +3 -3
- package/src/components/editor/room-handles.tsx +4 -5
- package/src/components/editor/room-highlight.tsx +6 -105
- package/src/components/editor/room-labels.test.ts +8 -822
- package/src/components/editor/room-labels.tsx +41 -1670
- package/src/components/editor/room-webgpu-materials.test.ts +1 -1
- package/src/components/editor/selection-manager.tsx +5 -3
- package/src/components/editor/site-edge-labels.tsx +7 -3
- package/src/components/editor/snapshot-capture-overlay.tsx +2 -5
- package/src/components/editor/use-floorplan-background-placement.ts +2 -1
- package/src/components/editor/views/plugins-view.tsx +1 -1
- package/src/components/editor/views/view-bar.tsx +9 -9
- package/src/components/editor/wall-measurement-label.tsx +31 -15
- package/src/components/editor/wall-move-side-handles.tsx +11 -7
- package/src/components/editor/wall-pull-grip.tsx +2 -2
- package/src/components/editor/wall-region-handles.tsx +2 -2
- package/src/components/editor/wall-snap-beacon-layer.tsx +53 -32
- package/src/components/editor-2d/floorplan-group-move.tsx +3 -4
- package/src/components/editor-2d/floorplan-measurement-tool-layer.tsx +13 -13
- package/src/components/editor-2d/floorplan-open-wall-ends-layer.tsx +2 -3
- package/src/components/editor-2d/floorplan-registry-action-menu.tsx +2 -1
- package/src/components/editor-2d/floorplan-registry-move-overlay.tsx +23 -6
- package/src/components/editor-2d/renderers/floorplan-annotation-layout.test.ts +0 -37
- package/src/components/editor-2d/renderers/floorplan-annotation-layout.ts +0 -30
- package/src/components/editor-2d/renderers/floorplan-dimension-edit-overlay.tsx +13 -3
- package/src/components/editor-2d/renderers/floorplan-draft-measurement.tsx +7 -1
- package/src/components/editor-2d/renderers/floorplan-placement-preview-layer.tsx +14 -3
- package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.test.tsx +35 -0
- package/src/components/editor-2d/renderers/floorplan-placement-typing-hud.tsx +65 -0
- package/src/components/editor-2d/renderers/floorplan-registry-layer.test.ts +30 -10
- package/src/components/editor-2d/renderers/floorplan-registry-layer.tsx +39 -35
- package/src/components/systems/roof/roof-edit-system.test.tsx +15 -1
- package/src/components/systems/roof/roof-edit-system.tsx +33 -21
- package/src/components/tools/distribution/distribution-run-tool.test.tsx +371 -3
- package/src/components/tools/distribution/distribution-run-tool.tsx +151 -33
- package/src/components/tools/item/move-tool.tsx +1 -6
- package/src/components/tools/item/placement-history.test.tsx +1 -1
- package/src/components/tools/item/use-placement-coordinator.tsx +3 -4
- package/src/components/tools/paint-region/wall-paint-region-tool.tsx +7 -3
- package/src/components/tools/registry/move-registry-node-tool.test.ts +42 -1
- package/src/components/tools/registry/move-registry-node-tool.tsx +39 -16
- package/src/components/tools/shared/cursor-sphere.tsx +1 -1
- package/src/components/tools/shared/draft-measurement-label.tsx +1 -1
- package/src/components/tools/shared/placement-box.tsx +2 -6
- package/src/components/tools/shared/placement-coordinate-input.tsx +94 -0
- package/src/components/tools/shared/placement-dimension-guides.tsx +1 -1
- package/src/components/tools/shared/segment-angle.ts +0 -4
- package/src/components/tools/site/terrain-brush-cursor.tsx +1 -1
- package/src/components/tools/tool-manager.tsx +1 -24
- package/src/components/tools/wall/wall-typed-entry.test.ts +99 -0
- package/src/components/tools/wall/wall-typed-entry.ts +70 -0
- package/src/components/ui/action-menu/camera-actions.tsx +2 -2
- package/src/components/ui/action-menu/control-modes.tsx +1 -1
- package/src/components/ui/action-menu/follow-pascal-pill.tsx +1 -1
- package/src/components/ui/action-menu/index.tsx +3 -3
- package/src/components/ui/action-menu/measurement-control.tsx +3 -3
- package/src/components/ui/action-menu/placement.ts +0 -18
- package/src/components/ui/action-menu/point-ask-button.tsx +1 -1
- package/src/components/ui/action-menu/view-toggles.tsx +5 -5
- package/src/components/ui/controls/finish-swatch.tsx +1 -1
- package/src/components/ui/controls/material-paint-panel.tsx +2 -2
- package/src/components/ui/controls/scene-material-list.tsx +2 -2
- package/src/components/ui/controls/select-control.tsx +1 -1
- package/src/components/ui/controls/slider-control.tsx +18 -6
- package/src/components/ui/controls/terrain-sculpt-panel.tsx +1 -1
- package/src/components/ui/controls/tool-options-panel.tsx +74 -44
- package/src/components/ui/floating-level-selector.tsx +3 -3
- package/src/components/ui/helpers/contextual-helper-panel.tsx +1 -1
- package/src/components/ui/helpers/helper-manager.test.tsx +54 -1
- package/src/components/ui/helpers/helper-manager.tsx +55 -1
- package/src/components/ui/level-duplicate-dialog.tsx +1 -1
- package/src/components/ui/panels/collections/collections-popover.tsx +2 -2
- package/src/components/ui/panels/floor-foundation-panel.tsx +3 -3
- package/src/components/ui/panels/floor-opening-panel.tsx +5 -5
- package/src/components/ui/panels/mobile-selection-bar.tsx +28 -24
- package/src/components/ui/panels/multi-height-mode.tsx +3 -3
- package/src/components/ui/panels/multi-selection-panel.tsx +1 -1
- package/src/components/ui/panels/node-display.ts +1 -1
- package/src/components/ui/panels/panel-manager.tsx +5 -3
- package/src/components/ui/panels/panel-wrapper.tsx +42 -19
- package/src/components/ui/panels/parametric-inspector.tsx +1 -1
- package/src/components/ui/panels/room-construction-rows.tsx +7 -7
- package/src/components/ui/panels/room-name-options.ts +1 -5
- package/src/components/ui/panels/room-openings-field.tsx +1 -1
- package/src/components/ui/panels/room-panel.tsx +7 -9
- package/src/components/ui/primitives/color-dot.tsx +2 -2
- package/src/components/ui/primitives/opacity-control.tsx +2 -2
- package/src/components/ui/primitives/sidebar.tsx +3 -3
- package/src/components/ui/right-stack.test.ts +13 -6
- package/src/components/ui/right-stack.tsx +22 -11
- package/src/components/ui/sidebar/icon-rail.tsx +1 -1
- package/src/components/ui/sidebar/panels/items-panel/function-tree-panel.tsx +1 -1
- package/src/components/ui/sidebar/panels/settings-panel/audio-settings-dialog.tsx +2 -2
- package/src/components/ui/sidebar/panels/settings-panel/construction-animation-setting.tsx +1 -1
- package/src/components/ui/sidebar/panels/settings-panel/index.tsx +2 -2
- package/src/components/ui/sidebar/panels/settings-panel/keyboard-shortcuts-dialog.tsx +1 -1
- package/src/components/ui/sidebar/panels/settings-panel/load-build-dialog.tsx +2 -6
- package/src/components/ui/sidebar/panels/settings-panel/print-export-button.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/building-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/ceiling-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/index.tsx +3 -10
- package/src/components/ui/sidebar/panels/site-panel/inline-rename-input.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/level-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/roof-tree-node.tsx +46 -7
- package/src/components/ui/sidebar/panels/site-panel/slab-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/tree-node-actions.tsx +1 -1
- package/src/components/ui/sidebar/panels/site-panel/tree-node-drag.tsx +14 -5
- package/src/components/ui/sidebar/panels/site-panel/unit-tree-node.tsx +2 -2
- package/src/components/ui/sidebar/panels/site-panel/zone-tree-node.tsx +1 -1
- package/src/components/ui/sidebar/panels/zone-panel/index.tsx +3 -3
- package/src/components/ui/sidebar/tab-bar.tsx +1 -1
- package/src/components/ui/wall-type/wall-type-editor-dialog.tsx +2 -2
- package/src/components/ui/wall-type/wall-type-menu.tsx +1 -1
- package/src/components/viewer-overlay.tsx +1 -2
- package/src/hooks/use-auto-frame.ts +1 -2
- package/src/hooks/use-keyboard.ts +1 -2
- package/src/hooks/use-selected-room.ts +5 -7
- package/src/i18n/floor-footprint-name.ts +1 -1
- package/src/i18n/locales/en/messages.po +1036 -306
- package/src/i18n/locales/en/messages.ts +1 -1
- package/src/i18n/locales/en-XA/messages.ts +1 -1
- package/src/i18n/locales/es/messages.po +2267 -439
- package/src/i18n/locales/fr/messages.po +2267 -439
- package/src/i18n/locales/ja/messages.po +2267 -439
- package/src/i18n/locales/zh-CN/messages.po +2267 -439
- package/src/i18n/locales.test.ts +1 -1
- package/src/index.tsx +183 -178
- package/src/lib/below-grade.test.tsx +4 -4
- package/src/lib/camera-facing.test.ts +1 -1
- package/src/lib/camera-facing.ts +2 -3
- package/src/lib/contextual-help.ts +6 -0
- package/src/lib/editor-level-display.ts +1 -1
- package/src/lib/elevation-guides.ts +21 -6
- package/src/lib/elevator-support.ts +1 -72
- package/src/lib/floor-footprints.test.ts +3 -3
- package/src/lib/floor-footprints.ts +1 -9
- package/src/lib/floor-foundation-support.test.ts +8 -3
- package/src/lib/floor-opening-draft.ts +2 -2
- package/src/lib/floor-region-session.ts +1 -1
- package/src/lib/floorplan/annotation-visibility.test.ts +1 -1
- package/src/lib/floorplan/annotation-visibility.ts +1 -1
- package/src/lib/floorplan/floorplan-export.test.ts +1 -1
- package/src/lib/floorplan/floorplan-export.tsx +8 -11
- package/src/lib/floorplan/floorplan-extension.ts +4 -157
- package/src/lib/floorplan/floorplan-mode.ts +2 -1
- package/src/lib/floorplan/floorplan-pdfkit-renderer.test.ts +1 -1
- package/src/lib/floorplan/floorplan-pdfkit-renderer.ts +8 -6
- package/src/lib/floorplan/floorplan-plugin-install.test.tsx +3 -4
- package/src/lib/floorplan/geometry.ts +2 -112
- package/src/lib/floorplan/index.ts +0 -9
- package/src/lib/floorplan/items.ts +2 -1
- package/src/lib/floorplan/open-wall-ends.ts +2 -1
- package/src/lib/floorplan/schedules.ts +6 -3
- package/src/lib/floorplan/sheet-export.ts +7 -3
- package/src/lib/floorplan/site-plan/site-parts.ts +7 -1
- package/src/lib/floorplan/site-plan/site-plan-layer.tsx +1 -1
- package/src/lib/follow-pascal-presentation.ts +1 -1
- package/src/lib/gesture-lifecycle.ts +3 -1
- package/src/lib/glb-export.ts +1 -1
- package/src/lib/interaction/scope.ts +1 -0
- package/src/lib/layer-thickness.ts +1 -1
- package/src/lib/level-selection.test.ts +18 -2
- package/src/lib/level-selection.ts +31 -8
- package/src/lib/linear-display.ts +1 -1
- package/src/lib/live-gesture-round-trip.test.ts +1 -1
- package/src/lib/material-paint.ts +1 -1
- package/src/lib/measurement-label.test.ts +1 -1
- package/src/lib/measurements.test.ts +7 -5
- package/src/lib/mezzanine-selection.test.ts +1 -1
- package/src/lib/node-action-movement.test.tsx +115 -0
- package/src/lib/node-action-movement.ts +2 -0
- package/src/lib/paint-region-mode.ts +1 -1
- package/src/lib/placement-metadata.ts +4 -0
- package/src/lib/point-ask/describe-target.ts +6 -8
- package/src/lib/point-ask/region.ts +1 -1
- package/src/lib/point-ask/session.ts +1 -2
- package/src/lib/print-shell-compiler.ts +12 -1
- package/src/lib/print-wall-solids.test.ts +11 -0
- package/src/lib/print-wall-solids.ts +9 -0
- package/src/lib/roof-duplication.test.ts +100 -0
- package/src/lib/roof-duplication.ts +30 -5
- package/src/lib/room-built-on.test.ts +2 -5
- package/src/lib/room-built-on.ts +1 -15
- package/src/lib/room-construction-commands.ts +3 -2
- package/src/lib/room-controls-phase6.test.ts +1 -1
- package/src/lib/room-handle-drag.ts +8 -37
- package/src/lib/room-name-catalog.test.ts +2 -1
- package/src/lib/room-name-messages.test.ts +2 -1
- package/src/lib/room-name-messages.ts +1 -118
- package/src/lib/room-name-storage.test.ts +2 -1
- package/src/lib/room-push-dimensions.test.ts +1 -1
- package/src/lib/room-selection-commands.ts +2 -2
- package/src/lib/room-selection.test.ts +6 -6
- package/src/lib/room-transform-session.ts +1 -2
- package/src/lib/room-zone-routing.ts +2 -2
- package/src/lib/scene-clipboard.ts +2 -1
- package/src/lib/selection-routing.test.ts +0 -28
- package/src/lib/selection-routing.ts +1 -40
- package/src/lib/sfx-bus.ts +8 -32
- package/src/lib/sfx-player.test.ts +72 -1
- package/src/lib/sfx-player.ts +49 -337
- package/src/lib/snapping-mode.test.ts +23 -1
- package/src/lib/viewer-selection.test.ts +38 -10
- package/src/lib/wall-pull.test.ts +1 -1
- package/src/lib/wall-pull.ts +1 -27
- package/src/lib/wall-region-list.ts +3 -1
- package/src/lib/window-interaction.test.ts +4 -2
- package/src/store/use-editor.tsx +22 -26
- package/src/store/use-floorplan-annotation-visibility.ts +5 -5
- package/src/store/use-placement-typing.test.ts +165 -0
- package/src/store/use-placement-typing.ts +186 -0
- package/src/store/use-wall-region-handles-selection.ts +1 -2
- package/src/components/editor/__bench__/room-label-placement.bench.ts +0 -108
- package/src/components/editor/first-person/build-collider-world.test.ts +0 -596
- package/src/components/editor/first-person/build-collider-world.ts +0 -549
- package/src/components/editor/first-person/ground-holes.test.ts +0 -128
- package/src/components/editor/first-person/ground-holes.ts +0 -130
- package/src/components/editor/first-person/mechanism-targets.test.ts +0 -162
- package/src/components/editor/first-person/mechanism-targets.ts +0 -88
- package/src/components/editor/first-person/terrain-collider.test.ts +0 -132
- package/src/components/editor/first-person/terrain-collider.ts +0 -212
- package/src/components/editor/floorplan-camera-sync.test.ts +0 -249
- package/src/components/editor/floorplan-camera-sync.ts +0 -213
- package/src/components/editor/localized-html.tsx +0 -22
- package/src/components/editor-2d/renderers/floorplan-dimension-renderer.test.tsx +0 -236
- package/src/components/editor-2d/renderers/floorplan-dimension-renderer.tsx +0 -708
- package/src/components/editor-2d/renderers/floorplan-geometry-renderer.test.tsx +0 -385
- package/src/components/editor-2d/renderers/floorplan-geometry-renderer.tsx +0 -670
- package/src/components/editor-2d/renderers/floorplan-label-angle.test.ts +0 -89
- package/src/components/editor-2d/renderers/floorplan-label-angle.ts +0 -106
- package/src/components/editor-2d/svg-paths.ts +0 -124
- package/src/components/tools/elevator/elevator-defaults.ts +0 -8
- package/src/components/tools/elevator/elevator-tool.tsx +0 -372
- package/src/components/tools/elevator/move-elevator-tool.tsx +0 -262
- package/src/components/ui/action-menu/action-button.tsx +0 -89
- package/src/components/ui/action-menu/follow-pascal-toggle.tsx +0 -42
- package/src/components/ui/primitives/button.tsx +0 -69
- package/src/components/ui/primitives/dropdown-menu.tsx +0 -232
- package/src/components/ui/primitives/popover.tsx +0 -42
- package/src/components/ui/primitives/switch.tsx +0 -29
- package/src/components/ui/primitives/tooltip.tsx +0 -57
- package/src/components/ui/scene-loader.tsx +0 -73
- package/src/components/viewer/floorplan-compass-button.tsx +0 -67
- package/src/components/viewer/floorplan-preview-geometry.test.ts +0 -107
- package/src/components/viewer/floorplan-preview-geometry.ts +0 -281
- package/src/components/viewer/floorplan-preview-navigation.test.ts +0 -43
- package/src/components/viewer/floorplan-preview-navigation.ts +0 -62
- package/src/components/viewer/floorplan-preview-visibility.test.ts +0 -35
- package/src/components/viewer/floorplan-preview-visibility.ts +0 -19
- package/src/components/viewer/floorplan-preview.tsx +0 -1065
- package/src/components/viewer/render-settings-menu.tsx +0 -294
- package/src/components/viewer/sky-control.tsx +0 -710
- package/src/components/viewer/use-viewer-camera-navigation-sync.ts +0 -140
- package/src/components/viewer/use-viewer-ui-sounds.test.ts +0 -15
- package/src/components/viewer/use-viewer-ui-sounds.ts +0 -46
- package/src/components/viewer/viewer-controls-bar.tsx +0 -496
- package/src/components/viewer/viewer-hover-label.tsx +0 -42
- package/src/components/viewer/viewer-rooms.tsx +0 -248
- package/src/components/viewer/viewer-scene-header.tsx +0 -286
- package/src/components/viewer/viewer-selection-manager.tsx +0 -124
- package/src/components/viewer/viewer-stage-modes.test.ts +0 -38
- package/src/components/viewer/viewer-stage-modes.ts +0 -49
- package/src/components/viewer/viewer-stage-switcher.tsx +0 -97
- package/src/components/viewer/viewer-stage.test.tsx +0 -47
- package/src/components/viewer/viewer-stage.tsx +0 -221
- package/src/components/walkthrough-hud.tsx +0 -193
- package/src/hooks/use-mobile.ts +0 -19
- package/src/i18n/level-name.ts +0 -39
- package/src/i18n/scene-theme-name.ts +0 -16
- package/src/lib/below-grade.ts +0 -133
- package/src/lib/camera-pose.test.ts +0 -237
- package/src/lib/camera-pose.ts +0 -172
- package/src/lib/door-interaction.ts +0 -102
- package/src/lib/floorplan/floorplan-extension.test.ts +0 -42
- package/src/lib/floorplan/floorplan-readonly.test.ts +0 -47
- package/src/lib/floorplan/floorplan-readonly.ts +0 -95
- package/src/lib/floorplan/marks.test.ts +0 -213
- package/src/lib/floorplan/marks.ts +0 -238
- package/src/lib/measurement-label.ts +0 -68
- package/src/lib/measurements.ts +0 -225
- package/src/lib/node-display-label.ts +0 -37
- package/src/lib/room-assembly-overlay.test.ts +0 -275
- package/src/lib/room-assembly-overlay.ts +0 -265
- package/src/lib/room-selection.ts +0 -417
- package/src/lib/scene-bounds.test.ts +0 -183
- package/src/lib/scene-bounds.ts +0 -169
- package/src/lib/typing-target.ts +0 -9
- package/src/lib/viewer-selection.ts +0 -595
- package/src/lib/window-interaction.ts +0 -142
- package/src/lib/zone-content.ts +0 -133
- package/src/store/camera-pose-store.test.ts +0 -29
- package/src/store/camera-pose-store.ts +0 -27
- package/src/store/navigation-sync-pose-store.test.ts +0 -34
- package/src/store/navigation-sync-pose-store.ts +0 -27
- package/src/store/use-audio.test.ts +0 -146
- package/src/store/use-audio.tsx +0 -169
- package/src/store/use-first-person-hud.ts +0 -40
- package/src/store/use-follow-pascal.test.ts +0 -62
- package/src/store/use-follow-pascal.ts +0 -53
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type AnyNode, type MessageDescriptor, type PascalI18n, scriptImages } from '@pascal-app/core'
|
|
2
|
-
import { displayRoomName } from '
|
|
2
|
+
import { displayRoomName } from '@pascal-app/viewer/ui'
|
|
3
3
|
|
|
4
4
|
export type NodeDisplay = {
|
|
5
5
|
icon: string
|
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
type DormerNode,
|
|
12
12
|
type ElevatorNode,
|
|
13
13
|
type FenceNode,
|
|
14
|
+
isMoveLocked,
|
|
15
|
+
isNodeDuplicable,
|
|
14
16
|
type ItemNode,
|
|
15
17
|
type RoofNode,
|
|
16
18
|
type RoofSegmentNode,
|
|
@@ -26,7 +28,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
|
|
|
26
28
|
import { useSelectedRoom, useZoneRoom } from '../../../hooks/use-selected-room'
|
|
27
29
|
import { FloorOpeningPanel } from './floor-opening-panel'
|
|
28
30
|
import { OpenRoomPanel, RoomPanel } from './room-panel'
|
|
29
|
-
import { useIsMobile } from '
|
|
31
|
+
import { useIsMobile } from '@pascal-app/viewer/ui'
|
|
30
32
|
import { shouldShowEditingControls } from '../../../lib/interaction/overlay-policy'
|
|
31
33
|
import { captureElementActionOrigin, completeElementAction } from '../../../lib/room-zone-routing'
|
|
32
34
|
import { sfxEmitter } from '../../../lib/sfx-bus'
|
|
@@ -155,9 +157,9 @@ function MobilePanelLayer({
|
|
|
155
157
|
<MobileSelectionBar
|
|
156
158
|
node={node}
|
|
157
159
|
onDelete={handleDelete}
|
|
158
|
-
onDuplicate={handleDuplicate}
|
|
160
|
+
onDuplicate={isNodeDuplicable(node) ? handleDuplicate : undefined}
|
|
159
161
|
onEdit={() => setIsSheetOpen((v) => !v)}
|
|
160
|
-
onMove={handleMove}
|
|
162
|
+
onMove={isMoveLocked(node) ? undefined : handleMove}
|
|
161
163
|
/>
|
|
162
164
|
)}
|
|
163
165
|
<MobilePanelSheet
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
useRef,
|
|
20
20
|
useState,
|
|
21
21
|
} from 'react'
|
|
22
|
-
import { useIsMobile } from '
|
|
22
|
+
import { useIsMobile } from '@pascal-app/viewer/ui'
|
|
23
23
|
import { NodeIconImage } from '../node-icon-image'
|
|
24
24
|
import { resolveActiveExtension, toggleCard } from '../../../lib/inspector-card-mode'
|
|
25
25
|
import { cn } from '../../../lib/utils'
|
|
@@ -45,7 +45,7 @@ function clamp(value: number, min: number, max: number): number {
|
|
|
45
45
|
* `data-viewer-bounds`) so it can't slide under the sidebar or top bar.
|
|
46
46
|
* Falls back to the viewport when the marker isn't found.
|
|
47
47
|
*/
|
|
48
|
-
function getDragBounds(el: HTMLElement | null): {
|
|
48
|
+
function getDragBounds(el: HTMLElement | null, inStack = false): {
|
|
49
49
|
left: number
|
|
50
50
|
top: number
|
|
51
51
|
right: number
|
|
@@ -56,7 +56,15 @@ function getDragBounds(el: HTMLElement | null): {
|
|
|
56
56
|
if (!rect) {
|
|
57
57
|
return { left: 0, top: 0, right: window.innerWidth, bottom: window.innerHeight }
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
const stack = inStack ? el?.closest('[data-right-stack]') : null
|
|
60
|
+
const stackRect = stack?.getBoundingClientRect()
|
|
61
|
+
const cardRect = stack?.querySelector('[data-right-stack-card]')?.getBoundingClientRect()
|
|
62
|
+
return {
|
|
63
|
+
left: rect.left,
|
|
64
|
+
top: stackRect ? stackRect.top - DRAG_MARGIN : rect.top,
|
|
65
|
+
right: rect.right,
|
|
66
|
+
bottom: cardRect && cardRect.height > 0 ? cardRect.top : rect.bottom,
|
|
67
|
+
}
|
|
60
68
|
}
|
|
61
69
|
|
|
62
70
|
/**
|
|
@@ -187,7 +195,7 @@ export function PanelWrapper({
|
|
|
187
195
|
if ((e.target as HTMLElement).closest('button, input, label')) return
|
|
188
196
|
const rect = panelRef.current?.getBoundingClientRect()
|
|
189
197
|
if (!rect) return
|
|
190
|
-
const bounds = getDragBounds(panelRef.current)
|
|
198
|
+
const bounds = getDragBounds(panelRef.current, inStack)
|
|
191
199
|
const base = offset ?? { x: 0, y: 0 }
|
|
192
200
|
dragRef.current = {
|
|
193
201
|
startX: e.clientX,
|
|
@@ -207,7 +215,7 @@ export function PanelWrapper({
|
|
|
207
215
|
setIsDragging(true)
|
|
208
216
|
e.currentTarget.setPointerCapture(e.pointerId)
|
|
209
217
|
},
|
|
210
|
-
[offset],
|
|
218
|
+
[offset, inStack],
|
|
211
219
|
)
|
|
212
220
|
|
|
213
221
|
const handleHeaderPointerMove = useCallback((e: React.PointerEvent<HTMLDivElement>) => {
|
|
@@ -238,22 +246,37 @@ export function PanelWrapper({
|
|
|
238
246
|
[handleCardToggle],
|
|
239
247
|
)
|
|
240
248
|
|
|
241
|
-
//
|
|
242
|
-
// collapsed — nudge it back inside the viewer bounds.
|
|
249
|
+
// Keep repositioned panels inside the available space as the card or viewer resizes.
|
|
243
250
|
useLayoutEffect(() => {
|
|
244
|
-
if (isMobile
|
|
251
|
+
if (isMobile) return
|
|
245
252
|
const el = panelRef.current
|
|
246
253
|
if (!el) return
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
254
|
+
const fit = () => {
|
|
255
|
+
const rect = el.getBoundingClientRect()
|
|
256
|
+
const bounds = getDragBounds(el, inStack)
|
|
257
|
+
const left = clamp(rect.left, bounds.left + DRAG_MARGIN, bounds.right - rect.width - DRAG_MARGIN)
|
|
258
|
+
const top = clamp(rect.top, bounds.top + DRAG_MARGIN, bounds.bottom - rect.height - DRAG_MARGIN)
|
|
259
|
+
const dx = left - rect.left
|
|
260
|
+
const dy = top - rect.top
|
|
261
|
+
if (Math.abs(dx) > 0.5 || Math.abs(dy) > 0.5) {
|
|
262
|
+
setOffset((prev) => ({ x: (prev?.x ?? 0) + dx, y: (prev?.y ?? 0) + dy }))
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
fit()
|
|
266
|
+
const resize = new ResizeObserver(fit)
|
|
267
|
+
resize.observe(el)
|
|
268
|
+
const stack = el.closest('[data-right-stack]')
|
|
269
|
+
if (stack) {
|
|
270
|
+
resize.observe(stack)
|
|
271
|
+
const card = stack.querySelector('[data-right-stack-card]')
|
|
272
|
+
if (card) resize.observe(card)
|
|
273
|
+
}
|
|
274
|
+
window.addEventListener('resize', fit)
|
|
275
|
+
return () => {
|
|
276
|
+
resize.disconnect()
|
|
277
|
+
window.removeEventListener('resize', fit)
|
|
255
278
|
}
|
|
256
|
-
}, [collapsed, isMobile])
|
|
279
|
+
}, [collapsed, isMobile, inStack])
|
|
257
280
|
|
|
258
281
|
return (
|
|
259
282
|
<div
|
|
@@ -264,7 +287,7 @@ export function PanelWrapper({
|
|
|
264
287
|
: inStack
|
|
265
288
|
? // In the shared right column: it grows down and scrolls on itself,
|
|
266
289
|
// leaving the shortcuts card below it its room (`right-stack.tsx`).
|
|
267
|
-
'pointer-events-auto flex max-h-
|
|
290
|
+
'pointer-events-auto flex max-h-[var(--inspector-available-height)] min-h-0 flex-[0_1_auto] flex-col overflow-hidden rounded-xl border border-border/50 bg-sidebar/95 shadow-2xl backdrop-blur-xl dark:text-foreground'
|
|
268
291
|
// Cap height at `100dvh - 154px` so a tall panel's bottom edge
|
|
269
292
|
// aligns flush with the top of the floating bottom action bar.
|
|
270
293
|
// Combined with `top-20` (80px), the panel's bottom sits at
|
|
@@ -291,7 +314,7 @@ export function PanelWrapper({
|
|
|
291
314
|
{!isMobile && (
|
|
292
315
|
<div
|
|
293
316
|
className={cn(
|
|
294
|
-
'relative flex select-none items-center justify-between px-3 py-3',
|
|
317
|
+
'relative flex shrink-0 select-none items-center justify-between px-3 py-3',
|
|
295
318
|
!collapsed && 'border-border/50 border-b',
|
|
296
319
|
isDragging ? 'cursor-grabbing' : 'cursor-grab',
|
|
297
320
|
)}
|
|
@@ -17,7 +17,7 @@ import { type ComponentType, lazy, Suspense, useCallback } from 'react'
|
|
|
17
17
|
import { resolveMoveActionNode } from '../../../lib/direct-manipulation'
|
|
18
18
|
import { commitParametricNodeFields } from '../../../lib/parametric-node-update'
|
|
19
19
|
import { sfxEmitter } from '../../../lib/sfx-bus'
|
|
20
|
-
import { collectZoneContentIds } from '
|
|
20
|
+
import { collectZoneContentIds } from '@pascal-app/viewer/ui'
|
|
21
21
|
import useEditor from '../../../store/use-editor'
|
|
22
22
|
import { IconRefImage } from '../icon-ref'
|
|
23
23
|
import { ActionButton, ActionGroup } from '../controls/action-button'
|
|
@@ -34,9 +34,9 @@ import {
|
|
|
34
34
|
roomFloorOwner,
|
|
35
35
|
roomFootprint,
|
|
36
36
|
} from '../../../lib/floor-footprints'
|
|
37
|
-
import { formatLinearMeasurement } from '
|
|
37
|
+
import { formatLinearMeasurement } from '@pascal-app/core'
|
|
38
38
|
import { startMezzanineDraft } from '../../../lib/mezzanine-draft'
|
|
39
|
-
import { resolveRoomAssemblyHeights } from '
|
|
39
|
+
import { resolveRoomAssemblyHeights } from '@pascal-app/viewer/ui'
|
|
40
40
|
import { type FloorChoice, roomBuiltOn, separateFloorSummary } from '../../../lib/room-built-on'
|
|
41
41
|
import type { RoomConstructionState } from '../../../lib/room-construction'
|
|
42
42
|
import { roomConstructionState } from '../../../lib/room-construction'
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
unlockRoomOutsideFaces,
|
|
59
59
|
} from '../../../lib/room-construction-commands'
|
|
60
60
|
import { ownFloorElevationBounds } from '../../../lib/room-handle-drag'
|
|
61
|
-
import type { RoomSelectionRecord } from '
|
|
61
|
+
import type { RoomSelectionRecord } from '@pascal-app/viewer/ui'
|
|
62
62
|
import { cn } from '../../../lib/utils'
|
|
63
63
|
import { roomPorchFramingCounts } from '../../../lib/room-construction'
|
|
64
64
|
import { applyRoomPlan } from '../../../lib/room-structure-commands'
|
|
@@ -70,16 +70,16 @@ import {
|
|
|
70
70
|
DropdownMenuItem,
|
|
71
71
|
DropdownMenuSeparator,
|
|
72
72
|
DropdownMenuTrigger,
|
|
73
|
-
} from '
|
|
74
|
-
import { Switch } from '
|
|
75
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '
|
|
73
|
+
} from '@pascal-app/viewer/ui'
|
|
74
|
+
import { Switch } from '@pascal-app/viewer/ui'
|
|
75
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@pascal-app/viewer/ui'
|
|
76
76
|
import { localizedFloorFootprintName } from '../../../i18n/floor-footprint-name'
|
|
77
77
|
import { messageWithSlot } from '../../../i18n/message-slot'
|
|
78
78
|
import { nodeLabel } from '../../../i18n/node-messages'
|
|
79
79
|
import { DeckBoardsFields } from './deck-boards-fields'
|
|
80
80
|
import { RoomOpeningsField } from './room-openings-field'
|
|
81
81
|
import { ShapeChoice } from './shape-choice'
|
|
82
|
-
import { displayRoomName } from '
|
|
82
|
+
import { displayRoomName } from '@pascal-app/viewer/ui'
|
|
83
83
|
|
|
84
84
|
/** The buttons a row offers — derived together with its presence. */
|
|
85
85
|
export function constructionActions(state: RoomConstructionState, part: RoomConstructionPart) {
|
|
@@ -4,11 +4,7 @@ import {
|
|
|
4
4
|
numberedRoomName,
|
|
5
5
|
type RoomNameSection,
|
|
6
6
|
} from '../../../lib/room-name-catalog'
|
|
7
|
-
import {
|
|
8
|
-
type DescriptorTranslator,
|
|
9
|
-
displayRoomName,
|
|
10
|
-
editedRoomName,
|
|
11
|
-
} from '../../../lib/room-name-messages'
|
|
7
|
+
import { type DescriptorTranslator, displayRoomName, editedRoomName } from '@pascal-app/viewer/ui'
|
|
12
8
|
import { renameRoom } from '../../../lib/room-structure-commands'
|
|
13
9
|
|
|
14
10
|
export type RoomNameOption = {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
useFloorEditSession,
|
|
12
12
|
} from '../../../lib/floor-edit-session'
|
|
13
13
|
import { type OpeningSurface, startOpeningDraft } from '../../../lib/floor-opening-draft'
|
|
14
|
-
import { formatAreaLabel } from '
|
|
14
|
+
import { formatAreaLabel } from '@pascal-app/core'
|
|
15
15
|
import { pill } from './room-construction-rows'
|
|
16
16
|
import { ShapeChoice } from './shape-choice'
|
|
17
17
|
|
|
@@ -17,11 +17,11 @@ import { type KeyboardEvent, useEffect, useId, useMemo, useRef, useState } from
|
|
|
17
17
|
import { startCeilingEdit } from '../../../lib/ceiling-edit-session'
|
|
18
18
|
import { resolveOverlayPolicy } from '../../../lib/interaction/overlay-policy'
|
|
19
19
|
import { finishScriptCode } from '../../../lib/geometry-script/finish-scripts'
|
|
20
|
-
import { formatAreaLabel, formatLinearMeasurement } from '
|
|
20
|
+
import { formatAreaLabel, formatLinearMeasurement } from '@pascal-app/core'
|
|
21
21
|
import { addMezzanineStairs } from '../../../lib/mezzanine-stairs'
|
|
22
22
|
import { roomFloorBase, roomRelativeFloorHeight } from '../../../lib/room-construction-commands'
|
|
23
23
|
import { mezzanineElevationBounds } from '../../../lib/room-handle-drag'
|
|
24
|
-
import type { RoomSelectionRecord } from '
|
|
24
|
+
import type { RoomSelectionRecord } from '@pascal-app/viewer/ui'
|
|
25
25
|
import {
|
|
26
26
|
baseRoomName,
|
|
27
27
|
type RoomNameSection,
|
|
@@ -39,9 +39,9 @@ import {
|
|
|
39
39
|
DropdownMenuItem,
|
|
40
40
|
DropdownMenuSeparator,
|
|
41
41
|
DropdownMenuTrigger,
|
|
42
|
-
} from '
|
|
42
|
+
} from '@pascal-app/viewer/ui'
|
|
43
43
|
import { ColorDot } from '../primitives/color-dot'
|
|
44
|
-
import { Popover, PopoverAnchor, PopoverContent } from '
|
|
44
|
+
import { Popover, PopoverAnchor, PopoverContent } from '@pascal-app/viewer/ui'
|
|
45
45
|
import { ShortcutToken } from '../primitives/shortcut-token'
|
|
46
46
|
import { PanelWrapper } from './panel-wrapper'
|
|
47
47
|
import { RoomOpeningsField } from './room-openings-field'
|
|
@@ -59,12 +59,10 @@ import {
|
|
|
59
59
|
type RoomNameOption,
|
|
60
60
|
roomNameOptions,
|
|
61
61
|
} from './room-name-options'
|
|
62
|
-
import { localizedLevelName } from '
|
|
62
|
+
import { localizedLevelName } from '@pascal-app/viewer/ui'
|
|
63
63
|
import { messageWithSlot } from '../../../i18n/message-slot'
|
|
64
|
-
import {
|
|
65
|
-
|
|
66
|
-
localizedRoomNameSections,
|
|
67
|
-
} from '../../../lib/room-name-messages'
|
|
64
|
+
import { displayRoomName } from '@pascal-app/viewer/ui'
|
|
65
|
+
import { localizedRoomNameSections } from '../../../lib/room-name-messages'
|
|
68
66
|
|
|
69
67
|
/** "Room · Ground floor", "Mezzanine · in Kitchen", "Room · not enclosed". */
|
|
70
68
|
export function roomKicker(
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
import { ZONE_COLOR_PALETTE } from '@pascal-app/core'
|
|
4
4
|
import { useState } from 'react'
|
|
5
5
|
import { cn } from '../../../lib/utils'
|
|
6
|
-
import { Popover, PopoverContent, PopoverTrigger } from '
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '
|
|
6
|
+
import { Popover, PopoverContent, PopoverTrigger } from '@pascal-app/viewer/ui'
|
|
7
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@pascal-app/viewer/ui'
|
|
8
8
|
|
|
9
9
|
export const PALETTE_COLORS = ZONE_COLOR_PALETTE
|
|
10
10
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Eye, EyeOff } from 'lucide-react'
|
|
4
4
|
import { useState } from 'react'
|
|
5
|
-
import { Button } from '
|
|
6
|
-
import { Popover, PopoverContent, PopoverTrigger } from '
|
|
5
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
6
|
+
import { Popover, PopoverContent, PopoverTrigger } from '@pascal-app/viewer/ui'
|
|
7
7
|
import { Slider } from '../../../components/ui/primitives/slider'
|
|
8
8
|
import { cn } from '../../../lib/utils'
|
|
9
9
|
|
|
@@ -6,7 +6,7 @@ import { PanelLeftIcon } from 'lucide-react'
|
|
|
6
6
|
import * as React from 'react'
|
|
7
7
|
import { create } from 'zustand'
|
|
8
8
|
import { persist } from 'zustand/middleware'
|
|
9
|
-
import { Button } from '
|
|
9
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
10
10
|
import { Input } from './../../../components/ui/primitives/input'
|
|
11
11
|
import { Separator } from './../../../components/ui/primitives/separator'
|
|
12
12
|
import {
|
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
TooltipContent,
|
|
23
23
|
TooltipProvider,
|
|
24
24
|
TooltipTrigger,
|
|
25
|
-
} from '
|
|
26
|
-
import { useIsMobile } from '
|
|
25
|
+
} from '@pascal-app/viewer/ui'
|
|
26
|
+
import { useIsMobile } from '@pascal-app/viewer/ui'
|
|
27
27
|
import { hydrationGatedStorage } from './../../../lib/hydration-gated-storage'
|
|
28
28
|
import { cn } from './../../../lib/utils'
|
|
29
29
|
|
|
@@ -14,16 +14,23 @@ test('the inspector keeps 180 px, or its own height if shorter, above the full c
|
|
|
14
14
|
).toEqual({ inspector: 0, card: 240 })
|
|
15
15
|
})
|
|
16
16
|
|
|
17
|
-
test('on a short window the
|
|
17
|
+
test('on a short window the help card scrolls to preserve editing space', () => {
|
|
18
18
|
expect(rightStackFloors({ ...tall, naturalHeight: 500, stackHeight: 400 })).toEqual({
|
|
19
|
-
inspector:
|
|
20
|
-
card:
|
|
19
|
+
inspector: 180,
|
|
20
|
+
card: 212,
|
|
21
21
|
})
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
test('
|
|
24
|
+
test('expanded hints cannot squeeze the inspector down to just its header', () => {
|
|
25
25
|
expect(rightStackFloors({ ...tall, naturalHeight: 500, stackHeight: 258 })).toEqual({
|
|
26
|
-
inspector:
|
|
27
|
-
card:
|
|
26
|
+
inspector: 180,
|
|
27
|
+
card: 70,
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('a column shorter than the inspector minimum still bounds both cards', () => {
|
|
32
|
+
expect(rightStackFloors({ ...tall, naturalHeight: 500, stackHeight: 100 })).toEqual({
|
|
33
|
+
inspector: 92,
|
|
34
|
+
card: 0,
|
|
28
35
|
})
|
|
29
36
|
})
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { createContext, type ReactNode, useContext,
|
|
4
|
-
import { useIsMobile } from '
|
|
3
|
+
import { createContext, type ReactNode, useContext, useLayoutEffect, useRef } from 'react'
|
|
4
|
+
import { useIsMobile } from '@pascal-app/viewer/ui'
|
|
5
5
|
import { cn } from '../../lib/utils'
|
|
6
6
|
import { TOP_MENU_CLEARANCE } from './action-menu/placement'
|
|
7
7
|
|
|
@@ -20,9 +20,8 @@ const GAP = 8
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* The heights neither panel shrinks below. The inspector keeps 180 px (or its
|
|
23
|
-
* own height, if shorter)
|
|
24
|
-
*
|
|
25
|
-
* very short window it gives way and scrolls on itself — both stay usable.
|
|
23
|
+
* own height, if shorter) and never less than its header row when the column allows.
|
|
24
|
+
* The card uses the remaining room and scrolls on itself on a short window — both stay usable.
|
|
26
25
|
*/
|
|
27
26
|
export function rightStackFloors(args: {
|
|
28
27
|
naturalHeight: number
|
|
@@ -33,9 +32,10 @@ export function rightStackFloors(args: {
|
|
|
33
32
|
const { naturalHeight, headerHeight, cardHeight, stackHeight } = args
|
|
34
33
|
const gap = naturalHeight > 0 && cardHeight > 0 ? GAP : 0
|
|
35
34
|
const header = Math.min(headerHeight, naturalHeight)
|
|
36
|
-
const inspector = Math.
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const inspector = Math.min(
|
|
36
|
+
naturalHeight,
|
|
37
|
+
stackHeight,
|
|
38
|
+
Math.max(header, Math.min(INSPECTOR_MIN_HEIGHT, stackHeight - gap)),
|
|
39
39
|
)
|
|
40
40
|
const card = Math.max(0, Math.min(cardHeight, stackHeight - gap - inspector))
|
|
41
41
|
return { inspector, card }
|
|
@@ -78,7 +78,7 @@ export function RightStack({
|
|
|
78
78
|
|
|
79
79
|
// `min(180px, its own height)` has no CSS form for a flex item that scrolls,
|
|
80
80
|
// so both floors are measured (`rightStackFloors`).
|
|
81
|
-
|
|
81
|
+
useLayoutEffect(() => {
|
|
82
82
|
if (isMobile) return
|
|
83
83
|
const stack = stackRef.current
|
|
84
84
|
const slot = inspectorRef.current
|
|
@@ -88,18 +88,29 @@ export function RightStack({
|
|
|
88
88
|
const fit = () => {
|
|
89
89
|
frame = 0
|
|
90
90
|
const { natural, header } = inspectorHeights(slot)
|
|
91
|
+
const cardHeight = Array.from(card.children).reduce(
|
|
92
|
+
(height, child) => height + child.scrollHeight + (child instanceof HTMLElement ? child.offsetHeight - child.clientHeight : 0),
|
|
93
|
+
0,
|
|
94
|
+
)
|
|
91
95
|
const floors = rightStackFloors({
|
|
92
96
|
naturalHeight: natural,
|
|
93
97
|
headerHeight: header,
|
|
94
|
-
cardHeight
|
|
98
|
+
cardHeight,
|
|
95
99
|
stackHeight: stack.clientHeight,
|
|
96
100
|
})
|
|
97
101
|
const inspectorMin = `${floors.inspector}px`
|
|
98
102
|
const cardMin = `${floors.card}px`
|
|
103
|
+
// Custom panels may wrap PanelWrapper in a non-flex element. Give the
|
|
104
|
+
// card an explicit inherited limit so those wrappers cannot bypass it.
|
|
105
|
+
const available = Math.max(0, stack.clientHeight - floors.card - (natural > 0 && floors.card > 0 ? GAP : 0))
|
|
106
|
+
const limit = `${available}px`
|
|
107
|
+
if (slot.style.getPropertyValue('--inspector-available-height') !== limit) {
|
|
108
|
+
slot.style.setProperty('--inspector-available-height', limit)
|
|
109
|
+
}
|
|
99
110
|
if (slot.style.minHeight !== inspectorMin) slot.style.minHeight = inspectorMin
|
|
100
111
|
if (card.style.minHeight !== cardMin) card.style.minHeight = cardMin
|
|
101
112
|
// The card is click-through; it takes the pointer only when it has to scroll.
|
|
102
|
-
const pointer = floors.card <
|
|
113
|
+
const pointer = floors.card < cardHeight ? 'auto' : ''
|
|
103
114
|
if (card.style.pointerEvents !== pointer) card.style.pointerEvents = pointer
|
|
104
115
|
}
|
|
105
116
|
const schedule = () => {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
TooltipContent,
|
|
12
12
|
TooltipProvider,
|
|
13
13
|
TooltipTrigger,
|
|
14
|
-
} from '
|
|
14
|
+
} from '@pascal-app/viewer/ui'
|
|
15
15
|
|
|
16
16
|
/** A function-axis taxonomy node, assembled into a tree by the embedder. */
|
|
17
17
|
export type FunctionTreeNode = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Volume2, VolumeX } from 'lucide-react'
|
|
2
|
-
import { Button } from '
|
|
2
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
3
3
|
import {
|
|
4
4
|
Dialog,
|
|
5
5
|
DialogContent,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
DialogTrigger,
|
|
10
10
|
} from '../../../../../components/ui/primitives/dialog'
|
|
11
11
|
import { Slider } from '../../../../../components/ui/slider'
|
|
12
|
-
import useAudio from '
|
|
12
|
+
import { useAudioSettings as useAudio } from '@pascal-app/viewer/sfx'
|
|
13
13
|
|
|
14
14
|
export function AudioSettingsDialog() {
|
|
15
15
|
const {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from '../../../../../store/use-construction-reveal'
|
|
9
9
|
import { SegmentedControl } from '../../../controls/segmented-control'
|
|
10
10
|
import { Badge } from '../../../primitives/badge'
|
|
11
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '
|
|
11
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '@pascal-app/viewer/ui'
|
|
12
12
|
|
|
13
13
|
/** Why Framing is greyed out. */
|
|
14
14
|
export const FRAMING_NEEDS_ARCHITECT = 'Framing needs the Architect plugin.'
|
|
@@ -61,7 +61,7 @@ import {
|
|
|
61
61
|
waitForLocalImport,
|
|
62
62
|
} from '../../../../../lib/send-to-app'
|
|
63
63
|
import { SegmentedControl } from './../../../../../components/ui/controls/segmented-control'
|
|
64
|
-
import { Button } from '
|
|
64
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
65
65
|
import {
|
|
66
66
|
Dialog,
|
|
67
67
|
DialogContent,
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
DialogTrigger,
|
|
70
70
|
} from './../../../../../components/ui/primitives/dialog'
|
|
71
71
|
import { Input } from './../../../../../components/ui/primitives/input'
|
|
72
|
-
import { Switch } from '
|
|
72
|
+
import { Switch } from '@pascal-app/viewer/ui'
|
|
73
73
|
import { cn } from './../../../../../lib/utils'
|
|
74
74
|
import { refusedObjectsNotice } from './../../../../../components/editor/group-actions'
|
|
75
75
|
import { addStoreyBelow, addStoreyOnTop } from './../../../../../lib/add-storey'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type MessageDescriptor, usePascalI18n } from '@pascal-app/core'
|
|
2
2
|
import { Keyboard } from 'lucide-react'
|
|
3
|
-
import { Button } from '
|
|
3
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
4
4
|
import {
|
|
5
5
|
Dialog,
|
|
6
6
|
DialogContent,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
XCircle,
|
|
15
15
|
} from 'lucide-react'
|
|
16
16
|
import { useState } from 'react'
|
|
17
|
-
import { Button } from '
|
|
17
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
18
18
|
import {
|
|
19
19
|
Dialog,
|
|
20
20
|
DialogContent,
|
|
@@ -23,11 +23,7 @@ import {
|
|
|
23
23
|
DialogHeader,
|
|
24
24
|
DialogTitle,
|
|
25
25
|
} from '../../../../../components/ui/primitives/dialog'
|
|
26
|
-
import {
|
|
27
|
-
getAreaUnitLabel,
|
|
28
|
-
type LinearUnit,
|
|
29
|
-
squareMetersToAreaUnit,
|
|
30
|
-
} from '../../../../../lib/measurements'
|
|
26
|
+
import { getAreaUnitLabel, type LinearUnit, squareMetersToAreaUnit } from '@pascal-app/core'
|
|
31
27
|
|
|
32
28
|
export type PendingImport = {
|
|
33
29
|
fileName: string
|
|
@@ -2,7 +2,7 @@ import { getProjectFileSink } from '@pascal-app/core'
|
|
|
2
2
|
import { downloadProjectFile } from '../../../../../lib/download-project-file'
|
|
3
3
|
import { AlertTriangle, Printer } from 'lucide-react'
|
|
4
4
|
import { useState } from 'react'
|
|
5
|
-
import { Button } from '
|
|
5
|
+
import { Button } from '@pascal-app/viewer/ui'
|
|
6
6
|
import {
|
|
7
7
|
isPrintLevelBundleReport,
|
|
8
8
|
type PrintLevelBundleReport,
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
Tooltip,
|
|
9
9
|
TooltipContent,
|
|
10
10
|
TooltipTrigger,
|
|
11
|
-
} from '
|
|
11
|
+
} from '@pascal-app/viewer/ui'
|
|
12
12
|
import { focusTreeNode, TreeNode, TreeNodeWrapper } from './tree-node'
|
|
13
13
|
import { TreeNodeActions } from './tree-node-actions'
|
|
14
14
|
|
|
@@ -4,7 +4,7 @@ import Image from 'next/image'
|
|
|
4
4
|
import { memo, useCallback, useEffect, useState } from 'react'
|
|
5
5
|
import { useShallow } from 'zustand/react/shallow'
|
|
6
6
|
import { startCeilingEditFromTreeSelection } from './../../../../../lib/ceiling-edit-session'
|
|
7
|
-
import { formatAreaLabel } from '
|
|
7
|
+
import { formatAreaLabel } from '@pascal-app/core'
|
|
8
8
|
import { InlineRenameInput } from './inline-rename-input'
|
|
9
9
|
import { focusTreeNode, handleTreeSelection, TreeNode, TreeNodeWrapper } from './tree-node'
|
|
10
10
|
import { TreeNodeActions } from './tree-node-actions'
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
Popover,
|
|
53
53
|
PopoverContent,
|
|
54
54
|
PopoverTrigger,
|
|
55
|
-
} from '
|
|
55
|
+
} from '@pascal-app/viewer/ui'
|
|
56
56
|
import {
|
|
57
57
|
buildLevelDuplicateCreateOps,
|
|
58
58
|
type LevelDuplicatePreset,
|
|
@@ -60,14 +60,7 @@ import {
|
|
|
60
60
|
import { addStoreyOnTop } from './../../../../../lib/add-storey'
|
|
61
61
|
import { offerExteriorWallCopy } from './../../../../../components/ui/level-wall-copy-prompt'
|
|
62
62
|
import { deleteLevelWithFallbackSelection } from './../../../../../lib/level-selection'
|
|
63
|
-
import {
|
|
64
|
-
formatAreaLabel,
|
|
65
|
-
getAreaUnitLabel,
|
|
66
|
-
getLinearUnitLabel,
|
|
67
|
-
linearUnitToMeters,
|
|
68
|
-
metersToLinearUnit,
|
|
69
|
-
squareMetersToAreaUnit,
|
|
70
|
-
} from './../../../../../lib/measurements'
|
|
63
|
+
import { formatAreaLabel, getAreaUnitLabel, getLinearUnitLabel, linearUnitToMeters, metersToLinearUnit, squareMetersToAreaUnit } from '@pascal-app/core'
|
|
71
64
|
import { createLocalGuideImage, createLocalScan } from './../../../../../lib/local-guide-image'
|
|
72
65
|
import { editorHostTreeChildrenRegistry } from './../../../../../lib/host-tree-children'
|
|
73
66
|
import { requestRoomDeletion } from './../../../../../lib/room-structure-commands'
|
|
@@ -88,7 +81,7 @@ import { focusTreeNode, TreeNode, TreeNodeWrapper } from './tree-node'
|
|
|
88
81
|
import { TreeNodeDragProvider } from './tree-node-drag'
|
|
89
82
|
import { zoneDefaultName } from './default-names'
|
|
90
83
|
import { nodeLabelDescriptor } from '../../../../../i18n/node-messages'
|
|
91
|
-
import { authoredLevelName, localizedLevelName } from '
|
|
84
|
+
import { authoredLevelName, localizedLevelName } from '@pascal-app/viewer/ui'
|
|
92
85
|
|
|
93
86
|
// ============================================================================
|
|
94
87
|
// PROPERTY LINE SECTION
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type AnyNodeId, usePascalI18n, useScene } from '@pascal-app/core'
|
|
2
2
|
import { Pencil } from 'lucide-react'
|
|
3
3
|
import { memo, useCallback, useEffect, useRef, useState } from 'react'
|
|
4
|
-
import { displayRoomName } from '
|
|
4
|
+
import { displayRoomName } from '@pascal-app/viewer/ui'
|
|
5
5
|
import { cn } from './../../../../../lib/utils'
|
|
6
6
|
import { commitTreeRoomRename } from './../../../panels/room-name-options'
|
|
7
7
|
|
|
@@ -6,7 +6,7 @@ import { useShallow } from 'zustand/react/shallow'
|
|
|
6
6
|
import { InlineRenameInput } from './inline-rename-input'
|
|
7
7
|
import { focusTreeNode, TreeNode, TreeNodeWrapper } from './tree-node'
|
|
8
8
|
import { TreeNodeActions } from './tree-node-actions'
|
|
9
|
-
import { authoredLevelName, localizedLevelName } from '
|
|
9
|
+
import { authoredLevelName, localizedLevelName } from '@pascal-app/viewer/ui'
|
|
10
10
|
|
|
11
11
|
interface LevelTreeNodeProps {
|
|
12
12
|
nodeId: LevelNode['id']
|