Rule Stack storyboard

This commit is contained in:
adilallo
2025-08-24 22:01:52 -06:00
parent 7c814de28e
commit f22cde728a
3 changed files with 261 additions and 1 deletions
+176
View File
@@ -0,0 +1,176 @@
import RuleCard from "../app/components/RuleCard";
import Image from "next/image";
export default {
title: "Components/RuleCard",
component: RuleCard,
parameters: {
layout: "centered",
docs: {
description: {
component:
"An interactive card component that displays governance templates and decision-making patterns. Features hover states, keyboard navigation, analytics tracking, and accessibility support. Use Tab key to test focus indicators and Enter/Space to activate.",
},
},
},
argTypes: {
title: {
control: { type: "text" },
description: "The title of the governance template",
},
description: {
control: { type: "text" },
description: "The description of the governance pattern",
},
backgroundColor: {
control: { type: "select" },
options: [
"bg-[var(--color-surface-default-brand-lime)]",
"bg-[var(--color-surface-default-brand-rust)]",
"bg-[var(--color-surface-default-brand-red)]",
"bg-[var(--color-surface-default-brand-teal)]",
"bg-[var(--color-community-teal-100)]",
],
description: "The background color variant for the card",
},
onClick: { action: "clicked" },
},
tags: ["autodocs"],
};
export const Default = {
args: {
title: "Consensus clusters",
description:
"Units called Circles have the ability to decide and act on matters in their domains, which their members agree on through a Council.",
backgroundColor: "bg-[var(--color-surface-default-brand-lime)]",
icon: (
<Image
src="/assets/Icon_Sociocracy.svg"
alt="Sociocracy"
width={40}
height={40}
className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]"
/>
),
},
};
export const AllVariants = {
render: (args) => (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-4xl">
<RuleCard
title="Consensus clusters"
description="Units called Circles have the ability to decide and act on matters in their domains, which their members agree on through a Council."
backgroundColor="bg-[var(--color-surface-default-brand-lime)]"
icon={
<Image
src="/assets/Icon_Sociocracy.svg"
alt="Sociocracy"
width={40}
height={40}
className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]"
/>
}
onClick={() => console.log("Consensus clusters selected")}
/>
<RuleCard
title="Consensus"
description="Decisions that affect the group collectively should involve participation of all participants."
backgroundColor="bg-[var(--color-surface-default-brand-rust)]"
icon={
<Image
src="/assets/Icon_Consensus.svg"
alt="Consensus"
width={40}
height={40}
className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]"
/>
}
onClick={() => console.log("Consensus selected")}
/>
<RuleCard
title="Elected Board"
description="An elected board determines policies and organizes their implementation."
backgroundColor="bg-[var(--color-surface-default-brand-red)]"
icon={
<Image
src="/assets/Icon_ElectedBoard.svg"
alt="Elected Board"
width={40}
height={40}
className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]"
/>
}
onClick={() => console.log("Elected Board selected")}
/>
<RuleCard
title="Petition"
description="All participants can propose and vote on proposals for the group."
backgroundColor="bg-[var(--color-surface-default-brand-teal)]"
icon={
<Image
src="/assets/Icon_Petition.svg"
alt="Petition"
width={40}
height={40}
className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]"
/>
}
onClick={() => console.log("Petition selected")}
/>
</div>
),
parameters: {
docs: {
description: {
story:
"All four governance template variants with their respective colors and icons. Test hover states, focus indicators, and click interactions.",
},
},
},
};
export const InteractiveStates = {
args: {
title: "Interactive Demo",
description:
"Hover over this card to see the scale and shadow effects. Use Tab to focus and Enter/Space to activate.",
backgroundColor: "bg-[var(--color-community-teal-100)]",
icon: (
<div className="w-10 h-10 md:w-14 md:h-14 lg:w-[90px] lg:h-[90px] bg-white rounded-full flex items-center justify-center">
<span className="text-lg font-bold text-gray-800">?</span>
</div>
),
},
parameters: {
docs: {
description: {
story:
"Demonstrates interactive states including hover effects, focus indicators, and keyboard navigation. Test with mouse hover and keyboard Tab/Enter/Space.",
},
},
},
};
export const AccessibilityTest = {
args: {
title: "Accessibility Demo",
description:
"This card is designed for accessibility testing. Use Tab to focus, Enter/Space to activate, and screen readers to test ARIA labels.",
backgroundColor: "bg-[var(--color-surface-default-brand-teal)]",
icon: (
<div className="w-10 h-10 md:w-14 md:h-14 lg:w-[90px] lg:h-[90px] bg-white rounded-full flex items-center justify-center">
<span className="text-lg font-bold text-gray-800"></span>
</div>
),
},
parameters: {
docs: {
description: {
story:
"Specifically designed for testing accessibility features including keyboard navigation, screen reader support, and focus management.",
},
},
},
};
+39
View File
@@ -0,0 +1,39 @@
import RuleStack from "../app/components/RuleStack";
export default {
title: "Components/RuleStack",
component: RuleStack,
parameters: {
layout: "fullscreen",
docs: {
description: {
component:
"A complete template library component that displays governance patterns in a responsive grid layout. Includes SectionHeader with multi-line variant, interactive RuleCard components, and a call-to-action button. Features comprehensive accessibility, analytics tracking, and responsive design across all breakpoints.\n\n" +
"**Testing Scenarios:**\n" +
"- **Responsive Testing**: Resize browser window to test layout adaptation from single column on mobile to 2x2 grid on larger screens\n" +
"- **Interactive Testing**: Hover over cards to see effects, use Tab to navigate between cards, and click to see analytics events in console\n" +
"- **Accessibility Testing**: Use screen readers to test ARIA labels, keyboard navigation to move between cards, and verify focus indicators\n" +
"- **Custom Styling**: Add className prop to customize background or other styling",
},
},
},
argTypes: {
className: {
control: { type: "text" },
description: "Additional CSS classes for custom styling",
},
},
tags: ["autodocs"],
};
export const Default = {
args: {},
parameters: {
docs: {
description: {
story:
"The complete RuleStack component with all four governance templates, responsive grid layout, and interactive features. Test hover states, keyboard navigation, and responsive behavior across different screen sizes.",
},
},
},
};
+46 -1
View File
@@ -8,7 +8,7 @@ export default {
docs: { docs: {
description: { description: {
component: component:
"A section header component that displays a title and subtitle with responsive typography and layout. Supports different title text for large breakpoints and maintains consistent spacing across all screen sizes.", "A section header component that displays a title and subtitle with responsive typography and layout. Supports different title text for large breakpoints and maintains consistent spacing across all screen sizes. Includes 'default' and 'multi-line' variants with different layout behaviors.",
}, },
}, },
}, },
@@ -26,6 +26,12 @@ export default {
description: description:
"The title text for lg and xl breakpoints (optional, falls back to title)", "The title text for lg and xl breakpoints (optional, falls back to title)",
}, },
variant: {
control: { type: "select" },
options: ["default", "multi-line"],
description:
"The layout variant - 'default' for traditional layout, 'multi-line' for 50/50 split layout",
},
}, },
tags: ["autodocs"], tags: ["autodocs"],
}; };
@@ -35,6 +41,24 @@ export const Default = {
title: "How CommunityRule works", title: "How CommunityRule works",
subtitle: "Here's a quick overview of the process, from start to finish.", subtitle: "Here's a quick overview of the process, from start to finish.",
titleLg: "How CommunityRule helps", titleLg: "How CommunityRule helps",
variant: "default",
},
};
export const MultiLine = {
args: {
title: "Popular templates",
subtitle:
"These are popular patterns for making decisions in mutual aid and open source communities. You can use them as they are or as a starting place for customizing your own CommunityRule.",
variant: "multi-line",
},
parameters: {
docs: {
description: {
story:
"The multi-line variant creates a 50/50 split layout at lg and xl breakpoints, with the title on the left and subtitle on the right. This variant is used in the RuleStack component.",
},
},
}, },
}; };
@@ -44,6 +68,7 @@ export const CustomContent = {
subtitle: subtitle:
"We're dedicated to helping communities thrive through better decision-making processes and transparent governance structures.", "We're dedicated to helping communities thrive through better decision-making processes and transparent governance structures.",
titleLg: "Building Better Communities", titleLg: "Building Better Communities",
variant: "default",
}, },
parameters: { parameters: {
docs: { docs: {
@@ -61,6 +86,7 @@ export const LongSubtitle = {
subtitle: subtitle:
"This is a much longer subtitle that demonstrates how the component handles extended text content across different breakpoints and layout configurations.", "This is a much longer subtitle that demonstrates how the component handles extended text content across different breakpoints and layout configurations.",
titleLg: "Complex Process Simplified", titleLg: "Complex Process Simplified",
variant: "default",
}, },
parameters: { parameters: {
docs: { docs: {
@@ -78,6 +104,7 @@ export const ResponsiveTest = {
subtitle: subtitle:
"Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.", "Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.",
titleLg: "Responsive Design Test", titleLg: "Responsive Design Test",
variant: "default",
}, },
parameters: { parameters: {
docs: { docs: {
@@ -94,6 +121,7 @@ export const WithoutTitleLg = {
title: "Simple Header", title: "Simple Header",
subtitle: subtitle:
"This example doesn't specify a titleLg prop, so it will use the same title text across all breakpoints.", "This example doesn't specify a titleLg prop, so it will use the same title text across all breakpoints.",
variant: "default",
}, },
parameters: { parameters: {
docs: { docs: {
@@ -104,3 +132,20 @@ export const WithoutTitleLg = {
}, },
}, },
}; };
export const MultiLineResponsive = {
args: {
title: "Multi-line Responsive Test",
subtitle:
"This multi-line variant demonstrates the 50/50 split layout at larger breakpoints. Resize your browser to see how the layout adapts from stacked on mobile to side-by-side on desktop.",
variant: "multi-line",
},
parameters: {
docs: {
description: {
story:
"Test the responsive behavior of the multi-line variant. The layout changes from stacked on mobile to 50/50 split on lg and xl breakpoints.",
},
},
},
};