@miragon/modeler-shell 0.0.0-stage → 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.
Files changed (147) hide show
  1. package/API.md +2869 -0
  2. package/LICENSE +21 -0
  3. package/README.md +566 -2
  4. package/THIRD_PARTY_NOTICES.md +52 -0
  5. package/dist/appearance-BBaM_4bD.d.ts +323 -0
  6. package/dist/appearance-D3FUcbu6.d.cts +53 -0
  7. package/dist/appearance-D3FUcbu6.d.ts +53 -0
  8. package/dist/appearance-XX3JC3pI.d.cts +323 -0
  9. package/dist/chunk-66HCSJNY.js +2792 -0
  10. package/dist/chunk-66HCSJNY.js.map +1 -0
  11. package/dist/chunk-KYDG5DMX.js +136 -0
  12. package/dist/chunk-KYDG5DMX.js.map +1 -0
  13. package/dist/chunk-N4QXFF3A.js +23 -0
  14. package/dist/chunk-N4QXFF3A.js.map +1 -0
  15. package/dist/chunk-OADW3GPA.js +785 -0
  16. package/dist/chunk-OADW3GPA.js.map +1 -0
  17. package/dist/core.cjs +873 -0
  18. package/dist/core.cjs.map +1 -0
  19. package/dist/core.d.cts +246 -0
  20. package/dist/core.d.ts +246 -0
  21. package/dist/core.js +131 -0
  22. package/dist/core.js.map +1 -0
  23. package/dist/diagram-js.cjs +1147 -0
  24. package/dist/diagram-js.cjs.map +1 -0
  25. package/dist/diagram-js.d.cts +170 -0
  26. package/dist/diagram-js.d.ts +170 -0
  27. package/dist/diagram-js.js +879 -0
  28. package/dist/diagram-js.js.map +1 -0
  29. package/dist/index.cjs +3632 -0
  30. package/dist/index.cjs.map +1 -0
  31. package/dist/index.d.cts +29 -0
  32. package/dist/index.d.ts +29 -0
  33. package/dist/index.js +143 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/protocol-DhYBakWL.d.cts +15 -0
  36. package/dist/protocol-IeW8bf4f.d.ts +15 -0
  37. package/dist/shell.css +1603 -0
  38. package/dist/testing-vscode-stub.cjs +332 -0
  39. package/dist/testing-vscode-stub.cjs.map +1 -0
  40. package/dist/testing-vscode-stub.d.cts +65 -0
  41. package/dist/testing-vscode-stub.d.ts +65 -0
  42. package/dist/testing-vscode-stub.js +154 -0
  43. package/dist/testing-vscode-stub.js.map +1 -0
  44. package/dist/testing.cjs +4663 -0
  45. package/dist/testing.cjs.map +1 -0
  46. package/dist/testing.d.cts +231 -0
  47. package/dist/testing.d.ts +231 -0
  48. package/dist/testing.js +4483 -0
  49. package/dist/testing.js.map +1 -0
  50. package/dist/toasts-Bp0REqdq.d.cts +142 -0
  51. package/dist/toasts-Bp0REqdq.d.ts +142 -0
  52. package/dist/types-CnRrINRs.d.cts +445 -0
  53. package/dist/types-PuDZczzy.d.ts +445 -0
  54. package/dist/vscode-extension.cjs +215 -0
  55. package/dist/vscode-extension.cjs.map +1 -0
  56. package/dist/vscode-extension.d.cts +103 -0
  57. package/dist/vscode-extension.d.ts +103 -0
  58. package/dist/vscode-extension.js +24 -0
  59. package/dist/vscode-extension.js.map +1 -0
  60. package/dist/vscode-webview.cjs +3561 -0
  61. package/dist/vscode-webview.cjs.map +1 -0
  62. package/dist/vscode-webview.d.cts +84 -0
  63. package/dist/vscode-webview.d.ts +84 -0
  64. package/dist/vscode-webview.js +259 -0
  65. package/dist/vscode-webview.js.map +1 -0
  66. package/package.json +145 -4
  67. package/src/core/appearance.ts +104 -0
  68. package/src/core/feedback/appearance.ts +141 -0
  69. package/src/core/feedback/problems.ts +23 -0
  70. package/src/core/feedback/toasts.ts +118 -0
  71. package/src/core/fit.ts +220 -0
  72. package/src/core/index.ts +127 -0
  73. package/src/core/keymap.ts +295 -0
  74. package/src/core/layout.ts +69 -0
  75. package/src/core/messages.ts +159 -0
  76. package/src/core/sizes.ts +85 -0
  77. package/src/core/types.ts +106 -0
  78. package/src/core/web-chrome/bottom-row.ts +37 -0
  79. package/src/core/web-chrome/drop.ts +78 -0
  80. package/src/core/web-chrome/top-row.ts +66 -0
  81. package/src/core/zoom.ts +74 -0
  82. package/src/core.ts +2 -0
  83. package/src/diagram-js/connect.ts +75 -0
  84. package/src/diagram-js/index.ts +16 -0
  85. package/src/diagram-js/module.ts +20 -0
  86. package/src/diagram-js/palette-skin.ts +267 -0
  87. package/src/diagram-js/palette.css +269 -0
  88. package/src/diagram-js/service.ts +243 -0
  89. package/src/diagram-js/types.ts +67 -0
  90. package/src/diagram-js/viewport.ts +583 -0
  91. package/src/diagram-js.ts +2 -0
  92. package/src/dom/buttons.css +124 -0
  93. package/src/dom/element.ts +51 -0
  94. package/src/dom/feedback/appearance.ts +184 -0
  95. package/src/dom/feedback/feedback.css +435 -0
  96. package/src/dom/feedback/problems-popover.ts +287 -0
  97. package/src/dom/feedback/toasts.ts +431 -0
  98. package/src/dom/hint.ts +51 -0
  99. package/src/dom/icons.ts +309 -0
  100. package/src/dom/index.ts +42 -0
  101. package/src/dom/inspector.ts +35 -0
  102. package/src/dom/keys.ts +67 -0
  103. package/src/dom/ledger.ts +87 -0
  104. package/src/dom/legend.ts +85 -0
  105. package/src/dom/menu.ts +404 -0
  106. package/src/dom/mount.ts +731 -0
  107. package/src/dom/problems.ts +73 -0
  108. package/src/dom/shell-dom.css +969 -0
  109. package/src/dom/status.ts +72 -0
  110. package/src/dom/tooltip.ts +237 -0
  111. package/src/dom/types.ts +459 -0
  112. package/src/dom/web/drop-zone.ts +181 -0
  113. package/src/dom/web/empty-state.ts +144 -0
  114. package/src/dom/web/legal.ts +75 -0
  115. package/src/dom/web/menu-groups.ts +69 -0
  116. package/src/dom/web/primary.ts +124 -0
  117. package/src/dom/web/web.css +386 -0
  118. package/src/dom/zoom-panel.ts +154 -0
  119. package/src/index.ts +3 -0
  120. package/src/shell.css +9 -0
  121. package/src/testing/case-tools.ts +164 -0
  122. package/src/testing/cases.ts +1077 -0
  123. package/src/testing/checks.ts +868 -0
  124. package/src/testing/facts.ts +641 -0
  125. package/src/testing/geometry.ts +652 -0
  126. package/src/testing/harness.ts +187 -0
  127. package/src/testing/index.ts +19 -0
  128. package/src/testing/page-tools.ts +457 -0
  129. package/src/testing/page.ts +27 -0
  130. package/src/testing/vscode-stub.ts +237 -0
  131. package/src/testing/web-cases.ts +913 -0
  132. package/src/testing/web-checks.ts +1049 -0
  133. package/src/testing/web-facts.ts +713 -0
  134. package/src/testing-vscode-stub.ts +2 -0
  135. package/src/testing.ts +2 -0
  136. package/src/vscode/extension/html.ts +107 -0
  137. package/src/vscode/extension/index.ts +8 -0
  138. package/src/vscode/extension/reveal.ts +9 -0
  139. package/src/vscode/extension/theme-bridge.ts +85 -0
  140. package/src/vscode/extension/types.ts +36 -0
  141. package/src/vscode/protocol.ts +31 -0
  142. package/src/vscode/webview/appearance.ts +141 -0
  143. package/src/vscode/webview/index.ts +8 -0
  144. package/src/vscode/webview/mount.ts +88 -0
  145. package/src/vscode/webview/state.ts +116 -0
  146. package/src/vscode-extension.ts +2 -0
  147. package/src/vscode-webview.ts +2 -0
