Contribution Guidelines
Relevant source files
The following files were used as context for generating this wiki page:This document provides a comprehensive guide for developers wishing to contribute to the Character Sheet Maker project. It outlines the project's architecture, coding standards, and key systems. The project is a "Local-First" web application built with React, TypeScript, and Vite, designed for creating system-agnostic RPG character sheets. Adhering to these guidelines ensures code consistency, maintainability, and a smooth development process.
The application's core is a drag-and-drop canvas where users can add and arrange various content blocks. The state is managed globally using Zustand, and styling is handled through a flexible theming system powered by Tailwind CSS.
1. Project Setup
To begin development, you must set up the project environment on your local machine. The project uses Node.js and relies on npm for package management.
1.1. Dependencies
The project is built on a modern frontend stack. Key dependencies include:
- Framework: React 19
- Language: TypeScript 5.9
- Build Tool: Vite (using the
rolldown-viteoverride) - Styling: Tailwind CSS 4
- State Management: Zustand
- Grid Layout:
react-grid-layout - UI Components: Radix UI primitives, managed via Shadcn UI
- Icons:
lucide-react
A full list of dependencies and dev-dependencies can be found in package.json.
Sources: package.json:10-30, package.json:32-46
1.2. Installation & Scripts
Follow these steps to run the project locally:
- Clone the repository.
- Install dependencies:
npm install - Run the development server:
npm run dev
The following diagram illustrates the local development workflow.
This diagram shows the standard workflow for setting up the project and starting development.
The available npm scripts are defined in package.json.
| Script | Description |
|---|---|
dev | Starts the Vite development server with hot-reloading. |
build | Compiles TypeScript and builds the project for production. |
lint | Runs ESLint to analyze the code for potential errors. |
preview | Serves the production build locally for previewing. |
Sources: package.json:5-9
2. Coding Standards & Tooling
To maintain code quality and consistency, the project enforces strict linting and TypeScript rules.
2.1. Linting with ESLint
The project uses ESLint, configured in eslint.config.js. The configuration extends recommended rules from:
@eslint/js(JavaScript standard rules)typescript-eslint(TypeScript-specific rules)eslint-plugin-react-hooks(Rules for React Hooks)eslint-plugin-react-refresh(For Vite's Fast Refresh)
All new TypeScript/TSX files (**/*.{ts,tsx}) are subject to these rules. The dist directory is ignored.
Sources: eslint.config.js
2.2. TypeScript Configuration
The TypeScript configuration in tsconfig.app.json is set for strictness to catch errors early. Key compiler options include:
"target": "ES2022""strict": true"noUnusedLocals": true"noUnusedParameters": true"moduleResolution": "bundler""jsx": "react-jsx"
These settings ensure type safety and prevent common mistakes like unused variables.
Sources: tsconfig.app.json:2-22
3. Project Structure
The project follows a standard structure for React applications. Path aliases are configured in vite.config.ts and tsconfig.app.json to simplify imports, with @/* resolving to the src/ directory.
This diagram outlines the main directories and key files within the project structure.
Sources: vite.config.ts:8-12, tsconfig.app.json:23-26, components.json:12-18
4. Core Systems
4.1. State Management with Zustand
Global application state is managed by a Zustand store defined in src/store/useSheetStore.ts. This store is the single source of truth for the character sheet's content (blocks), layout, and global styles. The state is persisted to localStorage under the key rpg-sheet-storage.
The following diagram illustrates the structure of the useSheetStore state.
This diagram shows the main entities within the Zustand store and their relationships.
Sources: src/store/useSheetStore.ts
Block Interface
The Block is the fundamental data structure for any element on the canvas.
| Property | Type | Description |
|---|---|---|
i | string | Unique identifier, required by react-grid-layout. |
x, y | number | Grid coordinates of the block. |
w, h | number | Width and height of the block in grid units. |
type | "text" | "image" | "header" | "form-box" | "shape" | "divider" | "list" | "container" | Determines how the block is rendered. |
data | any | The content of the block (e.g., text, image URL). |
config | object | Configuration specific to the block type (e.g., header level, shape type). |
Sources: src/store/useSheetStore.ts:20-33
Store Actions
The store exposes several actions to manipulate the state:
| Action | Description |
|---|---|
addBlock | Adds a new block of a specified type to the canvas. |
removeBlock | Removes a block by its ID. |
updateBlockData | Updates the data property of a specific block. |
updateLayout | Synchronizes the block layout (x, y, w, h) with react-grid-layout. |
setTheme | Changes the active global theme. |
toggleCompact | Toggles the grid compaction ("gravity") mode. |
Sources: src/store/useSheetStore.ts:36-45
4.2. Theming System
The application features a dynamic theming system defined in src/lib/themes.ts. This allows the entire look and feel of the character sheet to be changed instantly.
A theme is defined by the ThemeConfig interface, which includes fonts, colors, and specific Tailwind CSS classes for each block type.
This diagram shows how the BlockRenderer uses the current theme from useSheetStore to retrieve styling information from the THEMES configuration.
Sources: src/lib/themes.ts, src/store/useSheetStore.ts:10-18, src/components/sheet/BlockRenderer.tsx:8-9
Theme Configuration
Each theme is an object with the following structure:
| Key | Description |
|---|---|
name | The display name of the theme (e.g., "Modern Clean"). |
fonts | An object specifying font-family for heading and body text. |
colors | An object specifying Tailwind classes for text, accent, and faint colors. |
blocks | An object containing specific Tailwind classes for each block type (header, formBox, etc.). |
The project currently defines three themes:
| Theme Key | Name |
|---|---|
simple | Modern Clean |
medieval | Ancient Scroll |
cyberpunk | Neon Future |
Sources: src/lib/themes.ts:4-31, src/lib/themes.ts:33-116
4.3. UI Components and Styling
The project uses Shadcn UI for its component library, which is configured in components.json. This means that UI components are not imported from a package but are part of the source code in src/components/ui. They are built with Radix UI primitives and styled with Tailwind CSS.
The cn utility function, a combination of clsx and tailwind-merge from src/lib/utils.ts, is used extensively to conditionally and safely merge Tailwind CSS classes.
Sources: components.json, src/lib/utils.ts, src/components/ui/input.tsx:5
5. Conclusion
Contributing to the Character Sheet Maker involves understanding its core systems: the Zustand state store, the flexible theming engine, and the component-based architecture. By following the established coding standards and project structure, developers can effectively extend the application's functionality. Before submitting a pull request, ensure your code is properly formatted and passes the ESLint checks by running npm run lint.