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
+3 -7
View File
@@ -1,7 +1,5 @@
import React, { useState } from "react";
import AddCustomField from "../../app/components/controls/AddCustomField";
import { MessagesProvider } from "../../app/contexts/MessagesContext";
import messages from "../../messages/en/index";
/** Figma: Add Custom Field — node `20235:12994` (Community Rule System). */
export default {
@@ -9,11 +7,9 @@ export default {
component: AddCustomField,
decorators: [
(Story) => (
<MessagesProvider messages={messages}>
<div className="w-[min(100%,546px)] bg-[var(--color-surface-default-primary)] p-6">
<Story />
</div>
</MessagesProvider>
<div className="w-[min(100%,546px)] bg-[var(--color-surface-default-primary)] p-6">
<Story />
</div>
),
],
};
+8 -3
View File
@@ -1,4 +1,9 @@
import Chip from "../../app/components/controls/Chip";
import {
CHIP_PALETTE_OPTIONS,
CHIP_SIZE_OPTIONS,
CHIP_STATE_OPTIONS,
} from "../../lib/propNormalization";
export default {
title: "Components/Controls/Chip",
@@ -13,17 +18,17 @@ export default {
},
state: {
control: "select",
options: ["unselected", "selected", "disabled", "custom"],
options: [...CHIP_STATE_OPTIONS],
description: "Visual state of the chip",
},
palette: {
control: "select",
options: ["default", "inverse"],
options: [...CHIP_PALETTE_OPTIONS],
description: "Color palette of the chip",
},
size: {
control: "select",
options: ["s", "m"],
options: [...CHIP_SIZE_OPTIONS],
description: "Size of the chip",
},
disabled: {
@@ -1,71 +0,0 @@
import React from "react";
import HeaderLockup from "../../app/components/type/HeaderLockup";
import InfoMessageBox from "../../app/components/controls/InfoMessageBox";
/**
* Compose pattern used by create-flow “decision approaches” rail: headline lockup
* plus bordered checklist — no standalone wrapper component.
*/
export default {
title: "Components/Controls/Rail header (lockup + info box)",
parameters: {
layout: "centered",
backgrounds: { default: "dark" },
docs: {
description: {
component:
"`HeaderLockup` stacked with `InfoMessageBox` — same chrome as decision-approaches step sidebars.",
},
},
},
decorators: [
(Story) => (
<div className="bg-black p-8 max-w-lg w-full">
<Story />
</div>
),
],
tags: ["autodocs"],
};
const messageItems = [
{ id: "c1", label: "Consensus" },
{ id: "c2", label: "Majority vote" },
];
const compose = (args) => (
<div className="flex w-full min-w-0 flex-col gap-3">
<HeaderLockup
title={args.title}
description={args.description}
size={args.size}
justification={args.justification}
/>
<InfoMessageBox title={args.messageBoxTitle} items={args.messageBoxItems} />
</div>
);
export const Default = {
render: compose,
args: {
title: "How does your group make decisions?",
description:
"Choose the approaches that best match how your community operates.",
messageBoxTitle: "Common approaches",
messageBoxItems: messageItems,
size: "L",
justification: "left",
},
};
export const Medium = {
render: compose,
args: {
title: "Decision-making",
description: "Short description.",
messageBoxTitle: "Pick any",
messageBoxItems: [{ id: "x", label: "Single method" }],
size: "M",
justification: "left",
},
};
+37 -34
View File
@@ -44,43 +44,46 @@ const Template = (args) => {
};
// Default story
export const Default = Template.bind({});
Default.args = {
label: "Default Select Input",
placeholder: "Choose an option",
state: "default",
export const Default = {
args: {
label: "Default Select Input",
placeholder: "Choose an option",
state: "default",
},
render: Template,
}; // States
export const Active = {
args: {
label: "Active State",
placeholder: "Choose an option",
state: "active",
},
render: Template,
};
// States
export const Active = Template.bind({});
Active.args = {
label: "Active State",
placeholder: "Choose an option",
state: "active",
export const Focus = {
args: {
label: "Focus State",
placeholder: "Choose an option",
state: "focus",
},
render: Template,
};
export const Focus = Template.bind({});
Focus.args = {
label: "Focus State",
placeholder: "Choose an option",
state: "focus",
export const Error = {
args: {
label: "Error State",
placeholder: "Choose an option",
error: true,
},
render: Template,
};
export const Error = Template.bind({});
Error.args = {
label: "Error State",
placeholder: "Choose an option",
error: true,
};
export const Disabled = Template.bind({});
Disabled.args = {
label: "Disabled State",
placeholder: "Choose an option",
disabled: true,
};
// Interactive example
export const Disabled = {
args: {
label: "Disabled State",
placeholder: "Choose an option",
disabled: true,
},
render: Template,
}; // Interactive example
export const Interactive = (args) => {
const [value, setValue] = useState("");
+26 -22
View File
@@ -39,32 +39,36 @@ export default {
const Template = (args) => <Switch {...args} />;
export const Default = Template.bind({});
Default.args = {
propSwitch: false,
text: "Switch label",
export const Default = {
args: {
propSwitch: false,
text: "Switch label",
},
render: Template,
};
export const Checked = Template.bind({});
Checked.args = {
propSwitch: true,
text: "Switch label",
export const Checked = {
args: {
propSwitch: true,
text: "Switch label",
},
render: Template,
};
export const Focus = Template.bind({});
Focus.args = {
propSwitch: false,
state: "focus",
text: "Switch label",
export const Focus = {
args: {
propSwitch: false,
state: "focus",
text: "Switch label",
},
render: Template,
};
export const FocusChecked = Template.bind({});
FocusChecked.args = {
propSwitch: true,
state: "focus",
text: "Switch label",
export const FocusChecked = {
args: {
propSwitch: true,
state: "focus",
text: "Switch label",
},
render: Template,
};
export const States = () => (
<div className="space-y-4">
<div className="space-y-2">
+71 -54
View File
@@ -1,5 +1,11 @@
import React from "react";
import TextArea from "../../app/components/controls/TextArea";
import {
INPUT_STATE_OPTIONS,
LABEL_VARIANT_OPTIONS,
SMALL_MEDIUM_LARGE_OPTIONS,
TEXT_AREA_APPEARANCE_OPTIONS,
} from "../../lib/propNormalization";
export default {
title: "Components/Controls/TextArea",
@@ -10,15 +16,19 @@ export default {
argTypes: {
size: {
control: { type: "select" },
options: ["small", "medium", "large"],
options: [...SMALL_MEDIUM_LARGE_OPTIONS],
},
labelVariant: {
control: { type: "select" },
options: ["default", "horizontal"],
options: [...LABEL_VARIANT_OPTIONS],
},
appearance: {
control: { type: "select" },
options: [...TEXT_AREA_APPEARANCE_OPTIONS],
},
state: {
control: { type: "select" },
options: ["default", "active", "hover", "focus", "error"],
options: [...INPUT_STATE_OPTIONS],
},
disabled: {
control: { type: "boolean" },
@@ -31,64 +41,71 @@ export default {
const Template = (args) => <TextArea {...args} />;
export const Default = Template.bind({});
Default.args = {
label: "Text Area",
placeholder: "Enter text...",
value: "",
export const Default = {
args: {
label: "Text Area",
placeholder: "Enter text...",
value: "",
},
render: Template,
};
export const WithValue = Template.bind({});
WithValue.args = {
label: "Text Area",
placeholder: "Enter text...",
value:
"This is some sample text content that demonstrates how the text area looks with content.",
export const WithValue = {
args: {
label: "Text Area",
placeholder: "Enter text...",
value:
"This is some sample text content that demonstrates how the text area looks with content.",
},
render: Template,
};
export const Small = Template.bind({});
Small.args = {
size: "small",
label: "Small Text Area",
placeholder: "Enter text...",
value: "",
export const Small = {
args: {
size: "small",
label: "Small Text Area",
placeholder: "Enter text...",
value: "",
},
render: Template,
};
export const Medium = Template.bind({});
Medium.args = {
size: "medium",
label: "Medium Text Area",
placeholder: "Enter text...",
value: "",
export const Medium = {
args: {
size: "medium",
label: "Medium Text Area",
placeholder: "Enter text...",
value: "",
},
render: Template,
};
export const Large = Template.bind({});
Large.args = {
size: "large",
label: "Large Text Area",
placeholder: "Enter text...",
value: "",
export const Large = {
args: {
size: "large",
label: "Large Text Area",
placeholder: "Enter text...",
value: "",
},
render: Template,
};
export const Embedded = Template.bind({});
Embedded.args = {
label: "Section content",
placeholder: "Enter text...",
value:
"Embedded appearance used in create-flow modals: borderless, darker grey block.",
appearance: "embedded",
size: "large",
rows: 4,
export const Embedded = {
args: {
label: "Section content",
placeholder: "Enter text...",
value:
"Embedded appearance used in create-flow modals: borderless, darker grey block.",
appearance: "embedded",
size: "large",
rows: 4,
},
render: Template,
};
export const HorizontalLabel = Template.bind({});
HorizontalLabel.args = {
labelVariant: "horizontal",
label: "Horizontal Label",
placeholder: "Enter text...",
value: "",
export const HorizontalLabel = {
args: {
labelVariant: "horizontal",
label: "Horizontal Label",
placeholder: "Enter text...",
value: "",
},
render: Template,
};
export const AllSizes = () => (
<div className="space-y-6">
<div className="space-y-4">
+75 -66
View File
@@ -1,5 +1,9 @@
import React from "react";
import TextInput from "../../app/components/controls/TextInput";
import {
INPUT_STATE_OPTIONS,
TEXT_INPUT_SIZE_OPTIONS,
} from "../../lib/propNormalization";
export default {
title: "Components/Controls/TextInput",
@@ -10,11 +14,11 @@ export default {
argTypes: {
inputSize: {
control: { type: "select" },
options: ["small", "medium", "Small", "Medium"],
options: [...TEXT_INPUT_SIZE_OPTIONS],
},
state: {
control: { type: "select" },
options: ["default", "active", "hover", "focus", "error", "disabled"],
options: [...INPUT_STATE_OPTIONS],
},
disabled: {
control: { type: "boolean" },
@@ -37,75 +41,80 @@ export default {
const Template = (args) => <TextInput {...args} />;
// Default story
export const Default = Template.bind({});
Default.args = {
label: "Default Text Input",
placeholder: "Enter text...",
inputSize: "medium",
state: "default",
export const Default = {
args: {
label: "Default Text Input",
placeholder: "Enter text...",
inputSize: "medium",
state: "default",
},
render: Template,
}; // Size variants
export const Small = {
args: {
label: "Small Text Input",
placeholder: "Small size",
inputSize: "small",
state: "default",
},
render: Template,
};
// Size variants
export const Small = Template.bind({});
Small.args = {
label: "Small Text Input",
placeholder: "Small size",
inputSize: "small",
state: "default",
export const Medium = {
args: {
label: "Medium Text Input",
placeholder: "Medium size",
inputSize: "medium",
state: "default",
},
render: Template,
}; // States
export const Active = {
args: {
label: "Active State",
placeholder: "Active input",
inputSize: "medium",
state: "active",
},
render: Template,
};
export const Medium = Template.bind({});
Medium.args = {
label: "Medium Text Input",
placeholder: "Medium size",
inputSize: "medium",
state: "default",
export const Hover = {
args: {
label: "Hover State",
placeholder: "Hover input",
inputSize: "medium",
state: "hover",
},
render: Template,
};
// States
export const Active = Template.bind({});
Active.args = {
label: "Active State",
placeholder: "Active input",
inputSize: "medium",
state: "active",
export const Focus = {
args: {
label: "Focus State",
placeholder: "Focused input",
inputSize: "medium",
state: "focus",
},
render: Template,
};
export const Hover = Template.bind({});
Hover.args = {
label: "Hover State",
placeholder: "Hover input",
inputSize: "medium",
state: "hover",
export const Error = {
args: {
label: "Error State",
placeholder: "Error input",
inputSize: "medium",
state: "default",
error: true,
},
render: Template,
};
export const Focus = Template.bind({});
Focus.args = {
label: "Focus State",
placeholder: "Focused input",
inputSize: "medium",
state: "focus",
};
export const Error = Template.bind({});
Error.args = {
label: "Error State",
placeholder: "Error input",
inputSize: "medium",
state: "default",
error: true,
};
export const Disabled = Template.bind({});
Disabled.args = {
label: "Disabled State",
placeholder: "Disabled input",
inputSize: "medium",
state: "default",
disabled: true,
};
// Interactive example
export const Disabled = {
args: {
label: "Disabled State",
placeholder: "Disabled input",
inputSize: "medium",
state: "default",
disabled: true,
},
render: Template,
}; // Interactive example
export const Interactive = (args) => {
const [value, setValue] = React.useState("");
+16 -14
View File
@@ -44,22 +44,24 @@ export const States = () => (
</div>
);
export const WithText = Template.bind({});
WithText.args = {
label: "Text Toggle",
checked: false,
showText: true,
text: "Toggle",
export const WithText = {
args: {
label: "Text Toggle",
checked: false,
showText: true,
text: "Toggle",
},
render: Template,
};
export const WithIcon = Template.bind({});
WithIcon.args = {
label: "Icon Toggle",
checked: false,
showIcon: true,
icon: "I",
export const WithIcon = {
args: {
label: "Icon Toggle",
checked: false,
showIcon: true,
icon: "I",
},
render: Template,
};
export const Interactive = () => {
const [checked, setChecked] = React.useState(false);
const [state, setState] = React.useState("default");
+43 -34
View File
@@ -1,5 +1,9 @@
import React from "react";
import ToggleGroup from "../../app/components/controls/ToggleGroup";
import {
STATE_OPTIONS,
TOGGLE_GROUP_POSITION_OPTIONS,
} from "../../lib/propNormalization";
export default {
title: "Components/Controls/ToggleGroup",
@@ -10,11 +14,11 @@ export default {
argTypes: {
position: {
control: { type: "select" },
options: ["left", "middle", "right"],
options: [...TOGGLE_GROUP_POSITION_OPTIONS],
},
state: {
control: { type: "select" },
options: ["default", "hover", "focus", "selected"],
options: [...STATE_OPTIONS],
},
showText: {
control: { type: "boolean" },
@@ -24,27 +28,30 @@ export default {
const Template = (args) => <ToggleGroup {...args}>Toggle Item</ToggleGroup>;
export const Default = Template.bind({});
Default.args = {
position: "left",
state: "default",
showText: true,
export const Default = {
args: {
position: "left",
state: "default",
showText: true,
},
render: Template,
};
export const Middle = Template.bind({});
Middle.args = {
position: "middle",
state: "default",
showText: true,
export const Middle = {
args: {
position: "middle",
state: "default",
showText: true,
},
render: Template,
};
export const Right = Template.bind({});
Right.args = {
position: "right",
state: "default",
showText: true,
export const Right = {
args: {
position: "right",
state: "default",
showText: true,
},
render: Template,
};
export const States = () => (
<div className="space-y-4">
<div className="space-y-2">
@@ -89,22 +96,24 @@ export const Positions = () => (
</div>
);
export const WithText = Template.bind({});
WithText.args = {
position: "left",
state: "default",
showText: true,
children: "Active Deals",
export const WithText = {
args: {
position: "left",
state: "default",
showText: true,
children: "Active Deals",
},
render: Template,
};
export const WithoutText = Template.bind({});
WithoutText.args = {
position: "left",
state: "default",
showText: false,
children: "☰",
export const WithoutText = {
args: {
position: "left",
state: "default",
showText: false,
children: "☰",
},
render: Template,
};
export const WithIcons = () => (
<div className="space-y-4">
<div className="space-y-2">
+69 -59
View File
@@ -34,87 +34,97 @@ export default {
const Template = (args) => <Upload {...args} />;
// Default story
export const Default = Template.bind({});
Default.args = {
label: "Upload",
active: true,
showHelpIcon: true,
};
// Active state
export const Active = Template.bind({});
Active.args = {
label: "Upload",
active: true,
showHelpIcon: true,
};
Active.parameters = {
docs: {
description: {
story:
"Upload component in active state with white button and black text.",
export const Default = {
args: {
label: "Upload",
active: true,
showHelpIcon: true,
},
render: Template,
}; // Active state
export const Active = {
args: {
label: "Upload",
active: true,
showHelpIcon: true,
},
parameters: {
docs: {
description: {
story:
"Upload component in active state with white button and black text.",
},
},
},
render: Template,
};
// Inactive state
export const Inactive = Template.bind({});
Inactive.args = {
label: "Upload",
active: false,
showHelpIcon: true,
};
Inactive.parameters = {
docs: {
description: {
story:
"Upload component in inactive state with dark button and gray text.",
export const Inactive = {
args: {
label: "Upload",
active: false,
showHelpIcon: true,
},
parameters: {
docs: {
description: {
story:
"Upload component in inactive state with dark button and gray text.",
},
},
},
render: Template,
};
// Without help icon
export const WithoutHelpIcon = Template.bind({});
WithoutHelpIcon.args = {
label: "Upload",
active: true,
showHelpIcon: false,
};
WithoutHelpIcon.parameters = {
docs: {
description: {
story: "Upload component without help icon.",
export const WithoutHelpIcon = {
args: {
label: "Upload",
active: true,
showHelpIcon: false,
},
parameters: {
docs: {
description: {
story: "Upload component without help icon.",
},
},
},
render: Template,
};
// Without label
export const WithoutLabel = Template.bind({});
WithoutLabel.args = {
active: true,
showHelpIcon: false,
};
WithoutLabel.parameters = {
docs: {
description: {
story: "Upload component without label.",
export const WithoutLabel = {
args: {
active: true,
showHelpIcon: false,
},
parameters: {
docs: {
description: {
story: "Upload component without label.",
},
},
},
render: Template,
};
// Custom label
export const CustomLabel = Template.bind({});
CustomLabel.args = {
label: "Upload Files",
active: true,
showHelpIcon: true,
};
CustomLabel.parameters = {
docs: {
description: {
story: "Upload component with custom label text.",
export const CustomLabel = {
args: {
label: "Upload Files",
active: true,
showHelpIcon: true,
},
parameters: {
docs: {
description: {
story: "Upload component with custom label text.",
},
},
},
render: Template,
};
// All states comparison