393 lines
10 KiB
TypeScript
393 lines
10 KiB
TypeScript
import { AmesimPnpl01Symbol } from "./componentSymbols/boundary";
|
|
import {
|
|
AmesimF000Symbol,
|
|
AmesimForcSymbol,
|
|
AmesimLmechn1Symbol,
|
|
AmesimPnrp17Symbol,
|
|
AmesimLstp00aSymbol,
|
|
AmesimMecmas21Symbol,
|
|
} from "./componentSymbols/mechanical";
|
|
import {
|
|
AmesimHeliumMediumSymbol,
|
|
AmesimIdealAirMediumSymbol,
|
|
} from "./componentSymbols/media";
|
|
import {
|
|
AmesimPn3Node2Symbol,
|
|
AmesimP4Node2Symbol,
|
|
AmesimPnl0001Symbol,
|
|
AmesimPnl0002Symbol,
|
|
AmesimPnl0003Symbol,
|
|
AmesimPnl00rSymbol,
|
|
AmesimPnor001Symbol,
|
|
AmesimPnvo001FixedSymbol,
|
|
AmesimPnvo001SignalSymbol,
|
|
} from "./componentSymbols/pneumatic";
|
|
import { SymbolSvg } from "./componentSymbols/primitives";
|
|
import { AmesimStep0Symbol, AmesimUd00Symbol } from "./componentSymbols/signals";
|
|
import { AmesimPnch012Symbol, AmesimPnch023Symbol } from "./componentSymbols/storage";
|
|
import type {
|
|
ComponentSymbolParameters,
|
|
ComponentSymbolPortAnchors,
|
|
ComponentSymbolPresentation,
|
|
SymbolDefinition,
|
|
} from "./componentSymbols/types";
|
|
|
|
export type { ComponentSymbolPresentation } from "./componentSymbols/types";
|
|
|
|
export type ComponentSymbolSurface = "palette" | "canvas";
|
|
type ComponentSymbolProps = {
|
|
symbol: string;
|
|
surface: ComponentSymbolSurface;
|
|
className?: string;
|
|
parameters?: ComponentSymbolParameters;
|
|
};
|
|
|
|
function CylinderSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M3 24h7M54 24h7" stroke="currentColor" strokeWidth="2" />
|
|
<rect
|
|
fill="#dbeafe"
|
|
height="26"
|
|
rx="11"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
width="44"
|
|
x="10"
|
|
y="11"
|
|
/>
|
|
<path d="M33 12v24M33 24h21" stroke="currentColor" strokeWidth="2" />
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function TankSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h14M32 2v5M32 41v5" stroke="currentColor" strokeWidth="2" />
|
|
<path
|
|
d="M16 13c0-4 7.2-7 16-7s16 3 16 7v22c0 4-7.2 7-16 7s-16-3-16-7V13Z"
|
|
fill="#dcfce7"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
/>
|
|
<path d="M16 13c0 4 7.2 7 16 7s16-3 16-7" stroke="currentColor" strokeWidth="2" />
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function PipeSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h7M55 24h7M9 19h46M9 29h46" stroke="currentColor" strokeWidth="2" />
|
|
<path d="M9 17v14M55 17v14" stroke="currentColor" strokeWidth="2" />
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function OrificeSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h18M44 24h18" stroke="currentColor" strokeWidth="2" />
|
|
<path
|
|
d="m19 9 13 15-13 15V9ZM45 9 32 24l13 15V9Z"
|
|
fill="#ffedd5"
|
|
stroke="currentColor"
|
|
strokeLinejoin="round"
|
|
strokeWidth="2"
|
|
/>
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function TeeSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path
|
|
d="M2 24h28M30 24C42 24 44 12 62 12M30 24c12 0 14 12 32 12"
|
|
stroke="currentColor"
|
|
strokeLinecap="round"
|
|
strokeWidth="7"
|
|
/>
|
|
<path
|
|
d="M2 24h28M30 24C42 24 44 12 62 12M30 24c12 0 14 12 32 12"
|
|
stroke="#f8fafc"
|
|
strokeLinecap="round"
|
|
strokeWidth="3"
|
|
/>
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function GenericSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h9M53 24h9" stroke="currentColor" strokeWidth="2" />
|
|
<rect
|
|
fill="#f8fafc"
|
|
height="30"
|
|
rx="3"
|
|
stroke="currentColor"
|
|
strokeWidth="2"
|
|
width="42"
|
|
x="11"
|
|
y="9"
|
|
/>
|
|
<path d="m23 30 18-12M23 18h18v12" stroke="currentColor" strokeWidth="1.5" />
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function SignalSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h8M54 24h8" stroke="currentColor" strokeWidth="2" />
|
|
<circle cx="32" cy="24" fill="#f8fafc" r="22" stroke="currentColor" strokeWidth="2" />
|
|
<path
|
|
d="M16 25c4-13 8-13 12 0s8 13 12 0 6-10 8-4"
|
|
stroke="#2563eb"
|
|
strokeLinecap="round"
|
|
strokeLinejoin="round"
|
|
strokeWidth="2"
|
|
/>
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
function JunctionSymbol() {
|
|
return (
|
|
<SymbolSvg>
|
|
<path d="M2 24h60M32 2v44" stroke="currentColor" strokeWidth="2" />
|
|
<circle cx="32" cy="24" fill="currentColor" r="5" />
|
|
</SymbolSvg>
|
|
);
|
|
}
|
|
|
|
const symbolRegistry = {
|
|
cylinder: { presentation: "framed", render: CylinderSymbol },
|
|
tank: { presentation: "framed", render: TankSymbol },
|
|
pipe: { presentation: "framed", render: PipeSymbol },
|
|
orifice: { presentation: "framed", render: OrificeSymbol },
|
|
tee: { presentation: "framed", render: TeeSymbol },
|
|
generic: { presentation: "framed", render: GenericSymbol },
|
|
signal: { presentation: "framed", render: SignalSymbol },
|
|
junction: { presentation: "framed", render: JunctionSymbol },
|
|
amesim_pnpl01: { presentation: "framed", render: AmesimPnpl01Symbol },
|
|
amesim_pnch023: { presentation: "framed", render: AmesimPnch023Symbol },
|
|
amesim_pnch012: { presentation: "framed", render: AmesimPnch012Symbol },
|
|
amesim_pnor001: { presentation: "framed", render: AmesimPnor001Symbol },
|
|
amesim_pnvo001_fixed: {
|
|
presentation: "framed",
|
|
render: AmesimPnvo001FixedSymbol,
|
|
},
|
|
amesim_pnvo001: {
|
|
presentation: "framed",
|
|
render: AmesimPnvo001SignalSymbol,
|
|
},
|
|
amesim_pnl00r: { presentation: "framed", render: AmesimPnl00rSymbol },
|
|
amesim_pnl0001: { presentation: "framed", render: AmesimPnl0001Symbol },
|
|
amesim_pnl0002: { presentation: "framed", render: AmesimPnl0002Symbol },
|
|
amesim_pnl0003: { presentation: "framed", render: AmesimPnl0003Symbol },
|
|
amesim_pn3node2: { presentation: "framed", render: AmesimPn3Node2Symbol },
|
|
amesim_p4node2: { presentation: "framed", render: AmesimP4Node2Symbol },
|
|
amesim_step0: { presentation: "framed", render: AmesimStep0Symbol },
|
|
amesim_ud00: { presentation: "framed", render: AmesimUd00Symbol },
|
|
amesim_f000: { presentation: "framed", render: AmesimF000Symbol },
|
|
amesim_forc: { presentation: "framed", render: AmesimForcSymbol },
|
|
amesim_mecmas21: { presentation: "framed", render: AmesimMecmas21Symbol },
|
|
amesim_lstp00a: { presentation: "framed", render: AmesimLstp00aSymbol },
|
|
amesim_lmechn1: { presentation: "framed", render: AmesimLmechn1Symbol },
|
|
amesim_pnrp17: { presentation: "framed", render: AmesimPnrp17Symbol },
|
|
amesim_ideal_air_medium: {
|
|
presentation: "bare",
|
|
render: AmesimIdealAirMediumSymbol,
|
|
},
|
|
amesim_helium_medium: {
|
|
presentation: "bare",
|
|
render: AmesimHeliumMediumSymbol,
|
|
},
|
|
} satisfies Record<string, SymbolDefinition>;
|
|
|
|
type RegisteredComponentSymbol = keyof typeof symbolRegistry;
|
|
|
|
const symbolPortAnchors: Partial<
|
|
Record<RegisteredComponentSymbol, ComponentSymbolPortAnchors>
|
|
> = {
|
|
cylinder: {
|
|
left: [{ x: 3, y: 24 }],
|
|
right: [{ x: 61, y: 24 }],
|
|
},
|
|
tank: { left: [{ x: 2, y: 24 }] },
|
|
pipe: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
orifice: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
tee: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [
|
|
{ x: 62, y: 12 },
|
|
{ x: 62, y: 36 },
|
|
],
|
|
},
|
|
generic: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
signal: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
junction: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnpl01: { left: [{ x: 2, y: 24 }] },
|
|
amesim_pnch023: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnch012: {
|
|
left: [
|
|
{ x: 2, y: 16 },
|
|
{ x: 2, y: 32 },
|
|
],
|
|
right: [
|
|
{ x: 62, y: 16 },
|
|
{ x: 62, y: 32 },
|
|
],
|
|
},
|
|
amesim_pnor001: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnvo001_fixed: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnvo001: {
|
|
left: [
|
|
{ x: 26, y: 46 },
|
|
{ x: 2, y: 24 },
|
|
],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnl00r: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnl0001: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnl0002: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pnl0003: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_pn3node2: {
|
|
left: [{ x: 3, y: 24 }],
|
|
right: [
|
|
{ x: 61, y: 12 },
|
|
{ x: 61, y: 36 },
|
|
],
|
|
},
|
|
amesim_p4node2: {
|
|
left: [{ x: 3, y: 24 }],
|
|
right: [
|
|
{ x: 61, y: 8 },
|
|
{ x: 61, y: 24 },
|
|
{ x: 61, y: 40 },
|
|
],
|
|
},
|
|
amesim_step0: { right: [{ x: 60, y: 24 }] },
|
|
amesim_ud00: { right: [{ x: 60, y: 24 }] },
|
|
amesim_f000: { right: [{ x: 62, y: 24 }] },
|
|
amesim_forc: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_mecmas21: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_lstp00a: {
|
|
left: [{ x: 2, y: 24 }],
|
|
right: [{ x: 62, y: 24 }],
|
|
},
|
|
amesim_lmechn1: {
|
|
left: [7, 12, 17, 22, 27, 32, 37, 42].map((y) => ({ x: 5, y })),
|
|
right: [{ x: 59, y: 24 }],
|
|
},
|
|
amesim_pnrp17: {
|
|
left: [
|
|
{ x: 25.5, y: 48 },
|
|
{ x: 2, y: 4.4 },
|
|
{ x: 2, y: 24.1 },
|
|
],
|
|
right: [{ x: 62, y: 4.4 }, { x: 62, y: 24.1 }],
|
|
},
|
|
};
|
|
|
|
function isRegisteredComponentSymbol(symbol: string): symbol is RegisteredComponentSymbol {
|
|
return Object.prototype.hasOwnProperty.call(symbolRegistry, symbol);
|
|
}
|
|
|
|
export function hasComponentSymbol(symbol: string): boolean {
|
|
return isRegisteredComponentSymbol(symbol);
|
|
}
|
|
|
|
export function componentSymbolPresentation(
|
|
symbol: string,
|
|
): ComponentSymbolPresentation {
|
|
return isRegisteredComponentSymbol(symbol)
|
|
? symbolRegistry[symbol].presentation
|
|
: "framed";
|
|
}
|
|
|
|
export function componentSymbolPortAnchors(
|
|
symbol: string,
|
|
): ComponentSymbolPortAnchors | undefined {
|
|
return isRegisteredComponentSymbol(symbol)
|
|
? symbolPortAnchors[symbol]
|
|
: undefined;
|
|
}
|
|
|
|
export function ComponentSymbol({
|
|
symbol,
|
|
surface,
|
|
className,
|
|
parameters,
|
|
}: ComponentSymbolProps) {
|
|
const resolvedSymbol: RegisteredComponentSymbol = isRegisteredComponentSymbol(symbol)
|
|
? symbol
|
|
: "generic";
|
|
const definition = symbolRegistry[resolvedSymbol];
|
|
const SymbolRenderer = definition.render;
|
|
const rootClassName = [
|
|
"component-symbol",
|
|
`component-symbol-${surface}`,
|
|
`component-symbol-${resolvedSymbol}`,
|
|
className,
|
|
]
|
|
.filter(Boolean)
|
|
.join(" ");
|
|
|
|
return (
|
|
<span
|
|
aria-hidden="true"
|
|
className={rootClassName}
|
|
data-component-symbol={resolvedSymbol}
|
|
data-symbol-presentation={definition.presentation}
|
|
>
|
|
<SymbolRenderer parameters={parameters} />
|
|
</span>
|
|
);
|
|
}
|