@screenbook/ui 1.1.0 → 1.1.2

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 (37) hide show
  1. package/README.md +30 -0
  2. package/dist/client/_astro/coverage.BzPU-EGZ.css +1 -0
  3. package/dist/server/entry.mjs +1 -1
  4. package/dist/server/{manifest_smcahUO6.mjs → manifest_BGl49hHW.mjs} +1 -1
  5. package/dist/server/pages/coverage.astro.mjs +1 -1
  6. package/dist/server/pages/editor.astro.mjs +1 -1
  7. package/dist/server/pages/graph.astro.mjs +1 -1
  8. package/dist/server/pages/impact.astro.mjs +1 -1
  9. package/dist/server/pages/index.astro.mjs +1 -1
  10. package/dist/server/pages/screen/_id_.astro.mjs +1 -1
  11. package/package.json +5 -1
  12. package/.astro/content-assets.mjs +0 -1
  13. package/.astro/content-modules.mjs +0 -1
  14. package/.astro/content.d.ts +0 -199
  15. package/.astro/types.d.ts +0 -2
  16. package/.prettierrc +0 -15
  17. package/CHANGELOG.md +0 -77
  18. package/astro.config.mjs +0 -20
  19. package/dist/client/_astro/coverage.DLKSOM4m.css +0 -1
  20. package/public/logo.svg +0 -5
  21. package/src/components/MockFormEditor.tsx +0 -1280
  22. package/src/components/MockPreview.astro +0 -811
  23. package/src/layouts/Layout.astro +0 -77
  24. package/src/pages/api/save-mock.ts +0 -182
  25. package/src/pages/coverage.astro +0 -399
  26. package/src/pages/editor.astro +0 -33
  27. package/src/pages/graph.astro +0 -368
  28. package/src/pages/impact.astro +0 -462
  29. package/src/pages/index.astro +0 -176
  30. package/src/pages/screen/[id].astro +0 -195
  31. package/src/styles/global.css +0 -904
  32. package/src/styles/mock-editor.css +0 -1351
  33. package/src/utils/impactAnalysis.ts +0 -304
  34. package/src/utils/loadCoverage.ts +0 -30
  35. package/src/utils/loadScreens.ts +0 -18
  36. package/tsconfig.json +0 -10
  37. /package/dist/server/chunks/{loadScreens_CkCqdbH2.mjs → loadScreens_B8bVK3q5.mjs} +0 -0
