@storyshelf/app 0.7.0 → 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.
- package/dist/app-types.d.mts +1 -3
- package/dist/asset-manifest.mjs +1 -2
- package/dist/assets/htmx.mjs +1 -2
- package/dist/assets/mark.mjs +1 -2
- package/dist/boot-tasks.mjs +1 -2
- package/dist/build-state-flags.mjs +1 -2
- package/dist/build-state-setup.mjs +1 -2
- package/dist/capture-alerts.mjs +1 -2
- package/dist/capture-process.mjs +1 -2
- package/dist/capture-setup.mjs +1 -2
- package/dist/connections.mjs +1 -2
- package/dist/consumer-setup.mjs +1 -2
- package/dist/credential-keys.mjs +1 -2
- package/dist/credentials.mjs +1 -2
- package/dist/git-status.mjs +1 -2
- package/dist/hidden-data.mjs +1 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +2 -3
- package/dist/insights/budget.mjs +1 -2
- package/dist/insights/deps.mjs +1 -2
- package/dist/insights/errors.mjs +1 -2
- package/dist/insights/health-panel.mjs +0 -1
- package/dist/insights/job.mjs +1 -2
- package/dist/insights/load-health.mjs +1 -2
- package/dist/insights/load-triage.mjs +1 -2
- package/dist/insights/panel.mjs +1 -2
- package/dist/insights/request.mjs +1 -2
- package/dist/insights/stale.mjs +1 -2
- package/dist/insights/usage-report.mjs +1 -2
- package/dist/insights/view.mjs +1 -2
- package/dist/job-canceller.mjs +1 -2
- package/dist/job-queue.mjs +1 -2
- package/dist/jobs-setup.mjs +1 -2
- package/dist/lifecycle.mjs +2 -3
- package/dist/lifecycle.mjs.map +1 -1
- package/dist/middleware/auth-gate.mjs +1 -2
- package/dist/middleware/csrf.mjs +1 -2
- package/dist/middleware/rate-limit.mjs +1 -2
- package/dist/middleware/request-log.mjs +1 -2
- package/dist/middleware/require-review.mjs +1 -2
- package/dist/middleware/require-testing.mjs +1 -2
- package/dist/middleware/server-timing.mjs +1 -2
- package/dist/middleware/setup-gate.mjs +1 -2
- package/dist/middleware/store-scope.mjs +1 -2
- package/dist/notifications-pause.mjs +1 -2
- package/dist/notify.d.mts +1 -3
- package/dist/notify.mjs +1 -2
- package/dist/pages/a11y-violations.mjs +1 -2
- package/dist/pages/admin-ai.mjs +1 -2
- package/dist/pages/admin-system-origin.mjs +19 -10
- package/dist/pages/admin-system-origin.mjs.map +1 -1
- package/dist/pages/admin-system-targets.mjs +1 -2
- package/dist/pages/admin-system.mjs +1 -2
- package/dist/pages/build-detail.mjs +1 -2
- package/dist/pages/build-diff-actions.mjs +1 -2
- package/dist/pages/build-diff-comments.mjs +1 -2
- package/dist/pages/build-diff-default.mjs +53 -0
- package/dist/pages/build-diff-default.mjs.map +1 -0
- package/dist/pages/build-diff-environment.mjs +1 -2
- package/dist/pages/build-diff-header.mjs +1 -2
- package/dist/pages/build-diff-insight.mjs +1 -2
- package/dist/pages/build-diff-model.mjs +20 -3
- package/dist/pages/build-diff-model.mjs.map +1 -1
- package/dist/pages/build-diff-nav.mjs +1 -2
- package/dist/pages/build-diff-reference.mjs +84 -0
- package/dist/pages/build-diff-reference.mjs.map +1 -0
- package/dist/pages/build-diff-shortcuts.mjs +1 -2
- package/dist/pages/build-diff-stale.mjs +1 -2
- package/dist/pages/build-diff-usage.mjs +1 -2
- package/dist/pages/build-diff-viewer.mjs +38 -12
- package/dist/pages/build-diff-viewer.mjs.map +1 -1
- package/dist/pages/build-diff.mjs +6 -12
- package/dist/pages/build-diff.mjs.map +1 -1
- package/dist/pages/build-tests.mjs +1 -2
- package/dist/pages/component-detail.mjs +1 -2
- package/dist/pages/component-stories.mjs +1 -2
- package/dist/pages/compute-jobs.mjs +1 -2
- package/dist/pages/design-links.mjs +1 -2
- package/dist/pages/environment-change.mjs +1 -2
- package/dist/pages/health-panel.mjs +1 -2
- package/dist/pages/invite.mjs +1 -2
- package/dist/pages/label-detail.mjs +1 -2
- package/dist/pages/library-grid.mjs +1 -2
- package/dist/pages/library-model.mjs +1 -2
- package/dist/pages/library-snapshots.mjs +1 -2
- package/dist/pages/library.mjs +1 -2
- package/dist/pages/login.mjs +1 -2
- package/dist/pages/notifications-paused.mjs +1 -2
- package/dist/pages/passkey-ceremony.mjs +1 -2
- package/dist/pages/profile.mjs +1 -2
- package/dist/pages/project-builds-table.mjs +1 -2
- package/dist/pages/project-builds.mjs +1 -2
- package/dist/pages/project-create.mjs +1 -2
- package/dist/pages/project-settings.mjs +1 -2
- package/dist/pages/projects-card.mjs +1 -2
- package/dist/pages/projects.mjs +1 -2
- package/dist/pages/review-changeset.mjs +1 -2
- package/dist/pages/review-comments.mjs +1 -2
- package/dist/pages/review-verdict.mjs +1 -2
- package/dist/pages/root.mjs +1 -2
- package/dist/pages/settings-ai.mjs +1 -2
- package/dist/pages/settings-capture.mjs +1 -2
- package/dist/pages/settings-design-credential.mjs +1 -2
- package/dist/pages/settings-design-links.mjs +1 -2
- package/dist/pages/settings-design.mjs +1 -2
- package/dist/pages/settings-general.mjs +1 -2
- package/dist/pages/settings-labels.mjs +1 -2
- package/dist/pages/settings-links.mjs +1 -2
- package/dist/pages/settings-members.mjs +1 -2
- package/dist/pages/settings-notifications-git.mjs +1 -2
- package/dist/pages/settings-notifications.mjs +1 -2
- package/dist/pages/settings-tests.mjs +1 -2
- package/dist/pages/settings-tokens.mjs +1 -2
- package/dist/pages/settings-webhooks.mjs +1 -2
- package/dist/pages/storybook.mjs +1 -2
- package/dist/pages/target-choices.mjs +1 -2
- package/dist/publish-setup.mjs +1 -2
- package/dist/retention-timer.mjs +10 -11
- package/dist/retention-timer.mjs.map +1 -1
- package/dist/review-events.mjs +1 -2
- package/dist/routers/admin-pages.mjs +1 -2
- package/dist/routers/admin-public-origin.mjs +10 -3
- package/dist/routers/admin-public-origin.mjs.map +1 -1
- package/dist/routers/admin.mjs +8 -4
- package/dist/routers/admin.mjs.map +1 -1
- package/dist/routers/assets.mjs +1 -2
- package/dist/routers/attempts.mjs +1 -2
- package/dist/routers/auth-sync.mjs +1 -2
- package/dist/routers/auth.mjs +1 -2
- package/dist/routers/baseline-guard.mjs +2 -3
- package/dist/routers/baseline-guard.mjs.map +1 -1
- package/dist/routers/baseline-reference.mjs +72 -0
- package/dist/routers/baseline-reference.mjs.map +1 -0
- package/dist/routers/baselines.handlers.mjs +1 -2
- package/dist/routers/baselines.mjs +1 -2
- package/dist/routers/build-cancel.mjs +1 -2
- package/dist/routers/build-changeset.mjs +1 -2
- package/dist/routers/build-reviews.handlers.mjs +1 -2
- package/dist/routers/build-reviews.mjs +1 -2
- package/dist/routers/builds.handlers.mjs +23 -9
- package/dist/routers/builds.handlers.mjs.map +1 -1
- package/dist/routers/builds.mjs +7 -3
- package/dist/routers/builds.mjs.map +1 -1
- package/dist/routers/capture-cache.mjs +29 -0
- package/dist/routers/capture-cache.mjs.map +1 -0
- package/dist/routers/capture-config.mjs +1 -2
- package/dist/routers/comments.mjs +1 -2
- package/dist/routers/comparison-image.mjs +29 -0
- package/dist/routers/comparison-image.mjs.map +1 -0
- package/dist/routers/component-catalog.handlers.mjs +1 -2
- package/dist/routers/component.handlers.mjs +1 -2
- package/dist/routers/connections.mjs +1 -2
- package/dist/routers/design-connect.handlers.mjs +1 -2
- package/dist/routers/design.handlers.mjs +1 -2
- package/dist/routers/flash.mjs +1 -2
- package/dist/routers/health-report.mjs +1 -2
- package/dist/routers/health.mjs +1 -2
- package/dist/routers/helpers.mjs +1 -2
- package/dist/routers/htmx.mjs +1 -2
- package/dist/routers/insights-ui.mjs +1 -2
- package/dist/routers/insights.handlers.mjs +1 -2
- package/dist/routers/insights.mjs +1 -2
- package/dist/routers/labels.mjs +1 -2
- package/dist/routers/links.handlers.mjs +1 -2
- package/dist/routers/links.mjs +1 -2
- package/dist/routers/media.mjs +14 -5
- package/dist/routers/media.mjs.map +1 -1
- package/dist/routers/members.mjs +1 -2
- package/dist/routers/notification-channels.mjs +1 -2
- package/dist/routers/notification-subscriptions.mjs +1 -2
- package/dist/routers/oauth-state.mjs +1 -2
- package/dist/routers/preview-base.mjs +1 -2
- package/dist/routers/preview-token.mjs +1 -2
- package/dist/routers/profile.mjs +1 -2
- package/dist/routers/projects.mjs +1 -2
- package/dist/routers/publish-upload.mjs +19 -12
- package/dist/routers/publish-upload.mjs.map +1 -1
- package/dist/routers/published-access.mjs +1 -2
- package/dist/routers/published-compression.mjs +109 -0
- package/dist/routers/published-compression.mjs.map +1 -0
- package/dist/routers/published-files.mjs +26 -9
- package/dist/routers/published-files.mjs.map +1 -1
- package/dist/routers/review-forms.mjs +1 -2
- package/dist/routers/review-next.mjs +1 -2
- package/dist/routers/review-section.handlers.mjs +1 -2
- package/dist/routers/review-switch-off.mjs +1 -2
- package/dist/routers/schemas.mjs +1 -2
- package/dist/routers/scoped-models.mjs +1 -2
- package/dist/routers/settings-ai.mjs +1 -2
- package/dist/routers/settings-capture.mjs +1 -2
- package/dist/routers/settings-design.mjs +1 -2
- package/dist/routers/settings-general.mjs +1 -2
- package/dist/routers/settings-git-channel.mjs +1 -2
- package/dist/routers/settings-labels.mjs +1 -2
- package/dist/routers/settings-links.mjs +1 -2
- package/dist/routers/settings-members.mjs +1 -2
- package/dist/routers/settings-notifications.mjs +1 -2
- package/dist/routers/settings-tokens.mjs +1 -2
- package/dist/routers/settings-webhooks.mjs +1 -2
- package/dist/routers/settings.handlers.mjs +1 -2
- package/dist/routers/settings.mjs +1 -2
- package/dist/routers/signed-storybook.mjs +5 -3
- package/dist/routers/signed-storybook.mjs.map +1 -1
- package/dist/routers/snapshot-groups.mjs +1 -2
- package/dist/routers/snapshots.mjs +1 -2
- package/dist/routers/storybook.mjs +21 -17
- package/dist/routers/storybook.mjs.map +1 -1
- package/dist/routers/tokens.mjs +1 -2
- package/dist/routers/ui.mjs +4 -2
- package/dist/routers/ui.mjs.map +1 -1
- package/dist/routers/webhooks.mjs +1 -2
- package/dist/routers/well-known.mjs +1 -2
- package/dist/routes/api-routes.mjs +1 -2
- package/dist/routes/classification.mjs +1 -2
- package/dist/routes/openapi-classes.mjs +1 -2
- package/dist/routes/page-routes.mjs +2 -3
- package/dist/routes/page-routes.mjs.map +1 -1
- package/dist/runtime.mjs +1 -2
- package/dist/serverless.mjs +1 -2
- package/dist/store.mjs +1 -2
- package/dist/targets.mjs +1 -2
- package/dist/ui/avatar.mjs +1 -2
- package/dist/ui/buttons.mjs +1 -2
- package/dist/ui/code-block.mjs +1 -2
- package/dist/ui/compare-stage.mjs +86 -54
- package/dist/ui/compare-stage.mjs.map +1 -1
- package/dist/ui/csrf-field.mjs +1 -2
- package/dist/ui/css.mjs +1 -2
- package/dist/ui/design-reference.mjs +1 -2
- package/dist/ui/document.mjs +1 -2
- package/dist/ui/dropdown.mjs +1 -2
- package/dist/ui/feedback.mjs +1 -2
- package/dist/ui/filter-input.mjs +1 -2
- package/dist/ui/forms.mjs +1 -2
- package/dist/ui/icons/icon.mjs +1 -2
- package/dist/ui/icons/paths.mjs +1 -2
- package/dist/ui/icons/sprite.mjs +1 -2
- package/dist/ui/kbd.mjs +1 -2
- package/dist/ui/layout.mjs +1 -2
- package/dist/ui/preview-embed.mjs +1 -2
- package/dist/ui/progress.mjs +1 -2
- package/dist/ui/segmented.mjs +1 -2
- package/dist/ui/shell/account.mjs +1 -2
- package/dist/ui/shell/bare.mjs +1 -2
- package/dist/ui/shell/boot-script.mjs +1 -2
- package/dist/ui/shell/client-script.mjs +1 -2
- package/dist/ui/shell/nav.mjs +1 -2
- package/dist/ui/shell/review-script.mjs +17 -3
- package/dist/ui/shell/review-script.mjs.map +1 -1
- package/dist/ui/shell/sidebar.mjs +1 -2
- package/dist/ui/shell/topbar.mjs +1 -2
- package/dist/ui/stacks.mjs +1 -2
- package/dist/ui/styles/base.mjs +1 -2
- package/dist/ui/styles/behavior.mjs +1 -2
- package/dist/ui/styles/review-layout.mjs +1 -2
- package/dist/ui/styles/review.mjs +1 -2
- package/dist/ui/styles/tokens.mjs +1 -2
- package/dist/ui/styles.mjs +1 -2
- package/dist/ui/subnav.mjs +1 -2
- package/dist/ui/table.mjs +1 -2
- package/dist/ui/theme.mjs +1 -2
- package/dist/ui/thumbnail.mjs +1 -2
- package/dist/ui/time.mjs +1 -2
- package/package.json +9 -9
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Segmented } from "./segmented.mjs";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/compare-stage.tsx
|
|
8
8
|
/**
|
|
9
9
|
* Screenshot comparison surface. All modes share one set of images; the
|
|
10
10
|
* `data-view` / `data-zoom` / `data-flip` attributes on the root (driven by
|
|
@@ -70,6 +70,10 @@ const stageRoot = css`
|
|
|
70
70
|
font-size: var(--text-sm);
|
|
71
71
|
text-align: center;
|
|
72
72
|
}
|
|
73
|
+
.stage__note {
|
|
74
|
+
color: var(--text-secondary);
|
|
75
|
+
font-size: var(--text-sm);
|
|
76
|
+
}
|
|
73
77
|
.stage__divider,
|
|
74
78
|
.stage__controls {
|
|
75
79
|
display: none;
|
|
@@ -103,6 +107,10 @@ const stageRoot = css`
|
|
|
103
107
|
&[data-zoom="400"] .stage__img {
|
|
104
108
|
image-rendering: pixelated;
|
|
105
109
|
}
|
|
110
|
+
/* Design variant: screenshot against a render, two panes and no diff. */
|
|
111
|
+
&[data-variant="design"][data-view="split"] .stage__grid {
|
|
112
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
113
|
+
}
|
|
106
114
|
&[data-view="diff"] .stage__grid,
|
|
107
115
|
&[data-view="flip"] .stage__grid,
|
|
108
116
|
&[data-view="swipe"] .stage__grid,
|
|
@@ -218,6 +226,12 @@ const ZOOMS = [
|
|
|
218
226
|
value: "400"
|
|
219
227
|
}
|
|
220
228
|
];
|
|
229
|
+
/** Modes and zoom a design comparison offers: no pixel diff, and the render always fits the stage. */
|
|
230
|
+
const DESIGN_MODES = [
|
|
231
|
+
"split",
|
|
232
|
+
"swipe",
|
|
233
|
+
"onion"
|
|
234
|
+
];
|
|
221
235
|
function withActive(items, active) {
|
|
222
236
|
return items.map((item) => ({
|
|
223
237
|
...item,
|
|
@@ -244,12 +258,12 @@ const Pane = ({ kind, label, src, alt, empty, meta }) => {
|
|
|
244
258
|
});
|
|
245
259
|
};
|
|
246
260
|
/** Swipe and onion-skin sliders; each is shown only in its own mode (CSS). */
|
|
247
|
-
const RangeControls = () => {
|
|
261
|
+
const RangeControls = ({ baselineLabel }) => {
|
|
248
262
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("label", {
|
|
249
263
|
class: "stage__controls",
|
|
250
264
|
"data-for": "swipe",
|
|
251
265
|
children: [
|
|
252
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
266
|
+
/* @__PURE__ */ jsx("span", { children: baselineLabel }),
|
|
253
267
|
/* @__PURE__ */ jsx("input", {
|
|
254
268
|
type: "range",
|
|
255
269
|
min: "0",
|
|
@@ -264,7 +278,7 @@ const RangeControls = () => {
|
|
|
264
278
|
class: "stage__controls",
|
|
265
279
|
"data-for": "onion",
|
|
266
280
|
children: [
|
|
267
|
-
/* @__PURE__ */ jsx("span", { children:
|
|
281
|
+
/* @__PURE__ */ jsx("span", { children: baselineLabel }),
|
|
268
282
|
/* @__PURE__ */ jsx("input", {
|
|
269
283
|
type: "range",
|
|
270
284
|
min: "0",
|
|
@@ -277,68 +291,86 @@ const RangeControls = () => {
|
|
|
277
291
|
]
|
|
278
292
|
})] });
|
|
279
293
|
};
|
|
294
|
+
/** Mode switch, plus the zoom switch (a design comparison always fits, so it has none). */
|
|
295
|
+
const StageBar = ({ design }) => {
|
|
296
|
+
const modes = design ? MODES.filter((mode) => DESIGN_MODES.includes(mode.value)) : MODES;
|
|
297
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
298
|
+
class: "stage__bar",
|
|
299
|
+
children: [/* @__PURE__ */ jsx(Segmented, {
|
|
300
|
+
label: "Comparison mode",
|
|
301
|
+
"data-compare-mode": true,
|
|
302
|
+
items: withActive(modes, "split")
|
|
303
|
+
}), design ? null : /* @__PURE__ */ jsx(Segmented, {
|
|
304
|
+
label: "Zoom",
|
|
305
|
+
"data-compare-zoom": true,
|
|
306
|
+
items: withActive(ZOOMS, "fit")
|
|
307
|
+
})]
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
/** The panes (baseline or design, current, diff) and the swipe divider. */
|
|
311
|
+
const StageGrid = ({ baselineSrc, currentSrc, diffSrc, subject, baselineEmpty = "New story — no baseline yet. Approve to set the baseline.", diffEmpty = "No diff", diffMeta, design, baselineLabel }) => /* @__PURE__ */ jsxs("div", {
|
|
312
|
+
class: "stage__grid",
|
|
313
|
+
children: [
|
|
314
|
+
/* @__PURE__ */ jsx(Pane, {
|
|
315
|
+
kind: "baseline",
|
|
316
|
+
label: baselineLabel,
|
|
317
|
+
src: baselineSrc,
|
|
318
|
+
alt: `${baselineLabel} for ${subject}`,
|
|
319
|
+
empty: baselineEmpty
|
|
320
|
+
}),
|
|
321
|
+
/* @__PURE__ */ jsx(Pane, {
|
|
322
|
+
kind: "current",
|
|
323
|
+
label: "Current",
|
|
324
|
+
src: currentSrc,
|
|
325
|
+
alt: `Current for ${subject}`,
|
|
326
|
+
empty: "No screenshot"
|
|
327
|
+
}),
|
|
328
|
+
design ? null : /* @__PURE__ */ jsx(Pane, {
|
|
329
|
+
kind: "diff",
|
|
330
|
+
label: "Diff",
|
|
331
|
+
src: diffSrc,
|
|
332
|
+
alt: `Diff for ${subject}`,
|
|
333
|
+
empty: diffEmpty,
|
|
334
|
+
meta: diffMeta
|
|
335
|
+
}),
|
|
336
|
+
/* @__PURE__ */ jsx("span", {
|
|
337
|
+
class: "stage__divider",
|
|
338
|
+
"aria-hidden": "true",
|
|
339
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
340
|
+
class: "stage__knob",
|
|
341
|
+
"data-compare-knob": true,
|
|
342
|
+
children: "↔"
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
]
|
|
346
|
+
});
|
|
280
347
|
/** Baseline / current / diff comparison with swipe, onion-skin, flip, and zoom. */
|
|
281
|
-
const CompareStage = ({
|
|
348
|
+
const CompareStage = ({ variant = "baseline", baselineLabel = "Baseline", note, ...images }) => {
|
|
349
|
+
const design = variant === "design";
|
|
282
350
|
return /* @__PURE__ */ jsxs("div", {
|
|
283
351
|
class: stageRoot,
|
|
284
352
|
"data-compare": true,
|
|
285
353
|
"data-view": "split",
|
|
286
354
|
"data-zoom": "fit",
|
|
287
355
|
"data-flip": "current",
|
|
356
|
+
"data-variant": variant,
|
|
357
|
+
"data-modes": design ? DESIGN_MODES.join(",") : void 0,
|
|
358
|
+
"data-zooms": design ? "fit" : void 0,
|
|
288
359
|
children: [
|
|
289
|
-
/* @__PURE__ */
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
items: withActive(ZOOMS, "fit")
|
|
299
|
-
})]
|
|
300
|
-
}),
|
|
301
|
-
/* @__PURE__ */ jsxs("div", {
|
|
302
|
-
class: "stage__grid",
|
|
303
|
-
children: [
|
|
304
|
-
/* @__PURE__ */ jsx(Pane, {
|
|
305
|
-
kind: "baseline",
|
|
306
|
-
label: "Baseline",
|
|
307
|
-
src: baselineSrc,
|
|
308
|
-
alt: `Baseline for ${subject}`,
|
|
309
|
-
empty: baselineEmpty
|
|
310
|
-
}),
|
|
311
|
-
/* @__PURE__ */ jsx(Pane, {
|
|
312
|
-
kind: "current",
|
|
313
|
-
label: "Current",
|
|
314
|
-
src: currentSrc,
|
|
315
|
-
alt: `Current for ${subject}`,
|
|
316
|
-
empty: "No screenshot"
|
|
317
|
-
}),
|
|
318
|
-
/* @__PURE__ */ jsx(Pane, {
|
|
319
|
-
kind: "diff",
|
|
320
|
-
label: "Diff",
|
|
321
|
-
src: diffSrc,
|
|
322
|
-
alt: `Diff for ${subject}`,
|
|
323
|
-
empty: diffEmpty,
|
|
324
|
-
meta: diffMeta
|
|
325
|
-
}),
|
|
326
|
-
/* @__PURE__ */ jsx("span", {
|
|
327
|
-
class: "stage__divider",
|
|
328
|
-
"aria-hidden": "true",
|
|
329
|
-
children: /* @__PURE__ */ jsx("span", {
|
|
330
|
-
class: "stage__knob",
|
|
331
|
-
"data-compare-knob": true,
|
|
332
|
-
children: "↔"
|
|
333
|
-
})
|
|
334
|
-
})
|
|
335
|
-
]
|
|
360
|
+
/* @__PURE__ */ jsx(StageBar, { design }),
|
|
361
|
+
note ? /* @__PURE__ */ jsx("p", {
|
|
362
|
+
class: "stage__note",
|
|
363
|
+
children: note
|
|
364
|
+
}) : null,
|
|
365
|
+
/* @__PURE__ */ jsx(StageGrid, {
|
|
366
|
+
...images,
|
|
367
|
+
design,
|
|
368
|
+
baselineLabel
|
|
336
369
|
}),
|
|
337
|
-
/* @__PURE__ */ jsx(RangeControls, {})
|
|
370
|
+
/* @__PURE__ */ jsx(RangeControls, { baselineLabel })
|
|
338
371
|
]
|
|
339
372
|
});
|
|
340
373
|
};
|
|
341
|
-
//#endregion
|
|
342
374
|
export { CompareStage };
|
|
343
375
|
|
|
344
376
|
//# sourceMappingURL=compare-stage.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compare-stage.mjs","names":[],"sources":["../../src/ui/compare-stage.tsx"],"sourcesContent":["import type { FC } from \"hono/jsx\";\nimport { css } from \"./css.ts\";\nimport { Segmented } from \"./segmented.tsx\";\n\n/* eslint-disable promise-function-async -- Hono JSX components return HtmlEscapedString | Promise<HtmlEscapedString> */\n\n/**\n * Screenshot comparison surface. All modes share one set of images; the\n * `data-view` / `data-zoom` / `data-flip` attributes on the root (driven by\n * the review script) decide what is shown. Without JS it stays side-by-side.\n */\nconst stageRoot = css`\n /* compare-stage */\n display: grid;\n gap: var(--space-3);\n .stage__bar {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-3);\n align-items: center;\n justify-content: space-between;\n }\n .stage__grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--space-3);\n align-items: start;\n }\n .stage__pane {\n position: relative;\n min-width: 0;\n max-height: 78vh;\n overflow: auto;\n background: var(--surface-card);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n }\n .stage__label {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.35rem 0.6rem;\n background: var(--surface-subtle);\n border-bottom: 1px solid var(--border);\n color: var(--text-secondary);\n font-size: var(--text-xs);\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .stage__img {\n display: block;\n width: 100%;\n height: auto;\n background: repeating-conic-gradient(var(--surface-muted) 0% 25%, var(--surface-subtle) 0% 50%)\n 0 0 / 16px 16px;\n }\n .stage__empty {\n display: grid;\n place-items: center;\n aspect-ratio: 16 / 9;\n padding: var(--space-4);\n background: var(--surface-subtle);\n color: var(--text-secondary);\n font-size: var(--text-sm);\n text-align: center;\n }\n .stage__divider,\n .stage__controls {\n display: none;\n }\n .stage__controls {\n align-items: center;\n gap: var(--space-3);\n color: var(--text-secondary);\n font-size: var(--text-sm);\n }\n .stage__controls input {\n flex: 1;\n accent-color: var(--accent);\n }\n &[data-zoom=\"100\"] .stage__img {\n width: auto;\n max-width: none;\n }\n &[data-zoom=\"200\"] .stage__img {\n width: auto;\n max-width: none;\n zoom: 2;\n }\n &[data-zoom=\"400\"] .stage__img {\n width: auto;\n max-width: none;\n zoom: 4;\n }\n /* Zoomed in, show real pixels instead of a smoothed blur. */\n &[data-zoom=\"200\"] .stage__img,\n &[data-zoom=\"400\"] .stage__img {\n image-rendering: pixelated;\n }\n &[data-view=\"diff\"] .stage__grid,\n &[data-view=\"flip\"] .stage__grid,\n &[data-view=\"swipe\"] .stage__grid,\n &[data-view=\"onion\"] .stage__grid {\n grid-template-columns: minmax(0, 1fr);\n }\n &[data-view=\"diff\"] .stage__pane:not([data-pane=\"diff\"]) {\n display: none;\n }\n &[data-view=\"flip\"][data-flip=\"baseline\"] .stage__pane:not([data-pane=\"baseline\"]),\n &[data-view=\"flip\"]:not([data-flip=\"baseline\"]) .stage__pane:not([data-pane=\"current\"]) {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane[data-pane=\"diff\"],\n &[data-view=\"onion\"] .stage__pane[data-pane=\"diff\"] {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane,\n &[data-view=\"onion\"] .stage__pane,\n &[data-view=\"swipe\"] .stage__divider {\n grid-area: 1 / 1;\n }\n &[data-view=\"swipe\"] .stage__label,\n &[data-view=\"onion\"] .stage__label {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane[data-pane=\"current\"] {\n clip-path: inset(0 0 0 var(--swipe, 50%));\n background: transparent;\n }\n &[data-view=\"onion\"] .stage__pane[data-pane=\"current\"] {\n opacity: var(--onion, 0.5);\n background: transparent;\n }\n &[data-view=\"swipe\"] .stage__divider {\n position: relative;\n display: block;\n z-index: 3;\n justify-self: start;\n width: 2px;\n height: 100%;\n margin-left: var(--swipe, 50%);\n background: var(--accent);\n pointer-events: none;\n }\n /* The only part of the divider that takes pointer input: drag it to wipe. */\n .stage__knob {\n position: absolute;\n top: 50%;\n left: 50%;\n display: grid;\n place-items: center;\n width: 32px;\n height: 32px;\n transform: translate(-50%, -50%);\n background: var(--accent);\n color: var(--accent-contrast);\n border: 2px solid var(--surface-card);\n border-radius: var(--radius-pill);\n box-shadow: var(--shadow-2);\n font-size: var(--text-lg);\n line-height: 1;\n cursor: ew-resize;\n pointer-events: auto;\n touch-action: none;\n user-select: none;\n }\n &[data-view=\"flip\"] .stage__grid {\n cursor: pointer;\n }\n &[data-view=\"swipe\"] .stage__controls[data-for=\"swipe\"],\n &[data-view=\"onion\"] .stage__controls[data-for=\"onion\"] {\n display: flex;\n }\n`;\n\nconst MODES = [\n { label: \"Side by side\", value: \"split\" },\n { label: \"Swipe\", value: \"swipe\" },\n { label: \"Onion skin\", value: \"onion\" },\n { label: \"Diff\", value: \"diff\" },\n { label: \"Flip\", value: \"flip\" },\n];\n\nconst ZOOMS = [\n { label: \"Fit\", value: \"fit\" },\n { label: \"100%\", value: \"100\" },\n { label: \"200%\", value: \"200\" },\n { label: \"400%\", value: \"400\" },\n];\n\nfunction withActive(\n items: { label: string; value: string }[],\n active: string,\n): { label: string; value: string; active: boolean }[] {\n return items.map((item) => ({ ...item, active: item.value === active }));\n}\n\ninterface PaneProps {\n kind: \"baseline\" | \"current\" | \"diff\";\n label: string;\n src: string | null;\n alt: string;\n empty: unknown;\n meta?: string;\n}\n\nconst Pane: FC<PaneProps> = ({ kind, label, src, alt, empty, meta }) => {\n return (\n <div class=\"stage__pane\" data-pane={kind}>\n <div class=\"stage__label\">\n <span>{label}</span>\n {meta ? <span>{meta}</span> : null}\n </div>\n {src ? (\n <img class=\"stage__img\" src={src} alt={alt} loading=\"lazy\" decoding=\"async\" />\n ) : (\n <div class=\"stage__empty\">{empty}</div>\n )}\n </div>\n );\n};\n\n/** Swipe and onion-skin sliders; each is shown only in its own mode (CSS). */\nconst RangeControls: FC = () => {\n return (\n <>\n <label class=\"stage__controls\" data-for=\"swipe\">\n <span>Baseline</span>\n <input type=\"range\" min=\"0\" max=\"100\" value=\"50\" data-compare-swipe aria-label=\"Swipe\" />\n <span>Current</span>\n </label>\n <label class=\"stage__controls\" data-for=\"onion\">\n <span>Baseline</span>\n <input type=\"range\" min=\"0\" max=\"100\" value=\"50\" data-compare-onion aria-label=\"Opacity\" />\n <span>Current</span>\n </label>\n </>\n );\n};\n\n/** Props for the screenshot comparison surface. */\nexport interface CompareStageProps {\n /** Baseline image URL, or null when the story has no baseline yet. */\n baselineSrc: string | null;\n currentSrc: string;\n /** Diff overlay URL, or null when none was produced. */\n diffSrc: string | null;\n /** Accessible description shared by the images, e.g. \"Button / Primary\". */\n subject: string;\n baselineEmpty?: unknown;\n diffEmpty?: unknown;\n diffMeta?: string;\n}\n\n/** Baseline / current / diff comparison with swipe, onion-skin, flip, and zoom. */\nexport const CompareStage: FC<CompareStageProps> = ({\n baselineSrc,\n currentSrc,\n diffSrc,\n subject,\n baselineEmpty = \"New story — no baseline yet. Approve to set the baseline.\",\n diffEmpty = \"No diff\",\n diffMeta,\n}) => {\n return (\n <div class={stageRoot} data-compare data-view=\"split\" data-zoom=\"fit\" data-flip=\"current\">\n <div class=\"stage__bar\">\n <Segmented label=\"Comparison mode\" data-compare-mode items={withActive(MODES, \"split\")} />\n <Segmented label=\"Zoom\" data-compare-zoom items={withActive(ZOOMS, \"fit\")} />\n </div>\n <div class=\"stage__grid\">\n <Pane\n kind=\"baseline\"\n label=\"Baseline\"\n src={baselineSrc}\n alt={`Baseline for ${subject}`}\n empty={baselineEmpty}\n />\n <Pane\n kind=\"current\"\n label=\"Current\"\n src={currentSrc}\n alt={`Current for ${subject}`}\n empty=\"No screenshot\"\n />\n <Pane\n kind=\"diff\"\n label=\"Diff\"\n src={diffSrc}\n alt={`Diff for ${subject}`}\n empty={diffEmpty}\n meta={diffMeta}\n />\n <span class=\"stage__divider\" aria-hidden=\"true\">\n <span class=\"stage__knob\" data-compare-knob>\n ↔\n </span>\n </span>\n </div>\n <RangeControls />\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAWA,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyKrB,MAAM,QAAQ;CACZ;EAAE,OAAO;EAAgB,OAAO;CAAQ;CACxC;EAAE,OAAO;EAAS,OAAO;CAAQ;CACjC;EAAE,OAAO;EAAc,OAAO;CAAQ;CACtC;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;AACjC;AAEA,MAAM,QAAQ;CACZ;EAAE,OAAO;EAAO,OAAO;CAAM;CAC7B;EAAE,OAAO;EAAQ,OAAO;CAAM;CAC9B;EAAE,OAAO;EAAQ,OAAO;CAAM;CAC9B;EAAE,OAAO;EAAQ,OAAO;CAAM;AAChC;AAEA,SAAS,WACP,OACA,QACqD;CACrD,OAAO,MAAM,KAAK,UAAU;EAAE,GAAG;EAAM,QAAQ,KAAK,UAAU;CAAO,EAAE;AACzE;AAWA,MAAM,QAAuB,EAAE,MAAM,OAAO,KAAK,KAAK,OAAO,WAAW;CACtE,OACE,qBAAC,OAAD;EAAK,OAAM;EAAc,aAAW;EAApC,UAAA,CACE,qBAAC,OAAD;GAAK,OAAM;GAAX,UAAA,CACE,oBAAC,QAAD,EAAA,UAAO,MAAY,CAAA,GAClB,OAAO,oBAAC,QAAD,EAAA,UAAO,KAAW,CAAA,IAAI,IAC3B;EACJ,CAAA,GAAA,MACC,oBAAC,OAAD;GAAK,OAAM;GAAkB;GAAU;GAAK,SAAQ;GAAO,UAAS;EAAS,CAAA,IAE7E,oBAAC,OAAD;GAAK,OAAM;GAAgB,UAAA;EAAW,CAAA,CAErC;;AAET;;AAGA,MAAM,sBAA0B;CAC9B,OACE,qBAAA,UAAA,EAAA,UAAA,CACE,qBAAC,SAAD;EAAO,OAAM;EAAkB,YAAS;EAAxC,UAAA;GACE,oBAAC,QAAD,EAAA,UAAM,WAAc,CAAA;GACpB,oBAAC,SAAD;IAAO,MAAK;IAAQ,KAAI;IAAI,KAAI;IAAM,OAAM;IAAK,sBAAA;IAAmB,cAAW;GAAS,CAAA;GACxF,oBAAC,QAAD,EAAA,UAAM,UAAa,CAAA;EACd;CACP,CAAA,GAAA,qBAAC,SAAD;EAAO,OAAM;EAAkB,YAAS;EAAxC,UAAA;GACE,oBAAC,QAAD,EAAA,UAAM,WAAc,CAAA;GACpB,oBAAC,SAAD;IAAO,MAAK;IAAQ,KAAI;IAAI,KAAI;IAAM,OAAM;IAAK,sBAAA;IAAmB,cAAW;GAAW,CAAA;GAC1F,oBAAC,QAAD,EAAA,UAAM,UAAa,CAAA;EACd;CACP,CAAA,CAAA,EAAA,CAAA;AAEN;;AAiBA,MAAa,gBAAuC,EAClD,aACA,YACA,SACA,SACA,gBAAgB,6DAChB,YAAY,WACZ,eACI;CACJ,OACE,qBAAC,OAAD;EAAK,OAAO;EAAW,gBAAA;EAAa,aAAU;EAAQ,aAAU;EAAM,aAAU;EAAhF,UAAA;GACE,qBAAC,OAAD;IAAK,OAAM;IAAX,UAAA,CACE,oBAAC,WAAD;KAAW,OAAM;KAAkB,qBAAA;KAAkB,OAAO,WAAW,OAAO,OAAO;IAAI,CAAA,GACzF,oBAAC,WAAD;KAAW,OAAM;KAAO,qBAAA;KAAkB,OAAO,WAAW,OAAO,KAAK;IAAI,CAAA,CACzE;;GACL,qBAAC,OAAD;IAAK,OAAM;IAAX,UAAA;KACE,oBAAC,MAAD;MACE,MAAK;MACL,OAAM;MACN,KAAK;MACL,KAAK,gBAAgB;MACrB,OAAO;KACR,CAAA;KACD,oBAAC,MAAD;MACE,MAAK;MACL,OAAM;MACN,KAAK;MACL,KAAK,eAAe;MACpB,OAAM;KACP,CAAA;KACD,oBAAC,MAAD;MACE,MAAK;MACL,OAAM;MACN,KAAK;MACL,KAAK,YAAY;MACjB,OAAO;MACP,MAAM;KACP,CAAA;KACD,oBAAC,QAAD;MAAM,OAAM;MAAiB,eAAY;MACvC,UAAA,oBAAC,QAAD;OAAM,OAAM;OAAc,qBAAA;OAAkB,UAAA;MAEtC,CAAA;KACF,CAAA;IACH;;GACL,oBAAC,eAAD,CAAgB,CAAA;EACb;;AAET"}
|
|
1
|
+
{"version":3,"file":"compare-stage.mjs","names":[],"sources":["../../src/ui/compare-stage.tsx"],"sourcesContent":["import type { FC } from \"hono/jsx\";\nimport { css } from \"./css.ts\";\nimport { Segmented } from \"./segmented.tsx\";\n\n/* eslint-disable promise-function-async -- Hono JSX components return HtmlEscapedString | Promise<HtmlEscapedString> */\n\n/**\n * Screenshot comparison surface. All modes share one set of images; the\n * `data-view` / `data-zoom` / `data-flip` attributes on the root (driven by\n * the review script) decide what is shown. Without JS it stays side-by-side.\n */\nconst stageRoot = css`\n /* compare-stage */\n display: grid;\n gap: var(--space-3);\n .stage__bar {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-3);\n align-items: center;\n justify-content: space-between;\n }\n .stage__grid {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--space-3);\n align-items: start;\n }\n .stage__pane {\n position: relative;\n min-width: 0;\n max-height: 78vh;\n overflow: auto;\n background: var(--surface-card);\n border: 1px solid var(--border);\n border-radius: var(--radius);\n }\n .stage__label {\n position: sticky;\n top: 0;\n left: 0;\n z-index: 2;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.35rem 0.6rem;\n background: var(--surface-subtle);\n border-bottom: 1px solid var(--border);\n color: var(--text-secondary);\n font-size: var(--text-xs);\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n }\n .stage__img {\n display: block;\n width: 100%;\n height: auto;\n background: repeating-conic-gradient(var(--surface-muted) 0% 25%, var(--surface-subtle) 0% 50%)\n 0 0 / 16px 16px;\n }\n .stage__empty {\n display: grid;\n place-items: center;\n aspect-ratio: 16 / 9;\n padding: var(--space-4);\n background: var(--surface-subtle);\n color: var(--text-secondary);\n font-size: var(--text-sm);\n text-align: center;\n }\n .stage__note {\n color: var(--text-secondary);\n font-size: var(--text-sm);\n }\n .stage__divider,\n .stage__controls {\n display: none;\n }\n .stage__controls {\n align-items: center;\n gap: var(--space-3);\n color: var(--text-secondary);\n font-size: var(--text-sm);\n }\n .stage__controls input {\n flex: 1;\n accent-color: var(--accent);\n }\n &[data-zoom=\"100\"] .stage__img {\n width: auto;\n max-width: none;\n }\n &[data-zoom=\"200\"] .stage__img {\n width: auto;\n max-width: none;\n zoom: 2;\n }\n &[data-zoom=\"400\"] .stage__img {\n width: auto;\n max-width: none;\n zoom: 4;\n }\n /* Zoomed in, show real pixels instead of a smoothed blur. */\n &[data-zoom=\"200\"] .stage__img,\n &[data-zoom=\"400\"] .stage__img {\n image-rendering: pixelated;\n }\n /* Design variant: screenshot against a render, two panes and no diff. */\n &[data-variant=\"design\"][data-view=\"split\"] .stage__grid {\n grid-template-columns: repeat(2, minmax(0, 1fr));\n }\n &[data-view=\"diff\"] .stage__grid,\n &[data-view=\"flip\"] .stage__grid,\n &[data-view=\"swipe\"] .stage__grid,\n &[data-view=\"onion\"] .stage__grid {\n grid-template-columns: minmax(0, 1fr);\n }\n &[data-view=\"diff\"] .stage__pane:not([data-pane=\"diff\"]) {\n display: none;\n }\n &[data-view=\"flip\"][data-flip=\"baseline\"] .stage__pane:not([data-pane=\"baseline\"]),\n &[data-view=\"flip\"]:not([data-flip=\"baseline\"]) .stage__pane:not([data-pane=\"current\"]) {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane[data-pane=\"diff\"],\n &[data-view=\"onion\"] .stage__pane[data-pane=\"diff\"] {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane,\n &[data-view=\"onion\"] .stage__pane,\n &[data-view=\"swipe\"] .stage__divider {\n grid-area: 1 / 1;\n }\n &[data-view=\"swipe\"] .stage__label,\n &[data-view=\"onion\"] .stage__label {\n display: none;\n }\n &[data-view=\"swipe\"] .stage__pane[data-pane=\"current\"] {\n clip-path: inset(0 0 0 var(--swipe, 50%));\n background: transparent;\n }\n &[data-view=\"onion\"] .stage__pane[data-pane=\"current\"] {\n opacity: var(--onion, 0.5);\n background: transparent;\n }\n &[data-view=\"swipe\"] .stage__divider {\n position: relative;\n display: block;\n z-index: 3;\n justify-self: start;\n width: 2px;\n height: 100%;\n margin-left: var(--swipe, 50%);\n background: var(--accent);\n pointer-events: none;\n }\n /* The only part of the divider that takes pointer input: drag it to wipe. */\n .stage__knob {\n position: absolute;\n top: 50%;\n left: 50%;\n display: grid;\n place-items: center;\n width: 32px;\n height: 32px;\n transform: translate(-50%, -50%);\n background: var(--accent);\n color: var(--accent-contrast);\n border: 2px solid var(--surface-card);\n border-radius: var(--radius-pill);\n box-shadow: var(--shadow-2);\n font-size: var(--text-lg);\n line-height: 1;\n cursor: ew-resize;\n pointer-events: auto;\n touch-action: none;\n user-select: none;\n }\n &[data-view=\"flip\"] .stage__grid {\n cursor: pointer;\n }\n &[data-view=\"swipe\"] .stage__controls[data-for=\"swipe\"],\n &[data-view=\"onion\"] .stage__controls[data-for=\"onion\"] {\n display: flex;\n }\n`;\n\nconst MODES = [\n { label: \"Side by side\", value: \"split\" },\n { label: \"Swipe\", value: \"swipe\" },\n { label: \"Onion skin\", value: \"onion\" },\n { label: \"Diff\", value: \"diff\" },\n { label: \"Flip\", value: \"flip\" },\n];\n\nconst ZOOMS = [\n { label: \"Fit\", value: \"fit\" },\n { label: \"100%\", value: \"100\" },\n { label: \"200%\", value: \"200\" },\n { label: \"400%\", value: \"400\" },\n];\n\n/** Modes and zoom a design comparison offers: no pixel diff, and the render always fits the stage. */\nconst DESIGN_MODES = [\"split\", \"swipe\", \"onion\"];\n\nfunction withActive(\n items: { label: string; value: string }[],\n active: string,\n): { label: string; value: string; active: boolean }[] {\n return items.map((item) => ({ ...item, active: item.value === active }));\n}\n\ninterface PaneProps {\n kind: \"baseline\" | \"current\" | \"diff\";\n label: string;\n src: string | null;\n alt: string;\n empty: unknown;\n meta?: string;\n}\n\nconst Pane: FC<PaneProps> = ({ kind, label, src, alt, empty, meta }) => {\n return (\n <div class=\"stage__pane\" data-pane={kind}>\n <div class=\"stage__label\">\n <span>{label}</span>\n {meta ? <span>{meta}</span> : null}\n </div>\n {src ? (\n <img class=\"stage__img\" src={src} alt={alt} loading=\"lazy\" decoding=\"async\" />\n ) : (\n <div class=\"stage__empty\">{empty}</div>\n )}\n </div>\n );\n};\n\n/** Swipe and onion-skin sliders; each is shown only in its own mode (CSS). */\nconst RangeControls: FC<{ baselineLabel: string }> = ({ baselineLabel }) => {\n return (\n <>\n <label class=\"stage__controls\" data-for=\"swipe\">\n <span>{baselineLabel}</span>\n <input type=\"range\" min=\"0\" max=\"100\" value=\"50\" data-compare-swipe aria-label=\"Swipe\" />\n <span>Current</span>\n </label>\n <label class=\"stage__controls\" data-for=\"onion\">\n <span>{baselineLabel}</span>\n <input type=\"range\" min=\"0\" max=\"100\" value=\"50\" data-compare-onion aria-label=\"Opacity\" />\n <span>Current</span>\n </label>\n </>\n );\n};\n\n/** Props for the screenshot comparison surface. */\nexport interface CompareStageProps {\n /** Baseline image URL, or null when the story has no baseline yet. */\n baselineSrc: string | null;\n currentSrc: string;\n /** Diff overlay URL, or null when none was produced. */\n diffSrc: string | null;\n /** Accessible description shared by the images, e.g. \"Button / Primary\". */\n subject: string;\n baselineEmpty?: unknown;\n diffEmpty?: unknown;\n diffMeta?: string;\n /**\n * `design` compares the screenshot with a design render instead of a baseline: side by side,\n * swipe and onion only (no diff, no flip), fit zoom only.\n */\n variant?: \"baseline\" | \"design\";\n /** Name of the left-hand image in labels and sliders (default \"Baseline\"). */\n baselineLabel?: string;\n /** A line under the controls, e.g. what the left-hand image is. */\n note?: string;\n}\n\n/** Mode switch, plus the zoom switch (a design comparison always fits, so it has none). */\nconst StageBar: FC<{ design: boolean }> = ({ design }) => {\n const modes = design ? MODES.filter((mode) => DESIGN_MODES.includes(mode.value)) : MODES;\n return (\n <div class=\"stage__bar\">\n <Segmented label=\"Comparison mode\" data-compare-mode items={withActive(modes, \"split\")} />\n {design ? null : (\n <Segmented label=\"Zoom\" data-compare-zoom items={withActive(ZOOMS, \"fit\")} />\n )}\n </div>\n );\n};\n\n/** The panes (baseline or design, current, diff) and the swipe divider. */\nconst StageGrid: FC<CompareStageProps & { design: boolean; baselineLabel: string }> = ({\n baselineSrc,\n currentSrc,\n diffSrc,\n subject,\n baselineEmpty = \"New story — no baseline yet. Approve to set the baseline.\",\n diffEmpty = \"No diff\",\n diffMeta,\n design,\n baselineLabel,\n}) => (\n <div class=\"stage__grid\">\n <Pane\n kind=\"baseline\"\n label={baselineLabel}\n src={baselineSrc}\n alt={`${baselineLabel} for ${subject}`}\n empty={baselineEmpty}\n />\n <Pane\n kind=\"current\"\n label=\"Current\"\n src={currentSrc}\n alt={`Current for ${subject}`}\n empty=\"No screenshot\"\n />\n {design ? null : (\n <Pane\n kind=\"diff\"\n label=\"Diff\"\n src={diffSrc}\n alt={`Diff for ${subject}`}\n empty={diffEmpty}\n meta={diffMeta}\n />\n )}\n <span class=\"stage__divider\" aria-hidden=\"true\">\n <span class=\"stage__knob\" data-compare-knob>\n ↔\n </span>\n </span>\n </div>\n);\n\n/** Baseline / current / diff comparison with swipe, onion-skin, flip, and zoom. */\nexport const CompareStage: FC<CompareStageProps> = ({\n variant = \"baseline\",\n baselineLabel = \"Baseline\",\n note,\n ...images\n}) => {\n const design = variant === \"design\";\n return (\n <div\n class={stageRoot}\n data-compare\n data-view=\"split\"\n data-zoom=\"fit\"\n data-flip=\"current\"\n data-variant={variant}\n data-modes={design ? DESIGN_MODES.join(\",\") : undefined}\n data-zooms={design ? \"fit\" : undefined}\n >\n <StageBar design={design} />\n {note ? <p class=\"stage__note\">{note}</p> : null}\n <StageGrid {...images} design={design} baselineLabel={baselineLabel} />\n <RangeControls baselineLabel={baselineLabel} />\n </div>\n );\n};\n"],"mappings":"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"}
|
package/dist/ui/csrf-field.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { getStore } from "../store.mjs";
|
|
5
5
|
import { getCsrfToken } from "../middleware/csrf.mjs";
|
|
6
6
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/csrf-field.tsx
|
|
8
8
|
/** Hidden CSRF token so native (non-HTMX) form posts pass the csrf middleware. */
|
|
9
9
|
function csrfField() {
|
|
10
10
|
const { config, sessionId } = getStore();
|
|
@@ -14,7 +14,6 @@ function csrfField() {
|
|
|
14
14
|
value: getCsrfToken(config.secret, sessionId)
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
|
-
//#endregion
|
|
18
17
|
export { csrfField };
|
|
19
18
|
|
|
20
19
|
//# sourceMappingURL=csrf-field.mjs.map
|
package/dist/ui/css.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import "node:path";
|
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { createCssContext } from "hono/css";
|
|
5
|
-
|
|
5
|
+
// src/ui/css.ts
|
|
6
6
|
/**
|
|
7
7
|
* hono/css building blocks for the server-rendered UI.
|
|
8
8
|
*
|
|
@@ -30,7 +30,6 @@ const context = createCssContext({
|
|
|
30
30
|
const css = (strings, ...values) => context.css(strings, ...values);
|
|
31
31
|
/** Collects every used class into `<style id="storyshelf-css">`. */
|
|
32
32
|
const Style = (args) => context.Style(args);
|
|
33
|
-
//#endregion
|
|
34
33
|
export { Style, css };
|
|
35
34
|
|
|
36
35
|
//# sourceMappingURL=css.mjs.map
|
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Icon } from "./icons/icon.mjs";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/design-reference.tsx
|
|
8
8
|
const referenceRoot = css`
|
|
9
9
|
/* design-reference */
|
|
10
10
|
display: grid;
|
|
@@ -91,7 +91,6 @@ const DesignPreview = ({ src, name, providerName }) => /* @__PURE__ */ jsxs(Frag
|
|
|
91
91
|
class: previewCaption,
|
|
92
92
|
children: name
|
|
93
93
|
}) : null] });
|
|
94
|
-
//#endregion
|
|
95
94
|
export { DesignPreview, DesignReference };
|
|
96
95
|
|
|
97
96
|
//# sourceMappingURL=design-reference.mjs.map
|
package/dist/ui/document.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { baseStyle } from "./styles.mjs";
|
|
|
13
13
|
import { DARK_THEME, LIGHT_THEME } from "./theme.mjs";
|
|
14
14
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
15
15
|
import { raw } from "hono/html";
|
|
16
|
-
|
|
16
|
+
// src/ui/document.tsx
|
|
17
17
|
const shellRoot = css`
|
|
18
18
|
/* shell */
|
|
19
19
|
display: grid;
|
|
@@ -123,7 +123,6 @@ const DocumentLayout = ({ title, nav, layout = "default", children }) => {
|
|
|
123
123
|
] })]
|
|
124
124
|
})] });
|
|
125
125
|
};
|
|
126
|
-
//#endregion
|
|
127
126
|
export { DocumentLayout };
|
|
128
127
|
|
|
129
128
|
//# sourceMappingURL=document.mjs.map
|
package/dist/ui/dropdown.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Icon } from "./icons/icon.mjs";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/dropdown.tsx
|
|
8
8
|
const dropdownRoot = css`
|
|
9
9
|
/* dropdown */
|
|
10
10
|
position: relative;
|
|
@@ -175,7 +175,6 @@ const DropdownDivider = () => {
|
|
|
175
175
|
role: "separator"
|
|
176
176
|
});
|
|
177
177
|
};
|
|
178
|
-
//#endregion
|
|
179
178
|
export { Dropdown, DropdownDivider, DropdownItem };
|
|
180
179
|
|
|
181
180
|
//# sourceMappingURL=dropdown.mjs.map
|
package/dist/ui/feedback.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Icon } from "./icons/icon.mjs";
|
|
6
6
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/feedback.tsx
|
|
8
8
|
const badgeBase = css`
|
|
9
9
|
/* badge */
|
|
10
10
|
display: inline-flex;
|
|
@@ -335,7 +335,6 @@ const Meta = ({ as = "p", mono = false, tone = "neutral", center = false, childr
|
|
|
335
335
|
children
|
|
336
336
|
});
|
|
337
337
|
};
|
|
338
|
-
//#endregion
|
|
339
338
|
export { Alert, Badge, EmptyState, Meta, Stat, statusTone };
|
|
340
339
|
|
|
341
340
|
//# sourceMappingURL=feedback.mjs.map
|
package/dist/ui/filter-input.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Icon } from "./icons/icon.mjs";
|
|
6
6
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/filter-input.tsx
|
|
8
8
|
const filterWrap = css`
|
|
9
9
|
/* filter-input */
|
|
10
10
|
position: relative;
|
|
@@ -52,7 +52,6 @@ const FilterInput = ({ label, placeholder = "Filter…" }) => {
|
|
|
52
52
|
})]
|
|
53
53
|
});
|
|
54
54
|
};
|
|
55
|
-
//#endregion
|
|
56
55
|
export { FilterInput };
|
|
57
56
|
|
|
58
57
|
//# sourceMappingURL=filter-input.mjs.map
|
package/dist/ui/forms.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Icon } from "./icons/icon.mjs";
|
|
6
6
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/forms.tsx
|
|
8
8
|
const fieldWrap = css`
|
|
9
9
|
/* field */
|
|
10
10
|
display: grid;
|
|
@@ -286,7 +286,6 @@ const SelectField = ({ label, name, value, options, hint, disabled, required, la
|
|
|
286
286
|
]
|
|
287
287
|
});
|
|
288
288
|
};
|
|
289
|
-
//#endregion
|
|
290
289
|
export { CheckField, Field, FormActions, SelectField, TextareaField };
|
|
291
290
|
|
|
292
291
|
//# sourceMappingURL=forms.mjs.map
|
package/dist/ui/icons/icon.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import.meta.url;
|
|
|
4
4
|
import { css } from "../css.mjs";
|
|
5
5
|
import { iconHref } from "./sprite.mjs";
|
|
6
6
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
7
|
-
|
|
7
|
+
// src/ui/icons/icon.tsx
|
|
8
8
|
const iconBase = css`
|
|
9
9
|
/* icon */
|
|
10
10
|
flex: none;
|
|
@@ -47,7 +47,6 @@ const Icon = ({ name, size = "md", label }) => {
|
|
|
47
47
|
children: /* @__PURE__ */ jsx("use", { href: iconHref(name) })
|
|
48
48
|
});
|
|
49
49
|
};
|
|
50
|
-
//#endregion
|
|
51
50
|
export { Icon };
|
|
52
51
|
|
|
53
52
|
//# sourceMappingURL=icon.mjs.map
|
package/dist/ui/icons/paths.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/ui/icons/paths.ts
|
|
5
5
|
/**
|
|
6
6
|
* Icon set: inner SVG markup per icon on a 24x24 grid, stroke-based
|
|
7
7
|
* (Lucide-style, ISC). Add an icon here and it is in the sprite and the
|
|
@@ -56,7 +56,6 @@ const ICON_PATHS = {
|
|
|
56
56
|
book: "<path d=\"M4 19.5v-15A2.5 2.5 0 0 1 6.5 2H20v20H6.5a2.5 2.5 0 0 1 0-5H20\"/>",
|
|
57
57
|
server: "<rect width=\"20\" height=\"8\" x=\"2\" y=\"2\" rx=\"2\"/><rect width=\"20\" height=\"8\" x=\"2\" y=\"14\" rx=\"2\"/><path d=\"M6 6h.01M6 18h.01\"/>"
|
|
58
58
|
};
|
|
59
|
-
//#endregion
|
|
60
59
|
export { ICON_PATHS };
|
|
61
60
|
|
|
62
61
|
//# sourceMappingURL=paths.mjs.map
|
package/dist/ui/icons/sprite.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { ICON_PATHS } from "./paths.mjs";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
|
-
|
|
6
|
+
// src/ui/icons/sprite.ts
|
|
7
7
|
/** Assembled `<svg>` sprite of `<symbol id="i-<name>">` entries. */
|
|
8
8
|
function buildSprite(paths = ICON_PATHS) {
|
|
9
9
|
return `<svg xmlns="http://www.w3.org/2000/svg">${Object.entries(paths).toSorted(([a], [b]) => a.localeCompare(b)).map(([name, body]) => `<symbol id="i-${name}" viewBox="0 0 24 24">${body}</symbol>`).join("")}</svg>`;
|
|
@@ -20,7 +20,6 @@ const iconSpriteHref = `/assets/icons-${iconSpriteHash}.svg`;
|
|
|
20
20
|
function iconHref(name) {
|
|
21
21
|
return `${iconSpriteHref}#i-${name}`;
|
|
22
22
|
}
|
|
23
|
-
//#endregion
|
|
24
23
|
export { buildSprite, contentHash, iconHref, iconSprite, iconSpriteHash, iconSpriteHref };
|
|
25
24
|
|
|
26
25
|
//# sourceMappingURL=sprite.mjs.map
|
package/dist/ui/kbd.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { Fragment, jsx } from "hono/jsx/jsx-runtime";
|
|
6
|
-
|
|
6
|
+
// src/ui/kbd.tsx
|
|
7
7
|
const kbdKey = css`
|
|
8
8
|
/* kbd */
|
|
9
9
|
display: inline-flex;
|
|
@@ -27,7 +27,6 @@ const Kbd = ({ keys }) => {
|
|
|
27
27
|
children: key
|
|
28
28
|
}, String(index))) });
|
|
29
29
|
};
|
|
30
|
-
//#endregion
|
|
31
30
|
export { Kbd };
|
|
32
31
|
|
|
33
32
|
//# sourceMappingURL=kbd.mjs.map
|
package/dist/ui/layout.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
6
|
-
|
|
6
|
+
// src/ui/layout.tsx
|
|
7
7
|
const cardBase = css`
|
|
8
8
|
/* card */
|
|
9
9
|
background: var(--surface-card);
|
|
@@ -167,7 +167,6 @@ const SectionTitle = ({ level = 2, tone = "neutral", children }) => {
|
|
|
167
167
|
children
|
|
168
168
|
});
|
|
169
169
|
};
|
|
170
|
-
//#endregion
|
|
171
170
|
export { Card, CardSection, PageHeader, SectionTitle };
|
|
172
171
|
|
|
173
172
|
//# sourceMappingURL=layout.mjs.map
|
|
@@ -5,7 +5,7 @@ import { css } from "./css.mjs";
|
|
|
5
5
|
import { Button } from "./buttons.mjs";
|
|
6
6
|
import { Meta } from "./feedback.mjs";
|
|
7
7
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
8
|
-
|
|
8
|
+
// src/ui/preview-embed.tsx
|
|
9
9
|
/**
|
|
10
10
|
* Sandbox of the embedded story frame (ADR 0006, decision 9). Scripts only: no `allow-same-origin`,
|
|
11
11
|
* so a customer's Storybook never runs with the app's origin and its cookies, and no top navigation,
|
|
@@ -76,7 +76,6 @@ const PreviewEmbed = ({ src, title, refresh }) => /* @__PURE__ */ jsxs("div", {
|
|
|
76
76
|
})
|
|
77
77
|
})]
|
|
78
78
|
});
|
|
79
|
-
//#endregion
|
|
80
79
|
export { PREVIEW_SANDBOX, PreviewEmbed };
|
|
81
80
|
|
|
82
81
|
//# sourceMappingURL=preview-embed.mjs.map
|
package/dist/ui/progress.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
6
|
-
|
|
6
|
+
// src/ui/progress.tsx
|
|
7
7
|
const track = css`
|
|
8
8
|
/* progress */
|
|
9
9
|
height: 6px;
|
|
@@ -38,7 +38,6 @@ const Progress = ({ value, max, label }) => {
|
|
|
38
38
|
children: /* @__PURE__ */ jsx("span", { style: `width:${percent}%` })
|
|
39
39
|
});
|
|
40
40
|
};
|
|
41
|
-
//#endregion
|
|
42
41
|
export { Progress };
|
|
43
42
|
|
|
44
43
|
//# sourceMappingURL=progress.mjs.map
|
package/dist/ui/segmented.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { css } from "./css.mjs";
|
|
5
5
|
import { jsx } from "hono/jsx/jsx-runtime";
|
|
6
|
-
|
|
6
|
+
// src/ui/segmented.tsx
|
|
7
7
|
const segmentedRoot = css`
|
|
8
8
|
/* segmented */
|
|
9
9
|
display: inline-flex;
|
|
@@ -71,7 +71,6 @@ const Segmented = ({ items, label, ...rest }) => {
|
|
|
71
71
|
}, item.value))
|
|
72
72
|
});
|
|
73
73
|
};
|
|
74
|
-
//#endregion
|
|
75
74
|
export { Segmented };
|
|
76
75
|
|
|
77
76
|
//# sourceMappingURL=segmented.mjs.map
|
|
@@ -10,7 +10,7 @@ import { Dropdown, DropdownDivider, DropdownItem } from "../dropdown.mjs";
|
|
|
10
10
|
import { csrfField } from "../csrf-field.mjs";
|
|
11
11
|
import { Fragment, jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
12
12
|
import { safeImageUrl } from "@storyshelf/core/urls";
|
|
13
|
-
|
|
13
|
+
// src/ui/shell/account.tsx
|
|
14
14
|
/** Styles for the account widgets that live in the sidebar footer. */
|
|
15
15
|
const accountRoot = css`
|
|
16
16
|
/* account */
|
|
@@ -155,7 +155,6 @@ const UserMenu = () => {
|
|
|
155
155
|
})
|
|
156
156
|
});
|
|
157
157
|
};
|
|
158
|
-
//#endregion
|
|
159
158
|
export { ThemeMenu, UserMenu };
|
|
160
159
|
|
|
161
160
|
//# sourceMappingURL=account.mjs.map
|
package/dist/ui/shell/bare.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { css } from "../css.mjs";
|
|
|
5
5
|
import { Icon } from "../icons/icon.mjs";
|
|
6
6
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
7
7
|
import { safeImageUrl } from "@storyshelf/core/urls";
|
|
8
|
-
|
|
8
|
+
// src/ui/shell/bare.tsx
|
|
9
9
|
/** Chrome-free page for signed-out flows: brand over a centered column. */
|
|
10
10
|
const bareRoot = css`
|
|
11
11
|
/* bare */
|
|
@@ -63,7 +63,6 @@ const BareShell = ({ name, logo, children }) => {
|
|
|
63
63
|
})]
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
|
-
//#endregion
|
|
67
66
|
export { BareShell };
|
|
68
67
|
|
|
69
68
|
//# sourceMappingURL=bare.mjs.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/ui/shell/boot-script.ts
|
|
5
5
|
/**
|
|
6
6
|
* Runs in `<head>` before first paint so the saved theme and sidebar state
|
|
7
7
|
* apply without a flash. Exposes cookie helpers to the client script.
|
|
@@ -40,7 +40,6 @@ function bootScript() {
|
|
|
40
40
|
})();
|
|
41
41
|
`.trim();
|
|
42
42
|
}
|
|
43
|
-
//#endregion
|
|
44
43
|
export { bootScript };
|
|
45
44
|
|
|
46
45
|
//# sourceMappingURL=boot-script.mjs.map
|
|
@@ -3,7 +3,7 @@ import "node:url";
|
|
|
3
3
|
import.meta.url;
|
|
4
4
|
import { iconSpriteHref } from "../icons/sprite.mjs";
|
|
5
5
|
import { reviewScript } from "./review-script.mjs";
|
|
6
|
-
|
|
6
|
+
// src/ui/shell/client-script.ts
|
|
7
7
|
/** Attach the CSRF token to every HTMX request. */
|
|
8
8
|
function csrfPart() {
|
|
9
9
|
return `
|
|
@@ -338,7 +338,6 @@ function clientScript() {
|
|
|
338
338
|
})();
|
|
339
339
|
`.trim();
|
|
340
340
|
}
|
|
341
|
-
//#endregion
|
|
342
341
|
export { clientScript };
|
|
343
342
|
|
|
344
343
|
//# sourceMappingURL=client-script.mjs.map
|
package/dist/ui/shell/nav.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "node:path";
|
|
2
2
|
import "node:url";
|
|
3
3
|
import.meta.url;
|
|
4
|
-
|
|
4
|
+
// src/ui/shell/nav.ts
|
|
5
5
|
/**
|
|
6
6
|
* Entries shown for the current project. Entries for `testing` routes (Jobs) drop out on a
|
|
7
7
|
* hosting-only instance, where those routes answer 404.
|
|
@@ -109,7 +109,6 @@ function sectionCrumb(nav, urls) {
|
|
|
109
109
|
}
|
|
110
110
|
}[nav?.active ?? ""] ?? null;
|
|
111
111
|
}
|
|
112
|
-
//#endregion
|
|
113
112
|
export { adminNavItems, breadcrumbs, developerNavItems, projectNavItems };
|
|
114
113
|
|
|
115
114
|
//# sourceMappingURL=nav.mjs.map
|