Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ This repo contains all the prop definitions and zod parsers for tscircuit builti
This repo is the source-of-truth for defining the React props, API changes begin here. The focus of the API is on ergonomics for
the user (unlike [circuit-json](https://github.com/tscircuit/circuit-json) which focuses on ergonomics for a renderer)

> **Zod v4 migration:** This package now requires `zod@^4` and
> `circuit-json@^0.0.455` as peer dependencies. Schemas composed with these
> props must use the same Zod major; consumers that inspect raw Zod errors
> should update to the v4 error APIs.

```ts
import type { ResistorProps, ResistorPropsInput } from "@tscircuit/props";
import { resistorProps } from "@tscircuit/props";
Expand Down Expand Up @@ -440,8 +445,8 @@ export interface CadAssemblyProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer assembly. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer assembly. When omitted,
* the assembly leaves its original layer unspecified.
*/
originalLayer?: LayerRef;

Expand Down Expand Up @@ -846,8 +851,8 @@ export interface FootprintProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer footprint. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer footprint. When omitted,
* the footprint leaves its original layer unspecified.
*/
originalLayer?: LayerRef;
/**
Expand Down Expand Up @@ -2035,7 +2040,8 @@ export interface SymbolProps {
* The facing direction that the symbol is designed for. If you set this to "right",
* then it means the children were intended to represent the symbol facing right.
* Generally, you shouldn't set this except where it can help prevent confusion
* because you have a complex symbol. Default is "right" and this is most intuitive.
* because you have a complex symbol. When omitted, the symbol leaves its
* original facing direction unspecified.
*/
originalFacingDirection?: "up" | "down" | "left" | "right";
width?: string | number;
Expand Down
39 changes: 21 additions & 18 deletions generated/COMPONENT_TYPES.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export interface CadModelJscad extends CadModelBase {
jscad: Record<string, any>
}
export const cadModelJscad = cadModelBase.extend({
jscad: z.record(z.any()),
jscad: z.record(z.string(), z.any()),
})
export const cadModelProp = z.union([
z.null(),
Expand Down Expand Up @@ -143,7 +143,7 @@ export const circleShapeProps = z.object({
export const createConnectionsProp = <T extends readonly [string, ...string[]]>(
labels: T,
) => {
return z.record(z.enum(labels), connectionTarget)
return z.partialRecord(z.enum(labels), connectionTarget)
}
```

Expand Down Expand Up @@ -561,7 +561,9 @@ export interface SupplierProps {
supplierPartNumbers?: SupplierPartNumbers
}
export const supplierProps = z.object({
supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(),
supplierPartNumbers: z
.partialRecord(supplier_name, z.array(z.string()))
.optional(),
})
export interface CommonComponentProps<PinLabel extends string = string>
extends CommonLayoutProps {
Expand Down Expand Up @@ -878,6 +880,7 @@ export type SchematicPinStyle = Record<
}
/** @deprecated use marginBottom */
export const schematicPinStyle = z.record(
z.string(),
z.object({
marginLeft: distance.optional(),
marginRight: distance.optional(),
Expand All @@ -900,7 +903,7 @@ export const url = z.preprocess((value) => {
}

return value
}, z.string()) as z.ZodType<string, z.ZodTypeDef, string>
}, z.string()) as unknown as z.ZodType<string, string>
```

## Available Component Types
Expand Down Expand Up @@ -1118,9 +1121,9 @@ export interface AnalogTransientSimulationProps
export const analogTransientSimulationProps = z
.object({
...analogAnalysisSimulationBaseProps,
duration: positiveMilliseconds.default("10ms"),
startTime: ms.default("0ms"),
timePerStep: positiveMilliseconds.default("0.01ms"),
duration: positiveMilliseconds.prefault("10ms"),
startTime: ms.prefault("0ms"),
timePerStep: positiveMilliseconds.prefault("0.01ms"),
})
```

Expand Down Expand Up @@ -1290,11 +1293,11 @@ export interface CadAssemblyProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer assembly. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer assembly. When omitted,
* the assembly leaves its original layer unspecified.
*/
export const cadassemblyProps = z.object({
originalLayer: layer_ref.default("top").optional(),
originalLayer: layer_ref.optional(),
children: z.any().optional(),
})
```
Expand Down Expand Up @@ -1412,7 +1415,9 @@ export type ChipConnections<T extends (props: ChipProps<any>) => any> = {
}
export const pinCompatibleVariant = z.object({
manufacturerPartNumber: z.string().optional(),
supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(),
supplierPartNumber: z
.partialRecord(supplier_name, z.array(z.string()))
.optional(),
})
export const chipProps = commonComponentProps.extend({
manufacturerPartNumber: z.string().optional(),
Expand Down Expand Up @@ -1996,7 +2001,7 @@ export interface FootprintProps {
export const footprintProps = z.object({
children: z.any().optional(),
name: z.string().optional(),
originalLayer: layer_ref.default("top").optional(),
originalLayer: layer_ref.optional(),
circuitJson: z.array(z.any()).optional(),
src: footprintProp.describe("Can be a footprint or kicad string").optional(),
insertionDirection: footprintInsertionDirection
Expand Down Expand Up @@ -4076,7 +4081,7 @@ export const silkscreenPathProps = pcbLayoutProps
export const silkscreenRectProps = pcbLayoutProps
.omit({ pcbRotation: true })
.extend({
filled: z.boolean().default(true).optional(),
filled: z.boolean().optional(),
stroke: z.enum(["dashed", "solid", "none"]).optional(),
strokeWidth: distance.optional(),
width: distance,
Expand Down Expand Up @@ -4370,13 +4375,11 @@ export interface SymbolProps {
* The facing direction that the symbol is designed for. If you set this to "right",
* then it means the children were intended to represent the symbol facing right.
* Generally, you shouldn't set this except where it can help prevent confusion
* because you have a complex symbol. Default is "right" and this is most intuitive.
* because you have a complex symbol. When omitted, the symbol leaves its
* original facing direction unspecified.
*/
export const symbolProps = z.object({
originalFacingDirection: z
.enum(["up", "down", "left", "right"])
.default("right")
.optional(),
originalFacingDirection: z.enum(["up", "down", "left", "right"]).optional(),
width: distance.optional(),
height: distance.optional(),
name: z.string().optional(),
Expand Down
11 changes: 6 additions & 5 deletions generated/PROPS_OVERVIEW.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ export interface CadAssemblyProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer assembly. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer assembly. When omitted,
* the assembly leaves its original layer unspecified.
*/
originalLayer?: LayerRef

Expand Down Expand Up @@ -993,8 +993,8 @@ export interface FootprintProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer footprint. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer footprint. When omitted,
* the footprint leaves its original layer unspecified.
*/
originalLayer?: LayerRef
/**
Expand Down Expand Up @@ -2449,7 +2449,8 @@ export interface SymbolProps {
* The facing direction that the symbol is designed for. If you set this to "right",
* then it means the children were intended to represent the symbol facing right.
* Generally, you shouldn't set this except where it can help prevent confusion
* because you have a complex symbol. Default is "right" and this is most intuitive.
* because you have a complex symbol. When omitted, the symbol leaves its
* original facing direction unspecified.
*/
originalFacingDirection?: "up" | "down" | "left" | "right"
width?: string | number
Expand Down
2 changes: 1 addition & 1 deletion lib/common/cadModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export interface CadModelJscad extends CadModelBase {
jscad: Record<string, any>
}
export const cadModelJscad = cadModelBase.extend({
jscad: z.record(z.any()),
jscad: z.record(z.string(), z.any()),
})

export type CadModelProp =
Expand Down
2 changes: 1 addition & 1 deletion lib/common/connectionsProp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ export const connectionTarget = z
export const createConnectionsProp = <T extends readonly [string, ...string[]]>(
labels: T,
) => {
return z.record(z.enum(labels), connectionTarget)
return z.partialRecord(z.enum(labels), connectionTarget)
}
4 changes: 3 additions & 1 deletion lib/common/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,9 @@ export interface SupplierProps {
supplierPartNumbers?: SupplierPartNumbers
}
export const supplierProps = z.object({
supplierPartNumbers: z.record(supplier_name, z.array(z.string())).optional(),
supplierPartNumbers: z
.partialRecord(supplier_name, z.array(z.string()))
.optional(),
})

expectTypesMatch<SupplierProps, z.input<typeof supplierProps>>(true)
Expand Down
8 changes: 4 additions & 4 deletions lib/common/pcbSx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export const pcbSxValue = z.object({
visibility: z.enum(["hidden", "visible", "inherit"]).optional(),
})

export const pcbSx = z.record(
z.string(),
pcbSxValue,
) as unknown as z.ZodType<PcbSx>
export const pcbSx = z.record(z.string(), pcbSxValue) as unknown as z.ZodType<
PcbSx,
PcbSx
>

expectTypesMatch<PcbSx, z.input<typeof pcbSx>>(true)
1 change: 1 addition & 0 deletions lib/common/schematicPinStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export type SchematicPinStyle = Record<
>

export const schematicPinStyle = z.record(
z.string(),
z.object({
marginLeft: distance.optional(),
marginRight: distance.optional(),
Expand Down
2 changes: 1 addition & 1 deletion lib/common/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ export const url = z.preprocess((value) => {
}

return value
}, z.string()) as z.ZodType<string, z.ZodTypeDef, string>
}, z.string()) as unknown as z.ZodType<string, string>
2 changes: 1 addition & 1 deletion lib/components/analogsweepparameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const voltageSweepQuantity = voltage.pipe(z.number())
const currentSweepQuantity = current.pipe(z.number())

const createAnalogSweepCoordinateProps = (
sweepQuantity: z.ZodType<number, z.ZodTypeDef, number | string>,
sweepQuantity: z.ZodType<number, number | string>,
) => ({
name: z.string().optional(),
values: z.array(sweepQuantity).min(1).optional(),
Expand Down
6 changes: 3 additions & 3 deletions lib/components/analogtransientsimulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ const positiveMilliseconds = ms.refine(
export const analogTransientSimulationProps = z
.object({
...analogAnalysisSimulationBaseProps,
duration: positiveMilliseconds.default("10ms"),
startTime: ms.default("0ms"),
timePerStep: positiveMilliseconds.default("0.01ms"),
duration: positiveMilliseconds.prefault("10ms"),
startTime: ms.prefault("0ms"),
timePerStep: positiveMilliseconds.prefault("0.01ms"),
})
.superRefine((simulation, context) => {
if (
Expand Down
6 changes: 3 additions & 3 deletions lib/components/cadassembly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ export interface CadAssemblyProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer assembly. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer assembly. When omitted,
* the assembly leaves its original layer unspecified.
*/
originalLayer?: LayerRef

children?: any
}

export const cadassemblyProps = z.object({
originalLayer: layer_ref.default("top").optional(),
originalLayer: layer_ref.optional(),
children: z.any().optional(),
})

Expand Down
4 changes: 3 additions & 1 deletion lib/components/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,9 @@ expectTypesMatch<PinLabelsProp, z.input<typeof pinLabelsProp>>(true)

export const pinCompatibleVariant = z.object({
manufacturerPartNumber: z.string().optional(),
supplierPartNumber: z.record(supplier_name, z.array(z.string())).optional(),
supplierPartNumber: z
.partialRecord(supplier_name, z.array(z.string()))
.optional(),
})

export const chipProps = commonComponentProps.extend({
Expand Down
6 changes: 3 additions & 3 deletions lib/components/diode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ const connectionTarget = z
.or(z.array(z.string()).readonly())
.or(z.array(z.string()))

const connectionsProp = z.record(diodeConnectionKeys, connectionTarget)
const connectionsProp = z.partialRecord(diodeConnectionKeys, connectionTarget)

const diodePinLabelsProp = z.record(
const diodePinLabelsProp = z.partialRecord(
z.enum(diodePins),
schematicPinLabel
.or(z.array(schematicPinLabel).readonly())
Expand Down Expand Up @@ -79,7 +79,7 @@ export const diodeProps = commonComponentProps
message: "Exactly one diode variant must be enabled",
path: [],
})
return z.INVALID
return
}
})
.transform((data) => {
Expand Down
6 changes: 3 additions & 3 deletions lib/components/footprint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export interface FootprintProps {
* components will be mirrored.
*
* Generally, you shouldn't set this except where it can help prevent
* confusion because you have a complex multi-layer footprint. Default is
* "top" and this is most intuitive.
* confusion because you have a complex multi-layer footprint. When omitted,
* the footprint leaves its original layer unspecified.
*/
originalLayer?: LayerRef
/**
Expand All @@ -54,7 +54,7 @@ export interface FootprintProps {
export const footprintProps = z.object({
children: z.any().optional(),
name: z.string().optional(),
originalLayer: layer_ref.default("top").optional(),
originalLayer: layer_ref.optional(),
circuitJson: z.array(z.any()).optional(),
src: footprintProp.describe("Can be a footprint or kicad string").optional(),
insertionDirection: footprintInsertionDirection
Expand Down
12 changes: 6 additions & 6 deletions lib/components/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,12 @@ export const autorouterPreset = z.union([
])

const autorouterString = z.string() as z.ZodType<
AutocompleteString<AutorouterPreset>,
AutocompleteString<AutorouterPreset>
>

export const autorouterProp: z.ZodType<AutorouterProp> = z.union([
autorouterConfig,
autorouterPreset,
autorouterString,
])
export const autorouterProp: z.ZodType<AutorouterProp, AutorouterProp> =
z.union([autorouterConfig, autorouterPreset, autorouterString])

export const autorouterEffortLevel = z.enum(["1x", "2x", "5x", "10x", "100x"])

Expand Down Expand Up @@ -637,7 +635,9 @@ export const baseGroupProps = commonLayoutProps.extend({
pcbAnchorAlignment: pcbAnchorAlignmentAutocomplete.optional(),
})

export const partsEngine = z.custom<PartsEngine>((v) => "findPart" in v)
export const partsEngine = z.custom<PartsEngine>(
(value) => typeof value === "object" && value !== null && "findPart" in value,
)

export const subcircuitGroupProps = baseGroupProps.extend({
manualEdits: manual_edits_file.optional(),
Expand Down
10 changes: 4 additions & 6 deletions lib/components/platedhole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,10 @@ const inferPlatedHoleShapeAndDefaults = (rawProps: unknown): unknown => {
return props
}

const distanceHiddenUndefined = z
.custom<z.input<typeof distance>>()
.transform((a) => {
if (a === undefined) return undefined
return distance.parse(a)
})
const distanceHiddenUndefined = distance.optional() as unknown as z.ZodType<
Distance,
z.input<typeof distance>
>

const platedHolePropsByShape = z
.discriminatedUnion("shape", [
Expand Down
Loading
Loading