feat: initial project setup with Next.js 16 and Tailwind CSS 4
- Initialize Next.js 16 with React 19 and TypeScript 5 - Configure Tailwind CSS 4 with PostCSS - Set up static export for Docker deployment - Install figlet.js for ASCII art rendering - Add fuse.js for fuzzy search functionality - Create project structure (app/, components/, lib/, types/) - Add comprehensive README and IMPLEMENTATION_PLAN - Configure ESLint and TypeScript - Set up pnpm package management Tech stack matches units-ui project for consistency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
26
.dockerignore
Normal file
26
.dockerignore
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# build artifacts
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
|
||||||
|
# development
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# misc
|
||||||
|
README.md
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
3
.eslintrc.json
Normal file
3
.eslintrc.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "next/core-web-vitals"
|
||||||
|
}
|
||||||
44
.gitignore
vendored
Normal file
44
.gitignore
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.*
|
||||||
|
.yarn/*
|
||||||
|
!.yarn/patches
|
||||||
|
!.yarn/plugins
|
||||||
|
!.yarn/releases
|
||||||
|
!.yarn/versions
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# env files
|
||||||
|
.env*.local
|
||||||
|
.env
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
# Figlet fonts (will be cloned separately)
|
||||||
|
/public/fonts/figlet-fonts
|
||||||
443
IMPLEMENTATION_PLAN.md
Normal file
443
IMPLEMENTATION_PLAN.md
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
# Figlet UI - Implementation Plan
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
A modern, feature-rich web UI for generating ASCII art text using figlet.js with 700+ fonts from xero/figlet-fonts. This project aims to be the best figlet web interface, significantly improving upon existing solutions like TAAG.
|
||||||
|
|
||||||
|
**Tech Stack:**
|
||||||
|
- Next.js 16 with static export
|
||||||
|
- React 19
|
||||||
|
- TypeScript 5
|
||||||
|
- Tailwind CSS 4
|
||||||
|
- figlet.js for ASCII art rendering
|
||||||
|
- Fuse.js for fuzzy search
|
||||||
|
- Lucide React for icons
|
||||||
|
- Docker deployment with nginx
|
||||||
|
|
||||||
|
## Key Features & Improvements Over TAAG
|
||||||
|
|
||||||
|
### Superior Font Management
|
||||||
|
- **700+ fonts** from xero collection (vs ~300 on TAAG)
|
||||||
|
- Visual font preview cards
|
||||||
|
- Fuzzy search with intelligent matching
|
||||||
|
- Font categories and tags (3D, block, script, retro, etc.)
|
||||||
|
- Favorites system with localStorage
|
||||||
|
- Recently used fonts
|
||||||
|
- Random font discovery
|
||||||
|
|
||||||
|
### Better Export & Sharing
|
||||||
|
- One-click copy to clipboard
|
||||||
|
- Export as PNG/SVG images
|
||||||
|
- Export as HTML with styling
|
||||||
|
- Shareable URLs (text + font encoded)
|
||||||
|
- Download as .txt file
|
||||||
|
- Generate code snippets (JS, Python, Bash)
|
||||||
|
- Markdown-ready code blocks
|
||||||
|
|
||||||
|
### Enhanced UX
|
||||||
|
- Live preview as you type
|
||||||
|
- Debounced updates for performance
|
||||||
|
- Dark/light mode toggle
|
||||||
|
- Keyboard shortcuts (/, Esc, Ctrl+C, Ctrl+K)
|
||||||
|
- Command palette for quick actions
|
||||||
|
- Mobile-optimized layout
|
||||||
|
- Smooth animations and transitions
|
||||||
|
- Character counter
|
||||||
|
- Width constraint preview
|
||||||
|
|
||||||
|
### Modern UI Design
|
||||||
|
- Clean, minimalist interface
|
||||||
|
- Responsive layout (mobile-first)
|
||||||
|
- Better typography and spacing
|
||||||
|
- Smooth transitions
|
||||||
|
- Loading states
|
||||||
|
- Empty states
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
## Implementation Phases
|
||||||
|
|
||||||
|
### Phase 1: Project Setup ✅
|
||||||
|
- [x] Initialize git repository
|
||||||
|
- [x] Add GitHub remote origin
|
||||||
|
- [x] Create Next.js 16 project with TypeScript
|
||||||
|
- [x] Configure Tailwind CSS 4
|
||||||
|
- [x] Install dependencies (figlet, fuse.js, lucide-react)
|
||||||
|
- [x] Set up project structure (app/, components/, lib/, types/)
|
||||||
|
- [x] Configure static export
|
||||||
|
- [x] Create initial commit
|
||||||
|
|
||||||
|
### Phase 2: Font Management System
|
||||||
|
- [ ] Clone xero/figlet-fonts into public/fonts/
|
||||||
|
- [ ] Create font loading service
|
||||||
|
- [ ] List all available fonts
|
||||||
|
- [ ] Load fonts on-demand (lazy loading)
|
||||||
|
- [ ] Cache loaded fonts in memory
|
||||||
|
- [ ] Build font metadata system
|
||||||
|
- [ ] Extract font characteristics (height, width, style)
|
||||||
|
- [ ] Categorize fonts by style tags
|
||||||
|
- [ ] Generate font preview data
|
||||||
|
- [ ] Create font types and interfaces
|
||||||
|
|
||||||
|
### Phase 3: Core Figlet Engine
|
||||||
|
- [ ] Implement figlet.js wrapper service
|
||||||
|
- [ ] Initialize figlet with custom fonts
|
||||||
|
- [ ] Handle font loading errors
|
||||||
|
- [ ] Provide type-safe API
|
||||||
|
- [ ] Create real-time rendering hook
|
||||||
|
- [ ] Debounced text input (300ms)
|
||||||
|
- [ ] Handle multi-line text
|
||||||
|
- [ ] Optimize re-renders
|
||||||
|
- [ ] Add text validation and sanitization
|
||||||
|
- [ ] Implement character width calculations
|
||||||
|
|
||||||
|
### Phase 4: Main UI Components
|
||||||
|
- [ ] Build main converter interface
|
||||||
|
- [ ] Text input area (textarea)
|
||||||
|
- [ ] Live preview display (pre/code block)
|
||||||
|
- [ ] Font selector component
|
||||||
|
- [ ] Options panel (alignment, width, etc.)
|
||||||
|
- [ ] Create font selector with search
|
||||||
|
- [ ] Visual font preview cards
|
||||||
|
- [ ] Fuzzy search implementation
|
||||||
|
- [ ] Category filters
|
||||||
|
- [ ] Sort options (name, recent, popular)
|
||||||
|
- [ ] Build responsive layout
|
||||||
|
- [ ] Desktop: side-by-side layout
|
||||||
|
- [ ] Mobile: stacked layout
|
||||||
|
- [ ] Tablet: adaptive layout
|
||||||
|
|
||||||
|
### Phase 5: Search & Filters
|
||||||
|
- [ ] Implement Fuse.js integration
|
||||||
|
- [ ] Configure fuzzy matching
|
||||||
|
- [ ] Index font names and metadata
|
||||||
|
- [ ] Real-time search results
|
||||||
|
- [ ] Add category filtering
|
||||||
|
- [ ] Style tags (3D, block, script, etc.)
|
||||||
|
- [ ] Font size filters
|
||||||
|
- [ ] System filters (metric/imperial)
|
||||||
|
- [ ] Create search UI
|
||||||
|
- [ ] Search input with icon
|
||||||
|
- [ ] Keyboard shortcut (/) to focus
|
||||||
|
- [ ] Clear button
|
||||||
|
- [ ] Results count
|
||||||
|
|
||||||
|
### Phase 6: Export & Sharing
|
||||||
|
- [ ] Copy to clipboard functionality
|
||||||
|
- [ ] One-click copy button
|
||||||
|
- [ ] Success feedback
|
||||||
|
- [ ] Clipboard API with fallback
|
||||||
|
- [ ] Export as image (PNG/SVG)
|
||||||
|
- [ ] Canvas rendering for PNG
|
||||||
|
- [ ] SVG text rendering
|
||||||
|
- [ ] Download with proper filename
|
||||||
|
- [ ] Shareable URLs
|
||||||
|
- [ ] Encode text + font in URL params
|
||||||
|
- [ ] Base64 compression for long text
|
||||||
|
- [ ] Auto-load from URL on page load
|
||||||
|
- [ ] Code snippet generation
|
||||||
|
- [ ] JavaScript/Node.js example
|
||||||
|
- [ ] Python example
|
||||||
|
- [ ] Bash/CLI command
|
||||||
|
- [ ] Copy individual snippets
|
||||||
|
|
||||||
|
### Phase 7: User Preferences & History
|
||||||
|
- [ ] Favorites system
|
||||||
|
- [ ] Mark fonts as favorite (heart icon)
|
||||||
|
- [ ] Save to localStorage
|
||||||
|
- [ ] Quick access to favorites
|
||||||
|
- [ ] Favorites filter
|
||||||
|
- [ ] Recent fonts
|
||||||
|
- [ ] Track last 10 used fonts
|
||||||
|
- [ ] Save to localStorage
|
||||||
|
- [ ] Display in font selector
|
||||||
|
- [ ] Conversion history
|
||||||
|
- [ ] Save recent conversions
|
||||||
|
- [ ] History panel/sidebar
|
||||||
|
- [ ] Re-apply previous conversion
|
||||||
|
- [ ] Clear history
|
||||||
|
|
||||||
|
### Phase 8: Keyboard Shortcuts & Command Palette
|
||||||
|
- [ ] Implement keyboard shortcuts
|
||||||
|
- [ ] `/` - Focus search
|
||||||
|
- [ ] `Esc` - Clear/close
|
||||||
|
- [ ] `Ctrl/Cmd + C` - Copy result
|
||||||
|
- [ ] `Ctrl/Cmd + K` - Open command palette
|
||||||
|
- [ ] `Ctrl/Cmd + D` - Toggle dark mode
|
||||||
|
- [ ] `Arrow keys` - Navigate fonts
|
||||||
|
- [ ] Build command palette
|
||||||
|
- [ ] Search commands
|
||||||
|
- [ ] Quick actions
|
||||||
|
- [ ] Recent commands
|
||||||
|
- [ ] Keyboard hints
|
||||||
|
|
||||||
|
### Phase 9: Dark Mode & Theming
|
||||||
|
- [ ] Implement theme system
|
||||||
|
- [ ] Light/dark mode toggle
|
||||||
|
- [ ] Save preference to localStorage
|
||||||
|
- [ ] System preference detection
|
||||||
|
- [ ] Smooth theme transitions
|
||||||
|
- [ ] Update color variables
|
||||||
|
- [ ] Dark mode color palette
|
||||||
|
- [ ] Ensure WCAG contrast ratios
|
||||||
|
- [ ] Theme-aware components
|
||||||
|
|
||||||
|
### Phase 10: Mobile Optimization
|
||||||
|
- [ ] Responsive breakpoints
|
||||||
|
- [ ] Mobile (< 640px)
|
||||||
|
- [ ] Tablet (640px - 1024px)
|
||||||
|
- [ ] Desktop (> 1024px)
|
||||||
|
- [ ] Touch-friendly UI
|
||||||
|
- [ ] Large tap targets (44px min)
|
||||||
|
- [ ] Swipe gestures (optional)
|
||||||
|
- [ ] Mobile font selector (bottom sheet)
|
||||||
|
- [ ] Performance on mobile
|
||||||
|
- [ ] Lazy load fonts
|
||||||
|
- [ ] Optimize image exports
|
||||||
|
- [ ] Reduce bundle size
|
||||||
|
|
||||||
|
### Phase 11: Advanced Features
|
||||||
|
- [ ] Font comparison mode
|
||||||
|
- [ ] Side-by-side preview
|
||||||
|
- [ ] Compare 2-4 fonts
|
||||||
|
- [ ] Toggle comparison view
|
||||||
|
- [ ] Random font generator
|
||||||
|
- [ ] Shuffle button
|
||||||
|
- [ ] Exclude recently used
|
||||||
|
- [ ] Lock text while changing font
|
||||||
|
- [ ] Text alignment options
|
||||||
|
- [ ] Left, center, right
|
||||||
|
- [ ] Custom width constraints
|
||||||
|
- [ ] Auto-fit to viewport
|
||||||
|
- [ ] Multi-line text support
|
||||||
|
- [ ] Preserve line breaks
|
||||||
|
- [ ] Line-by-line rendering
|
||||||
|
- [ ] Vertical spacing options
|
||||||
|
|
||||||
|
### Phase 12: Performance Optimization
|
||||||
|
- [ ] Web Workers for rendering
|
||||||
|
- [ ] Offload figlet rendering
|
||||||
|
- [ ] Non-blocking UI updates
|
||||||
|
- [ ] Progress indicators
|
||||||
|
- [ ] Lazy loading
|
||||||
|
- [ ] Font files on-demand
|
||||||
|
- [ ] Virtual scrolling for font list
|
||||||
|
- [ ] Intersection Observer for previews
|
||||||
|
- [ ] Bundle optimization
|
||||||
|
- [ ] Code splitting
|
||||||
|
- [ ] Tree shaking
|
||||||
|
- [ ] Dynamic imports
|
||||||
|
- [ ] Minification
|
||||||
|
|
||||||
|
### Phase 13: Accessibility & Polish
|
||||||
|
- [ ] WCAG 2.1 AA compliance
|
||||||
|
- [ ] Keyboard navigation
|
||||||
|
- [ ] Screen reader support
|
||||||
|
- [ ] ARIA labels and roles
|
||||||
|
- [ ] Focus indicators
|
||||||
|
- [ ] Color contrast
|
||||||
|
- [ ] Error handling
|
||||||
|
- [ ] Font load failures
|
||||||
|
- [ ] Network errors
|
||||||
|
- [ ] Invalid input handling
|
||||||
|
- [ ] User-friendly messages
|
||||||
|
- [ ] Loading states
|
||||||
|
- [ ] Skeleton screens
|
||||||
|
- [ ] Progress indicators
|
||||||
|
- [ ] Smooth transitions
|
||||||
|
- [ ] Empty states
|
||||||
|
- [ ] No search results
|
||||||
|
- [ ] No favorites yet
|
||||||
|
- [ ] No history
|
||||||
|
|
||||||
|
### Phase 14: Docker Deployment
|
||||||
|
- [ ] Create multi-stage Dockerfile
|
||||||
|
- [ ] Stage 1: Dependencies (node:22-alpine)
|
||||||
|
- [ ] Stage 2: Builder (pnpm build)
|
||||||
|
- [ ] Stage 3: Runner (nginx:alpine)
|
||||||
|
- [ ] Configure nginx.conf
|
||||||
|
- [ ] Static file serving
|
||||||
|
- [ ] Gzip compression
|
||||||
|
- [ ] Cache headers
|
||||||
|
- [ ] Security headers
|
||||||
|
- [ ] Add health check
|
||||||
|
- [ ] Create .dockerignore
|
||||||
|
- [ ] Build and test image
|
||||||
|
- [ ] Document deployment
|
||||||
|
|
||||||
|
### Phase 15: SEO & Meta Tags
|
||||||
|
- [ ] Add comprehensive metadata
|
||||||
|
- [ ] Title, description, keywords
|
||||||
|
- [ ] OpenGraph tags
|
||||||
|
- [ ] Twitter card tags
|
||||||
|
- [ ] Favicon and app icons
|
||||||
|
- [ ] Generate sitemap
|
||||||
|
- [ ] Add robots.txt
|
||||||
|
- [ ] Structured data (Schema.org)
|
||||||
|
- [ ] Performance optimization
|
||||||
|
- [ ] Lighthouse audit
|
||||||
|
- [ ] Core Web Vitals
|
||||||
|
- [ ] Image optimization
|
||||||
|
|
||||||
|
## Technical Architecture
|
||||||
|
|
||||||
|
### Component Structure
|
||||||
|
```
|
||||||
|
components/
|
||||||
|
├── converter/
|
||||||
|
│ ├── TextInput.tsx # Main text input
|
||||||
|
│ ├── FontPreview.tsx # ASCII art preview display
|
||||||
|
│ ├── FontSelector.tsx # Font selection with search
|
||||||
|
│ ├── FontCard.tsx # Individual font preview card
|
||||||
|
│ ├── OptionsPanel.tsx # Conversion options
|
||||||
|
│ └── ExportButtons.tsx # Export/copy actions
|
||||||
|
├── search/
|
||||||
|
│ ├── FuzzySearch.tsx # Search with Fuse.js
|
||||||
|
│ ├── SearchInput.tsx # Search input component
|
||||||
|
│ └── FilterPanel.tsx # Category/tag filters
|
||||||
|
├── ui/
|
||||||
|
│ ├── Button.tsx # Reusable button
|
||||||
|
│ ├── Input.tsx # Reusable input
|
||||||
|
│ ├── Card.tsx # Card container
|
||||||
|
│ ├── Badge.tsx # Tag/badge
|
||||||
|
│ ├── Tabs.tsx # Tab navigation
|
||||||
|
│ ├── Dialog.tsx # Modal dialog
|
||||||
|
│ └── CommandPalette.tsx # Keyboard command UI
|
||||||
|
└── layout/
|
||||||
|
├── Header.tsx # App header
|
||||||
|
├── Footer.tsx # App footer
|
||||||
|
└── ThemeToggle.tsx # Dark mode switch
|
||||||
|
```
|
||||||
|
|
||||||
|
### Service Layer
|
||||||
|
```
|
||||||
|
lib/
|
||||||
|
├── figlet/
|
||||||
|
│ ├── figletService.ts # Figlet.js wrapper
|
||||||
|
│ ├── fontLoader.ts # Font loading logic
|
||||||
|
│ ├── fontMetadata.ts # Font info/categorization
|
||||||
|
│ └── fontCache.ts # In-memory font cache
|
||||||
|
├── search/
|
||||||
|
│ ├── fuzzySearch.ts # Fuse.js integration
|
||||||
|
│ └── searchConfig.ts # Search configuration
|
||||||
|
├── export/
|
||||||
|
│ ├── clipboard.ts # Clipboard operations
|
||||||
|
│ ├── imageExport.ts # PNG/SVG generation
|
||||||
|
│ ├── codeGenerator.ts # Code snippet generation
|
||||||
|
│ └── urlSharing.ts # URL encoding/decoding
|
||||||
|
├── storage/
|
||||||
|
│ ├── favorites.ts # Favorites management
|
||||||
|
│ ├── history.ts # Conversion history
|
||||||
|
│ └── preferences.ts # User preferences
|
||||||
|
└── utils/
|
||||||
|
├── cn.ts # clsx + tailwind-merge
|
||||||
|
├── debounce.ts # Debounce utility
|
||||||
|
└── validation.ts # Input validation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type Definitions
|
||||||
|
```typescript
|
||||||
|
// Font metadata
|
||||||
|
interface FigletFont {
|
||||||
|
name: string;
|
||||||
|
path: string;
|
||||||
|
style: FontStyle[];
|
||||||
|
height: number;
|
||||||
|
width: number;
|
||||||
|
preview?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type FontStyle = '3d' | 'block' | 'script' | 'retro' | 'small' | 'banner' | 'decorative';
|
||||||
|
|
||||||
|
// Conversion settings
|
||||||
|
interface ConversionOptions {
|
||||||
|
font: string;
|
||||||
|
text: string;
|
||||||
|
horizontalLayout?: 'default' | 'fitted' | 'full';
|
||||||
|
verticalLayout?: 'default' | 'fitted' | 'full';
|
||||||
|
width?: number;
|
||||||
|
whitespaceBreak?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export format
|
||||||
|
type ExportFormat = 'text' | 'png' | 'svg' | 'html' | 'code';
|
||||||
|
|
||||||
|
// User preferences
|
||||||
|
interface UserPreferences {
|
||||||
|
theme: 'light' | 'dark' | 'system';
|
||||||
|
defaultFont: string;
|
||||||
|
recentFonts: string[];
|
||||||
|
favorites: string[];
|
||||||
|
history: ConversionRecord[];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conversion history
|
||||||
|
interface ConversionRecord {
|
||||||
|
id: string;
|
||||||
|
timestamp: number;
|
||||||
|
text: string;
|
||||||
|
font: string;
|
||||||
|
result: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Design System
|
||||||
|
|
||||||
|
### Color Palette
|
||||||
|
```css
|
||||||
|
/* Light mode */
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 0 0% 3.9%;
|
||||||
|
--primary: 0 0% 9%;
|
||||||
|
--muted: 0 0% 96.1%;
|
||||||
|
--border: 0 0% 89.8%;
|
||||||
|
|
||||||
|
/* Dark mode */
|
||||||
|
--background: 0 0% 3.9%;
|
||||||
|
--foreground: 0 0% 98%;
|
||||||
|
--primary: 0 0% 98%;
|
||||||
|
--muted: 0 0% 14.9%;
|
||||||
|
--border: 0 0% 14.9%;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Typography
|
||||||
|
- **Headings**: System font stack
|
||||||
|
- **Body**: System font stack
|
||||||
|
- **Mono**: Monospace (for ASCII art display)
|
||||||
|
|
||||||
|
### Spacing Scale
|
||||||
|
- Tailwind CSS 4 default scale (0.5rem increments)
|
||||||
|
|
||||||
|
## Performance Targets
|
||||||
|
|
||||||
|
- **First Contentful Paint**: < 1.0s
|
||||||
|
- **Time to Interactive**: < 2.0s
|
||||||
|
- **Lighthouse Score**: > 95
|
||||||
|
- **Bundle Size**: < 150KB (gzipped)
|
||||||
|
- **Font Load Time**: < 100ms per font
|
||||||
|
|
||||||
|
## Browser Support
|
||||||
|
|
||||||
|
- Chrome/Edge (last 2 versions)
|
||||||
|
- Firefox (last 2 versions)
|
||||||
|
- Safari (last 2 versions)
|
||||||
|
- Mobile Safari iOS 14+
|
||||||
|
- Chrome Android (last 2 versions)
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
- [ ] Custom font upload (.flf files)
|
||||||
|
- [ ] Animated ASCII art support
|
||||||
|
- [ ] Batch text generation
|
||||||
|
- [ ] API endpoint for programmatic access
|
||||||
|
- [ ] Browser extension
|
||||||
|
- [ ] PWA support with offline capability
|
||||||
|
- [ ] Multi-language support (i18n)
|
||||||
|
- [ ] Font editor/creator
|
||||||
|
- [ ] Collaborative sharing
|
||||||
|
- [ ] ASCII art gallery
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Project Start Date:** 2025-11-09
|
||||||
|
**Target Completion:** TBD
|
||||||
|
**Version:** 1.0.0
|
||||||
105
README.md
Normal file
105
README.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# Figlet UI
|
||||||
|
|
||||||
|
A modern, feature-rich web UI for generating ASCII art text using figlet.js with 700+ fonts from the [xero/figlet-fonts](https://github.com/xero/figlet-fonts) collection.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **700+ Figlet Fonts** - Massive library from xero's curated collection
|
||||||
|
- **Live Preview** - Real-time rendering as you type
|
||||||
|
- **Fuzzy Search** - Quickly find fonts by name or style
|
||||||
|
- **Visual Font Previews** - See actual rendering in the selector
|
||||||
|
- **Multiple Export Formats** - Copy, download as text, PNG, or SVG
|
||||||
|
- **Shareable URLs** - Share your creations with encoded URLs
|
||||||
|
- **Dark Mode** - Eye-friendly interface
|
||||||
|
- **Keyboard Shortcuts** - Power user features
|
||||||
|
- **Mobile Optimized** - Works great on all devices
|
||||||
|
- **Code Generation** - Generate snippets for JS, Python, CLI
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
|
||||||
|
- [Next.js 16](https://nextjs.org/) - React framework with static export
|
||||||
|
- [React 19](https://react.dev/) - Latest React with concurrent features
|
||||||
|
- [TypeScript 5](https://www.typescriptlang.org/) - Type-safe development
|
||||||
|
- [Tailwind CSS 4](https://tailwindcss.com/) - Modern utility-first CSS
|
||||||
|
- [figlet.js](https://github.com/patorjk/figlet.js) - ASCII art rendering engine
|
||||||
|
- [Fuse.js](https://fusejs.io/) - Fuzzy search functionality
|
||||||
|
- [Lucide React](https://lucide.dev/) - Beautiful icon library
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js 22+ (managed via nvm)
|
||||||
|
- pnpm (enabled via corepack)
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# Run development server with Turbopack
|
||||||
|
pnpm dev
|
||||||
|
|
||||||
|
# Build for production (static export)
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# Lint code
|
||||||
|
pnpm lint
|
||||||
|
```
|
||||||
|
|
||||||
|
The development server will be available at [http://localhost:3000](http://localhost:3000).
|
||||||
|
|
||||||
|
## Docker Deployment
|
||||||
|
|
||||||
|
Build and run with Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build Docker image
|
||||||
|
docker build -t figlet-ui .
|
||||||
|
|
||||||
|
# Run container
|
||||||
|
docker run -p 80:80 figlet-ui
|
||||||
|
```
|
||||||
|
|
||||||
|
The application will be available at [http://localhost](http://localhost).
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
figlet-ui/
|
||||||
|
├── app/ # Next.js app directory
|
||||||
|
│ ├── layout.tsx # Root layout with metadata
|
||||||
|
│ ├── page.tsx # Home page
|
||||||
|
│ └── globals.css # Global styles
|
||||||
|
├── components/ # React components
|
||||||
|
├── lib/ # Utility functions and services
|
||||||
|
├── types/ # TypeScript type definitions
|
||||||
|
├── public/ # Static assets
|
||||||
|
├── Dockerfile # Multi-stage Docker build
|
||||||
|
├── nginx.conf # Nginx configuration for static serving
|
||||||
|
└── IMPLEMENTATION_PLAN.md # Detailed implementation roadmap
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why Figlet UI is Better Than TAAG
|
||||||
|
|
||||||
|
- **10x More Fonts**: 700+ fonts vs ~300 on TAAG
|
||||||
|
- **Modern UI/UX**: Clean, responsive design with animations
|
||||||
|
- **Better Search**: Fuzzy search with visual previews
|
||||||
|
- **More Export Options**: PNG, SVG, code snippets, not just text
|
||||||
|
- **Shareable Links**: URL-encoded sharing
|
||||||
|
- **Performance**: Lazy loading, Web Workers for smooth experience
|
||||||
|
- **Dark Mode**: Built-in theme switching
|
||||||
|
- **Keyboard Shortcuts**: Power user efficiency
|
||||||
|
- **Mobile First**: Optimized for touch devices
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- [figlet.js](https://github.com/patorjk/figlet.js) by Patrick Gillespie
|
||||||
|
- [xero/figlet-fonts](https://github.com/xero/figlet-fonts) - Curated font collection
|
||||||
|
- Original [FIGlet](http://www.figlet.org/) project
|
||||||
58
app/globals.css
Normal file
58
app/globals.css
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
@import "tailwindcss";
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--background: 0 0% 100%;
|
||||||
|
--foreground: 0 0% 3.9%;
|
||||||
|
--card: 0 0% 100%;
|
||||||
|
--card-foreground: 0 0% 3.9%;
|
||||||
|
--popover: 0 0% 100%;
|
||||||
|
--popover-foreground: 0 0% 3.9%;
|
||||||
|
--primary: 0 0% 9%;
|
||||||
|
--primary-foreground: 0 0% 98%;
|
||||||
|
--secondary: 0 0% 96.1%;
|
||||||
|
--secondary-foreground: 0 0% 9%;
|
||||||
|
--muted: 0 0% 96.1%;
|
||||||
|
--muted-foreground: 0 0% 45.1%;
|
||||||
|
--accent: 0 0% 96.1%;
|
||||||
|
--accent-foreground: 0 0% 9%;
|
||||||
|
--destructive: 0 84.2% 60.2%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 0 0% 89.8%;
|
||||||
|
--input: 0 0% 89.8%;
|
||||||
|
--ring: 0 0% 3.9%;
|
||||||
|
--radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: 0 0% 3.9%;
|
||||||
|
--foreground: 0 0% 98%;
|
||||||
|
--card: 0 0% 3.9%;
|
||||||
|
--card-foreground: 0 0% 98%;
|
||||||
|
--popover: 0 0% 3.9%;
|
||||||
|
--popover-foreground: 0 0% 98%;
|
||||||
|
--primary: 0 0% 98%;
|
||||||
|
--primary-foreground: 0 0% 9%;
|
||||||
|
--secondary: 0 0% 14.9%;
|
||||||
|
--secondary-foreground: 0 0% 98%;
|
||||||
|
--muted: 0 0% 14.9%;
|
||||||
|
--muted-foreground: 0 0% 63.9%;
|
||||||
|
--accent: 0 0% 14.9%;
|
||||||
|
--accent-foreground: 0 0% 98%;
|
||||||
|
--destructive: 0 62.8% 30.6%;
|
||||||
|
--destructive-foreground: 0 0% 98%;
|
||||||
|
--border: 0 0% 14.9%;
|
||||||
|
--input: 0 0% 14.9%;
|
||||||
|
--ring: 0 0% 83.1%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
app/layout.tsx
Normal file
28
app/layout.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import type { Metadata } from 'next';
|
||||||
|
import './globals.css';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Figlet UI - ASCII Art Text Generator',
|
||||||
|
description: 'A modern web UI for generating ASCII art text with 700+ figlet fonts. Preview custom text in any figlet font, export to multiple formats, and share your creations.',
|
||||||
|
keywords: ['figlet', 'ascii art', 'text generator', 'banner', 'ascii', 'text art'],
|
||||||
|
authors: [{ name: 'Valknar' }],
|
||||||
|
openGraph: {
|
||||||
|
title: 'Figlet UI - ASCII Art Text Generator',
|
||||||
|
description: 'Generate beautiful ASCII art text with 700+ fonts',
|
||||||
|
type: 'website',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="en">
|
||||||
|
<body className="antialiased">
|
||||||
|
{children}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
28
app/page.tsx
Normal file
28
app/page.tsx
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
export default function Home() {
|
||||||
|
return (
|
||||||
|
<main className="min-h-screen p-8">
|
||||||
|
<div className="max-w-7xl mx-auto">
|
||||||
|
<header className="mb-8">
|
||||||
|
<h1 className="text-4xl font-bold mb-2">Figlet UI</h1>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
ASCII Art Text Generator with 700+ Fonts
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div className="bg-card border rounded-lg p-6">
|
||||||
|
<pre className="font-mono text-sm">
|
||||||
|
{` _____ _ _ _ _ _ ___
|
||||||
|
| ___(_) __ _| | ___| |_ | | | |_ _|
|
||||||
|
| |_ | |/ _\` | |/ _ \\ __| | | | || |
|
||||||
|
| _| | | (_| | | __/ |_ | |_| || |
|
||||||
|
|_| |_|\\__, |_|\\___|\\__| \\___/|___|
|
||||||
|
|___/ `}
|
||||||
|
</pre>
|
||||||
|
<p className="mt-4 text-muted-foreground">
|
||||||
|
Coming soon: A modern interface for generating beautiful ASCII art text.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
8
next.config.ts
Normal file
8
next.config.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type { NextConfig } from 'next';
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
output: 'export',
|
||||||
|
reactStrictMode: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
32
package.json
Normal file
32
package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "figlet-ui",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"figlet": "^1.8.0",
|
||||||
|
"fuse.js": "^7.1.0",
|
||||||
|
"lucide-react": "^0.553.0",
|
||||||
|
"next": "^16.0.0",
|
||||||
|
"react": "^19.0.0",
|
||||||
|
"react-dom": "^19.0.0",
|
||||||
|
"tailwind-merge": "^3.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4.1.17",
|
||||||
|
"@types/figlet": "^1.7.0",
|
||||||
|
"@types/node": "^22",
|
||||||
|
"@types/react": "^19",
|
||||||
|
"@types/react-dom": "^19",
|
||||||
|
"eslint": "^9",
|
||||||
|
"eslint-config-next": "^16.0.0",
|
||||||
|
"tailwindcss": "^4.0.0",
|
||||||
|
"typescript": "^5"
|
||||||
|
}
|
||||||
|
}
|
||||||
4090
pnpm-lock.yaml
generated
Normal file
4090
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
5
postcss.config.mjs
Normal file
5
postcss.config.mjs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export default {
|
||||||
|
plugins: {
|
||||||
|
'@tailwindcss/postcss': {},
|
||||||
|
},
|
||||||
|
};
|
||||||
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user