@dineug/erd-editor 3.3.1 → 3.5.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 +197 -17
- package/dist/components/appContext.d.ts +8 -1
- package/dist/components/erd/automatic-table-placement/createAutomaticTablePlacement.d.ts +17 -1
- package/dist/components/erd/canvas/Canvas.d.ts +5 -0
- package/dist/components/erd/canvas/Canvas.styles.d.ts +11 -0
- package/dist/components/erd/canvas/CanvasScene.d.ts +18 -0
- package/dist/components/erd/canvas/EditOverlay.d.ts +8 -0
- package/dist/components/erd/canvas/EditOverlay.styles.d.ts +6 -0
- package/dist/components/erd/canvas/SceneIcon.template.d.ts +21 -0
- package/dist/components/erd/canvas/altDragDuplicate.d.ts +3 -0
- package/dist/components/erd/canvas/drag-select/DragSelect.d.ts +11 -0
- package/dist/components/erd/canvas/duplicate-ghost/DuplicateGhost.d.ts +9 -0
- package/dist/components/erd/canvas/entityDrag.d.ts +4 -0
- package/dist/components/erd/canvas/high-level-table/HighLevelTable.d.ts +4 -0
- package/dist/components/erd/canvas/memo/Memo.d.ts +2 -0
- package/dist/components/erd/canvas/memo/memo-sash/MemoSash.d.ts +11 -1
- package/dist/components/erd/canvas/memo/memoCaret.d.ts +26 -0
- package/dist/components/erd/canvas/memo/memoScroll.d.ts +28 -0
- package/dist/components/erd/canvas/memo/memoText.d.ts +33 -0
- package/dist/components/erd/canvas/memo/useMoveMemo.d.ts +6 -0
- package/dist/components/erd/canvas/relationship-group/RelationshipGroup.d.ts +15 -0
- package/dist/components/erd/canvas/relationship-group/relationship/Relationship.template.d.ts +17 -0
- package/dist/components/erd/canvas/sceneHit.d.ts +18 -0
- package/dist/components/erd/canvas/sceneKind.d.ts +11 -0
- package/dist/components/erd/canvas/sceneRetention.d.ts +31 -0
- package/dist/components/erd/canvas/sceneTokens.d.ts +67 -0
- package/dist/components/erd/canvas/shared-drag-select/SharedDragSelect.d.ts +8 -0
- package/dist/components/erd/canvas/shared-mouse-tracker/SharedMouseTracker.d.ts +1 -0
- package/dist/components/erd/canvas/shared-mouse-tracker/shared-mouse-cursor/SharedMouseCursor.d.ts +5 -0
- package/dist/components/erd/canvas/table/Table.d.ts +8 -0
- package/dist/components/erd/canvas/table/cellLayout.d.ts +63 -0
- package/dist/components/erd/canvas/table/column/Column.d.ts +23 -6
- package/dist/components/erd/canvas/table/doubleClick.d.ts +14 -0
- package/dist/components/erd/canvas/table/useMoveTable.d.ts +1 -1
- package/dist/components/erd/canvas/table/useSharedFocusTable.d.ts +6 -0
- package/dist/components/erd/canvas/useMoveEntity.d.ts +18 -0
- package/dist/components/erd/canvas/useSharedSelectEntity.d.ts +4 -0
- package/dist/components/erd/erd-context-menu/ErdContextMenu.d.ts +1 -2
- package/dist/components/erd/erd-context-menu/menus/drawRelationshipMenus.d.ts +3 -2
- package/dist/components/erd/erd-context-menu/menus/exportMenus.d.ts +7 -6
- package/dist/components/erd/erd-context-menu/menus/importMenus.d.ts +6 -6
- package/dist/components/erd/erd-context-menu/menus/relationshipMenus.d.ts +1 -1
- package/dist/components/erd/hide-sign/hideSignBounds.d.ts +9 -0
- package/dist/components/erd/hitTest.d.ts +22 -0
- package/dist/components/erd/minimap/Minimap.styles.d.ts +0 -1
- package/dist/components/erd/minimap/MinimapScene.d.ts +16 -0
- package/dist/components/erd/minimap/memo/Memo.d.ts +5 -0
- package/dist/components/erd/minimap/minimapGeometry.d.ts +52 -0
- package/dist/components/erd/minimap/table/Table.d.ts +5 -0
- package/dist/components/erd/table-properties/table-properties-indexes/indexes-checkbox-column/IndexesCheckboxColumn.d.ts +1 -1
- package/dist/components/erd/virtual-scroll/useVirtualScroll.d.ts +19 -0
- package/dist/components/erd-editor/ErdEditor.d.ts +4 -0
- package/dist/components/erd-editor/ErdEditor.stories.d.ts +1 -1
- package/dist/components/global-styles/GlobalStyles.d.ts +5 -0
- package/dist/components/primitives/button/Button.stories.d.ts +4 -4
- package/dist/components/primitives/code-block/CodeBlock.stories.d.ts +4 -4
- package/dist/components/primitives/code-block/CodeBlock.styles.d.ts +6 -1
- package/dist/components/primitives/color-picker/ColorPicker.d.ts +1 -1
- package/dist/components/primitives/color-picker/ColorPicker.stories.d.ts +1 -1
- package/dist/components/primitives/context-menu/ContextMenu.stories.d.ts +1 -1
- package/dist/components/primitives/context-menu/context-menu-item/ContextMenuItem.d.ts +1 -1
- package/dist/components/primitives/context-menu/menu/Menu.d.ts +2 -2
- package/dist/components/primitives/edit-input/EditInput.d.ts +2 -2
- package/dist/components/primitives/edit-input/EditInput.stories.d.ts +6 -6
- package/dist/components/primitives/highlighted-text/HighlightedText.stories.d.ts +1 -1
- package/dist/components/primitives/icon/Icon.d.ts +2 -3
- package/dist/components/primitives/icon/Icon.stories.d.ts +3 -1
- package/dist/components/primitives/icon/icons.d.ts +95 -26
- package/dist/components/primitives/kbd/Kbd.stories.d.ts +3 -3
- package/dist/components/primitives/sash/Sash.stories.d.ts +6 -6
- package/dist/components/primitives/separator/Separator.stories.d.ts +3 -3
- package/dist/components/primitives/slider/Slider.stories.d.ts +4 -4
- package/dist/components/primitives/switch/Switch.stories.d.ts +3 -3
- package/dist/components/primitives/text-input/TextInput.d.ts +1 -1
- package/dist/components/primitives/text-input/TextInput.stories.d.ts +7 -7
- package/dist/components/primitives/toast/Toast.d.ts +4 -0
- package/dist/components/primitives/toast/Toast.stories.d.ts +17 -4
- package/dist/components/primitives/toast/Toast.styles.d.ts +5 -0
- package/dist/components/{erd/canvas/table → table-view}/column/column-data-type/ColumnDataType.d.ts +4 -4
- package/dist/components/{erd/canvas/table → table-view}/column/column-not-null/ColumnNotNull.d.ts +1 -1
- package/dist/components/{erd/canvas/table → table-view}/column/column-option/ColumnOption.d.ts +1 -1
- package/dist/components/table-view/column/useColumnCell.d.ts +23 -0
- package/dist/components/themeContext.d.ts +9 -0
- package/dist/components/toast-container/openToastWhileRunning.d.ts +11 -0
- package/dist/components/visualization/Visualization.d.ts +6 -0
- package/dist/components/visualization/Visualization.styles.d.ts +6 -0
- package/dist/components/visualization/VisualizationScene.d.ts +21 -0
- package/dist/components/visualization/createVisualization.d.ts +67 -8
- package/dist/components/visualization/graph-node/GraphNode.d.ts +23 -0
- package/dist/components/visualization/table/Table.d.ts +0 -1
- package/dist/components/visualization/table/column/Column.d.ts +0 -1
- package/dist/components/visualization/visualizationView.d.ts +90 -0
- package/dist/constants/language.d.ts +7 -1
- package/dist/constants/layout.d.ts +13 -0
- package/dist/constants/schema.d.ts +12 -3
- package/dist/constants/sql/dataType/Databricks.d.ts +5 -0
- package/dist/constants/sql/dataType/MSSQL.d.ts +1 -1
- package/dist/constants/sql/dataType/MySQL.d.ts +1 -1
- package/dist/constants/sql/dataType/Oracle.d.ts +1 -1
- package/dist/constants/sql/dataType/Snowflake.d.ts +5 -0
- package/dist/constants/sql/database.d.ts +2 -0
- package/dist/engine/history.d.ts +5 -3
- package/dist/engine/hooks.d.ts +3 -3
- package/dist/engine/modules/editor/actions.d.ts +30 -1
- package/dist/engine/modules/editor/atom.actions.d.ts +131 -0
- package/dist/engine/modules/editor/generator.actions.d.ts +18 -0
- package/dist/engine/modules/editor/state.d.ts +43 -0
- package/dist/engine/modules/editor/utils/duplicate.d.ts +13 -0
- package/dist/engine/modules/memo/actions.d.ts +3 -0
- package/dist/engine/modules/memo/atom.actions.d.ts +12 -0
- package/dist/engine/modules/settings/atom.actions.d.ts +24 -0
- package/dist/engine/modules/table/actions.d.ts +1 -0
- package/dist/engine/modules/table/atom.actions.d.ts +4 -0
- package/dist/engine.js +40 -51
- package/dist/erd-editor.js +40775 -26895
- package/dist/konva/batchDraw.d.ts +41 -0
- package/dist/konva/host.d.ts +29 -0
- package/dist/konva/scene/columnDropTarget.d.ts +13 -0
- package/dist/konva/scene/konvaFlip.d.ts +18 -0
- package/dist/konva/scene/metrics.d.ts +29 -0
- package/dist/konva/scene/renderScene.d.ts +34 -0
- package/dist/konva/scene/viewport.d.ts +38 -0
- package/dist/konva/testHandle.d.ts +22 -0
- package/dist/konva/theme.d.ts +31 -0
- package/dist/konva/workerDomStubs.d.ts +1 -0
- package/dist/schemaGCService-DrlqIen8.js +17549 -0
- package/dist/services/export-png/ExportScene.d.ts +9 -0
- package/dist/services/export-png/documentScene.d.ts +20 -0
- package/dist/services/export-png/exportPng.shared-worker.d.ts +0 -0
- package/dist/services/export-png/exportPngService.d.ts +24 -0
- package/dist/services/export-png/index.d.ts +48 -0
- package/dist/services/export-png/pixelRatio.d.ts +21 -0
- package/dist/services/export-png/renderPng.d.ts +37 -0
- package/dist/services/export-png/textWidth.d.ts +27 -0
- package/dist/services/schema-gc/index.d.ts +5 -0
- package/dist/services/shikiService.d.ts +1 -1
- package/dist/styles/colorPicker.style.d.ts +6 -1
- package/dist/styles/fonts.styles.d.ts +2 -1
- package/dist/styles/reset.styles.d.ts +5 -1
- package/dist/styles/scrollbar.styles.d.ts +6 -1
- package/dist/styles/typography.styles.d.ts +2 -1
- package/dist/themes/radix-ui-theme.d.ts +1 -1
- package/dist/themes/tokens.d.ts +6 -2
- package/dist/utils/calcTable.d.ts +7 -0
- package/dist/utils/draw-relationship/chamfer.d.ts +2 -0
- package/dist/utils/draw-relationship/incremental.d.ts +70 -0
- package/dist/utils/draw-relationship/index.d.ts +78 -14
- package/dist/utils/draw-relationship/nudge.d.ts +4 -0
- package/dist/utils/draw-relationship/pathFinding.d.ts +7 -1
- package/dist/utils/draw-relationship/route.d.ts +27 -0
- package/dist/utils/draw-relationship/stub.d.ts +36 -0
- package/dist/utils/emitter.d.ts +32 -0
- package/dist/utils/file/exportFile.d.ts +10 -1
- package/dist/utils/file/importFile.d.ts +4 -1
- package/dist/utils/focus.d.ts +5 -3
- package/dist/utils/generator-code/aml.d.ts +4 -0
- package/dist/utils/generator-code/dbml.d.ts +4 -0
- package/dist/utils/generator-code/drizzle.d.ts +4 -0
- package/dist/utils/generator-code/go.d.ts +4 -0
- package/dist/utils/generator-code/sequelize.d.ts +4 -0
- package/dist/utils/generator-code/sqlalchemy.d.ts +4 -0
- package/dist/utils/generator-code/typeorm.d.ts +4 -0
- package/dist/utils/globalEventObservable.d.ts +13 -12
- package/dist/utils/icon.d.ts +9 -1
- package/dist/utils/keyboard-shortcut/index.d.ts +7 -1
- package/dist/utils/promise.d.ts +1 -0
- package/dist/utils/schema-aml-parser/convert.d.ts +4 -0
- package/dist/utils/schema-aml-parser/dataType.d.ts +12 -0
- package/dist/utils/schema-aml-parser/index.d.ts +3 -0
- package/dist/utils/schema-aml-parser/parser.d.ts +2 -0
- package/dist/utils/schema-aml-parser/tokenizer.d.ts +23 -0
- package/dist/utils/schema-aml-parser/types.d.ts +78 -0
- package/dist/utils/schema-dbml-parser/convert.d.ts +4 -0
- package/dist/utils/schema-dbml-parser/dataType.d.ts +7 -0
- package/dist/utils/schema-dbml-parser/index.d.ts +3 -0
- package/dist/utils/schema-dbml-parser/parser.d.ts +2 -0
- package/dist/utils/schema-dbml-parser/tokenizer.d.ts +16 -0
- package/dist/utils/schema-dbml-parser/types.d.ts +62 -0
- package/dist/utils/schema-graphql-parser/convert.d.ts +4 -0
- package/dist/utils/schema-graphql-parser/dataType.d.ts +7 -0
- package/dist/utils/schema-graphql-parser/index.d.ts +3 -0
- package/dist/utils/schema-graphql-parser/parser.d.ts +2 -0
- package/dist/utils/schema-graphql-parser/types.d.ts +58 -0
- package/dist/utils/schema-sql/Databricks.d.ts +5 -0
- package/dist/utils/schema-sql/Snowflake.d.ts +5 -0
- package/dist/utils/sharedColor.d.ts +2 -0
- package/dist/utils/table-clipboard/copy.d.ts +7 -0
- package/dist/utils/table-clipboard/index.d.ts +2 -0
- package/dist/utils/table-clipboard/paste.d.ts +3 -0
- package/dist/utils/table-clipboard/payload.d.ts +83 -0
- package/dist/utils/table-clipboard/placement.d.ts +30 -0
- package/dist/utils/validation.d.ts +1 -0
- package/package.json +34 -29
- package/dist/components/erd/canvas/canvas-svg/CanvasSvg.d.ts +0 -7
- package/dist/components/erd/canvas/canvas-svg/relationship/Relationship.template.d.ts +0 -3
- package/dist/components/erd/canvas/draw-relationship/DrawRelationship.styles.d.ts +0 -1
- package/dist/components/erd/canvas/high-level-table/HighLevelTable.styles.d.ts +0 -1
- package/dist/components/erd/canvas/memo/Memo.styles.d.ts +0 -6
- package/dist/components/erd/canvas/shared-mouse-tracker/shared-mouse-cursor/SharedMouseCursor.styles.d.ts +0 -1
- package/dist/components/erd/canvas/table/column/Column.styles.d.ts +0 -2
- package/dist/components/erd/drag-select/DragSelect.d.ts +0 -9
- package/dist/components/erd/drag-select/DragSelect.styles.d.ts +0 -1
- package/dist/schemaGCService-Br6jn6B2.js +0 -15866
- /package/dist/components/erd/canvas/{canvas-svg → relationship-group}/relationship/Relationship.d.ts +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/Table.styles.d.ts +0 -0
- /package/dist/components/{erd/canvas/canvas-svg/CanvasSvg.styles.d.ts → table-view/column/Column.styles.d.ts} +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/column/column-data-type/ColumnDataType.styles.d.ts +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/column/column-key/ColumnKey.d.ts +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/column/column-key/ColumnKey.styles.d.ts +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/column/column-not-null/ColumnNotNull.styles.d.ts +0 -0
- /package/dist/components/{erd/canvas/table → table-view}/column/column-option/ColumnOption.styles.d.ts +0 -0
- /package/dist/{services/schema-gc/schemaGC.worker.d.ts → konva/jsx-types.test-d.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
-
# erd-editor
|
|
1
|
+
# @dineug/erd-editor
|
|
2
2
|
|
|
3
|
-
> Entity-Relationship Diagram Editor
|
|
3
|
+
> Entity-Relationship Diagram Editor as a custom element
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
7
|
+
`<erd-editor>` is a full database-schema editor in a single custom element. It has no
|
|
8
|
+
framework dependency and renders into a closed shadow root, so it drops into any page —
|
|
9
|
+
React, Vue, Svelte, or plain HTML — without leaking styles either way.
|
|
10
|
+
|
|
11
|
+
This is the same editor that powers [erd-editor.io](https://erd-editor.io), the
|
|
12
|
+
[VS Code extension](https://marketplace.visualstudio.com/items?itemName=dineug.vuerd-vscode)
|
|
13
|
+
and the [IntelliJ plugin](https://plugins.jetbrains.com/plugin/23594-erd-editor).
|
|
14
|
+
|
|
15
|
+
## Features
|
|
16
|
+
|
|
17
|
+
- Visual schema design — tables, columns, memos, and four relationship cardinalities
|
|
18
|
+
(zero-one, zero-N, one-only, one-N)
|
|
19
|
+
- Import — a `.sql` dump, a GraphQL SDL schema from any tool that emits one, a `.dbml` file, or
|
|
20
|
+
an `.aml` file
|
|
21
|
+
- SQL DDL export — Databricks, MariaDB, MSSQL, MySQL, Oracle, PostgreSQL, Snowflake and SQLite
|
|
22
|
+
- Code generation — TypeScript, GraphQL, C#, Java, JPA, Kotlin, Scala, Go,
|
|
23
|
+
SQLAlchemy, TypeORM, Sequelize, Drizzle, DBML, AML
|
|
24
|
+
- Export — `.erd.json`, `.sql`, `.png`
|
|
25
|
+
- Force-directed visualization of table relationships
|
|
26
|
+
- Quick search, undo / redo, remappable keyboard shortcuts, and a built-in theme builder
|
|
27
|
+
- Collaboration hooks — the editor emits and applies actions; you supply the transport
|
|
28
|
+
|
|
7
29
|
## Install
|
|
8
30
|
|
|
9
31
|
```sh
|
|
@@ -16,37 +38,195 @@ npm install @dineug/erd-editor
|
|
|
16
38
|
import '@dineug/erd-editor';
|
|
17
39
|
|
|
18
40
|
const editor = document.createElement('erd-editor');
|
|
41
|
+
// the editor fills its container, and a custom element is inline by default
|
|
42
|
+
Object.assign(editor.style, { display: 'block', width: '100%', height: '100vh' });
|
|
19
43
|
document.body.appendChild(editor);
|
|
44
|
+
|
|
45
|
+
// load a document without adding an undo entry, then keep it in sync
|
|
46
|
+
editor.setInitialValue(localStorage.getItem('my-diagram') ?? '');
|
|
47
|
+
editor.addEventListener('change', () => {
|
|
48
|
+
localStorage.setItem('my-diagram', editor.value);
|
|
49
|
+
});
|
|
20
50
|
```
|
|
21
51
|
|
|
22
|
-
|
|
52
|
+
`setInitialValue('')` starts an empty document.
|
|
53
|
+
|
|
54
|
+
### Server-side rendering
|
|
55
|
+
|
|
56
|
+
Importing the package registers the custom element at module scope, so it needs a DOM and
|
|
57
|
+
throws in Node. In Next.js, Nuxt, SvelteKit or Astro, reach it from a client-only path:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
import('@dineug/erd-editor');
|
|
62
|
+
}, []);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### HTML
|
|
23
66
|
|
|
24
67
|
```html
|
|
68
|
+
<erd-editor system-dark-mode enable-theme-builder></erd-editor>
|
|
25
69
|
<script type="module">
|
|
26
|
-
import '
|
|
70
|
+
import '@dineug/erd-editor';
|
|
27
71
|
|
|
28
|
-
const editor = document.
|
|
29
|
-
document.body.appendChild(editor);
|
|
72
|
+
const editor = document.querySelector('erd-editor');
|
|
30
73
|
</script>
|
|
31
|
-
<!-- or -->
|
|
32
|
-
<script type="module" src="https://esm.run/@dineug/erd-editor"></script>
|
|
33
74
|
```
|
|
34
75
|
|
|
35
|
-
|
|
76
|
+
```css
|
|
77
|
+
erd-editor {
|
|
78
|
+
display: block;
|
|
79
|
+
width: 100%;
|
|
80
|
+
height: 100vh;
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### CDN
|
|
36
85
|
|
|
37
86
|
```html
|
|
38
|
-
<erd-editor
|
|
87
|
+
<erd-editor style="display: block; width: 100%; height: 100vh"></erd-editor>
|
|
39
88
|
<script type="module">
|
|
40
89
|
import 'https://esm.run/@dineug/erd-editor';
|
|
41
|
-
|
|
42
|
-
const editor = document.querySelector('erd-editor');
|
|
43
90
|
</script>
|
|
44
91
|
```
|
|
45
92
|
|
|
46
|
-
##
|
|
93
|
+
## API
|
|
94
|
+
|
|
95
|
+
### Attributes
|
|
96
|
+
|
|
97
|
+
| Attribute | Property | Description |
|
|
98
|
+
| --- | --- | --- |
|
|
99
|
+
| `readonly` | `readonly` | Blocks editing and suppresses the `change` event. Assigning `value`, `setSchemaSQL()`, `setSchemaGraphQL()`, `setSchemaDBML()`, `setSchemaAML()` and `clear()` are ignored while it is set — load with `setInitialValue()` instead. Viewport actions and the SQL/code output settings still apply. |
|
|
100
|
+
| `system-dark-mode` | `systemDarkMode` | Follows the OS color scheme |
|
|
101
|
+
| `enable-theme-builder` | `enableThemeBuilder` | Shows the built-in theme builder |
|
|
102
|
+
|
|
103
|
+
### Properties
|
|
104
|
+
|
|
105
|
+
| Property | Description |
|
|
106
|
+
| --- | --- |
|
|
107
|
+
| `value: string` | The document as JSON — an `.erd.json` document ([schema](https://github.com/dineug/erd-editor/blob/main/json-schema/schema.json)). Assigning it loads the document as an edit, so it lands in the undo history; use `setInitialValue` to load without one. |
|
|
108
|
+
|
|
109
|
+
### Methods
|
|
110
|
+
|
|
111
|
+
| Method | Description |
|
|
112
|
+
| --- | --- |
|
|
113
|
+
| `setInitialValue(value: string)` | Load the initial document. Does not create a history entry. |
|
|
114
|
+
| `getSchemaSQL(vendor?)` | Export DDL. `vendor` is one of `Databricks`, `MariaDB`, `MSSQL`, `MySQL`, `Oracle`, `PostgreSQL`, `Snowflake`, `SQLite`; omit it to use the document's own setting. |
|
|
115
|
+
| `setSchemaSQL(value: string)` | Parse a DDL string and **replace** the current document with it. Lands in the undo history; an empty string is ignored. |
|
|
116
|
+
| `setSchemaGraphQL(value: string)` | Parse a GraphQL SDL string and **replace** the current document with it. Object types become tables, scalars map to the document's own dialect, and relationships are read from the fields that point at another type. Lands in the undo history; an empty string is ignored. |
|
|
117
|
+
| `setSchemaDBML(value: string)` | Parse a DBML string and **replace** the current document with it. Tables, columns, indexes and every `Ref` spelling are read; a `Project`, `TableGroup` or sticky `Note` is skipped, and text it cannot read loads an empty document rather than being refused. Lands in the undo history; an empty string is ignored. |
|
|
118
|
+
| `setSchemaAML(value: string)` | Parse an [AML](https://azimutt.app) string and **replace** the current document with it. Entities, attributes, indexes and every relation arrow are read, in the v2 and the legacy v1 spelling; a check, a struct type and a view are skipped, and text it cannot read loads an empty document rather than being refused. Lands in the undo history; an empty string is ignored. |
|
|
119
|
+
| `setDiffValue(value: string)` | Open the diff viewer against another document. |
|
|
120
|
+
| `setPresetTheme(options)` | Set `appearance`, `grayColor` and `accentColor`. |
|
|
121
|
+
| `setTheme(theme)` | Override individual theme tokens. |
|
|
122
|
+
| `setKeyBindingMap(map)` | Remap shortcuts. `edit`, `stop`, `search`, `undo`, `redo`, `zoomIn` and `zoomOut` are reserved. |
|
|
123
|
+
| `getSharedStore(config?)` | Returns `{ subscribe, dispatch, dispatchSync, connection, disconnect, destroy }`. `subscribe` gives you this editor's actions to relay; `dispatch` applies a peer's. You supply the transport. `config` is `{ getNickname?, mouseTracker?, focusTracker? }`; both trackers default to `true` and broadcast this editor's cursor and table focus to peers. |
|
|
124
|
+
| `focus()` / `blur()` | Move focus in and out of the editor. |
|
|
125
|
+
| `clear()` | Empty the document. |
|
|
126
|
+
| `destroy()` | Tear the editor down and release its listeners, subscriptions and shared stores. |
|
|
127
|
+
|
|
128
|
+
### Events
|
|
129
|
+
|
|
130
|
+
| Event | Description |
|
|
131
|
+
| --- | --- |
|
|
132
|
+
| `change` | The document changed. Debounced, and never fired while `readonly`. Read `editor.value`. |
|
|
133
|
+
| `changePresetTheme` | The theme was changed from inside the editor. `event.detail` carries the new options. |
|
|
134
|
+
|
|
135
|
+
## Syntax highlighting
|
|
136
|
+
|
|
137
|
+
The SQL and code-generation panels render as plain text unless a highlighter is supplied.
|
|
138
|
+
[`@dineug/erd-editor-shiki-worker`](https://www.npmjs.com/package/@dineug/erd-editor-shiki-worker)
|
|
139
|
+
runs one in a shared worker. It is a separate install:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
npm install @dineug/erd-editor-shiki-worker
|
|
143
|
+
```
|
|
47
144
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
145
|
+
```js
|
|
146
|
+
import { setGetShikiServiceCallback } from '@dineug/erd-editor';
|
|
147
|
+
|
|
148
|
+
// deferred, so the highlighter never lands in your main chunk
|
|
149
|
+
import('@dineug/erd-editor-shiki-worker').then(({ getShikiService }) => {
|
|
150
|
+
setGetShikiServiceCallback(getShikiService);
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## File dialogs
|
|
155
|
+
|
|
156
|
+
Import and export go through injectable callbacks, so a host without a browser file dialog —
|
|
157
|
+
an IDE webview, for example — can supply its own. The two are not symmetric: export hands you
|
|
158
|
+
the finished file, while import only asks for one, and you push the content back in yourself.
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
import { setExportFileCallback, setImportFileCallback } from '@dineug/erd-editor';
|
|
162
|
+
|
|
163
|
+
setExportFileCallback((blob, { fileName }) => host.writeFile(fileName, blob));
|
|
164
|
+
|
|
165
|
+
setImportFileCallback(async ({ type, op, accept }) => {
|
|
166
|
+
const text = await host.pickFile(accept);
|
|
167
|
+
|
|
168
|
+
if (op === 'diff') {
|
|
169
|
+
editor.setDiffValue(text);
|
|
170
|
+
} else if (type === 'json') {
|
|
171
|
+
editor.value = text;
|
|
172
|
+
} else if (type === 'sql') {
|
|
173
|
+
editor.setSchemaSQL(text);
|
|
174
|
+
} else if (type === 'graphql') {
|
|
175
|
+
editor.setSchemaGraphQL(text);
|
|
176
|
+
} else if (type === 'dbml') {
|
|
177
|
+
editor.setSchemaDBML(text);
|
|
178
|
+
} else if (type === 'aml') {
|
|
179
|
+
editor.setSchemaAML(text);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Dispatch on every `type` you handle and ignore the rest. Assigning `value` clears the
|
|
185
|
+
document before it parses, so routing a payload there that is not an `.erd.json` document —
|
|
186
|
+
through a catch-all `else`, or because a `type` added later fell through — empties the
|
|
187
|
+
diagram instead of importing anything. `accept` carries the extensions for that type
|
|
188
|
+
(`.json`, `.sql`, or `.graphql,.gql,.graphqls`), ready to hand to a host file dialog.
|
|
189
|
+
|
|
190
|
+
Left unset, the editor uses the browser's own download and file-picker behavior.
|
|
191
|
+
|
|
192
|
+
## Headless replica
|
|
193
|
+
|
|
194
|
+
A second entry point runs the document store with no DOM, for hosts that need to apply an
|
|
195
|
+
action stream and serialize the result off the main thread:
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
import { createReplicationStore } from '@dineug/erd-editor/engine.js';
|
|
199
|
+
|
|
200
|
+
// `toWidth` measures text for layout — a worker has no DOM, so you supply it
|
|
201
|
+
const store = createReplicationStore({ toWidth });
|
|
202
|
+
|
|
203
|
+
store.setInitialValue(savedJson);
|
|
204
|
+
store.on({ change: () => persist(store.value) });
|
|
205
|
+
store.dispatch(actions); // actions relayed from a live editor's shared store
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Development
|
|
209
|
+
|
|
210
|
+
This package is the editor core of the [erd-editor monorepo](https://github.com/dineug/erd-editor);
|
|
211
|
+
work on it from a workspace checkout.
|
|
212
|
+
|
|
213
|
+
```sh
|
|
214
|
+
pnpm --filter @dineug/erd-editor dev # builds workspace deps, then a dev server
|
|
215
|
+
pnpm --filter @dineug/erd-editor dev:storybook # component playground
|
|
216
|
+
pnpm exec vp run --filter @dineug/erd-editor --fail-if-no-match test
|
|
217
|
+
pnpm --filter @dineug/erd-editor e2e # Playwright
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Documentation
|
|
221
|
+
|
|
222
|
+
- [Documentation](https://docs.erd-editor.io)
|
|
51
223
|
- [Editing Guide](https://docs.erd-editor.io/docs/category/guides)
|
|
52
|
-
- [API](https://docs.erd-editor.io/docs/api/erd-editor-element)
|
|
224
|
+
- [Element API](https://docs.erd-editor.io/docs/api/erd-editor-element)
|
|
225
|
+
|
|
226
|
+
## Issues
|
|
227
|
+
|
|
228
|
+
Found a bug or want a feature? [Open an issue](https://github.com/dineug/erd-editor/issues).
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
[MIT](https://github.com/dineug/erd-editor/blob/main/LICENSE) © SeungHwan-Lee
|
|
@@ -17,7 +17,14 @@ export type AppContext = EngineContext & {
|
|
|
17
17
|
emitter: Emitter;
|
|
18
18
|
};
|
|
19
19
|
export type InjectAppContext = InjectEngineContext;
|
|
20
|
-
export
|
|
20
|
+
export type AppContextOptions = RxStoreOptions & {
|
|
21
|
+
/**
|
|
22
|
+
* Whether a dev build connects the store to the redux devtools extension. Off
|
|
23
|
+
* for a store built where there is no window to look the extension up on.
|
|
24
|
+
*/
|
|
25
|
+
devtools?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export declare function createAppContext(ctx: InjectAppContext, options?: AppContextOptions): AppContext;
|
|
21
28
|
export declare const appContext: import('@dineug/r-html').Context<AppContext>;
|
|
22
29
|
export declare const useAppContext: (ctx: Ctx, fallback?: AppContext) => import('@dineug/r-html').Ref<AppContext>;
|
|
23
30
|
export declare function appDestroy(app: AppContext): void;
|
|
@@ -7,5 +7,21 @@ type Node = {
|
|
|
7
7
|
y: number;
|
|
8
8
|
ref: Table;
|
|
9
9
|
};
|
|
10
|
-
|
|
10
|
+
/** The two readings of a simulation's heat that its progress is taken from. */
|
|
11
|
+
type Cooling = {
|
|
12
|
+
alpha(): number;
|
|
13
|
+
alphaMin(): number;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* How far a placement has run, from 0 to 1. The simulation cools by a fixed
|
|
17
|
+
* factor a tick until its heat reaches the floor it stops at, so the log of
|
|
18
|
+
* the heat over the log of that floor is the share of the ticks it will take.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* simulation.on('tick.progress', () => {
|
|
22
|
+
* state.progress = placementProgress(simulation);
|
|
23
|
+
* });
|
|
24
|
+
*/
|
|
25
|
+
export declare function placementProgress(simulation: Cooling): number;
|
|
26
|
+
export declare function createAutomaticTablePlacement(state: RootState): import('d3-force').Simulation<Node, undefined>;
|
|
11
27
|
export {};
|
|
@@ -4,5 +4,10 @@ export type CanvasProps = {
|
|
|
4
4
|
canvas: Ref<HTMLDivElement>;
|
|
5
5
|
grabMove?: boolean;
|
|
6
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* The dom shell the scene hangs in: a controller box, the Stage container in it
|
|
9
|
+
* and the editing overlay over that. Scroll and zoom moved onto the scene's
|
|
10
|
+
* layers, so the shell is viewport sized rather than schema sized.
|
|
11
|
+
*/
|
|
7
12
|
declare const Canvas: FC<CanvasProps>;
|
|
8
13
|
export default Canvas;
|
|
@@ -1,2 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A document box, painted with the canvas background. The minimap's thumbnail
|
|
3
|
+
* is one of these; the editor's own document box is a konva rect on the scene's
|
|
4
|
+
* bottom layer, because the stage container below is the screen, not the box.
|
|
5
|
+
*/
|
|
1
6
|
export declare const root: import('@dineug/r-html').CSSTemplateLiterals;
|
|
7
|
+
/**
|
|
8
|
+
* The stage container, which is viewport sized. It paints nothing of its own so
|
|
9
|
+
* that the boundary background of whatever holds the editor shows through
|
|
10
|
+
* wherever the scene has drawn no document.
|
|
11
|
+
*/
|
|
12
|
+
export declare const stage: import('@dineug/r-html').CSSTemplateLiterals;
|
|
2
13
|
export declare const controller: import('@dineug/r-html').CSSTemplateLiterals;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FC, Ref } from '@dineug/r-html';
|
|
2
|
+
import { Stage } from 'konva/lib/Stage';
|
|
3
|
+
export type CanvasSceneProps = {
|
|
4
|
+
root: Ref<HTMLDivElement>;
|
|
5
|
+
};
|
|
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.
|
|
10
|
+
*/
|
|
11
|
+
declare const CanvasScene: FC<CanvasSceneProps>;
|
|
12
|
+
/**
|
|
13
|
+
* Renders the scene as the root of a Stage. Named in lower case on purpose:
|
|
14
|
+
* r-html's refresh boundary treats an all-upper-case export list as a component
|
|
15
|
+
* module and would self-accept this one, which kills hmr for the whole scene.
|
|
16
|
+
*/
|
|
17
|
+
export declare function renderCanvasScene(stage: Stage, props: CanvasSceneProps): void;
|
|
18
|
+
export default CanvasScene;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FC } from '@dineug/r-html';
|
|
2
|
+
/**
|
|
3
|
+
* The one editing surface over the Stage. A canvas has no caret, no selection
|
|
4
|
+
* and no IME, so the edited cell hides its konva text and a real input takes
|
|
5
|
+
* its place, under the same zoom the scene layer carries.
|
|
6
|
+
*/
|
|
7
|
+
declare const EditOverlay: FC;
|
|
8
|
+
export default EditOverlay;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A cell editor, laid out on the text the scene drew rather than beside it. The
|
|
3
|
+
* input's own line is centred in the same box konva centred one in, and it
|
|
4
|
+
* paints no underline of its own: the scene's rect keeps running under it.
|
|
5
|
+
*/
|
|
6
|
+
export declare const cell: import('@dineug/r-html').CSSTemplateLiterals;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DOMTemplateLiterals } from '@dineug/r-html';
|
|
2
|
+
import { SceneMouseEvent } from './sceneTokens';
|
|
3
|
+
import { LucideIconName } from '../../primitives/icon/icons';
|
|
4
|
+
export type SceneIconOptions = {
|
|
5
|
+
icon: LucideIconName;
|
|
6
|
+
name: string;
|
|
7
|
+
kind: string;
|
|
8
|
+
size: number;
|
|
9
|
+
color: string;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
click?: (event: SceneMouseEvent) => void;
|
|
13
|
+
mouseenter?: (event: SceneMouseEvent) => void;
|
|
14
|
+
mouseleave?: (event: SceneMouseEvent) => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A lucide icon drawn at size, by scaling its own 24 unit box. The scale carries
|
|
18
|
+
* the stroke with it, which is what keeps the weight the same as the svg the DOM
|
|
19
|
+
* scene rendered at that size.
|
|
20
|
+
*/
|
|
21
|
+
export declare function sceneIcon({ icon, name, kind, size, color, x, y, click, mouseenter, mouseleave, }: SceneIconOptions): DOMTemplateLiterals | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FC, Ref } from '@dineug/r-html';
|
|
2
|
+
export type DragSelectProps = {
|
|
3
|
+
root: Ref<HTMLDivElement>;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* The marquee, drawn in the screen space its own mousemove measures against the
|
|
7
|
+
* erd root. Its home is the overlay layer the canvas leaves untransformed, so
|
|
8
|
+
* these are the numbers the DOM version wrote into left and top.
|
|
9
|
+
*/
|
|
10
|
+
declare const DragSelect: FC<DragSelectProps>;
|
|
11
|
+
export default DragSelect;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FC } from '@dineug/r-html';
|
|
2
|
+
export type DuplicateGhostProps = {};
|
|
3
|
+
/**
|
|
4
|
+
* The Alt-drag copies, drawn on the presence layer above the scene. Ghost
|
|
5
|
+
* geometry is schema coordinates read from table.ui, and the drag delta rides
|
|
6
|
+
* on the group above them, so both halves compose into the committed offset.
|
|
7
|
+
*/
|
|
8
|
+
declare const DuplicateGhost: FC<DuplicateGhostProps>;
|
|
9
|
+
export default DuplicateGhost;
|
|
@@ -2,6 +2,10 @@ import { FC } from '@dineug/r-html';
|
|
|
2
2
|
import { Table } from '../../../../internal-types';
|
|
3
3
|
export type HighLevelTableProps = {
|
|
4
4
|
table: Table;
|
|
5
|
+
/** A drawn copy rather than the table itself, so nothing in it takes an id. */
|
|
6
|
+
preview?: boolean;
|
|
7
|
+
/** Off while the table is kept built but scrolled out of the culling rect. */
|
|
8
|
+
visible?: boolean;
|
|
5
9
|
};
|
|
6
10
|
declare const HighLevelTable: FC<HighLevelTableProps>;
|
|
7
11
|
export default HighLevelTable;
|
|
@@ -2,6 +2,8 @@ import { FC } from '@dineug/r-html';
|
|
|
2
2
|
import { Memo } from '../../../../internal-types';
|
|
3
3
|
export type MemoProps = {
|
|
4
4
|
memo: Memo;
|
|
5
|
+
/** A drawn copy rather than the memo itself, so nothing in it takes an id. */
|
|
6
|
+
preview?: boolean;
|
|
5
7
|
};
|
|
6
8
|
declare const Memo: FC<MemoProps>;
|
|
7
9
|
export default Memo;
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { FC } from '@dineug/r-html';
|
|
2
|
-
import { Memo } from '../../../../../internal-types';
|
|
2
|
+
import { Memo, ValuesType } from '../../../../../internal-types';
|
|
3
3
|
export type MemoSashProps = {
|
|
4
4
|
memo: Memo;
|
|
5
5
|
top: number;
|
|
6
6
|
left: number;
|
|
7
7
|
};
|
|
8
|
+
export declare const MemoSashPosition: {
|
|
9
|
+
readonly left: "left";
|
|
10
|
+
readonly right: "right";
|
|
11
|
+
readonly bottom: "bottom";
|
|
12
|
+
readonly lt: "lt";
|
|
13
|
+
readonly rt: "rt";
|
|
14
|
+
readonly lb: "lb";
|
|
15
|
+
readonly rb: "rb";
|
|
16
|
+
};
|
|
17
|
+
export type MemoSashPosition = ValuesType<typeof MemoSashPosition>;
|
|
8
18
|
declare const MemoSash: FC<MemoSashProps>;
|
|
9
19
|
export default MemoSash;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The offset in a memo's editor value that a point in its drawn body falls on,
|
|
3
|
+
* in the body's own coordinates. Past the last line box a textarea takes the
|
|
4
|
+
* end of the value whatever x is, which is where an author carries on writing.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const offset = memoCaretOffsetAt(memo.value, memo.ui.width, 12, 40);
|
|
8
|
+
*/
|
|
9
|
+
export declare function memoCaretOffsetAt(value: string, width: number, x: number, y: number): number;
|
|
10
|
+
/**
|
|
11
|
+
* Asks the next body editor for this memo to open with its caret here. The
|
|
12
|
+
* editor is a textarea the click itself mounts, so the point the pointer landed
|
|
13
|
+
* on is gone by the time it exists and has to be carried across.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* requestMemoCaret(memo.id, memoCaretOffsetAt(memo.value, width, x, y));
|
|
17
|
+
*/
|
|
18
|
+
export declare function requestMemoCaret(memoId: string, offset: number): void;
|
|
19
|
+
/**
|
|
20
|
+
* The caret asked for, taken once. Anything the pointer did not open, and any
|
|
21
|
+
* request left over from another memo, opens the body at its start instead.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const offset = takeMemoCaret(target.memoId);
|
|
25
|
+
*/
|
|
26
|
+
export declare function takeMemoCaret(memoId: string): number;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Editor } from '../../../../engine/modules/editor/state';
|
|
2
|
+
import { Memo } from '../../../../internal-types';
|
|
3
|
+
/**
|
|
4
|
+
* The furthest a memo body scrolls: what its folded lines overrun the box by,
|
|
5
|
+
* in body px. A body the box holds whole has nowhere to go, which is where a
|
|
6
|
+
* textarea of the same box stops too.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const max = getMemoScrollMax(memo);
|
|
10
|
+
*/
|
|
11
|
+
export declare function getMemoScrollMax(memo: Memo): number;
|
|
12
|
+
/**
|
|
13
|
+
* A scroll pulled into the travel the body allows. The value, the width and
|
|
14
|
+
* the height can all change under a stored scroll, so the clamp runs where the
|
|
15
|
+
* scroll is read rather than where it was written.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* const next = clampMemoScrollTop(memo, scrollTop + event.deltaY);
|
|
19
|
+
*/
|
|
20
|
+
export declare function clampMemoScrollTop(memo: Memo, scrollTop: number): number;
|
|
21
|
+
/**
|
|
22
|
+
* How far down its body the scene shows a memo from. A memo nothing has
|
|
23
|
+
* scrolled starts on its first line, as every memo always did.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* const scrollTop = getMemoScrollTop(store.state.editor, memo);
|
|
27
|
+
*/
|
|
28
|
+
export declare function getMemoScrollTop(editor: Editor, memo: Memo): number;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** The weight utils/text.ts measures with, which is what the body is drawn in. */
|
|
2
|
+
export declare const MEMO_FONT_WEIGHT = "400";
|
|
3
|
+
/** The css font shorthand the scene text and the overlay editor both resolve to. */
|
|
4
|
+
export declare const MEMO_FONT: string;
|
|
5
|
+
/**
|
|
6
|
+
* The leading a memo body takes, in px, which a css line-height and pretext
|
|
7
|
+
* both take. The dom textarea this replaced left it to line-height normal, so
|
|
8
|
+
* that is the advance, and the only way to it is to lay the lines out.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const advance = getMemoLineHeightPx();
|
|
12
|
+
*/
|
|
13
|
+
export declare function getMemoLineHeightPx(): number;
|
|
14
|
+
/** The same leading as konva's multiple of the font size, which is what it takes. */
|
|
15
|
+
export declare function getMemoLineHeight(): number;
|
|
16
|
+
/**
|
|
17
|
+
* The baseline konva draws the first body line on, down from the top of the
|
|
18
|
+
* text node. A canvas has no line box, so the leading and the canvas metrics
|
|
19
|
+
* konva itself measures with are the whole of where that line lands.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const baseline = getMemoTextBaseline();
|
|
23
|
+
*/
|
|
24
|
+
export declare function getMemoTextBaseline(): number;
|
|
25
|
+
/**
|
|
26
|
+
* The lines a memo body folds into at a box width, the way a textarea folds the
|
|
27
|
+
* same text. Konva breaks a string by rules of its own, so the scene draws
|
|
28
|
+
* these lines rather than handing it the value to wrap.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const text = layoutMemoLines(memo.value, memo.ui.width).join('\n');
|
|
32
|
+
*/
|
|
33
|
+
export declare function layoutMemoLines(value: string, width: number): readonly string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FC } from '@dineug/r-html';
|
|
2
|
+
import { Relationship as RelationshipType } from '../../../../internal-types';
|
|
3
|
+
import { CullingRect } from '../../../../konva/scene/viewport';
|
|
4
|
+
export type RelationshipGroupProps = {
|
|
5
|
+
relationships: RelationshipType[];
|
|
6
|
+
viewport?: CullingRect;
|
|
7
|
+
strokeWidth?: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Culling lives here, not in the parent, because a route is a side channel of
|
|
11
|
+
* the sort: a parent that filtered would have to route every connector to learn
|
|
12
|
+
* where it reaches, which is the work this arrangement avoids.
|
|
13
|
+
*/
|
|
14
|
+
declare const RelationshipGroup: FC<RelationshipGroupProps>;
|
|
15
|
+
export default RelationshipGroup;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { DOMTemplateLiterals } from '@dineug/r-html';
|
|
2
|
+
import { Circle, PointToPoint, RelationshipPath } from '../../../../../utils/draw-relationship';
|
|
3
|
+
/**
|
|
4
|
+
* What every decoration node answers a lookup and an ancestor walk with. Konva
|
|
5
|
+
* has no class list, so the one token is both.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DECORATION = "relationship-decoration";
|
|
8
|
+
/** Konva takes one flat pair list where svg took four attributes. */
|
|
9
|
+
export declare const segment: ({ x1, y1, x2, y2 }: PointToPoint) => number[];
|
|
10
|
+
/**
|
|
11
|
+
* One stroke of a cardinality marker. The paint, the width and the two naming
|
|
12
|
+
* attributes are per node in konva, so every marker is drawn through here.
|
|
13
|
+
*/
|
|
14
|
+
export declare function decorationLine(points: PointToPoint, stroke: string): DOMTemplateLiterals;
|
|
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;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Context } from 'konva/lib/Context';
|
|
2
|
+
import { Shape } from 'konva/lib/Shape';
|
|
3
|
+
/** What konva calls to put a shape on the hit canvas, in the shape's own space. */
|
|
4
|
+
export type HitFunc = (context: Context, shape: Shape) => void;
|
|
5
|
+
/**
|
|
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.
|
|
9
|
+
*/
|
|
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;
|
|
13
|
+
/**
|
|
14
|
+
* The whole 24 unit box of a lucide icon, answered by the first shape it draws.
|
|
15
|
+
* A circle's origin is its centre, so its own position is what puts the box
|
|
16
|
+
* back at the icon's corner.
|
|
17
|
+
*/
|
|
18
|
+
export declare const iconHit: HitFunc;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A scene node as an ancestor walk sees it. Konva has no closest, so the routing
|
|
3
|
+
* climbs from the node an event landed on until a kind attr names one of the
|
|
4
|
+
* shapes it knows, which is the rule a class selector gave the dom scene.
|
|
5
|
+
*/
|
|
6
|
+
export type SceneKindNode = {
|
|
7
|
+
getAttr(name: string): any;
|
|
8
|
+
getParent(): SceneKindNode | null;
|
|
9
|
+
};
|
|
10
|
+
/** Whether the node itself or any ancestor of it carries one of the kinds. */
|
|
11
|
+
export declare function hasKindAncestor(node: SceneKindNode | null | undefined, kinds: readonly string[]): boolean;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type RetentionOptions = {
|
|
2
|
+
/** Hidden tables kept per drawn table. */
|
|
3
|
+
perDrawn: number;
|
|
4
|
+
/** The fewest kept however little is drawn. */
|
|
5
|
+
atLeast: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Three hidden per drawn. Building a table costs about twelve milliseconds and
|
|
9
|
+
* a fast pan builds dozens a frame, while konva walks every built node, hidden
|
|
10
|
+
* or not, on each scroll; this is the trade between the two that measured best.
|
|
11
|
+
*/
|
|
12
|
+
export declare const RETAINED_PER_DRAWN = 3;
|
|
13
|
+
/** Kept even where nothing is drawn, so crossing an empty stretch keeps the pool. */
|
|
14
|
+
export declare const RETAINED_AT_LEAST = 16;
|
|
15
|
+
export type RetentionPool = {
|
|
16
|
+
/**
|
|
17
|
+
* The ids to keep built but hidden this render: what left the drawn set most
|
|
18
|
+
* recently, up to the bound, and never a table the document no longer holds.
|
|
19
|
+
*/
|
|
20
|
+
retain(drawnIds: ReadonlySet<string>, presentIds: ReadonlySet<string>): ReadonlySet<string>;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Remembers which tables scrolled off so the scene hides them instead of
|
|
24
|
+
* destroying them, and a scroll back finds them built. Each call is one render:
|
|
25
|
+
* it takes what is drawn now and answers what to keep beside it.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* const retention = createRetentionPool();
|
|
29
|
+
* const retainedIds = retention.retain(drawnIds, new Set(tableIds));
|
|
30
|
+
*/
|
|
31
|
+
export declare function createRetentionPool({ perDrawn, atLeast, }?: Partial<RetentionOptions>): RetentionPool;
|