Core Dithering System: - Add Bayer matrix 8×8/4×4 ordered dithering algorithm - Implement DitherEngine with canvas-based text rendering - Create reveal (one-shot) and pulse (continuous) animation modes - Add SSR safety checks for Next.js server-side rendering New UI Components: - DitherCanvas: Base component with RAF-based animation - DitherHeadline: Multi-line staggered reveal for hero text - DitherSectionHeader: Pulsing section headers - FlowDiagram: Animated SVG showing agent→registry→tools flow - ActivityStream: Live ticker with mock tool activity Accessibility Features: - useReducedMotion hook for prefers-reduced-motion support - Screen reader compatibility with aria-labels - Fallback to static rendering when animations disabled Homepage Redesign: - Replace generic sections with narrative storytelling - Add ProblemSection: Fragmented chaos design (before tpmjs) - Add VisionSection: Dynamic ecosystem visualization (after tpmjs) - Redesign EcosystemStats with dithered counters and live activity - Add DeveloperStories: Code-first testimonials - Update HeroSection with dithered headline and blueprint scanline Visual Design: - Minimalist + Blueprint technical aesthetic - Animated scanline background effect - Grid patterns with subtle opacity - Brutalist typography and hard edges Technical Implementation: - Export new components in UI package.json - Add components to tsup.config.ts entry points - SSR-safe canvas operations with environment checks - Performance optimizations: frame caching, mobile detection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
71 lines
2.1 KiB
TypeScript
71 lines
2.1 KiB
TypeScript
import path from 'node:path';
|
|
import { glob } from 'glob';
|
|
import { defineConfig } from 'tsup';
|
|
|
|
/**
|
|
* Auto-discover all component entry points
|
|
* Looks for src/ComponentName/ComponentName.tsx files where the folder name matches the file name
|
|
*/
|
|
const allFiles = glob.sync('src/**/[A-Z]*.{ts,tsx}', {
|
|
ignore: [
|
|
'**/*.test.ts',
|
|
'**/*.test.tsx',
|
|
'**/*.stories.ts',
|
|
'**/types.ts',
|
|
'**/tokens.ts',
|
|
'**/variants.ts',
|
|
'**/index.ts',
|
|
'src/test-setup.ts',
|
|
'src/tokens/**',
|
|
'src/system/**',
|
|
],
|
|
});
|
|
|
|
// Filter to only include files where the folder name matches the file name
|
|
// e.g., src/Button/Button.tsx is included, but src/Button/helpers.ts is not
|
|
const entries = allFiles.filter((file) => {
|
|
const dir = path.dirname(file);
|
|
const folderName = path.basename(dir);
|
|
const fileName = path.basename(file).replace(/\.(ts|tsx)$/, '');
|
|
return folderName === fileName;
|
|
});
|
|
|
|
// Manually add RadioGroup which doesn't match the folder/file naming convention
|
|
entries.push('src/Radio/RadioGroup.tsx');
|
|
|
|
// Manually add DitherText components
|
|
entries.push('src/DitherText/DitherHeadline.tsx');
|
|
entries.push('src/DitherText/DitherSectionHeader.tsx');
|
|
|
|
// Manually add system hooks
|
|
entries.push('src/system/hooks/useScrollReveal.ts');
|
|
entries.push('src/system/hooks/useCountUp.ts');
|
|
entries.push('src/system/hooks/useParallax.ts');
|
|
entries.push('src/system/hooks/useReducedMotion.ts');
|
|
entries.push('src/system/hooks/useDitherAnimation.ts');
|
|
|
|
export default defineConfig({
|
|
entry: entries,
|
|
format: ['esm'],
|
|
dts: {
|
|
// Reduce memory usage in CI by disabling concurrent workers
|
|
// This prevents "JS heap out of memory" errors when building many components
|
|
compilerOptions: {
|
|
composite: false,
|
|
},
|
|
},
|
|
clean: true,
|
|
treeshake: false, // Disable treeshaking to preserve 'use client'
|
|
splitting: false,
|
|
external: ['react', 'react-dom'],
|
|
banner: {
|
|
js: '"use client";',
|
|
},
|
|
esbuildOptions(options) {
|
|
options.jsx = 'automatic';
|
|
// Try to preserve directives
|
|
options.legalComments = 'inline';
|
|
},
|
|
// Reduce bundle size by minifying in production
|
|
minify: false, // Disable minification to preserve directives
|
|
});
|