+ ) : null}
{/* Loading state */}
- {imageLoading && (
+ {imageLoading && !imageError && (
)}
{/* Error state - show initials */}
- {imageError && !imageLoading && (
+ {imageError && (
@@ -184,7 +186,20 @@ const QuoteBlock = ({
className="relative"
>
{quote}
@@ -199,7 +214,16 @@ const QuoteBlock = ({
{source && (
{source}
diff --git a/stories/QuoteBlock.stories.js b/stories/QuoteBlock.stories.js
new file mode 100644
index 0000000..3b4f0f6
--- /dev/null
+++ b/stories/QuoteBlock.stories.js
@@ -0,0 +1,146 @@
+import QuoteBlock from "../app/components/QuoteBlock";
+
+export default {
+ title: "Components/QuoteBlock",
+ component: QuoteBlock,
+ parameters: {
+ layout: "fullscreen",
+ docs: {
+ description: {
+ component: `
+A responsive quote section component that displays inspirational governance quotes with author attribution and decorative geometric elements.
+
+## Features
+- **Three variants**: compact, standard, and extended layouts
+- **Responsive design**: Adapts across all breakpoints
+- **Error handling**: Graceful fallbacks for image loading failures
+- **Accessibility**: WCAG 2.1 AA compliant with proper ARIA labels
+- **Design system integration**: Uses design tokens for consistent styling
+
+## Usage
+\`\`\`jsx
+
+\`\`\`
+ `,
+ },
+ },
+ },
+ argTypes: {
+ variant: {
+ control: { type: "select" },
+ options: ["compact", "standard", "extended"],
+ description: "Layout variant for different use cases",
+ },
+ quote: {
+ control: { type: "text" },
+ description: "The quote text to display",
+ },
+ author: {
+ control: { type: "text" },
+ description: "Author name for attribution",
+ },
+ source: {
+ control: { type: "text" },
+ description: "Source title (book, article, etc.)",
+ },
+ avatarSrc: {
+ control: { type: "text" },
+ description: "Path to author avatar image",
+ },
+ fallbackAvatarSrc: {
+ control: { type: "text" },
+ description: "Fallback avatar image path",
+ },
+ onError: {
+ action: "error",
+ description: "Error callback function",
+ },
+ },
+};
+
+// Default story
+export const Default = {
+ args: {
+ variant: "standard",
+ quote:
+ "The rules of decision-making must be open and available to everyone, and this can happen only if they are formalized.",
+ author: "Jo Freeman",
+ source: "The Tyranny of Structurelessness",
+ avatarSrc: "assets/Quote_Avatar.svg",
+ },
+};
+
+// All variants comparison
+export const AllVariants = {
+ render: () => (
+
+
+
Compact Variant
+
+
+
+
+
Standard Variant
+
+
+
+
+
Extended Variant
+
+
+
+ ),
+ parameters: {
+ docs: {
+ description: {
+ story:
+ "Side-by-side comparison of all three variants to show the differences in layout, typography, and spacing.",
+ },
+ },
+ },
+};
+
+// Error state simulation
+export const ErrorState = {
+ args: {
+ variant: "standard",
+ quote:
+ "The rules of decision-making must be open and available to everyone, and this can happen only if they are formalized.",
+ author: "Jo Freeman",
+ source: "The Tyranny of Structurelessness",
+ avatarSrc: "invalid-image-path.jpg", // This will trigger error state
+ onError: (error) => console.log("QuoteBlock error:", error),
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ "Error state when avatar image fails to load. Shows initials fallback and error handling.",
+ },
+ },
+ },
+};
--
2.43.0
From 3609501fea3d4146f730b6368febfa0e256ff345 Mon Sep 17 00:00:00 2001
From: adilallo <39313955+adilallo@users.noreply.github.com>
Date: Tue, 26 Aug 2025 10:45:20 -0600
Subject: [PATCH 8/8] Fix github pages storybook fonts
---
.storybook/preview.github.js | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/.storybook/preview.github.js b/.storybook/preview.github.js
index 1fd25df..8b6689a 100644
--- a/.storybook/preview.github.js
+++ b/.storybook/preview.github.js
@@ -1,5 +1,29 @@
import "../app/globals.css";
+// Import Google Fonts for Storybook
+import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google";
+
+const inter = Inter({
+ subsets: ["latin"],
+ weight: ["400", "500", "600", "700"],
+ variable: "--font-inter",
+ display: "swap",
+});
+
+const bricolageGrotesque = Bricolage_Grotesque({
+ subsets: ["latin"],
+ weight: ["400", "500", "700", "800"],
+ variable: "--font-bricolage-grotesque",
+ display: "swap",
+});
+
+const spaceGrotesk = Space_Grotesk({
+ subsets: ["latin"],
+ weight: ["400", "500", "700"],
+ variable: "--font-space-grotesk",
+ display: "swap",
+});
+
/** @type { import('@storybook/react').Preview } */
const preview = {
parameters: {
@@ -11,6 +35,15 @@ const preview = {
},
},
},
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
};
export default preview;
--
2.43.0