181 lines
4.6 KiB
TypeScript
181 lines
4.6 KiB
TypeScript
import type { ParametricDescriptor } from '@pascal-app/core'
|
|
import type { ChimneyNode } from './schema'
|
|
|
|
export const chimneyParametrics: ParametricDescriptor<ChimneyNode> = {
|
|
// The chimney panel is a bespoke tabbed UI (Cap / Flues / Shoulder /
|
|
// Bands / Cricket / Panels) ported from the archive — auto-derived
|
|
// groups can't reproduce its layout. `groups` stays declared for the
|
|
// MCP path and for any future fallback consumer, but the inspector
|
|
// mounts the custom panel.
|
|
customPanel: () => import('./panel'),
|
|
groups: [
|
|
{
|
|
label: 'Body',
|
|
fields: [
|
|
{
|
|
key: 'bodyShape',
|
|
kind: 'enum',
|
|
options: ['square', 'round'],
|
|
display: 'segmented',
|
|
},
|
|
{ key: 'width', kind: 'number', unit: 'm', min: 0.2, max: 2, step: 0.05 },
|
|
{
|
|
key: 'depth',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.2,
|
|
max: 2,
|
|
step: 0.05,
|
|
visibleIf: (n) => n.bodyShape === 'square',
|
|
},
|
|
{ key: 'heightAboveRidge', kind: 'number', unit: 'm', min: 0.2, max: 3, step: 0.05 },
|
|
{
|
|
key: 'cornerBevel',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0,
|
|
max: 0.1,
|
|
step: 0.005,
|
|
visibleIf: (n) => n.bodyShape === 'square',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Shoulder',
|
|
fields: [
|
|
{
|
|
key: 'shoulderStyle',
|
|
kind: 'enum',
|
|
options: ['none', 'tapered', 'corbeled'],
|
|
display: 'segmented',
|
|
},
|
|
{
|
|
key: 'shoulderHeight',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.1,
|
|
max: 1.5,
|
|
step: 0.05,
|
|
visibleIf: (n) => n.shoulderStyle !== 'none',
|
|
},
|
|
{
|
|
key: 'shoulderExtent',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0,
|
|
max: 0.5,
|
|
step: 0.01,
|
|
visibleIf: (n) => n.shoulderStyle !== 'none',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Cap',
|
|
fields: [
|
|
{ key: 'cap', kind: 'boolean' },
|
|
{
|
|
key: 'capShape',
|
|
kind: 'enum',
|
|
options: ['none', 'sloped', 'flat', 'stepped'],
|
|
display: 'segmented',
|
|
visibleIf: (n) => n.cap === true,
|
|
},
|
|
{
|
|
key: 'capOverhang',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0,
|
|
max: 0.2,
|
|
step: 0.01,
|
|
visibleIf: (n) => n.cap === true && n.capShape !== 'none',
|
|
},
|
|
{
|
|
key: 'capThickness',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.02,
|
|
max: 0.2,
|
|
step: 0.005,
|
|
visibleIf: (n) => n.cap === true && n.capShape !== 'none',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Flues',
|
|
fields: [
|
|
{ key: 'flueCount', kind: 'number', min: 0, max: 4, step: 1 },
|
|
{
|
|
key: 'flueShape',
|
|
kind: 'enum',
|
|
options: ['round', 'square'],
|
|
display: 'segmented',
|
|
visibleIf: (n) => n.flueCount > 0,
|
|
},
|
|
{
|
|
key: 'flueHeight',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.05,
|
|
max: 0.8,
|
|
step: 0.01,
|
|
visibleIf: (n) => n.flueCount > 0,
|
|
},
|
|
{
|
|
key: 'flueDiameter',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.05,
|
|
max: 0.4,
|
|
step: 0.01,
|
|
visibleIf: (n) => n.flueCount > 0,
|
|
},
|
|
{
|
|
key: 'flueSpacing',
|
|
kind: 'number',
|
|
min: 0,
|
|
max: 1,
|
|
step: 0.05,
|
|
visibleIf: (n) => n.flueCount > 1,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
label: 'Cricket',
|
|
fields: [
|
|
{
|
|
key: 'cricketStyle',
|
|
kind: 'enum',
|
|
options: ['none', 'simple'],
|
|
display: 'segmented',
|
|
visibleIf: (n) => n.bodyShape === 'square',
|
|
},
|
|
{
|
|
key: 'cricketSide',
|
|
kind: 'enum',
|
|
options: ['front', 'back'],
|
|
display: 'segmented',
|
|
visibleIf: (n) => n.bodyShape === 'square' && n.cricketStyle !== 'none',
|
|
},
|
|
{
|
|
key: 'cricketLength',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.2,
|
|
max: 2,
|
|
step: 0.05,
|
|
visibleIf: (n) => n.bodyShape === 'square' && n.cricketStyle !== 'none',
|
|
},
|
|
{
|
|
key: 'cricketHeight',
|
|
kind: 'number',
|
|
unit: 'm',
|
|
min: 0.1,
|
|
max: 1,
|
|
step: 0.05,
|
|
visibleIf: (n) => n.bodyShape === 'square' && n.cricketStyle !== 'none',
|
|
},
|
|
],
|
|
},
|
|
],
|
|
}
|