From 4f9dc4666d249c1c67c51a3901c4f657ff9723ef Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 3 Nov 2025 18:24:24 -0600 Subject: [PATCH] docs(abacus-react): add Storybook stories for AbacusStatic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comprehensive documentation and examples demonstrating: - Default usage and different values - All color schemes (place-value, monochrome, heaven-earth, alternating) - All bead shapes (circle, diamond, square) - Compact mode for inline displays - Hide inactive beads - Theme presets (light, dark, trophy) - Column highlighting and labels - Scaling options - Server Component usage examples - Preview card grids Highlights that AbacusStatic shares logic with AbacusReact (no duplication). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../abacus-react/src/AbacusStatic.stories.tsx | 264 ++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 packages/abacus-react/src/AbacusStatic.stories.tsx diff --git a/packages/abacus-react/src/AbacusStatic.stories.tsx b/packages/abacus-react/src/AbacusStatic.stories.tsx new file mode 100644 index 00000000..789becab --- /dev/null +++ b/packages/abacus-react/src/AbacusStatic.stories.tsx @@ -0,0 +1,264 @@ +import type { Meta, StoryObj } from '@storybook/react' +import { AbacusStatic } from './AbacusStatic' +import { ABACUS_THEMES } from './AbacusThemes' + +/** + * AbacusStatic - Server Component compatible static abacus + * + * ## Key Features: + * - ✅ Works in React Server Components (no "use client") + * - ✅ Shares core utilities with AbacusReact (numberToAbacusState, color logic) + * - ✅ No animations, hooks, or client-side JavaScript + * - ✅ Lightweight rendering for static displays + * + * ## Shared Code (No Duplication!): + * - Uses `numberToAbacusState()` from AbacusUtils + * - Uses same color scheme logic as AbacusReact + * - Uses same bead positioning concepts + * - Accepts same `customStyles` prop structure + * + * ## When to Use: + * - React Server Components (Next.js App Router) + * - Static site generation + * - Non-interactive previews + * - Server-side rendering without hydration + */ +const meta = { + title: 'AbacusStatic/Server Component Ready', + component: AbacusStatic, + parameters: { + layout: 'centered', + }, + tags: ['autodocs'], +} satisfies Meta + +export default meta +type Story = StoryObj + +export const Default: Story = { + args: { + value: 123, + columns: 'auto', + }, +} + +export const DifferentValues: Story = { + render: () => ( +
+ {[1, 5, 10, 25, 50, 100, 456, 789].map((value) => ( +
+ +

{value}

+
+ ))} +
+ ), +} + +export const ColorSchemes: Story = { + render: () => ( +
+
+ +

Place Value

+
+
+ +

Monochrome

+
+
+ +

Heaven-Earth

+
+
+ +

Alternating

+
+
+ ), +} + +export const BeadShapes: Story = { + render: () => ( +
+
+ +

Circle

+
+
+ +

Diamond

+
+
+ +

Square

+
+
+ ), +} + +export const CompactMode: Story = { + render: () => ( +
+ The equation: + + + + + = + +
+ ), +} + +export const HideInactiveBeads: Story = { + render: () => ( +
+
+ +

Show All

+
+
+ +

Hide Inactive

+
+
+ ), +} + +export const WithThemes: Story = { + render: () => ( +
+
+ +

Light

+
+
+ +

Dark

+
+
+ +

Trophy

+
+
+ ), +} + +export const ColumnHighlightingAndLabels: Story = { + render: () => ( +
+
+ +

Highlighting tens place

+
+
+ +

Multiple highlights

+
+
+ ), +} + +export const Scaling: Story = { + render: () => ( +
+
+ +

0.5x

+
+
+ +

1x

+
+
+ +

1.5x

+
+
+ ), +} + +export const ServerComponentExample: Story = { + render: () => ( +
+

React Server Component Usage

+
+        {`// app/flashcards/page.tsx (Server Component)
+import { AbacusStatic } from '@soroban/abacus-react'
+
+export default function FlashcardsPage() {
+  const numbers = [1, 5, 10, 25, 50, 100]
+
+  return (
+    
+ {numbers.map(num => ( +
+ +

{num}

+
+ ))} +
+ ) +} + +// ✅ No "use client" needed! +// ✅ Rendered on server +// ✅ Zero client JavaScript`} +
+
+ ), +} + +export const PreviewCards: Story = { + render: () => ( +
+ {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 25, 50].map((value) => ( +
+ + {value} +
+ ))} +
+ ), +}