From 7d7ccb680d39776e00db10f2af0af181e8d66891 Mon Sep 17 00:00:00 2001 From: Mustafa Mulla Date: Thu, 23 Jul 2026 23:25:22 +0530 Subject: [PATCH 1/4] Add schematic symbol props --- README.md | 16 ++++++++ generated/COMPONENT_TYPES.md | 25 ++++++++++++ generated/PROPS_OVERVIEW.md | 10 +++++ lib/components/schematic-symbol.ts | 45 +++++++++++++++++++++ lib/index.ts | 1 + tests/schematic-symbol.test.ts | 65 ++++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+) create mode 100644 lib/components/schematic-symbol.ts create mode 100644 tests/schematic-symbol.test.ts diff --git a/README.md b/README.md index c2aee406..df5970d6 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ resistorProps.parse({ resistance: "10k" } as ResistorPropsInput); | `` | [`SchematicRowProps`](#schematicrowprops-schematicrow) | | `` | [`SchematicSectionProps`](#schematicsectionprops-schematicsection) | | `` | [`SchematicSheetProps`](#schematicsheetprops-schematicsheet) | +| `` | [`SchematicSymbolProps`](#schematicsymbolprops-schematicsymbol) | | `` | [`SchematicTableProps`](#schematictableprops-schematictable) | | `` | [`SchematicTextProps`](#schematictextprops-schematictext) | | `` | [`SilkscreenCircleProps`](#silkscreencircleprops-silkscreencircle) | @@ -1691,6 +1692,21 @@ export interface SchematicSheetProps { [Source](https://github.com/tscircuit/props/blob/main/lib/components/schematic-sheet.ts) +### SchematicSymbolProps `` + +```ts +export interface SchematicSymbolProps extends CommonComponentProps { + /** Selector for the physical component represented by this symbol. */ + chipRef?: string; + /** Name of the symbol from the schematic-symbol library. */ + symbolName: string; + /** Maps symbol port labels to physical component port selectors. */ + connections: Connections; +} +``` + +[Source](https://github.com/tscircuit/props/blob/main/lib/components/schematic-symbol.ts) + ### SchematicTableProps `` ```ts diff --git a/generated/COMPONENT_TYPES.md b/generated/COMPONENT_TYPES.md index 39b5cdcc..54d96496 100644 --- a/generated/COMPONENT_TYPES.md +++ b/generated/COMPONENT_TYPES.md @@ -3719,6 +3719,31 @@ export const schematicSheetProps = z.object({ }) ``` +### schematic-symbol + +```typescript +/** + * Places a named schematic-symbol representation of an existing physical + * component. The connection keys are labels exposed by `symbolName`; each + * value selects the corresponding port on the component referenced by + * `chipRef`. + * + * Standard component props such as `displayName` and schematic placement are + * inherited from `CommonComponentProps`. + */ +export interface SchematicSymbolProps extends CommonComponentProps { + chipRef?: string + symbolName: string + connections: Connections +} +/** Maps symbol port labels to physical component port selectors. */ +export const schematicSymbolProps = commonComponentProps.extend({ + chipRef: z.string().min(1).optional(), + symbolName: z.string().min(1), + connections: schematicSymbolConnections, +}) +``` + ### schematic-table ```typescript diff --git a/generated/PROPS_OVERVIEW.md b/generated/PROPS_OVERVIEW.md index 6dd36661..79c2c853 100644 --- a/generated/PROPS_OVERVIEW.md +++ b/generated/PROPS_OVERVIEW.md @@ -2101,6 +2101,16 @@ export interface SchematicSheetProps { } +export interface SchematicSymbolProps extends CommonComponentProps { + /** Selector for the physical component represented by this symbol. */ + chipRef?: string + /** Name of the symbol from the schematic-symbol library. */ + symbolName: string + /** Maps symbol port labels to physical component port selectors. */ + connections: Connections +} + + export interface SchematicTableProps { schX?: number | string schY?: number | string diff --git a/lib/components/schematic-symbol.ts b/lib/components/schematic-symbol.ts new file mode 100644 index 00000000..37269fda --- /dev/null +++ b/lib/components/schematic-symbol.ts @@ -0,0 +1,45 @@ +import { connectionTarget } from "lib/common/connectionsProp" +import { + commonComponentProps, + type CommonComponentProps, +} from "lib/common/layout" +import { expectTypesMatch } from "lib/typecheck" +import type { Connections } from "lib/utility-types/connections-and-selectors" +import { z } from "zod" + +/** + * Places a named schematic-symbol representation of an existing physical + * component. The connection keys are labels exposed by `symbolName`; each + * value selects the corresponding port on the component referenced by + * `chipRef`. + * + * Standard component props such as `displayName` and schematic placement are + * inherited from `CommonComponentProps`. + */ +export interface SchematicSymbolProps extends CommonComponentProps { + /** Selector for the physical component represented by this symbol. */ + chipRef?: string + /** Name of the symbol from the schematic-symbol library. */ + symbolName: string + /** Maps symbol port labels to physical component port selectors. */ + connections: Connections +} + +const schematicSymbolConnections = z + .custom() + .pipe(z.record(z.string(), connectionTarget)) + .refine((value) => Object.keys(value).length > 0, { + message: "connections must map at least one schematic symbol port", + }) + +export const schematicSymbolProps = commonComponentProps.extend({ + chipRef: z.string().min(1).optional(), + symbolName: z.string().min(1), + connections: schematicSymbolConnections, +}) + +export type InferredSchematicSymbolProps = z.input + +expectTypesMatch>( + true, +) diff --git a/lib/index.ts b/lib/index.ts index 421456d5..f6584961 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -104,6 +104,7 @@ export * from "./components/ammeter" export * from "./components/schematic-arc" export * from "./components/toolingrail" export * from "./components/schematic-box" +export * from "./components/schematic-symbol" export * from "./components/schematic-circle" export * from "./components/schematic-rect" export * from "./components/schematic-line" diff --git a/tests/schematic-symbol.test.ts b/tests/schematic-symbol.test.ts new file mode 100644 index 00000000..23fd8c3d --- /dev/null +++ b/tests/schematic-symbol.test.ts @@ -0,0 +1,65 @@ +import { expect, test } from "bun:test" +import { schematicSymbolProps } from "lib/components/schematic-symbol" + +test("schematic symbol parses a physical component projection", () => { + const parsed = schematicSymbolProps.parse({ + name: "A", + displayName: "Q1A", + chipRef: ".Q1", + symbolName: "n_channel_e_mosfet_transistor", + connections: { + gate: ".Q1 > .G1", + source: ".Q1 > .S1", + drain: [".Q1 > .pin7", ".Q1 > .pin8"], + }, + schX: "2mm", + schY: "-1mm", + schRotation: "90deg", + schSectionName: "Switching", + schSheetName: "Power", + }) + + expect(parsed).toEqual({ + name: "A", + displayName: "Q1A", + chipRef: ".Q1", + symbolName: "n_channel_e_mosfet_transistor", + connections: { + gate: ".Q1 > .G1", + source: ".Q1 > .S1", + drain: [".Q1 > .pin7", ".Q1 > .pin8"], + }, + schX: 2, + schY: -1, + schRotation: 90, + schSectionName: "Switching", + schSheetName: "Power", + }) +}) + +test("schematic symbol accepts standard component props and optional chipRef", () => { + const parsed = schematicSymbolProps.parse({ + name: "B", + displayName: "Q1B", + symbolName: "n_channel_e_mosfet_transistor", + connections: { + gate: ".Q1 > .G2", + source: ".Q1 > .S2", + drain: ".Q1 > .D2", + }, + }) + + expect(parsed.displayName).toBe("Q1B") + expect(parsed.chipRef).toBeUndefined() +}) + +test("schematic symbol requires at least one connection", () => { + expect( + schematicSymbolProps.safeParse({ + name: "A", + chipRef: ".Q1", + symbolName: "n_channel_e_mosfet_transistor", + connections: {}, + }).success, + ).toBe(false) +}) From d0ebe07d207a0beac90c1340ed4d955edf951c2c Mon Sep 17 00:00:00 2001 From: Mustafa Mulla Date: Thu, 23 Jul 2026 23:30:21 +0530 Subject: [PATCH 2/4] Narrow schematic symbol props --- README.md | 9 ++++++++- generated/COMPONENT_TYPES.md | 20 ++++++++++++++++---- generated/PROPS_OVERVIEW.md | 9 ++++++++- lib/components/schematic-symbol.ts | 27 +++++++++++++++++++-------- tests/schematic-symbol.test.ts | 6 +----- 5 files changed, 52 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index df5970d6..fd97e200 100644 --- a/README.md +++ b/README.md @@ -1695,13 +1695,20 @@ export interface SchematicSheetProps { ### SchematicSymbolProps `` ```ts -export interface SchematicSymbolProps extends CommonComponentProps { +export interface SchematicSymbolProps { + /** Stable name for this representation, such as `A` or `B`. */ + name: string; /** Selector for the physical component represented by this symbol. */ chipRef?: string; /** Name of the symbol from the schematic-symbol library. */ symbolName: string; /** Maps symbol port labels to physical component port selectors. */ connections: Connections; + schX?: Distance; + schY?: Distance; + schRotation?: number | string; + schSectionName?: string; + schSheetName?: string; } ``` diff --git a/generated/COMPONENT_TYPES.md b/generated/COMPONENT_TYPES.md index 54d96496..ee19e684 100644 --- a/generated/COMPONENT_TYPES.md +++ b/generated/COMPONENT_TYPES.md @@ -3728,19 +3728,31 @@ export const schematicSheetProps = z.object({ * value selects the corresponding port on the component referenced by * `chipRef`. * - * Standard component props such as `displayName` and schematic placement are - * inherited from `CommonComponentProps`. + * This is a schematic-only projection, so it accepts only the identity, + * connection, and schematic placement props it needs. */ -export interface SchematicSymbolProps extends CommonComponentProps { +export interface SchematicSymbolProps { + name: string chipRef?: string symbolName: string connections: Connections + schX?: Distance + schY?: Distance + schRotation?: number | string + schSectionName?: string + schSheetName?: string } /** Maps symbol port labels to physical component port selectors. */ -export const schematicSymbolProps = commonComponentProps.extend({ +export const schematicSymbolProps = z.object({ + name: z.string().min(1), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), connections: schematicSymbolConnections, + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + schSectionName: z.string().optional(), + schSheetName: z.string().optional(), }) ``` diff --git a/generated/PROPS_OVERVIEW.md b/generated/PROPS_OVERVIEW.md index 79c2c853..784fb978 100644 --- a/generated/PROPS_OVERVIEW.md +++ b/generated/PROPS_OVERVIEW.md @@ -2101,13 +2101,20 @@ export interface SchematicSheetProps { } -export interface SchematicSymbolProps extends CommonComponentProps { +export interface SchematicSymbolProps { + /** Stable name for this representation, such as `A` or `B`. */ + name: string /** Selector for the physical component represented by this symbol. */ chipRef?: string /** Name of the symbol from the schematic-symbol library. */ symbolName: string /** Maps symbol port labels to physical component port selectors. */ connections: Connections + schX?: Distance + schY?: Distance + schRotation?: number | string + schSectionName?: string + schSheetName?: string } diff --git a/lib/components/schematic-symbol.ts b/lib/components/schematic-symbol.ts index 37269fda..9819c57f 100644 --- a/lib/components/schematic-symbol.ts +++ b/lib/components/schematic-symbol.ts @@ -1,8 +1,6 @@ +import { rotation } from "circuit-json" import { connectionTarget } from "lib/common/connectionsProp" -import { - commonComponentProps, - type CommonComponentProps, -} from "lib/common/layout" +import { distance, type Distance } from "lib/common/distance" import { expectTypesMatch } from "lib/typecheck" import type { Connections } from "lib/utility-types/connections-and-selectors" import { z } from "zod" @@ -13,16 +11,23 @@ import { z } from "zod" * value selects the corresponding port on the component referenced by * `chipRef`. * - * Standard component props such as `displayName` and schematic placement are - * inherited from `CommonComponentProps`. + * This is a schematic-only projection, so it accepts only the identity, + * connection, and schematic placement props it needs. */ -export interface SchematicSymbolProps extends CommonComponentProps { +export interface SchematicSymbolProps { + /** Stable name for this representation, such as `A` or `B`. */ + name: string /** Selector for the physical component represented by this symbol. */ chipRef?: string /** Name of the symbol from the schematic-symbol library. */ symbolName: string /** Maps symbol port labels to physical component port selectors. */ connections: Connections + schX?: Distance + schY?: Distance + schRotation?: number | string + schSectionName?: string + schSheetName?: string } const schematicSymbolConnections = z @@ -32,10 +37,16 @@ const schematicSymbolConnections = z message: "connections must map at least one schematic symbol port", }) -export const schematicSymbolProps = commonComponentProps.extend({ +export const schematicSymbolProps = z.object({ + name: z.string().min(1), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), connections: schematicSymbolConnections, + schX: distance.optional(), + schY: distance.optional(), + schRotation: rotation.optional(), + schSectionName: z.string().optional(), + schSheetName: z.string().optional(), }) export type InferredSchematicSymbolProps = z.input diff --git a/tests/schematic-symbol.test.ts b/tests/schematic-symbol.test.ts index 23fd8c3d..ff1bdbfd 100644 --- a/tests/schematic-symbol.test.ts +++ b/tests/schematic-symbol.test.ts @@ -4,7 +4,6 @@ import { schematicSymbolProps } from "lib/components/schematic-symbol" test("schematic symbol parses a physical component projection", () => { const parsed = schematicSymbolProps.parse({ name: "A", - displayName: "Q1A", chipRef: ".Q1", symbolName: "n_channel_e_mosfet_transistor", connections: { @@ -21,7 +20,6 @@ test("schematic symbol parses a physical component projection", () => { expect(parsed).toEqual({ name: "A", - displayName: "Q1A", chipRef: ".Q1", symbolName: "n_channel_e_mosfet_transistor", connections: { @@ -37,10 +35,9 @@ test("schematic symbol parses a physical component projection", () => { }) }) -test("schematic symbol accepts standard component props and optional chipRef", () => { +test("schematic symbol allows an optional chipRef", () => { const parsed = schematicSymbolProps.parse({ name: "B", - displayName: "Q1B", symbolName: "n_channel_e_mosfet_transistor", connections: { gate: ".Q1 > .G2", @@ -49,7 +46,6 @@ test("schematic symbol accepts standard component props and optional chipRef", ( }, }) - expect(parsed.displayName).toBe("Q1B") expect(parsed.chipRef).toBeUndefined() }) From ad7ec270f898f6039e29012d0655c616093fc38b Mon Sep 17 00:00:00 2001 From: Mustafa Mulla Date: Thu, 23 Jul 2026 23:31:57 +0530 Subject: [PATCH 3/4] Add schematic symbol display name --- README.md | 2 ++ generated/COMPONENT_TYPES.md | 2 ++ generated/PROPS_OVERVIEW.md | 2 ++ lib/components/schematic-symbol.ts | 3 +++ tests/schematic-symbol.test.ts | 2 ++ 5 files changed, 11 insertions(+) diff --git a/README.md b/README.md index fd97e200..631a4cbd 100644 --- a/README.md +++ b/README.md @@ -1698,6 +1698,8 @@ export interface SchematicSheetProps { export interface SchematicSymbolProps { /** Stable name for this representation, such as `A` or `B`. */ name: string; + /** Optional human-facing name shown in the schematic. */ + displayName?: string; /** Selector for the physical component represented by this symbol. */ chipRef?: string; /** Name of the symbol from the schematic-symbol library. */ diff --git a/generated/COMPONENT_TYPES.md b/generated/COMPONENT_TYPES.md index ee19e684..c081aba3 100644 --- a/generated/COMPONENT_TYPES.md +++ b/generated/COMPONENT_TYPES.md @@ -3733,6 +3733,7 @@ export const schematicSheetProps = z.object({ */ export interface SchematicSymbolProps { name: string + displayName?: string chipRef?: string symbolName: string connections: Connections @@ -3745,6 +3746,7 @@ export interface SchematicSymbolProps { /** Maps symbol port labels to physical component port selectors. */ export const schematicSymbolProps = z.object({ name: z.string().min(1), + displayName: z.string().optional(), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), connections: schematicSymbolConnections, diff --git a/generated/PROPS_OVERVIEW.md b/generated/PROPS_OVERVIEW.md index 784fb978..27772528 100644 --- a/generated/PROPS_OVERVIEW.md +++ b/generated/PROPS_OVERVIEW.md @@ -2104,6 +2104,8 @@ export interface SchematicSheetProps { export interface SchematicSymbolProps { /** Stable name for this representation, such as `A` or `B`. */ name: string + /** Optional human-facing name shown in the schematic. */ + displayName?: string /** Selector for the physical component represented by this symbol. */ chipRef?: string /** Name of the symbol from the schematic-symbol library. */ diff --git a/lib/components/schematic-symbol.ts b/lib/components/schematic-symbol.ts index 9819c57f..6bb8288a 100644 --- a/lib/components/schematic-symbol.ts +++ b/lib/components/schematic-symbol.ts @@ -17,6 +17,8 @@ import { z } from "zod" export interface SchematicSymbolProps { /** Stable name for this representation, such as `A` or `B`. */ name: string + /** Optional human-facing name shown in the schematic. */ + displayName?: string /** Selector for the physical component represented by this symbol. */ chipRef?: string /** Name of the symbol from the schematic-symbol library. */ @@ -39,6 +41,7 @@ const schematicSymbolConnections = z export const schematicSymbolProps = z.object({ name: z.string().min(1), + displayName: z.string().optional(), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), connections: schematicSymbolConnections, diff --git a/tests/schematic-symbol.test.ts b/tests/schematic-symbol.test.ts index ff1bdbfd..8006ca23 100644 --- a/tests/schematic-symbol.test.ts +++ b/tests/schematic-symbol.test.ts @@ -4,6 +4,7 @@ import { schematicSymbolProps } from "lib/components/schematic-symbol" test("schematic symbol parses a physical component projection", () => { const parsed = schematicSymbolProps.parse({ name: "A", + displayName: "Q1A", chipRef: ".Q1", symbolName: "n_channel_e_mosfet_transistor", connections: { @@ -20,6 +21,7 @@ test("schematic symbol parses a physical component projection", () => { expect(parsed).toEqual({ name: "A", + displayName: "Q1A", chipRef: ".Q1", symbolName: "n_channel_e_mosfet_transistor", connections: { From bd95e6c99613ad3bda0d0a8579cb0bb95fe68bb3 Mon Sep 17 00:00:00 2001 From: Mustafa Mulla Date: Thu, 23 Jul 2026 23:33:56 +0530 Subject: [PATCH 4/4] Make schematic symbol connections optional --- README.md | 2 +- generated/COMPONENT_TYPES.md | 4 ++-- generated/PROPS_OVERVIEW.md | 2 +- lib/components/schematic-symbol.ts | 4 ++-- tests/schematic-symbol.test.ts | 10 +++------- 5 files changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 631a4cbd..ea1650cf 100644 --- a/README.md +++ b/README.md @@ -1705,7 +1705,7 @@ export interface SchematicSymbolProps { /** Name of the symbol from the schematic-symbol library. */ symbolName: string; /** Maps symbol port labels to physical component port selectors. */ - connections: Connections; + connections?: Connections; schX?: Distance; schY?: Distance; schRotation?: number | string; diff --git a/generated/COMPONENT_TYPES.md b/generated/COMPONENT_TYPES.md index c081aba3..3a76247c 100644 --- a/generated/COMPONENT_TYPES.md +++ b/generated/COMPONENT_TYPES.md @@ -3736,7 +3736,7 @@ export interface SchematicSymbolProps { displayName?: string chipRef?: string symbolName: string - connections: Connections + connections?: Connections schX?: Distance schY?: Distance schRotation?: number | string @@ -3749,7 +3749,7 @@ export const schematicSymbolProps = z.object({ displayName: z.string().optional(), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), - connections: schematicSymbolConnections, + connections: schematicSymbolConnections.optional(), schX: distance.optional(), schY: distance.optional(), schRotation: rotation.optional(), diff --git a/generated/PROPS_OVERVIEW.md b/generated/PROPS_OVERVIEW.md index 27772528..c6229d94 100644 --- a/generated/PROPS_OVERVIEW.md +++ b/generated/PROPS_OVERVIEW.md @@ -2111,7 +2111,7 @@ export interface SchematicSymbolProps { /** Name of the symbol from the schematic-symbol library. */ symbolName: string /** Maps symbol port labels to physical component port selectors. */ - connections: Connections + connections?: Connections schX?: Distance schY?: Distance schRotation?: number | string diff --git a/lib/components/schematic-symbol.ts b/lib/components/schematic-symbol.ts index 6bb8288a..d097d5f7 100644 --- a/lib/components/schematic-symbol.ts +++ b/lib/components/schematic-symbol.ts @@ -24,7 +24,7 @@ export interface SchematicSymbolProps { /** Name of the symbol from the schematic-symbol library. */ symbolName: string /** Maps symbol port labels to physical component port selectors. */ - connections: Connections + connections?: Connections schX?: Distance schY?: Distance schRotation?: number | string @@ -44,7 +44,7 @@ export const schematicSymbolProps = z.object({ displayName: z.string().optional(), chipRef: z.string().min(1).optional(), symbolName: z.string().min(1), - connections: schematicSymbolConnections, + connections: schematicSymbolConnections.optional(), schX: distance.optional(), schY: distance.optional(), schRotation: rotation.optional(), diff --git a/tests/schematic-symbol.test.ts b/tests/schematic-symbol.test.ts index 8006ca23..fea8694e 100644 --- a/tests/schematic-symbol.test.ts +++ b/tests/schematic-symbol.test.ts @@ -37,21 +37,17 @@ test("schematic symbol parses a physical component projection", () => { }) }) -test("schematic symbol allows an optional chipRef", () => { +test("schematic symbol allows optional chipRef and connections", () => { const parsed = schematicSymbolProps.parse({ name: "B", symbolName: "n_channel_e_mosfet_transistor", - connections: { - gate: ".Q1 > .G2", - source: ".Q1 > .S2", - drain: ".Q1 > .D2", - }, }) expect(parsed.chipRef).toBeUndefined() + expect(parsed.connections).toBeUndefined() }) -test("schematic symbol requires at least one connection", () => { +test("schematic symbol rejects an empty connections map", () => { expect( schematicSymbolProps.safeParse({ name: "A",