@supersuit/artifacts 0.28.0 → 0.29.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/CHANGELOG.md CHANGED
@@ -3,6 +3,21 @@
3
3
  `@supersuit/artifacts`. One entry per version, newest first. Each entry says what changed, how a
4
4
  host can tell whether it is affected (DETECTOR), what a host does about it (REMEDY), and the tests.
5
5
 
6
+ ## 0.29.0
7
+
8
+ **The "comment can't be shown" notice is a readable card with a way in.** 0.28.0 drew it as a pill
9
+ across the top of the page, over the title, and told a signed-out reader to sign in with nothing to
10
+ press.
11
+
12
+ - A card at the top of the screen, inset from the edges, at most 24rem wide, with the message, a
13
+ close button and, for a signed-out reader, a **Sign in** button.
14
+ - Sign in returns to the exact address, `#comment-<id>` included, so the reader lands on the
15
+ comment once signed in.
16
+ - DETECTOR: open a link to a comment you cannot see, signed out. A pill with no button means 0.28.0.
17
+ - REMEDY: update the dependency.
18
+ - Tests: `comment-layer.test.tsx` (the Sign in link returns to the comment's address). `test:packed`
19
+ green.
20
+
6
21
  ## 0.28.0
7
22
 
8
23
  **A link to a comment opens for the page's admins, and says so when it cannot.** On an owner-only
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  // Comments on any part of a page, Figma style. Select text and a "Comment" chip appears; hold and
4
4
  // drag over anything that is not text (an image, a table, the gap between paragraphs) and a box
5
5
  // draws. Either opens the card (comment-card.tsx), which says before anything is typed whether
@@ -37,6 +37,18 @@ import { boxOf, headingAt, indexText, offsetAt, placeAnchor, regionFrom } from '
37
37
  const isValue = (v) => !!v && typeof v === 'object' && typeof v.body === 'string' && !!v.anchor && typeof v.anchor === 'object';
38
38
  const LONG_PRESS_MS = 400;
39
39
  const HASH = /^#comment-([A-Za-z0-9_-]{1,128})$/;
40
+ /** The sign-in link, returning to this exact address, hash included, so a reader who signs in to
41
+ * see a linked comment lands on it. */
42
+ function signInBack(signIn) {
43
+ try {
44
+ const u = new URL(signIn);
45
+ u.searchParams.set('to', window.location.href);
46
+ return u.toString();
47
+ }
48
+ catch {
49
+ return signIn;
50
+ }
51
+ }
40
52
  /** The entry id a `#comment-<id>` hash names, or null. */
41
53
  const commentHashId = (hash) => HASH.exec(hash)?.[1] ?? null;
42
54
  const DRAG_PX = 8;
@@ -480,7 +492,7 @@ export function CommentLayer({ artifactId, rootId, ownerName, comments, canShare
480
492
  const open = layout.placed.find((p) => p.item.id === thread);
481
493
  const openItem = open?.item ?? layout.earlier.find((i) => i.id === thread);
482
494
  const count = tops.length;
483
- const overlay = mounted ? (_jsxs("div", { "data-comment-ui": true, "data-nospeak": true, className: "font-sans", style: theme, children: [missing ? (_jsxs("div", { "data-comment-missing": true, role: "status", className: "fixed left-1/2 top-4 z-50 flex -translate-x-1/2 items-center gap-2 rounded-full border border-[color:var(--a-line-strong)] bg-[color:var(--a-surface)] px-4 py-2 text-sm text-[color:var(--a-strong)] shadow-lg", children: [_jsxs("span", { children: ["That comment can't be shown to you. Comments on this page are visible to its owner and admins", signedIn ? '' : '; sign in if that is you', "."] }), _jsx("button", { type: "button", "aria-label": "Close", onClick: () => setMissing(false), className: "opacity-70", children: "\u00D7" })] })) : null, showPins ? layout.placed.map(({ item, left, top, box }) => (_jsxs("div", { children: [box ? (_jsx("div", { "data-comment-box": item.id, "aria-hidden": true, className: "pointer-events-none absolute z-30 rounded-md border-2", style: { left: box.left, top: box.top, width: box.width, height: box.height, borderColor: accent, borderStyle: item.kind === 'personal' ? 'dashed' : 'solid', opacity: thread === item.id ? 1 : 0.55 } })) : null, _jsx(Pin, { item: item, left: left, top: top, accent: accent, ground: ground, onOpen: () => setThread(thread === item.id ? null : item.id) })] }, item.id))) : null, chip && !draft ? (
495
+ const overlay = mounted ? (_jsxs("div", { "data-comment-ui": true, "data-nospeak": true, className: "font-sans", style: theme, children: [missing ? (_jsxs("div", { "data-comment-missing": true, role: "status", className: "fixed inset-x-3 top-3 z-50 mx-auto max-w-sm rounded-xl border border-[color:var(--a-line-strong)] bg-[color:var(--a-surface)] p-4 font-sans text-sm leading-snug text-[color:var(--a-strong)] shadow-xl", children: [_jsxs("div", { className: "flex items-start gap-3", children: [_jsx("p", { className: "m-0 flex-1", children: "That comment can't be shown to you. Comments on this page are visible to its owner and admins." }), _jsx("button", { type: "button", "aria-label": "Close", onClick: () => setMissing(false), className: "-mr-1 -mt-1 px-1 text-lg leading-none opacity-60", children: "\u00D7" })] }), !signedIn && signIn ? (_jsx("a", { "data-comment-missing-sign-in": true, href: signInBack(signIn), className: "mt-3 inline-block rounded-full px-4 py-1.5 font-medium no-underline", style: { background: accent, color: 'var(--a-on-accent, #111)' }, children: "Sign in" })) : null] })) : null, showPins ? layout.placed.map(({ item, left, top, box }) => (_jsxs("div", { children: [box ? (_jsx("div", { "data-comment-box": item.id, "aria-hidden": true, className: "pointer-events-none absolute z-30 rounded-md border-2", style: { left: box.left, top: box.top, width: box.width, height: box.height, borderColor: accent, borderStyle: item.kind === 'personal' ? 'dashed' : 'solid', opacity: thread === item.id ? 1 : 0.55 } })) : null, _jsx(Pin, { item: item, left: left, top: top, accent: accent, ground: ground, onOpen: () => setThread(thread === item.id ? null : item.id) })] }, item.id))) : null, chip && !draft ? (
484
496
  // On a phone the button sits at the TOP of the screen, never beside the selection: that is
485
497
  // where iOS draws its own Copy / Look Up menu, and the two fought for the same tap (Gary,
486
498
  // 2026-09-29: "I keep trying to fight with the Apple pop-up"). A mouse keeps it by the text.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supersuit/artifacts",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "Publish markdown as branded, read-aloud pages from a Next.js app: the artifacts store, the route factory, the read-along reader, brand packs, password and confidential pages, and share cards.",
5
5
  "license": "MIT",
6
6
  "type": "module",