@ponchia/ui 0.5.0 → 0.6.3
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/CHANGELOG.md +386 -4
- package/MIGRATIONS.json +14 -0
- package/README.md +29 -6
- package/annotations/index.d.ts +398 -276
- package/annotations/index.d.ts.map +1 -0
- package/annotations/index.js +350 -77
- package/behaviors/carousel.d.ts +28 -0
- package/behaviors/carousel.d.ts.map +1 -0
- package/behaviors/carousel.js +20 -16
- package/behaviors/combobox.d.ts +40 -0
- package/behaviors/combobox.d.ts.map +1 -0
- package/behaviors/combobox.js +111 -29
- package/behaviors/command.d.ts +41 -0
- package/behaviors/command.d.ts.map +1 -0
- package/behaviors/command.js +27 -15
- package/behaviors/connectors.d.ts +17 -0
- package/behaviors/connectors.d.ts.map +1 -0
- package/behaviors/connectors.js +7 -5
- package/behaviors/crosshair.d.ts +42 -0
- package/behaviors/crosshair.d.ts.map +1 -0
- package/behaviors/crosshair.js +23 -6
- package/behaviors/dialog.d.ts +20 -0
- package/behaviors/dialog.d.ts.map +1 -0
- package/behaviors/dialog.js +6 -2
- package/behaviors/disclosure.d.ts +10 -0
- package/behaviors/disclosure.d.ts.map +1 -0
- package/behaviors/disclosure.js +6 -2
- package/behaviors/dismissible.d.ts +10 -0
- package/behaviors/dismissible.d.ts.map +1 -0
- package/behaviors/dismissible.js +6 -2
- package/behaviors/forms.d.ts +27 -0
- package/behaviors/forms.d.ts.map +1 -0
- package/behaviors/forms.js +54 -13
- package/behaviors/glyph.d.ts +14 -0
- package/behaviors/glyph.d.ts.map +1 -0
- package/behaviors/glyph.js +28 -5
- package/behaviors/index.d.ts +31 -237
- package/behaviors/index.d.ts.map +1 -0
- package/behaviors/index.js +17 -0
- package/behaviors/inert.d.ts +20 -0
- package/behaviors/inert.d.ts.map +1 -0
- package/behaviors/inert.js +46 -0
- package/behaviors/internal.d.ts +25 -0
- package/behaviors/internal.d.ts.map +1 -0
- package/behaviors/internal.js +77 -1
- package/behaviors/legend.d.ts +35 -0
- package/behaviors/legend.d.ts.map +1 -0
- package/behaviors/legend.js +32 -2
- package/behaviors/menu.d.ts +16 -0
- package/behaviors/menu.d.ts.map +1 -0
- package/behaviors/menu.js +6 -2
- package/behaviors/modal.d.ts +41 -0
- package/behaviors/modal.d.ts.map +1 -0
- package/behaviors/modal.js +124 -0
- package/behaviors/popover.d.ts +28 -0
- package/behaviors/popover.d.ts.map +1 -0
- package/behaviors/popover.js +78 -7
- package/behaviors/spotlight.d.ts +17 -0
- package/behaviors/spotlight.d.ts.map +1 -0
- package/behaviors/spotlight.js +7 -5
- package/behaviors/table.d.ts +36 -0
- package/behaviors/table.d.ts.map +1 -0
- package/behaviors/table.js +84 -17
- package/behaviors/tabs.d.ts +20 -0
- package/behaviors/tabs.d.ts.map +1 -0
- package/behaviors/tabs.js +17 -14
- package/behaviors/theme.d.ts +54 -0
- package/behaviors/theme.d.ts.map +1 -0
- package/behaviors/theme.js +22 -3
- package/behaviors/toast.d.ts +49 -0
- package/behaviors/toast.d.ts.map +1 -0
- package/behaviors/toast.js +47 -3
- package/classes/classes.json +2527 -0
- package/classes/index.d.ts +134 -15
- package/classes/index.js +280 -80
- package/classes/vscode.css-custom-data.json +12 -0
- package/connectors/index.d.ts +201 -69
- package/connectors/index.d.ts.map +1 -0
- package/connectors/index.js +142 -25
- package/css/app.css +69 -13
- package/css/base.css +15 -10
- package/css/bullet.css +108 -0
- package/css/code.css +98 -0
- package/css/connectors.css +17 -0
- package/css/content.css +22 -3
- package/css/crosshair.css +7 -7
- package/css/dataviz.css +5 -1
- package/css/diff.css +153 -0
- package/css/disclosure.css +53 -7
- package/css/dots.css +94 -7
- package/css/feedback.css +97 -7
- package/css/forms.css +113 -4
- package/css/legend.css +16 -9
- package/css/marks.css +38 -8
- package/css/motion.css +98 -53
- package/css/navigation.css +7 -0
- package/css/overlay.css +90 -3
- package/css/primitives.css +158 -13
- package/css/report.css +73 -56
- package/css/sidenote.css +67 -0
- package/css/site.css +16 -2
- package/css/sources.css +43 -1
- package/css/spark.css +62 -0
- package/css/spotlight.css +1 -1
- package/css/table.css +9 -2
- package/css/term.css +110 -0
- package/css/textref.css +63 -0
- package/css/toc.css +91 -0
- package/css/tokens.css +49 -1
- package/css/tree.css +134 -0
- package/css/workbench.css +1 -1
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/base.css +1 -1
- package/dist/css/bullet.css +1 -0
- package/dist/css/code.css +1 -0
- package/dist/css/connectors.css +1 -1
- package/dist/css/content.css +1 -1
- package/dist/css/crosshair.css +1 -1
- package/dist/css/diff.css +1 -0
- package/dist/css/disclosure.css +1 -1
- package/dist/css/dots.css +1 -1
- package/dist/css/feedback.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/legend.css +1 -1
- package/dist/css/marks.css +1 -1
- package/dist/css/motion.css +1 -1
- package/dist/css/navigation.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report.css +1 -1
- package/dist/css/sidenote.css +1 -0
- package/dist/css/site.css +1 -1
- package/dist/css/sources.css +1 -1
- package/dist/css/spark.css +1 -0
- package/dist/css/spotlight.css +1 -1
- package/dist/css/table.css +1 -1
- package/dist/css/term.css +1 -0
- package/dist/css/textref.css +1 -0
- package/dist/css/toc.css +1 -0
- package/dist/css/tokens.css +1 -1
- package/dist/css/tree.css +1 -0
- package/dist/css/workbench.css +1 -1
- package/docs/adr/0003-theme-model.md +1 -1
- package/docs/annotations.md +133 -14
- package/docs/architecture.md +49 -6
- package/docs/bullet.md +78 -0
- package/docs/code.md +76 -0
- package/docs/contrast.md +116 -92
- package/docs/d2.md +196 -0
- package/docs/diff.md +146 -0
- package/docs/legends.md +23 -3
- package/docs/marks.md +9 -2
- package/docs/mermaid.md +169 -0
- package/docs/reference.md +201 -26
- package/docs/reporting.md +416 -57
- package/docs/sidenote.md +64 -0
- package/docs/sources.md +27 -0
- package/docs/spark.md +78 -0
- package/docs/stability.md +10 -2
- package/docs/term.md +81 -0
- package/docs/textref.md +78 -0
- package/docs/theming.md +44 -5
- package/docs/toc.md +83 -0
- package/docs/tree.md +74 -0
- package/docs/usage.md +354 -16
- package/docs/vega.md +244 -0
- package/docs/workbench.md +7 -1
- package/glyphs/glyphs.js +13 -5
- package/llms.txt +285 -14
- package/package.json +95 -17
- package/qwik/index.d.ts +44 -59
- package/qwik/index.d.ts.map +1 -0
- package/qwik/index.js +65 -3
- package/react/index.d.ts +41 -61
- package/react/index.d.ts.map +1 -0
- package/react/index.js +63 -3
- package/solid/index.d.ts +68 -61
- package/solid/index.d.ts.map +1 -0
- package/solid/index.js +66 -3
- package/tokens/d2.d.ts +38 -0
- package/tokens/d2.js +71 -0
- package/tokens/d2.json +43 -0
- package/tokens/index.d.ts +5 -5
- package/tokens/index.js +15 -1
- package/tokens/index.json +9 -0
- package/tokens/mermaid.d.ts +23 -0
- package/tokens/mermaid.js +181 -0
- package/tokens/mermaid.json +163 -0
- package/tokens/resolved.json +45 -1
- package/tokens/skins.js +3 -2
- package/tokens/tokens.dtcg.json +26 -0
- package/tokens/vega.d.ts +34 -0
- package/tokens/vega.js +155 -0
- package/tokens/vega.json +179 -0
package/connectors/index.d.ts
CHANGED
|
@@ -1,71 +1,203 @@
|
|
|
1
|
+
export function finite(name: any, value: any, fallback: any): any;
|
|
2
|
+
export function dimension(name: any, value: any, fallback: any): any;
|
|
3
|
+
export function roundNumber(value: any): number;
|
|
4
|
+
export function fmt(value: any): string;
|
|
5
|
+
export function point(x: any, y: any): string;
|
|
6
|
+
export function clamp(value: any, min: any, max: any): any;
|
|
1
7
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
8
|
+
* A point on a rect's edge (or centre). `rect` is `{ x, y, width, height }`.
|
|
9
|
+
* @param {Rect} rect
|
|
10
|
+
* @param {Side} [side]
|
|
11
|
+
* @returns {Point}
|
|
4
12
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
export
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
|
|
71
|
-
|
|
13
|
+
export function anchorPoint(rect: Rect, side?: Side): Point;
|
|
14
|
+
/**
|
|
15
|
+
* Angle (radians) from `from` to `to`.
|
|
16
|
+
* @param {Point} from
|
|
17
|
+
* @param {Point} to
|
|
18
|
+
* @returns {number}
|
|
19
|
+
*/
|
|
20
|
+
export function angleBetween(from: Point, to: Point): number;
|
|
21
|
+
/**
|
|
22
|
+
* Straight line from `from` to `to`.
|
|
23
|
+
* @param {Point} from
|
|
24
|
+
* @param {Point} to
|
|
25
|
+
* @returns {string}
|
|
26
|
+
*/
|
|
27
|
+
export function straightPath(from: Point, to: Point): string;
|
|
28
|
+
/**
|
|
29
|
+
* Right-angle dogleg. Turns on the dominant axis at `mid` (0..1) of the span.
|
|
30
|
+
* @param {Point} from
|
|
31
|
+
* @param {Point} to
|
|
32
|
+
* @param {{ mid?: number }} [opts]
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
export function elbowPath(from: Point, to: Point, opts?: {
|
|
36
|
+
mid?: number;
|
|
37
|
+
}): string;
|
|
38
|
+
/**
|
|
39
|
+
* Cubic curve; control points extend along the dominant axis by `curvature`.
|
|
40
|
+
* @param {Point} from
|
|
41
|
+
* @param {Point} to
|
|
42
|
+
* @param {{ curvature?: number }} [opts]
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
45
|
+
export function curvePath(from: Point, to: Point, opts?: {
|
|
46
|
+
curvature?: number;
|
|
47
|
+
}): string;
|
|
48
|
+
/**
|
|
49
|
+
* Build a path between two points by `shape` (`straight` | `elbow` | `curve`).
|
|
50
|
+
* @param {ConnectorPathOptions} [opts]
|
|
51
|
+
* @returns {string}
|
|
52
|
+
*/
|
|
53
|
+
export function connectorPath(opts?: ConnectorPathOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* A filled triangle arrowhead at `p`, pointing along `angle` (radians).
|
|
56
|
+
* @param {Point} p
|
|
57
|
+
* @param {number} angle
|
|
58
|
+
* @param {number} [size]
|
|
59
|
+
* @param {number} [spread] Half-angle of the head in radians (default 0.45).
|
|
60
|
+
* Smaller is crisper/sharper; must be in (0, π/2).
|
|
61
|
+
* @returns {string}
|
|
62
|
+
*/
|
|
63
|
+
export function arrowHead(p: Point, angle: number, size?: number, spread?: number): string;
|
|
64
|
+
/**
|
|
65
|
+
* A filled dot at `p`.
|
|
66
|
+
* @param {Point} p
|
|
67
|
+
* @param {number} [radius]
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
export function dotMark(p: Point, radius?: number): string;
|
|
71
|
+
/**
|
|
72
|
+
* An axis-aligned rectangle path from its corners (callers derive the corners
|
|
73
|
+
* from a centre or a top-left as they need). Shared by the annotation
|
|
74
|
+
* rect/band and evidence-marker subjects. (code-quality audit Q5.)
|
|
75
|
+
* @param {number} left
|
|
76
|
+
* @param {number} top
|
|
77
|
+
* @param {number} right
|
|
78
|
+
* @param {number} bottom
|
|
79
|
+
* @returns {string}
|
|
80
|
+
*/
|
|
81
|
+
export function rectPath(left: number, top: number, right: number, bottom: number): string;
|
|
82
|
+
/**
|
|
83
|
+
* Pick facing edges from the rects' relative centres.
|
|
84
|
+
* @param {Rect} fromRect
|
|
85
|
+
* @param {Rect} toRect
|
|
86
|
+
* @returns {{ from: Side, to: Side }}
|
|
87
|
+
*/
|
|
88
|
+
export function autoSides(fromRect: Rect, toRect: Rect): {
|
|
89
|
+
from: Side;
|
|
90
|
+
to: Side;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Angle (radians) at which a `shape` path *arrives* at `to` — straight is the
|
|
94
|
+
* chord; elbow/curve arrive axis-aligned along the dominant axis. Rotate an
|
|
95
|
+
* end marker by this so it points along the path, not the chord.
|
|
96
|
+
* @param {Point} from
|
|
97
|
+
* @param {Point} to
|
|
98
|
+
* @param {ConnectorShape} [shape]
|
|
99
|
+
* @returns {number}
|
|
100
|
+
*/
|
|
101
|
+
export function endTangentAngle(from: Point, to: Point, shape?: ConnectorShape): number;
|
|
102
|
+
/**
|
|
103
|
+
* Connect two rects. Resolves anchor points (explicit `fromSide`/`toSide`, else
|
|
104
|
+
* auto), builds the path, and returns `{ d, from, to, angle }` so the caller can
|
|
105
|
+
* place an arrowhead/dot at `to` rotated by `angle`.
|
|
106
|
+
* @param {ConnectRectsOptions} [opts]
|
|
107
|
+
* @returns {ConnectRectsResult}
|
|
108
|
+
*/
|
|
109
|
+
export function connectRects(opts?: ConnectRectsOptions): ConnectRectsResult;
|
|
110
|
+
/**
|
|
111
|
+
* @ponchia/ui/connectors — dependency-free SVG geometry for connecting two
|
|
112
|
+
* elements (or two points) with a leader line.
|
|
113
|
+
*
|
|
114
|
+
* Pure functions only: they take points/rects and return SVG path strings (or
|
|
115
|
+
* resolved coordinates). They own no DOM, no scales, and no live tracking —
|
|
116
|
+
* that optional glue lives in `@ponchia/ui/behaviors` (`initConnectors`). This
|
|
117
|
+
* is the page-coordinate, element-to-element cousin of the figure-coordinate
|
|
118
|
+
* `@ponchia/ui/annotations` helpers.
|
|
119
|
+
*
|
|
120
|
+
* import { connectRects } from '@ponchia/ui/connectors';
|
|
121
|
+
* const { d } = connectRects({ fromRect: a, toRect: b, shape: 'elbow' });
|
|
122
|
+
*
|
|
123
|
+
* The public types below are JSDoc `@typedef`s; the shipped `index.d.ts` is
|
|
124
|
+
* generated from them (and these signatures) by `tsc --emitDeclarationOnly`.
|
|
125
|
+
*
|
|
126
|
+
* @typedef {{ x: number, y: number }} Point
|
|
127
|
+
* @typedef {{ x: number, y: number, width: number, height: number }} Rect
|
|
128
|
+
* @typedef {'top' | 'right' | 'bottom' | 'left' | 'center'} Side
|
|
129
|
+
* @typedef {'straight' | 'elbow' | 'curve'} ConnectorShape
|
|
130
|
+
*
|
|
131
|
+
* @typedef {object} ConnectorPathOptions
|
|
132
|
+
* @property {Point} from
|
|
133
|
+
* @property {Point} to
|
|
134
|
+
* @property {ConnectorShape} [shape]
|
|
135
|
+
* @property {number} [curvature] Curve control-point reach along the dominant axis (curve shape). Default 0.5.
|
|
136
|
+
* @property {number} [mid] Turn position 0..1 along the span (elbow shape). Default 0.5.
|
|
137
|
+
*
|
|
138
|
+
* @typedef {object} ConnectRectsOptions
|
|
139
|
+
* @property {Rect} fromRect
|
|
140
|
+
* @property {Rect} toRect
|
|
141
|
+
* @property {Side} [fromSide] Anchor edges. Omit both to auto-pick facing edges from the rects.
|
|
142
|
+
* @property {Side} [toSide]
|
|
143
|
+
* @property {ConnectorShape} [shape]
|
|
144
|
+
* @property {number} [curvature]
|
|
145
|
+
* @property {number} [mid]
|
|
146
|
+
*
|
|
147
|
+
* @typedef {object} ConnectRectsResult
|
|
148
|
+
* @property {string} d SVG path data.
|
|
149
|
+
* @property {Point} from
|
|
150
|
+
* @property {Point} to
|
|
151
|
+
* @property {number} angle The path's end-tangent at `to` in radians — the direction the path arrives, so rotating an arrowhead at `to` by this points it along the path. Equals the straight `from`→`to` angle for `shape: 'straight'`; axis-aligned for `elbow`/`curve`.
|
|
152
|
+
*/
|
|
153
|
+
export const PRECISION: 1000;
|
|
154
|
+
export type Point = {
|
|
155
|
+
x: number;
|
|
156
|
+
y: number;
|
|
157
|
+
};
|
|
158
|
+
export type Rect = {
|
|
159
|
+
x: number;
|
|
160
|
+
y: number;
|
|
161
|
+
width: number;
|
|
162
|
+
height: number;
|
|
163
|
+
};
|
|
164
|
+
export type Side = "top" | "right" | "bottom" | "left" | "center";
|
|
165
|
+
export type ConnectorShape = "straight" | "elbow" | "curve";
|
|
166
|
+
export type ConnectorPathOptions = {
|
|
167
|
+
from: Point;
|
|
168
|
+
to: Point;
|
|
169
|
+
shape?: ConnectorShape | undefined;
|
|
170
|
+
/**
|
|
171
|
+
* Curve control-point reach along the dominant axis (curve shape). Default 0.5.
|
|
172
|
+
*/
|
|
173
|
+
curvature?: number | undefined;
|
|
174
|
+
/**
|
|
175
|
+
* Turn position 0..1 along the span (elbow shape). Default 0.5.
|
|
176
|
+
*/
|
|
177
|
+
mid?: number | undefined;
|
|
178
|
+
};
|
|
179
|
+
export type ConnectRectsOptions = {
|
|
180
|
+
fromRect: Rect;
|
|
181
|
+
toRect: Rect;
|
|
182
|
+
/**
|
|
183
|
+
* Anchor edges. Omit both to auto-pick facing edges from the rects.
|
|
184
|
+
*/
|
|
185
|
+
fromSide?: Side | undefined;
|
|
186
|
+
toSide?: Side | undefined;
|
|
187
|
+
shape?: ConnectorShape | undefined;
|
|
188
|
+
curvature?: number | undefined;
|
|
189
|
+
mid?: number | undefined;
|
|
190
|
+
};
|
|
191
|
+
export type ConnectRectsResult = {
|
|
192
|
+
/**
|
|
193
|
+
* SVG path data.
|
|
194
|
+
*/
|
|
195
|
+
d: string;
|
|
196
|
+
from: Point;
|
|
197
|
+
to: Point;
|
|
198
|
+
/**
|
|
199
|
+
* The path's end-tangent at `to` in radians — the direction the path arrives, so rotating an arrowhead at `to` by this points it along the path. Equals the straight `from`→`to` angle for `shape: 'straight'`; axis-aligned for `elbow`/`curve`.
|
|
200
|
+
*/
|
|
201
|
+
angle: number;
|
|
202
|
+
};
|
|
203
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAkDA,kEAIC;AAED,qEAIC;AAKD,gDAGC;AAED,wCAEC;AAED,8CAEC;AAID,2DAGC;AAED;;;;;GAKG;AACH,kCAJW,IAAI,SACJ,IAAI,GACF,KAAK,CAoBjB;AAED;;;;;GAKG;AACH,mCAJW,KAAK,MACL,KAAK,GACH,MAAM,CAOlB;AAED;;;;;GAKG;AACH,mCAJW,KAAK,MACL,KAAK,GACH,MAAM,CAOlB;AAED;;;;;;GAMG;AACH,gCALW,KAAK,MACL,KAAK,SACL;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACd,MAAM,CAgBlB;AAED;;;;;;GAMG;AACH,gCALW,KAAK,MACL,KAAK,SACL;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACpB,MAAM,CAclB;AAED;;;;GAIG;AACH,qCAHW,oBAAoB,GAClB,MAAM,CAOlB;AAED;;;;;;;;GAQG;AACH,6BAPW,KAAK,SACL,MAAM,SACN,MAAM,WACN,MAAM,GAEJ,MAAM,CAalB;AAED;;;;;GAKG;AACH,2BAJW,KAAK,WACL,MAAM,GACJ,MAAM,CAUlB;AAED;;;;;;;;;GASG;AACH,+BANW,MAAM,OACN,MAAM,SACN,MAAM,UACN,MAAM,GACJ,MAAM,CAIlB;AAED;;;;;GAKG;AACH,oCAJW,IAAI,UACJ,IAAI,GACF;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,IAAI,CAAA;CAAE,CAWpC;AAED;;;;;;;;GAQG;AACH,sCALW,KAAK,MACL,KAAK,UACL,cAAc,GACZ,MAAM,CAQlB;AAED;;;;;;GAMG;AACH,oCAHW,mBAAmB,GACjB,kBAAkB,CAW9B;AAvSD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAMH,wBAAyB,IAAI,CAAC;oBAhCjB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE;mBACxB;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;mBACvD,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ;6BAC9C,UAAU,GAAG,OAAO,GAAG,OAAO;;UAG7B,KAAK;QACL,KAAK;;;;;;;;;;;;cAML,IAAI;YACJ,IAAI;;;;;;;;;;;;;;OAQJ,MAAM;UACN,KAAK;QACL,KAAK;;;;WACL,MAAM"}
|
package/connectors/index.js
CHANGED
|
@@ -10,36 +10,85 @@
|
|
|
10
10
|
*
|
|
11
11
|
* import { connectRects } from '@ponchia/ui/connectors';
|
|
12
12
|
* const { d } = connectRects({ fromRect: a, toRect: b, shape: 'elbow' });
|
|
13
|
+
*
|
|
14
|
+
* The public types below are JSDoc `@typedef`s; the shipped `index.d.ts` is
|
|
15
|
+
* generated from them (and these signatures) by `tsc --emitDeclarationOnly`.
|
|
16
|
+
*
|
|
17
|
+
* @typedef {{ x: number, y: number }} Point
|
|
18
|
+
* @typedef {{ x: number, y: number, width: number, height: number }} Rect
|
|
19
|
+
* @typedef {'top' | 'right' | 'bottom' | 'left' | 'center'} Side
|
|
20
|
+
* @typedef {'straight' | 'elbow' | 'curve'} ConnectorShape
|
|
21
|
+
*
|
|
22
|
+
* @typedef {object} ConnectorPathOptions
|
|
23
|
+
* @property {Point} from
|
|
24
|
+
* @property {Point} to
|
|
25
|
+
* @property {ConnectorShape} [shape]
|
|
26
|
+
* @property {number} [curvature] Curve control-point reach along the dominant axis (curve shape). Default 0.5.
|
|
27
|
+
* @property {number} [mid] Turn position 0..1 along the span (elbow shape). Default 0.5.
|
|
28
|
+
*
|
|
29
|
+
* @typedef {object} ConnectRectsOptions
|
|
30
|
+
* @property {Rect} fromRect
|
|
31
|
+
* @property {Rect} toRect
|
|
32
|
+
* @property {Side} [fromSide] Anchor edges. Omit both to auto-pick facing edges from the rects.
|
|
33
|
+
* @property {Side} [toSide]
|
|
34
|
+
* @property {ConnectorShape} [shape]
|
|
35
|
+
* @property {number} [curvature]
|
|
36
|
+
* @property {number} [mid]
|
|
37
|
+
*
|
|
38
|
+
* @typedef {object} ConnectRectsResult
|
|
39
|
+
* @property {string} d SVG path data.
|
|
40
|
+
* @property {Point} from
|
|
41
|
+
* @property {Point} to
|
|
42
|
+
* @property {number} angle The path's end-tangent at `to` in radians — the direction the path arrives, so rotating an arrowhead at `to` by this points it along the path. Equals the straight `from`→`to` angle for `shape: 'straight'`; axis-aligned for `elbow`/`curve`.
|
|
13
43
|
*/
|
|
14
44
|
|
|
15
|
-
|
|
45
|
+
// Shared scalar/geometry primitives. Exported so the annotations layer composes
|
|
46
|
+
// on the SAME kernel instead of copy-pasting it (the copies had silently
|
|
47
|
+
// diverged — see `clamp`). Low-level helpers; the documented API is the path
|
|
48
|
+
// builders below.
|
|
49
|
+
export const PRECISION = 1000;
|
|
16
50
|
|
|
17
|
-
function finite(name, value, fallback) {
|
|
51
|
+
export function finite(name, value, fallback) {
|
|
18
52
|
const v = value ?? fallback;
|
|
19
53
|
if (!Number.isFinite(v)) throw new TypeError(`${name} must be a finite number`);
|
|
20
54
|
return v;
|
|
21
55
|
}
|
|
22
56
|
|
|
23
|
-
function dimension(name, value, fallback) {
|
|
57
|
+
export function dimension(name, value, fallback) {
|
|
24
58
|
const v = finite(name, value, fallback);
|
|
25
59
|
if (v < 0) throw new RangeError(`${name} must be greater than or equal to 0`);
|
|
26
60
|
return v;
|
|
27
61
|
}
|
|
28
62
|
|
|
29
|
-
|
|
63
|
+
// Round to PRECISION, normalising -0 → 0, and return the NUMBER (the numeric
|
|
64
|
+
// core `fmt` stringifies). Shared with the annotations layer for the rounded
|
|
65
|
+
// coordinates it echoes back to the host. (code-quality audit Q5.)
|
|
66
|
+
export function roundNumber(value) {
|
|
30
67
|
const rounded = Math.round((Object.is(value, -0) ? 0 : value) * PRECISION) / PRECISION;
|
|
31
|
-
return
|
|
68
|
+
return Object.is(rounded, -0) ? 0 : rounded;
|
|
32
69
|
}
|
|
33
70
|
|
|
34
|
-
function
|
|
71
|
+
export function fmt(value) {
|
|
72
|
+
return String(roundNumber(value));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function point(x, y) {
|
|
35
76
|
return `${fmt(x)},${fmt(y)}`;
|
|
36
77
|
}
|
|
37
78
|
|
|
38
|
-
|
|
79
|
+
// Guarded form (returns min when the range is inverted) — the reconciled body;
|
|
80
|
+
// connectors only ever calls clamp(v, 0, 1) so this is output-identical here.
|
|
81
|
+
export function clamp(value, min, max) {
|
|
82
|
+
if (max < min) return min;
|
|
39
83
|
return Math.min(max, Math.max(min, value));
|
|
40
84
|
}
|
|
41
85
|
|
|
42
|
-
/**
|
|
86
|
+
/**
|
|
87
|
+
* A point on a rect's edge (or centre). `rect` is `{ x, y, width, height }`.
|
|
88
|
+
* @param {Rect} rect
|
|
89
|
+
* @param {Side} [side]
|
|
90
|
+
* @returns {Point}
|
|
91
|
+
*/
|
|
43
92
|
export function anchorPoint(rect, side = 'center') {
|
|
44
93
|
const x = finite('rect.x', rect?.x, 0);
|
|
45
94
|
const y = finite('rect.y', rect?.y, 0);
|
|
@@ -60,7 +109,12 @@ export function anchorPoint(rect, side = 'center') {
|
|
|
60
109
|
}
|
|
61
110
|
}
|
|
62
111
|
|
|
63
|
-
/**
|
|
112
|
+
/**
|
|
113
|
+
* Angle (radians) from `from` to `to`.
|
|
114
|
+
* @param {Point} from
|
|
115
|
+
* @param {Point} to
|
|
116
|
+
* @returns {number}
|
|
117
|
+
*/
|
|
64
118
|
export function angleBetween(from, to) {
|
|
65
119
|
return Math.atan2(
|
|
66
120
|
finite('to.y', to?.y) - finite('from.y', from?.y),
|
|
@@ -68,6 +122,12 @@ export function angleBetween(from, to) {
|
|
|
68
122
|
);
|
|
69
123
|
}
|
|
70
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Straight line from `from` to `to`.
|
|
127
|
+
* @param {Point} from
|
|
128
|
+
* @param {Point} to
|
|
129
|
+
* @returns {string}
|
|
130
|
+
*/
|
|
71
131
|
export function straightPath(from, to) {
|
|
72
132
|
return `M${point(finite('from.x', from?.x), finite('from.y', from?.y))}L${point(
|
|
73
133
|
finite('to.x', to?.x),
|
|
@@ -75,7 +135,13 @@ export function straightPath(from, to) {
|
|
|
75
135
|
)}`;
|
|
76
136
|
}
|
|
77
137
|
|
|
78
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* Right-angle dogleg. Turns on the dominant axis at `mid` (0..1) of the span.
|
|
140
|
+
* @param {Point} from
|
|
141
|
+
* @param {Point} to
|
|
142
|
+
* @param {{ mid?: number }} [opts]
|
|
143
|
+
* @returns {string}
|
|
144
|
+
*/
|
|
79
145
|
export function elbowPath(from, to, opts = {}) {
|
|
80
146
|
const fx = finite('from.x', from?.x);
|
|
81
147
|
const fy = finite('from.y', from?.y);
|
|
@@ -92,7 +158,13 @@ export function elbowPath(from, to, opts = {}) {
|
|
|
92
158
|
return `M${point(fx, fy)}V${fmt(my)}H${fmt(tx)}V${fmt(ty)}`;
|
|
93
159
|
}
|
|
94
160
|
|
|
95
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* Cubic curve; control points extend along the dominant axis by `curvature`.
|
|
163
|
+
* @param {Point} from
|
|
164
|
+
* @param {Point} to
|
|
165
|
+
* @param {{ curvature?: number }} [opts]
|
|
166
|
+
* @returns {string}
|
|
167
|
+
*/
|
|
96
168
|
export function curvePath(from, to, opts = {}) {
|
|
97
169
|
const fx = finite('from.x', from?.x);
|
|
98
170
|
const fy = finite('from.y', from?.y);
|
|
@@ -107,7 +179,11 @@ export function curvePath(from, to, opts = {}) {
|
|
|
107
179
|
return `M${point(fx, fy)}C${point(c1.x, c1.y)} ${point(c2.x, c2.y)} ${point(tx, ty)}`;
|
|
108
180
|
}
|
|
109
181
|
|
|
110
|
-
/**
|
|
182
|
+
/**
|
|
183
|
+
* Build a path between two points by `shape` (`straight` | `elbow` | `curve`).
|
|
184
|
+
* @param {ConnectorPathOptions} [opts]
|
|
185
|
+
* @returns {string}
|
|
186
|
+
*/
|
|
111
187
|
export function connectorPath(opts = {}) {
|
|
112
188
|
const { from, to, shape = 'straight' } = opts;
|
|
113
189
|
if (shape === 'elbow') return elbowPath(from, to, opts);
|
|
@@ -115,20 +191,34 @@ export function connectorPath(opts = {}) {
|
|
|
115
191
|
return straightPath(from, to);
|
|
116
192
|
}
|
|
117
193
|
|
|
118
|
-
/**
|
|
119
|
-
|
|
194
|
+
/**
|
|
195
|
+
* A filled triangle arrowhead at `p`, pointing along `angle` (radians).
|
|
196
|
+
* @param {Point} p
|
|
197
|
+
* @param {number} angle
|
|
198
|
+
* @param {number} [size]
|
|
199
|
+
* @param {number} [spread] Half-angle of the head in radians (default 0.45).
|
|
200
|
+
* Smaller is crisper/sharper; must be in (0, π/2).
|
|
201
|
+
* @returns {string}
|
|
202
|
+
*/
|
|
203
|
+
export function arrowHead(p, angle, size = 8, spread = 0.45) {
|
|
120
204
|
const px = finite('p.x', p?.x);
|
|
121
205
|
const py = finite('p.y', p?.y);
|
|
122
206
|
const a = finite('angle', angle, 0);
|
|
123
207
|
const s = dimension('size', size, 8);
|
|
208
|
+
const sp = finite('spread', spread, 0.45);
|
|
209
|
+
if (sp <= 0 || sp >= Math.PI / 2) throw new RangeError('spread must be in (0, π/2)');
|
|
124
210
|
const back = a + Math.PI;
|
|
125
|
-
const
|
|
126
|
-
const
|
|
127
|
-
const p2 = { x: px + Math.cos(back + spread) * s, y: py + Math.sin(back + spread) * s };
|
|
211
|
+
const p1 = { x: px + Math.cos(back - sp) * s, y: py + Math.sin(back - sp) * s };
|
|
212
|
+
const p2 = { x: px + Math.cos(back + sp) * s, y: py + Math.sin(back + sp) * s };
|
|
128
213
|
return `M${point(px, py)}L${point(p1.x, p1.y)}L${point(p2.x, p2.y)}Z`;
|
|
129
214
|
}
|
|
130
215
|
|
|
131
|
-
/**
|
|
216
|
+
/**
|
|
217
|
+
* A filled dot at `p`.
|
|
218
|
+
* @param {Point} p
|
|
219
|
+
* @param {number} [radius]
|
|
220
|
+
* @returns {string}
|
|
221
|
+
*/
|
|
132
222
|
export function dotMark(p, radius = 3) {
|
|
133
223
|
const px = finite('p.x', p?.x);
|
|
134
224
|
const py = finite('p.y', p?.y);
|
|
@@ -139,7 +229,26 @@ export function dotMark(p, radius = 3) {
|
|
|
139
229
|
)} 0 1 1 ${point(px, py - r)}Z`;
|
|
140
230
|
}
|
|
141
231
|
|
|
142
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* An axis-aligned rectangle path from its corners (callers derive the corners
|
|
234
|
+
* from a centre or a top-left as they need). Shared by the annotation
|
|
235
|
+
* rect/band and evidence-marker subjects. (code-quality audit Q5.)
|
|
236
|
+
* @param {number} left
|
|
237
|
+
* @param {number} top
|
|
238
|
+
* @param {number} right
|
|
239
|
+
* @param {number} bottom
|
|
240
|
+
* @returns {string}
|
|
241
|
+
*/
|
|
242
|
+
export function rectPath(left, top, right, bottom) {
|
|
243
|
+
return `M${point(left, top)}H${fmt(right)}V${fmt(bottom)}H${fmt(left)}Z`;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Pick facing edges from the rects' relative centres.
|
|
248
|
+
* @param {Rect} fromRect
|
|
249
|
+
* @param {Rect} toRect
|
|
250
|
+
* @returns {{ from: Side, to: Side }}
|
|
251
|
+
*/
|
|
143
252
|
export function autoSides(fromRect, toRect) {
|
|
144
253
|
const fc = anchorPoint(fromRect, 'center');
|
|
145
254
|
const tc = anchorPoint(toRect, 'center');
|
|
@@ -152,13 +261,14 @@ export function autoSides(fromRect, toRect) {
|
|
|
152
261
|
}
|
|
153
262
|
|
|
154
263
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
264
|
+
* Angle (radians) at which a `shape` path *arrives* at `to` — straight is the
|
|
265
|
+
* chord; elbow/curve arrive axis-aligned along the dominant axis. Rotate an
|
|
266
|
+
* end marker by this so it points along the path, not the chord.
|
|
267
|
+
* @param {Point} from
|
|
268
|
+
* @param {Point} to
|
|
269
|
+
* @param {ConnectorShape} [shape]
|
|
270
|
+
* @returns {number}
|
|
158
271
|
*/
|
|
159
|
-
/** Angle (radians) at which a `shape` path *arrives* at `to` — straight is the
|
|
160
|
-
* chord; elbow/curve arrive axis-aligned along the dominant axis. Rotate an
|
|
161
|
-
* end marker by this so it points along the path, not the chord. */
|
|
162
272
|
export function endTangentAngle(from, to, shape = 'straight') {
|
|
163
273
|
if (shape === 'straight') return angleBetween(from, to);
|
|
164
274
|
const dx = finite('to.x', to?.x) - finite('from.x', from?.x);
|
|
@@ -167,6 +277,13 @@ export function endTangentAngle(from, to, shape = 'straight') {
|
|
|
167
277
|
return dy >= 0 ? Math.PI / 2 : -Math.PI / 2;
|
|
168
278
|
}
|
|
169
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Connect two rects. Resolves anchor points (explicit `fromSide`/`toSide`, else
|
|
282
|
+
* auto), builds the path, and returns `{ d, from, to, angle }` so the caller can
|
|
283
|
+
* place an arrowhead/dot at `to` rotated by `angle`.
|
|
284
|
+
* @param {ConnectRectsOptions} [opts]
|
|
285
|
+
* @returns {ConnectRectsResult}
|
|
286
|
+
*/
|
|
170
287
|
export function connectRects(opts = {}) {
|
|
171
288
|
const { fromRect, toRect, shape = 'straight', curvature, mid } = opts;
|
|
172
289
|
// Honor each side override independently; auto-pick whichever is unset.
|