diff --git a/frontend/src/components/ArtistSupportLink.tsx b/frontend/src/components/ArtistSupportLink.tsx index 5e9d8704f..efa797820 100644 --- a/frontend/src/components/ArtistSupportLink.tsx +++ b/frontend/src/components/ArtistSupportLink.tsx @@ -66,9 +66,18 @@ const LINK_TYPE_LABELS: Record = { instagram: "Instagram", }; +// The button shell - wraps the collapsed row and (once expanded) the disclosure panel, so the +// panel renders within the same widget boundary as the link/toggle rather than as an unrelated +// sibling block below it (issue #747). +const CompactLine = styled.div` + display: flex; + flex-direction: column; + min-width: 0; +`; + // The collapsed row - primary link + toggle - never wraps to a second line, regardless of how // narrow the caller's container is (the question feed's illustration credit caps it at 220px). -const CompactLine = styled.div` +const CompactLineRow = styled.div` display: flex; align-items: center; gap: 6px; @@ -149,76 +158,80 @@ export function ArtistSupportLink({ data-testid="artist-support-applet" > - - {artistName} - - - setExpanded((previous) => !previous)} - aria-expanded={expanded} - aria-controls={expandedPanelId} - data-testid="artist-support-toggle" - > - - - {expanded ? "Hide artist links" : "Show more artist links"} - - - - {expanded && ( -
- {commerceLinks.length > 0 && ( + + + {artistName} + + + setExpanded((previous) => !previous)} + aria-expanded={expanded} + aria-controls={expandedPanelId} + data-testid="artist-support-toggle" + > + + + {expanded ? "Hide artist links" : "Show more artist links"} + + + + {expanded && ( +
+ {commerceLinks.length > 0 && ( +
+ {commerceLinks.map((link) => ( + + {LINK_TYPE_LABELS[link.type] ?? link.type}{" "} + + + ))} +
+ )} + {hasSignatureService && ( + + Mark's Signature Service + + )}
- {commerceLinks.map((link) => ( - - {LINK_TYPE_LABELS[link.type] ?? link.type}{" "} - - - ))} + Source:{" "} + + {MTGArtistConnection} +
- )} - {hasSignatureService && ( - - Mark's Signature Service - - )} -
- Source:{" "} - - {MTGArtistConnection} -
-
- )} + )} +
); } diff --git a/frontend/src/features/display/ArtistSection.tsx b/frontend/src/features/display/ArtistSection.tsx index e6cdca362..e0c80bab8 100644 --- a/frontend/src/features/display/ArtistSection.tsx +++ b/frontend/src/features/display/ArtistSection.tsx @@ -10,7 +10,8 @@ * page link, the MTGAC credit line) rather than a single caller-styled `` wrapping caller- * supplied `children` - this caller no longer passes `className`/children for button styling, * the applet owns its own layout ("buttons stretch to fill the applet", owner instruction). The - * plain credit line ("Art by ") stays separate, non-linked text above the applet. + * applet's own page-link button already names the artist, so this caller renders no separate + * name label alongside it (issue #747). * * Upstream-divergence note (docs/upstreaming/readiness-audit.md's styling-divergence ledger): * chilli-axe/mpc-autofill has no artist-support surface at all - ArtistSupportLink is a @@ -39,18 +40,10 @@ export function ArtistSection({ cardDocument }: ArtistSectionProps) { return (
{cardDocument.canonicalArtist != null ? ( - <> -
- Art by{" "} - - {cardDocument.canonicalArtist.name} - -
- - + ) : ( Unknown )} diff --git a/frontend/src/features/questionFeed/QuestionFeed.tsx b/frontend/src/features/questionFeed/QuestionFeed.tsx index fe280ade0..e85943e28 100644 --- a/frontend/src/features/questionFeed/QuestionFeed.tsx +++ b/frontend/src/features/questionFeed/QuestionFeed.tsx @@ -747,8 +747,8 @@ export function QuestionFeed() { const [fetchToken, setFetchToken] = useState(0); // Artist Support Links v1 - set once the user casts a real (non-"Unknown") artist vote on an // "artist"-type item, via ArtistVotePicker's onArtistConfirmed below. Drives the post-answer - // "Art by - support them" banner - reset on every new item alongside the other - // per-question state, so it can't bleed into the next question. + // ArtistSupportLink banner - reset on every new item alongside the other per-question state, + // so it can't bleed into the next question. const [confirmedArtistName, setConfirmedArtistName] = useState( null ); @@ -1711,9 +1711,6 @@ export function QuestionFeed() { {illustrationArtist != null && ( -
- Illustration by {illustrationArtist} -
)} @@ -1869,9 +1866,6 @@ export function QuestionFeed() { /> {confirmedArtistName != null && (
-
- Art by {confirmedArtistName} - support them -
)} diff --git a/frontend/tests/DisplayPage.spec.ts b/frontend/tests/DisplayPage.spec.ts index df9635cc7..df722f514 100644 --- a/frontend/tests/DisplayPage.spec.ts +++ b/frontend/tests/DisplayPage.spec.ts @@ -928,7 +928,7 @@ test.describe("DisplayPage (Proposal H, Step 1)", () => { await expect(select).toHaveValue("force-bleed"); }); - test("the promoted artist line shows a plain credit + the MTG Artist Connection applet (page-link button, credit line) for a card with a known canonical artist (M2 applet round, docs/features/artist-support-links.md)", async ({ + test("the promoted artist line shows the MTG Artist Connection applet (page-link button, credit line) for a card with a known canonical artist (M2 applet round, docs/features/artist-support-links.md)", async ({ page, network, }) => { @@ -943,14 +943,6 @@ test.describe("DisplayPage (Proposal H, Step 1)", () => { await importTextOnEditorLanding(page, "1 card 8 (xyz) 001"); await page.getByTestId("page-preview-slot").first().click(); - // Plain (non-linked) credit line names the artist. - await expect(page.getByTestId("display-artist-section")).toContainText( - "Art by" - ); - await expect(page.getByTestId("display-artist-section")).toContainText( - "Alpha Artist" - ); - // M2 round: ArtistSupportLink is now a self-contained applet (RTK Query fetch, no // caller-supplied children/className for button styling - see ArtistSupportLink.tsx's own // module docstring). The primary page-link button now names the ARTIST (the applet's own diff --git a/frontend/tests/QuestionFeed.spec.ts b/frontend/tests/QuestionFeed.spec.ts index 2e3258420..038cb6540 100644 --- a/frontend/tests/QuestionFeed.spec.ts +++ b/frontend/tests/QuestionFeed.spec.ts @@ -879,9 +879,9 @@ test.describe("question feed - artist question type", () => { ).toBeVisible(); }); - // Artist Support Links v1 - the post-answer moment ("Art by - support them"), a - // zero-crawl link-out to MTG Artist Connection built deterministically from the artist name - // the user just voted for. See docs/features/artist-support-links.md. + // Artist Support Links v1 - the post-answer moment, a zero-crawl link-out to MTG Artist + // Connection built deterministically from the artist name the user just voted for. See + // docs/features/artist-support-links.md. test("voting for a named artist shows the Artist Support Link, built from that artist's name", async ({ page, network, @@ -907,10 +907,8 @@ test.describe("question feed - artist question type", () => { const banner = page.getByTestId("question-feed-artist-support"); await expect(banner).toBeVisible(); - await expect(banner).toContainText( - `Art by ${canonicalArtist1.name} - support them` - ); const link = banner.getByTestId("artist-support-link"); + await expect(link).toContainText(canonicalArtist1.name); await expect(link).toHaveAttribute( "href", `https://www.mtgartistconnection.com/artist/${encodeURIComponent(