@storyshelf/app 0.6.2 → 0.8.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 (429) hide show
  1. package/README.md +42 -4
  2. package/dist/app-types.d.mts +2 -6
  3. package/dist/asset-manifest.mjs +14 -7
  4. package/dist/asset-manifest.mjs.map +1 -1
  5. package/dist/assets/{htmx.min.js → htmx.mjs} +9 -1
  6. package/dist/assets/htmx.mjs.map +1 -0
  7. package/dist/assets/mark.mjs +9 -0
  8. package/dist/assets/mark.mjs.map +1 -0
  9. package/dist/boot-tasks.mjs +79 -0
  10. package/dist/boot-tasks.mjs.map +1 -0
  11. package/dist/build-state-flags.mjs +17 -0
  12. package/dist/build-state-flags.mjs.map +1 -0
  13. package/dist/build-state-setup.mjs +74 -0
  14. package/dist/build-state-setup.mjs.map +1 -0
  15. package/dist/capture-alerts.mjs +45 -0
  16. package/dist/capture-alerts.mjs.map +1 -0
  17. package/dist/capture-process.mjs +58 -0
  18. package/dist/capture-process.mjs.map +1 -0
  19. package/dist/capture-setup.mjs +96 -119
  20. package/dist/capture-setup.mjs.map +1 -1
  21. package/dist/connections.mjs +33 -0
  22. package/dist/connections.mjs.map +1 -0
  23. package/dist/consumer-setup.mjs +57 -0
  24. package/dist/consumer-setup.mjs.map +1 -0
  25. package/dist/credential-keys.mjs +1 -2
  26. package/dist/credentials.mjs +1 -2
  27. package/dist/git-status.mjs +45 -0
  28. package/dist/git-status.mjs.map +1 -0
  29. package/dist/hidden-data.mjs +23 -0
  30. package/dist/hidden-data.mjs.map +1 -0
  31. package/dist/index.d.mts +3 -5
  32. package/dist/index.mjs +204 -127
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/insights/budget.mjs +48 -0
  35. package/dist/insights/budget.mjs.map +1 -0
  36. package/dist/insights/deps.mjs +20 -0
  37. package/dist/insights/deps.mjs.map +1 -0
  38. package/dist/insights/errors.mjs +21 -0
  39. package/dist/insights/errors.mjs.map +1 -0
  40. package/dist/insights/health-panel.mjs +39 -0
  41. package/dist/insights/health-panel.mjs.map +1 -0
  42. package/dist/insights/job.mjs +102 -0
  43. package/dist/insights/job.mjs.map +1 -0
  44. package/dist/insights/load-health.mjs +58 -0
  45. package/dist/insights/load-health.mjs.map +1 -0
  46. package/dist/insights/load-triage.mjs +97 -0
  47. package/dist/insights/load-triage.mjs.map +1 -0
  48. package/dist/insights/panel.mjs +27 -0
  49. package/dist/insights/panel.mjs.map +1 -0
  50. package/dist/insights/request.mjs +112 -0
  51. package/dist/insights/request.mjs.map +1 -0
  52. package/dist/insights/stale.mjs +20 -0
  53. package/dist/insights/stale.mjs.map +1 -0
  54. package/dist/insights/usage-report.mjs +59 -0
  55. package/dist/insights/usage-report.mjs.map +1 -0
  56. package/dist/insights/view.mjs +47 -0
  57. package/dist/insights/view.mjs.map +1 -0
  58. package/dist/job-canceller.mjs +13 -0
  59. package/dist/job-canceller.mjs.map +1 -0
  60. package/dist/job-queue.mjs +50 -0
  61. package/dist/job-queue.mjs.map +1 -0
  62. package/dist/jobs-setup.mjs +131 -0
  63. package/dist/jobs-setup.mjs.map +1 -0
  64. package/dist/lifecycle.mjs +93 -22
  65. package/dist/lifecycle.mjs.map +1 -1
  66. package/dist/middleware/auth-gate.mjs +5 -4
  67. package/dist/middleware/auth-gate.mjs.map +1 -1
  68. package/dist/middleware/csrf.mjs +1 -2
  69. package/dist/middleware/rate-limit.mjs +42 -35
  70. package/dist/middleware/rate-limit.mjs.map +1 -1
  71. package/dist/middleware/request-log.mjs +4 -4
  72. package/dist/middleware/request-log.mjs.map +1 -1
  73. package/dist/middleware/require-review.mjs +50 -0
  74. package/dist/middleware/require-review.mjs.map +1 -0
  75. package/dist/middleware/require-testing.mjs +40 -0
  76. package/dist/middleware/require-testing.mjs.map +1 -0
  77. package/dist/middleware/server-timing.mjs +1 -2
  78. package/dist/middleware/setup-gate.mjs +1 -2
  79. package/dist/middleware/setup-gate.mjs.map +1 -1
  80. package/dist/middleware/store-scope.mjs +13 -4
  81. package/dist/middleware/store-scope.mjs.map +1 -1
  82. package/dist/notifications-pause.mjs +32 -0
  83. package/dist/notifications-pause.mjs.map +1 -0
  84. package/dist/notify.d.mts +3 -4
  85. package/dist/notify.mjs +79 -41
  86. package/dist/notify.mjs.map +1 -1
  87. package/dist/pages/a11y-violations.mjs +115 -0
  88. package/dist/pages/a11y-violations.mjs.map +1 -0
  89. package/dist/pages/admin-ai.mjs +77 -0
  90. package/dist/pages/admin-ai.mjs.map +1 -0
  91. package/dist/pages/admin-system-origin.mjs +132 -0
  92. package/dist/pages/admin-system-origin.mjs.map +1 -0
  93. package/dist/pages/admin-system-targets.mjs +52 -0
  94. package/dist/pages/admin-system-targets.mjs.map +1 -0
  95. package/dist/pages/admin-system.mjs +64 -15
  96. package/dist/pages/admin-system.mjs.map +1 -1
  97. package/dist/pages/build-detail.mjs +105 -78
  98. package/dist/pages/build-detail.mjs.map +1 -1
  99. package/dist/pages/build-diff-actions.mjs +88 -35
  100. package/dist/pages/build-diff-actions.mjs.map +1 -1
  101. package/dist/pages/build-diff-comments.mjs +17 -16
  102. package/dist/pages/build-diff-comments.mjs.map +1 -1
  103. package/dist/pages/build-diff-default.mjs +53 -0
  104. package/dist/pages/build-diff-default.mjs.map +1 -0
  105. package/dist/pages/build-diff-environment.mjs +81 -0
  106. package/dist/pages/build-diff-environment.mjs.map +1 -0
  107. package/dist/pages/build-diff-header.mjs +23 -6
  108. package/dist/pages/build-diff-header.mjs.map +1 -1
  109. package/dist/pages/build-diff-insight.mjs +112 -0
  110. package/dist/pages/build-diff-insight.mjs.map +1 -0
  111. package/dist/pages/build-diff-model.mjs +74 -12
  112. package/dist/pages/build-diff-model.mjs.map +1 -1
  113. package/dist/pages/build-diff-nav.mjs +29 -14
  114. package/dist/pages/build-diff-nav.mjs.map +1 -1
  115. package/dist/pages/build-diff-reference.mjs +84 -0
  116. package/dist/pages/build-diff-reference.mjs.map +1 -0
  117. package/dist/pages/build-diff-shortcuts.mjs +6 -3
  118. package/dist/pages/build-diff-shortcuts.mjs.map +1 -1
  119. package/dist/pages/build-diff-stale.mjs +1 -2
  120. package/dist/pages/build-diff-usage.mjs +62 -0
  121. package/dist/pages/build-diff-usage.mjs.map +1 -0
  122. package/dist/pages/build-diff-viewer.mjs +97 -14
  123. package/dist/pages/build-diff-viewer.mjs.map +1 -1
  124. package/dist/pages/build-diff.mjs +37 -22
  125. package/dist/pages/build-diff.mjs.map +1 -1
  126. package/dist/pages/build-tests.mjs +73 -0
  127. package/dist/pages/build-tests.mjs.map +1 -0
  128. package/dist/pages/component-detail.mjs +248 -0
  129. package/dist/pages/component-detail.mjs.map +1 -0
  130. package/dist/pages/component-stories.mjs +167 -0
  131. package/dist/pages/component-stories.mjs.map +1 -0
  132. package/dist/pages/compute-jobs.mjs +14 -28
  133. package/dist/pages/compute-jobs.mjs.map +1 -1
  134. package/dist/pages/design-links.mjs +181 -0
  135. package/dist/pages/design-links.mjs.map +1 -0
  136. package/dist/pages/environment-change.mjs +52 -0
  137. package/dist/pages/environment-change.mjs.map +1 -0
  138. package/dist/pages/health-panel.mjs +125 -0
  139. package/dist/pages/health-panel.mjs.map +1 -0
  140. package/dist/pages/invite.mjs +1 -2
  141. package/dist/pages/label-detail.mjs +1 -2
  142. package/dist/pages/library-grid.mjs +104 -0
  143. package/dist/pages/library-grid.mjs.map +1 -0
  144. package/dist/pages/library-model.mjs +46 -0
  145. package/dist/pages/library-model.mjs.map +1 -0
  146. package/dist/pages/library-snapshots.mjs +129 -0
  147. package/dist/pages/library-snapshots.mjs.map +1 -0
  148. package/dist/pages/library.mjs +113 -220
  149. package/dist/pages/library.mjs.map +1 -1
  150. package/dist/pages/login.mjs +1 -2
  151. package/dist/pages/notifications-paused.mjs +21 -0
  152. package/dist/pages/notifications-paused.mjs.map +1 -0
  153. package/dist/pages/passkey-ceremony.mjs +1 -2
  154. package/dist/pages/profile.mjs +54 -50
  155. package/dist/pages/profile.mjs.map +1 -1
  156. package/dist/pages/project-builds-table.mjs +3 -4
  157. package/dist/pages/project-builds-table.mjs.map +1 -1
  158. package/dist/pages/project-builds.mjs +52 -23
  159. package/dist/pages/project-builds.mjs.map +1 -1
  160. package/dist/pages/project-create.mjs +1 -2
  161. package/dist/pages/project-settings.mjs +52 -14
  162. package/dist/pages/project-settings.mjs.map +1 -1
  163. package/dist/pages/projects-card.mjs +15 -3
  164. package/dist/pages/projects-card.mjs.map +1 -1
  165. package/dist/pages/projects.mjs +7 -4
  166. package/dist/pages/projects.mjs.map +1 -1
  167. package/dist/pages/review-changeset.mjs +115 -0
  168. package/dist/pages/review-changeset.mjs.map +1 -0
  169. package/dist/pages/review-comments.mjs +102 -0
  170. package/dist/pages/review-comments.mjs.map +1 -0
  171. package/dist/pages/review-verdict.mjs +101 -0
  172. package/dist/pages/review-verdict.mjs.map +1 -0
  173. package/dist/pages/root.mjs +1 -2
  174. package/dist/pages/settings-ai.mjs +68 -0
  175. package/dist/pages/settings-ai.mjs.map +1 -0
  176. package/dist/pages/settings-capture.mjs +123 -0
  177. package/dist/pages/settings-capture.mjs.map +1 -0
  178. package/dist/pages/settings-design-credential.mjs +98 -0
  179. package/dist/pages/settings-design-credential.mjs.map +1 -0
  180. package/dist/pages/settings-design-links.mjs +178 -0
  181. package/dist/pages/settings-design-links.mjs.map +1 -0
  182. package/dist/pages/settings-design.mjs +47 -0
  183. package/dist/pages/settings-design.mjs.map +1 -0
  184. package/dist/pages/settings-general.mjs +47 -23
  185. package/dist/pages/settings-general.mjs.map +1 -1
  186. package/dist/pages/settings-labels.mjs +44 -4
  187. package/dist/pages/settings-labels.mjs.map +1 -1
  188. package/dist/pages/settings-links.mjs +111 -0
  189. package/dist/pages/settings-links.mjs.map +1 -0
  190. package/dist/pages/settings-members.mjs +1 -2
  191. package/dist/pages/settings-notifications-git.mjs +127 -0
  192. package/dist/pages/settings-notifications-git.mjs.map +1 -0
  193. package/dist/pages/settings-notifications.mjs +80 -44
  194. package/dist/pages/settings-notifications.mjs.map +1 -1
  195. package/dist/pages/settings-tests.mjs +34 -4
  196. package/dist/pages/settings-tests.mjs.map +1 -1
  197. package/dist/pages/settings-tokens.mjs +1 -2
  198. package/dist/pages/settings-webhooks.mjs +1 -2
  199. package/dist/pages/storybook.mjs +1 -2
  200. package/dist/pages/target-choices.mjs +38 -0
  201. package/dist/pages/target-choices.mjs.map +1 -0
  202. package/dist/publish-setup.mjs +88 -0
  203. package/dist/publish-setup.mjs.map +1 -0
  204. package/dist/retention-timer.mjs +12 -12
  205. package/dist/retention-timer.mjs.map +1 -1
  206. package/dist/review-events.mjs +47 -0
  207. package/dist/review-events.mjs.map +1 -0
  208. package/dist/routers/admin-pages.mjs +46 -5
  209. package/dist/routers/admin-pages.mjs.map +1 -1
  210. package/dist/routers/admin-public-origin.mjs +92 -0
  211. package/dist/routers/admin-public-origin.mjs.map +1 -0
  212. package/dist/routers/admin.mjs +8 -4
  213. package/dist/routers/admin.mjs.map +1 -1
  214. package/dist/routers/assets.mjs +10 -4
  215. package/dist/routers/assets.mjs.map +1 -1
  216. package/dist/routers/attempts.mjs +1 -2
  217. package/dist/routers/auth-sync.mjs +1 -2
  218. package/dist/routers/auth.mjs +2 -3
  219. package/dist/routers/baseline-guard.mjs +4 -5
  220. package/dist/routers/baseline-guard.mjs.map +1 -1
  221. package/dist/routers/baseline-reference.mjs +72 -0
  222. package/dist/routers/baseline-reference.mjs.map +1 -0
  223. package/dist/routers/baselines.handlers.mjs +63 -0
  224. package/dist/routers/baselines.handlers.mjs.map +1 -0
  225. package/dist/routers/baselines.mjs +124 -0
  226. package/dist/routers/baselines.mjs.map +1 -0
  227. package/dist/routers/build-cancel.mjs +67 -0
  228. package/dist/routers/build-cancel.mjs.map +1 -0
  229. package/dist/routers/build-changeset.mjs +69 -0
  230. package/dist/routers/build-changeset.mjs.map +1 -0
  231. package/dist/routers/build-reviews.handlers.mjs +85 -0
  232. package/dist/routers/build-reviews.handlers.mjs.map +1 -0
  233. package/dist/routers/build-reviews.mjs +73 -0
  234. package/dist/routers/build-reviews.mjs.map +1 -0
  235. package/dist/routers/builds.handlers.mjs +65 -60
  236. package/dist/routers/builds.handlers.mjs.map +1 -1
  237. package/dist/routers/builds.mjs +77 -19
  238. package/dist/routers/builds.mjs.map +1 -1
  239. package/dist/routers/capture-cache.mjs +29 -0
  240. package/dist/routers/capture-cache.mjs.map +1 -0
  241. package/dist/routers/capture-config.mjs +34 -0
  242. package/dist/routers/capture-config.mjs.map +1 -0
  243. package/dist/routers/comments.mjs +42 -17
  244. package/dist/routers/comments.mjs.map +1 -1
  245. package/dist/routers/comparison-image.mjs +29 -0
  246. package/dist/routers/comparison-image.mjs.map +1 -0
  247. package/dist/routers/component-catalog.handlers.mjs +70 -0
  248. package/dist/routers/component-catalog.handlers.mjs.map +1 -0
  249. package/dist/routers/component.handlers.mjs +120 -0
  250. package/dist/routers/component.handlers.mjs.map +1 -0
  251. package/dist/routers/connections.mjs +117 -0
  252. package/dist/routers/connections.mjs.map +1 -0
  253. package/dist/routers/design-connect.handlers.mjs +43 -0
  254. package/dist/routers/design-connect.handlers.mjs.map +1 -0
  255. package/dist/routers/design.handlers.mjs +113 -0
  256. package/dist/routers/design.handlers.mjs.map +1 -0
  257. package/dist/routers/flash.mjs +1 -2
  258. package/dist/routers/health-report.mjs +3 -5
  259. package/dist/routers/health-report.mjs.map +1 -1
  260. package/dist/routers/health.mjs +5 -5
  261. package/dist/routers/health.mjs.map +1 -1
  262. package/dist/routers/helpers.mjs +20 -5
  263. package/dist/routers/helpers.mjs.map +1 -1
  264. package/dist/routers/htmx.mjs +1 -2
  265. package/dist/routers/insights-ui.mjs +63 -0
  266. package/dist/routers/insights-ui.mjs.map +1 -0
  267. package/dist/routers/insights.handlers.mjs +44 -0
  268. package/dist/routers/insights.handlers.mjs.map +1 -0
  269. package/dist/routers/insights.mjs +188 -0
  270. package/dist/routers/insights.mjs.map +1 -0
  271. package/dist/routers/labels.mjs +1 -2
  272. package/dist/routers/links.handlers.mjs +79 -0
  273. package/dist/routers/links.handlers.mjs.map +1 -0
  274. package/dist/routers/links.mjs +138 -0
  275. package/dist/routers/links.mjs.map +1 -0
  276. package/dist/routers/media.mjs +30 -7
  277. package/dist/routers/media.mjs.map +1 -1
  278. package/dist/routers/members.mjs +3 -3
  279. package/dist/routers/members.mjs.map +1 -1
  280. package/dist/routers/notification-channels.mjs +18 -25
  281. package/dist/routers/notification-channels.mjs.map +1 -1
  282. package/dist/routers/notification-subscriptions.mjs +1 -2
  283. package/dist/routers/oauth-state.mjs +44 -0
  284. package/dist/routers/oauth-state.mjs.map +1 -0
  285. package/dist/routers/preview-base.mjs +37 -0
  286. package/dist/routers/preview-base.mjs.map +1 -0
  287. package/dist/routers/preview-token.mjs +50 -0
  288. package/dist/routers/preview-token.mjs.map +1 -0
  289. package/dist/routers/profile.mjs +4 -3
  290. package/dist/routers/profile.mjs.map +1 -1
  291. package/dist/routers/projects.mjs +18 -3
  292. package/dist/routers/projects.mjs.map +1 -1
  293. package/dist/routers/publish-upload.mjs +85 -0
  294. package/dist/routers/publish-upload.mjs.map +1 -0
  295. package/dist/routers/published-access.mjs +51 -0
  296. package/dist/routers/published-access.mjs.map +1 -0
  297. package/dist/routers/published-compression.mjs +109 -0
  298. package/dist/routers/published-compression.mjs.map +1 -0
  299. package/dist/routers/published-files.mjs +69 -0
  300. package/dist/routers/published-files.mjs.map +1 -0
  301. package/dist/routers/review-forms.mjs +71 -0
  302. package/dist/routers/review-forms.mjs.map +1 -0
  303. package/dist/routers/review-next.mjs +1 -2
  304. package/dist/routers/review-section.handlers.mjs +84 -0
  305. package/dist/routers/review-section.handlers.mjs.map +1 -0
  306. package/dist/routers/review-switch-off.mjs +28 -0
  307. package/dist/routers/review-switch-off.mjs.map +1 -0
  308. package/dist/routers/schemas.mjs +141 -24
  309. package/dist/routers/schemas.mjs.map +1 -1
  310. package/dist/routers/scoped-models.mjs +21 -0
  311. package/dist/routers/scoped-models.mjs.map +1 -0
  312. package/dist/routers/settings-ai.mjs +34 -0
  313. package/dist/routers/settings-ai.mjs.map +1 -0
  314. package/dist/routers/settings-capture.mjs +76 -0
  315. package/dist/routers/settings-capture.mjs.map +1 -0
  316. package/dist/routers/settings-design.mjs +102 -0
  317. package/dist/routers/settings-design.mjs.map +1 -0
  318. package/dist/routers/settings-general.mjs +56 -12
  319. package/dist/routers/settings-general.mjs.map +1 -1
  320. package/dist/routers/settings-git-channel.mjs +76 -0
  321. package/dist/routers/settings-git-channel.mjs.map +1 -0
  322. package/dist/routers/settings-labels.mjs +28 -3
  323. package/dist/routers/settings-labels.mjs.map +1 -1
  324. package/dist/routers/settings-links.mjs +62 -0
  325. package/dist/routers/settings-links.mjs.map +1 -0
  326. package/dist/routers/settings-members.mjs +5 -9
  327. package/dist/routers/settings-members.mjs.map +1 -1
  328. package/dist/routers/settings-notifications.mjs +16 -12
  329. package/dist/routers/settings-notifications.mjs.map +1 -1
  330. package/dist/routers/settings-tokens.mjs +3 -7
  331. package/dist/routers/settings-tokens.mjs.map +1 -1
  332. package/dist/routers/settings-webhooks.mjs +8 -26
  333. package/dist/routers/settings-webhooks.mjs.map +1 -1
  334. package/dist/routers/settings.handlers.mjs +108 -28
  335. package/dist/routers/settings.handlers.mjs.map +1 -1
  336. package/dist/routers/settings.mjs +17 -6
  337. package/dist/routers/settings.mjs.map +1 -1
  338. package/dist/routers/signed-storybook.mjs +55 -0
  339. package/dist/routers/signed-storybook.mjs.map +1 -0
  340. package/dist/routers/snapshot-groups.mjs +62 -0
  341. package/dist/routers/snapshot-groups.mjs.map +1 -0
  342. package/dist/routers/snapshots.mjs +104 -7
  343. package/dist/routers/snapshots.mjs.map +1 -1
  344. package/dist/routers/storybook.mjs +57 -104
  345. package/dist/routers/storybook.mjs.map +1 -1
  346. package/dist/routers/tokens.mjs +3 -7
  347. package/dist/routers/tokens.mjs.map +1 -1
  348. package/dist/routers/ui.mjs +38 -7
  349. package/dist/routers/ui.mjs.map +1 -1
  350. package/dist/routers/webhooks.mjs +6 -13
  351. package/dist/routers/webhooks.mjs.map +1 -1
  352. package/dist/routers/well-known.mjs +12 -6
  353. package/dist/routers/well-known.mjs.map +1 -1
  354. package/dist/routes/api-routes.mjs +92 -0
  355. package/dist/routes/api-routes.mjs.map +1 -0
  356. package/dist/routes/classification.mjs +37 -0
  357. package/dist/routes/classification.mjs.map +1 -0
  358. package/dist/routes/openapi-classes.mjs +21 -0
  359. package/dist/routes/openapi-classes.mjs.map +1 -0
  360. package/dist/routes/page-routes.mjs +103 -0
  361. package/dist/routes/page-routes.mjs.map +1 -0
  362. package/dist/runtime.mjs +19 -15
  363. package/dist/runtime.mjs.map +1 -1
  364. package/dist/serverless.mjs +4 -0
  365. package/dist/store.mjs +20 -3
  366. package/dist/store.mjs.map +1 -1
  367. package/dist/targets.mjs +45 -0
  368. package/dist/targets.mjs.map +1 -0
  369. package/dist/ui/avatar.mjs +1 -2
  370. package/dist/ui/buttons.mjs +17 -5
  371. package/dist/ui/buttons.mjs.map +1 -1
  372. package/dist/ui/code-block.mjs +1 -2
  373. package/dist/ui/compare-stage.mjs +86 -54
  374. package/dist/ui/compare-stage.mjs.map +1 -1
  375. package/dist/ui/csrf-field.mjs +1 -2
  376. package/dist/ui/css.mjs +1 -2
  377. package/dist/ui/design-reference.mjs +96 -0
  378. package/dist/ui/design-reference.mjs.map +1 -0
  379. package/dist/ui/document.mjs +2 -4
  380. package/dist/ui/document.mjs.map +1 -1
  381. package/dist/ui/dropdown.mjs +1 -2
  382. package/dist/ui/feedback.mjs +1 -2
  383. package/dist/ui/filter-input.mjs +1 -2
  384. package/dist/ui/forms.mjs +7 -7
  385. package/dist/ui/forms.mjs.map +1 -1
  386. package/dist/ui/icons/icon.mjs +1 -2
  387. package/dist/ui/icons/paths.mjs +2 -2
  388. package/dist/ui/icons/paths.mjs.map +1 -1
  389. package/dist/ui/icons/sprite.mjs +1 -2
  390. package/dist/ui/kbd.mjs +1 -2
  391. package/dist/ui/layout.mjs +1 -2
  392. package/dist/ui/preview-embed.mjs +81 -0
  393. package/dist/ui/preview-embed.mjs.map +1 -0
  394. package/dist/ui/progress.mjs +1 -2
  395. package/dist/ui/segmented.mjs +1 -2
  396. package/dist/ui/shell/account.mjs +1 -2
  397. package/dist/ui/shell/bare.mjs +1 -2
  398. package/dist/ui/shell/boot-script.mjs +1 -2
  399. package/dist/ui/shell/client-script.mjs +86 -2
  400. package/dist/ui/shell/client-script.mjs.map +1 -1
  401. package/dist/ui/shell/nav.mjs +13 -10
  402. package/dist/ui/shell/nav.mjs.map +1 -1
  403. package/dist/ui/shell/review-script.mjs +25 -3
  404. package/dist/ui/shell/review-script.mjs.map +1 -1
  405. package/dist/ui/shell/sidebar.mjs +3 -4
  406. package/dist/ui/shell/sidebar.mjs.map +1 -1
  407. package/dist/ui/shell/topbar.mjs +1 -2
  408. package/dist/ui/stacks.mjs +1 -2
  409. package/dist/ui/styles/base.mjs +1 -2
  410. package/dist/ui/styles/behavior.mjs +1 -2
  411. package/dist/ui/styles/review-layout.mjs +1 -2
  412. package/dist/ui/styles/review.mjs +1 -2
  413. package/dist/ui/styles/tokens.mjs +1 -2
  414. package/dist/ui/styles.mjs +1 -2
  415. package/dist/ui/subnav.mjs +1 -2
  416. package/dist/ui/table.mjs +1 -2
  417. package/dist/ui/theme.mjs +1 -2
  418. package/dist/ui/thumbnail.mjs +1 -2
  419. package/dist/ui/time.mjs +1 -2
  420. package/package.json +14 -12
  421. package/dist/asset-paths.mjs +0 -23
  422. package/dist/asset-paths.mjs.map +0 -1
  423. package/dist/assets/mark.svg +0 -1
  424. package/dist/pages/settings-status.mjs +0 -137
  425. package/dist/pages/settings-status.mjs.map +0 -1
  426. package/dist/routers/settings-status.mjs +0 -77
  427. package/dist/routers/settings-status.mjs.map +0 -1
  428. package/dist/routers/status-configs.mjs +0 -108
  429. package/dist/routers/status-configs.mjs.map +0 -1
