@tscircuit/props 0.0.711 → 0.0.713

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,9 @@
1
1
  import { z } from "zod"
2
2
  import { expectTypesMatch } from "lib/typecheck"
3
3
 
4
+ const dimensionAnchor = z.enum(["center", "left", "right", "top", "bottom"])
5
+ export type AssemblyDrawingDimensionAnchor = z.infer<typeof dimensionAnchor>
6
+
4
7
  /** Authoring intent for a dimension of model geometry or a part view's extent.
5
8
  * Core resolves geometry, measurement text and paper placement in a follow-up.
6
9
  */
@@ -13,6 +16,14 @@ export interface AssemblyDrawingDimensionProps {
13
16
  widthOfView?: boolean
14
17
  /** Request the selected geometry's height in the view. Conflicts with edgeRef and widthOfView=true. */
15
18
  heightOfView?: boolean
19
+ /** Paired selectors for holes, boards or named model outlines. Both are required; conflicts with edgeRef and true view targets. */
20
+ fromRef?: string
21
+ toRef?: string
22
+ /** Anchor on the reference's projected bounds. Defaults to center; directions are relative to the drawing view, not CAD world axes. */
23
+ fromAnchor?: AssemblyDrawingDimensionAnchor
24
+ toAnchor?: AssemblyDrawingDimensionAnchor
25
+ /** Measure separation on the view's horizontal (x) or vertical (y) axis. Omitted chooses the larger separation, x on ties. Requires paired references. */
26
+ axis?: "x" | "y"
16
27
  }
17
28
 
18
29
  export const assemblyDrawingDimensionProps = z
@@ -21,18 +32,39 @@ export const assemblyDrawingDimensionProps = z
21
32
  edgeRef: z.string().trim().min(1).optional(),
22
33
  widthOfView: z.boolean().optional(),
23
34
  heightOfView: z.boolean().optional(),
35
+ fromRef: z.string().trim().min(1).optional(),
36
+ toRef: z.string().trim().min(1).optional(),
37
+ fromAnchor: dimensionAnchor.optional(),
38
+ toAnchor: dimensionAnchor.optional(),
39
+ axis: z.enum(["x", "y"]).optional(),
24
40
  })
25
41
  .superRefine((dimension, ctx) => {
26
42
  const targets = [
27
43
  dimension.edgeRef !== undefined,
28
44
  dimension.widthOfView === true,
29
45
  dimension.heightOfView === true,
46
+ dimension.fromRef !== undefined || dimension.toRef !== undefined,
30
47
  ].filter(Boolean).length
31
48
  if (targets !== 1)
32
49
  ctx.addIssue({
33
50
  code: "custom",
34
51
  message:
35
- "Specify exactly one of edgeRef, widthOfView=true, or heightOfView=true",
52
+ "Specify exactly one of edgeRef, widthOfView=true, heightOfView=true, or paired fromRef/toRef",
53
+ })
54
+ if ((dimension.fromRef === undefined) !== (dimension.toRef === undefined))
55
+ ctx.addIssue({
56
+ code: "custom",
57
+ message: "fromRef and toRef must be specified together",
58
+ })
59
+ if (
60
+ (dimension.axis !== undefined ||
61
+ dimension.fromAnchor !== undefined ||
62
+ dimension.toAnchor !== undefined) &&
63
+ (dimension.fromRef === undefined || dimension.toRef === undefined)
64
+ )
65
+ ctx.addIssue({
66
+ code: "custom",
67
+ message: "axis, fromAnchor and toAnchor require paired fromRef/toRef",
36
68
  })
37
69
  })
38
70
 
@@ -18,7 +18,8 @@ export interface SymbolProps {
18
18
  * Source sizing bounds in the local symbol coordinate space (mm, +X right, +Y up).
19
19
  * With width/height, maps the bounds center to the symbol position; all artwork
20
20
  * and ports use the same transform. Omitted uses automatic bounds including ports.
21
- * maxX must exceed minX and maxY must exceed minY. No aliases; no change to existing defaults.
21
+ * maxX must exceed minX and maxY must exceed minY. Other shapes are rejected
22
+ * with a diagnostic listing the required bounds. No aliases; existing defaults are unchanged.
22
23
  */
23
24
  viewbox?: {
24
25
  minX: number | string
@@ -29,6 +30,22 @@ export interface SymbolProps {
29
30
  name?: string
30
31
  }
31
32
 
33
+ const symbolViewboxBounds = z
34
+ .object({
35
+ minX: distance,
36
+ maxX: distance,
37
+ minY: distance,
38
+ maxY: distance,
39
+ })
40
+ .refine((bounds) => bounds.maxX > bounds.minX, {
41
+ message: "viewbox maxX must exceed minX",
42
+ path: ["maxX"],
43
+ })
44
+ .refine((bounds) => bounds.maxY > bounds.minY, {
45
+ message: "viewbox maxY must exceed minY",
46
+ path: ["maxY"],
47
+ })
48
+
32
49
  export const symbolProps = z.object({
33
50
  originalFacingDirection: z
34
51
  .enum(["up", "down", "left", "right"])
@@ -38,20 +55,20 @@ export const symbolProps = z.object({
38
55
  height: distance.optional(),
39
56
  fit: z.enum(["fill", "contain", "stretch"]).optional(),
40
57
  viewbox: z
41
- .object({
42
- minX: distance,
43
- maxX: distance,
44
- minY: distance,
45
- maxY: distance,
46
- })
47
- .refine((bounds) => bounds.maxX > bounds.minX, {
48
- message: "viewbox maxX must exceed minX",
49
- path: ["maxX"],
50
- })
51
- .refine((bounds) => bounds.maxY > bounds.minY, {
52
- message: "viewbox maxY must exceed minY",
53
- path: ["maxY"],
54
- })
58
+ .custom<z.input<typeof symbolViewboxBounds>>(
59
+ (bounds) =>
60
+ typeof bounds === "object" &&
61
+ bounds !== null &&
62
+ "minX" in bounds &&
63
+ "maxX" in bounds &&
64
+ "minY" in bounds &&
65
+ "maxY" in bounds,
66
+ {
67
+ message:
68
+ "viewbox requires { minX, maxX, minY, maxY } bounds in the local symbol coordinate space.",
69
+ },
70
+ )
71
+ .pipe(symbolViewboxBounds)
55
72
  .optional(),
56
73
  name: z.string().optional(),
57
74
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/props",
3
- "version": "0.0.711",
3
+ "version": "0.0.713",
4
4
  "description": "Props for tscircuit builtin component types",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",