@dineug/erd-editor 3.6.0 → 3.8.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.
Files changed (107) hide show
  1. package/README.md +21 -24
  2. package/dist/components/erd/automatic-table-placement/AutomaticTablePlacement.d.ts +5 -15
  3. package/dist/components/erd/automatic-table-placement/runElkPlacement.d.ts +23 -0
  4. package/dist/components/erd/canvas/CanvasScene.d.ts +3 -3
  5. package/dist/components/erd/canvas/entityDrag.d.ts +5 -4
  6. package/dist/components/erd/canvas/highlightTransition.d.ts +35 -0
  7. package/dist/components/erd/canvas/memo/useMoveMemo.d.ts +3 -1
  8. package/dist/components/erd/canvas/mixColor.d.ts +7 -0
  9. package/dist/components/erd/canvas/relationship-group/RelationshipGroup.d.ts +2 -0
  10. package/dist/components/erd/canvas/relationship-group/relationship/Relationship.d.ts +2 -0
  11. package/dist/components/erd/canvas/relationship-group/relationship/Relationship.template.d.ts +3 -3
  12. package/dist/components/erd/canvas/sceneHit.d.ts +7 -6
  13. package/dist/components/erd/canvas/sceneTokens.d.ts +30 -4
  14. package/dist/components/erd/canvas/table/Table.d.ts +7 -0
  15. package/dist/components/erd/canvas/table/cellLayout.d.ts +48 -18
  16. package/dist/components/erd/canvas/table/column/Column.d.ts +26 -0
  17. package/dist/components/erd/canvas/table/goToErd.d.ts +18 -0
  18. package/dist/components/erd/canvas/table/useMoveTable.d.ts +3 -1
  19. package/dist/components/erd/canvas/table/useViewPin.d.ts +19 -0
  20. package/dist/components/erd/canvas/useMoveEntity.d.ts +9 -2
  21. package/dist/components/erd/content-compass/ContentCompass.d.ts +1 -1
  22. package/dist/components/erd/content-compass/compassGeometry.d.ts +27 -4
  23. package/dist/components/erd/erd-context-menu/menus/tablePlacementMenus.d.ts +24 -0
  24. package/dist/components/erd/floating-toolbar/FloatingToolbar.d.ts +3 -3
  25. package/dist/components/erd/floating-toolbar/FloatingToolbar.styles.d.ts +3 -0
  26. package/dist/components/erd/floating-toolbar/ToolbarCompass.template.d.ts +14 -0
  27. package/dist/components/erd/minimap/MinimapScene.d.ts +1 -1
  28. package/dist/components/erd/minimap/minimapGeometry.d.ts +4 -3
  29. package/dist/components/flowCenters.d.ts +10 -0
  30. package/dist/components/primitives/code-block/CodeBlock.d.ts +2 -2
  31. package/dist/components/primitives/icon/icons.d.ts +7 -0
  32. package/dist/components/sceneSourceContext.d.ts +10 -0
  33. package/dist/components/theme-builder/ThemeBuilder.styles.d.ts +5 -0
  34. package/dist/components/visualization/Visualization.d.ts +3 -4
  35. package/dist/components/visualization/VisualizationFlow.d.ts +10 -0
  36. package/dist/components/visualization/VisualizationGraph.d.ts +10 -0
  37. package/dist/components/visualization/flowLayout.d.ts +29 -0
  38. package/dist/components/visualization/graphViewHandle.d.ts +33 -0
  39. package/dist/components/visualization/particles/ParticleLayer.d.ts +10 -0
  40. package/dist/components/visualization/particles/particleEdges.d.ts +15 -0
  41. package/dist/components/visualization/particles/particleLoop.d.ts +28 -0
  42. package/dist/components/visualization/particles/particlePath.d.ts +83 -0
  43. package/dist/components/visualization/useViewGestures.d.ts +24 -0
  44. package/dist/components/visualization/visualization-toolbar/VisualizationToolbar.d.ts +10 -0
  45. package/dist/components/visualization/visualization-toolbar/VisualizationToolbar.styles.d.ts +4 -0
  46. package/dist/components/visualization/visualizationView.d.ts +29 -5
  47. package/dist/components/visualization/zoomVisualization.d.ts +20 -0
  48. package/dist/constants/layout.d.ts +50 -0
  49. package/dist/constants/tablePlacement.d.ts +16 -0
  50. package/dist/constants/zoom.d.ts +7 -0
  51. package/dist/engine/actions.d.ts +6 -0
  52. package/dist/engine/index.js +12 -12
  53. package/dist/engine/modules/editor/actions.d.ts +60 -2
  54. package/dist/engine/modules/editor/atom.actions.d.ts +136 -0
  55. package/dist/engine/modules/editor/generator.actions.d.ts +16 -4
  56. package/dist/engine/modules/editor/state.d.ts +41 -0
  57. package/dist/engine/modules/editor/view.actions.d.ts +270 -0
  58. package/dist/engine/modules/editor/view.d.ts +28 -0
  59. package/dist/engine/modules/editor/view.generator.actions.d.ts +24 -0
  60. package/dist/engine/modules/settings/atom.actions.d.ts +17 -3
  61. package/dist/engine/modules/settings/generator.actions.d.ts +6 -4
  62. package/dist/engine/rx-operators/viewActionRedirect.d.ts +10 -0
  63. package/dist/engine/rx-operators/viewIgnoreFilter.d.ts +10 -0
  64. package/dist/erd-editor.umd.js +319 -282
  65. package/dist/index.d.ts +0 -1
  66. package/dist/index.dev.d.ts +0 -1
  67. package/dist/index.js +6238 -4937
  68. package/dist/konva/scene/columnDropTarget.d.ts +2 -1
  69. package/dist/konva/scene/contentBounds.d.ts +12 -5
  70. package/dist/konva/scene/fitZoom.d.ts +16 -0
  71. package/dist/konva/scene/metrics.d.ts +6 -5
  72. package/dist/konva/scene/viewFreeze.d.ts +10 -7
  73. package/dist/konva/scene/viewLayout.d.ts +89 -0
  74. package/dist/konva/scene/viewport.d.ts +17 -4
  75. package/dist/{schemaGCService--wGet5O7.js → schemaGCService-CXVjeF9p.js} +3145 -2655
  76. package/dist/services/elk-layout/elkGraph.d.ts +83 -0
  77. package/dist/services/elk-layout/elkLayout.shared-worker.d.ts +2 -0
  78. package/dist/services/elk-layout/elkLayoutOptions.d.ts +46 -0
  79. package/dist/services/elk-layout/elkLayoutService.d.ts +25 -0
  80. package/dist/services/elk-layout/elkWorkerRealm.d.ts +2 -0
  81. package/dist/services/elk-layout/index.d.ts +19 -0
  82. package/dist/services/shiki/index.d.ts +10 -0
  83. package/dist/services/shiki/shiki.shared-worker.d.ts +2 -0
  84. package/dist/services/shiki/shikiService.d.ts +18 -0
  85. package/dist/utils/calcTable.d.ts +27 -1
  86. package/dist/utils/clickGesture.d.ts +19 -0
  87. package/dist/utils/domEvent.d.ts +12 -0
  88. package/dist/utils/draw-relationship/bezier.d.ts +32 -0
  89. package/dist/utils/draw-relationship/calc.d.ts +6 -1
  90. package/dist/utils/draw-relationship/geometrySource.d.ts +9 -0
  91. package/dist/utils/draw-relationship/incremental.d.ts +7 -1
  92. package/dist/utils/draw-relationship/index.d.ts +37 -11
  93. package/dist/utils/draw-relationship/pathFinding.d.ts +2 -1
  94. package/dist/utils/draw-relationship/route.d.ts +5 -3
  95. package/dist/utils/draw-relationship/sort.d.ts +2 -1
  96. package/dist/utils/draw-relationship/stub.d.ts +9 -4
  97. package/dist/utils/emitter.d.ts +18 -7
  98. package/dist/utils/globalEventObservable.d.ts +6 -1
  99. package/dist/utils/keyboard-shortcut/index.d.ts +2 -1
  100. package/dist/utils/promise.d.ts +6 -0
  101. package/dist/workers/elkLayout.shared-worker.js +1 -0
  102. package/dist/workers/exportPng.shared-worker.js +26 -26
  103. package/dist/workers/shiki.shared-worker.js +1 -0
  104. package/dist/workers/spawn.d.ts +5 -3
  105. package/dist/workers/spawn.inline.d.ts +2 -0
  106. package/package.json +7 -4
  107. package/dist/services/shikiService.d.ts +0 -9
