@screenbook/ui 0.1.0 → 1.1.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 (83) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/astro.config.mjs +2 -0
  3. package/dist/client/_astro/MockFormEditor.0L29BkPy.js +9 -0
  4. package/dist/client/_astro/MockFormEditor.OiYzJAtR.css +1 -0
  5. package/dist/client/_astro/{_baseUniq.BGai4mcc.js → _baseUniq.D9ouiLRJ.js} +1 -1
  6. package/dist/client/_astro/_id_.BqQf-JH6.css +1 -0
  7. package/dist/client/_astro/{arc.DUp0dfXj.js → arc.CLU0JlVT.js} +1 -1
  8. package/dist/client/_astro/{architectureDiagram-VXUJARFQ.De_Gt-YC.js → architectureDiagram-VXUJARFQ.BF0V2v9-.js} +1 -1
  9. package/dist/client/_astro/{blockDiagram-VD42YOAC.BBt_VNhR.js → blockDiagram-VD42YOAC.6LO7yu7m.js} +1 -1
  10. package/dist/client/_astro/{c4Diagram-YG6GDRKO.DfgUlHvt.js → c4Diagram-YG6GDRKO.BqntXNsZ.js} +1 -1
  11. package/dist/client/_astro/channel._8es88oH.js +1 -0
  12. package/dist/client/_astro/{chunk-4BX2VUAB.BL0ar6du.js → chunk-4BX2VUAB.b97OIY94.js} +1 -1
  13. package/dist/client/_astro/{chunk-55IACEB6.CI6SkZkY.js → chunk-55IACEB6.Cf9hglsl.js} +1 -1
  14. package/dist/client/_astro/{chunk-B4BG7PRW.Z25N80K6.js → chunk-B4BG7PRW.vDfM6vb1.js} +1 -1
  15. package/dist/client/_astro/{chunk-DI55MBZ5.BqjPVmi1.js → chunk-DI55MBZ5.8pHdnkw9.js} +1 -1
  16. package/dist/client/_astro/{chunk-FMBD7UC4.bZ9DWnFm.js → chunk-FMBD7UC4.l_Ue7ZYJ.js} +1 -1
  17. package/dist/client/_astro/{chunk-QN33PNHL.BkzuUgWB.js → chunk-QN33PNHL.CyBZ7SCx.js} +1 -1
  18. package/dist/client/_astro/{chunk-QZHKN3VN.C__d68N_.js → chunk-QZHKN3VN.BC5tI2Vw.js} +1 -1
  19. package/dist/client/_astro/{chunk-TZMSLE5B.BIpu8bMn.js → chunk-TZMSLE5B.DxkkbOL4.js} +1 -1
  20. package/dist/client/_astro/classDiagram-2ON5EDUG.DMv55r4w.js +1 -0
  21. package/dist/client/_astro/classDiagram-v2-WZHVMYZB.DMv55r4w.js +1 -0
  22. package/dist/client/_astro/client.9unXo8s5.js +33 -0
  23. package/dist/client/_astro/clone.COAvtnt5.js +1 -0
  24. package/dist/client/_astro/{cose-bilkent-S5V4N54A.D48yfMll.js → cose-bilkent-S5V4N54A.DlRxGhCG.js} +1 -1
  25. package/dist/client/_astro/coverage.DLKSOM4m.css +1 -0
  26. package/dist/client/_astro/{dagre-6UL2VRFP.LKVH7b30.js → dagre-6UL2VRFP.tCLd0f1c.js} +1 -1
  27. package/dist/client/_astro/{diagram-PSM6KHXK.AHgUjH56.js → diagram-PSM6KHXK.CJA_rnN3.js} +1 -1
  28. package/dist/client/_astro/{diagram-QEK2KX5R.DvS33xWZ.js → diagram-QEK2KX5R.BoqLvsuS.js} +1 -1
  29. package/dist/client/_astro/{diagram-S2PKOQOG.BWisaYrQ.js → diagram-S2PKOQOG.T8h5wODN.js} +1 -1
  30. package/dist/client/_astro/{erDiagram-Q2GNP2WA.B7oID6oT.js → erDiagram-Q2GNP2WA.B4hpr69H.js} +1 -1
  31. package/dist/client/_astro/{flowDiagram-NV44I4VS.Bb1qJLxr.js → flowDiagram-NV44I4VS.CV4Oenkb.js} +1 -1
  32. package/dist/client/_astro/{ganttDiagram-JELNMOA3.3vGHETyo.js → ganttDiagram-JELNMOA3.DdpXJeX3.js} +1 -1
  33. package/dist/client/_astro/{gitGraphDiagram-NY62KEGX.Co2SKcif.js → gitGraphDiagram-NY62KEGX.BeY3JZYI.js} +1 -1
  34. package/dist/client/_astro/{graph.B5fevUwB.js → graph.CO6LxWoK.js} +1 -1
  35. package/dist/client/_astro/graph.astro_astro_type_script_index_0_lang.BxaPom9e.js +1 -0
  36. package/dist/client/_astro/{impact.astro_astro_type_script_index_0_lang.D4cAR9AL.js → impact.astro_astro_type_script_index_0_lang.VjeLQGe6.js} +1 -1
  37. package/dist/client/_astro/index.WFquGv8Z.js +9 -0
  38. package/dist/client/_astro/{infoDiagram-WHAUD3N6.B6ULtps1.js → infoDiagram-WHAUD3N6.D2_J_fR6.js} +1 -1
  39. package/dist/client/_astro/{journeyDiagram-XKPGCS4Q.BSOCzWmw.js → journeyDiagram-XKPGCS4Q.7c4ngVDw.js} +1 -1
  40. package/dist/client/_astro/{kanban-definition-3W4ZIXB7.D8KKGc1o.js → kanban-definition-3W4ZIXB7.D_eWex6x.js} +1 -1
  41. package/dist/client/_astro/{layout.8vv24qEg.js → layout.Cn9EjNLq.js} +1 -1
  42. package/dist/client/_astro/{linear.B6O9ymuK.js → linear.BlE_mLsy.js} +1 -1
  43. package/dist/client/_astro/{mermaid.core.CReXU7YN.js → mermaid.core.CgCLOZ6t.js} +5 -5
  44. package/dist/client/_astro/{min.CdGMGVU0.js → min.OtQS-qlD.js} +1 -1
  45. package/dist/client/_astro/{mindmap-definition-VGOIOE7T.G14HgtDw.js → mindmap-definition-VGOIOE7T.CjNYt18e.js} +1 -1
  46. package/dist/client/_astro/{pieDiagram-ADFJNKIX.bC2VkyoW.js → pieDiagram-ADFJNKIX.D18DPyo6.js} +1 -1
  47. package/dist/client/_astro/{quadrantDiagram-AYHSOK5B.BlLaQQxO.js → quadrantDiagram-AYHSOK5B.Cma08fPv.js} +1 -1
  48. package/dist/client/_astro/{requirementDiagram-UZGBJVZJ.DHRnMofO.js → requirementDiagram-UZGBJVZJ.BlhVOrX0.js} +1 -1
  49. package/dist/client/_astro/{sankeyDiagram-TZEHDZUN.BMuaJBmt.js → sankeyDiagram-TZEHDZUN.HRsqw4ej.js} +1 -1
  50. package/dist/client/_astro/{sequenceDiagram-WL72ISMW.CnU62wqy.js → sequenceDiagram-WL72ISMW.3cZYkaSP.js} +1 -1
  51. package/dist/client/_astro/{stateDiagram-FKZM4ZOC.CewI55YO.js → stateDiagram-FKZM4ZOC.DdlRd9N7.js} +1 -1
  52. package/dist/client/_astro/stateDiagram-v2-4FDKWEC3.DCPDjwi7.js +1 -0
  53. package/dist/client/_astro/{timeline-definition-IT6M3QCI.D1PLRwss.js → timeline-definition-IT6M3QCI.BshW8mMW.js} +1 -1
  54. package/dist/client/_astro/{treemap-KMMF4GRG.D3VNVvXF.js → treemap-KMMF4GRG.BxXN_YfK.js} +1 -1
  55. package/dist/client/_astro/{xychartDiagram-PRI3JC2R.CQex0-ul.js → xychartDiagram-PRI3JC2R.Mg5_s08f.js} +1 -1
  56. package/dist/server/entry.mjs +15 -11
  57. package/dist/server/manifest_smcahUO6.mjs +101 -0
  58. package/dist/server/pages/api/save-mock.astro.mjs +142 -0
  59. package/dist/server/pages/coverage.astro.mjs +1 -1
  60. package/dist/server/pages/editor.astro.mjs +30 -0
  61. package/dist/server/pages/graph.astro.mjs +18 -3
  62. package/dist/server/pages/impact.astro.mjs +1 -1
  63. package/dist/server/pages/index.astro.mjs +1 -1
  64. package/dist/server/pages/screen/_id_.astro.mjs +126 -3
  65. package/dist/server/renderers.mjs +200 -1
  66. package/package.json +8 -2
  67. package/src/components/MockFormEditor.tsx +1280 -0
  68. package/src/components/MockPreview.astro +811 -0
  69. package/src/pages/api/save-mock.ts +182 -0
  70. package/src/pages/editor.astro +33 -0
  71. package/src/pages/graph.astro +35 -1
  72. package/src/pages/screen/[id].astro +9 -0
  73. package/src/styles/mock-editor.css +1351 -0
  74. package/tsconfig.json +1 -0
  75. package/dist/client/_astro/channel.CNyr52v1.js +0 -1
  76. package/dist/client/_astro/classDiagram-2ON5EDUG.CxT3aW-h.js +0 -1
  77. package/dist/client/_astro/classDiagram-v2-WZHVMYZB.CxT3aW-h.js +0 -1
  78. package/dist/client/_astro/clone.U_lSZ6fe.js +0 -1
  79. package/dist/client/_astro/coverage.BnE2oGo8.css +0 -1
  80. package/dist/client/_astro/graph.astro_astro_type_script_index_0_lang.B0fEnVdy.js +0 -1
  81. package/dist/client/_astro/stateDiagram-v2-4FDKWEC3.7xUQqoNr.js +0 -1
  82. package/dist/server/manifest_CicDtuHD.mjs +0 -101
  83. /package/dist/server/chunks/{loadScreens_JhK3F9tC.mjs → loadScreens_CkCqdbH2.mjs} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { e as createComponent, f as createAstro, k as renderComponent, r as renderTemplate, m as maybeRenderHead, n as renderScript, l as Fragment, h as addAttribute } from '../chunks/astro/server_m7yT4wCr.mjs';