@@ -1,368 +0,0 @@
1
- ---
2
- import Layout from "@/layouts/Layout.astro"
3
- import { loadScreens } from "@/utils/loadScreens"
4
-
5
- const screens = loadScreens()
6
-
7
- // Generate Navigation Mermaid graph
8
- let navigationGraph = ""
9
- const screensWithMock: string[] = []
10
- if (screens.length > 0) {
11
- const lines: string[] = ["flowchart TD"]
12
-
13
- for (const screen of screens) {
14
- const label = screen.title.replace(/"/g, "'")
15
- const id = screen.id.replace(/\./g, "_")
16
- const mockIndicator = screen.mock ? " 📱" : ""
17
- lines.push(` ${id}["${label}${mockIndicator}"]`)
18
- lines.push(` click ${id} "/screen/${screen.id}"`)
19
- if (screen.mock) {
20
- screensWithMock.push(id)
21
- }
22
- }
23
-
24
- lines.push("")
25
-
26
- for (const screen of screens) {
27
- if (screen.next) {
28
- const fromId = screen.id.replace(/\./g, "_")
29
- for (const nextId of screen.next) {
30
- const toId = nextId.replace(/\./g, "_")
31
- lines.push(` ${fromId} --> ${toId}`)
32
- }
33
- }
34
- }
35
-
36
- // Add styling for screens with mock
37
- if (screensWithMock.length > 0) {
38
- lines.push("")
39
- lines.push(" %% Mock styling")
40
- lines.push(" classDef hasMock stroke:#14b8a6,stroke-width:2px")
41
- for (const id of screensWithMock) {
42
- lines.push(` class ${id} hasMock`)
43
- }
44
- }
45
-
46
- navigationGraph = lines.join("\n")
47
- }
48
-
49
- // Count screens with mock
50
- const mockCount = screens.filter(s => s.mock).length
51
-
52
- // Generate API Dependency Mermaid graph
53
- let apiGraph = ""
54
- if (screens.length > 0) {
55
- const lines: string[] = ["flowchart LR"]
56
-
57
- // Collect all unique APIs
58
- const apis = new Set<string>()
59
- for (const screen of screens) {
60
- if (screen.dependsOn) {
61
- for (const api of screen.dependsOn) {
62
- // Get the base API name (e.g., "InvoiceAPI" from "InvoiceAPI.getDetail")
63
- const baseName = api.split(".")[0]
64
- apis.add(baseName)
65
- }
66
- }
67
- }
68
-
69
- // Add API nodes with different style
70
- lines.push(" %% API nodes")
71
- for (const api of apis) {
72
- const id = api.replace(/\./g, "_")
73
- lines.push(` ${id}[/"${api}"/]`)
74
- }
75
-
76
- lines.push("")
77
- lines.push(" %% Screen nodes")
78
-
79
- // Add screen nodes
80
- for (const screen of screens) {
81
- if (screen.dependsOn && screen.dependsOn.length > 0) {
82
- const label = screen.title.replace(/"/g, "'")
83
- const id = screen.id.replace(/\./g, "_")
84
- lines.push(` ${id}["${label}"]`)
85
- }
86
- }
87
-
88
- lines.push("")
89
- lines.push(" %% Dependencies")
90
-
91
- // Add edges from APIs to screens
92
- for (const screen of screens) {
93
- if (screen.dependsOn) {
94
- const screenId = screen.id.replace(/\./g, "_")
95
- const connectedApis = new Set<string>()
96
- for (const api of screen.dependsOn) {
97
- const baseName = api.split(".")[0]
98
- if (!connectedApis.has(baseName)) {
99
- connectedApis.add(baseName)
100
- const apiId = baseName.replace(/\./g, "_")
101
- lines.push(` ${apiId} --> ${screenId}`)
102
- }
103
- }
104
- }
105
- }
106
-
107
- // Add styling for API nodes
108
- lines.push("")
109
- lines.push(" %% Styling")
110
- lines.push(` classDef apiNode fill:#14b8a6,stroke:#5eead4,stroke-width:2px,color:#042f2e`)
111
- for (const api of apis) {
112
- const id = api.replace(/\./g, "_")
113
- lines.push(` class ${id} apiNode`)
114
- }
115
-
116
- apiGraph = lines.join("\n")
117
- }
118
-
119
- // Count APIs for stats
120
- const apiCount = new Set(
121
- screens.flatMap(s => (s.dependsOn || []).map(d => d.split(".")[0]))
122
- ).size
123
- ---
124
-
125
- <Layout title="Graph" currentPage="graph">
126
- <div class="container">
127
- <div class="page-header">
128
- <h1 class="page-title">Dependency Graph</h1>
129
- <p class="page-description">
130
- Visualize relationships between screens and APIs.
131
- </p>
132
- </div>
133
-
134
- {screens.length === 0 ? (
135
- <div class="empty-state">
136
- <svg class="empty-state-icon" aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
137
- <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
138
- </svg>
139
- <h2 class="empty-state-title">No graph data</h2>
140
- <p class="empty-state-description">
141
- Run the build command to generate screen metadata.
142
- </p>
143
- <code class="empty-state-code">
144
- <span class="prompt">$</span> screenbook build
145
- </code>
146
- </div>
147
- ) : (
148
- <>
149
- <div class="graph-controls">
150
- <div class="view-toggle" role="group" aria-label="Graph view">
151
- <button class="toggle-btn active" data-view="navigation" aria-pressed="true">
152
- <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
153
- <path stroke-linecap="round" stroke-linejoin="round" d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
154
- </svg>
155
- Navigation
156
- </button>
157
- <button class="toggle-btn" data-view="api" aria-pressed="false">
158
- <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
159
- <path stroke-linecap="round" stroke-linejoin="round" d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z" />
160
- </svg>
161
- API Dependencies
162
- </button>
163
- </div>
164
- <div class="graph-stats">
165
- <span class="stat">{screens.length} screens</span>
166
- <span class="stat">{apiCount} APIs</span>
167
- {mockCount > 0 && <span class="stat stat-mock">📱 {mockCount} with mock</span>}
168
- </div>
169
- </div>
170
-
171
- <div class="graph-container" id="navigation-graph" role="img" aria-label={`Navigation graph showing ${screens.length} screens and their navigation relationships`}>
172
- <pre class="mermaid" data-graph="navigation" aria-hidden="true">{navigationGraph}</pre>
173
- </div>
174
-
175
- <div class="graph-container hidden" id="api-graph" role="img" aria-label={`API dependency graph showing ${screens.length} screens and ${apiCount} APIs`}>
176
- <pre class="mermaid" data-graph="api" aria-hidden="true">{apiGraph}</pre>
177
- </div>
178
-
179
- <div class="graph-legend" id="navigation-legend">
180
- <div class="graph-legend-item">
181
- <div class="legend-node"></div>
182
- <span>Screen</span>
183
- </div>
184
- <div class="graph-legend-item">
185
- <div class="legend-node legend-mock"></div>
186
- <span>Screen with mock 📱</span>
187
- </div>
188
- <div class="graph-legend-item">
189
- <div class="legend-edge"></div>
190
- <span>Navigation flow</span>
191
- </div>
192
- </div>
193
-
194
- <div class="graph-legend hidden" id="api-legend">
195
- <div class="graph-legend-item">
196
- <div class="legend-node legend-api"></div>
197
- <span>API</span>
198
- </div>
199
- <div class="graph-legend-item">
200
- <div class="legend-node"></div>
201
- <span>Screen</span>
202
- </div>
203
- <div class="graph-legend-item">
204
- <div class="legend-edge"></div>
205
- <span>Depends on</span>
206
- </div>
207
- </div>
208
- </>
209
- )}
210
- </div>
211
-
212
- <script>
213
- import mermaid from "mermaid"
214
-
215
- const mermaidConfig = {
216
- startOnLoad: false,
217
- theme: "dark",
218
- securityLevel: "loose", // Enable click handlers
219
- themeVariables: {
220
- darkMode: true,
221
- background: "transparent",
222
- primaryColor: "#222222",
223
- primaryBorderColor: "#3a3a3a",
224
- primaryTextColor: "#eeeeee",
225
- lineColor: "#5eead4",
226
- fontFamily: "system-ui, sans-serif",
227
- },
228
- flowchart: {
229
- useMaxWidth: true,
230
- htmlLabels: true,
231
- curve: "basis",
232
- padding: 20,
233
- nodeSpacing: 50,
234
- rankSpacing: 60,
235
- },
236
- }
237
-
238
- mermaid.initialize(mermaidConfig)
239
-
240
- // Render both graphs on load
241
- async function renderGraphs() {
242
- const graphs = document.querySelectorAll(".mermaid")
243
- for (const graph of graphs) {
244
- const graphType = graph.getAttribute("data-graph")
245
- const content = graph.textContent || ""
246
- try {
247
- const { svg } = await mermaid.render(`mermaid-${graphType}`, content)
248
- graph.innerHTML = svg
249
- } catch (e) {
250
- console.error(`Failed to render ${graphType} graph:`, e)
251
- }
252
- }
253
- }
254
-
255
- renderGraphs()
256
-
257
- // View toggle functionality
258
- const toggleBtns = document.querySelectorAll(".toggle-btn")
259
- const navGraph = document.getElementById("navigation-graph")
260
- const apiGraph = document.getElementById("api-graph")
261
- const navLegend = document.getElementById("navigation-legend")
262
- const apiLegend = document.getElementById("api-legend")
263
-
264
- toggleBtns.forEach((btn) => {
265
- btn.addEventListener("click", () => {
266
- const view = btn.getAttribute("data-view")
267
-
268
- // Update active button and aria-pressed
269
- toggleBtns.forEach((b) => {
270
- b.classList.remove("active")
271
- b.setAttribute("aria-pressed", "false")
272
- })
273
- btn.classList.add("active")
274
- btn.setAttribute("aria-pressed", "true")
275
-
276
- // Toggle graph visibility
277
- if (view === "navigation") {
278
- navGraph?.classList.remove("hidden")
279
- apiGraph?.classList.add("hidden")
280
- navLegend?.classList.remove("hidden")
281
- apiLegend?.classList.add("hidden")
282
- } else {
283
- navGraph?.classList.add("hidden")
284
- apiGraph?.classList.remove("hidden")
285
- navLegend?.classList.add("hidden")
286
- apiLegend?.classList.remove("hidden")
287
- }
288
- })
289
- })
290
- </script>
291
- </Layout>
292
-
293
- <style>
294
- .graph-controls {
295
- display: flex;
296
- justify-content: space-between;
297
- align-items: center;
298
- margin-bottom: 24px;
299
- flex-wrap: wrap;
300
- gap: 16px;
301
- }
302
-
303
- .view-toggle {
304
- display: flex;
305
- gap: 8px;
306
- background: var(--color-surface);
307
- padding: 4px;
308
- border-radius: var(--radius-lg);
309
- border: 1px solid var(--color-border);
310
- }
311
-
312
- .toggle-btn {
313
- display: flex;
314
- align-items: center;
315
- gap: 8px;
316
- padding: 8px 16px;
317
- border: none;
318
- background: transparent;
319
- color: var(--color-text-muted);
320
- font-size: var(--text-sm);
321
- font-weight: 500;
322
- border-radius: var(--radius-md);
323
- cursor: pointer;
324
- transition: all 0.15s ease;
325
- }
326
-
327
- .toggle-btn:hover {
328
- color: var(--color-text);
329
- }
330
-
331
- .toggle-btn.active {
332
- background: var(--color-accent);
333
- color: var(--color-bg);
334
- }
335
-
336
- .toggle-btn svg {
337
- width: 16px;
338
- height: 16px;
339
- }
340
-
341
- .graph-stats {
342
- display: flex;
343
- gap: 16px;
344
- }
345
-
346
- .stat {
347
- font-size: var(--text-sm);
348
- color: var(--color-text-muted);
349
- }
350
-
351
- .hidden {
352
- display: none !important;
353
- }
354
-
355
- .legend-api {
356
- background: #14b8a6 !important;
357
- border-color: #5eead4 !important;
358
- }
359
-
360
- .legend-mock {
361
- border-color: #14b8a6 !important;
362
- border-width: 2px !important;
363
- }
364
-
365
- .stat-mock {
366
- color: #14b8a6;
367
- }
368
- </style>