@coral-viz/viz 0.2.3 → 0.2.4
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/README.md +4 -0
- package/dist/compatibility/CompatibilityEdge.d.ts +9 -11
- package/dist/compatibility/CompatibilityEdge.d.ts.map +1 -1
- package/dist/compatibility/CompatibilityEdge.js +136 -27
- package/dist/compatibility/CompatibilityEdge.js.map +1 -1
- package/dist/components/DiagramFontFaces.d.ts +8 -0
- package/dist/components/DiagramFontFaces.d.ts.map +1 -0
- package/dist/components/DiagramFontFaces.js +18 -0
- package/dist/components/DiagramFontFaces.js.map +1 -0
- package/dist/components/SymbolNode.d.ts.map +1 -1
- package/dist/components/SymbolNode.js +46 -11
- package/dist/components/SymbolNode.js.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +1 -0
- package/dist/components/index.js.map +1 -1
- package/dist/editor/CoralEditor.js +1 -1
- package/dist/editor/CoralEditor.js.map +1 -1
- package/dist/editor/converter.d.ts +1 -1
- package/dist/editor/converter.d.ts.map +1 -1
- package/dist/editor/converter.js +40 -19
- package/dist/editor/converter.js.map +1 -1
- package/dist/editor/dimensions.d.ts +7 -0
- package/dist/editor/dimensions.d.ts.map +1 -0
- package/dist/editor/dimensions.js +26 -0
- package/dist/editor/dimensions.js.map +1 -0
- package/dist/file/deserialize.d.ts.map +1 -1
- package/dist/file/deserialize.js +8 -13
- package/dist/file/deserialize.js.map +1 -1
- package/dist/file/index.d.ts +2 -1
- package/dist/file/index.d.ts.map +1 -1
- package/dist/file/index.js +2 -1
- package/dist/file/index.js.map +1 -1
- package/dist/file/layoutProfile.d.ts +11 -0
- package/dist/file/layoutProfile.d.ts.map +1 -0
- package/dist/file/layoutProfile.js +89 -0
- package/dist/file/layoutProfile.js.map +1 -0
- package/dist/file/schema.d.ts +27 -0
- package/dist/file/schema.d.ts.map +1 -1
- package/dist/file/schema.js +70 -0
- package/dist/file/schema.js.map +1 -1
- package/dist/file/serialize.d.ts.map +1 -1
- package/dist/file/serialize.js +23 -10
- package/dist/file/serialize.js.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/layout/elk.d.ts +2 -51
- package/dist/layout/elk.d.ts.map +1 -1
- package/dist/layout/elk.js +125 -329
- package/dist/layout/elk.js.map +1 -1
- package/dist/layout/nodeSizing.d.ts +4 -61
- package/dist/layout/nodeSizing.d.ts.map +1 -1
- package/dist/layout/nodeSizing.js +4 -315
- package/dist/layout/nodeSizing.js.map +1 -1
- package/dist/layout/positionStability.d.ts.map +1 -1
- package/dist/layout/positionStability.js +21 -26
- package/dist/layout/positionStability.js.map +1 -1
- package/dist/layout/useAxisConstrain.d.ts.map +1 -1
- package/dist/layout/useAxisConstrain.js +20 -20
- package/dist/layout/useAxisConstrain.js.map +1 -1
- package/dist/layout/useDiagramState.d.ts +2 -1
- package/dist/layout/useDiagramState.d.ts.map +1 -1
- package/dist/layout/useLayoutHistory.d.ts.map +1 -1
- package/dist/layout/useLayoutHistory.js +67 -100
- package/dist/layout/useLayoutHistory.js.map +1 -1
- package/dist/settings/FontSettingsForm.d.ts.map +1 -1
- package/dist/settings/FontSettingsForm.js +9 -4
- package/dist/settings/FontSettingsForm.js.map +1 -1
- package/dist/settings/LayoutSettingsForm.d.ts +3 -1
- package/dist/settings/LayoutSettingsForm.d.ts.map +1 -1
- package/dist/settings/LayoutSettingsForm.js +43 -20
- package/dist/settings/LayoutSettingsForm.js.map +1 -1
- package/dist/settings/SettingsPanel.d.ts +10 -2
- package/dist/settings/SettingsPanel.d.ts.map +1 -1
- package/dist/settings/SettingsPanel.js +45 -3
- package/dist/settings/SettingsPanel.js.map +1 -1
- package/dist/settings/useSettings.d.ts +8 -2
- package/dist/settings/useSettings.d.ts.map +1 -1
- package/dist/settings/useSettings.js +20 -5
- package/dist/settings/useSettings.js.map +1 -1
- package/dist/text-editor/SplitEditor.d.ts +5 -1
- package/dist/text-editor/SplitEditor.d.ts.map +1 -1
- package/dist/text-editor/SplitEditor.js +5 -12
- package/dist/text-editor/SplitEditor.js.map +1 -1
- package/dist/text-editor/TextEditor.d.ts +44 -33
- package/dist/text-editor/TextEditor.d.ts.map +1 -1
- package/dist/text-editor/TextEditor.js +174 -168
- package/dist/text-editor/TextEditor.js.map +1 -1
- package/dist/text-editor/hooks/useBidirectionalSync.d.ts +15 -0
- package/dist/text-editor/hooks/useBidirectionalSync.d.ts.map +1 -1
- package/dist/text-editor/hooks/useBidirectionalSync.js +9 -22
- package/dist/text-editor/hooks/useBidirectionalSync.js.map +1 -1
- package/dist/text-editor/index.d.ts +2 -2
- package/dist/text-editor/index.d.ts.map +1 -1
- package/dist/text-editor/index.js +1 -1
- package/dist/text-editor/index.js.map +1 -1
- package/dist/types.d.ts +22 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +4 -1
- package/dist/types.js.map +1 -1
- package/dist/viewMetadata.d.ts +4 -0
- package/dist/viewMetadata.d.ts.map +1 -0
- package/dist/viewMetadata.js +63 -0
- package/dist/viewMetadata.js.map +1 -0
- package/dist/waypoints/useWaypointManager.d.ts.map +1 -1
- package/dist/waypoints/useWaypointManager.js +60 -84
- package/dist/waypoints/useWaypointManager.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,319 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Compatibility exports for deterministic node sizing.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* - Shape geometry constraints (textBoundsRatio)
|
|
7
|
-
* - Minimum size requirements
|
|
8
|
-
* - Padding specifications
|
|
4
|
+
* The implementation lives in @coral-viz/render so the editor, server-side
|
|
5
|
+
* renderer, exporters, and MCP tools all use the same bundled font metrics.
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Default sizing for shapes without explicit sizing metadata
|
|
13
|
-
*/
|
|
14
|
-
const DEFAULT_SIZING = {
|
|
15
|
-
textBoundsRatio: { x: 1.0, y: 1.0 },
|
|
16
|
-
minSize: { width: 60, height: 30 },
|
|
17
|
-
padding: { x: 16, y: 12 },
|
|
18
|
-
};
|
|
19
|
-
/**
|
|
20
|
-
* Default font settings
|
|
21
|
-
*/
|
|
22
|
-
const DEFAULT_FONT = {
|
|
23
|
-
fontSize: 12,
|
|
24
|
-
fontFamily: 'system-ui, -apple-system, sans-serif',
|
|
25
|
-
fontWeight: 500,
|
|
26
|
-
lineHeight: 1.4,
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Canvas context for text measurement (cached for performance)
|
|
30
|
-
*/
|
|
31
|
-
let measureContext = null;
|
|
32
|
-
/**
|
|
33
|
-
* Get or create a canvas context for text measurement
|
|
34
|
-
*/
|
|
35
|
-
function getMeasureContext() {
|
|
36
|
-
if (measureContext) {
|
|
37
|
-
return measureContext;
|
|
38
|
-
}
|
|
39
|
-
// Check if we're in a browser environment
|
|
40
|
-
if (typeof document === 'undefined') {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
const canvas = document.createElement('canvas');
|
|
44
|
-
measureContext = canvas.getContext('2d');
|
|
45
|
-
return measureContext;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Measure text dimensions using canvas
|
|
49
|
-
*
|
|
50
|
-
* Uses the Canvas API's measureText() for accurate text width measurement,
|
|
51
|
-
* with word wrapping support when maxWidth is specified.
|
|
52
|
-
*/
|
|
53
|
-
export function measureText(options) {
|
|
54
|
-
const { text, fontSize = DEFAULT_FONT.fontSize, fontFamily = DEFAULT_FONT.fontFamily, fontWeight = DEFAULT_FONT.fontWeight, maxWidth, lineHeight = DEFAULT_FONT.lineHeight, } = options;
|
|
55
|
-
const ctx = getMeasureContext();
|
|
56
|
-
// Fallback for non-browser environments (SSR, tests)
|
|
57
|
-
if (!ctx) {
|
|
58
|
-
return measureTextFallback(options);
|
|
59
|
-
}
|
|
60
|
-
// Set font for measurement
|
|
61
|
-
ctx.font = `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
62
|
-
// If no max width, measure as single line
|
|
63
|
-
if (!maxWidth) {
|
|
64
|
-
const metrics = ctx.measureText(text);
|
|
65
|
-
return {
|
|
66
|
-
width: Math.ceil(metrics.width),
|
|
67
|
-
height: Math.ceil(fontSize * lineHeight),
|
|
68
|
-
lines: [text],
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
// Word wrap to fit maxWidth
|
|
72
|
-
const lines = wrapText(ctx, text, maxWidth);
|
|
73
|
-
const lineHeightPx = fontSize * lineHeight;
|
|
74
|
-
// Find the widest line
|
|
75
|
-
let maxLineWidth = 0;
|
|
76
|
-
for (const line of lines) {
|
|
77
|
-
const metrics = ctx.measureText(line);
|
|
78
|
-
maxLineWidth = Math.max(maxLineWidth, metrics.width);
|
|
79
|
-
}
|
|
80
|
-
return {
|
|
81
|
-
width: Math.ceil(maxLineWidth),
|
|
82
|
-
height: Math.ceil(lines.length * lineHeightPx),
|
|
83
|
-
lines,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Wrap text to fit within maxWidth
|
|
88
|
-
*/
|
|
89
|
-
function wrapText(ctx, text, maxWidth) {
|
|
90
|
-
// Handle empty text
|
|
91
|
-
if (!text || text.trim() === '') {
|
|
92
|
-
return [''];
|
|
93
|
-
}
|
|
94
|
-
// Split by explicit line breaks first
|
|
95
|
-
const paragraphs = text.split('\n');
|
|
96
|
-
const lines = [];
|
|
97
|
-
for (const paragraph of paragraphs) {
|
|
98
|
-
const words = paragraph.split(/\s+/).filter((w) => w.length > 0);
|
|
99
|
-
if (words.length === 0) {
|
|
100
|
-
lines.push('');
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
let currentLine = words[0];
|
|
104
|
-
for (let i = 1; i < words.length; i++) {
|
|
105
|
-
const word = words[i];
|
|
106
|
-
const testLine = currentLine + ' ' + word;
|
|
107
|
-
const metrics = ctx.measureText(testLine);
|
|
108
|
-
if (metrics.width <= maxWidth) {
|
|
109
|
-
currentLine = testLine;
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
lines.push(currentLine);
|
|
113
|
-
currentLine = word;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
lines.push(currentLine);
|
|
117
|
-
}
|
|
118
|
-
return lines;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Fallback text measurement for non-browser environments
|
|
122
|
-
* Uses character-based approximation
|
|
123
|
-
*/
|
|
124
|
-
function measureTextFallback(options) {
|
|
125
|
-
const { text, fontSize = DEFAULT_FONT.fontSize, lineHeight = DEFAULT_FONT.lineHeight, maxWidth, } = options;
|
|
126
|
-
// Approximate character width (varies by font, but 0.6 is reasonable for sans-serif)
|
|
127
|
-
const avgCharWidth = fontSize * 0.6;
|
|
128
|
-
const lineHeightPx = fontSize * lineHeight;
|
|
129
|
-
// Always split by newlines first
|
|
130
|
-
const paragraphs = text.split('\n');
|
|
131
|
-
if (!maxWidth) {
|
|
132
|
-
// No wrapping, just return paragraphs as lines
|
|
133
|
-
const maxLineWidth = Math.max(0, ...paragraphs.map((p) => p.length * avgCharWidth));
|
|
134
|
-
return {
|
|
135
|
-
width: Math.ceil(maxLineWidth),
|
|
136
|
-
height: Math.ceil(paragraphs.length * lineHeightPx),
|
|
137
|
-
lines: paragraphs,
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
// Approximate word wrapping
|
|
141
|
-
const charsPerLine = Math.floor(maxWidth / avgCharWidth);
|
|
142
|
-
const lines = [];
|
|
143
|
-
for (const paragraph of paragraphs) {
|
|
144
|
-
if (paragraph.length === 0) {
|
|
145
|
-
lines.push('');
|
|
146
|
-
}
|
|
147
|
-
else if (paragraph.length <= charsPerLine) {
|
|
148
|
-
lines.push(paragraph);
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
// Simple word-aware wrapping
|
|
152
|
-
const words = paragraph.split(/\s+/);
|
|
153
|
-
let currentLine = '';
|
|
154
|
-
for (const word of words) {
|
|
155
|
-
if ((currentLine + ' ' + word).length <= charsPerLine) {
|
|
156
|
-
currentLine = currentLine ? currentLine + ' ' + word : word;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
if (currentLine)
|
|
160
|
-
lines.push(currentLine);
|
|
161
|
-
currentLine = word;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (currentLine)
|
|
165
|
-
lines.push(currentLine);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
const maxLineWidth = Math.max(0, ...lines.map((l) => l.length * avgCharWidth));
|
|
169
|
-
return {
|
|
170
|
-
width: Math.ceil(maxLineWidth),
|
|
171
|
-
height: Math.ceil(lines.length * lineHeightPx),
|
|
172
|
-
lines,
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Compute optimal node size based on text content and shape geometry
|
|
177
|
-
*
|
|
178
|
-
* The sizing algorithm:
|
|
179
|
-
* 1. Measure text dimensions
|
|
180
|
-
* 2. Apply shape's textBoundsRatio to account for geometry (e.g., diamond needs more space)
|
|
181
|
-
* 3. Add padding for visual breathing room
|
|
182
|
-
* 4. Enforce minimum size constraints
|
|
183
|
-
* 5. Optionally apply uniform sizing across nodes of the same shape
|
|
184
|
-
*/
|
|
185
|
-
export function computeNodeSize(options) {
|
|
186
|
-
const { text, shapeId, sizingMode, fontSize = DEFAULT_FONT.fontSize, fontFamily = DEFAULT_FONT.fontFamily, fontWeight = DEFAULT_FONT.fontWeight, minWidth, minHeight, uniformSizes, } = options;
|
|
187
|
-
// Get shape definition and sizing metadata
|
|
188
|
-
const shape = shapeRegistry.get(shapeId);
|
|
189
|
-
const sizing = shape?.sizing || DEFAULT_SIZING;
|
|
190
|
-
const defaultSize = shape?.defaultSize || { width: 100, height: 60 };
|
|
191
|
-
// For uniform mode, use cached sizes if available
|
|
192
|
-
if (sizingMode === 'uniform' && uniformSizes?.has(shapeId)) {
|
|
193
|
-
const uniformSize = uniformSizes.get(shapeId);
|
|
194
|
-
return {
|
|
195
|
-
width: uniformSize.width,
|
|
196
|
-
height: uniformSize.height,
|
|
197
|
-
textBox: computeTextBox(uniformSize.width, uniformSize.height, sizing),
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
// Measure text with initial max width estimate
|
|
201
|
-
const initialMaxWidth = defaultSize.width - sizing.padding.x * 2;
|
|
202
|
-
const textDims = measureText({
|
|
203
|
-
text: text || '',
|
|
204
|
-
fontSize,
|
|
205
|
-
fontFamily,
|
|
206
|
-
fontWeight,
|
|
207
|
-
maxWidth: initialMaxWidth > 0 ? initialMaxWidth : undefined,
|
|
208
|
-
});
|
|
209
|
-
// Apply textBoundsRatio to account for shape geometry
|
|
210
|
-
// For a diamond, text occupies ~70% of the bounding box, so ratio is 1.45
|
|
211
|
-
const contentWidth = textDims.width * sizing.textBoundsRatio.x + sizing.padding.x * 2;
|
|
212
|
-
const contentHeight = textDims.height * sizing.textBoundsRatio.y + sizing.padding.y * 2;
|
|
213
|
-
// Determine final size based on sizing mode
|
|
214
|
-
let width;
|
|
215
|
-
let height;
|
|
216
|
-
switch (sizingMode) {
|
|
217
|
-
case 'adaptive':
|
|
218
|
-
// Size adapts to content
|
|
219
|
-
width = Math.max(contentWidth, sizing.minSize.width, minWidth || 0);
|
|
220
|
-
height = Math.max(contentHeight, sizing.minSize.height, minHeight || 0);
|
|
221
|
-
break;
|
|
222
|
-
case 'uniform':
|
|
223
|
-
// All nodes of this shape use the same size (largest needed)
|
|
224
|
-
// This will be populated on a second pass
|
|
225
|
-
width = Math.max(contentWidth, sizing.minSize.width, minWidth || 0);
|
|
226
|
-
height = Math.max(contentHeight, sizing.minSize.height, minHeight || 0);
|
|
227
|
-
break;
|
|
228
|
-
case 'hybrid':
|
|
229
|
-
default:
|
|
230
|
-
// Blend: adaptive width, uniform height per shape type
|
|
231
|
-
width = Math.max(contentWidth, sizing.minSize.width, minWidth || 0);
|
|
232
|
-
height = Math.max(sizing.minSize.height, defaultSize.height, minHeight || 0);
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
// Round to reasonable values
|
|
236
|
-
width = Math.ceil(width);
|
|
237
|
-
height = Math.ceil(height);
|
|
238
|
-
return {
|
|
239
|
-
width,
|
|
240
|
-
height,
|
|
241
|
-
textBox: computeTextBox(width, height, sizing),
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Compute the text bounding box within a node
|
|
246
|
-
* This is where text can be safely rendered without clipping
|
|
247
|
-
*/
|
|
248
|
-
function computeTextBox(width, height, sizing) {
|
|
249
|
-
// Text box is centered within the shape, reduced by the textBoundsRatio
|
|
250
|
-
const textWidth = (width - sizing.padding.x * 2) / sizing.textBoundsRatio.x;
|
|
251
|
-
const textHeight = (height - sizing.padding.y * 2) / sizing.textBoundsRatio.y;
|
|
252
|
-
return {
|
|
253
|
-
x: (width - textWidth) / 2,
|
|
254
|
-
y: (height - textHeight) / 2,
|
|
255
|
-
width: textWidth,
|
|
256
|
-
height: textHeight,
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Compute uniform sizes for all shapes in a diagram
|
|
261
|
-
*
|
|
262
|
-
* For uniform sizing mode, we need to find the maximum required size
|
|
263
|
-
* for each shape type, then apply that to all nodes of that type.
|
|
264
|
-
*/
|
|
265
|
-
export function computeUniformSizes(nodes, options) {
|
|
266
|
-
const uniformSizes = new Map();
|
|
267
|
-
// First pass: compute adaptive sizes for all nodes
|
|
268
|
-
const sizesByShape = new Map();
|
|
269
|
-
for (const node of nodes) {
|
|
270
|
-
const dims = computeNodeSize({
|
|
271
|
-
text: node.text,
|
|
272
|
-
shapeId: node.shapeId,
|
|
273
|
-
sizingMode: 'adaptive',
|
|
274
|
-
...options,
|
|
275
|
-
});
|
|
276
|
-
if (!sizesByShape.has(node.shapeId)) {
|
|
277
|
-
sizesByShape.set(node.shapeId, []);
|
|
278
|
-
}
|
|
279
|
-
sizesByShape.get(node.shapeId).push({ width: dims.width, height: dims.height });
|
|
280
|
-
}
|
|
281
|
-
// Second pass: find max size for each shape
|
|
282
|
-
for (const [shapeId, sizes] of sizesByShape) {
|
|
283
|
-
const maxWidth = Math.max(...sizes.map((s) => s.width));
|
|
284
|
-
const maxHeight = Math.max(...sizes.map((s) => s.height));
|
|
285
|
-
uniformSizes.set(shapeId, { width: maxWidth, height: maxHeight });
|
|
286
|
-
}
|
|
287
|
-
return uniformSizes;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Apply adaptive sizing to a set of nodes
|
|
291
|
-
*
|
|
292
|
-
* This is the main entry point for layout integration.
|
|
293
|
-
* Returns nodes with updated width/height properties.
|
|
294
|
-
*/
|
|
295
|
-
export function applyAdaptiveSizing(nodes, options) {
|
|
296
|
-
const { sizingMode, getShapeId, fontSize, fontFamily, fontWeight } = options;
|
|
297
|
-
// For uniform mode, pre-compute sizes
|
|
298
|
-
let uniformSizes;
|
|
299
|
-
if (sizingMode === 'uniform') {
|
|
300
|
-
uniformSizes = computeUniformSizes(nodes.map((n) => ({ text: n.data.label || '', shapeId: getShapeId(n) })), { fontSize, fontFamily, fontWeight });
|
|
301
|
-
}
|
|
302
|
-
return nodes.map((node) => {
|
|
303
|
-
const dims = computeNodeSize({
|
|
304
|
-
text: node.data.label || '',
|
|
305
|
-
shapeId: getShapeId(node),
|
|
306
|
-
sizingMode,
|
|
307
|
-
fontSize,
|
|
308
|
-
fontFamily,
|
|
309
|
-
fontWeight,
|
|
310
|
-
uniformSizes,
|
|
311
|
-
});
|
|
312
|
-
return {
|
|
313
|
-
...node,
|
|
314
|
-
width: dims.width,
|
|
315
|
-
height: dims.height,
|
|
316
|
-
};
|
|
317
|
-
});
|
|
318
|
-
}
|
|
7
|
+
export { applyAdaptiveSizing, computeNodeSize, computeUniformSizes, measureText, } from '@coral-viz/render';
|
|
319
8
|
//# sourceMappingURL=nodeSizing.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nodeSizing.js","sourceRoot":"","sources":["../../src/layout/nodeSizing.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"nodeSizing.js","sourceRoot":"","sources":["../../src/layout/nodeSizing.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,WAAW,GACZ,MAAM,mBAAmB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"positionStability.d.ts","sourceRoot":"","sources":["../../src/layout/positionStability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"positionStability.d.ts","sourceRoot":"","sources":["../../src/layout/positionStability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAgB,SAAS,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExG;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,GAAG,SAAS,CAuCtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,aAAa,EACvB,QAAQ,EAAE,aAAa,EACvB,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACtC,kBAAkB,CA0BpB;AAED;;GAEG;AACH,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,UAAU,cAAc;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,KAAK,EAAE,cAAc,EAAE,EACvB,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EACtC,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE;IACR,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACA,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CA8FhC"}
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* Separates parse, render, and layout operations to prevent undo/redo
|
|
6
6
|
* positions from being overwritten by automatic layout.
|
|
7
7
|
*/
|
|
8
|
-
import
|
|
9
|
-
const elk = new ELK();
|
|
8
|
+
import { computeElkLayout } from '@coral-viz/render/layout';
|
|
10
9
|
/**
|
|
11
10
|
* Compare two graphs and identify added, removed, modified, and unchanged nodes.
|
|
12
11
|
*
|
|
@@ -126,8 +125,8 @@ export async function incrementalLayout(nodes, edges, pinnedPositions, needsLayo
|
|
|
126
125
|
// Strategy: Run ELK on only the nodes that need layout, plus any nodes
|
|
127
126
|
// they connect to. Then merge results with pinned positions.
|
|
128
127
|
// For simplicity, we'll run ELK on all nodes but restore pinned positions after
|
|
129
|
-
const
|
|
130
|
-
const
|
|
128
|
+
const layoutNodes = nodes.map((node) => {
|
|
129
|
+
const layoutNode = {
|
|
131
130
|
id: node.id,
|
|
132
131
|
width: node.width,
|
|
133
132
|
height: node.height,
|
|
@@ -135,32 +134,28 @@ export async function incrementalLayout(nodes, edges, pinnedPositions, needsLayo
|
|
|
135
134
|
// Set initial position for ELK (helps with layout stability)
|
|
136
135
|
const pinnedPos = pinnedPositions.get(node.id);
|
|
137
136
|
if (pinnedPos) {
|
|
138
|
-
|
|
139
|
-
elkNode.y = pinnedPos.y;
|
|
137
|
+
Object.assign(layoutNode, { position: pinnedPos });
|
|
140
138
|
}
|
|
141
|
-
return
|
|
139
|
+
return layoutNode;
|
|
142
140
|
});
|
|
143
|
-
const elkEdges = edges.map((edge) => ({
|
|
144
|
-
id: edge.id,
|
|
145
|
-
sources: [edge.source],
|
|
146
|
-
targets: [edge.target],
|
|
147
|
-
}));
|
|
148
|
-
const elkGraph = {
|
|
149
|
-
id: 'root',
|
|
150
|
-
layoutOptions: {
|
|
151
|
-
'elk.algorithm': options?.algorithm || 'layered',
|
|
152
|
-
'elk.direction': options?.direction || 'DOWN',
|
|
153
|
-
'elk.spacing.nodeNode': String(options?.spacing || 50),
|
|
154
|
-
'elk.layered.spacing.nodeNodeBetweenLayers': '70',
|
|
155
|
-
},
|
|
156
|
-
children: elkChildren,
|
|
157
|
-
edges: elkEdges,
|
|
158
|
-
};
|
|
159
141
|
try {
|
|
160
|
-
const layoutedGraph = await
|
|
142
|
+
const layoutedGraph = await computeElkLayout({
|
|
143
|
+
id: 'root',
|
|
144
|
+
defaults: {
|
|
145
|
+
algorithm: 'layered', direction: 'DOWN',
|
|
146
|
+
spacing: { nodeNode: 50, layerSpacing: 70 },
|
|
147
|
+
},
|
|
148
|
+
options: {
|
|
149
|
+
algorithm: options?.algorithm,
|
|
150
|
+
direction: options?.direction,
|
|
151
|
+
spacing: options?.spacing === undefined ? undefined : { nodeNode: options.spacing },
|
|
152
|
+
},
|
|
153
|
+
nodes: layoutNodes,
|
|
154
|
+
edges,
|
|
155
|
+
});
|
|
161
156
|
// Collect positions from layout result, but restore pinned positions
|
|
162
157
|
const result = new Map();
|
|
163
|
-
for (const elkNode of layoutedGraph.
|
|
158
|
+
for (const elkNode of layoutedGraph.nodes) {
|
|
164
159
|
// For pinned nodes, use the original position
|
|
165
160
|
const pinnedPos = pinnedPositions.get(elkNode.id);
|
|
166
161
|
if (pinnedPos && !needsLayoutSet.has(elkNode.id)) {
|
|
@@ -168,7 +163,7 @@ export async function incrementalLayout(nodes, edges, pinnedPositions, needsLayo
|
|
|
168
163
|
}
|
|
169
164
|
else {
|
|
170
165
|
// Use ELK-computed position for new nodes
|
|
171
|
-
result.set(elkNode.id,
|
|
166
|
+
result.set(elkNode.id, elkNode.position);
|
|
172
167
|
}
|
|
173
168
|
}
|
|
174
169
|
return result;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"positionStability.js","sourceRoot":"","sources":["../../src/layout/positionStability.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"positionStability.js","sourceRoot":"","sources":["../../src/layout/positionStability.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAxisConstrain.d.ts","sourceRoot":"","sources":["../../src/layout/useAxisConstrain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAc,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAWvE,MAAM,WAAW,sBAAsB,CAAC,QAAQ,SAAS,QAAQ,GAAG,QAAQ;IAC1E,6EAA6E;IAC7E,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,IAAI,CAAC;CAC1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,SAAS,QAAQ,GAAG,QAAQ,EACnE,qBAAqB,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,IAAI,EAChE,KAAK,EAAE,QAAQ,EAAE,GAChB,sBAAsB,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"useAxisConstrain.d.ts","sourceRoot":"","sources":["../../src/layout/useAxisConstrain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAc,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAWvE,MAAM,WAAW,sBAAsB,CAAC,QAAQ,SAAS,QAAQ,GAAG,QAAQ;IAC1E,6EAA6E;IAC7E,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,IAAI,CAAC;CAC1D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,SAAS,QAAQ,GAAG,QAAQ,EACnE,qBAAqB,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,KAAK,IAAI,EAChE,KAAK,EAAE,QAAQ,EAAE,GAChB,sBAAsB,CAAC,QAAQ,CAAC,CA8FlC"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* axis is detected after a small movement threshold.
|
|
7
7
|
*/
|
|
8
8
|
import { useCallback, useRef, useEffect } from 'react';
|
|
9
|
-
/** Threshold in
|
|
9
|
+
/** Threshold in diagram-space units before locking to an axis */
|
|
10
10
|
const AXIS_LOCK_THRESHOLD = 5;
|
|
11
11
|
/**
|
|
12
12
|
* Wraps onNodesChange to add Shift+drag axis constraint.
|
|
@@ -16,7 +16,7 @@ const AXIS_LOCK_THRESHOLD = 5;
|
|
|
16
16
|
*/
|
|
17
17
|
export function useAxisConstrain(originalOnNodesChange, nodes) {
|
|
18
18
|
const shiftHeld = useRef(false);
|
|
19
|
-
const
|
|
19
|
+
const dragStates = useRef(new Map());
|
|
20
20
|
// Track Shift key globally
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
const onKeyDown = (e) => {
|
|
@@ -24,12 +24,17 @@ export function useAxisConstrain(originalOnNodesChange, nodes) {
|
|
|
24
24
|
shiftHeld.current = true;
|
|
25
25
|
};
|
|
26
26
|
const onKeyUp = (e) => {
|
|
27
|
-
if (e.key === 'Shift')
|
|
27
|
+
if (e.key === 'Shift') {
|
|
28
28
|
shiftHeld.current = false;
|
|
29
|
+
dragStates.current.clear();
|
|
30
|
+
}
|
|
29
31
|
};
|
|
32
|
+
const onBlur = () => { shiftHeld.current = false; dragStates.current.clear(); };
|
|
33
|
+
window.addEventListener('blur', onBlur);
|
|
30
34
|
window.addEventListener('keydown', onKeyDown);
|
|
31
35
|
window.addEventListener('keyup', onKeyUp);
|
|
32
36
|
return () => {
|
|
37
|
+
window.removeEventListener('blur', onBlur);
|
|
33
38
|
window.removeEventListener('keydown', onKeyDown);
|
|
34
39
|
window.removeEventListener('keyup', onKeyUp);
|
|
35
40
|
};
|
|
@@ -37,8 +42,7 @@ export function useAxisConstrain(originalOnNodesChange, nodes) {
|
|
|
37
42
|
const onNodesChange = useCallback((changes) => {
|
|
38
43
|
if (!shiftHeld.current) {
|
|
39
44
|
// No Shift held — pass through unmodified, reset drag state
|
|
40
|
-
|
|
41
|
-
dragState.current = null;
|
|
45
|
+
dragStates.current.clear();
|
|
42
46
|
originalOnNodesChange(changes);
|
|
43
47
|
return;
|
|
44
48
|
}
|
|
@@ -46,28 +50,24 @@ export function useAxisConstrain(originalOnNodesChange, nodes) {
|
|
|
46
50
|
if (change.type !== 'position')
|
|
47
51
|
return change;
|
|
48
52
|
const posChange = change;
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
dragState.current = null;
|
|
53
|
-
}
|
|
53
|
+
// Programmatic positions are not gestures. The terminal drag event
|
|
54
|
+
// still uses the existing lock before that lock is released.
|
|
55
|
+
if (posChange.dragging === undefined)
|
|
54
56
|
return change;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
let state = dragStates.current.get(posChange.id);
|
|
58
|
+
if (posChange.dragging === false)
|
|
59
|
+
dragStates.current.delete(posChange.id);
|
|
57
60
|
if (!posChange.position)
|
|
58
61
|
return change;
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
if (!state) {
|
|
63
|
+
if (posChange.dragging === false)
|
|
64
|
+
return change;
|
|
61
65
|
const node = nodes.find((n) => n.id === posChange.id);
|
|
62
66
|
if (!node)
|
|
63
67
|
return change;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
startPos: { x: node.position.x, y: node.position.y },
|
|
67
|
-
axis: null,
|
|
68
|
-
};
|
|
68
|
+
state = { nodeId: posChange.id, startPos: { ...node.position }, axis: null };
|
|
69
|
+
dragStates.current.set(posChange.id, state);
|
|
69
70
|
}
|
|
70
|
-
const state = dragState.current;
|
|
71
71
|
const dx = posChange.position.x - state.startPos.x;
|
|
72
72
|
const dy = posChange.position.y - state.startPos.y;
|
|
73
73
|
// Detect axis if not yet locked
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAxisConstrain.js","sourceRoot":"","sources":["../../src/layout/useAxisConstrain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,
|
|
1
|
+
{"version":3,"file":"useAxisConstrain.js","sourceRoot":"","sources":["../../src/layout/useAxisConstrain.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ export interface ParsedGraph {
|
|
|
27
27
|
/**
|
|
28
28
|
* Node data for React Flow
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
interface DiagramNodeData {
|
|
31
31
|
label: string;
|
|
32
32
|
nodeType: string;
|
|
33
33
|
[key: string]: unknown;
|
|
@@ -89,4 +89,5 @@ export interface UseDiagramStateResult {
|
|
|
89
89
|
* positions from being overwritten by automatic layout.
|
|
90
90
|
*/
|
|
91
91
|
export declare function useDiagramState(options?: UseDiagramStateOptions): UseDiagramStateResult;
|
|
92
|
+
export {};
|
|
92
93
|
//# sourceMappingURL=useDiagramState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDiagramState.d.ts","sourceRoot":"","sources":["../../src/layout/useDiagramState.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAG3E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,
|
|
1
|
+
{"version":3,"file":"useDiagramState.d.ts","sourceRoot":"","sources":["../../src/layout/useDiagramState.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAG3E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC;AAgB/B;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B;IAC/B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,+BAA+B;IAC/B,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IAEnB,uCAAuC;IACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,0CAA0C;IAC1C,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACzD,gDAAgD;IAChD,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,+DAA+D;IAC/D,gBAAgB,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IAErF,qCAAqC;IACrC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,CAAC;IAElE,gCAAgC;IAChC,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,8BAA8B;IAC9B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,gBAAgB;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAwS3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useLayoutHistory.d.ts","sourceRoot":"","sources":["../../src/layout/useLayoutHistory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CACzC;AAED,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CACzC;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,YAAY,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,KAAK,IAAI,CAAC;IAChG,2FAA2F;IAC3F,IAAI,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAClC,uFAAuF;IACvF,IAAI,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAClC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,
|
|
1
|
+
{"version":3,"file":"useLayoutHistory.d.ts","sourceRoot":"","sources":["../../src/layout/useLayoutHistory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,iCAAiC;IACjC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CACzC;AAED,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CACzC;AAED,4CAA4C;AAC5C,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,sEAAsE;IACtE,YAAY,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,KAAK,IAAI,CAAC;IAChG,2FAA2F;IAC3F,IAAI,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAClC,uFAAuF;IACvF,IAAI,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;IAClC,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CA4ExB"}
|