@toolpath/tool-drawing 0.2.0 → 0.3.1

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.
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import { ViewerAssembly, Outline } from './geometry/index.js';
2
- export { Provenance, ViewerHolder, ViewerHolderProfile, ViewerTool, isHolderProfile } from './geometry/index.js';
3
- import { F as Frame, S as Sheet, T as Theme, P as Padding } from './sheet-D0LSO7qP.js';
4
- export { B as Box, E as Extent, a as FrameOptions, O as Orientation, b as SHEETS, f as frameFor, o as orientationFor, t as typeSizeFor } from './sheet-D0LSO7qP.js';
2
+ export { ViewerHolder, ViewerHolderProfile, ViewerTool } from './geometry/index.js';
3
+ import { F as Frame, S as Sheet, T as Theme, P as Padding } from './sheet-DicKQYfF.js';
4
+ export { B as Box, E as Extent, a as FrameOptions, O as Orientation, b as SHEETS, f as frameFor, o as orientationFor, t as typeSizeFor } from './sheet-DicKQYfF.js';
5
5
  import * as react from 'react';
6
6
  import { ReactNode } from 'react';
7
+ export { Provenance, isHolderProfile } from '@toolpath/tool-support';
7
8
 
8
9
  /**
9
10
  * What a drawing of this tool dimensions, and where each dimension goes.
@@ -18,11 +19,20 @@ import { ReactNode } from 'react';
18
19
  * axis. Every length is measured **from the tip**, which is where a machinist
19
20
  * measures from and where every rule in the sheet measures from.
20
21
  *
21
- * Only stated numbers are dimensioned. A drawing that carries a figure the
22
+ * Only stated numbers are dimensioned. A drawing that carries a dimension the
22
23
  * vendor never published is worse than one that carries fewer — the note under
23
24
  * the drawing already names what was assumed, and a dimension line looks like a
24
25
  * measurement whatever the note says.
25
26
  *
27
+ * ## Nothing here is lettered
28
+ *
29
+ * The drawing writes no numbers on itself (Paul, 2026-09-02). The figures were
30
+ * six two-line blocks fighting for the margin of a panel that already had the
31
+ * same six numbers in a table beside it, and the table is where a number can be
32
+ * read. What is left is the linework, and a way to say which line the reader is
33
+ * pointing at — so this model says which dimensions exist and where they run,
34
+ * and never what they are called or how they are written.
35
+ *
26
36
  * ## Sides are `minus` and `plus`, not `left` and `right`
27
37
  *
28
38
  * This model was written for a drawing that only ran vertically, where the two
@@ -38,6 +48,15 @@ interface LengthDimension {
38
48
  /** From the tip, in millimetres — always 0 for now, kept for a dimension that is not. */
39
49
  readonly from: number;
40
50
  readonly to: number;
51
+ /**
52
+ * The other codes this same line answers to.
53
+ *
54
+ * Two codes are one span more often than they look — see
55
+ * {@link oneLinePerSpan} — and the line is drawn once, under `code`, rather
56
+ * than as two of exactly the same length in two lanes. Pointing at any of
57
+ * these names lights it.
58
+ */
59
+ readonly aliases?: ReadonlyArray<string>;
41
60
  /**
42
61
  * Which line out from the stack this one runs in, 0 nearest.
43
62
  *
@@ -56,17 +75,18 @@ interface WidthDimension {
56
75
  readonly at: number;
57
76
  }
58
77
  /**
59
- * An angle called out with a leader rather than measured between two lines.
78
+ * An angle between two faces, drawn as the two faces extended.
60
79
  *
61
80
  * **A drill is its point** (Paul, 2026-09-01: "shouldn't a 2d rep of a drill be
62
81
  * showing me a tip angle?"). On a ⌀1 drill the cone is three tenths of a
63
- * millimetre tall — drawn to scale it is invisible, and the number is the only
64
- * way the drawing says 140° rather than 118°.
82
+ * millimetre tall — drawn to scale it is invisible so the drawing runs the
83
+ * point's two flanks out past the tool and arcs between them, which is what a
84
+ * sheet does with an angle too small to letter between its own faces.
65
85
  */
