@visualli/core 0.1.7 → 0.2.0
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 +37 -105
- package/dist/chunk-25AJTPMS.js +68 -0
- package/dist/chunk-25AJTPMS.js.map +1 -0
- package/dist/{chunk-6NXADJK2.js → chunk-7NJWM7ZE.js} +84 -117
- package/dist/chunk-7NJWM7ZE.js.map +1 -0
- package/dist/chunk-KVSM3APM.js +96 -0
- package/dist/chunk-KVSM3APM.js.map +1 -0
- package/dist/{chunk-PDP5CVUL.js → chunk-LOQLNYB3.js} +2 -2
- package/dist/chunk-LV3EXUQY.js +753 -0
- package/dist/chunk-LV3EXUQY.js.map +1 -0
- package/dist/chunk-N7HCYULH.js +12 -0
- package/dist/chunk-N7HCYULH.js.map +1 -0
- package/dist/{chunk-I75TMOE4.js → chunk-P6PKWVYF.js} +2 -2
- package/dist/chunk-TPLJJKAU.js +151 -0
- package/dist/chunk-TPLJJKAU.js.map +1 -0
- package/dist/chunk-UAMEJG2C.js +267 -0
- package/dist/chunk-UAMEJG2C.js.map +1 -0
- package/dist/{chunk-LJYSKSCE.js → chunk-W2CAOOJJ.js} +6 -6
- package/dist/chunk-W2CAOOJJ.js.map +1 -0
- package/dist/config/index.cjs +250 -349
- package/dist/config/index.cjs.map +1 -1
- package/dist/config/index.d.cts +107 -66
- package/dist/config/index.d.ts +107 -66
- package/dist/config/index.js +52 -34
- package/dist/constants/index.cjs +14 -333
- package/dist/constants/index.cjs.map +1 -1
- package/dist/constants/index.d.cts +5 -243
- package/dist/constants/index.d.ts +5 -243
- package/dist/constants/index.js +5 -75
- package/dist/designSystem-BOrZHfEq.d.cts +150 -0
- package/dist/designSystem-BOrZHfEq.d.ts +150 -0
- package/dist/document-BFBwn93X.d.ts +26 -0
- package/dist/document-MEJEfxl3.d.cts +26 -0
- package/dist/ideaSize-CLDKeyqD.d.cts +11 -0
- package/dist/ideaSize-DxxGy2E8.d.ts +11 -0
- package/dist/index-BmILeKj6.d.cts +99 -0
- package/dist/index-CcPRwVUL.d.ts +99 -0
- package/dist/index.cjs +1636 -961
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +350 -27
- package/dist/index.d.ts +350 -27
- package/dist/index.js +434 -179
- package/dist/index.js.map +1 -1
- package/dist/{document-B3hnNr-F.d.cts → layer-B2A3Ki48.d.cts} +2 -16
- package/dist/{document-B3hnNr-F.d.ts → layer-B2A3Ki48.d.ts} +2 -16
- package/dist/layout/index.d.cts +2 -1
- package/dist/layout/index.d.ts +2 -1
- package/dist/mindmap-C3Qr0qKW.d.cts +182 -0
- package/dist/mindmap-DHeVa86G.d.ts +182 -0
- package/dist/parser/index.cjs +745 -179
- package/dist/parser/index.cjs.map +1 -1
- package/dist/parser/index.d.cts +23 -8
- package/dist/parser/index.d.ts +23 -8
- package/dist/parser/index.js +7 -2
- package/dist/performance/index.cjs +13 -0
- package/dist/performance/index.cjs.map +1 -1
- package/dist/performance/index.js +2 -2
- package/dist/theme/index.cjs +884 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/index.d.cts +2 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/index.js +53 -0
- package/dist/types/index.d.cts +4 -2
- package/dist/types/index.d.ts +4 -2
- package/dist/viewport/index.cjs +17 -6
- package/dist/viewport/index.cjs.map +1 -1
- package/dist/viewport/index.d.cts +6 -4
- package/dist/viewport/index.d.ts +6 -4
- package/dist/viewport/index.js +2 -2
- package/licenses/visualli-design-system/LICENSE +9 -0
- package/licenses/visualli-design-system/NOTICE.md +6 -0
- package/package.json +12 -4
- package/src/config/README.md +2 -4
- package/src/config/USAGE_EXAMPLES.md +0 -4
- package/src/config/index.ts +3 -4
- package/src/constants/index.ts +1 -1
- package/src/constants/layout.ts +11 -0
- package/src/constants/performanceConstants.ts +8 -27
- package/src/generated/README.md +12 -0
- package/src/generated/designSystem.ts +758 -0
- package/src/generated/geometry/blob.ts +99 -0
- package/src/generated/geometry/blobShapes.ts +4 -0
- package/src/generated/geometry/color.ts +37 -0
- package/src/generated/geometry/container.ts +84 -0
- package/src/generated/geometry/detail.ts +22 -0
- package/src/generated/geometry/idea.ts +56 -0
- package/src/generated/geometry/interaction.ts +122 -0
- package/src/generated/geometry/motion.ts +140 -0
- package/src/index.ts +18 -1
- package/src/parser/configUtils.ts +12 -19
- package/src/parser/visualliConverter.ts +71 -112
- package/src/parser/visualliParser.ts +16 -1
- package/src/rendering/culling.ts +16 -12
- package/src/rendering/ideaSize.ts +21 -0
- package/src/rendering/nodeGeometry.ts +97 -0
- package/src/theme/index.ts +136 -0
- package/src/types/document.ts +9 -0
- package/src/types/layer.ts +1 -1
- package/src/types/mindmap.ts +13 -0
- package/src/utils/navigation.ts +33 -63
- package/src/viewport/viewportUtils.ts +6 -4
- package/dist/animations/index.cjs +0 -146
- package/dist/animations/index.cjs.map +0 -1
- package/dist/animations/index.d.cts +0 -81
- package/dist/animations/index.d.ts +0 -81
- package/dist/animations/index.js +0 -35
- package/dist/chunk-6NXADJK2.js.map +0 -1
- package/dist/chunk-F36SMC3K.js +0 -106
- package/dist/chunk-F36SMC3K.js.map +0 -1
- package/dist/chunk-G5H3P4YZ.js +0 -273
- package/dist/chunk-G5H3P4YZ.js.map +0 -1
- package/dist/chunk-LDJRGT2Q.js +0 -163
- package/dist/chunk-LDJRGT2Q.js.map +0 -1
- package/dist/chunk-LJYSKSCE.js.map +0 -1
- package/dist/chunk-LNTJTDB2.js +0 -349
- package/dist/chunk-LNTJTDB2.js.map +0 -1
- package/dist/mindmap-DWS0WZT_.d.cts +0 -118
- package/dist/mindmap-DWS0WZT_.d.ts +0 -118
- package/src/animations/constants.ts +0 -72
- package/src/animations/easing.ts +0 -70
- package/src/animations/index.ts +0 -2
- package/src/config/blobShapes.ts +0 -146
- package/src/config/textScaling.ts +0 -54
- package/src/constants/design.ts +0 -281
- /package/dist/{chunk-PDP5CVUL.js.map → chunk-LOQLNYB3.js.map} +0 -0
- /package/dist/{chunk-I75TMOE4.js.map → chunk-P6PKWVYF.js.map} +0 -0
- /package/dist/{animations → theme}/index.js.map +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
import { R as RenderConfig, N as NodeSelection, F as FlatNode, M as MindMapConnection, V as ViewportState } from './mindmap-
|
|
2
|
-
export { a as
|
|
3
|
-
import { V as VisualliDocument
|
|
4
|
-
export {
|
|
1
|
+
import { R as RenderConfig, N as NodeSelection, F as FlatNode, M as MindMapConnection, V as ViewportState } from './mindmap-DHeVa86G.js';
|
|
2
|
+
export { a as IDEA, I as IdeaKind, L as LABEL_GROWTH, b as MindMapConfig, c as MindMapData, d as MindMapNode, e as NodeMap, S as SpatialBounds, T as TopLevelConnection, i as ideaSize, l as labelGrowth, w as wrapLines } from './mindmap-DHeVa86G.js';
|
|
3
|
+
import { V as VisualliDocument } from './document-BFBwn93X.js';
|
|
4
|
+
export { S as SemanticAnchor, a as VisualliMeta } from './document-BFBwn93X.js';
|
|
5
|
+
import { V as VisualliLayer } from './layer-B2A3Ki48.js';
|
|
6
|
+
export { L as LayerConnection, a as LayerContainer, b as LayerNode, c as VisualliRenderConnection, d as VisualliRenderNode } from './layer-B2A3Ki48.js';
|
|
5
7
|
export { VisualliFragment } from './types/index.js';
|
|
6
8
|
export { CircularLayoutOptions, CollisionBox, LinearLayoutOptions, applyCircularLayout, applyLinearHorizontalLayout, applyLinearVerticalLayout, calculateMinimumRadius, calculateOptimalRadiusPercentage, checkCollision, getNodeBounds, optimizeLayout, resolveCollisions } from './layout/index.js';
|
|
7
|
-
export { VisualliParseError, calculateDistance, convertLayerToFlatNodes, convertVisualliToFlatNodes, countLayersBeneath, createMindMapConfig, fetchAndParseVisualli, flattenNodes, generateSampleConfig, getChildLayers, getNodeConnections, getNodesForLayer, getTopLevelConnections, getVisibleNodes, loadVisualliFileFromFile, parseVisualliFile, parseVisualliFromMongoDB, resolveNodeOverlaps } from './parser/index.js';
|
|
9
|
+
export { ConvertOptions, VisualliParseError, calculateDistance, convertLayerToFlatNodes, convertVisualliToFlatNodes, countLayersBeneath, createMindMapConfig, fetchAndParseVisualli, flattenNodes, generateSampleConfig, getChildLayers, getNodeConnections, getNodesForLayer, getSemanticAnchors, getTopLevelConnections, getVisibleNodes, loadVisualliFileFromFile, parseVisualliFile, parseVisualliFromMongoDB, resolveNodeOverlaps } from './parser/index.js';
|
|
8
10
|
import { FEATURE_FLAGS } from './constants/index.js';
|
|
9
|
-
export {
|
|
11
|
+
export { CIRCULAR_REFERENCE_MAX_DEPTH, CLICK_THRESHOLD, CULLING_QUERY_TIME_BUDGET, DEFAULT_CANVAS_HEIGHT, DEFAULT_CANVAS_WIDTH, DEFAULT_RENDER_CONFIG, DOUBLE_CLICK_DELAY, DRAG_START_DISTANCE, FPS_CRITICAL_THRESHOLD, FPS_DOWNGRADE_THRESHOLD, FPS_SAMPLE_WINDOW, FPS_STABILIZATION_FRAMES, FPS_TARGET, FPS_TARGETS, FPS_UPDATE_INTERVAL, FPS_UPGRADE_THRESHOLD, FPS_WARNING_THRESHOLD, LAYOUT_SPACING, MAX_FRAME_TIME, MAX_NODES, MAX_VISIBLE_NODES, MEMORY_CHECK_INTERVAL, MEMORY_CRITICAL_MB, MEMORY_LIMITS, MEMORY_TARGET_MB, MEMORY_WARNING_MB, NODE_COUNT_THRESHOLDS, PERFORMANCE_TOAST_COOLDOWN, QUALITY_HIGH, QUALITY_LEVELS, QUALITY_LOW, QUALITY_MEDIUM, QUALITY_SETTINGS, QualityLevel, RBUSH_MAX_ENTRIES, RENDER_MODES, RESIZE_DEBOUNCE, RenderMode, SCROLL_THROTTLE, SEARCH_DEBOUNCE, SIMPLIFIED_RENDER_CONFIG, SPATIAL_INDEX_BUILD_BUDGET, TARGET_FRAME_TIME, TIMING_THRESHOLDS, VIEWPORT_CONFIG, VIEWPORT_MARGIN, ZOOM_DEFAULT, ZOOM_MAX, ZOOM_MIN, getOptimalQualityLevel, getRecommendedRenderConfig, getRenderConfigForQuality, isFeatureEnabled } from './constants/index.js';
|
|
10
12
|
export { WorldBounds, calculateViewportBounds, clampZoom, focusOnNode, isNodeInViewport, panViewport, recalculateViewportBounds, screenToWorld, setViewportCenter, worldToScreen, zoomViewport } from './viewport/index.js';
|
|
11
13
|
export { FPSMonitor, MemoryMonitor, MemoryStats, PerformanceProfiler } from './performance/index.js';
|
|
12
|
-
export { ANIMATION_DURATION, ANIMATION_PHASES, COOLDOWN, EasingFunction, OPACITY, TARGET_ZOOM, VIEWPORT_FRAMING, ZOOM_THRESHOLDS, createCubicBezier, easeInCubic, easeInOutCubic, easeInOutQuart, easeInOutSine, easeOutCubic, easeOutQuad, easeZoomTransition } from './animations/index.js';
|
|
13
14
|
import * as zustand_vanilla from 'zustand/vanilla';
|
|
14
|
-
export {
|
|
15
|
+
export { BLOB_SHAPES, ConnectorGeometry, MAX_RINGS, NodeLike, RINGS, SHAPE, arrowPath, blobPath, blobRadius, connectorGeometry, drawBlob, edgePath, nodeBounds, nodeRadii, outlineRadius, ringCount, ringsFor, shapeForLevel, shapeOfLevel } from './config/index.js';
|
|
16
|
+
export { I as IdeaMeasure, a as approximateMeasure, i as ideaKindOf } from './ideaSize-DxxGy2E8.js';
|
|
17
|
+
export { C as CUSTOM, a as Comfort, I as IdeaColor, M as Metrics, R as ResolvedComfort, T as TOPIC_ORDER, b as ThemeEnv, c as ThemeFamily, d as ThemeInput, e as TopicStyle, f as customColor, g as getTokens, i as ideaColor, h as ideaStyle, j as isContrastTheme, k as isDarkTheme, l as isFocusTheme, m as isThemeName, n as labelScale, o as metricsFor, r as resolveComfort, p as resolveTheme, t as token, q as topicFor, s as topicFromName, u as topicStyle } from './index-CcPRwVUL.js';
|
|
18
|
+
export { C as CANVAS_STYLE, D as DESIGN_SYSTEM_VERSION, M as METRICS, b as METRICS_REDUCED_MOTION, c as THEME_NAMES, d as TOKENS, e as TOPICS, f as TYPE_STYLES, a as ThemeName, T as TopicName } from './designSystem-BOrZHfEq.js';
|
|
15
19
|
export { Connection, Container, Extension, Layer, Meta, Node } from '@visualli/bindings';
|
|
16
20
|
|
|
17
21
|
interface BoundingBox {
|
|
@@ -75,6 +79,143 @@ interface IRenderConfigStore extends RenderConfig {
|
|
|
75
79
|
}
|
|
76
80
|
declare const renderConfigStore: zustand_vanilla.StoreApi<IRenderConfigStore>;
|
|
77
81
|
|
|
82
|
+
/** Terms (semantic anchors) in a peek's text. */
|
|
83
|
+
declare const TERM: {
|
|
84
|
+
/** Hovering the term this long opens its definition card… */ readonly hoverOpen: 250;
|
|
85
|
+
/** …which closes this long after the pointer leaves both the term and the card (moving between them keeps it open). */ readonly hoverClose: 300;
|
|
86
|
+
/** Only a mouse opens on hover; touch and pen open on tap. */ readonly hoverPointers: readonly string[];
|
|
87
|
+
/** A click, tap, Enter or Space pins the card open (hovering away doesn't close it); pressing again unpins and closes. */ readonly clickPins: true;
|
|
88
|
+
/** Escape closes the card and returns focus to the term; a press anywhere outside the term and its card closes it. */ readonly escapeCloses: true;
|
|
89
|
+
readonly pressOutsideCloses: true;
|
|
90
|
+
/** Opening by click or keyboard moves focus to the card's first link or button. */ readonly focusCardOnOpen: true;
|
|
91
|
+
/** The card is kept this far inside the viewport's left and right edges. */ readonly viewportMargin: 8;
|
|
92
|
+
/** The card's link to a source about the term. */ readonly learnMoreLabel: "Learn more";
|
|
93
|
+
};
|
|
94
|
+
/** The peek: an idea's summary card on hover (pointer) or tap (touch). */
|
|
95
|
+
declare const PEEK: {
|
|
96
|
+
/** Hovering an idea opens its peek at once; it stays this long after the pointer leaves the idea (and while the
|
|
97
|
+
* pointer is over the peek itself), so the pointer can travel from the idea onto the card. */ readonly hoverClose: 180;
|
|
98
|
+
};
|
|
99
|
+
/** The touch peek: a bottom sheet with a grip. */
|
|
100
|
+
declare const SHEET: {
|
|
101
|
+
/** Dragging the grip down this far closes the sheet (or collapses it when expanded); up this far expands it. */ readonly dismissDrag: 80;
|
|
102
|
+
readonly expandDrag: 40;
|
|
103
|
+
/** Its height: this share of the map, at most `maxHeight` px; the map pans the chosen idea into the space above it. */ readonly heightRatio: 0.42;
|
|
104
|
+
readonly maxHeight: 300;
|
|
105
|
+
};
|
|
106
|
+
/** Zoom, pan and fit. */
|
|
107
|
+
declare const VIEW: {
|
|
108
|
+
/** Each zoom step multiplies or divides the zoom by this. */ readonly zoomStep: 1.2;
|
|
109
|
+
/** Zoom limits (the zoom-min / zoom-max tokens; the build checks they agree). */ readonly zoomMin: 0.3;
|
|
110
|
+
readonly zoomMax: 5;
|
|
111
|
+
/** Fit to view never enlarges a layer beyond this. */ readonly fitMax: 1.1;
|
|
112
|
+
};
|
|
113
|
+
/** Touch gestures on the map (any touch input — phones, tablets and touchscreen laptops alike; it follows the pointer
|
|
114
|
+
* in use, not the device, so a mouse or trackpad on the same laptop isn't affected). */
|
|
115
|
+
declare const GESTURE: {
|
|
116
|
+
/** Two fingers pinch to zoom the map's contents — ideas, connectors, containers and their labels — around the
|
|
117
|
+
* point between the fingers, within VIEW's limits. Controls, the depth trail, the peek, chat and the page never scale. */ readonly pinchZoom: true;
|
|
118
|
+
/** Moving both fingers pans the contents. */ readonly twoFingerPan: true;
|
|
119
|
+
/** The pointers that pinch (PointerEvent.pointerType). */ readonly pointers: readonly string[];
|
|
120
|
+
/** Where the map is the page (an app: AppShell, the mobile app), it takes every touch gesture (touch-action: none),
|
|
121
|
+
* so the browser never zooms the page. Embedded on a scrolling page (website, docs), one finger still scrolls the
|
|
122
|
+
* page (touch-action: pan-x pan-y); two fingers that land together pinch the map. */ readonly appTouchAction: "none";
|
|
123
|
+
readonly embeddedTouchAction: "pan-x pan-y";
|
|
124
|
+
/** Zoom never navigates: stepping inside and backing out stay explicit (tap an idea / Step inside, the depth trail,
|
|
125
|
+
* Escape or Backspace). */ readonly zoomNavigates: false;
|
|
126
|
+
};
|
|
127
|
+
/** The zoom after a pinch: the zoom at the start, scaled by how far the fingers spread, within VIEW's limits. */
|
|
128
|
+
declare function pinchZoom(startZoom: number, startDistance: number, distance: number): number;
|
|
129
|
+
/** Keeps the map point that was under `from` under `to` when the scale changes from `s0` to `s1`: the new
|
|
130
|
+
* translation, given the old one (screen = world × s + t). Used to zoom around the fingers. */
|
|
131
|
+
declare function zoomAround(t0: {
|
|
132
|
+
x: number;
|
|
133
|
+
y: number;
|
|
134
|
+
}, s0: number, s1: number, from: {
|
|
135
|
+
x: number;
|
|
136
|
+
y: number;
|
|
137
|
+
}, to: {
|
|
138
|
+
x: number;
|
|
139
|
+
y: number;
|
|
140
|
+
}): {
|
|
141
|
+
x: number;
|
|
142
|
+
y: number;
|
|
143
|
+
};
|
|
144
|
+
/** Framing a layer (fit to view): its ideas with room around them, and its container hulls with room for the name pill. */
|
|
145
|
+
declare const FRAME: {
|
|
146
|
+
/** Room beyond each idea's outline (at least `minPadX` / `minPadY` from its centre). */ readonly clearX: 50;
|
|
147
|
+
readonly clearY: 46;
|
|
148
|
+
readonly minPadX: 150;
|
|
149
|
+
readonly minPadY: 120;
|
|
150
|
+
/** Room beyond each container hull for its dashed line and the name pill straddling it. */ readonly hullX: 24;
|
|
151
|
+
readonly hullY: 40;
|
|
152
|
+
};
|
|
153
|
+
type FrameBox = {
|
|
154
|
+
x0: number;
|
|
155
|
+
y0: number;
|
|
156
|
+
x1: number;
|
|
157
|
+
y1: number;
|
|
158
|
+
};
|
|
159
|
+
/** The box a layer is framed by: every idea (`rx` / `ry` its half size) and every container hull. */
|
|
160
|
+
declare function layerBounds(ideas: ReadonlyArray<{
|
|
161
|
+
x: number;
|
|
162
|
+
y: number;
|
|
163
|
+
rx: number;
|
|
164
|
+
ry: number;
|
|
165
|
+
}>, hulls?: ReadonlyArray<FrameBox>): FrameBox;
|
|
166
|
+
/** Fit to view: the scale that shows `bounds` in an area of `width` × `height` (never beyond VIEW.fitMax), and the
|
|
167
|
+
* world point to centre. */
|
|
168
|
+
declare function fitView(bounds: FrameBox, width: number, height: number): {
|
|
169
|
+
scale: number;
|
|
170
|
+
center: {
|
|
171
|
+
x: number;
|
|
172
|
+
y: number;
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
/** Where the peek card sits (pointer): beside the idea — right of it if it fits, else left — and level with it. */
|
|
176
|
+
declare const PEEK_PLACEMENT: {
|
|
177
|
+
/** Gap between the idea's outermost ring and the card. */ readonly gap: 16;
|
|
178
|
+
/** The card's width and the height kept clear below it. */ readonly cardWidth: 300;
|
|
179
|
+
readonly cardHeight: 220;
|
|
180
|
+
/** The card is raised this much above the idea's centre. */ readonly raise: 70;
|
|
181
|
+
/** Kept this far inside the map's edges. */ readonly margin: 12;
|
|
182
|
+
};
|
|
183
|
+
/** The peek card's top-left, in map (screen) pixels. `idea`: the idea's centre on screen and its on-screen half
|
|
184
|
+
* width with its outermost ring (`half`); `box`: the map's size. */
|
|
185
|
+
declare function peekPosition(idea: {
|
|
186
|
+
x: number;
|
|
187
|
+
y: number;
|
|
188
|
+
half: number;
|
|
189
|
+
}, box: {
|
|
190
|
+
w: number;
|
|
191
|
+
h: number;
|
|
192
|
+
}, card?: {
|
|
193
|
+
w: number;
|
|
194
|
+
h: number;
|
|
195
|
+
}): {
|
|
196
|
+
left: number;
|
|
197
|
+
top: number;
|
|
198
|
+
side: "right" | "left";
|
|
199
|
+
};
|
|
200
|
+
/** The depth trail: each entry shows the idea that was stepped into — its title and a dot in its color (the same
|
|
201
|
+
* topic or custom color the idea is drawn in, including the sibling-order topic of an uncolored idea). The first
|
|
202
|
+
* entry is the map itself: a `stone` dot and the home glyph only (`rootLabel: 'icon'`) — no text, since a map's title
|
|
203
|
+
* usually repeats its centre idea's, which the next entry shows; its accessible name and tooltip are the map's title.
|
|
204
|
+
* The dot is the idea shape (shapeForLevel). */
|
|
205
|
+
declare const TRAIL: {
|
|
206
|
+
readonly rootTopic: "stone";
|
|
207
|
+
readonly rootLabel: "icon";
|
|
208
|
+
readonly homeIconSize: 12;
|
|
209
|
+
readonly dotBox: 16;
|
|
210
|
+
readonly dotRadius: 6.4;
|
|
211
|
+
readonly stroke: 1.25;
|
|
212
|
+
readonly currentStroke: 1.75;
|
|
213
|
+
};
|
|
214
|
+
/** How an input answers: a mouse hovers (peeks and terms open on hover); touch and pen tap. Null for unknown pointers. */
|
|
215
|
+
declare function pointerModeFor(pointerType: string): 'hover' | 'touch' | null;
|
|
216
|
+
/** Whether a pointer of this type opens a term on hover (PointerEvent.pointerType). */
|
|
217
|
+
declare function hoverOpensTerm(pointerType: string): boolean;
|
|
218
|
+
|
|
78
219
|
/**
|
|
79
220
|
* Returns all top-level connections that originate from the given layer.
|
|
80
221
|
* A "top-level connection" links two nodes that both live in `layerId`.
|
|
@@ -94,21 +235,18 @@ interface FitResult {
|
|
|
94
235
|
centerY: number;
|
|
95
236
|
zoomLevel: number;
|
|
96
237
|
}
|
|
97
|
-
/**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
* geometrically centred.
|
|
110
|
-
*/
|
|
111
|
-
declare function calculateFitCenter(nodes: FlatNode[]): {
|
|
238
|
+
/** The box a layer is framed by: its ideas (their real sizes) and the hulls of its `containers`. */
|
|
239
|
+
declare function layerFrame(nodes: ReadonlyArray<FlatNode>, containers?: ReadonlyArray<{
|
|
240
|
+
nodeIds: string[];
|
|
241
|
+
}>): FrameBox;
|
|
242
|
+
/** The zoom that fits a layer's ideas (and container hulls) into a canvas of `canvasWidth` × `canvasHeight`. */
|
|
243
|
+
declare function calculateFitZoom(nodes: FlatNode[], canvasWidth: number, canvasHeight: number, containers?: ReadonlyArray<{
|
|
244
|
+
nodeIds: string[];
|
|
245
|
+
}>): number;
|
|
246
|
+
/** The world point a fitted layer is centred on: the middle of its frame. */
|
|
247
|
+
declare function calculateFitCenter(nodes: FlatNode[], containers?: ReadonlyArray<{
|
|
248
|
+
nodeIds: string[];
|
|
249
|
+
}>): {
|
|
112
250
|
x: number;
|
|
113
251
|
y: number;
|
|
114
252
|
};
|
|
@@ -119,12 +257,14 @@ interface ContainerGroupInfo {
|
|
|
119
257
|
level: number;
|
|
120
258
|
}
|
|
121
259
|
/**
|
|
122
|
-
* Returns the container groups
|
|
260
|
+
* Returns the container groups the given layer draws, normalising both the
|
|
123
261
|
* nested-data format `{data:{label,formation}}` and the flat format `{label}`.
|
|
124
262
|
*/
|
|
125
263
|
declare function getContainersForLayer(doc: VisualliDocument, layerId: string): ContainerGroupInfo[];
|
|
126
|
-
/**
|
|
127
|
-
declare function calculateFitView(nodes: FlatNode[], canvasWidth: number, canvasHeight: number
|
|
264
|
+
/** Fit to view: centre and zoom for a layer in one call (the design system's fitView). */
|
|
265
|
+
declare function calculateFitView(nodes: FlatNode[], canvasWidth: number, canvasHeight: number, containers?: ReadonlyArray<{
|
|
266
|
+
nodeIds: string[];
|
|
267
|
+
}>): FitResult;
|
|
128
268
|
|
|
129
269
|
interface CullingOptions {
|
|
130
270
|
nodes: FlatNode[];
|
|
@@ -137,10 +277,193 @@ interface CullingOptions {
|
|
|
137
277
|
spatialIndex?: RBushSpatialIndex | null;
|
|
138
278
|
spatialIndexThreshold?: number;
|
|
139
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* True when anything drawn for the node touches the viewport. Nodes are drawn
|
|
282
|
+
* CENTRED on (x, y) with rings and stroke around them, so the test uses the
|
|
283
|
+
* node's real visual bounds (not a top-left rectangle).
|
|
284
|
+
*/
|
|
285
|
+
declare function intersectsViewport(n: FlatNode, bounds: {
|
|
286
|
+
minX: number;
|
|
287
|
+
minY: number;
|
|
288
|
+
maxX: number;
|
|
289
|
+
maxY: number;
|
|
290
|
+
}): boolean;
|
|
140
291
|
/**
|
|
141
292
|
* Returns the subset of nodes currently visible in the viewport.
|
|
142
293
|
* Framework-agnostic logic for culling and spatial indexing.
|
|
143
294
|
*/
|
|
144
295
|
declare function getViewportVisibleNodes(options: CullingOptions): FlatNode[];
|
|
145
296
|
|
|
146
|
-
|
|
297
|
+
type Bezier = readonly [number, number, number, number];
|
|
298
|
+
declare const EASE: {
|
|
299
|
+
/** ease-standard — UI and connector drawing. */ standard: Bezier;
|
|
300
|
+
/** ease-zoom — diving into and out of layers. */ zoom: Bezier;
|
|
301
|
+
/** ease-bloom — ideas arriving, with a little overshoot. */ bloom: Bezier;
|
|
302
|
+
};
|
|
303
|
+
declare const MOTION: {
|
|
304
|
+
/** A layer arrives: ideas bloom one by one in sibling order, center first, then connectors draw. */
|
|
305
|
+
readonly reveal: {
|
|
306
|
+
/** duration-reveal: each idea's bloom. */ readonly duration: 420;
|
|
307
|
+
/** stagger-reveal: delay between consecutive ideas. */ readonly stagger: 70;
|
|
308
|
+
/** An idea starts at this scale… */ readonly fromScale: 0.55;
|
|
309
|
+
/** …and this fraction of the way from its place toward the layer's center. */ readonly fromCenter: 0.5;
|
|
310
|
+
readonly ease: Bezier;
|
|
311
|
+
/** Settle time after the last bloom before the map is idle (interactive again). */ readonly tail: 200;
|
|
312
|
+
};
|
|
313
|
+
/** Connectors of an arriving layer: they start once the ideas are mostly in. */
|
|
314
|
+
readonly connector: {
|
|
315
|
+
/** Lead time before the first connector, on top of the ideas' stagger. */ readonly lead: 240;
|
|
316
|
+
/** Delay between consecutive connectors. */ readonly stagger: 60;
|
|
317
|
+
/** A solid connector draws from source to target; a dashed one fades in instead. */ readonly draw: 500;
|
|
318
|
+
/** The connector group's fade (duration-base). */ readonly fade: 240;
|
|
319
|
+
readonly ease: Bezier;
|
|
320
|
+
};
|
|
321
|
+
/** Step inside: the current layer zooms toward the idea and fades; the inner layer then arrives (reveal). */
|
|
322
|
+
readonly dive: {
|
|
323
|
+
/** The old layer's zoom, toward the idea's position. */ readonly scale: 3.2;
|
|
324
|
+
/** duration-zoom. */ readonly duration: 500;
|
|
325
|
+
/** It fades out after this delay, over `fade`. */ readonly fadeDelay: 150;
|
|
326
|
+
readonly fade: 160;
|
|
327
|
+
/** The layers swap (and the reveal starts) this long after the dive starts. */ readonly swapAfter: 320;
|
|
328
|
+
readonly ease: Bezier;
|
|
329
|
+
};
|
|
330
|
+
/** Back out (depth trail): the current layer shrinks toward the center and fades; the outer layer arrives. */
|
|
331
|
+
readonly surface: {
|
|
332
|
+
readonly scale: 0.6;
|
|
333
|
+
readonly duration: 220;
|
|
334
|
+
readonly fade: 200;
|
|
335
|
+
readonly swapAfter: 220;
|
|
336
|
+
readonly ease: Bezier;
|
|
337
|
+
};
|
|
338
|
+
/** The arriving layer as a whole settles from slightly small. */
|
|
339
|
+
readonly settle: {
|
|
340
|
+
readonly fromScale: 0.94;
|
|
341
|
+
readonly duration: 260;
|
|
342
|
+
readonly ease: Bezier;
|
|
343
|
+
};
|
|
344
|
+
/** Hover (pointer) or select: the idea lifts; its rings turn and grow a touch — a nudge, not a wobble. */
|
|
345
|
+
readonly hover: {
|
|
346
|
+
readonly lift: 2;
|
|
347
|
+
readonly ringRotate: -2;
|
|
348
|
+
readonly ringScale: 1.015;
|
|
349
|
+
/** duration-base, for both the lift (ease-bloom) and the rings (ease-standard). */ readonly duration: 240;
|
|
350
|
+
readonly liftEase: Bezier;
|
|
351
|
+
readonly ringEase: Bezier;
|
|
352
|
+
};
|
|
353
|
+
/** Reduced motion, or Gradual reveal off: everything appears together with a short fade; dives become cross-fades. */
|
|
354
|
+
readonly reduced: {
|
|
355
|
+
readonly fade: 120;
|
|
356
|
+
};
|
|
357
|
+
/** Large layers. The stagger is written for a dozen ideas; a layer of hundreds would take minutes to arrive and
|
|
358
|
+
* every frame of a bloom repaints the whole layer. Above `staggerSlots` ideas (and connectors), they share that many
|
|
359
|
+
* slots, so a layer never takes longer to arrive than `staggerSlots` ideas would. Above `bloomMax` ideas the layer
|
|
360
|
+
* fades in together (the reduced fade) and hover lifts snap instead of easing. */
|
|
361
|
+
readonly largeLayer: {
|
|
362
|
+
readonly staggerSlots: 30;
|
|
363
|
+
readonly bloomMax: 150;
|
|
364
|
+
};
|
|
365
|
+
};
|
|
366
|
+
type Point = {
|
|
367
|
+
x: number;
|
|
368
|
+
y: number;
|
|
369
|
+
};
|
|
370
|
+
/** Delay before idea `i` (sibling order) starts to bloom. */
|
|
371
|
+
declare function revealDelay(i: number): number;
|
|
372
|
+
/** Delay before connector `i` starts, in a layer of `nodeCount` ideas. */
|
|
373
|
+
declare function connectorDelay(i: number, nodeCount: number): number;
|
|
374
|
+
/** How long a layer's arrival takes, until the map is idle again. 0 with reduced motion. */
|
|
375
|
+
declare function revealTotal(nodeCount: number, reduced?: boolean): number;
|
|
376
|
+
/** Where an idea starts its bloom, as an offset from its final position: part of the way toward the layer's center. */
|
|
377
|
+
declare function bloomOffset(node: Point, center: Point): Point;
|
|
378
|
+
/** When the layers swap after Step inside ('in') or Back out ('out'). 0 with reduced motion (a cross-fade). */
|
|
379
|
+
declare function swapDelay(dir: 'in' | 'out', reduced?: boolean): number;
|
|
380
|
+
/** The stagger slot of item `i` of `count` (ideas or connectors): its own index up to `staggerSlots`, then shared. */
|
|
381
|
+
declare function revealSlot(i: number, count: number): number;
|
|
382
|
+
/** Whether a layer of `nodeCount` ideas blooms in one by one (else it fades in together and hover lifts snap). */
|
|
383
|
+
declare function layerBlooms(nodeCount: number): boolean;
|
|
384
|
+
/** A layer's whole arrival, large layers included: when idea `i` and connector `i` start, and when the layer is idle. */
|
|
385
|
+
declare function layerReveal(nodeCount: number, connectorCount: number, reduced?: boolean): {
|
|
386
|
+
/** Fades in together (reduced motion, Gradual reveal off, or a layer past `bloomMax`). */ instant: boolean;
|
|
387
|
+
ideaDelay: (i: number) => number;
|
|
388
|
+
connectorDelay: (i: number) => number;
|
|
389
|
+
/** Until the map is idle again. */
|
|
390
|
+
total: number;
|
|
391
|
+
};
|
|
392
|
+
/** CSS form of an easing. */
|
|
393
|
+
declare function cssEase(e: Bezier): string;
|
|
394
|
+
/** Evaluate an easing at progress t (0–1), for renderers that animate in their own loop. */
|
|
395
|
+
declare function ease(e: Bezier, t: number): number;
|
|
396
|
+
/** The CSS variables VisualMap sets on its root, so its stylesheet animates with exactly these values. */
|
|
397
|
+
declare function motionVars(): Record<string, string>;
|
|
398
|
+
|
|
399
|
+
type Pt = {
|
|
400
|
+
x: number;
|
|
401
|
+
y: number;
|
|
402
|
+
};
|
|
403
|
+
type Box = {
|
|
404
|
+
x0: number;
|
|
405
|
+
y0: number;
|
|
406
|
+
x1: number;
|
|
407
|
+
y1: number;
|
|
408
|
+
};
|
|
409
|
+
type Hull = Box & {
|
|
410
|
+
radius: number;
|
|
411
|
+
};
|
|
412
|
+
type LabelSide = 'bottom' | 'top' | 'left' | 'right';
|
|
413
|
+
type LabelPlacement = {
|
|
414
|
+
x: number;
|
|
415
|
+
y: number;
|
|
416
|
+
side: LabelSide;
|
|
417
|
+
score: number;
|
|
418
|
+
};
|
|
419
|
+
/** The hull reaches this far beyond its ideas' centers, and rounds its corners this much. */
|
|
420
|
+
declare const HULL: {
|
|
421
|
+
padX: number;
|
|
422
|
+
padY: number;
|
|
423
|
+
radius: number;
|
|
424
|
+
};
|
|
425
|
+
/** Room kept between a member's outline and the hull, for ideas larger than the base size. */
|
|
426
|
+
declare const HULL_CLEAR: {
|
|
427
|
+
readonly x: 50;
|
|
428
|
+
readonly y: 51;
|
|
429
|
+
};
|
|
430
|
+
/** The hull around a group's ideas: `padX` / `padY` beyond their centres, or more for an idea that has grown to show
|
|
431
|
+
* its label (`rx` / `ry`, its half size: then its outline plus HULL_CLEAR). */
|
|
432
|
+
declare function containerHull(members: ReadonlyArray<Pt & {
|
|
433
|
+
rx?: number;
|
|
434
|
+
ry?: number;
|
|
435
|
+
}>): Hull | null;
|
|
436
|
+
/** Candidate spots for a w × h pill, in preference order: bottom center (the default look), top center, the thirds of
|
|
437
|
+
* bottom and top, then the sides. Spots keep the whole pill on the straight part of an edge, clear of the corners. */
|
|
438
|
+
declare function labelCandidates(hull: Hull, w: number, h: number): {
|
|
439
|
+
x: number;
|
|
440
|
+
y: number;
|
|
441
|
+
side: LabelSide;
|
|
442
|
+
}[];
|
|
443
|
+
/** Where a container's name goes. `ideas`: the boxes of every idea on the layer (outermost ring included);
|
|
444
|
+
* `connectors`: points sampled along every connector; `labels`: the pills already placed on this layer.
|
|
445
|
+
* `gap` keeps a little air between the pill and what it avoids. */
|
|
446
|
+
declare function placeContainerLabel(hull: Hull, size: {
|
|
447
|
+
w: number;
|
|
448
|
+
h: number;
|
|
449
|
+
}, obstacles: {
|
|
450
|
+
ideas: Box[];
|
|
451
|
+
connectors?: Pt[][];
|
|
452
|
+
labels?: Box[];
|
|
453
|
+
}, gap?: number): LabelPlacement;
|
|
454
|
+
/** Points along a connector, for `connectors`: the same cubic edgePath draws (control points two-thirds of the way
|
|
455
|
+
* from each end to the bowed midpoint `mid`, which edgePath returns). */
|
|
456
|
+
declare function connectorSamples(a: Pt, mid: Pt, b: Pt, n?: number): Pt[];
|
|
457
|
+
|
|
458
|
+
declare const DETAIL: {
|
|
459
|
+
/** Below this on-screen width an idea draws only its body: no rings, label or shadow. */ readonly bodyOnlyBelow: 24;
|
|
460
|
+
/** Below this it may be drawn as a plain filled speck in its topic fill (no outline) — indistinguishable at this size. */ readonly speckBelow: 12;
|
|
461
|
+
/** Above this many ideas in view, idea shadows are skipped (the costliest effect to draw). */ readonly shadowsMaxVisible: 150;
|
|
462
|
+
};
|
|
463
|
+
type IdeaDetail = 'full' | 'body' | 'speck';
|
|
464
|
+
/** What an idea of this on-screen width draws. A selected, focused or hovered idea always draws in full. */
|
|
465
|
+
declare function ideaDetail(screenWidth: number, emphasised?: boolean): IdeaDetail;
|
|
466
|
+
/** Whether idea shadows are drawn with this many ideas in view. */
|
|
467
|
+
declare function shadowsShown(visibleIdeas: number): boolean;
|
|
468
|
+
|
|
469
|
+
export { type Bezier, type BoundingBox, type ContainerGroupInfo, type CullingOptions, DETAIL, EASE, FEATURE_FLAGS, FRAME, type FitResult, FlatNode, type FrameBox, GESTURE, HULL, HULL_CLEAR, type Hull, type IRenderConfigStore, type ISelectionStore, type ISpatialIndex, type IdeaDetail, type Box as LabelBox, type LabelPlacement, type LabelSide, MOTION, MindMapConnection, NodeSelection, PEEK, PEEK_PLACEMENT, type Pt, RBushSpatialIndex, RenderConfig, SHEET, TERM, TRAIL, VIEW, ViewportState, VisualliDocument, VisualliLayer, bloomOffset, calculateFitCenter, calculateFitView, calculateFitZoom, connectorDelay, connectorSamples, containerHull, cssEase, ease as easeBezier, fitView, getChildLayerForNode, getConnectionsForLayer, getContainersForLayer, getLayerForNavigation, getViewportVisibleNodes, hoverOpensTerm, ideaDetail, intersectsViewport, labelCandidates, layerBlooms, layerBounds, layerFrame, layerReveal, motionVars, peekPosition, pinchZoom, placeContainerLabel, pointerModeFor, renderConfigStore, revealDelay, revealSlot, revealTotal, selectionStore, shadowsShown, swapDelay, zoomAround };
|