package/README.md CHANGED
@@ -34,10 +34,11 @@ npm install @dineug/erd-editor
34
34
 
35
35
  The package ships ES modules with its dependencies left as bare imports, so any bundler
36
36
  (Vite, webpack, Rspack, esbuild, …) resolves, dedupes and tree-shakes them like the rest of
37
- your app. Two features run in shared workers — schema garbage collection and the PNG export
38
- constructed as `new SharedWorker(new URL('./workers/…', import.meta.url))`, which those bundlers
39
- emit as worker files beside your chunks; a strict CSP needs `worker-src 'self'`. Without a
40
- bundler, use the UMD file described under [Script tag](#script-tag) instead.
37
+ your app. Four features run in shared workers — schema garbage collection, the PNG export, the
38
+ automatic table placement and the syntax highlighting constructed as
39
+ `new SharedWorker(new URL('./workers/…', import.meta.url))`, which those bundlers emit as worker
40
+ files beside your chunks; a strict CSP needs `worker-src 'self'`. Without a bundler, use the UMD
41
+ file described under [Script tag](#script-tag) instead.
41
42
 
42
43
  ## Usage
43
44
 
@@ -79,7 +80,7 @@ that step; a production build needs nothing.
79
80
  // vite.config.js
80
81
  export default {
81
82
  optimizeDeps: {
82
- exclude: ['@dineug/erd-editor', '@dineug/erd-editor-shiki-worker'],
83
+ exclude: ['@dineug/erd-editor'],
83
84
  },
84
85
  };
85
86
  ```
@@ -87,16 +88,12 @@ export default {
87
88
  ### Script tag
88
89
 
89
90
  `dist/erd-editor.umd.js` is a self-contained build for a plain `<script>` tag: every
90
- dependency and both workers are inside it, and it registers `<erd-editor>` and exposes the
91
- three callbacks as `window.ErdEditor`. It is what `unpkg` and `jsdelivr` serve.
91
+ dependency and all four workers are inside it, and it registers `<erd-editor>` and exposes the
92
+ two file callbacks as `window.ErdEditor`. It is what `unpkg` and `jsdelivr` serve.
92
93
 
93
94
  ```html
94
95
  <erd-editor style="display: block; width: 100%; height: 100vh"></erd-editor>
95
96
  <script src="https://cdn.jsdelivr.net/npm/@dineug/erd-editor/dist/erd-editor.umd.js"></script>
96
- <script src="https://cdn.jsdelivr.net/npm/@dineug/erd-editor-shiki-worker/dist/erd-editor-shiki-worker.umd.js"></script>
97
- <script>
98
- ErdEditor.setGetShikiServiceCallback(ErdEditorShikiWorker.getShikiService);
99
- </script>
100
97
  ```
101
98
 
102
99
  The workers travel inside the file as `data:` URLs, so a strict CSP needs `worker-src data:`
@@ -165,22 +162,22 @@ erd-editor {
165
162
 
166
163
  ## Syntax highlighting
167
164
 
168
- The SQL and code-generation panels render as plain text unless a highlighter is supplied.
169
- [`@dineug/erd-editor-shiki-worker`](https://www.npmjs.com/package/@dineug/erd-editor-shiki-worker)
170
- runs one in a shared worker. It is a separate install:
165
+ The SQL and code-generation panels are highlighted by [Shiki](https://shiki.style), in a shared
166
+ worker of its own. There is nothing to install or register: the worker is built the first time a
167
+ code panel renders, so a page that opens none never fetches the grammars.
171
168
 
172
- ```sh
173
- npm install @dineug/erd-editor-shiki-worker
174
- ```
169
+ | | |
170
+ | --- | --- |
171
+ | Languages | SQL, TypeScript, GraphQL, C#, Java, Kotlin, Scala, Go, Python |
172
+ | Themes | `github-dark`, `github-light`, picked from the editor's light / dark appearance |
175
173
 
176
- ```js
177
- import { setGetShikiServiceCallback } from '@dineug/erd-editor';
174
+ Those are exactly the languages the panels emit — the JPA generator emits Java, the SQLAlchemy
175
+ generator emits Python, the TypeORM, Sequelize and Drizzle generators emit TypeScript, and the
176
+ DBML and AML generators are highlighted as SQL, the closest grammar shiki ships.
178
177
 
179
- // deferred, so the highlighter never lands in your main chunk
180
- import('@dineug/erd-editor-shiki-worker').then(({ getShikiService }) => {
181
- setGetShikiServiceCallback(getShikiService);
182
- });
183
- ```
178
+ Where `SharedWorker` is missing — Chrome on Android, Safari before 16.4 the underlying error is
179
+ logged and the panels render as plain text; nothing else is affected. The regex engine is plain
180
+ JavaScript, so no host CSP needs `wasm-unsafe-eval`.
184
181
 
185
182
  ## File dialogs
186
183
 
@@ -1,7 +1,5 @@
1
1
  import { FC, Ref } from '@dineug/r-html';
2
2
  import { AppContext } from '../../appContext';
3
- import { Viewport } from '../../../engine/modules/editor/state';
4
- import { Rect } from '../../../konva/scene/metrics';
5
3
  export type AutomaticTablePlacementProps = {
6
4
  app: Ref<AppContext>;
7
5
  onChange: (tables: TablePoint[]) => void;
@@ -11,19 +9,11 @@ export type TablePoint = {
11
9
  x: number;
12
10
  y: number;
13
11
  };
14
- /**
15
- * Scene units left around the content when the preview fits it, so a table at
16
- * the edge of the document is not flush against the edge of the screen.
17
- */
18
- export declare const FIT_PADDING = 200;
19
- /** The closest the preview opens at: the whole document is what it is for. */
20
- export declare const PREVIEW_ZOOM_MAX = 0.7;
21
- /**
22
- * The zoom the preview opens at: the content with its padding fitted into the
23
- * screen on both axes, rounded to the two places a zoom is kept to, and held
24
- * between the floor every zoom has and the ceiling above.
25
- */
26
- export declare function previewZoomLevel(content: Rect, viewport: Viewport): number;
12
+ /** How far the simulation has cooled, from 0 to 1. */
13
+ export type PlacementToastState = {
14
+ progress: number;
15
+ };
16
+ export declare function placementDescription({ progress, }: PlacementToastState): string;
27
17
  declare const AutomaticTablePlacement: FC<AutomaticTablePlacementProps>;
28
18
  export default AutomaticTablePlacement;
29
19
  //# sourceMappingURL=AutomaticTablePlacement.d.ts.map
@@ -0,0 +1,23 @@
1
+ import { FC } from '@dineug/r-html';
2
+ import { AppContext } from '../../appContext';
3
+ import { ElkLayoutPoint, ElkPlacement } from '../../../services/elk-layout';
4
+ type PlacingToastProps = {
5
+ onCancel: () => void;
6
+ };
7
+ /**
8
+ * The message up while ELK works, and the whole of what a one-shot placement
9
+ * shows. There is no progress to follow and nothing to read off a layout that
10
+ * does not exist yet, so Cancel is the only thing on it. A view placement shows it too.
11
+ */
12
+ export declare const PlacingToast: FC<PlacingToastProps>;
13
+ /**
14
+ * Places every table by ELK and hands the layout straight over. No preview
15
+ * overlay: one layout arrives at once, there is nothing to weigh before it
16
+ * lands, and a single undo puts every table back.
17
+ *
18
+ * @example
19
+ * runElkPlacement(app.value, placement, handleChangeAutomaticTablePlacement);
20
+ */
21
+ export declare function runElkPlacement(app: AppContext, placement: ElkPlacement, onChange: (tables: ElkLayoutPoint[]) => void): Promise<void>;
22
+ export {};
23
+ //# sourceMappingURL=runElkPlacement.d.ts.map
@@ -4,9 +4,9 @@ export type CanvasSceneProps = {
4
4
  root: Ref<HTMLDivElement>;
5
5
  };
6
6
  /**
7
- * The four layers of the canvas, plus the one a drag opens. Background, scene
8
- * and presence carry the canvas transform, and the marquee layer stays in
9
- * screen space because that is where its own mousemove measures.
7
+ * The layers of the canvas, four over the document and four under a view,
8
+ * plus the one a drag opens. Each carries the canvas transform but the
9
+ * marquee, which stays in screen space where its own mousemove measures.
10
10
  */
11
11
  declare const CanvasScene: FC<CanvasSceneProps>;
12
12
  /**
@@ -1,7 +1,8 @@
1
1
  import { RootState } from '../../../engine/state';
2
- /** Raises the flag and holds the view as it stands until endEntityDrag. */
3
- export declare function beginEntityDrag(root: RootState): void;
4
- export declare function endEntityDrag(root: RootState): void;
2
+ import { GeometrySource } from '../../../utils/draw-relationship/geometrySource';
3
+ /** Raises the flag and holds the scene's view as it stands until endEntityDrag. */
4
+ export declare function beginEntityDrag(root: RootState, source?: GeometrySource): void;
5
+ export declare function endEntityDrag(root: RootState, source?: GeometrySource): void;
5
6
  /** Reads the flag through the observable, so a scene render tracks it. */
6
- export declare function isEntityDragActive(root: RootState): boolean;
7
+ export declare function isEntityDragActive(root: RootState, source?: GeometrySource): boolean;
7
8
  //# sourceMappingURL=entityDrag.d.ts.map
@@ -0,0 +1,35 @@
1
+ /** The time and the frame a transition runs on, so a spec can step it and count its frames. */
2
+ export type TransitionClock = {
3
+ now(): number;
4
+ requestFrame(callback: () => void): number;
5
+ cancelFrame(handle: number): void;
6
+ };
7
+ /** How long a highlight takes to come up or go out, the span the reference gives its edges. */
8
+ export declare const TRANSITION_MS = 300;
9
+ /**
10
+ * The key one transition is held under. The editor id leads so a scene that
11
+ * closes drops its own keys and no one else's, and the kind separates a table
12
+ * from a connector that was minted the same id.
13
+ */
14
+ export declare function transitionKey(editorId: string, kind: string, id: string): string;
15
+ /**
16
+ * What the key shows now: where the frame last put it, or the target it rests
17
+ * at. Reading a key that is not moving arms nothing, which is what keeps this
18
+ * module frameless in the export worker that carries it.
19
+ */
20
+ export declare function progressOf(key: string): number;
21
+ /**
22
+ * Sends a key toward the target given. A key already heading there is left
23
+ * alone, and a key asked for the first time settles on the target at once, so
24
+ * only a change a reader could have watched is animated.
25
+ */
26
+ export declare function transitionTo(key: string, target: number): void;
27
+ /** Drops every key one editor holds and cancels the frame if nothing else is moving. */
28
+ export declare function stopTransitions(editorId: string): void;
29
+ /**
30
+ * Runs the transitions on the clock given, or on the browser's own again when
31
+ * called with nothing. Whatever was moving lands on its target, since a start
32
+ * time taken from one clock means nothing against another.
33
+ */
34
+ export declare function setTransitionClock(next?: TransitionClock): void;
35
+ //# sourceMappingURL=highlightTransition.d.ts.map
@@ -1,7 +1,9 @@
1
+ import { Ref } from '@dineug/r-html';
1
2
  import { Ctx, Memo } from '../../../../internal-types';
3
+ import { GeometrySource } from '../../../../utils/draw-relationship/geometrySource';
2
4
  export declare function useMoveMemo(ctx: Ctx, props: {
3
5
  memo: Memo;
4
- }): {
6
+ }, source: Ref<GeometrySource>): {
5
7
  onMoveStart: (event: import('../sceneTokens').ScenePointerEvent) => void;
6
8
  };
7
9
  //# sourceMappingURL=useMoveMemo.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The colour a fraction of the way from one to the other, mixed straight in
3
+ * rgb. Both ends come back exactly as they were given, and a colour this
4
+ * cannot read is handed back whole rather than mangled into one that is not.
5
+ */
6
+ export declare function mixColor(from: string, to: string, t: number): string;
7
+ //# sourceMappingURL=mixColor.d.ts.map
@@ -5,6 +5,8 @@ export type RelationshipGroupProps = {
5
5
  relationships: RelationshipType[];
6
6
  viewport?: CullingRect;
7
7
  strokeWidth?: number;
8
+ /** The connectors a view lights, decided once by the scene rather than by each leaf. */
9
+ litIds?: Set<string>;
8
10
  };
9
11
  /**
10
12
  * Culling lives here, not in the parent, because a route is a side channel of
@@ -3,6 +3,8 @@ import { Relationship as RelationshipType } from '../../../../../internal-types'
3
3
  export type RelationshipProps = {
4
4
  relationship: RelationshipType;
5
5
  strokeWidth: number;
6
+ /** Whether the view lights this connector, decided by the scene it is drawn in. */
7
+ lit?: boolean;
6
8
  };
7
9
  declare const Relationship: FC<RelationshipProps>;
8
10
  export default Relationship;
@@ -11,8 +11,8 @@ export declare const segment: ({ x1, y1, x2, y2 }: PointToPoint) => number[];
11
11
  * One stroke of a cardinality marker. The paint, the width and the two naming
12
12
  * attributes are per node in konva, so every marker is drawn through here.
13
13
  */
14
- export declare function decorationLine(points: PointToPoint, stroke: string): DOMTemplateLiterals;
14
+ export declare function decorationLine(points: PointToPoint, stroke: string, strokeWidth: number): DOMTemplateLiterals;
15
15
  /** The optional ring of a cardinality marker, at either anchor. */
16
- export declare function decorationRing({ cx, cy }: Circle, stroke: string): DOMTemplateLiterals;
17
- export declare function relationshipShape(relationshipType: number, { path, line }: RelationshipPath, stroke: string): DOMTemplateLiterals | null;
16
+ export declare function decorationRing({ cx, cy }: Circle, stroke: string, strokeWidth: number): DOMTemplateLiterals;
17
+ export declare function relationshipShape(relationshipType: number, { path, line }: RelationshipPath, stroke: string, strokeWidth: number): DOMTemplateLiterals | null;
18
18
  //# sourceMappingURL=Relationship.template.d.ts.map
@@ -1,15 +1,16 @@
1
1
  import { Context } from 'konva/lib/Context';
2
2
  import { Shape } from 'konva/lib/Shape';
3
+ import { GeometrySource } from '../../../utils/draw-relationship/geometrySource';
3
4
  /** What konva calls to put a shape on the hit canvas, in the shape's own space. */
4
5
  export type HitFunc = (context: Context, shape: Shape) => void;
5
6
  /**
6
- * The box a column cell's text answers a press for: the full row height and
7
- * the gap to the next cell, which is the div the dom scene put the input in.
8
- * The text carries it so the cell needs no shape that exists only to be hit.
7
+ * One of those per source, built once. A row is not the same height in a view
8
+ * as in the document, and konva reads this off an attribute, so a function
9
+ * built per render would mark every cell dirty every frame.
9
10
  */
10
- export declare const columnCellHit: HitFunc;
11
- /** The header cell's box, the same way, at the header input's own height. */
12
- export declare const headerCellHit: HitFunc;
11
+ export declare const columnCellHit: Record<GeometrySource, HitFunc>;
12
+ /** One of those per source, built once, for the reason columnCellHit is. */
13
+ export declare const headerCellHit: Record<GeometrySource, HitFunc>;
13
14
  /**
14
15
  * The whole 24 unit box of a lucide icon, answered by the first shape it draws.
15
16
  * A circle's origin is its centre, so its own position is what puts the box
@@ -8,10 +8,20 @@ export type ScenePointerEvent = SceneMouseEvent | SceneTouchEvent;
8
8
  * make a cell wider or narrower than the width the layout reserved for it.
9
9
  */
10
10
  export declare const SCENE_FONT_FAMILY: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', 'Open Sans', system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'";
11
+ /**
12
+ * The monospace face a view draws a type cell in, the same stack the code
13
+ * panels use. A second face on the scene, so the metrics below are kept per
14
+ * face rather than as the one pair the text face used to be the whole of.
15
+ */
16
+ export declare const SCENE_CODE_FONT_FAMILY: "'Menlo', 'Consolas', 'Bitstream Vera Sans Mono', monospace, 'Apple Color Emoji', 'Segoe UI Emoji'";
11
17
  /** The px behind font-size-1, which is what typography.paragraph resolves to. */
12
18
  export declare const SCENE_FONT_SIZE = 12;
13
- /** The css font shorthand konva builds for a cell's text, and measures it with. */
19
+ /** That shorthand in the text face. */
14
20
  export declare const SCENE_FONT: string;
21
+ /** The weight every cell but a view card's header name is drawn at. */
22
+ export declare const SCENE_FONT_WEIGHT = "normal";
23
+ /** The heavier weight a view card draws its header name at. */
24
+ export declare const VIEW_HEADER_FONT_WEIGHT = "500";
15
25
  /** The pair a canvas centres a drawn line by, which no line box is involved in. */
16
26
  export type SceneFontMetrics = {
17
27
  ascent: number;
@@ -19,13 +29,13 @@ export type SceneFontMetrics = {
19
29
  };
20
30
  /**
21
31
  * The ascent and descent konva centres a drawn line by, read with the measure
22
- * call konva makes itself. A canvas has no line box to lean on, so this pair is
23
- * the whole of where a baseline lands, and the editor has to read the same one.
32
+ * call konva makes itself, and kept per face: the scene draws a type cell in
33
+ * the code face, whose overhang is not the text face's and whose baseline is its own.
24
34
  *
25
35
  * @example
26
36
  * const { ascent, descent } = getSceneFontMetrics();
27
37
  */
28
- export declare function getSceneFontMetrics(): SceneFontMetrics;
38
+ export declare function getSceneFontMetrics(fontFamily?: string): SceneFontMetrics;
29
39
  /**
30
40
  * The px behind font-size-5 through font-size-9, in the order HighLevelTable
31
41
  * steps through them as the zoom falls. The scale itself is a CSS custom
@@ -42,6 +52,22 @@ export declare const HEADER_COLOR_HEIGHT = 4;
42
52
  export declare const FOCUS_BORDER_HEIGHT = 1.5;
43
53
  /** What the ring outside a table box costs, as outline and box-shadow both do. */
44
54
  export declare const RING_WIDTH = 1;
55
+ /**
56
+ * The drop shadow a view card sits on, which is what lifts it off the ground
57
+ * the ERD canvas draws flat. The alpha is the shadow's own, since the shadow
58
+ * colour token is opaque and the palette has no translucent spelling of it.
59
+ */
60
+ export declare const VIEW_CARD_SHADOW_BLUR = 20;
61
+ export declare const VIEW_CARD_SHADOW_OFFSET_X = 0;
62
+ export declare const VIEW_CARD_SHADOW_OFFSET_Y = 2;
63
+ export declare const VIEW_CARD_SHADOW_OPACITY = 0.4;
64
+ /**
65
+ * The bloom a lit view card wears, drawn as a shadow on a stroke and never as
66
+ * a filled sibling: a fill behind the body would have to be reordered under it,
67
+ * and the ledger is the only thing allowed to order the scene.
68
+ */
69
+ export declare const VIEW_CARD_GLOW_BLUR = 14;
70
+ export declare const VIEW_CARD_GLOW_OPACITY = 0.55;
45
71
  /** The side of the square viewBox every icon is authored in. */
46
72
  export declare const ICON_VIEW_SIZE: number;
47
73
  /** What a colour is when the scene paints nothing, as a CSS keyword konva takes. */
@@ -10,6 +10,13 @@ export type TableProps = {
10
10
  editorFocused?: boolean;
11
11
  /** Off while the table is kept built but scrolled out of the culling rect. */
12
12
  visible?: boolean;
13
+ /** Whether the view lights this card, decided by the scene it is drawn in. */
14
+ lit?: boolean;
15
+ /**
16
+ * The rows of this table a relationship ends on, which a view tints. Decided
17
+ * by the scene, which walks the document's links once for every card it draws.
18
+ */
19
+ relatedColumnIds?: Set<string> | null;
13
20
  };
14
21
  declare const Table: FC<TableProps>;
15
22
  export default Table;
@@ -3,6 +3,7 @@ import { RootState } from '../../../../engine/state';
3
3
  import { Table } from '../../../../internal-types';
4
4
  import { Theme } from '../../../../themes/tokens';
5
5
  import { ColumnWidth } from '../../../../utils/calcTable';
6
+ import { GeometrySource } from '../../../../utils/draw-relationship/geometrySource';
6
7
  /** The four widths a column row measures from its table; the rest are fixed. */
7
8
  export type ColumnCellWidths = Pick<ColumnWidth, 'comment' | 'dataType' | 'default' | 'name'>;
8
9
  /** One editable box on a table, positioned inside the table's own group. */
@@ -16,12 +17,40 @@ export type ColumnCellSlot = CellSlot & {
16
17
  };
17
18
  /** Where the header cell row starts inside a table group. */
18
19
  export declare const HEADER_CELLS_X: number;
19
- export declare const HEADER_CELLS_Y: number;
20
- /** The text line inside a header cell and inside a column cell. */
21
- export declare const HEADER_TEXT_Y = 2;
22
- export declare const COLUMN_TEXT_Y = 2;
23
- /** Where the scene runs its focus rect inside a cell, header and column both. */
20
+ /**
21
+ * How far down a table group the header cells start. The document keeps the
22
+ * icon band above them; a view draws no icon there, so its cells begin at the
23
+ * inset itself.
24
+ */
25
+ export declare function getHeaderCellsY(source?: GeometrySource): number;
26
+ /**
27
+ * The text line inside a header cell. The document pads its input box; a view
28
+ * starts its line at the top of the icon band, which the card's own padding has
29
+ * already put where the band wants it.
30
+ */
31
+ export declare function getHeaderTextY(source?: GeometrySource): number;
32
+ /**
33
+ * The box that line is centred in. The document uses the box its editor opens
34
+ * an input in; a view centres on the icon beside the name instead, so the two
35
+ * share one middle.
36
+ */
37
+ export declare function getHeaderTextHeight(source?: GeometrySource): number;
38
+ /** The text line inside a column cell, at the padding its own source lays rows out with. */
39
+ export declare function getColumnTextY(source?: GeometrySource): number;
40
+ /**
41
+ * The box that line is centred in, the same split: the editor's input box in
42
+ * the document, and the row's own icon band in a view, which is what leaves the
43
+ * text on the badge's middle.
44
+ */
45
+ export declare function getColumnTextHeight(source?: GeometrySource, fontFamily?: string): number;
46
+ /** Where the scene runs its focus rect inside a header cell. */
24
47
  export declare const CELL_UNDERLINE_Y: number;
48
+ /**
49
+ * The same rect inside a column cell, along the foot of the line box the row
50
+ * leaves between its two paddings. The document draws it alone, so the row it
51
+ * is measured against is the document's.
52
+ */
53
+ export declare function getColumnUnderlineY(): number;
25
54
  /**
26
55
  * The paint that focus rect takes, header and column both: the input colour
27
56
  * while the cell is being edited, and greyed out with the rest of the focus
@@ -30,35 +59,36 @@ export declare const CELL_UNDERLINE_Y: number;
30
59
  export declare function focusBorderFill(theme: Theme, edit: boolean, editorFocused: boolean | undefined): string;
31
60
  /**
32
61
  * The baseline one line of cell text is drawn on, down from the top of the
33
- * cell. Blink puts a painted baseline on the device grid before the zoom scales
34
- * it, so only a whole pixel survives both rasterisers unchanged.
62
+ * cell, in the face named or the scene's own. Blink puts a painted baseline on
63
+ * the device grid before the zoom scales it, so only a whole pixel survives both rasterisers.
35
64
  *
36
65
  * @example
37
66
  * const baseline = getCellTextBaseline();
38
67
  */
39
- export declare function getCellTextBaseline(): number;
68
+ export declare function getCellTextBaseline(fontFamily?: string): number;
40
69
  /**
41
- * The box one line of cell text is centred in. The scene hands konva this
42
- * height with verticalAlign middle and the editor gives its input the same one,
43
- * which is what puts the two baselines on one whole pixel instead of two.
70
+ * The box one line of cell text is centred in, in the face named or the
71
+ * scene's own. The scene hands konva this height with verticalAlign middle and
72
+ * the editor gives its input the same one, which puts the two baselines on one whole pixel.
44
73
  *
45
74
  * @example
46
75
  * const height = getCellTextHeight();
47
76
  */
48
- export declare function getCellTextHeight(): number;
49
- /** Where a column row's cells start, past the key badge. */
50
- export declare const COLUMN_CELLS_X: number;
77
+ export declare function getCellTextHeight(fontFamily?: string): number;
78
+ /** Where a column row's cells start, past the key badge its own source sizes. */
79
+ export declare function getColumnCellsX(source?: GeometrySource): number;
51
80
  /** The comment width a table draws at, clamped by the setting when it is set. */
52
81
  export declare function getWidthComment(state: RootState, table: Table): number;
53
82
  /**
54
83
  * The name and comment boxes across a table header. One list feeds both the
55
84
  * scene that draws them and the overlay that edits them, so an editor can never
56
- * sit anywhere but on the text it replaces.
85
+ * sit anywhere but on the text it replaces. A view draws the name alone.
57
86
  */
58
- export declare function getHeaderCellSlots(state: RootState, table: Table): CellSlot[];
87
+ export declare function getHeaderCellSlots(state: RootState, table: Table, source?: GeometrySource): CellSlot[];
59
88
  /**
60
89
  * The cells of one column row, in the order the settings put them and at the x
61
- * each lands on once the ones before it have taken their width.
90
+ * each lands on once the ones before it have taken their width. A view lays
91
+ * out the name and the type and reads neither the show bits nor the order.
62
92
  */
63
- export declare function getColumnCellSlots(state: RootState, widths: ColumnCellWidths): ColumnCellSlot[];
93
+ export declare function getColumnCellSlots(state: RootState, widths: ColumnCellWidths, source?: GeometrySource): ColumnCellSlot[];
64
94
  //# sourceMappingURL=cellLayout.d.ts.map
@@ -1,8 +1,34 @@
1
1
  import { FC } from '@dineug/r-html';
2
2
  import { SceneMouseEvent } from '../../sceneTokens';
3
3
  import { Column } from '../../../../../internal-types';
4
+ import { GeometrySource } from '../../../../../utils/draw-relationship/geometrySource';
4
5
  export type ColumnProps = {
5
6
  column: Column;
7
+ /**
8
+ * The source the table drawing this row reads, which picks the row's cells. A
9
+ * prop rather than useSceneSource, the one leaf to depart from it: the table
10
+ * resolved it already, and a context costs an observable and a subscription per row.
11
+ */
12
+ source: GeometrySource;
13
+ /**
14
+ * Whether a relationship ends on this column, which a view tints the row
15
+ * for. Decided by the scene, which walks the links once for every card.
16
+ */
17
+ related?: boolean;
18
+ /**
19
+ * How far the light has come up on the card this row is drawn in, which is
20
+ * what the row tint and the type cell above are both drawn at. One number, so
21
+ * the two of them come up over the one span of time and a document row reads none of it.
22
+ */
23
+ litAlpha?: number;
24
+ /** Whether a view rules a line under this row, which every row but the last does. */
25
+ divider?: boolean;
26
+ /**
27
+ * Whether this is the row a view card ends at. A view draws no padding under
28
+ * its rows, so the last one meets the card's bottom border and takes the two
29
+ * corners it is rounded by, or its square tint would stand outside them.
30
+ */
31
+ last?: boolean;
6
32
  y: number;
7
33
  width: number;
8
34
  selected: boolean;
@@ -0,0 +1,18 @@
1
+ import { GeneratorAction } from '../../../../engine/generator.actions';
2
+ import { RxStore } from '../../../../engine/rx-store';
3
+ /**
4
+ * Stands the reader on one table in the document, selected, scrolled to the
5
+ * middle of the screen at the document's own zoom unless it is already on
6
+ * screen whole, since that scroll is the one change the host hears of. One that is gone is passed over.
7
+ */
8
+ export declare const showErdTableAction$: (tableId: string) => GeneratorAction;
9
+ /**
10
+ * The Go to ERD button's whole errand: the tab in one dispatch, the scroll and
11
+ * the selection in a second. A batch is classified by the state before it, so
12
+ * a scroll travelling with the tab change would be redirected into the view it leaves.
13
+ *
14
+ * @example
15
+ * goToErdTable(store, 'orders');
16
+ */
17
+ export declare function goToErdTable(store: RxStore, tableId: string): void;
18
+ //# sourceMappingURL=goToErd.d.ts.map
@@ -1,7 +1,9 @@
1
+ import { Ref } from '@dineug/r-html';
1
2
  import { Ctx, Table } from '../../../../internal-types';
3
+ import { GeometrySource } from '../../../../utils/draw-relationship/geometrySource';
2
4
  export declare function useMoveTable(ctx: Ctx, props: {
3
5
  table: Table;
4
- }): {
6
+ }, source: Ref<GeometrySource>): {
5
7
  onMoveStart: (event: import('../sceneTokens').ScenePointerEvent) => void;
6
8
  };
7
9
  //# sourceMappingURL=useMoveTable.d.ts.map
@@ -0,0 +1,19 @@
1
+ import { Ref } from '@dineug/r-html';
2
+ import { AppContext } from '../../../appContext';
3
+ import { ScenePointerEvent } from '../sceneTokens';
4
+ import { Table } from '../../../../internal-types';
5
+ import { GeometrySource } from '../../../../utils/draw-relationship/geometrySource';
6
+ /**
7
+ * The click a view scene takes on a table: pressed with the main button and
8
+ * lifted without moving and without the modifier. It pins the highlight on
9
+ * that table, and a second click on the same one lets it go. Documents take none.
10
+ *
11
+ * @example
12
+ * const pin = useViewPin(app, props, sourceRef);
13
+ */
14
+ export declare function useViewPin(app: Ref<AppContext>, props: {
15
+ table: Table;
16
+ }, source: Ref<GeometrySource>): {
17
+ onPress: (event: ScenePointerEvent) => void;
18
+ };
19
+ //# sourceMappingURL=useViewPin.d.ts.map
@@ -1,12 +1,19 @@
1
+ import { Ref } from '@dineug/r-html';
1
2
  import { ScenePointerEvent } from './sceneTokens';
2
3
  import { SelectType } from '../../../engine/modules/editor/state';
3
4
  import { Ctx } from '../../../internal-types';
5
+ import { GeometrySource } from '../../../utils/draw-relationship/geometrySource';
4
6
  export type MoveEntityOptions = {
5
7
  /** Read late, because repeat hands a component a new entity in place. */
6
8
  entityId: () => string;
7
9
  selectType: SelectType;
8
- /** The scene kinds a drag never starts from, as closest read their classes. */
9
- blockedKinds: readonly string[];
10
+ /** The scene kinds a drag never starts from in the scene pressed, as closest read their classes. */
11
+ blockedKinds: (source: GeometrySource) => readonly string[];
12
+ /**
13
+ * The scene the component already stands in, handed down rather than read
14
+ * again here, so a leaf pays for one context subscription and not two.
15
+ */
16
+ source: Ref<GeometrySource>;
10
17
  };
11
18
  /**
12
19
  * The pointer start every draggable entity shares: select it, hand an Alt drag
@@ -3,7 +3,7 @@ export type ContentCompassProps = {};
3
3
  /**
4
4
  * The one thing on a screen that has been panned off every table and memo: an
5
5
  * arrow at the nearest of them, how far off it lies, and a press that puts it
6
- * back in the middle of the screen.
6
+ * back in the middle. A pill of its own, for the diff viewer, which draws no bar to carry one.
7
7
  */
8
8
  declare const ContentCompass: FC<ContentCompassProps>;
9
9
  export default ContentCompass;
@@ -1,5 +1,8 @@
1
+ import { RxStore } from '../../../engine/rx-store';
1
2
  import { RootState } from '../../../engine/state';
2
3
  import { Point } from '../../../internal-types';
4
+ import { Rect } from '../../../konva/scene/metrics';
5
+ import { GeometrySource } from '../../../utils/draw-relationship/geometrySource';
3
6
  /** Which way the nearest entity lies and how far, while the screen holds none. */
4
7
  export type ContentCompass = {
5
8
  /** Degrees clockwise from east, which is the rotation the arrow is drawn at. */
@@ -10,11 +13,31 @@ export type ContentCompass = {
10
13
  target: Point;
11
14
  };
12
15
  /**
13
- * Where the nearest entity stands when the screen shows none of them, measured
14
- * from the screen's own middle. Null while any table or memo reaches the screen,
15
- * touching it counting as reaching it, and null while nobody has measured one.
16
+ * Where the nearest of the rects stands when the screen holds none of them,
17
+ * measured from the screen's own middle. Null while any of them reaches the
18
+ * screen, touching it counting as reaching it, and null where there are none.
19
+ *
20
+ * @example
21
+ * const compass = nearestContent(getContentRects(state, [], source), screen);
16
22
  */
17
- export declare function getContentCompass(state: RootState): ContentCompass | null;
23
+ export declare function nearestContent(rects: Iterable<Rect>, screen: Rect): ContentCompass | null;
24
+ /**
25
+ * Where the nearest entity stands when the screen shows none of them, in the
26
+ * scene the source names. Null while any table or memo reaches the screen and
27
+ * null while nobody has measured one.
28
+ */
29
+ export declare function getContentCompass(state: RootState, source?: GeometrySource): ContentCompass | null;
30
+ /** Small enough beside a label or a button to read as a mark rather than one. */
31
+ export declare const COMPASS_ARROW_SIZE = 14;
32
+ /**
33
+ * Puts the nearest entity in the middle of the screen of the source given, and
34
+ * does nothing while the screen holds one. Read on the press rather than closed
35
+ * over by the render that drew the arrow, since a wheel between the two moves the screen.
36
+ *
37
+ * @example
38
+ * scrollToNearestContent(store, ViewKind.flow);
39
+ */
40
+ export declare function scrollToNearestContent(store: RxStore, source?: GeometrySource): void;
18
41
  /**
19
42
  * The gap as the pill prints it: whole scene units under a thousand, then
20
43
  * thousands, millions and billions carrying one decimal under ten, so the label