Repository navigation
Description
Plans execution for #250 (Olivia / 0xOlivanode, "[Feature] Widget showcase in storybook"). Preserves #250's content unchanged.
Approved by Olivia (Bounty Lead) on 2026-10-14, contingent on the six-point revision below landing — it has. Executed under job-gw250-exec; PR #253 opened.
Reference files
GoodDollar/GoodWidget (verified against main @ 291142f)
Reference pattern (already aligned, not touched by this plan):
examples/storybook/src/stories/streaming-widget/{StreamingWidget.stories.tsx, StreamingWidgetThemeOverrides.stories.tsx, StreamingWidgetQA.stories.tsx, StreamingWidget.mdx}examples/storybook/src/stories/staking-migration-widget/{...same 4 files...}
Shared Storybook helpers to reuse as-is:
examples/storybook/src/stories/helpers/themeOverridePresets.ts— brand preset system (BRAND_PRESET_OPTIONS,brandPresetOverrides), widget-agnosticexamples/storybook/src/stories/helpers/withDefaultPreset.tsx— Theme overrides decoratorexamples/storybook/src/stories/docs/DocsLayout.tsx—DocsPage/DocsSection/DocsCard/DocsGrid/DocsCallout/DocsList, used by every MDX and Theme overrides file
Per-widget targets (current → target state, itemized in Execution plan below). Revised: new Theme overrides files in this plan wire controls only against primitive targets (dark_Card/light_Card, dark_Button/light_Button from packages/ui) — the widget-specific named targets noted below already exist in each widget's own source (pre-dating this bounty) but do not get dedicated story controls this round; that finer-grained coverage is a follow-up, not a gap:
citizen-claim-widget/{CitizenClaimWidgetShowcase.stories.tsx, CitizenClaimWidgetQA.stories.tsx, CitizenClaimWidget.mdx}+packages/citizen-claim-widget/src/CitizenClaimWidget.tsx(existing named theme targets, not newly created, not individually exposed this round:ClaimCard,ClaimActionGlow,ClaimActionRing,ClaimActionInner,TokenAmountText)goodreserve-widget/GoodReserveWidget.stories.tsx(single flat file, 22 stories, no MDX yet) +packages/goodreserve-widget/src/ReserveSwapView.tsx(existing named theme targets, not newly created, not individually exposed this round:ReserveSwapShell,ReserveAmountCard,ReserveSurface,ReserveSurfaceInner,ReserveDetailsTable,ReserveTokenBadge,ReserveSwapDirectionButton,ReserveSettingsButton,ReserveSuccessIcon,ReserveConfirmToBadge)governance-widget/{GovernanceWidgetShowcase.stories.tsx, GovernanceWidgetQA.stories.tsx, GovernanceWidgetThemeOverrides.stories.tsx (already exists, reference only), GovernanceOnboarding.stories.tsx, GovernanceWidget.mdx}ai-credits-widget/{AiCreditsWidgetShowcase.stories.tsx, AiCreditsWidgetQA.stories.tsx, AiCreditsWidget.mdx}+packages/ai-credits-widget/src/components/theme/cards.ts(existing named theme targets, not newly created, not individually exposed this round:AiCreditsStatusNotice,BonusBadgeFrame)superfluid-campaign-widget/{SuperfluidCampaignWidget.stories.tsx, SuperfluidCampaignWidgetQA.stories.tsx, SuperfluidCampaignWidgetApiContracts.stories.tsx, SuperfluidCampaignWidget.mdx}— has no named theme-component module at all (unlike the three above, there is no pre-existingshared.tsx-style target to point at); this is a real design-system gap, not just reduced story coverage this round — see New components / gaps logging below.gooddata-widget/GoodDataWidgetQA.stories.tsx(no MDX yet) +packages/gooddata-widget/src/{GoodDataWidget.tsx, dashboards/aiCredits/AiCreditsDashboard.tsx, dashboards/registry.ts}
No-op risk check (resolves Olivia's PR #73 concern), confirmed via packages/ui/src/presets.ts: ClaimCard, ClaimActionButton, and ClaimActionGlow already have dedicated light_*/dark_* presets of their own, so a plain dark_Card/dark_Button override is a no-op against CitizenClaimWidget's default/most-prominent claim surface, which renders through those named components instead — see that widget's Required states entry below for how the new Theme overrides file accounts for this. ReserveSwapView's family (GoodReserveWidget), AiCreditsStatusNotice/BonusBadgeFrame (AiCreditsWidget), and SuperfluidCampaignWidget (no named components at all) have no dedicated presets, so they correctly fall back to/cascade from Card's and Button's own theme — dark_Card/dark_Button overrides apply and visibly change those widgets as expected.
dark_/light_ pairing (resolves Olivia's second PR #73 concern): every new Theme overrides file in this plan wires a matching light_* control for every dark_* control it wires. Both existing reference files were re-checked and confirmed to only wire dark_* controls as live controls — StreamingWidgetThemeOverrides.stories.tsx (dark_Button/dark_StreamRow/dark_BalanceCard) and StakingMigrationWidgetThemeOverrides.stories.tsx (dark_ClaimCard/dark_ClaimActionGlow/dark_ClaimActionRing); light_* names appear only inside their documentation callout text, never as an actual wired control. New files in this bounty deliberately deviate from copying that part of the pattern. The two existing files' own light/dark gap is logged (not fixed here) under "[BountyPrep] Storybook: missing primitives and design system gaps" — see New components / gaps logging below.
Playwright specs needing hardcoded story-id updates (tests/widgets/**/*.spec.ts, testDir confirmed in playwright.config.ts):
tests/widgets/governance-widget/onboarding.spec.ts— 8 refs towidgets-governanceonboarding--*(title moves to the QA namespace)tests/widgets/superfluid-campaign-widget/states.spec.ts— 2 refs towidgets-superfluidcampaignwidget-api-contracts--*(title moves to QA)tests/widgets/gooddata-widget/states.spec.ts— 5 refs toqa-aicreditsdashboard-runtime-fixtures--*(title renames toqa-gooddatawidget-runtime-fixtures--*)tests/widgets/goodreserve-widget/states.spec.ts— 16 refs towidgets-goodreservewidget--*(file splits into Showcase/QA titles)tests/widgets/ai-credits-widget/states.spec.ts— verified no spec references the ShowcaseMockBackendstory id directly, so moving it to QA needs no spec edit; re-confirm during execution in case a new QA id collides with an existing fixture name.
GoodDollar/GoodProtocol
releases/deployment.json(repo root) — per-environment contract deployment map, 28 environment keys total. Relevant entries for the Celo-track environments these widgets actually use:- development-celo:
GoodDaoHouses(+FlowSplitter/PoolId/Pool),MentoReserve,GoodDollarStaking,Identity,UBIScheme,ClaimersDistribution - staging-celo:
MentoReserve,GoodDollarStaking,Identity,UBIScheme,ClaimersDistribution— noGoodDaoHouses - production-celo:
MentoReserve,Identity,UBIScheme— noGoodDaoHouses, noGoodDollarStaking - No Celo environment has Superfluid contracts — streaming-widget/superfluid-campaign-widget depend on the Superfluid SDK/subgraph, not a GoodProtocol Celo deployment entry
ai-credits-widgetandgooddata-widget: no matching contract entries at all anywhere in the file — both are off-chain/API-backed, not gated by this file- Environment options rule (revised): every Showcase environment control offers development/production only, never staging — even on widgets where a
staging-celoentry exists for the relevant contract (e.g.MentoReserve,Identity,UBISchemeall have staging-celo entries, but staging is never offered as a selectable option). An environment is only offered if both (a) the widget's contract/SDK actually supports that value, and (b) the contract is deployed per this file for that environment. - Revised further — a control must offer a genuine choice and the widget must already expose the prop: GoodReserveWidget has no
environmentprop anywhere in its source (confirmed via grep — zero matches), so no control is added for it; adding one would require apackages/goodreserve-widgetcode change, which this bounty does not make (see Required states below — logged as a gap instead). GovernanceWidget's only deployed environment forGoodDaoHousesisdevelopment-celo, so a single-value environment control is a pointless UI element — its control is dropped in favor of a static "development only" note inGovernanceWidget.mdx. CitizenClaimWidget already has anenvironmentprop today (confirmed via grep:packages/citizen-claim-widget/src/CitizenClaimWidget.tsx), and Identity/UBIScheme are deployed on both development-celo and production-celo, so it remains the only widget that gets a genuine development/production Showcase control.
- development-celo:
Required states, flows, and behaviors
Restates #250's per-widget breakdown against the verified current repo state; bolded notes are corrections/refinements found during this scan.
- CitizenClaimWidget — Showcase/QA split already correct, no changes there. Add a Theme overrides file wiring controls against the primitive
dark_Card/dark_Button/light_Card/light_Buttontargets (not the widget's existingClaimCard/ClaimActionGlow/ClaimActionRing/ClaimActionInner/TokenAmountTextnamed targets — see Reference files above), following StreamingWidget's pattern for structure only. No-op risk, confirmed and accounted for:packages/ui/src/presets.tsalready defines dedicatedClaimCard/ClaimActionButton/ClaimActionGlowpresets, so adark_Card/dark_Buttonoverride is a no-op against the default claim-tab surface, which renders through those named components, not the primitives. The new story instead demonstrates the override against confirmed plain-primitive surfaces that are actually reachable and do fall back to Card/Button's theme: the plain<Button>on the identity-verification step (CitizenClaimWidget.tsx~line 401) and the plain<Card>on the Invite Rewards/News tab placeholder (~line 625) — and visibly changes when toggled, not just compiles. Add an environment control to Showcase: Identity + UBIScheme are deployed on development-celo and production-celo (staging is never offered, per the revised environments rule), so offer development/production — currently the story helper hardcodesenvironment: 'development'with no control at all. - GoodReserveWidget — single flat file (
title: 'Widgets/GoodReserveWidget', no/Showcasesuffix) must split. 19 mocked/fixture stories (NoProvider,SdkInitializing,UnsupportedChain,IdleBuy,AmountEditing,QuoteLoading,QuoteReadyBuy,QuoteReadyBuyLightTheme,QuoteReadySell,QuoteReadyXdc,QuoteError,QuoteRefreshing,InsufficientBalance,SlippageSelection,ConfirmDialog,ApprovalPending,SwapPending,SwapSuccess,SwapError) move toQA/GoodReserveWidget/Runtime Fixturesunchanged in behavior (title/file move only). 3 live stories (Interactive,InjectedWallet,LiveWallet) move toWidgets/GoodReserveWidget/Showcase. New Theme overrides file wiring controls against the primitivedark_Card/dark_Button/light_Card/light_Buttontargets (not the widget's existing 9ReserveSwapViewnamed targets, which have no dedicated presets and correctly cascade from Card/Button's theme — see Reference files above). No MDX exists today — net new. Revised: no environment control, and nopackages/edit. The widget has noenvironmentprop anywhere in its source (confirmed via grep — zero matches), so per this plan's own rule (a control is only added where the widget's prop already supports the value) it's unsupported; adding one would require modifyingpackages/goodreserve-widget, which is out of scope for this bounty.packages/goodreserve-widgetis not touched at all. Log "GoodReserveWidget has no environment prop" in "[BountyPrep] Storybook: missing primitives and design system gaps" instead of building it here. - GovernanceWidget —
GovernanceOnboarding.stories.tsx(currentlytitle: 'Widgets/GovernanceOnboarding', 15 stories, all mocked/deterministic step-flow fixtures, wraps the distinctGovernanceOnboardingWidgetinternal-flow component, not the top-level widget) moves into the QA namespace, as originally planned. Revised per maintainer decision (overrides this plan's earlierDemofinding):Demo,Injected Wallet, andCustodial Walletall stay in Showcase.Demois genuinely mocked (staticadapterFactorystate, no provider or contract) and would move to QA under the plain mocked/live rule, but Laurence has made an explicit maintainer-policy exception keeping it in Showcase alongside the two wallet stories — this is not a reclassification ofDemoas live, it's a deliberate, logged exception to the "mocks go to QA" rule.Custodial Wallet(createCustodialEip1193Provider()against the same real dev-celoGoodDaoHousescontract asInjectedWallet) also stays, and remains hidden from the Storybook sidebar for lack of a "dev" tag — that's existing behavior, left as-is, not something this bounty fixes. Theme overrides file already exists, no new file needed — just confirm the onboarding move doesn't orphan a reference inside it. Revised: no environment control.GoodDaoHousesis deployed ondevelopment-celoonly, so an environment control here would offer a single, unchangeable option — a pointless UI element. Showcase gets no environment-switcher control (remove it if one exists today; do not add one if it doesn't); instead, add a plain note toGovernanceWidget.mdxstating the widget currently only operates against the development-celo deployment. - AiCreditsWidget —
MockBackend("Mock Backend (browser wallet)") moves from Showcase to QA as a new fixture story (no existing QA equivalent to merge into — this relocates the only copy). Add a Theme overrides file wiring controls against the primitivedark_Card/dark_Button/light_Card/light_Buttontargets (not the widget's existingAiCreditsStatusNotice/BonusBadgeFramenamed targets, which have no dedicated presets and correctly cascade from Card/Button's theme — see Reference files above, confirmed viapackages/ui/src/presets.ts). No GoodProtocol contract dependency (off-chain/API-backed per deployment.json) — no environment control needed unless execution finds a real backend-environment concept the widget already exposes; if none exists, leave as-is rather than inventing one, consistent with [Feature] Widget showcase in storybook #250's "most widgets support development/production only" being conditional on the widget actually having that axis. - SuperfluidCampaignWidget —
SuperfluidCampaignWidgetApiContracts.stories.tsx(currentlytitle: 'Widgets/SuperfluidCampaignWidget/API Contracts', both stories are Playwright response-interception contract tests) moves toQA/SuperfluidCampaignWidget/API Contracts. New Theme overrides file wiring controls against the primitivedark_Card/dark_Button/light_Card/light_Buttontargets only, confirmed to cascade correctly since the widget has no named theme-component module at all — no newshared.tsxnamed-component module is created for this bounty (revised: dropped the earlierCampaignHeader/RewardPoolSection/LeaderboardView/ActionCardextraction). This leaves the widget with no granular theme-targetable sub-components, unlike its siblings that already have one — log that gap in "[BountyPrep] Storybook: missing primitives and design system gaps" rather than building it here. No GoodProtocol contract dependency on Celo — no environment control. - GoodData widget — QA title renames from
QA/AiCreditsDashboard/Runtime FixturestoQA/GoodDataWidget/Runtime Fixtures(matches the actual package name@goodwidget/gooddata-widget;AiCreditsDashboardis just the one dashboard currently registered inside the genericGoodDataWidgetshell). Add a newWidgets/GoodDataWidget/Showcaseentry built on the realaiCreditsconnector's live data-fetch mode (paralleling the existingLive/LiveUnavailableQA fixture pair, but using the real connector instead of mocks) — this widget's "live" means live API data, not a wallet connection, matching how SuperfluidCampaignWidget's live stories work. No MDX exists today — net new. No GoodProtocol contract dependency — no environment control. New Theme overrides file, scoped to Button only: addGoodDataWidgetThemeOverrides.stories.tsxwiring controls against the primitivedark_Button/light_Buttontargets only — confirmed viagrep -rln "Card" packages/gooddata-widget/src(zero matches) that GoodDataWidget rendersButton(pagination and data-source-toggle controls) but never rendersCardanywhere in its source, so adark_Card/light_Cardcontrol would be a no-op; the file includes a short note explaining the Card exemption, consistent with the no-op acceptance criterion below rather than a silent omission. Vercel/CORS verification (resolves Olivia's live-connector concern): confirmed live, via a direct request to theaiCreditsconnector's backing Cloudflare Worker (https://gooddollar-antseed-integration.goodworker.workers.dev) with a simulated Vercel-previewOriginheader, that it responds withAccess-Control-Allow-Origin: *— the connector's browserfetchwill succeed from a Vercel preview deployment, not just locally. The live-connector Showcase approach can proceed as planned; no workaround needed. - ClaimWidget Theme Demo / StreamingWidget — no changes (per [Feature] Widget showcase in storybook #250). StakingMigrationWidget — re-checked under the revised no-staging rule, definitive answer: stays out of scope, unchanged. Verified live against
packages/staking-migration-widget/src/StakingMigrationWidget.tsx: the widget has noenvironmentprop or concept anywhere in its source (confirmed via grep — zero matches for "environment"); it hardcodes a Celo→Fuse chain switch (actions.switchToFuse()) and exposes onlymigrationApiBaseUrlas its external-config axis, which is an API endpoint, not a GoodProtocol Celo per-environment contract deployment. This is architecturally different from GoodReserveWidget's gap: GoodReserveWidget is missing an environment prop for a contract (MentoReserve) that genuinely varies by GoodProtocol Celo environment, so adding one is an identified widget-code-change dependency; StakingMigrationWidget's chain (Fuse) and axis (migrationApiBaseUrl) sit entirely outside the Celo-trackdeployment.jsongating this plan uses, so there is no missing environment axis to add — it was never applicable, and the staging-exclusion rule change doesn't affect that conclusion.
Confirmed: zero packages/ edits anywhere in this bounty. With GoodReserveWidget's environment control dropped (item 2) and GovernanceWidget's dropped (item 3), CitizenClaimWidget is the only widget retaining a genuine environment control, and packages/citizen-claim-widget already has the environment prop today (confirmed via grep), so wiring its Showcase control needs no widget-code change either. No item in this plan requires modifying packages/goodreserve-widget, packages/citizen-claim-widget, packages/governance-widget, packages/ai-credits-widget, packages/superfluid-campaign-widget, packages/gooddata-widget, or packages/ui — every change in this plan is confined to examples/storybook/ (new/moved story and MDX files) and tests/widgets/ (story-id updates).
New components to create (package placement)
- Environment-switcher control (new). No existing pattern anywhere in
examples/storybook/src/stories/helpers/exposesenvironmentas a Storybook arg — the story helper currently hardcodes it internally (citizenClaimWidgetStories.tsx:190). Revised scope: CitizenClaimWidget is the only widget that gets this control — GoodReserveWidget has noenvironmentprop to wire it to, and GovernanceWidget's single deployed value makes a control pointless (see Required states above). Needs: a sharedenvironmentargType/options source, fixed todevelopment/productiononly (staging is never an option, revised rule — see Reference files above). Placement: new file underexamples/storybook/src/stories/helpers/(e.g.environmentOptions.ts), notpackages/ui. This is Storybook-only dev tooling for selecting whichGoodWidgetProvider environment=value a preview uses — never shipped to a widget consumer, so it does not belong in the reusable runtime design-system package. - Theme overrides scaffolding — no new shared component needed. Revised: no new named theme-target components are created in any widget package for this bounty. Every widget already supports the primitive
dark_Card/dark_Button/light_Card/light_Buttontheme targets frompackages/ui; the five new Theme overrides files in this plan (CitizenClaimWidget, GoodReserveWidget, AiCreditsWidget, SuperfluidCampaignWidget, GoodDataWidget) wire controls against those primitives only — eachdark_*control paired with a matchinglight_*control, which deliberately deviates from the existing reference files' dark-only wiring (see Reference files above) — following theCodeBlock/DocsCalloutcopy-adapt pattern (Streaming, Governance) for structure but not for widget-specific named targets. GoodDataWidget's file is Button-only (no Card control — the widget renders no Card anywhere in its source, confirmed via grep). Finer per-widget named-target extraction (CitizenClaimWidget'sClaimCardfamily, GoodReserveWidget'sReserveSwapViewfamily, AiCreditsWidget'sAiCreditsStatusNotice/BonusBadgeFrame, and a SuperfluidCampaignWidgetshared.tsx) is explicitly deferred to a follow-up, not built here. - No new
packages/uiprimitives, and no new widget-package named theme-target components, are created for anything in this plan — nothing here is blocked on a missing design-system primitive, and no new named theme targets are introduced. Log gaps surfaced during execution — including SuperfluidCampaignWidget's lack of any named theme-component module (it alone, unlike its siblings, has no pre-existingshared.tsx-style target to fall back on even for a future pass), GoodReserveWidget's missingenvironmentprop (the widget-code change this bounty deliberately does not make), the existingStreamingWidgetThemeOverrides.stories.tsx/StakingMigrationWidgetThemeOverrides.stories.tsxfiles' own dark-only wiring (pre-dating this bounty, same class of gap as PR Storybook polish: interactive theming controls for widgets (#64) #73's finding, not fixed as part of this plan since neither file is otherwise touched), and any other widget where a story had been relying on a named target that no longer gets built this round — in "[BountyPrep] Storybook: missing primitives and design system gaps" per [Feature] Widget showcase in storybook #250's explicit out-of-scope instruction; do not build any of it here.
Execution plan
- CitizenClaimWidget: add
CitizenClaimWidgetThemeOverrides.stories.tsx(title: 'Widgets/CitizenClaimWidget/Theme overrides') wiring paireddark_Card/light_Card/dark_Button/light_Buttoncontrols against the confirmed plain-primitive surfaces (identity-verification<Button>, Invite Rewards/News tab<Card>), following the StreamingWidget pattern for file/title/docs structure only — not againstClaimCard/ClaimActionButton/ClaimActionGlow, which already have dedicated presets and would make the override a no-op; wire the new environment control (development/production, no staging) on Showcase only; updateCitizenClaimWidget.mdxwith a Theme overrides section embedding the new Playground story. - GoodReserveWidget: split
GoodReserveWidget.stories.tsxintoGoodReserveWidgetShowcase.stories.tsx(Interactive/InjectedWallet/LiveWallet,title: 'Widgets/GoodReserveWidget/Showcase', no environment control — widget has noenvironmentprop,packages/goodreserve-widgetis not touched) andGoodReserveWidgetQA.stories.tsx(19 fixture stories,title: 'QA/GoodReserveWidget/Runtime Fixtures',mockState-driven, behavior unchanged); addGoodReserveWidgetThemeOverrides.stories.tsxwiring paireddark_Card/light_Card/dark_Button/light_Buttoncontrols; createGoodReserveWidget.mdx(net new, following the reference MDX shape); log "GoodReserveWidget has no environment prop" in "[BountyPrep] Storybook: missing primitives and design system gaps"; update the 16 story-id references intests/widgets/goodreserve-widget/states.spec.ts. - GovernanceWidget: move
GovernanceOnboarding.stories.tsxinto the QA namespace (e.g.title: 'QA/GovernanceWidget/Onboarding'); leaveGovernanceWidgetShowcase.stories.tsxuntouched aside from removing its environment control (if present) —Demo,InjectedWallet, andCustodialWalletall stay (maintainer policy exception forDemo, confirmed genuinely live for the two wallet stories;CustodialWallet's missing "dev" sidebar tag is pre-existing and left as-is); add a "development only" note toGovernanceWidget.mdxin place of the dropped control; update the 8 story-id references intests/widgets/governance-widget/onboarding.spec.ts. - AiCreditsWidget: move
MockBackendout ofAiCreditsWidgetShowcase.stories.tsxintoAiCreditsWidgetQA.stories.tsxas a new fixture story; addAiCreditsWidgetThemeOverrides.stories.tsxwiring paireddark_Card/light_Card/dark_Button/light_Buttoncontrols; updateAiCreditsWidget.mdx; re-runtests/widgets/ai-credits-widget/states.spec.tsto confirm the move introduces no id collisions (no pre-existing reference to update, per the Reference files section above). - SuperfluidCampaignWidget: move
SuperfluidCampaignWidgetApiContracts.stories.tsxinto the QA namespace (title: 'QA/SuperfluidCampaignWidget/API Contracts'); addSuperfluidCampaignWidgetThemeOverrides.stories.tsxwiring paireddark_Card/light_Card/dark_Button/light_Buttoncontrols only (no newshared.tsxnamed-component module this round — log the gap per New components above); update the 2 story-id references intests/widgets/superfluid-campaign-widget/states.spec.ts. - GoodData widget: rename
GoodDataWidgetQA.stories.tsx's title fromQA/AiCreditsDashboard/Runtime FixturestoQA/GoodDataWidget/Runtime Fixtures; addGoodDataWidgetShowcase.stories.tsx(title: 'Widgets/GoodDataWidget/Showcase') built on the realaiCreditsconnector (Vercel/CORS compatibility confirmed, see Required states above); addGoodDataWidgetThemeOverrides.stories.tsxwiring paireddark_Button/light_Buttoncontrols only (no Card control — widget renders no Card, confirmed via grep — file notes the exemption); createGoodDataWidget.mdx(net new); update the 5 story-id references intests/widgets/gooddata-widget/states.spec.ts. - Run the full Playwright suite (
tests/widgets/**/*.spec.ts) after all moves land; fix any remaining story-id breakage beyond what's listed above — the per-widget lists above are what's been verified via static grep so far, a full run is the final check, not a substitute for it. - Manual QA: load the live Storybook preview locally; verify CitizenClaimWidget's Showcase environment control offers development/production only, never staging; verify GoodReserveWidget's and GovernanceWidget's Showcase stories have no environment control at all; verify no
QA/<Name>story exposes an environment-switcher control; verify everyWidgets/<Name>MDX page renders its "How to mount it" and "Theme overrides" sections correctly; verify no new Theme overrides file references a widget-specific named theme target (primitives only); toggle every wired control in every new Theme overrides story (bothdark_*and its pairedlight_*) and confirm the rendered widget visibly changes — not just that the story compiles; verify GoodDataWidget's Showcase loads realaiCreditsdata on the deployed Vercel preview, not only locally. - Log any design-system primitive or named-theme-target gap found during execution — including SuperfluidCampaignWidget's missing
shared.tsx-style module, GoodReserveWidget's missingenvironmentprop, and the existing StreamingWidget/StakingMigrationWidget Theme overrides files' dark-only wiring — in "[BountyPrep] Storybook: missing primitives and design system gaps" (do not build it here); leave "[BountyPrep] Storybook: live deployment review" for Olivia's own UX/docs pass.
Acceptance criteria
(Carried forward from #250's own checklist, which already enumerates these precisely — repeated here as this sub-issue's tracked checklist.)
- Every widget with a live, integratable component follows the
Widgets/<Name>/Showcase+Widgets/<Name>/Theme overrides+QA/<Name>/Runtime Fixturesstructure (StreamingWidget / StakingMigrationWidget pattern). -
ClaimWidget Theme Demois left as a Showcase + Theme overrides only (no QA section added). - Every
Widgets/<Name>entry has an MDX docs page with a "How to mount it" snippet and a "Theme overrides" section embedding the Playground story. - New
Theme overridesplaygrounds follow the existing*ThemeOverrides.stories.tsxpattern (flat color controls, live code snippet, reference callout) — no new pattern introduced. - Environment controls appear only where the widget both has a working
environmentprop and the environment list would offer a genuine choice (more than one deployed value) — CitizenClaimWidget's Showcase control offers development/production only (never staging); GoodReserveWidget and GovernanceWidget get no environment control (no prop, and single-value, respectively — see Required states above);QA/<Name>stories remain deterministic with no environment switching anywhere. - CitizenClaimWidget gets a
Theme overridesplayground with paireddark_*/light_*controls wired against primitive (Card/Button) targets only, demonstrated on surfaces confirmed to actually render the plain primitive (notClaimCard/ClaimActionButton, which have dedicated presets and would make the override a no-op). - GoodReserveWidget is fully split: mocked/fixture states under
QA/GoodReserveWidget/Runtime Fixtures, live stories underWidgets/GoodReserveWidget/Showcasewith no environment control, plus a newTheme overridesfile with paireddark_*/light_*controls wired against primitive targets only.packages/goodreserve-widgetis not modified. - GovernanceWidget's
GovernanceOnboarding(internal flow) moves underQA/GovernanceWidget; the Showcase file'sDemo,InjectedWallet, andCustodialWalletstories all stay as-is (maintainer policy exception, not a mocked/live reclassification — see Required states above); Showcase has no environment control, replaced by a "development only" note inGovernanceWidget.mdx. - AiCreditsWidget's
Mock Backendstory moves to QA;Theme overridesfile + paireddark_*/light_*controls added, wired against primitive targets only. - SuperfluidCampaignWidget gets a
Theme overridesfile + paireddark_*/light_*controls wired against primitive targets only (no newshared.tsxnamed-component module);API Contractsstory file is moved/renamed under the QA section; the missing named-theme-target gap is logged, not built. - GoodData widget gets a
Widgets/GoodDataWidget/Showcaseentry (liveaiCreditsconnector, CORS-verified to work from a Vercel preview deployment) and aTheme overridesfile scoped to paireddark_Button/light_Buttoncontrols only (no Card control — the widget renders no Card anywhere in its source); its QA path naming is aligned with the widget's actual package name (no moreAiCreditsDashboardnaming mismatch). - No wired Theme overrides control is a no-op: review found this is NOT fully met — see feat(storybook): showcase all GoodWidget widgets with QA fixtures and theme overrides #253's review comment (2026-10-21):
AiCreditsHero,ReserveSwapShell/ReserveAmountCard, and SuperfluidCampaignWidget's outer Card hardcode their own background tokens, so thebackgroundhalf of thedark_Card/light_Cardcontrol is a no-op on those three (border half works). Tracked as a fix item in the follow-up [GoodBounty] issue. - Every
dark_*control wired in a new Theme overrides file has a matching wiredlight_*control (not just documentation text referencing it) — a deliberate improvement over the existing StreamingWidget/StakingMigrationWidget reference files, which wiredark_*only. - Nothing under
packages/is modified anywhere in this bounty — confirmed no plan item implies a widget-source code change. - All existing Playwright specs under
tests/widgets/**/*.spec.tspass; any spec referencing a story id that moved/changed as part of this restructuring is updated to the new id. - No new design-system primitives/components and no new widget-package named theme targets are introduced; any gaps found (including SuperfluidCampaignWidget's missing named-theme-component module, GoodReserveWidget's missing
environmentprop, and the existing reference files' dark-only wiring) are logged in "[BountyPrep] Storybook: missing primitives and design system gaps" ([BountyPrep] Storybook: missing primitives and design system gaps #254), not built here. - Bounty Lead sign-off on the resulting preview deployment — Olivia's review complete 2026-10-21 (see feat(storybook): showcase all GoodWidget widgets with QA fixtures and theme overrides #253), follow-up items tracked in a new
[GoodBounty]issue.
Human-reviewer checklist
- Every widget's Showcase/Theme overrides/QA split matches the StreamingWidget/StakingMigrationWidget reference pattern exactly (file naming, title strings, tags).
- GovernanceWidget's Showcase stories confirmed unchanged at merge:
Demostaying in Showcase is a deliberate maintainer policy exception (not a live/mocked reclassification),InjectedWallet/CustodialWalletstay as confirmed-live, andCustodialWallet's hidden-sidebar behavior (missing "dev" tag) is intentionally left alone — verify none of this drifted during implementation. - Each widget's Showcase environment-control options re-checked against the live
releases/deployment.jsonat merge time, in case it changed since this plan was drafted — and confirm no control offersstaging/staging-celoanywhere. Confirm GoodReserveWidget and GovernanceWidget still have no environment control (re-check this wasn't silently reintroduced). - No QA story anywhere exposes an environment-switcher control.
- Confirm zero diffs under any
packages/directory in the final PR — this bounty is storybook-and-tests only. If a reviewer finds apackages/diff, it should be flagged, not merged as-is. - All Playwright specs pass with updated story ids; no hardcoded id missed.
- No new Theme overrides file in this bounty references a widget-specific named theme target (e.g.
ClaimCard,ReserveSwapShell,AiCreditsStatusNotice, or a new SuperfluidCampaignWidget component) — every new file targets only the primitiveCard/Button. - Every wired control in every new Theme overrides story was actually exercised and confirmed to visibly change the rendered widget (not just reviewed for code shape) — spot-check at least one
dark_*/light_*pair per widget, per the no-op finding from PR Storybook polish: interactive theming controls for widgets (#64) #73. Partially failed on first pass — see acceptance criteria above and the follow-up [GoodBounty] issue. - Every
dark_*control has a matching wiredlight_*control in each new Theme overrides file — confirm neither is present only in documentation text. - GoodDataWidget's Theme overrides file is Button-only with no Card control, and its exemption note is present and accurate (re-confirm the widget still renders no Card before merge, in case execution added one).
- GoodDataWidget's live
aiCreditsShowcase story is checked against the actual deployed Vercel preview URL, not just a local dev server. - No new
packages/uiprimitives and no new widget-package named theme-target components introduced anywhere; any gaps found (including SuperfluidCampaignWidget's missingshared.tsx-style module, GoodReserveWidget's missingenvironmentprop, and the existing reference files' dark-only wiring) are filed in "[BountyPrep] Storybook: missing primitives and design system gaps" ([BountyPrep] Storybook: missing primitives and design system gaps #254), not built inline. - StakingMigrationWidget's out-of-scope status reconfirmed at merge: no environment prop/concept added, still gated only on
migrationApiBaseUrland its hardcoded Fuse chain. - MDX docs for every
Widgets/<Name>entry reviewed for accuracy of the "How to mount it" snippet against the actual current widget API. - Olivia's live-preview UX/docs pass (tracked separately in "[BountyPrep] Storybook: live deployment review") is linked but not treated as a blocking condition for this PR's own merge.
Plans #250. Executed as PR #253. Follow-up fixes tracked in a dedicated [GoodBounty] issue per Olivia's 2026-10-21 review.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsIn Progress
Activity
[-][DRAFT][PLAN] Widget showcase in storybook[/-][+][PLAN] Widget showcase in storybook[/+]