66
86
  interface AngleDimension {
67
87
  readonly code: string;
68
88
  readonly degrees: number;
69
- /** Where the leader points: a radius from the axis and a height above the tip. */
89
+ /** Halfway up the cone's own flank: a radius from the axis and a height above the tip. */
70
90
  readonly at: {
71
91
  readonly r: number;
72
92
  readonly z: number;
@@ -88,140 +108,54 @@ interface ToolDimensions {
88
108
  * out of it.
89
109
  */
90
110
  declare const dimensionsFor: (assembly: ViewerAssembly) => ToolDimensions;
91
- declare const dimensionLabel: (code: string) => string;
92
- /**
93
- * How a length is written out.
94
- *
95
- * A function rather than a unit, because a unit system is the application's:
96
- * this package has no opinion on whether a shop reads millimetres or inches,
97
- * and owning one would mean owning its rounding too. Millimetres in, a string
98
- * out; the default is only so the package draws something on its own.
99
- */
100
- type FormatLength = (millimetres: number) => string;
101
- declare const formatMillimetres: FormatLength;
102
- /** One label's box on the drawing, before anything has been moved. */
103
- interface LabelBox {
104
- readonly key: string;
105
- /** The inboard edge across the axis, and how far the box reaches outward. */
106
- readonly across: number;
107
- readonly width: number;
108
- /** The end nearest the tip, and how far the box reaches along the axis. */
109
- readonly along: number;
110
- readonly height: number;
111
- }
112
- /**
113
- * The same labels, moved apart until none covers another.
114
- *
115
- * **Because a dimension is only worth drawing if it can be read** (Paul,
116
- * 2026-09-01). A tool 50 mm long with 4 mm of flute puts its flute length, its
117
- * relief and its cutting diameter inside the bottom tenth of the drawing, and
118
- * three figures land on each other however carefully each one is placed. Each
119
- * label carries a box, so the boxes can be stacked: the one nearest the tip
120
- * keeps its place, and anything that would cover it moves **away from the
121
- * tip**, which is where the drawing has room.
122
- *
123
- * Pure arithmetic over rectangles — no measuring of text and no reading of the
124
- * DOM, so it runs the same on a server as in a browser.
125
- *
126
- * **Along the axis, not up the screen.** The original moved a clash "up",
127
- * which was the same direction only because the tool was always drawn
128
- * standing. Away from the tip is what that meant, and it is what holds when
129
- * the tool is laid on its side.
130
- */
131
- declare const stackLabels: (boxes: ReadonlyArray<LabelBox>, gap?: number,
132
- /**
133
- * Boxes that cannot move: the drawing's own lines, so a figure rises clear
134
- * of an extension line rather than sitting on it (Paul, 2026-09-01 — the
135
- * figures moved in beside their own lanes, and the lines outboard of them
136
- * cross those bands).
137
- */
138
- fixed?: ReadonlyArray<LabelBox>) => Map<string, number>;
111
+ /** Which flank of the tool a lane runs on. */
112
+ type Side = 'minus' | 'plus';
139
113
  /**
140
- * Where every figure on the drawing stands.
114
+ * One length's lane: which flank it runs on, and how far out along it.
141
115
  *
142
- * **Each figure beside its own line, in the band just outboard of it** (Paul,
143
- * 2026-09-01: "I'd love to put SFDM, LCF and shoulder dia closer to the part —
144
- * like, inside the below holder and OAL lines"). One column in the far margin
145
- * put the number for a dimension at the tool's edge as far from it as the
146
- * number for the overall length, and the eye has to travel the width of the
147
- * sheet to pair them up. So the margin is a series of bands: the widths sit in
148
- * the first, just past their arrows, and each length's figure sits in the band
149
- * outboard of its own lane.
150
- *
151
- * A band is only as wide as the widest figure in it, because the room it takes
152
- * comes out of the tool.
116
+ * {@link LengthDimension.lane} numbers the lanes across the whole drawing,
117
+ * shortest innermost. Where both flanks are offered they alternate, so each
118
+ * flank carries its own run of lanes starting at 0 and it is that per-flank
119
+ * number, not the global one, that says how far out the line is drawn.
153
120
  */
154
- /** Which flank of the tool a figure stands off. */
155
- type Side = 'minus' | 'plus';
156
- /** The type a figure is set in, given the drawing's own size. */
157
- declare const figureType: (fontSize: number) => number;
158
- /** One figure, and the band it stands in. */
159
- interface DimensionFigure {
121
+ interface DimensionLane {
160
122
  readonly code: string;
161
123
  readonly side: Side;
162
- /** 0 is the band nearest the tool — the widths'; band `i + 1` is outboard of lane `i`. */
163
- readonly band: number;
164
- /** The lane this figure's dimension runs in on its own side, or null for a width. */
165
- readonly lane: number | null;
166
- readonly lines: ReadonlyArray<string>;
167
- /** How far the figure reaches perpendicular to the tool axis. Bands are sized by this. */
168
- readonly across: number;
169
- /** How far it reaches parallel to the tool axis. The stacker moves figures along this. */
170
- readonly along: number;
124
+ readonly lane: number;
125
+ }
126
+ interface LaneLayout {
127
+ readonly lanes: ReadonlyArray<DimensionLane>;
128
+ /** How many lanes each flank carries, which is the room that flank needs. */
129
+ readonly count: Readonly<Record<Side, number>>;
171
130
  }
172
131
  /**
173
- * How tall a block of this many lines is, set at that type size.
132
+ * Which flank each length runs on, and its lane on that flank.
174
133
  *
175
- * The renderer sets type at {@link figureType} and leads it at 1.15, with half
176
- * a line of padding above and below; this is that sum, and the two have to
177
- * agree or a figure's box is not the size of the figure in it.
134
+ * **The drawing carries no figures**, so this is the whole of the layout: a
135
+ * lane is a place for a line, and a line needs nothing but room for itself.
136
+ * What replaced the bands is a plain ladder the numbers live in the
137
+ * consumer's own table, and the drawing lights the line the reader is pointing
138
+ * at (Paul, 2026-09-02).
178
139
  */
179
- declare const figureHeight: (lines: number, type: number) => number;
180
- interface DimensionLayout {
181
- readonly figures: ReadonlyArray<DimensionFigure>;
182
- /** Per side, the width of every band, nearest the tool first. */
183
- readonly bands: Readonly<Record<Side, ReadonlyArray<number>>>;
184
- }
185
- /** The room a side's bands take, measured out from the edge of the stack. */
186
- interface BandRoom {
140
+ declare const laneLayout: (model: ToolDimensions, sides?: "one" | "both") => LaneLayout;
141
+ /** The room one flank's lines take, measured out from the edge of the stack. */
142
+ interface LaneRoom {
187
143
  /** How far the width dimensions' arrows reach past the tool. */
188
144
  readonly arrow: number;
189
- /** The clearance between a band and the line beside it. */
145
+ /** The clearance between the arrows and the first lane. */
190
146
  readonly gap: number;
147
+ /** From one lane to the next. */
148
+ readonly step: number;
191
149
  }
192
- /** Where a band's inboard edge is: the offset a figure in it reads outward from. */
193
- declare const bandOffset: (bands: ReadonlyArray<number>, band: number, room: BandRoom) => number;
194
- /** Where a lane's line runs: just outboard of the band that carries its figure. */
195
- declare const laneOffset: (bands: ReadonlyArray<number>, lane: number, room: BandRoom) => number;
196
- /** Everything one side needs, out to the far edge of its last band. */
197
- declare const bandRoom: (bands: ReadonlyArray<number>, room: BandRoom) => number;
150
+ /** Where a lane's line runs, out from the edge of the stack. */
151
+ declare const laneOffset: (lane: number, room: LaneRoom) => number;
198
152
  /**
199
- * Every figure, on the side and in the band it belongs to.
153
+ * Everything one flank needs, out to its outermost line.
200
154
  *
201
- * The sides alternate lengths by lane, widths by their own order — so
202
- * neither margin runs away with the whole drawing while the other stands
203
- * empty. Where the drawing has something beside it, everything stays on the
204
- * one flank.
155
+ * Never less than the arrows, because a width is dimensioned from outside on
156
+ * **both** flanks whether or not a length runs up either of them.
205
157
  */
206
- declare const dimensionLayout: (model: ToolDimensions, format: FormatLength, fontSize: number, sides?: "one" | "both",
207
- /**
208
- * **Whether horizontal text runs parallel to the tool axis.**
209
- *
210
- * The one fact about the drawing's orientation that this model cannot do
211
- * without, and it is here rather than in the renderer so that it is stated
212
- * once, in a pure function, with a test on it.
213
- *
214
- * Everything else in this package is orientation-agnostic because a
215
- * millimetre is a millimetre whichever way the axis runs. Type is the
216
- * exception: **text does not rotate.** A figure two lines deep and twelve
217
- * characters wide is wide on the screen either way, so when the tool is laid
218
- * along the screen's width that figure reaches mostly *along* the tool, and
219
- * when the tool stands up it reaches *across* it. The bands are sized on the
220
- * across measure, so which of the two the type contributes decides how much
221
- * room the margins take — and getting it backwards pads the wrong axis by a
222
- * factor of about five.
223
- */
224
- textAlongAxis?: boolean) => DimensionLayout;
158
+ declare const laneRoom: (lanes: number, room: LaneRoom) => number;
225
159
 
226
160
  /**
227
161
  * What `<ToolDrawing>` hands the things drawn inside it.
@@ -282,6 +216,10 @@ interface ToolDrawingProps {
282
216
  /**
283
217
  * Draw the dimensions: every stated length and width, on the tool.
284
218
  *
219
+ * Lines only — the drawing letters none of them (Paul, 2026-09-02). Which
220
+ * line is which is said by {@link ToolDrawingProps.highlight}, from the
221
+ * consumer's own table of numbers.
222
+ *
285
223
  * Off by default, because the drawing is also used small — on a card beside
286
224
  * a list, where a dimension line is noise. The panel that has room turns it
287
225
  * on (Paul, 2026-09-01).
@@ -297,12 +235,25 @@ interface ToolDrawingProps {
297
235
  */
298
236
  readonly dimensionSides?: 'one' | 'both';
299
237
  /**
300
- * How a length is written out. Millimetres in, a string out.
238
+ * The dimension or dimensions drawn in the sheet's accent, by ISO 13399 code
239
+ * — `DC`, `LCF`, `OAL`, `SFDM`, `LBH`, `stickout`, `SIG`, and the two
240
+ * `shoulder-` codes.
241
+ *
242
+ * **The drawing letters nothing**, so this is how a reader is told which
243
+ * line is which (Paul, 2026-09-02): the consumer's own table of numbers
244
+ * lights the line for the number under the reader's pointer. A code that
245
+ * this tool does not dimension highlights nothing, which is what should
246
+ * happen when the table carries a number the drawing has no line for.
247
+ */
248
+ readonly highlight?: string | ReadonlyArray<string> | null;
249
+ /**
250
+ * The code under the pointer, and `null` when it leaves — so the table can
251
+ * be lit from the drawing as well as the other way about.
301
252
  *
302
- * The application's, because the unit a shop reads in is the application's
303
- * and owning one would mean owning its rounding too.
253
+ * Passing it puts hit targets on the lines; leaving it off draws none, and
254
+ * the drawing stays inert.
304
255
  */
305
- readonly formatLength?: FormatLength;
256
+ readonly onDimensionHover?: (code: string | null) => void;
306
257
  /**
307
258
  * Extra room for chrome around the drawing, in pixels, on top of whatever
308
259
  * the dimension bands ask for.
@@ -348,6 +299,6 @@ interface ToolDrawingProps {
348
299
  readonly children?: ReactNode;
349
300
  readonly className?: string;
350
301
  }
351
- declare const ToolDrawing: ({ assembly, theme, caption, dimensions, dimensionSides, formatLength, padding, collisions, verdict, children, className, }: ToolDrawingProps) => react.JSX.Element;
302
+ declare const ToolDrawing: ({ assembly, theme, caption, dimensions, dimensionSides, highlight, onDimensionHover, padding, collisions, verdict, children, className, }: ToolDrawingProps) => react.JSX.Element;
352
303
 
353
- export { type AngleDimension, type BandRoom, type DimensionFigure, type DimensionLayout, type DrawingContext, type FormatLength, Frame, type LabelBox, type LengthDimension, Padding, Sheet, type Side, Theme, type ToolDimensions, ToolDrawing, type ToolDrawingProps, ViewerAssembly, type WidthDimension, bandOffset, bandRoom, dimensionLabel, dimensionLayout, dimensionsFor, figureHeight, figureType, formatMillimetres, laneOffset, stackLabels, useDrawingContext };
304
+ export { type AngleDimension, type DimensionLane, type DrawingContext, Frame, type LaneLayout, type LaneRoom, type LengthDimension, Padding, Sheet, type Side, Theme, type ToolDimensions, ToolDrawing, type ToolDrawingProps, ViewerAssembly, type WidthDimension, dimensionsFor, laneLayout, laneOffset, laneRoom, useDrawingContext };