@@ -0,0 +1,142 @@
1
+ /** A point in pixels or diagram coordinates, as the context says. */
2
+ interface Point {
3
+ x: number;
4
+ y: number;
5
+ }
6
+ interface Size {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ /** A rectangle; content bounds and viewboxes are in diagram coordinates. */
11
+ interface Bounds {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }
17
+ /** A viewbox together with the scale diagram-js shows it at (`canvas.viewbox().scale`). */
18
+ interface ScaledViewbox extends Bounds {
19
+ scale: number;
20
+ }
21
+ /** Distances in pixels from the edges of the modeler's container. */
22
+ interface Insets {
23
+ top: number;
24
+ right: number;
25
+ bottom: number;
26
+ left: number;
27
+ }
28
+ /**
29
+ * The host column of guide §5.2: `ide` is a VS Code webview (later IntelliJ), `web` a Miragon web
30
+ * app that owns its page, `embedded` a modeler inside a foreign page (designIQ, modeler-api hosts).
31
+ */
32
+ type ShellHost = "ide" | "web" | "embedded";
33
+ /**
34
+ * The `data-chrome` names of the chrome (guide §5.2, §13.4). The web column adds `primary`, `legal`,
35
+ * `toasts`, `empty-state`, `drop-zone` and `problems-popover` (0.2); IDE and embedded hosts never
36
+ * show `primary`, `legal`, `empty-state` and `drop-zone`, the IDE host never `toasts` and
37
+ * `problems-popover`.
38
+ */
39
+ type ChromeIsland = "menu" | "palette" | "primary" | "zoom" | "problems" | "legend" | "inspector" | "status" | "legal" | "toasts" | "empty-state" | "drop-zone" | "problems-popover";
40
+ declare const CHROME_ISLANDS: readonly ChromeIsland[];
41
+ /** Where the palette sits: in the top row, or in the second row below it (guide §5.15). */
42
+ type PaletteRow = "top" | "second-row";
43
+ /**
44
+ * What the zoom panel and the chrome keys act on. The diagram-js viewport implements it; the DOM
45
+ * shell only talks to this interface.
46
+ */
47
+ interface ZoomTarget {
48
+ /** The current zoom, 1 = 100 % (diagram-js `canvas.zoom()`, rounded to three decimals). */
49
+ zoom(): number;
50
+ /** One step on the zoom raster around the container centre (diagram-js `zoomScroll.stepZoom`). */
51
+ stepZoom(direction: 1 | -1): void;
52
+ /** 100 % around the container centre. Counts as a user move. */
53
+ zoomToActual(): void;
54
+ /** Explicit fit (button, Shift+1, command): animated unless reduced motion, makes the view automatic. */
55
+ fit(): void;
56
+ /** False while there is nothing to fit (the content bounds are empty). */
57
+ canFit(): boolean;
58
+ /**
59
+ * Calls `listener` after every viewbox change and whenever `canFit()` may have changed, possibly
60
+ * several times per frame. Returns the unsubscribe function.
61
+ */
62
+ onChange(listener: () => void): () => void;
63
+ }
64
+ /** The persisted view (VS Code `setState`): JSON-serializable. */
65
+ interface ViewportState {
66
+ viewbox: Bounds;
67
+ /** The user zoomed or panned since the last fit; a resize no longer refits. */
68
+ userMoved: boolean;
69
+ }
70
+
71
+ /** The statuses of guide §3.3 and §9; each colours bar and dot through `--cd-ui-<status>`. */
72
+ type ToastStatus = "success" | "info" | "warning" | "danger";
73
+ /** A ghost button before Close (guide §8); the toast then never closes by itself. */
74
+ interface ToastAction {
75
+ label: string;
76
+ /** Runs after the toast closed. */
77
+ onSelect(): void;
78
+ }
79
+ interface ToastRequest {
80
+ status: ToastStatus;
81
+ /** What happened and what you can do (guide §2): "Link copied", "Couldn't read this file. …". */
82
+ text: string;
83
+ action?: ToastAction | undefined;
84
+ /** Only to give a long text more time than `TOAST_DURATION_MS`; ignored with an `action`. */
85
+ durationMs?: number | undefined;
86
+ }
87
+ /** At most three toasts at once, the newest at the bottom (guide §8). */
88
+ declare const MAX_TOASTS = 3;
89
+ /**
90
+ * How long a toast stays without hover or focus (guide §8: about 2.8 s, errors about 5 s). A
91
+ * warning asks you to read a sentence and act on it like an error, so it gets the error's 5 s.
92
+ */
93
+ declare const TOAST_DURATION_MS: Readonly<Record<ToastStatus, number>>;
94
+ /** The stack's widest toast: `min(480px, 100cqw − 24px)` (guide §8). */
95
+ declare const TOAST_MAX_WIDTH = 480;
96
+ /**
97
+ * Milliseconds until the toast closes by itself: `undefined` with an `action` (it never closes by
98
+ * itself, guide §8), else `max(TOAST_DURATION_MS[status], durationMs ?? 0)`.
99
+ */
100
+ declare function toastLifetime(request: ToastRequest): number | undefined;
101
+ /** A toast in the stack as the eviction sees it, oldest first. */
102
+ interface ToastSlot {
103
+ id: number;
104
+ hasAction: boolean;
105
+ /** Hovered or holding the focus. */
106
+ engaged: boolean;
107
+ }
108
+ /**
109
+ * Which toast leaves when a fourth arrives (`MAX_TOASTS`): the oldest that is neither engaged nor
110
+ * has an action, else the oldest that is not engaged, else the oldest. `undefined` while the
111
+ * stack has room.
112
+ */
113
+ declare function toastToEvict(stack: readonly ToastSlot[]): number | undefined;
114
+ /** Something in the bottom row the toast stack must clear, relative to the shell root. */
115
+ interface BottomObstacle {
116
+ left: number;
117
+ right: number;
118
+ /** Distance of its top edge from the container's bottom edge. */
119
+ top: number;
120
+ }
121
+ interface ToastStackInput {
122
+ containerWidth: number;
123
+ /** The visible zoom panel, legal line and problems pill (not the legend card). */
124
+ obstacles: readonly BottomObstacle[];
125
+ /**
126
+ * Measured width of the widest toast in the stack. The cards are sized to their text and centred
127
+ * in the stack, so only this column can touch an obstacle; absent = the whole `toastStackWidth`.
128
+ */
129
+ cardWidth?: number | undefined;
130
+ }
131
+ /** `min(TOAST_MAX_WIDTH, containerWidth − 2 · SHELL.edge)`. */
132
+ declare function toastStackWidth(containerWidth: number): number;
133
+ /**
134
+ * The stack's `bottom` in px. Guide §8 anchors it at `bottom: 12px`, centred; where the column of
135
+ * its widest card (`cardWidth`, at most `toastStackWidth`, centred) comes closer than `SHELL.gap`
136
+ * horizontally to an obstacle, the stack stands `SHELL.gap` above the highest such obstacle instead
137
+ * (above the legal line 40, above the zoom panel 60, above a raised zoom panel or the web pill 88).
138
+ * Guide §8 does not settle this collision of a narrow container; it is the shell's rule until it does.
139
+ */
140
+ declare function toastStackBottom(input: ToastStackInput): number;
141
+
142
+ export { type BottomObstacle as B, CHROME_ISLANDS as C, type Insets as I, MAX_TOASTS as M, type PaletteRow as P, type ScaledViewbox as S, TOAST_DURATION_MS as T, type ViewportState as V, type ZoomTarget as Z, type Bounds as a, type ChromeIsland as b, type Point as c, type ShellHost as d, type Size as e, TOAST_MAX_WIDTH as f, type ToastAction as g, type ToastRequest as h, type ToastSlot as i, type ToastStackInput as j, type ToastStatus as k, toastStackBottom as l, toastStackWidth as m, toastToEvict as n, toastLifetime as t };
@@ -0,0 +1,142 @@
1
+ /** A point in pixels or diagram coordinates, as the context says. */
2
+ interface Point {
3
+ x: number;
4
+ y: number;
5
+ }
6
+ interface Size {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ /** A rectangle; content bounds and viewboxes are in diagram coordinates. */
11
+ interface Bounds {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }
17
+ /** A viewbox together with the scale diagram-js shows it at (`canvas.viewbox().scale`). */
18
+ interface ScaledViewbox extends Bounds {
19
+ scale: number;
20
+ }
21
+ /** Distances in pixels from the edges of the modeler's container. */
22
+ interface Insets {
23
+ top: number;
24
+ right: number;
25
+ bottom: number;
26
+ left: number;
27
+ }
28
+ /**
29
+ * The host column of guide §5.2: `ide` is a VS Code webview (later IntelliJ), `web` a Miragon web
30
+ * app that owns its page, `embedded` a modeler inside a foreign page (designIQ, modeler-api hosts).
31
+ */
32
+ type ShellHost = "ide" | "web" | "embedded";
33
+ /**
34
+ * The `data-chrome` names of the chrome (guide §5.2, §13.4). The web column adds `primary`, `legal`,
35
+ * `toasts`, `empty-state`, `drop-zone` and `problems-popover` (0.2); IDE and embedded hosts never
36
+ * show `primary`, `legal`, `empty-state` and `drop-zone`, the IDE host never `toasts` and
37
+ * `problems-popover`.
38
+ */
39
+ type ChromeIsland = "menu" | "palette" | "primary" | "zoom" | "problems" | "legend" | "inspector" | "status" | "legal" | "toasts" | "empty-state" | "drop-zone" | "problems-popover";
40
+ declare const CHROME_ISLANDS: readonly ChromeIsland[];
41
+ /** Where the palette sits: in the top row, or in the second row below it (guide §5.15). */
42
+ type PaletteRow = "top" | "second-row";
43
+ /**
44
+ * What the zoom panel and the chrome keys act on. The diagram-js viewport implements it; the DOM
45
+ * shell only talks to this interface.
46
+ */
47
+ interface ZoomTarget {
48
+ /** The current zoom, 1 = 100 % (diagram-js `canvas.zoom()`, rounded to three decimals). */
49
+ zoom(): number;
50
+ /** One step on the zoom raster around the container centre (diagram-js `zoomScroll.stepZoom`). */
51
+ stepZoom(direction: 1 | -1): void;
52
+ /** 100 % around the container centre. Counts as a user move. */
53
+ zoomToActual(): void;
54
+ /** Explicit fit (button, Shift+1, command): animated unless reduced motion, makes the view automatic. */
55
+ fit(): void;
56
+ /** False while there is nothing to fit (the content bounds are empty). */
57
+ canFit(): boolean;
58
+ /**
59
+ * Calls `listener` after every viewbox change and whenever `canFit()` may have changed, possibly
60
+ * several times per frame. Returns the unsubscribe function.
61
+ */
62
+ onChange(listener: () => void): () => void;
63
+ }
64
+ /** The persisted view (VS Code `setState`): JSON-serializable. */
65
+ interface ViewportState {
66
+ viewbox: Bounds;
67
+ /** The user zoomed or panned since the last fit; a resize no longer refits. */
68
+ userMoved: boolean;
69
+ }
70
+
71
+ /** The statuses of guide §3.3 and §9; each colours bar and dot through `--cd-ui-<status>`. */
72
+ type ToastStatus = "success" | "info" | "warning" | "danger";
73
+ /** A ghost button before Close (guide §8); the toast then never closes by itself. */
74
+ interface ToastAction {
75
+ label: string;
76
+ /** Runs after the toast closed. */
77
+ onSelect(): void;
78
+ }
79
+ interface ToastRequest {
80
+ status: ToastStatus;
81
+ /** What happened and what you can do (guide §2): "Link copied", "Couldn't read this file. …". */
82
+ text: string;
83
+ action?: ToastAction | undefined;
84
+ /** Only to give a long text more time than `TOAST_DURATION_MS`; ignored with an `action`. */
85
+ durationMs?: number | undefined;
86
+ }
87
+ /** At most three toasts at once, the newest at the bottom (guide §8). */
88
+ declare const MAX_TOASTS = 3;
89
+ /**
90
+ * How long a toast stays without hover or focus (guide §8: about 2.8 s, errors about 5 s). A
91
+ * warning asks you to read a sentence and act on it like an error, so it gets the error's 5 s.
92
+ */
93
+ declare const TOAST_DURATION_MS: Readonly<Record<ToastStatus, number>>;
94
+ /** The stack's widest toast: `min(480px, 100cqw − 24px)` (guide §8). */
95
+ declare const TOAST_MAX_WIDTH = 480;
96
+ /**
97
+ * Milliseconds until the toast closes by itself: `undefined` with an `action` (it never closes by
98
+ * itself, guide §8), else `max(TOAST_DURATION_MS[status], durationMs ?? 0)`.
99
+ */
100
+ declare function toastLifetime(request: ToastRequest): number | undefined;
101
+ /** A toast in the stack as the eviction sees it, oldest first. */
102
+ interface ToastSlot {
103
+ id: number;
104
+ hasAction: boolean;
105
+ /** Hovered or holding the focus. */
106
+ engaged: boolean;
107
+ }
108
+ /**
109
+ * Which toast leaves when a fourth arrives (`MAX_TOASTS`): the oldest that is neither engaged nor
110
+ * has an action, else the oldest that is not engaged, else the oldest. `undefined` while the
111
+ * stack has room.
112
+ */
113
+ declare function toastToEvict(stack: readonly ToastSlot[]): number | undefined;
114
+ /** Something in the bottom row the toast stack must clear, relative to the shell root. */
115
+ interface BottomObstacle {
116
+ left: number;
117
+ right: number;
118
+ /** Distance of its top edge from the container's bottom edge. */
119
+ top: number;
120
+ }
121
+ interface ToastStackInput {
122
+ containerWidth: number;
123
+ /** The visible zoom panel, legal line and problems pill (not the legend card). */
124
+ obstacles: readonly BottomObstacle[];
125
+ /**
126
+ * Measured width of the widest toast in the stack. The cards are sized to their text and centred
127
+ * in the stack, so only this column can touch an obstacle; absent = the whole `toastStackWidth`.
128
+ */
129
+ cardWidth?: number | undefined;
130
+ }
131
+ /** `min(TOAST_MAX_WIDTH, containerWidth − 2 · SHELL.edge)`. */
132
+ declare function toastStackWidth(containerWidth: number): number;
133
+ /**
134
+ * The stack's `bottom` in px. Guide §8 anchors it at `bottom: 12px`, centred; where the column of
135
+ * its widest card (`cardWidth`, at most `toastStackWidth`, centred) comes closer than `SHELL.gap`
136
+ * horizontally to an obstacle, the stack stands `SHELL.gap` above the highest such obstacle instead
137
+ * (above the legal line 40, above the zoom panel 60, above a raised zoom panel or the web pill 88).
138
+ * Guide §8 does not settle this collision of a narrow container; it is the shell's rule until it does.
139
+ */
140
+ declare function toastStackBottom(input: ToastStackInput): number;
141
+
142
+ export { type BottomObstacle as B, CHROME_ISLANDS as C, type Insets as I, MAX_TOASTS as M, type PaletteRow as P, type ScaledViewbox as S, TOAST_DURATION_MS as T, type ViewportState as V, type ZoomTarget as Z, type Bounds as a, type ChromeIsland as b, type Point as c, type ShellHost as d, type Size as e, TOAST_MAX_WIDTH as f, type ToastAction as g, type ToastRequest as h, type ToastSlot as i, type ToastStackInput as j, type ToastStatus as k, toastStackBottom as l, toastStackWidth as m, toastToEvict as n, toastLifetime as t };