Available Block Types
Relevant source files
The following files were used as context for generating this wiki page:Blocks are the fundamental, draggable, and resizable components used to build a character sheet. Each block has a specific type that determines its appearance, behavior, and the data it holds. The entire character sheet is composed of a collection of these blocks arranged on a grid.
The state of all blocks is managed centrally by a Zustand store, defined in useSheetStore.ts. The BlockRenderer.tsx component is responsible for interpreting a block's type and data to render the appropriate React component. The visual styling of each block is highly dependent on the currently selected theme, which provides specific CSS classes for different block elements.
The Block Data Structure
Every component on the canvas is an instance of the Block interface. This interface defines the block's position and size on the grid, its functional type, its content, and its specific configuration.
Sources: src/store/useSheetStore.ts:20-36
Block Interface Diagram
The following diagram illustrates the structure of the Block object.
Sources: src/store/useSheetStore.ts:20-36
Block Properties
| Property | Type | Description |
|---|---|---|
i | string | A unique identifier for the block, required by React Grid Layout (RGL). |
x | number | The block's horizontal position on the grid (in grid units). |
y | number | The block's vertical position on the grid (in grid units). |
w | number | The block's width on the grid (in grid units). |
h | number | The block's height on the grid (in grid units). |
type | "text" | "image" | "header" | "form-box" | "shape" | "divider" | "list" | "container" | The functional type of the block, which determines how it is rendered. |
data | any | An object containing the block's content, such as text, image URLs, or list items. The structure varies by block type. |
config | object | An object for configuring the block's appearance and behavior, such as header level or shape type. |
Sources: src/store/useSheetStore.ts:20-36
Block Creation Flow
Blocks are added to the sheet via the ToolsSidebar. Clicking a tool button calls the addBlock function from the useSheetStore, which creates a new block object with a unique ID and default properties. This updated state triggers a re-render of the Canvas, which in turn uses BlockRenderer to display the new block.
Block Types
The application supports several distinct block types, each serving a different purpose in the character sheet layout.
header
A block for displaying titles and subtitles. It supports two levels, which correspond to different styling rules defined in the theme.
config.level:1 | 2. Level 1 is for main titles (h1), and level 2 is for subtitles (h2).data.text:string. The text content of the header.- Added via: "Big Title" and "Subtitle" buttons in
ToolsSidebar.
The rendering logic in BlockRenderer selects the appropriate theme class (h1 or h2) based on the config.level.
Sources: src/components/sheet/BlockRenderer.tsx:28-46, src/store/useSheetStore.ts:29-31, src/components/layout/ToolsSidebar.tsx:115-117
form-box
A composite block that includes an editable label and a multi-line text input area. It's designed for character stats, attributes, or any field requiring a label and a value.
data.label:string. The text for the upper label.data.value:string. The content of thetextarea.- Added via: "Input" button in
ToolsSidebar.
The theme provides separate styles for the label and input parts of this block.
Sources: src/components/sheet/BlockRenderer.tsx:49-76, src/lib/themes.ts:20-21, src/components/layout/ToolsSidebar.tsx:123-124
text
A simple, free-form text area for notes, descriptions, or backstories.
data.text:string. The content of thetextarea.- Added via: "Paragraph" button in
ToolsSidebar.
Sources: src/components/sheet/BlockRenderer.tsx:231-246, src/components/layout/ToolsSidebar.tsx:118-119
list
A block that renders a bulleted list of items. Users can edit existing items and add new ones.
data.items:string[]. An array of strings, where each string is a list item.- Added via: "List" button in
ToolsSidebar.
The component provides an "Add item" button to append new empty strings to the data.items array, which are then rendered as new input fields.
Sources: src/components/sheet/BlockRenderer.tsx:147-184, src/components/layout/ToolsSidebar.tsx:119-120
image
A block for displaying an image. It initially shows an upload prompt. Once an image is selected, it's read as a Data URL and stored in the block's state.
data.src:string. The Base64-encoded Data URL of the uploaded image.- Added via: "Image" button in
ToolsSidebar.
The handleImageUpload function uses FileReader to convert the selected image file into a Data URL, which is then saved using updateBlockData.
Sources: src/components/sheet/BlockRenderer.tsx:187-228, src/components/layout/ToolsSidebar.tsx:122-123
divider
A simple horizontal line used for visually separating sections of the sheet.
config/data: This block does not useconfigordataproperties.- Added via: "Divisor" button in
ToolsSidebar.
Its appearance is controlled entirely by the currentTheme.blocks.divider class.
Sources: src/components/sheet/BlockRenderer.tsx:114-121, src/lib/themes.ts:23, src/components/layout/ToolsSidebar.tsx:124-125
shape
A decorative block that can render different geometric shapes.
config.shapeType:"square" | "circle" | "rounded" | "heart". Determines the rendered shape.data: This block does not use thedataproperty.- Added via: "Square" and "Circle" buttons in
ToolsSidebar.
The rendering logic applies CSS classes like rounded-full or rounded-xl based on shapeType. The "heart" shape is a special case that renders a '♥' text character.
Sources: src/components/sheet/BlockRenderer.tsx:79-111, src/store/useSheetStore.ts:32, src/components/layout/ToolsSidebar.tsx:132-141
container
A visual grouping block that acts as a background for other blocks. It is intended to be placed on a lower layer to visually group related elements.
config.zIndex:"back". When added from theToolsSidebar, it's configured to be in the back.data: This block does not use thedataproperty.- Added via: "Group Container" button in
ToolsSidebar.
In Canvas.tsx, any block with type: "container" or config.zIndex: "back" is assigned a !z-0 CSS class to ensure it renders behind other blocks.
Sources: src/components/sheet/BlockRenderer.tsx:124-139, src/components/layout/ToolsSidebar.tsx:129-132, src/components/sheet/Canvas.tsx:66-67
Summary of Block Types
| Type | UI Button | Configurable Properties | Data Properties | Purpose |
|---|---|---|---|---|
header | "Big Title", "Subtitle" | level: 1 | 2 | text: string | Section titles |
form-box | "Input" | - | label: string, value: string | Labeled input fields |
text | "Paragraph" | - | text: string | Free-form text notes |
list | "List" | - | items: string[] | Bulleted lists |
image | "Image" | - | src: string | Character portraits or icons |
divider | "Divisor" | - | - | Visual separator |
shape | "Square", "Circle" | shapeType: "square" | "circle" | ... | - | Decorative elements |
container | "Group Container" | zIndex: "back" | - | Background for grouping blocks |
Sources: src/components/layout/ToolsSidebar.tsx:114-142, src/store/useSheetStore.ts:25-36, src/components/sheet/BlockRenderer.tsx