feat: HVAC ductwork + DWV plumbing systems (#402)
Adds two new MEP node families (HVAC ductwork, DWV plumbing) built on a shared port-connectivity model. Co-authored by @sudhir9297.
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
'use client'
|
||||
|
||||
import { type AnyNodeId, useScene } from '@pascal-app/core'
|
||||
import { useViewer } from '@pascal-app/viewer'
|
||||
import { useEffect } from 'react'
|
||||
import { cycleRotationAxis } from '../shared/fitting-rotation'
|
||||
|
||||
/**
|
||||
* Selection-time rotation support for placed pipe fittings — mirrors
|
||||
* the duct-fitting affordance, mounted by the editor's
|
||||
* SelectionAffordanceManager (`def.affordanceTools.selection`). R/T
|
||||
* rotation lives in `def.keyboardActions`; this contributes the piece
|
||||
* that hook can't: **Alt cycles the active rotation axis** while a
|
||||
* single fitting is selected. The axis lives on `useEditor.rotationAxis`,
|
||||
* which the floating action menu reads to show the axis pill — so this
|
||||
* component renders nothing.
|
||||
*/
|
||||
const PipeFittingSelectionAffordance = () => {
|
||||
const selectedIds = useViewer((s) => s.selection.selectedIds)
|
||||
const hasSelectedFitting = useScene((s) => {
|
||||
if (selectedIds.length !== 1) return false
|
||||
return s.nodes[selectedIds[0] as AnyNodeId]?.type === 'pipe-fitting'
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!hasSelectedFitting) return
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key !== 'Alt' || e.repeat) return
|
||||
const tag = (e.target as HTMLElement | null)?.tagName
|
||||
if (tag === 'INPUT' || tag === 'TEXTAREA') return
|
||||
e.preventDefault()
|
||||
cycleRotationAxis()
|
||||
}
|
||||
// Bubble phase — when the placement tool is active its capture-phase
|
||||
// handler stops propagation, so the two never double-cycle.
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
return () => window.removeEventListener('keydown', onKeyDown)
|
||||
}, [hasSelectedFitting])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export default PipeFittingSelectionAffordance
|
||||
Reference in New Issue
Block a user