@principal-ai/subsystems-react 0.51.0 → 0.51.1
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/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts +1 -1
- package/dist/pierre/PierreTrailCodeView.d.ts.map +1 -1
- package/dist/pierre/PierreTrailCodeView.js +44 -21
- package/dist/pierre/PierreTrailCodeView.js.map +1 -1
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts +493 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.d.ts.map +1 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js +329 -0
- package/dist/stories/Subsystem/C4Graph/c4ProposedElements.fixture.js.map +1 -0
- package/dist/subsystem/C4Graph.d.ts +2 -2
- package/dist/subsystem/C4Graph.d.ts.map +1 -1
- package/dist/subsystem/C4Graph.js +25 -16
- package/dist/subsystem/C4Graph.js.map +1 -1
- package/dist/subsystem/C4NodeCard.d.ts +71 -36
- package/dist/subsystem/C4NodeCard.d.ts.map +1 -1
- package/dist/subsystem/C4NodeCard.js +88 -94
- package/dist/subsystem/C4NodeCard.js.map +1 -1
- package/dist/subsystem/FileDrawer.d.ts.map +1 -1
- package/dist/subsystem/FileDrawer.js +20 -21
- package/dist/subsystem/FileDrawer.js.map +1 -1
- package/dist/subsystem/IssueList.js +1 -1
- package/dist/subsystem/IssueList.js.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.d.ts.map +1 -1
- package/dist/subsystem/SubsystemComponentGraph.js +13 -4
- package/dist/subsystem/SubsystemComponentGraph.js.map +1 -1
- package/dist/subsystem/c4.d.ts +272 -0
- package/dist/subsystem/c4.d.ts.map +1 -0
- package/dist/subsystem/c4.js +322 -0
- package/dist/subsystem/c4.js.map +1 -0
- package/dist/subsystem/c4Evidence.d.ts +143 -0
- package/dist/subsystem/c4Evidence.d.ts.map +1 -0
- package/dist/subsystem/c4Evidence.js +240 -0
- package/dist/subsystem/c4Evidence.js.map +1 -0
- package/dist/subsystem/model.d.ts +2 -6
- package/dist/subsystem/model.d.ts.map +1 -1
- package/dist/subsystem/model.js.map +1 -1
- package/package.json +4 -3
- package/src/index.ts +26 -28
- package/src/pierre/PierreTrailCodeView.tsx +49 -21
- package/src/stories/Subsystem/C4Graph/C4NodeGallery.stories.tsx +167 -79
- package/src/stories/Subsystem/C4Graph/ProposedElements.stories.tsx +293 -0
- package/src/stories/Subsystem/C4Graph/c4ProposedElements.fixture.ts +366 -0
- package/src/stories/Subsystem/ComponentGraph/IssueOverlay.stories.tsx +1 -1
- package/src/stories/Subsystem/ComponentGraph/Issues.stories.tsx +1 -1
- package/src/subsystem/C4Graph.tsx +39 -24
- package/src/subsystem/C4NodeCard.test.ts +169 -64
- package/src/subsystem/C4NodeCard.tsx +102 -108
- package/src/subsystem/FileDrawer.tsx +32 -34
- package/src/subsystem/IssueList.tsx +1 -1
- package/src/subsystem/SubsystemComponentGraph.tsx +13 -5
- package/src/subsystem/c4.test.ts +573 -0
- package/src/subsystem/c4.ts +558 -0
- package/src/subsystem/c4Evidence.test.ts +386 -0
- package/src/subsystem/c4Evidence.ts +329 -0
- package/src/subsystem/model.ts +2 -6
- package/dist/stories/Subsystem/C4Graph/c4Associations.fixture.d.ts +0 -95
- package/dist/stories/Subsystem/C4Graph/c4Associations.fixture.d.ts.map +0 -1
- package/dist/stories/Subsystem/C4Graph/c4Associations.fixture.js +0 -340
- package/dist/stories/Subsystem/C4Graph/c4Associations.fixture.js.map +0 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts +0 -7
- package/dist/stories/Subsystem/C4Graph/c4Fixture.d.ts.map +0 -1
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js +0 -7335
- package/dist/stories/Subsystem/C4Graph/c4Fixture.js.map +0 -1
- package/dist/stories/Subsystem/C4Graph/generateFixture.d.ts +0 -2
- package/dist/stories/Subsystem/C4Graph/generateFixture.d.ts.map +0 -1
- package/dist/stories/Subsystem/C4Graph/generateFixture.js +0 -145
- package/dist/stories/Subsystem/C4Graph/generateFixture.js.map +0 -1
- package/dist/subsystem/c4Associations.d.ts +0 -186
- package/dist/subsystem/c4Associations.d.ts.map +0 -1
- package/dist/subsystem/c4Associations.js +0 -284
- package/dist/subsystem/c4Associations.js.map +0 -1
- package/dist/subsystem/toC4.d.ts +0 -214
- package/dist/subsystem/toC4.d.ts.map +0 -1
- package/dist/subsystem/toC4.js +0 -282
- package/dist/subsystem/toC4.js.map +0 -1
- package/src/stories/Subsystem/C4Graph/C4Associations.stories.tsx +0 -273
- package/src/stories/Subsystem/C4Graph/C4Container.stories.tsx +0 -101
- package/src/stories/Subsystem/C4Graph/c4Associations.fixture.ts +0 -344
- package/src/stories/Subsystem/C4Graph/c4Fixture.ts +0 -7339
- package/src/stories/Subsystem/C4Graph/generateFixture.ts +0 -161
- package/src/subsystem/c4Associations.test.ts +0 -484
- package/src/subsystem/c4Associations.ts +0 -398
- package/src/subsystem/toC4.test.ts +0 -114
- package/src/subsystem/toC4.ts +0 -478
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
3
3
|
import { ThemeProvider, defaultEditorTheme, useTheme } from '@principal-ade/industry-theme';
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
C4NodeCard,
|
|
6
|
+
nodeStyle,
|
|
7
|
+
nodeSubtitle,
|
|
8
|
+
nodeTag,
|
|
9
|
+
nodeShape,
|
|
10
|
+
nodeSize,
|
|
11
|
+
nodeMissing,
|
|
12
|
+
NODE_W,
|
|
13
|
+
} from '../../../subsystem/C4NodeCard';
|
|
14
|
+
import type { C4Node } from '../../../subsystem/c4';
|
|
6
15
|
|
|
7
16
|
// ---------------------------------------------------------------------------
|
|
8
17
|
// A card gallery: every C4 box variant, outside the graph.
|
|
@@ -14,6 +23,10 @@ import type { C4Node, C4ElementType } from '../../../subsystem/toC4';
|
|
|
14
23
|
// Rendering the card directly (not through React Flow) is the point: the node
|
|
15
24
|
// is a plain presentational component, so it can be reviewed and diffed
|
|
16
25
|
// without a layout engine in the way.
|
|
26
|
+
//
|
|
27
|
+
// Every card here is a flattened `C4Node` — exactly what `buildC4Model`
|
|
28
|
+
// produces from an authored element, with the per-kind fields already resolved
|
|
29
|
+
// to the one shape the card draws with.
|
|
17
30
|
// ---------------------------------------------------------------------------
|
|
18
31
|
|
|
19
32
|
const meta = {
|
|
@@ -39,33 +52,27 @@ function node(over: Partial<C4Node> & { id: string; label: string }): C4Node {
|
|
|
39
52
|
kind: 'container',
|
|
40
53
|
members: [],
|
|
41
54
|
constructs: [],
|
|
42
|
-
|
|
55
|
+
state: 'proposed',
|
|
43
56
|
...over,
|
|
44
57
|
};
|
|
45
58
|
}
|
|
46
59
|
|
|
47
|
-
const CONFIRMED = {
|
|
48
|
-
id: 'container:studio-host',
|
|
49
|
-
label: 'Studio Host',
|
|
50
|
-
type: 'application' as C4ElementType,
|
|
51
|
-
technology: 'Bun + Electrobun',
|
|
52
|
-
description: 'Runs the audit pipeline, owns the model store, serves the RPC surface.',
|
|
53
|
-
state: 'accepted' as const,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
60
|
const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
57
61
|
// `id` on each variant is its caption key, not a component field.
|
|
62
|
+
|
|
58
63
|
// --- confirmation state: the axis that matters most --------------------
|
|
59
64
|
{
|
|
60
65
|
group: 'Confirmation state',
|
|
61
|
-
note: '
|
|
66
|
+
note: 'Solid = a person signed off. Dashed = an agent asked and nobody answered. This is the only field that changes how a box is drawn, so it is the only one a confirm UI needs to move.',
|
|
62
67
|
node: node({
|
|
63
68
|
id: 'a1',
|
|
64
|
-
label: '
|
|
65
|
-
key: 'subsystems-studio/host',
|
|
69
|
+
label: 'Subsystem Studio — host',
|
|
66
70
|
members: ['a', 'b', 'c'],
|
|
67
71
|
constructs: ['function', 'store'],
|
|
68
|
-
|
|
72
|
+
containerKind: 'application',
|
|
73
|
+
technology: 'Bun + Electrobun',
|
|
74
|
+
description: 'Runs the audit pipeline, owns the model store, serves the RPC surface.',
|
|
75
|
+
state: 'accepted',
|
|
69
76
|
}),
|
|
70
77
|
},
|
|
71
78
|
{
|
|
@@ -73,16 +80,12 @@ const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
|
73
80
|
note: '',
|
|
74
81
|
node: node({
|
|
75
82
|
id: 'a2',
|
|
76
|
-
label: 'subsystems-
|
|
77
|
-
key: 'subsystems-core/types',
|
|
83
|
+
label: 'subsystems-react (proposed container?)',
|
|
78
84
|
members: ['x', 'y'],
|
|
79
|
-
constructs: ['
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type: 'library',
|
|
84
|
-
state: 'proposed',
|
|
85
|
-
},
|
|
85
|
+
constructs: ['function', 'interface'],
|
|
86
|
+
containerKind: 'application',
|
|
87
|
+
technology: 'React',
|
|
88
|
+
state: 'proposed',
|
|
86
89
|
}),
|
|
87
90
|
},
|
|
88
91
|
{
|
|
@@ -90,45 +93,56 @@ const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
|
90
93
|
note: '',
|
|
91
94
|
node: node({
|
|
92
95
|
id: 'a3',
|
|
93
|
-
label: '
|
|
94
|
-
key: 'principal-studio-cli',
|
|
96
|
+
label: 'Subsystem Modeling CLI',
|
|
95
97
|
members: ['cli-create'],
|
|
96
98
|
constructs: ['function'],
|
|
99
|
+
containerKind: 'application',
|
|
100
|
+
technology: 'Node',
|
|
101
|
+
description: 'Creates and updates models from the terminal.',
|
|
102
|
+
state: 'accepted',
|
|
97
103
|
}),
|
|
98
104
|
},
|
|
99
105
|
{
|
|
100
106
|
group: '',
|
|
101
|
-
note: '',
|
|
107
|
+
note: 'Rejected elements are not drawn at all. This card exists to prove the fallback branch exists, not because a diagram ever shows one.',
|
|
102
108
|
node: node({
|
|
103
109
|
id: 'a4',
|
|
104
110
|
label: 'graphify/extract',
|
|
105
|
-
key: 'graphify/extract',
|
|
106
111
|
members: ['extract'],
|
|
107
112
|
constructs: ['function'],
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
type: 'application',
|
|
112
|
-
state: 'rejected',
|
|
113
|
-
},
|
|
113
|
+
containerKind: 'application',
|
|
114
|
+
technology: 'Bun',
|
|
115
|
+
state: 'rejected',
|
|
114
116
|
}),
|
|
115
117
|
},
|
|
116
118
|
{
|
|
117
119
|
group: '',
|
|
118
|
-
note: '',
|
|
119
|
-
node: node({
|
|
120
|
+
note: 'A box that consolidated two derived keys says so — the inputs are hidden once merged, and silently losing them would be a lie about provenance.',
|
|
121
|
+
node: node({
|
|
122
|
+
id: 'a5',
|
|
123
|
+
label: 'Subsystem Studio — host',
|
|
124
|
+
derivedFrom: ['subsystems-studio/host', 'principal-studio/host'],
|
|
125
|
+
members: ['a'],
|
|
126
|
+
constructs: ['function'],
|
|
127
|
+
containerKind: 'application',
|
|
128
|
+
technology: 'Bun + Electrobun',
|
|
129
|
+
state: 'accepted',
|
|
130
|
+
}),
|
|
120
131
|
},
|
|
121
132
|
|
|
122
|
-
// ---
|
|
133
|
+
// --- the four kinds ------------------------------------------------------
|
|
123
134
|
{
|
|
124
|
-
group: '
|
|
125
|
-
note: 'C4
|
|
135
|
+
group: 'The four kinds',
|
|
136
|
+
note: 'C4 has a closed vocabulary: software system, container, component, code. Outside the boundary it adds people. There is no "library" kind — c4model says a module typically is not an element at all, so a library is a review comment, not a fifth box.',
|
|
126
137
|
node: node({
|
|
127
138
|
id: 'b1',
|
|
128
139
|
label: 'Subsystem model store',
|
|
129
140
|
members: ['s1'],
|
|
130
141
|
constructs: ['store'],
|
|
131
|
-
|
|
142
|
+
containerKind: 'data-store',
|
|
143
|
+
technology: 'JSON files on disk',
|
|
144
|
+
description: 'Every stored model plus its index.',
|
|
145
|
+
state: 'accepted',
|
|
132
146
|
}),
|
|
133
147
|
},
|
|
134
148
|
{
|
|
@@ -139,30 +153,39 @@ const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
|
139
153
|
label: 'Audit correction queue',
|
|
140
154
|
members: ['s2'],
|
|
141
155
|
constructs: ['store'],
|
|
142
|
-
|
|
156
|
+
containerKind: 'queue',
|
|
157
|
+
technology: 'agent session transport',
|
|
158
|
+
description: 'Proposals awaiting a human decision.',
|
|
159
|
+
state: 'accepted',
|
|
143
160
|
}),
|
|
144
161
|
},
|
|
145
162
|
{
|
|
146
163
|
group: '',
|
|
147
|
-
note: '',
|
|
164
|
+
note: 'A component is a real square, not a smaller rectangle. Border weight drops to 1px as a second signal, so the level survives grayscale.',
|
|
148
165
|
node: node({
|
|
149
166
|
id: 'b3',
|
|
150
|
-
label: '
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
167
|
+
label: 'Boundary layout builder',
|
|
168
|
+
kind: 'component',
|
|
169
|
+
parentId: 'container:shared-ui',
|
|
170
|
+
members: ['h1', 'h2'],
|
|
171
|
+
constructs: ['function'],
|
|
172
|
+
technology: 'React + ELK',
|
|
173
|
+
description: 'Turns claims into nested compound frames.',
|
|
174
|
+
state: 'accepted',
|
|
154
175
|
}),
|
|
155
176
|
},
|
|
156
177
|
{
|
|
157
178
|
group: '',
|
|
158
|
-
note: '',
|
|
179
|
+
note: 'An external system keeps the rectangle but goes dashed — it is outside the boundary, which is a different statement from "inside, and unconfirmed".',
|
|
159
180
|
node: node({
|
|
160
181
|
id: 'b4',
|
|
161
182
|
label: 'OpenCode v2 service',
|
|
162
|
-
kind: 'external',
|
|
183
|
+
kind: 'external-system',
|
|
163
184
|
members: ['oc2'],
|
|
164
185
|
constructs: ['external'],
|
|
165
|
-
|
|
186
|
+
technology: 'HTTP',
|
|
187
|
+
description: 'Runs maintain agent sessions.',
|
|
188
|
+
state: 'accepted',
|
|
166
189
|
}),
|
|
167
190
|
},
|
|
168
191
|
{
|
|
@@ -171,24 +194,26 @@ const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
|
171
194
|
node: node({
|
|
172
195
|
id: 'b5',
|
|
173
196
|
label: 'Maintain operator',
|
|
174
|
-
kind: '
|
|
197
|
+
kind: 'person',
|
|
175
198
|
members: ['a'],
|
|
176
199
|
constructs: ['custom_entity'],
|
|
177
|
-
|
|
200
|
+
description: 'Reviews and accepts correction proposals.',
|
|
201
|
+
state: 'proposed',
|
|
178
202
|
}),
|
|
179
203
|
},
|
|
180
204
|
|
|
181
205
|
// --- the gaps C4 keeps asking about ------------------------------------
|
|
182
206
|
{
|
|
183
207
|
group: 'Notation gaps',
|
|
184
|
-
note: 'C4 requires technology and description on every container. A
|
|
208
|
+
note: 'C4 requires technology and description on every container. A box that never got either says so on its face rather than looking finished — and `technology` is required by the type, so the only way to have the gap is an empty string.',
|
|
185
209
|
node: node({
|
|
186
210
|
id: 'c1',
|
|
187
|
-
label: '
|
|
188
|
-
key: 'site/web',
|
|
211
|
+
label: 'In-memory renderer state',
|
|
189
212
|
members: ['w1', 'w2', 'w3'],
|
|
190
|
-
constructs: ['
|
|
191
|
-
|
|
213
|
+
constructs: ['store'],
|
|
214
|
+
containerKind: 'application',
|
|
215
|
+
technology: '',
|
|
216
|
+
state: 'accepted',
|
|
192
217
|
}),
|
|
193
218
|
},
|
|
194
219
|
{
|
|
@@ -196,25 +221,50 @@ const VARIANTS: Array<{ group: string; note: string; node: C4Node }> = [
|
|
|
196
221
|
note: '',
|
|
197
222
|
node: node({
|
|
198
223
|
id: 'c2',
|
|
199
|
-
label: '
|
|
200
|
-
key: 'subsystems-studio/renderer',
|
|
224
|
+
label: 'Subsystem Studio — renderer',
|
|
201
225
|
members: ['r1', 'r2'],
|
|
202
226
|
constructs: ['function'],
|
|
203
|
-
|
|
227
|
+
containerKind: 'application',
|
|
228
|
+
technology: 'React 19',
|
|
229
|
+
state: 'accepted',
|
|
204
230
|
}),
|
|
205
231
|
},
|
|
206
232
|
|
|
207
|
-
// ---
|
|
233
|
+
// --- the pair that was confusing, side by side ------------------------
|
|
208
234
|
{
|
|
209
|
-
group: '
|
|
210
|
-
note: 'Same
|
|
235
|
+
group: 'Container vs component',
|
|
236
|
+
note: 'The case that started this. Same border colour and same state, previously identical. Now a wide rectangle says "container" and a square says "component", so the level is readable before the text is.',
|
|
211
237
|
node: node({
|
|
212
|
-
id: '
|
|
213
|
-
label: '
|
|
238
|
+
id: 'e1',
|
|
239
|
+
label: 'Subsystem Studio — host',
|
|
240
|
+
members: ['a', 'b', 'c'],
|
|
241
|
+
constructs: ['function', 'store'],
|
|
242
|
+
containerKind: 'application',
|
|
243
|
+
technology: 'Bun + Electrobun',
|
|
244
|
+
description: 'Runs the audit pipeline.',
|
|
245
|
+
state: 'accepted',
|
|
246
|
+
}),
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
group: '',
|
|
250
|
+
note: '',
|
|
251
|
+
node: node({
|
|
252
|
+
id: 'e2',
|
|
253
|
+
label: 'Studio Host',
|
|
214
254
|
kind: 'component',
|
|
215
|
-
|
|
255
|
+
parentId: 'container:studio-host',
|
|
256
|
+
members: ['h1'],
|
|
216
257
|
constructs: ['function'],
|
|
217
|
-
|
|
258
|
+
technology: 'Bun',
|
|
259
|
+
description: 'Resolves the model root and registers repos.',
|
|
260
|
+
state: 'accepted',
|
|
261
|
+
component: {
|
|
262
|
+
alias: 'h1',
|
|
263
|
+
name: 'StudioHost',
|
|
264
|
+
construct: 'function',
|
|
265
|
+
file: 'packages/subsystems-studio/src/bun/index.ts',
|
|
266
|
+
purl: 'pkg:x#packages/subsystems-studio/src/bun/index.ts',
|
|
267
|
+
},
|
|
218
268
|
}),
|
|
219
269
|
},
|
|
220
270
|
];
|
|
@@ -242,6 +292,8 @@ function Case({ caption, children }: { caption: string; children: React.ReactNod
|
|
|
242
292
|
return (
|
|
243
293
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 5, alignItems: 'flex-start' }}>
|
|
244
294
|
{children}
|
|
295
|
+
{/* Caption spans the container box so every card's caption starts at the
|
|
296
|
+
same x — otherwise the narrower square column looks misaligned. */}
|
|
245
297
|
<span
|
|
246
298
|
style={{
|
|
247
299
|
fontFamily: 'monospace',
|
|
@@ -257,14 +309,16 @@ function Case({ caption, children }: { caption: string; children: React.ReactNod
|
|
|
257
309
|
);
|
|
258
310
|
}
|
|
259
311
|
|
|
312
|
+
const KINDS = ['container', 'component', 'external-system', 'person'] as const;
|
|
313
|
+
|
|
260
314
|
function Gallery() {
|
|
261
315
|
const { theme } = useTheme();
|
|
262
316
|
const muted = theme.colors.textMuted ?? '#9a9aa0';
|
|
263
317
|
|
|
264
318
|
const legend: Array<[string, string]> = [
|
|
265
|
-
['accepted', nodeStyle({ id: 'x',
|
|
266
|
-
['proposed', nodeStyle({ id: 'x',
|
|
267
|
-
['
|
|
319
|
+
['accepted', nodeStyle(node({ id: 'x', label: '', state: 'accepted' }), theme).color],
|
|
320
|
+
['proposed', nodeStyle(node({ id: 'x', label: '', state: 'proposed' }), theme).color],
|
|
321
|
+
['rejected', nodeStyle(node({ id: 'x', label: '', state: 'rejected' }), theme).color],
|
|
268
322
|
];
|
|
269
323
|
|
|
270
324
|
let currentGroup = '';
|
|
@@ -277,13 +331,45 @@ function Gallery() {
|
|
|
277
331
|
encoding.
|
|
278
332
|
</p>
|
|
279
333
|
|
|
280
|
-
<div style={{
|
|
281
|
-
{
|
|
282
|
-
<span
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
334
|
+
<div style={{ fontFamily: 'monospace', fontSize: 11, marginBottom: 26, lineHeight: 1.9 }}>
|
|
335
|
+
<div style={{ display: 'flex', gap: 20, flexWrap: 'wrap' }}>
|
|
336
|
+
<span style={{ color: '#e8e8ea' }}>KIND — shape and border weight</span>
|
|
337
|
+
</div>
|
|
338
|
+
<div style={{ display: 'flex', gap: 18, flexWrap: 'wrap', marginTop: 4 }}>
|
|
339
|
+
{KINDS.map((kind) => {
|
|
340
|
+
const s = nodeShape(node({ id: 'x', label: '', kind }));
|
|
341
|
+
const size = nodeSize(node({ id: 'x', label: '', kind }));
|
|
342
|
+
const color = nodeStyle(node({ id: 'x', label: '', kind }), theme).color;
|
|
343
|
+
const weight = kind === 'component' ? 1 : 2;
|
|
344
|
+
// Drawn at the real aspect ratio — the whole signal is square vs
|
|
345
|
+
// rectangle, so a legend that flattened both would lie.
|
|
346
|
+
return (
|
|
347
|
+
<span key={kind} style={{ display: 'flex', alignItems: 'center', gap: 6, color: muted }}>
|
|
348
|
+
<span
|
|
349
|
+
style={{
|
|
350
|
+
width: 28,
|
|
351
|
+
height: Math.round((28 * size.height) / size.width),
|
|
352
|
+
borderRadius: Math.min(s.radius, 9),
|
|
353
|
+
border: `${weight} ${s.dash} ${color}`,
|
|
354
|
+
display: 'inline-block',
|
|
355
|
+
}}
|
|
356
|
+
/>
|
|
357
|
+
{kind}
|
|
358
|
+
</span>
|
|
359
|
+
);
|
|
360
|
+
})}
|
|
361
|
+
</div>
|
|
362
|
+
<div style={{ display: 'flex', gap: 20, flexWrap: 'wrap', marginTop: 14 }}>
|
|
363
|
+
<span style={{ color: '#e8e8ea' }}>CONFIRMATION — colour and dash, never the shape</span>
|
|
364
|
+
</div>
|
|
365
|
+
<div style={{ display: 'flex', gap: 18, flexWrap: 'wrap', marginTop: 4 }}>
|
|
366
|
+
{legend.map(([name, color]) => (
|
|
367
|
+
<span key={name} style={{ display: 'flex', alignItems: 'center', gap: 6, color: muted }}>
|
|
368
|
+
<span style={{ width: 22, height: 0, borderTop: `3px solid ${color}`, display: 'inline-block' }} />
|
|
369
|
+
{name}
|
|
370
|
+
</span>
|
|
371
|
+
))}
|
|
372
|
+
</div>
|
|
287
373
|
</div>
|
|
288
374
|
|
|
289
375
|
<Row>
|
|
@@ -291,14 +377,16 @@ function Gallery() {
|
|
|
291
377
|
const showHeader = v.group && v.group !== currentGroup;
|
|
292
378
|
if (v.group) currentGroup = v.group;
|
|
293
379
|
return (
|
|
294
|
-
<React.Fragment key={v.
|
|
380
|
+
<React.Fragment key={v.node.id}>
|
|
295
381
|
{showHeader && (
|
|
296
382
|
<div style={{ width: '100%' }}>
|
|
297
383
|
<Section title={v.group} note={v.note} />
|
|
298
384
|
</div>
|
|
299
385
|
)}
|
|
300
386
|
<Case
|
|
301
|
-
caption={`${v.node.id} ·
|
|
387
|
+
caption={`${v.node.id} · "${nodeTag(v.node)}" · ${v.node.state} · ${nodeShape(v.node).kind} ${
|
|
388
|
+
nodeSize(v.node).width
|
|
389
|
+
}×${nodeSize(v.node).height} · ${nodeSubtitle(v.node)}${
|
|
302
390
|
nodeMissing(v.node).length ? ` · missing ${nodeMissing(v.node).join('+')}` : ''
|
|
303
391
|
}`}
|
|
304
392
|
>
|