@lupinum/board-core 1.0.0-beta.4 → 1.0.0-beta.6

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 (26) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +46 -25
  3. package/dist/agent/AGENTS.md +53 -57
  4. package/dist/agent/pages/docs/build-features/connections.md +333 -2
  5. package/dist/agent/pages/docs/build-features/custom-node-renderers.md +366 -2
  6. package/dist/agent/pages/docs/build-features/read-only-and-command-guards.md +278 -2
  7. package/dist/agent/pages/docs/build-features/save-and-load.md +264 -2
  8. package/dist/agent/pages/docs/build-features/selection-and-keyboard.md +257 -2
  9. package/dist/agent/pages/docs/build-features/theming.md +285 -2
  10. package/dist/agent/pages/docs/evaluate/how-nuxt-board-works.md +451 -2
  11. package/dist/agent/pages/docs/project/contributing.md +4 -4
  12. package/dist/agent/pages/docs/project/support-and-security.md +1 -1
  13. package/dist/agent/pages/docs/reference/events-and-errors.md +279 -2
  14. package/dist/agent/pages/docs/reference/package-overview.md +2 -2
  15. package/dist/agent/pages/docs/solutions/mind-map.md +448 -2
  16. package/dist/agent/pages/docs/solutions/nuxt-application.md +214 -2
  17. package/dist/agent/pages/docs/solutions/planning-board.md +281 -2
  18. package/dist/agent/pages/docs/solutions/read-only-viewer.md +278 -2
  19. package/dist/agent/pages/docs/solutions/workflow-builder.md +435 -2
  20. package/dist/agent/pages/docs/start-building/customize-your-first-node.md +381 -2
  21. package/dist/agent/pages/docs/start-building/installation.md +6 -14
  22. package/dist/agent/pages/docs/understand-the-system/commands-and-transactions.md +456 -2
  23. package/dist/agent/pages/docs/understand-the-system/document-and-session-state.md +348 -2
  24. package/dist/agent/pages/docs/understand-the-system/persistence-and-json-canvas.md +445 -2
  25. package/package.json +3 -2
  26. package/dist/agent/manifest.json +0 -320
@@ -15,8 +15,291 @@ source: "ginko-content"
15
15
 
16
16
  Theme the board with CSS variables. Keep semantic state, such as node color presets, in engine state.
17
17
 