@@ -0,0 +1,104 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { getStore } from "../store.mjs";
5
+ import { Button } from "../ui/buttons.mjs";
6
+ import { Badge, Meta } from "../ui/feedback.mjs";
7
+ import { Card, CardSection, SectionTitle } from "../ui/layout.mjs";
8
+ import { HStack, VStack } from "../ui/stacks.mjs";
9
+ import { SnapshotCards } from "./library-snapshots.mjs";
10
+ import { jsx, jsxs } from "hono/jsx/jsx-runtime";
11
+ import { createUrlBuilder } from "@storyshelf/core/urls";
12
+ // src/pages/library-grid.tsx
13
+ /** The component cards of a build; `layer` is present only with `testing` and captured snapshots. */
14
+ function LibraryGrid(props) {
15
+ return /* @__PURE__ */ jsx(VStack, { children: props.groups.map((group) => /* @__PURE__ */ jsx(LibraryCard, {
16
+ group,
17
+ project: props.project,
18
+ build: props.build,
19
+ layer: props.layer
20
+ }, group.title)) });
21
+ }
22
+ function LibraryCard(props) {
23
+ const { group, project, build, layer } = props;
24
+ const href = componentHref(project, group);
25
+ const captured = layer ? group.stories.flatMap((story) => layer.byStory.get(story.id) ?? []) : [];
26
+ const plain = group.stories.filter((story) => !layer?.byStory.has(story.id));
27
+ return /* @__PURE__ */ jsxs(Card, {
28
+ padded: false,
29
+ "data-filter-item": true,
30
+ "data-filter-text": `${group.title} ${group.stories.map((story) => story.name).join(" ")}`,
31
+ children: [/* @__PURE__ */ jsxs(CardSection, {
32
+ divider: true,
33
+ children: [/* @__PURE__ */ jsx(SectionTitle, { children: href ? /* @__PURE__ */ jsx("a", {
34
+ href,
35
+ children: group.title
36
+ }) : group.title }), /* @__PURE__ */ jsxs(HStack, { children: [
37
+ group.tags.map((tag) => /* @__PURE__ */ jsx(Badge, {
38
+ tone: "neutral",
39
+ children: tag
40
+ }, tag)),
41
+ /* @__PURE__ */ jsxs(Meta, {
42
+ as: "span",
43
+ children: [
44
+ group.stories.length,
45
+ " ",
46
+ group.stories.length === 1 ? "story" : "stories"
47
+ ]
48
+ }),
49
+ /* @__PURE__ */ jsx(DocsLink, {
50
+ group,
51
+ project,
52
+ build
53
+ })
54
+ ] })]
55
+ }), /* @__PURE__ */ jsx(CardSection, { children: /* @__PURE__ */ jsxs(VStack, { children: [layer && captured.length > 0 ? /* @__PURE__ */ jsx(SnapshotCards, {
56
+ snapshots: captured,
57
+ project,
58
+ buildId: build.id,
59
+ layer,
60
+ componentHref: href
61
+ }) : null, plain.length > 0 ? /* @__PURE__ */ jsx(StoryLinks, {
62
+ stories: plain,
63
+ project,
64
+ build
65
+ }) : null] }) })]
66
+ });
67
+ }
68
+ /** Component page of a group (its story file), when the index names one. */
69
+ function componentHref(project, group) {
70
+ return group.importPath ? createUrlBuilder("/", getStore().config.publishedBaseDomain).component(project.slug, group.importPath) : void 0;
71
+ }
72
+ function DocsLink(props) {
73
+ const docs = props.group.docs[0];
74
+ if (!docs) return null;
75
+ return /* @__PURE__ */ jsx(Button, {
76
+ variant: "ghost",
77
+ size: "sm",
78
+ icon: "book",
79
+ href: `/projects/${props.project.slug}/storybook/build/${props.build.id}/?storyId=${encodeURIComponent(docs.id)}&viewMode=docs`,
80
+ target: "_blank",
81
+ rel: "noopener",
82
+ children: "Docs"
83
+ });
84
+ }
85
+ /** Links into the published Storybook, one per story, for stories without a snapshot. */
86
+ function StoryLinks(props) {
87
+ const base = createUrlBuilder("/", getStore().config.publishedBaseDomain).storybookBuild(props.project.slug, props.build.id);
88
+ return /* @__PURE__ */ jsx(HStack, { children: props.stories.map((story) => /* @__PURE__ */ jsx("span", {
89
+ "data-filter-item": true,
90
+ "data-filter-text": `${story.title} ${story.name}`,
91
+ children: /* @__PURE__ */ jsx(Button, {
92
+ variant: "ghost",
93
+ size: "sm",
94
+ icon: "external-link",
95
+ href: `${base}/?storyId=${encodeURIComponent(story.id)}`,
96
+ target: "_blank",
97
+ rel: "noopener",
98
+ children: story.name
99
+ })
100
+ }, story.id)) });
101
+ }
102
+ export { LibraryGrid };
103
+
104
+ //# sourceMappingURL=library-grid.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-grid.mjs","names":[],"sources":["../../src/pages/library-grid.tsx"],"sourcesContent":["/** The library's component list: one card per title, from the catalog, with snapshots layered on. */\nimport type { Build, Project } from \"@storyshelf/core/schema\";\nimport { createUrlBuilder } from \"@storyshelf/core/urls\";\nimport type { HtmlEscapedString } from \"hono/utils/html\";\nimport { getStore } from \"../store.ts\";\nimport {\n Badge,\n Button,\n Card,\n CardSection,\n HStack,\n Meta,\n SectionTitle,\n VStack,\n} from \"../ui/components.tsx\";\nimport type { LibraryGroup } from \"./library-model.ts\";\nimport { SnapshotCards, type SnapshotLayer } from \"./library-snapshots.tsx\";\n\n/* eslint-disable promise-function-async -- Hono JSX components return HtmlEscapedString | Promise<HtmlEscapedString> */\n\ntype Rendered = HtmlEscapedString | Promise<HtmlEscapedString>;\n\n/** The component cards of a build; `layer` is present only with `testing` and captured snapshots. */\nexport function LibraryGrid(props: {\n groups: LibraryGroup[];\n project: Project;\n build: Build;\n layer: SnapshotLayer | null;\n}): Rendered {\n return (\n <VStack>\n {props.groups.map((group): Rendered => (\n <LibraryCard\n key={group.title}\n group={group}\n project={props.project}\n build={props.build}\n layer={props.layer}\n />\n ))}\n </VStack>\n );\n}\n\nfunction LibraryCard(props: {\n group: LibraryGroup;\n project: Project;\n build: Build;\n layer: SnapshotLayer | null;\n}): Rendered {\n const { group, project, build, layer } = props;\n const href = componentHref(project, group);\n const captured = layer ? group.stories.flatMap((story) => layer.byStory.get(story.id) ?? []) : [];\n const plain = group.stories.filter((story) => !layer?.byStory.has(story.id));\n return (\n <Card\n padded={false}\n data-filter-item\n data-filter-text={`${group.title} ${group.stories.map((story) => story.name).join(\" \")}`}\n >\n <CardSection divider>\n <SectionTitle>{href ? <a href={href}>{group.title}</a> : group.title}</SectionTitle>\n <HStack>\n {group.tags.map((tag) => (\n <Badge key={tag} tone=\"neutral\">\n {tag}\n </Badge>\n ))}\n <Meta as=\"span\">\n {group.stories.length} {group.stories.length === 1 ? \"story\" : \"stories\"}\n </Meta>\n <DocsLink group={group} project={project} build={build} />\n </HStack>\n </CardSection>\n <CardSection>\n <VStack>\n {layer && captured.length > 0 ? (\n <SnapshotCards\n snapshots={captured}\n project={project}\n buildId={build.id}\n layer={layer}\n componentHref={href}\n />\n ) : null}\n {plain.length > 0 ? <StoryLinks stories={plain} project={project} build={build} /> : null}\n </VStack>\n </CardSection>\n </Card>\n );\n}\n\n/** Component page of a group (its story file), when the index names one. */\nfunction componentHref(project: Project, group: LibraryGroup): string | undefined {\n return group.importPath\n ? createUrlBuilder(\"/\", getStore().config.publishedBaseDomain).component(\n project.slug,\n group.importPath,\n )\n : undefined;\n}\n\nfunction DocsLink(props: { group: LibraryGroup; project: Project; build: Build }): Rendered | null {\n const docs = props.group.docs[0];\n if (!docs) {\n return null;\n }\n return (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n icon=\"book\"\n href={`/projects/${props.project.slug}/storybook/build/${props.build.id}/?storyId=${encodeURIComponent(docs.id)}&viewMode=docs`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Docs\n </Button>\n );\n}\n\n/** Links into the published Storybook, one per story, for stories without a snapshot. */\nfunction StoryLinks(props: {\n stories: LibraryGroup[\"stories\"];\n project: Project;\n build: Build;\n}): Rendered {\n const base = createUrlBuilder(\"/\", getStore().config.publishedBaseDomain).storybookBuild(\n props.project.slug,\n props.build.id,\n );\n return (\n <HStack>\n {props.stories.map((story): Rendered => (\n <span key={story.id} data-filter-item data-filter-text={`${story.title} ${story.name}`}>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n icon=\"external-link\"\n href={`${base}/?storyId=${encodeURIComponent(story.id)}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n {story.name}\n </Button>\n </span>\n ))}\n </HStack>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { normalizeImportPath } from "@storyshelf/core/models";
5
+ // src/pages/library-model.ts
6
+ /** Tags Storybook adds on its own; they say nothing about the component. */
7
+ const STORYBOOK_TAGS = /* @__PURE__ */ new Set([
8
+ "dev",
9
+ "test",
10
+ "autodocs",
11
+ "play-fn",
12
+ "manifest",
13
+ "attached-mdx",
14
+ "unattached-mdx"
15
+ ]);
16
+ /** Group catalog entries by title, ordered by title; stories keep index order. */
17
+ function groupLibrary(entries) {
18
+ return [...Map.groupBy(entries, (entry) => entry.title).entries()].map(([title, group]) => {
19
+ return {
20
+ title,
21
+ importPath: group.find((entry) => entry.importPath !== "")?.importPath ?? "",
22
+ stories: group.filter((entry) => entry.type === "story"),
23
+ docs: group.filter((entry) => entry.type === "docs"),
24
+ tags: [...new Set(group.flatMap((entry) => entry.tags))].filter((tag) => !STORYBOOK_TAGS.has(tag))
25
+ };
26
+ }).toSorted((a, b) => a.title.localeCompare(b.title));
27
+ }
28
+ /**
29
+ * Entries rebuilt from a build's snapshots, for a captured build whose Storybook index is gone
30
+ * (statics purged): the pages still list what was captured.
31
+ */
32
+ function entriesFromSnapshots(snapshots) {
33
+ const seen = /* @__PURE__ */ new Map();
34
+ for (const snap of snapshots) if (!seen.has(snap.storyId)) seen.set(snap.storyId, {
35
+ id: snap.storyId,
36
+ title: snap.storyTitle || "Untitled",
37
+ name: snap.storyName,
38
+ importPath: snap.storyImportPath ? normalizeImportPath(snap.storyImportPath) : "",
39
+ type: "story",
40
+ tags: []
41
+ });
42
+ return [...seen.values()];
43
+ }
44
+ export { entriesFromSnapshots, groupLibrary };
45
+
46
+ //# sourceMappingURL=library-model.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-model.mjs","names":[],"sources":["../../src/pages/library-model.ts"],"sourcesContent":["import type { CatalogEntry } from \"@storyshelf/core/capture\";\nimport { normalizeImportPath } from \"@storyshelf/core/models\";\nimport type { Snapshot } from \"@storyshelf/core/schema\";\n\n/** Tags Storybook adds on its own; they say nothing about the component. */\nconst STORYBOOK_TAGS: ReadonlySet<string> = new Set([\n \"dev\",\n \"test\",\n \"autodocs\",\n \"play-fn\",\n \"manifest\",\n \"attached-mdx\",\n \"unattached-mdx\",\n]);\n\n/** The library's unit: every entry that shares a title, grouped like Storybook's sidebar. */\nexport interface LibraryGroup {\n title: string;\n /** Story file of the first entry that has one; empty when the index names none. */\n importPath: string;\n stories: CatalogEntry[];\n /** Docs entries; the first is the component's docs page. */\n docs: CatalogEntry[];\n /** Tags worth showing, in first-seen order. */\n tags: string[];\n}\n\n/** Group catalog entries by title, ordered by title; stories keep index order. */\nexport function groupLibrary(entries: readonly CatalogEntry[]): LibraryGroup[] {\n const groups = Map.groupBy(entries, (entry) => entry.title);\n return [...groups.entries()]\n .map(([title, group]): LibraryGroup => {\n return {\n title,\n importPath: group.find((entry) => entry.importPath !== \"\")?.importPath ?? \"\",\n stories: group.filter((entry) => entry.type === \"story\"),\n docs: group.filter((entry) => entry.type === \"docs\"),\n tags: [...new Set(group.flatMap((entry) => entry.tags))].filter(\n (tag) => !STORYBOOK_TAGS.has(tag),\n ),\n };\n })\n .toSorted((a, b) => a.title.localeCompare(b.title));\n}\n\n/**\n * Entries rebuilt from a build's snapshots, for a captured build whose Storybook index is gone\n * (statics purged): the pages still list what was captured.\n */\nexport function entriesFromSnapshots(snapshots: readonly Snapshot[]): CatalogEntry[] {\n const seen = new Map<string, CatalogEntry>();\n for (const snap of snapshots) {\n if (!seen.has(snap.storyId)) {\n seen.set(snap.storyId, {\n id: snap.storyId,\n title: snap.storyTitle || \"Untitled\",\n name: snap.storyName,\n importPath: snap.storyImportPath ? normalizeImportPath(snap.storyImportPath) : \"\",\n type: \"story\",\n tags: [],\n });\n }\n }\n return [...seen.values()];\n}\n"],"mappings":";;;;;;AAKA,MAAM,iCAAsC,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;;AAeD,SAAgB,aAAa,SAAkD;CAE7E,OAAO,CAAC,GADO,IAAI,QAAQ,UAAU,UAAU,MAAM,KACrC,CAAC,CAAC,QAAQ,CAAC,CAAC,CACzB,KAAK,CAAC,OAAO,WAAyB;EACrC,OAAO;GACL;GACA,YAAY,MAAM,MAAM,UAAU,MAAM,eAAe,EAAE,CAAC,EAAE,cAAc;GAC1E,SAAS,MAAM,QAAQ,UAAU,MAAM,SAAS,OAAO;GACvD,MAAM,MAAM,QAAQ,UAAU,MAAM,SAAS,MAAM;GACnD,MAAM,CAAC,GAAG,IAAI,IAAI,MAAM,SAAS,UAAU,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,QACtD,QAAQ,CAAC,eAAe,IAAI,GAAG,CAClC;EACF;CACF,CAAC,CAAC,CACD,UAAU,GAAG,MAAM,EAAE,MAAM,cAAc,EAAE,KAAK,CAAC;AACtD;;;;;AAMA,SAAgB,qBAAqB,WAAgD;CACnF,MAAM,uBAAO,IAAI,IAA0B;CAC3C,KAAK,MAAM,QAAQ,WACjB,IAAI,CAAC,KAAK,IAAI,KAAK,OAAO,GACxB,KAAK,IAAI,KAAK,SAAS;EACrB,IAAI,KAAK;EACT,OAAO,KAAK,cAAc;EAC1B,MAAM,KAAK;EACX,YAAY,KAAK,kBAAkB,oBAAoB,KAAK,eAAe,IAAI;EAC/E,MAAM;EACN,MAAM,CAAC;CACT,CAAC;CAGL,OAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAC1B"}
@@ -0,0 +1,129 @@
1
+ import "node:path";
2
+ import "node:url";
3
+ import.meta.url;
4
+ import { getStore } from "../store.mjs";
5
+ import { css } from "../ui/css.mjs";
6
+ import { Button } from "../ui/buttons.mjs";
7
+ import { Badge, statusTone } from "../ui/feedback.mjs";
8
+ import { SectionTitle } from "../ui/layout.mjs";
9
+ import { HStack } from "../ui/stacks.mjs";
10
+ import { designUrlsFor, loadDesignPreviews, loadDesignResolutions, loadProjectDesignLinks, providerNameFor } from "../routers/design.handlers.mjs";
11
+ import { diffPaneImg, snapshotCard, snapshotCardBody, snapshotCardHead, snapshotCardMeta, snapshotGrid } from "../ui/styles/review.mjs";
12
+ import { A11yViolationsDetails } from "./a11y-violations.mjs";
13
+ import { groupSnapshots } from "./build-diff-model.mjs";
14
+ import { DesignButtons } from "./design-links.mjs";
15
+ import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
16
+ import { createUrlBuilder } from "@storyshelf/core/urls";
17
+ // src/pages/library-snapshots.tsx
18
+ /** Snapshot image with library height cap, extending the shared diff pane image. */
19
+ const snapshotImg = css`
20
+ /* snapshot-img */
21
+ ${diffPaneImg}
22
+ max-height: 240px;
23
+ object-fit: contain;
24
+ `;
25
+ const NO_DESIGN = {
26
+ bySnapshot: /* @__PURE__ */ new Map(),
27
+ previews: /* @__PURE__ */ new Map(),
28
+ projectLinks: []
29
+ };
30
+ /** The layer for a build's snapshots; design data that cannot be loaded leaves the library plain. */
31
+ async function loadSnapshotLayer(project, snapshots) {
32
+ const primary = groupSnapshots(snapshots).map((group) => group.primary);
33
+ const design = await loadLibraryDesign(project, primary).catch(() => NO_DESIGN);
34
+ return {
35
+ byStory: Map.groupBy(primary, (snap) => snap.storyId),
36
+ design,
37
+ multipleViewports: new Set(primary.map((snap) => snap.viewportName)).size > 1
38
+ };
39
+ }
40
+ async function loadLibraryDesign(project, snapshots) {
41
+ const [resolutions, projectLinks] = await Promise.all([loadDesignResolutions(project, snapshots), loadProjectDesignLinks(project)]);
42
+ const bySnapshot = new Map(snapshots.map((snap) => [snap.id, designUrlsFor(resolutions, snap)]));
43
+ return {
44
+ bySnapshot,
45
+ previews: await loadDesignPreviews(project, [...bySnapshot.values()].flat()),
46
+ projectLinks
47
+ };
48
+ }
49
+ /** Snapshot cards of a component's captured stories, one grid per viewport. */
50
+ function SnapshotCards(props) {
51
+ const byViewport = Map.groupBy(props.snapshots, (snap) => snap.viewportName);
52
+ return /* @__PURE__ */ jsx(Fragment, { children: [...byViewport.keys()].toSorted().map((name) => /* @__PURE__ */ jsxs("div", { children: [props.layer.multipleViewports ? /* @__PURE__ */ jsx(SectionTitle, {
53
+ level: 3,
54
+ children: name
55
+ }) : null, /* @__PURE__ */ jsx("div", {
56
+ class: snapshotGrid,
57
+ children: (byViewport.get(name) ?? []).toSorted((a, b) => a.storyName.localeCompare(b.storyName)).map((snap) => /* @__PURE__ */ jsx(SnapshotCardItem, {
58
+ snap,
59
+ ...props
60
+ }, snap.id))
61
+ })] }, name)) });
62
+ }
63
+ function SnapshotCardItem(props) {
64
+ const { snap, project, buildId } = props;
65
+ return /* @__PURE__ */ jsxs("div", {
66
+ class: snapshotCard,
67
+ "data-filter-item": true,
68
+ "data-filter-text": `${snap.storyTitle} ${snap.storyName}`,
69
+ children: [/* @__PURE__ */ jsxs("div", {
70
+ class: snapshotCardHead,
71
+ children: [/* @__PURE__ */ jsx("strong", { children: snap.storyName }), /* @__PURE__ */ jsxs("span", {
72
+ class: snapshotCardMeta,
73
+ children: [
74
+ /* @__PURE__ */ jsx(Badge, {
75
+ tone: statusTone(snap.status),
76
+ children: snap.status
77
+ }),
78
+ " ",
79
+ snap.viewportWidth,
80
+ "×",
81
+ snap.viewportHeight
82
+ ]
83
+ })]
84
+ }), /* @__PURE__ */ jsxs("div", {
85
+ class: snapshotCardBody,
86
+ children: [
87
+ /* @__PURE__ */ jsx("img", {
88
+ class: snapshotImg,
89
+ src: `/api/v1/projects/${project.slug}/builds/${buildId}/snapshots/${snap.id}/image`,
90
+ alt: `${snap.storyTitle} / ${snap.storyName}`,
91
+ loading: "lazy"
92
+ }),
93
+ /* @__PURE__ */ jsx(A11yViolationsDetails, { snapshot: snap }),
94
+ /* @__PURE__ */ jsx(SnapshotActions, { ...props })
95
+ ]
96
+ })]
97
+ });
98
+ }
99
+ function SnapshotActions(props) {
100
+ const { snap, project, buildId, layer } = props;
101
+ const urls = createUrlBuilder("/", getStore().config.publishedBaseDomain);
102
+ return /* @__PURE__ */ jsxs(HStack, { children: [
103
+ /* @__PURE__ */ jsx(Button, {
104
+ variant: "secondary",
105
+ size: "sm",
106
+ icon: "columns",
107
+ href: `${urls.buildDiff(project.slug, buildId)}?snapshot=${snap.id}`,
108
+ children: "Review"
109
+ }),
110
+ /* @__PURE__ */ jsx(Button, {
111
+ variant: "ghost",
112
+ size: "sm",
113
+ icon: "external-link",
114
+ href: `${urls.storybookBuild(project.slug, buildId)}/?storyId=${encodeURIComponent(snap.storyId)}`,
115
+ target: "_blank",
116
+ rel: "noopener",
117
+ children: "Preview"
118
+ }),
119
+ /* @__PURE__ */ jsx(DesignButtons, {
120
+ urls: layer.design.bySnapshot.get(snap.id) ?? [],
121
+ providerName: providerNameFor,
122
+ previews: layer.design.previews,
123
+ componentHref: props.componentHref
124
+ })
125
+ ] });
126
+ }
127
+ export { SnapshotCards, loadSnapshotLayer };
128
+
129
+ //# sourceMappingURL=library-snapshots.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"library-snapshots.mjs","names":[],"sources":["../../src/pages/library-snapshots.tsx"],"sourcesContent":["/** The snapshot layer of the library: what `testing` adds on top of the catalog (ADR 0006, decision 9). */\nimport type { Project, Snapshot } from \"@storyshelf/core/schema\";\nimport { createUrlBuilder } from \"@storyshelf/core/urls\";\nimport type { HtmlEscapedString } from \"hono/utils/html\";\nimport {\n loadDesignResolutions,\n designUrlsFor,\n loadDesignPreviews,\n loadProjectDesignLinks,\n providerNameFor,\n} from \"../routers/design.handlers.ts\";\nimport { getStore } from \"../store.ts\";\nimport { Badge, Button, HStack, SectionTitle, statusTone } from \"../ui/components.tsx\";\nimport { css } from \"../ui/css.ts\";\nimport {\n diffPaneImg,\n snapshotCard,\n snapshotCardBody,\n snapshotCardHead,\n snapshotCardMeta,\n snapshotGrid,\n} from \"../ui/styles/review.ts\";\nimport { A11yViolationsDetails } from \"./a11y-violations.tsx\";\nimport { groupSnapshots } from \"./build-diff-model.ts\";\nimport { DesignButtons, type DesignPreviewInfo, type ProjectDesignLink } from \"./design-links.tsx\";\n\n/* eslint-disable promise-function-async -- Hono JSX components return HtmlEscapedString | Promise<HtmlEscapedString> */\n\ntype Rendered = HtmlEscapedString | Promise<HtmlEscapedString>;\n\n/** Snapshot image with library height cap, extending the shared diff pane image. */\nconst snapshotImg = css`\n /* snapshot-img */\n ${diffPaneImg}\n max-height: 240px;\n object-fit: contain;\n`;\n\n/** Design data of the library: per-snapshot component links plus project-level file links. */\nexport interface LibraryDesign {\n bySnapshot: Map<string, string[]>;\n previews: Map<string, DesignPreviewInfo>;\n projectLinks: ProjectDesignLink[];\n}\n\n/** Snapshots and design links of the build, by story; layered onto the catalog's stories. */\nexport interface SnapshotLayer {\n /** One snapshot per story and mode (the primary engine's; other browsers are review detail). */\n byStory: Map<string, Snapshot[]>;\n design: LibraryDesign;\n /** Whether the build has more than one viewport (so the cards name theirs). */\n multipleViewports: boolean;\n}\n\nconst NO_DESIGN: LibraryDesign = { bySnapshot: new Map(), previews: new Map(), projectLinks: [] };\n\n/** The layer for a build's snapshots; design data that cannot be loaded leaves the library plain. */\nexport async function loadSnapshotLayer(\n project: Project,\n snapshots: Snapshot[],\n): Promise<SnapshotLayer> {\n const primary = groupSnapshots(snapshots).map((group) => group.primary);\n const design = await loadLibraryDesign(project, primary).catch(() => NO_DESIGN);\n return {\n byStory: Map.groupBy(primary, (snap) => snap.storyId),\n design,\n multipleViewports: new Set(primary.map((snap) => snap.viewportName)).size > 1,\n };\n}\n\nasync function loadLibraryDesign(project: Project, snapshots: Snapshot[]): Promise<LibraryDesign> {\n const [resolutions, projectLinks] = await Promise.all([\n loadDesignResolutions(project, snapshots),\n loadProjectDesignLinks(project),\n ]);\n const bySnapshot = new Map(\n snapshots.map((snap) => [snap.id, designUrlsFor(resolutions, snap)] as const),\n );\n const previews = await loadDesignPreviews(project, [...bySnapshot.values()].flat());\n return { bySnapshot, previews, projectLinks };\n}\n\n/** Snapshot cards of a component's captured stories, one grid per viewport. */\nexport function SnapshotCards(props: {\n snapshots: Snapshot[];\n project: Project;\n buildId: string;\n layer: SnapshotLayer;\n componentHref: string | undefined;\n}): Rendered {\n const byViewport = Map.groupBy(props.snapshots, (snap) => snap.viewportName);\n return (\n <>\n {[...byViewport.keys()].toSorted().map((name): Rendered => (\n <div key={name}>\n {props.layer.multipleViewports ? <SectionTitle level={3}>{name}</SectionTitle> : null}\n <div class={snapshotGrid}>\n {(byViewport.get(name) ?? [])\n .toSorted((a, b) => a.storyName.localeCompare(b.storyName))\n .map((snap) => (\n <SnapshotCardItem key={snap.id} snap={snap} {...props} />\n ))}\n </div>\n </div>\n ))}\n </>\n );\n}\n\nfunction SnapshotCardItem(props: {\n snap: Snapshot;\n project: Project;\n buildId: string;\n layer: SnapshotLayer;\n componentHref: string | undefined;\n}): Rendered {\n const { snap, project, buildId } = props;\n return (\n <div\n class={snapshotCard}\n data-filter-item\n data-filter-text={`${snap.storyTitle} ${snap.storyName}`}\n >\n <div class={snapshotCardHead}>\n <strong>{snap.storyName}</strong>\n <span class={snapshotCardMeta}>\n <Badge tone={statusTone(snap.status)}>{snap.status}</Badge> {snap.viewportWidth}×\n {snap.viewportHeight}\n </span>\n </div>\n <div class={snapshotCardBody}>\n <img\n class={snapshotImg}\n src={`/api/v1/projects/${project.slug}/builds/${buildId}/snapshots/${snap.id}/image`}\n alt={`${snap.storyTitle} / ${snap.storyName}`}\n loading=\"lazy\"\n />\n <A11yViolationsDetails snapshot={snap} />\n <SnapshotActions {...props} />\n </div>\n </div>\n );\n}\n\nfunction SnapshotActions(props: {\n snap: Snapshot;\n project: Project;\n buildId: string;\n layer: SnapshotLayer;\n componentHref: string | undefined;\n}): Rendered {\n const { snap, project, buildId, layer } = props;\n const urls = createUrlBuilder(\"/\", getStore().config.publishedBaseDomain);\n return (\n <HStack>\n <Button\n variant=\"secondary\"\n size=\"sm\"\n icon=\"columns\"\n href={`${urls.buildDiff(project.slug, buildId)}?snapshot=${snap.id}`}\n >\n Review\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n icon=\"external-link\"\n href={`${urls.storybookBuild(project.slug, buildId)}/?storyId=${encodeURIComponent(snap.storyId)}`}\n target=\"_blank\"\n rel=\"noopener\"\n >\n Preview\n </Button>\n <DesignButtons\n urls={layer.design.bySnapshot.get(snap.id) ?? []}\n providerName={providerNameFor}\n previews={layer.design.previews}\n componentHref={props.componentHref}\n />\n </HStack>\n );\n}\n"],"mappings":"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"}