2
2
  import 'piccolore';
3
- import { l as loadScreens, $ as $$Layout } from '../chunks/loadScreens_JhK3F9tC.mjs';
3
+ import { l as loadScreens, $ as $$Layout } from '../chunks/loadScreens_CkCqdbH2.mjs';
4
4
  import { g as getAllApis, a as analyzeImpact, b as generateImpactMermaid, f as formatImpactMarkdown } from '../chunks/impactAnalysis_LvYEc57d.mjs';
5
5
  /* empty css */
6
6
  export { renderers } from '../renderers.mjs';
@@ -1,6 +1,6 @@
1
1
  import { e as createComponent, k as renderComponent, r as renderTemplate, m as maybeRenderHead, n as renderScript, l as Fragment, h as addAttribute } from '../chunks/astro/server_m7yT4wCr.mjs';
2
2
  import 'piccolore';
3
- import { l as loadScreens, $ as $$Layout } from '../chunks/loadScreens_JhK3F9tC.mjs';
3
+ import { l as loadScreens, $ as $$Layout } from '../chunks/loadScreens_CkCqdbH2.mjs';
4
4
  export { renderers } from '../renderers.mjs';
5
5
 
6
6
  const $$Index = createComponent(($$result, $$props, $$slots) => {
@@ -1,9 +1,132 @@
1
- import { e as createComponent, f as createAstro, k as renderComponent, r as renderTemplate, m as maybeRenderHead, h as addAttribute } from '../../chunks/astro/server_m7yT4wCr.mjs';
1
+ import { e as createComponent, f as createAstro, m as maybeRenderHead, h as addAttribute, r as renderTemplate, k as renderComponent } from '../../chunks/astro/server_m7yT4wCr.mjs';
2
2
  import 'piccolore';
3
- import { l as loadScreens, $ as $$Layout } from '../../chunks/loadScreens_JhK3F9tC.mjs';
3
+ import { l as loadScreens, $ as $$Layout } from '../../chunks/loadScreens_CkCqdbH2.mjs';
4
+ import 'clsx';
5
+ /* empty css */
4
6
  import { c as getApiDependencyCount } from '../../chunks/impactAnalysis_LvYEc57d.mjs';
5
7
  export { renderers } from '../../renderers.mjs';
6
8
 
9
+ const $$Astro$1 = createAstro();
10
+ const $$MockPreview = createComponent(($$result, $$props, $$slots) => {
11
+ const Astro2 = $$result.createAstro($$Astro$1, $$props, $$slots);
12
+ Astro2.self = $$MockPreview;
13
+ const { mock, screenId } = Astro2.props;
14
+ function getButtonStyle(variant) {
15
+ switch (variant) {
16
+ case "primary":
17
+ return "background: linear-gradient(135deg, #14b8a6 0%, #0d9488 100%); color: white;";
18
+ case "danger":
19
+ return "background: #ef4444; color: white;";
20
+ default:
21
+ return "background: #3d4660; color: #94a3b8;";
22
+ }
23
+ }
24
+ function getTextStyle(variant) {
25
+ switch (variant) {
26
+ case "heading":
27
+ return "font-size: 16px; font-weight: 700; color: #e2e8f0;";
28
+ case "subheading":
29
+ return "font-size: 14px; font-weight: 600; color: #cbd5e1;";
30
+ case "caption":
31
+ return "font-size: 11px; color: #64748b;";
32
+ default:
33
+ return "font-size: 13px; color: #94a3b8;";
34
+ }
35
+ }
36
+ function getAspectRatioPadding(ratio) {
37
+ if (!ratio) return "56.25%";
38
+ const [w, h] = ratio.split(":").map(Number);
39
+ if (!w || !h) return "56.25%";
40
+ return `${h / w * 100}%`;
41
+ }
42
+ return renderTemplate`${maybeRenderHead()}<div class="mock-preview" data-astro-cid-ewujvhfk> <div class="mock-header" data-astro-cid-ewujvhfk> <div class="mock-header-left" data-astro-cid-ewujvhfk> <svg class="mock-icon" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ewujvhfk> <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 1.5H8.25A2.25 2.25 0 006 3.75v16.5a2.25 2.25 0 002.25 2.25h7.5A2.25 2.25 0 0018 20.25V3.75a2.25 2.25 0 00-2.25-2.25H13.5m-3 0V3h3V1.5m-3 0h3m-3 18.75h3" data-astro-cid-ewujvhfk></path> </svg> <span data-astro-cid-ewujvhfk>Wireframe Mock</span> </div> <a${addAttribute(`/editor?screen=${screenId}`, "href")} class="edit-mock-link" data-astro-cid-ewujvhfk> <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" data-astro-cid-ewujvhfk> <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" data-astro-cid-ewujvhfk></path> </svg>
43
+ Edit Mock
44
+ </a> </div> <div class="mock-frame" data-astro-cid-ewujvhfk> ${mock.sections.map((section) => renderTemplate`<div class="mock-section" data-astro-cid-ewujvhfk> ${section.title && renderTemplate`<div class="section-title" data-astro-cid-ewujvhfk>${section.title}</div>`} <div${addAttribute(`section-elements ${section.layout === "horizontal" ? "horizontal" : "vertical"}`, "class")} data-astro-cid-ewujvhfk> ${section.elements.map((element) => {
45
+ if (element.type === "button") {
46
+ const buttonContent = renderTemplate`<div${addAttribute(`mock-button ${element.navigateTo ? "has-navigation" : ""}`, "class")}${addAttribute(getButtonStyle(element.variant), "style")} data-astro-cid-ewujvhfk> <span class="button-label" data-astro-cid-ewujvhfk>${element.label}</span> ${element.navigateTo && renderTemplate`<span class="button-navigate" data-astro-cid-ewujvhfk>
47
+ → ${element.navigateTo} </span>`} </div>`;
48
+ return element.navigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.navigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${buttonContent} </a>` : buttonContent;
49
+ }
50
+ if (element.type === "input") {
51
+ return renderTemplate`<div class="mock-input" data-astro-cid-ewujvhfk> <span class="input-label" data-astro-cid-ewujvhfk>${element.label}</span> <span class="input-placeholder" data-astro-cid-ewujvhfk> ${element.placeholder || "Enter value..."} </span> </div>`;
52
+ }
53
+ if (element.type === "link") {
54
+ const linkContent = renderTemplate`<div${addAttribute(`mock-link-card ${element.navigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <span class="link-label" data-astro-cid-ewujvhfk>${element.label}</span> ${element.navigateTo && renderTemplate`<span class="link-navigate" data-astro-cid-ewujvhfk>→ ${element.navigateTo}</span>`} </div>`;
55
+ return element.navigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.navigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${linkContent} </a>` : renderTemplate`<div class="mock-link" data-astro-cid-ewujvhfk>${element.label}</div>`;
56
+ }
57
+ if (element.type === "text") {
58
+ return renderTemplate`<div class="mock-text"${addAttribute(getTextStyle(element.variant), "style")} data-astro-cid-ewujvhfk> ${element.label} </div>`;
59
+ }
60
+ if (element.type === "image") {
61
+ return renderTemplate`<div class="mock-image"${addAttribute(`padding-bottom: ${getAspectRatioPadding(element.aspectRatio)}`, "style")} data-astro-cid-ewujvhfk> <div class="image-placeholder" data-astro-cid-ewujvhfk> <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" data-astro-cid-ewujvhfk> <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" data-astro-cid-ewujvhfk></path> </svg> <span data-astro-cid-ewujvhfk>${element.label}</span> </div> </div>`;
62
+ }
63
+ if (element.type === "list") {
64
+ const itemCount = element.itemCount || 3;
65
+ const listContent = renderTemplate`<div${addAttribute(`mock-list ${element.itemNavigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <div class="list-header" data-astro-cid-ewujvhfk>${element.label}</div> ${Array.from({ length: itemCount }).map((_, i) => renderTemplate`<div class="list-item"${addAttribute(
66
+ i < itemCount - 1 ? "border-bottom: 1px solid #1e2433;" : "",
67
+ "style"
68
+ )} data-astro-cid-ewujvhfk>
69
+ Item ${i + 1} </div>`)} ${element.itemNavigateTo && renderTemplate`<div class="list-footer" data-astro-cid-ewujvhfk>→ ${element.itemNavigateTo}</div>`} </div>`;
70
+ return element.itemNavigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.itemNavigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${listContent} </a>` : listContent;
71
+ }
72
+ if (element.type === "table") {
73
+ const columns = element.columns || [
74
+ "Column 1",
75
+ "Column 2",
76
+ "Column 3"
77
+ ];
78
+ const rowCount = element.rowCount || 3;
79
+ const tableContent = renderTemplate`<div${addAttribute(`mock-table ${element.rowNavigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <div class="table-header" data-astro-cid-ewujvhfk>${element.label}</div> <div class="table-content" data-astro-cid-ewujvhfk> <div class="table-row table-header-row" data-astro-cid-ewujvhfk> ${columns.map((col) => renderTemplate`<div class="table-cell" data-astro-cid-ewujvhfk>${col}</div>`)} </div> ${Array.from({ length: rowCount }).map((_, i) => renderTemplate`<div class="table-row" data-astro-cid-ewujvhfk> ${columns.map((_2, j) => renderTemplate`<div class="table-cell" data-astro-cid-ewujvhfk>
80
+ Data ${i + 1}-${j + 1} </div>`)} </div>`)} </div> ${element.rowNavigateTo && renderTemplate`<div class="table-footer" data-astro-cid-ewujvhfk>→ ${element.rowNavigateTo}</div>`} </div>`;
81
+ return element.rowNavigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.rowNavigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${tableContent} </a>` : tableContent;
82
+ }
83
+ return null;
84
+ })} </div> ${section.children && section.children.length > 0 && renderTemplate`<div class="child-sections" data-astro-cid-ewujvhfk> ${section.children.map((childSection) => renderTemplate`<div class="mock-section child-section" data-astro-cid-ewujvhfk> ${childSection.title && renderTemplate`<div class="section-title child-section-title" data-astro-cid-ewujvhfk> ${childSection.title} </div>`} <div${addAttribute(`section-elements ${childSection.layout === "horizontal" ? "horizontal" : "vertical"}`, "class")} data-astro-cid-ewujvhfk> ${childSection.elements.map((element) => {
85
+ if (element.type === "button") {
86
+ const buttonContent = renderTemplate`<div${addAttribute(`mock-button ${element.navigateTo ? "has-navigation" : ""}`, "class")}${addAttribute(getButtonStyle(element.variant), "style")} data-astro-cid-ewujvhfk> <span class="button-label" data-astro-cid-ewujvhfk>${element.label}</span> ${element.navigateTo && renderTemplate`<span class="button-navigate" data-astro-cid-ewujvhfk>
87
+ → ${element.navigateTo} </span>`} </div>`;
88
+ return element.navigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.navigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${buttonContent} </a>` : buttonContent;
89
+ }
90
+ if (element.type === "input") {
91
+ return renderTemplate`<div class="mock-input" data-astro-cid-ewujvhfk> <span class="input-label" data-astro-cid-ewujvhfk>${element.label}</span> <span class="input-placeholder" data-astro-cid-ewujvhfk> ${element.placeholder || "Enter value..."} </span> </div>`;
92
+ }
93
+ if (element.type === "link") {
94
+ const linkContent = renderTemplate`<div${addAttribute(`mock-link-card ${element.navigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <span class="link-label" data-astro-cid-ewujvhfk>${element.label}</span> ${element.navigateTo && renderTemplate`<span class="link-navigate" data-astro-cid-ewujvhfk>
95
+ → ${element.navigateTo} </span>`} </div>`;
96
+ return element.navigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.navigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${linkContent} </a>` : renderTemplate`<div class="mock-link" data-astro-cid-ewujvhfk>${element.label}</div>`;
97
+ }
98
+ if (element.type === "text") {
99
+ return renderTemplate`<div class="mock-text"${addAttribute(getTextStyle(element.variant), "style")} data-astro-cid-ewujvhfk> ${element.label} </div>`;
100
+ }
101
+ if (element.type === "image") {
102
+ return renderTemplate`<div class="mock-image"${addAttribute(`padding-bottom: ${getAspectRatioPadding(element.aspectRatio)}`, "style")} data-astro-cid-ewujvhfk> <div class="image-placeholder" data-astro-cid-ewujvhfk> <svg fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5" data-astro-cid-ewujvhfk> <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" data-astro-cid-ewujvhfk></path> </svg> <span data-astro-cid-ewujvhfk>${element.label}</span> </div> </div>`;
103
+ }
104
+ if (element.type === "list") {
105
+ const itemCount = element.itemCount || 3;
106
+ const listContent = renderTemplate`<div${addAttribute(`mock-list ${element.itemNavigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <div class="list-header" data-astro-cid-ewujvhfk>${element.label}</div> ${Array.from({ length: itemCount }).map((_, i) => renderTemplate`<div class="list-item"${addAttribute(
107
+ i < itemCount - 1 ? "border-bottom: 1px solid #1e2433;" : "",
108
+ "style"
109
+ )} data-astro-cid-ewujvhfk>
110
+ Item ${i + 1} </div>`)} ${element.itemNavigateTo && renderTemplate`<div class="list-footer" data-astro-cid-ewujvhfk>
111
+ → ${element.itemNavigateTo} </div>`} </div>`;
112
+ return element.itemNavigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.itemNavigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${listContent} </a>` : listContent;
113
+ }
114
+ if (element.type === "table") {
115
+ const columns = element.columns || [
116
+ "Column 1",
117
+ "Column 2",
118
+ "Column 3"
119
+ ];
120
+ const rowCount = element.rowCount || 3;
121
+ const tableContent = renderTemplate`<div${addAttribute(`mock-table ${element.rowNavigateTo ? "has-navigation" : ""}`, "class")} data-astro-cid-ewujvhfk> <div class="table-header" data-astro-cid-ewujvhfk>${element.label}</div> <div class="table-content" data-astro-cid-ewujvhfk> <div class="table-row table-header-row" data-astro-cid-ewujvhfk> ${columns.map((col) => renderTemplate`<div class="table-cell" data-astro-cid-ewujvhfk>${col}</div>`)} </div> ${Array.from({ length: rowCount }).map((_, i) => renderTemplate`<div class="table-row" data-astro-cid-ewujvhfk> ${columns.map((_2, j) => renderTemplate`<div class="table-cell" data-astro-cid-ewujvhfk>
122
+ Data ${i + 1}-${j + 1} </div>`)} </div>`)} </div> ${element.rowNavigateTo && renderTemplate`<div class="table-footer" data-astro-cid-ewujvhfk>
123
+ → ${element.rowNavigateTo} </div>`} </div>`;
124
+ return element.rowNavigateTo ? renderTemplate`<a${addAttribute(`/screen/${element.rowNavigateTo}`, "href")} class="element-link" data-astro-cid-ewujvhfk> ${tableContent} </a>` : tableContent;
125
+ }
126
+ return null;
127
+ })} </div> </div>`)} </div>`} </div>`)} </div> </div> `;
128
+ }, "/home/runner/work/screenbook/screenbook/packages/ui/src/components/MockPreview.astro", void 0);
129
+
7
130
  const $$Astro = createAstro();
8
131
  function getStaticPaths() {
9
132
  const screens = loadScreens();
@@ -29,7 +152,7 @@ Back to screens
29
152
  const count = apiCounts.get(dep) || 1;
30
153
  const otherCount = count - 1;
31
154
  return renderTemplate`<a${addAttribute(`/impact?api=${encodeURIComponent(dep)}`, "href")} class="dep-item dep-item-link"> <div class="dep-item-main"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M17.25 6.75L22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3l-4.5 16.5"></path> </svg> <span>${dep}</span> </div> <div class="dep-item-meta"> ${otherCount > 0 && renderTemplate`<span class="dep-count">+${otherCount} other${otherCount > 1 ? "s" : ""}</span>`} <svg class="dep-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z"></path> </svg> </div> </a>`;
32
- })} </div> </div>`} <!-- External Links --> ${screen.links && screen.links.length > 0 && renderTemplate`<div class="section"> <h2 class="section-title">Links</h2> <div class="dep-list"> ${screen.links.map((link) => renderTemplate`<a${addAttribute(link.url, "href")} target="_blank" rel="noopener noreferrer" class="dep-item"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"></path> </svg> ${link.label} </a>`)} </div> </div>`} </div> <div> <!-- Entry Points --> ${entryScreens.length > 0 && renderTemplate`<div class="sidebar-card"> <h3 class="sidebar-card-title"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"></path> </svg>
155
+ })} </div> </div>`} <!-- External Links --> ${screen.links && screen.links.length > 0 && renderTemplate`<div class="section"> <h2 class="section-title">Links</h2> <div class="dep-list"> ${screen.links.map((link) => renderTemplate`<a${addAttribute(link.url, "href")} target="_blank" rel="noopener noreferrer" class="dep-item"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 003 8.25v10.5A2.25 2.25 0 005.25 21h10.5A2.25 2.25 0 0018 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"></path> </svg> ${link.label} </a>`)} </div> </div>`} <!-- Mock Preview --> ${screen.mock && renderTemplate`<div class="section"> <h2 class="section-title">UI Wireframe</h2> ${renderComponent($$result2, "MockPreview", $$MockPreview, { "mock": screen.mock, "screenId": screen.id })} </div>`} </div> <div> <!-- Entry Points --> ${entryScreens.length > 0 && renderTemplate`<div class="sidebar-card"> <h3 class="sidebar-card-title"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3"></path> </svg>
33
156
  Entry Points
34
157
  </h3> <div class="screen-link-list"> ${entryScreens.map((s) => renderTemplate`<a${addAttribute(`/screen/${s.id}`, "href")} class="screen-link"> <div class="screen-link-info"> <span class="screen-link-title">${s.title}</span> <span class="screen-link-id">${s.id}</span> </div> <svg class="screen-link-arrow" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path> </svg> </a>`)} </div> </div>`} <!-- Next Screens --> ${nextScreens.length > 0 && renderTemplate`<div class="sidebar-card"> <h3 class="sidebar-card-title"> <svg aria-hidden="true" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5L21 12m0 0l-7.5 7.5M21 12H3"></path> </svg>
35
158
  Next Screens
@@ -1,3 +1,202 @@
1
- const renderers = [];
1
+ import React, { createElement } from 'react';
2
+ import ReactDOM from 'react-dom/server';
3
+
4
+ const contexts = /* @__PURE__ */ new WeakMap();
5
+ const ID_PREFIX = "r";
6
+ function getContext(rendererContextResult) {
7
+ if (contexts.has(rendererContextResult)) {
8
+ return contexts.get(rendererContextResult);
9
+ }
10
+ const ctx = {
11
+ currentIndex: 0,
12
+ get id() {
13
+ return ID_PREFIX + this.currentIndex.toString();
14
+ }
15
+ };
16
+ contexts.set(rendererContextResult, ctx);
17
+ return ctx;
18
+ }
19
+ function incrementId(rendererContextResult) {
20
+ const ctx = getContext(rendererContextResult);
21
+ const id = ctx.id;
22
+ ctx.currentIndex++;
23
+ return id;
24
+ }
25
+
26
+ const StaticHtml = ({
27
+ value,
28
+ name,
29
+ hydrate = true
30
+ }) => {
31
+ if (!value) return null;
32
+ const tagName = hydrate ? "astro-slot" : "astro-static-slot";
33
+ return createElement(tagName, {
34
+ name,
35
+ suppressHydrationWarning: true,
36
+ dangerouslySetInnerHTML: { __html: value }
37
+ });
38
+ };
39
+ StaticHtml.shouldComponentUpdate = () => false;
40
+ var static_html_default = StaticHtml;
41
+
42
+ const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
43
+ const reactTypeof = Symbol.for("react.element");
44
+ const reactTransitionalTypeof = Symbol.for("react.transitional.element");
45
+ async function check(Component, props, children) {
46
+ if (typeof Component === "object") {
47
+ return Component["$$typeof"].toString().slice("Symbol(".length).startsWith("react");
48
+ }
49
+ if (typeof Component !== "function") return false;
50
+ if (Component.name === "QwikComponent") return false;
51
+ if (typeof Component === "function" && Component["$$typeof"] === Symbol.for("react.forward_ref"))
52
+ return false;
53
+ if (Component.prototype != null && typeof Component.prototype.render === "function") {
54
+ return React.Component.isPrototypeOf(Component) || React.PureComponent.isPrototypeOf(Component);
55
+ }
56
+ let isReactComponent = false;
57
+ function Tester(...args) {
58
+ try {
59
+ const vnode = Component(...args);
60
+ if (vnode && (vnode["$$typeof"] === reactTypeof || vnode["$$typeof"] === reactTransitionalTypeof)) {
61
+ isReactComponent = true;
62
+ }
63
+ } catch {
64
+ }
65
+ return React.createElement("div");
66
+ }
67
+ await renderToStaticMarkup.call(this, Tester, props, children);
68
+ return isReactComponent;
69
+ }
70
+ async function getNodeWritable() {
71
+ let nodeStreamBuiltinModuleName = "node:stream";
72
+ let { Writable } = await import(
73
+ /* @vite-ignore */
74
+ nodeStreamBuiltinModuleName
75
+ );
76
+ return Writable;
77
+ }
78
+ function needsHydration(metadata) {
79
+ return metadata?.astroStaticSlot ? !!metadata.hydrate : true;
80
+ }
81
+ async function renderToStaticMarkup(Component, props, { default: children, ...slotted }, metadata) {
82
+ let prefix;
83
+ if (this && this.result) {
84
+ prefix = incrementId(this.result);
85
+ }
86
+ const attrs = { prefix };
87
+ delete props["class"];
88
+ const slots = {};
89
+ for (const [key, value] of Object.entries(slotted)) {
90
+ const name = slotName(key);
91
+ slots[name] = React.createElement(static_html_default, {
92
+ hydrate: needsHydration(metadata),
93
+ value,
94
+ name
95
+ });
96
+ }
97
+ const newProps = {
98
+ ...props,
99
+ ...slots
100
+ };
101
+ const newChildren = children ?? props.children;
102
+ if (newChildren != null) {
103
+ newProps.children = React.createElement(static_html_default, {
104
+ hydrate: needsHydration(metadata),
105
+ value: newChildren
106
+ });
107
+ }
108
+ const formState = this ? await getFormState(this) : void 0;
109
+ if (formState) {
110
+ attrs["data-action-result"] = JSON.stringify(formState[0]);
111
+ attrs["data-action-key"] = formState[1];
112
+ attrs["data-action-name"] = formState[2];
113
+ }
114
+ const vnode = React.createElement(Component, newProps);
115
+ const renderOptions = {
116
+ identifierPrefix: prefix,
117
+ formState
118
+ };
119
+ let html;
120
+ if ("renderToReadableStream" in ReactDOM) {
121
+ html = await renderToReadableStreamAsync(vnode, renderOptions);
122
+ } else {
123
+ html = await renderToPipeableStreamAsync(vnode, renderOptions);
124
+ }
125
+ return { html, attrs };
126
+ }
127
+ async function getFormState({
128
+ result
129
+ }) {
130
+ const { request, actionResult } = result;
131
+ if (!actionResult) return void 0;
132
+ if (!isFormRequest(request.headers.get("content-type"))) return void 0;
133
+ const { searchParams } = new URL(request.url);
134
+ const formData = await request.clone().formData();
135
+ const actionKey = formData.get("$ACTION_KEY")?.toString();
136
+ const actionName = searchParams.get("_action");
137
+ if (!actionKey || !actionName) return void 0;
138
+ return [actionResult, actionKey, actionName];
139
+ }
140
+ async function renderToPipeableStreamAsync(vnode, options) {
141
+ const Writable = await getNodeWritable();
142
+ let html = "";
143
+ return new Promise((resolve, reject) => {
144
+ let error = void 0;
145
+ let stream = ReactDOM.renderToPipeableStream(vnode, {
146
+ ...options,
147
+ onError(err) {
148
+ error = err;
149
+ reject(error);
150
+ },
151
+ onAllReady() {
152
+ stream.pipe(
153
+ new Writable({
154
+ write(chunk, _encoding, callback) {
155
+ html += chunk.toString("utf-8");
156
+ callback();
157
+ },
158
+ destroy() {
159
+ resolve(html);
160
+ }
161
+ })
162
+ );
163
+ }
164
+ });
165
+ });
166
+ }
167
+ async function readResult(stream) {
168
+ const reader = stream.getReader();
169
+ let result = "";
170
+ const decoder = new TextDecoder("utf-8");
171
+ while (true) {
172
+ const { done, value } = await reader.read();
173
+ if (done) {
174
+ if (value) {
175
+ result += decoder.decode(value);
176
+ } else {
177
+ decoder.decode(new Uint8Array());
178
+ }
179
+ return result;
180
+ }
181
+ result += decoder.decode(value, { stream: true });
182
+ }
183
+ }
184
+ async function renderToReadableStreamAsync(vnode, options) {
185
+ return await readResult(await ReactDOM.renderToReadableStream(vnode, options));
186
+ }
187
+ const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"];
188
+ function isFormRequest(contentType) {
189
+ const type = contentType?.split(";")[0].toLowerCase();
190
+ return formContentTypes.some((t) => type === t);
191
+ }
192
+ const renderer = {
193
+ name: "@astrojs/react",
194
+ check,
195
+ renderToStaticMarkup,
196
+ supportsAstroStaticSlot: true
197
+ };
198
+ var server_default = renderer;
199
+
200
+ const renderers = [Object.assign({"name":"@astrojs/react","clientEntrypoint":"@astrojs/react/client.js","serverEntrypoint":"@astrojs/react/server.js"}, { ssr: server_default }),];
2
201
 
3
202
  export { renderers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@screenbook/ui",
3
- "version": "0.1.0",
3
+ "version": "1.1.0",
4
4
  "description": "UI for Screenbook - screen catalog and navigation graph viewer",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -12,10 +12,13 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@astrojs/node": "^9.5.1",
15
+ "@astrojs/react": "^4.4.2",
15
16
  "@screenbook/core": "workspace:*",
16
17
  "@tailwindcss/vite": "^4.0.0",
17
18
  "astro": "^5.16.0",
18
19
  "mermaid": "^11.4.0",
20
+ "react": "^19.2.3",
21
+ "react-dom": "^19.2.3",
19
22
  "tailwindcss": "^4.0.0"
20
23
  },
21
24
  "keywords": [
@@ -36,7 +39,10 @@
36
39
  "url": "https://github.com/wadakatu/screenbook/issues"
37
40
  },
38
41
  "devDependencies": {
42
+ "@types/react": "^19.2.7",
43
+ "@types/react-dom": "^19.2.3",
39
44
  "prettier": "^3.7.4",
40
- "prettier-plugin-astro": "^0.14.1"
45
+ "prettier-plugin-astro": "^0.14.1",
46
+ "ts-morph": "^27.0.2"
41
47
  }
42
48
  }