18
- > Component omitted: `theme-playground`.
19
- > This page contains an interactive or site-specific block that has no agent markdown serializer yet.
18
+ ## Live example source
19
+
20
+ Use the installation guide to register @lupinum/nuxt-board. These are the actual documentation demo files. Keep their paths under app/. The module auto-imports Board components; install the optional packages named in imports. For the local content components, use components: [{ path: "~/components/content", pathPrefix: false }, "~/components"] in nuxt.config.ts, as this site does, or import them explicitly. createDemoDocument is a local helper, not a package export. DocsLab and the inspector components provide presentation only.
21
+
22
+ ### app/components/demos/ThemePlayground.vue
23
+
24
+ ````vue
25
+ <script setup lang="ts">
26
+ import { computed, onMounted, reactive } from 'vue'
27
+ import { createBoardEngine } from '@lupinum/board-core'
28
+ import { createDemoDocument } from '../../utils/demoDocument'
29
+
30
+ const engine = createBoardEngine({
31
+ grid: { size: 20, majorEvery: 5, snap: true, pattern: 'dot' },
32
+ })
33
+
34
+ const colors = reactive({
35
+ bg: '#f8fafc',
36
+ fg: '#0f172a',
37
+ nodeBg: '#ffffff',
38
+ nodeBorder: '#cbd5e1',
39
+ accent: '#0ea5e9',
40
+ })
41
+
42
+ const boardStyle = computed(() => ({
43
+ '--board-bg': colors.bg,
44
+ '--board-fg': colors.fg,
45
+ '--board-node-bg': colors.nodeBg,
46
+ '--board-node-border': colors.nodeBorder,
47
+ '--board-node-stripe': `${colors.fg}14`,
48
+ '--board-accent': colors.accent,
49
+ '--board-handle-shadow': `${colors.fg}33`,
50
+ }))
51
+
52
+ function seed() {
53
+ engine.loadDocument(
54
+ createDemoDocument({
55
+ camera: { x: 0, y: 0, z: 1 },
56
+ grid: engine.getGridSettings(),
57
+ nodes: [
58
+ {
59
+ id: 'theme-1',
60
+ type: 'text',
61
+ x: 70,
62
+ y: 70,
63
+ width: 240,
64
+ height: 100,
65
+ text: 'Node',
66
+ zIndex: 1,
67
+ locked: false,
68
+ visible: true,
69
+ },
70
+ {
71
+ id: 'theme-2',
72
+ type: 'text',
73
+ x: 370,
74
+ y: 190,
75
+ width: 240,
76
+ height: 100,
77
+ text: 'Node',
78
+ zIndex: 2,
79
+ locked: false,
80
+ visible: true,
81
+ },
82
+ ],
83
+ selection: [],
84
+ nextZIndex: 3,
85
+ }),
86
+ { mode: 'replace' },
87
+ )
88
+ }
89
+
90
+ function resetColors() {
91
+ colors.bg = '#f8fafc'
92
+ colors.fg = '#0f172a'
93
+ colors.nodeBg = '#ffffff'
94
+ colors.nodeBorder = '#cbd5e1'
95
+ colors.accent = '#0ea5e9'
96
+ }
97
+
98
+ async function reset() {
99
+ seed()
100
+ resetColors()
101
+ await engine.zoomToFit(60, false)
102
+ }
103
+
104
+ onMounted(reset)
105
+ </script>
106
+
107
+ <template>
108
+ <div class="demo-frame">
109
+ <div class="demo-toolbar">
110
+ <button class="demo-danger" @click="reset">Reset theme</button>
111
+ <span class="demo-toolbar-note"
112
+ >Change the CSS custom properties and the board updates
113
+ immediately.</span
114
+ >
115
+ </div>
116
+
117
+ <div class="grid gap-0 lg:grid-cols-[320px_minmax(0,1fr)]">
118
+ <div
119
+ class="border-b border-default bg-elevated p-4 lg:border-r lg:border-b-0"
120
+ >
121
+ <div class="space-y-4">
122
+ <label class="demo-color-field">
123
+ <div>
124
+ <span>Board background</span
125
+ ><code class="demo-color-var">--board-bg</code>
126
+ </div>
127
+ <input v-model="colors.bg" type="color" />
128
+ </label>
129
+ <label class="demo-color-field">
130
+ <div>
131
+ <span>Board foreground</span
132
+ ><code class="demo-color-var">--board-fg</code>
133
+ </div>
134
+ <input v-model="colors.fg" type="color" />
135
+ </label>
136
+ <label class="demo-color-field">
137
+ <div>
138
+ <span>Node background</span
139
+ ><code class="demo-color-var">--board-node-bg</code>
140
+ </div>
141
+ <input v-model="colors.nodeBg" type="color" />
142
+ </label>
143
+ <label class="demo-color-field">
144
+ <div>
145
+ <span>Node border</span
146
+ ><code class="demo-color-var">--board-node-border</code>
147
+ </div>
148
+ <input v-model="colors.nodeBorder" type="color" />
149
+ </label>
150
+ <label class="demo-color-field">
151
+ <div>
152
+ <span>Accent</span
153
+ ><code class="demo-color-var">--board-accent</code>
154
+ </div>
155
+ <input v-model="colors.accent" type="color" />
156
+ </label>
157
+ </div>
158
+ </div>
159
+
160
+ <div class="p-4">
161
+ <div
162
+ class="overflow-hidden rounded-md border border-default"
163
+ :style="boardStyle"
164
+ >
165
+ <BoardRoot
166
+ :engine="engine"
167
+ :grid="{ minorOpacity: 0.12, majorOpacity: 0.18, fadeEdges: true }"
168
+ style="height: 360px"
169
+ />
170
+ </div>
171
+ </div>
172
+ </div>
173
+ </div>
174
+ </template>
175
+ ````
176
+
177
+ ### app/utils/demoDocument.ts
178
+
179
+ ````ts
180
+ import type {
181
+ BoardNode,
182
+ BoardNodeMetadata,
183
+ Camera,
184
+ GridSettings,
185
+ JsonCanvasDocument,
186
+ JsonCanvasNode,
187
+ NodeId,
188
+ } from '@lupinum/board-core'
189
+
190
+ type DemoNode = Omit<
191
+ Pick<
192
+ BoardNode,
193
+ | 'id'
194
+ | 'type'
195
+ | 'x'
196
+ | 'y'
197
+ | 'width'
198
+ | 'height'
199
+ | 'color'
200
+ | 'text'
201
+ | 'file'
202
+ | 'subpath'
203
+ | 'url'
204
+ | 'label'
205
+ | 'background'
206
+ | 'backgroundStyle'
207
+ | 'zIndex'
208
+ | 'locked'
209
+ | 'visible'
210
+ | 'parentId'
211
+ >,
212
+ 'id' | 'parentId'
213
+ > & {
214
+ id: NodeId | string
215
+ parentId?: NodeId | string
216
+ }
217
+
218
+ export interface DemoDocumentInput {
219
+ nodes: readonly DemoNode[]
220
+ camera?: Camera
221
+ grid?: GridSettings
222
+ selection?: readonly (NodeId | string)[]
223
+ nextZIndex?: number
224
+ }
225
+
226
+ function toJsonCanvasNode(node: DemoNode): JsonCanvasNode {
227
+ const base = {
228
+ id: node.id as NodeId,
229
+ type: node.type,
230
+ x: node.x,
231
+ y: node.y,
232
+ width: node.width,
233
+ height: node.height,
234
+ ...(node.color ? { color: node.color } : {}),
235
+ }
236
+
237
+ switch (node.type) {
238
+ case 'file':
239
+ return {
240
+ ...base,
241
+ type: 'file',
242
+ file: node.file ?? '',
243
+ ...(node.subpath ? { subpath: node.subpath } : {}),
244
+ }
245
+ case 'link':
246
+ return {
247
+ ...base,
248
+ type: 'link',
249
+ url: node.url ?? '',
250
+ }
251
+ case 'group':
252
+ return {
253
+ ...base,
254
+ type: 'group',
255
+ ...((node.label ?? node.text)
256
+ ? { label: node.label ?? node.text }
257
+ : {}),
258
+ ...(node.background ? { background: node.background } : {}),
259
+ ...(node.backgroundStyle
260
+ ? { backgroundStyle: node.backgroundStyle }
261
+ : {}),
262
+ }
263
+ case 'text':
264
+ default:
265
+ return {
266
+ ...base,
267
+ type: 'text',
268
+ text: node.text ?? '',
269
+ }
270
+ }
271
+ }
272
+
273
+ function toNodeMetadata(node: DemoNode): BoardNodeMetadata {
274
+ return {
275
+ zIndex: node.zIndex,
276
+ locked: node.locked,
277
+ visible: node.visible,
278
+ ...(node.parentId ? { parentId: node.parentId as NodeId } : {}),
279
+ }
280
+ }
281
+
282
+ export function createDemoDocument(
283
+ input: DemoDocumentInput,
284
+ ): JsonCanvasDocument {
285
+ return {
286
+ nodes: input.nodes.map(toJsonCanvasNode),
287
+ 'x-lupinum-board': {
288
+ ...(input.camera ? { camera: input.camera } : {}),
289
+ ...(input.grid ? { grid: input.grid } : {}),
290
+ ...(input.selection
291
+ ? { selection: input.selection.map((id) => id as NodeId) }
292
+ : {}),
293
+ nextZIndex:
294
+ input.nextZIndex ??
295
+ input.nodes.reduce((max, node) => Math.max(max, node.zIndex), 0) + 1,
296
+ nodes: Object.fromEntries(
297
+ input.nodes.map((node) => [node.id, toNodeMetadata(node)]),
298
+ ),
299
+ },
300
+ }
301
+ }
302
+ ````
20
303
 
21
304
  ## Core tokens
22
305