diff --git a/packages/nodes/src/ceiling/panel.tsx b/packages/nodes/src/ceiling/panel.tsx index 210976f8c3..c3cb2cb809 100644 --- a/packages/nodes/src/ceiling/panel.tsx +++ b/packages/nodes/src/ceiling/panel.tsx @@ -55,7 +55,7 @@ export function CeilingPanel() { const parent = node?.parentId ? s.nodes[node.parentId as AnyNode['id']] : undefined return parent?.type === 'level' ? getCeilingClampBound(parent.id, s.nodes, node?.polygon ?? []) - : 6 + : Number.POSITIVE_INFINITY }) // Effective height: the stored custom height, or — for follows-mode @@ -271,16 +271,34 @@ export function CeilingPanel() { )} {/* Presets write an explicit height (clamped to the bound), so - clicking one on a follows-mode ceiling switches it to custom. */} + clicking one on a follows-mode ceiling switches it to custom. + A preset taller than the storey would clamp silently and look + like a dead button — disable it and name the real gate instead. */}
- {heightPresets.map((preset) => ( - handleHeightChange(preset.height)} - /> - ))} + {heightPresets.map((preset) => { + const fits = preset.height <= maxHeight + return ( + handleHeightChange(preset.height)} + title={ + fits + ? undefined + : `Taller than this level (${formatLinearMeasurement(maxHeight, unit, metricNotation)} available). Raise the level height first.` + } + /> + ) + })}
+ {Number.isFinite(maxHeight) && ( +
+ Limited by the level to {formatLinearMeasurement(maxHeight, unit, metricNotation)} — + raise the level height for a taller ceiling. +
+ )} diff --git a/packages/nodes/src/slab/panel.tsx b/packages/nodes/src/slab/panel.tsx index 07e88ade22..b582b3ca97 100644 --- a/packages/nodes/src/slab/panel.tsx +++ b/packages/nodes/src/slab/panel.tsx @@ -279,9 +279,11 @@ export function SlabPanel() { width={320} > + {/* Range mirrors the 20 m storey cap; `clampSlabElevation` in the + write path stays the real bound against the level. */}