chore: catch up Storybook preview, coverage, and story hygiene

Stories were throwing without AuthModal/CreateFlow providers, autodocs was a no-op, and several DS/create-flow screens had no stories.
This commit is contained in:
adilallo
2026-08-17 19:25:46 -06:00
parent 1983a67ffd
commit db1581337c
44 changed files with 1215 additions and 932 deletions
+109 -96
View File
@@ -42,119 +42,132 @@ const Template = (args) => {
);
};
export const ToastDefault = Template.bind({});
ToastDefault.args = {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "toast",
export const ToastDefault = {
args: {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "toast",
},
render: Template,
};
export const ToastPositive = Template.bind({});
ToastPositive.args = {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "toast",
export const ToastPositive = {
args: {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "toast",
},
render: Template,
};
export const ToastWarning = Template.bind({});
ToastWarning.args = {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "warning",
type: "toast",
export const ToastWarning = {
args: {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "warning",
type: "toast",
},
render: Template,
};
export const ToastDanger = Template.bind({});
ToastDanger.args = {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "danger",
type: "toast",
export const ToastDanger = {
args: {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "danger",
type: "toast",
},
render: Template,
};
export const Banner = Template.bind({});
Banner.args = {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "banner",
export const Banner = {
args: {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "banner",
},
render: Template,
};
export const BannerPositive = Template.bind({});
BannerPositive.args = {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "banner",
export const BannerPositive = {
args: {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "banner",
},
render: Template,
};
export const BannerWarning = Template.bind({});
BannerWarning.args = {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "warning",
type: "banner",
export const BannerWarning = {
args: {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "warning",
type: "banner",
},
render: Template,
};
export const BannerDanger = Template.bind({});
BannerDanger.args = {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "danger",
type: "banner",
export const BannerDanger = {
args: {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "danger",
type: "banner",
},
render: Template,
};
export const TitleOnly = Template.bind({});
TitleOnly.args = {
title: "Short alert banner message goes here",
status: "default",
type: "toast",
export const TitleOnly = {
args: {
title: "Short alert banner message goes here",
status: "default",
type: "toast",
},
render: Template,
};
export const ToastSmall = Template.bind({});
ToastSmall.args = {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "toast",
size: "s",
export const ToastSmall = {
args: {
title: "Short alert toast message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "default",
type: "toast",
size: "s",
},
render: Template,
};
export const BannerSmall = Template.bind({});
BannerSmall.args = {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "banner",
size: "s",
export const BannerSmall = {
args: {
title: "Short alert banner message goes here",
description:
"Nascetur ipsum a nisi tempor cras nam neque volutpat. Aliquam id est faucibus nunc quis. Eleifend suspendisse.",
status: "positive",
type: "banner",
size: "s",
},
render: Template,
};
const NoDismissTemplate = (args) => (
<div className="p-8 max-w-[600px]">
<Alert {...args} />
</div>
);
export const BannerNoDismiss = NoDismissTemplate.bind({});
BannerNoDismiss.args = {
title: "Non-dismissible banner (no onClose)",
description: "Used when the message clears via navigation or parent state only.",
status: "danger",
type: "banner",
size: "s",
export const BannerNoDismiss = {
args: {
title: "Non-dismissible banner (no onClose)",
description:
"Used when the message clears via navigation or parent state only.",
status: "danger",
type: "banner",
size: "s",
},
render: NoDismissTemplate,
};
export const AllStatuses = () => {
const [visible, setVisible] = useState({
default: true,
+157 -147
View File
@@ -54,158 +54,168 @@ const Template = (args) => {
);
};
export const Default = Template.bind({});
Default.args = {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
export const Default = {
args: {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
},
render: Template,
};
export const WithStepper = Template.bind({});
WithStepper.args = {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
currentStep: 1,
totalSteps: 3,
export const WithStepper = {
args: {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
currentStep: 1,
totalSteps: 3,
},
render: Template,
};
export const Step2 = Template.bind({});
Step2.args = {
isOpen: true,
title: "How should conflicts be resolved?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Enter text" value="" />
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
currentStep: 2,
totalSteps: 3,
export const Step2 = {
args: {
isOpen: true,
title: "How should conflicts be resolved?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Enter text" value="" />
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: false,
currentStep: 2,
totalSteps: 3,
},
render: Template,
};
export const Step3 = Template.bind({});
Step3.args = {
isOpen: true,
title: "Final step",
description: "Review your settings",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Review your policy configuration
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Finish",
nextButtonDisabled: false,
currentStep: 3,
totalSteps: 3,
export const Step3 = {
args: {
isOpen: true,
title: "Final step",
description: "Review your settings",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Review your policy configuration
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Finish",
nextButtonDisabled: false,
currentStep: 3,
totalSteps: 3,
},
render: Template,
};
export const WithCustomHeader = Template.bind({});
WithCustomHeader.args = {
isOpen: true,
headerContent: <div className="text-lg font-semibold">Custom header</div>,
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
When headerContent is provided, the default title and description are
not shown.
</p>
</div>
),
showBackButton: false,
showNextButton: true,
nextButtonText: "Continue",
export const WithCustomHeader = {
args: {
isOpen: true,
headerContent: <div className="text-lg font-semibold">Custom header</div>,
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
When headerContent is provided, the default title and description are
not shown.
</p>
</div>
),
showBackButton: false,
showNextButton: true,
nextButtonText: "Continue",
},
render: Template,
};
export const WithoutFooter = Template.bind({});
WithoutFooter.args = {
isOpen: true,
title: "Simple Create Dialog",
description: "This create dialog has no footer buttons",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Modal content without footer
</p>
</div>
),
showBackButton: false,
showNextButton: false,
export const WithoutFooter = {
args: {
isOpen: true,
title: "Simple Create Dialog",
description: "This create dialog has no footer buttons",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Modal content without footer
</p>
</div>
),
showBackButton: false,
showNextButton: false,
},
render: Template,
};
export const LoginYellowBackdrop = Template.bind({});
LoginYellowBackdrop.args = {
isOpen: true,
title: "Horizontalism",
description: "Edit or add to this description to describe what this value means to your community.",
backdropVariant: "blurredYellow",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Core value detail body (yellow blurred overlay like Login).
</p>
</div>
),
showBackButton: false,
showNextButton: true,
nextButtonText: "Add Value",
nextButtonDisabled: false,
export const LoginYellowBackdrop = {
args: {
isOpen: true,
title: "Horizontalism",
description:
"Edit or add to this description to describe what this value means to your community.",
backdropVariant: "blurredYellow",
children: (
<div className="space-y-4">
<p className="text-[var(--color-content-default-primary)]">
Core value detail body (yellow blurred overlay like Login).
</p>
</div>
),
showBackButton: false,
showNextButton: true,
nextButtonText: "Add Value",
nextButtonDisabled: false,
},
render: Template,
};
export const NextButtonDisabled = Template.bind({});
NextButtonDisabled.args = {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: true,
currentStep: 1,
totalSteps: 3,
export const NextButtonDisabled = {
args: {
isOpen: true,
title: "What do you call your group's new policy?",
description: "You can also combine or add new approaches to the list",
children: (
<div className="space-y-4">
<TextInput label="Label" placeholder="Policy name" value="" />
<p className="text-[12px] text-[var(--color-content-default-tertiary)]">
0/48
</p>
</div>
),
showBackButton: true,
showNextButton: true,
backButtonText: "Back",
nextButtonText: "Next",
nextButtonDisabled: true,
currentStep: 1,
totalSteps: 3,
},
render: Template,
};
+15 -12
View File
@@ -1,6 +1,9 @@
import React, { Suspense, useEffect } from "react";
import Login from "../../app/components/modals/Login";
import LoginForm from "../../app/components/modals/Login/LoginForm";
import messages from "../../messages/en/index";
const backToHome = messages.pages.login.backToHome;
/**
* Storybook runs outside Next.js request context; successful "Send link" needs fetch mocked
@@ -43,11 +46,11 @@ function FakeMarketingPageBehindOverlay({
return (
<div className="relative min-h-[100dvh] overflow-hidden">
<div
className="absolute inset-0 bg-gradient-to-br from-amber-100 via-white to-amber-50"
className="absolute inset-0 bg-[var(--color-surface-inverse-brand-primary)]"
aria-hidden
/>
<div className="relative z-0 px-8 py-16">
<p className="font-inter max-w-md text-lg text-neutral-800">
<p className="max-w-md text-large-paragraph text-[var(--color-content-invert-primary)]">
Placeholder page content the login overlay portals above this and
uses backdrop blur (`blurredYellow`).
</p>
@@ -107,13 +110,13 @@ export const HeaderOverlayBlurred = {
belowCard={
<a
href="/"
className="font-inter font-normal text-[14px] leading-[20px] text-[var(--color-content-invert-tertiary,#2d2d2d)] text-center hover:opacity-90"
className="text-center text-small-paragraph text-[var(--color-content-invert-tertiary)] hover:opacity-90"
>
Back to home
{backToHome}
</a>
}
>
<Suspense fallback={<p className="font-inter p-6">Loading</p>}>
<Suspense fallback={<p className="p-6 text-small-paragraph">Loading</p>}>
<LoginForm />
</Suspense>
</Login>
@@ -152,13 +155,13 @@ export const FullPageRouteSolid = {
belowCard={
<a
href="/"
className="font-inter font-normal text-[14px] leading-[20px] text-[var(--color-content-invert-tertiary,#2d2d2d)] text-center hover:opacity-90"
className="text-center text-small-paragraph text-[var(--color-content-invert-tertiary)] hover:opacity-90"
>
Back to home
{backToHome}
</a>
}
>
<Suspense fallback={<p className="font-inter p-6">Loading</p>}>
<Suspense fallback={<p className="p-6 text-small-paragraph">Loading</p>}>
<LoginForm />
</Suspense>
</Login>
@@ -178,15 +181,15 @@ export const ModalChromeOnly = {
belowCard={
<a
href="/"
className="font-inter font-normal text-[14px] leading-[20px] text-[var(--color-content-invert-tertiary,#2d2d2d)] text-center hover:opacity-90"
className="text-center text-small-paragraph text-[var(--color-content-invert-tertiary)] hover:opacity-90"
>
Back to home
{backToHome}
</a>
}
>
<p
id="login-modal-heading"
className="font-inter px-2 py-4 text-[var(--color-content-default-primary)]"
className="px-2 py-4 text-[var(--color-content-default-primary)]"
>
Placeholder body use &quot;Header overlay&quot; or &quot;Full-page
route&quot; for the real flow.
@@ -215,7 +218,7 @@ export const FormOnly = {
],
render: () => (
<div className="mx-auto max-w-[560px] rounded-[20px] bg-[var(--color-surface-default-primary)] p-6 shadow-lg">
<Suspense fallback={<p className="font-inter">Loading</p>}>
<Suspense fallback={<p className="text-small-paragraph">Loading</p>}>
<LoginForm />
</Suspense>
</div>
+28 -24
View File
@@ -1,41 +1,45 @@
import React, { useState } from "react";
import Share from "../../app/components/modals/Share";
import { MessagesProvider } from "../../app/contexts/MessagesContext";
import messages from "../../messages/en/index";
/** Figma: Modal / Share — node 22073-30884 (Community Rule System). */
export default {
title: "modals/Share",
title: "Components/Modals/Share",
component: Share,
parameters: {
layout: "fullscreen",
docs: {
description: {
component:
"Share modal for published rules (copy link and channel actions).",
},
},
},
};
function ShareStoryHost() {
const [open, setOpen] = useState(true);
return (
<MessagesProvider messages={messages}>
<div className="min-h-[100dvh] bg-[var(--color-surface-inverse-brand-primary)] p-6">
<button
type="button"
className="rounded-md bg-white px-4 py-2 text-sm text-black"
onClick={() => setOpen(true)}
>
Open Share
</button>
<Share
isOpen={open}
onClose={() => setOpen(false)}
onCopyLink={() => {}}
onEmailShare={() => {}}
onSignalShare={() => {}}
onSlackShare={() => {}}
onDiscordShare={() => {}}
/>
</div>
</MessagesProvider>
<div className="min-h-[100dvh] bg-[var(--color-surface-inverse-brand-primary)] p-6">
<button
type="button"
className="rounded-md bg-[var(--color-surface-default-primary)] px-4 py-2 text-small-paragraph text-[var(--color-content-default-primary)]"
onClick={() => setOpen(true)}
>
Open Share
</button>
<Share
isOpen={open}
onClose={() => setOpen(false)}
onCopyLink={() => {}}
onEmailShare={() => {}}
onSignalShare={() => {}}
onSlackShare={() => {}}
onDiscordShare={() => {}}
/>
</div>
);
}
export const Default = {
name: "Modal / Share",
render: () => <ShareStoryHost />,
};
+33 -27
View File
@@ -1,6 +1,7 @@
import React from "react";
import Tooltip from "../../app/components/modals/Tooltip";
import Button from "../../app/components/buttons/Button";
import { TOOLTIP_POSITION_OPTIONS } from "../../lib/propNormalization";
export default {
title: "Components/Modals/Tooltip",
@@ -8,7 +9,7 @@ export default {
argTypes: {
position: {
control: { type: "select" },
options: ["top", "bottom"],
options: [...TOOLTIP_POSITION_OPTIONS],
},
disabled: {
control: { type: "boolean" },
@@ -29,37 +30,42 @@ const Template = (args) => (
</div>
);
export const Default = Template.bind({});
Default.args = {
text: "Tooltip text goes here",
position: "top",
disabled: false,
export const Default = {
args: {
text: "Tooltip text goes here",
position: "top",
disabled: false,
},
render: Template,
};
export const Top = Template.bind({});
Top.args = {
text: "Tooltip positioned at top",
position: "top",
export const Top = {
args: {
text: "Tooltip positioned at top",
position: "top",
},
render: Template,
};
export const Bottom = Template.bind({});
Bottom.args = {
text: "Tooltip positioned at bottom",
position: "bottom",
export const Bottom = {
args: {
text: "Tooltip positioned at bottom",
position: "bottom",
},
render: Template,
};
export const Disabled = Template.bind({});
Disabled.args = {
text: "This tooltip is disabled",
disabled: true,
export const Disabled = {
args: {
text: "This tooltip is disabled",
disabled: true,
},
render: Template,
};
export const LongText = Template.bind({});
LongText.args = {
text: "This is a longer tooltip text that demonstrates how the component handles multiple words and extended content",
position: "top",
export const LongText = {
args: {
text: "This is a longer tooltip text that demonstrates how the component handles multiple words and extended content",
position: "top",
},
render: Template,
};
export const WithIcon = () => (
<div className="p-16 flex items-center justify-center min-h-[200px]">
<Tooltip text="Tooltip with icon button" position="top">