Thank you for your interest in contributing! This project welcomes contributions from everyone.
This project was vibe-coded using Lovable and has been checked for security issues using Lovable's built-in security scanning tools. However, the repository owner has not manually reviewed all code. Please keep this in mind when contributing and reviewing.
- Check if the issue already exists in the Issues tab
- If not, create a new issue with:
- A clear, descriptive title
- Steps to reproduce the bug
- Expected vs actual behavior
- Browser and OS information
- Open a new issue with the
enhancementlabel - Describe the feature and its use case
- Explain how it fits with the Johnny Decimal methodology
- Fork the repository
- Clone your fork locally
- Create a branch for your changes:
git checkout -b feature/your-feature-name
- Make your changes following the code style guidelines below
- Test your changes locally:
npm install npm run dev
- Commit with a clear message:
git commit -m "Add: brief description of changes" - Push to your fork and open a Pull Request
- TypeScript: Use strict typing, avoid
any - React: Functional components with hooks
- Styling: Use Tailwind CSS with semantic tokens from the design system
- Formatting: The project uses standard Prettier/ESLint configuration
- Components: Keep components small and focused; create new files for new components
src/
├── components/ # React components
│ └── ui/ # Reusable UI components (shadcn/ui)
├── hooks/ # Custom React hooks
│ └── useKeyboardHandlers.ts # Unified keyboard handling
├── lib/ # Utility functions and validation
├── pages/ # Page components
└── types/ # TypeScript type definitions
All keyboard shortcuts are centralized in src/hooks/useKeyboardHandlers.ts to prevent regressions and ensure consistent behavior across components. This includes:
useInputKeyboard: For simple input fields (Enter to submit, Escape to cancel/blur)useDescriptionKeyboard: For description textareas (item parsing, hashtag extraction)useContainerNavigation: For container-level arrow key navigation
When adding new keyboard interactions, extend these hooks rather than adding inline handlers.
Items use the format prefix.categoryId.number (e.g., d1.22.03). The system prefix is extracted from the system name using the pattern ^([a-zA-Z]\d+) (e.g., "d1-Work" → "d1").
Users can add categories or items by typing Name [XX] in area or category descriptions. The regex /^(.+?)\s*\[(\d+)\]$/ matches this pattern.
Areas, categories, and items can be renamed inline by clicking the pencil icon. The rename state is managed locally in SystemTree.tsx and SearchResults.tsx using renamingId and renameValue state variables.
Categories and items can be deleted using the X button that appears on hover. The removeCategory function in useJohnnyDecimal.ts handles category deletion.
- All data is stored in
localStorage- no backend required - The app uses the Johnny Decimal methodology
- Import/export uses JSON format with Zod validation
- Search uses BM25 algorithm for relevance ranking
- Press
?to open the help dialog for keyboard shortcut reference
When modifying keyboard handling:
- Test
/focuses search from anywhere - Test
?opens help dialog - Test
1-9switch systems (only when not in an input) - Test
↑/↓navigate search results - Test
Enterexpands results and focuses description - Test
Escblurs fields and closes editors - Test
Name [XX]+ Enter adds categories in area descriptions - Test
Name [XX]+ Enter adds items in category descriptions - Test
#tag+ Space adds tags in descriptions - Test pencil icon triggers rename mode for areas, categories, and items
- Test X button deletes categories and items
Feel free to open an issue for any questions about contributing.
Thank you for helping improve Johnny Decimal Manager!