Phase 2: - Extract React Query patterns to reference/react-query-mutations.md - Extract TensorFlow debugging to reference/tensorflow-browser-debugging.md - Extract Abacus Visualizations to reference/abacus-react.md - Slim Production Dependencies (73→7 lines) - Slim Code Factoring (75→9 lines) - Slim Data Attributes (49→9 lines) Phase 3: - Consolidate 3 CRITICAL behavioral sections (92→12 lines) - Slim Merge Conflict, Z-Index, Animation, Game Settings sections - Slim Flowchart Walker, Daily Practice, Rithmomachia - Remove duplicate package.json scripts section - Consolidate workflow and dev server sections Total reduction: 1,531 → 258 lines (83% smaller) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
3.1 KiB
3.1 KiB
Abacus Visualizations Reference
CRITICAL: This project uses @soroban/abacus-react for all abacus visualizations.
Quick Reference
- Package:
@soroban/abacus-react(location:packages/abacus-react) - Main components:
AbacusReact,useAbacusConfig,useAbacusDisplay - Docs:
packages/abacus-react/README.md
Rules
- ✅ Always use
AbacusReactfrom@soroban/abacus-react - ✅ Use
useAbacusConfigfor abacus configuration - ✅ Use
useAbacusDisplayfor reading abacus state - ❌ Don't create custom abacus components or SVGs
- ❌ Don't manually render abacus beads or columns
Server-Side Rendering
AbacusReact already supports SSR - it detects SSR and disables animations automatically.
✅ CORRECT - Use in build scripts:
// scripts/generateAbacusIcons.tsx
import React from 'react'
import { renderToStaticMarkup } from 'react-dom/server'
import { AbacusReact } from '@soroban/abacus-react'
const svg = renderToStaticMarkup(<AbacusReact value={5} columns={2} />)
// This works! Scripts can use react-dom/server
❌ WRONG - Do NOT use in Next.js route handlers:
// src/app/icon/route.tsx - DON'T DO THIS!
import { renderToStaticMarkup } from 'react-dom/server' // ❌ Next.js forbids this!
import { AbacusReact } from '@soroban/abacus-react'
export async function GET() {
const svg = renderToStaticMarkup(<AbacusReact ... />) // ❌ Will fail!
}
✅ CORRECT - Pre-generate and read in route handlers:
// src/app/icon/route.tsx
import { readFileSync } from "fs";
export async function GET() {
// Read pre-generated SVG from scripts/generateAbacusIcons.tsx
const svg = readFileSync("public/icons/day-01.svg", "utf-8");
return new Response(svg, { headers: { "Content-Type": "image/svg+xml" } });
}
Pattern to follow:
- Generate static SVGs using
scripts/generateAbacusIcons.tsx(uses renderToStaticMarkup) - Commit generated SVGs to
public/icons/orpublic/ - Route handlers read and serve the pre-generated files
- Regenerate icons when abacus styling changes
Customizing AbacusReact
ALWAYS read the full README documentation before customizing:
- Location:
packages/abacus-react/README.md - Check homepage implementation:
src/app/page.tsx(MiniAbacus component) - Check storybook examples:
src/stories/AbacusReact.*.stories.tsx
Key Documentation Points:
- Custom Styles: Use
fill(not juststroke) for columnPosts and reckoningBar - Props: Use direct props like
value,columns,scaleFactor(not config objects)
Example with Custom Styles:
const darkStyles = {
columnPosts: {
fill: 'rgba(255, 255, 255, 0.3)',
stroke: 'rgba(255, 255, 255, 0.2)',
strokeWidth: 2,
},
reckoningBar: {
fill: 'rgba(255, 255, 255, 0.4)',
stroke: 'rgba(255, 255, 255, 0.25)',
strokeWidth: 3,
},
}
<AbacusReact
value={123}
columns={3}
customStyles={darkStyles}
/>
Basic Usage:
import { AbacusReact } from '@soroban/abacus-react'
<AbacusReact value={123} columns={5} scaleFactor={1.5} showNumbers={true} />