Layout: ToolsSidebar
Relevant source files
The following files were used as context for generating this wiki page:
The ToolsSidebar is a fundamental UI component within the application's Editor page. Its primary function is to serve as a control panel, providing users with a set of tools to add various content blocks (e.g., text, images, shapes) to the character sheet canvas. It also offers global styling controls, including theme selection and a "physics" toggle for the grid layout.
The sidebar is designed to be responsive, featuring a collapsible state that minimizes its width to save screen space while retaining core functionality through icons and tooltips. It is tightly integrated with the global state management (zustand) to dispatch actions that modify the sheet's content and appearance.
Sources: src/components/layout/ToolsSidebar.tsx, src/pages/Editor.tsx:16-18
Core Architecture & State Management
The ToolsSidebar is a React functional component that is rendered within the main Editor page. Its visibility and collapsed/expanded state are controlled by the parent Editor component via the isOpen and toggle props.
For all its actions, the sidebar interacts with a global zustand store, useSheetStore. It does not manage any significant internal state, instead relying on the store for both retrieving current sheet state (like the active theme or compact mode) and dispatching actions to modify it (like adding a block or changing a theme).
Sources: src/pages/Editor.tsx:8, 18, src/components/layout/ToolsSidebar.tsx:25
This diagram illustrates the component's relationship with its parent and the global state store.
State and Actions from useSheetStore
The component hooks into useSheetStore to access the following:
| Name | Type | Description |
|---|---|---|
addBlock | function | Adds a new block of a specified type to the sheet. |
toggleCompact | function | Toggles the "physics" (compact layout) of the grid. |
setTheme | function | Sets the global theme for the entire sheet. |
isCompact | boolean | The current state of the grid's compact layout. |
globalStyle | object | Contains the current theme key. |
Sources: src/components/layout/ToolsSidebar.tsx:25, src/store/useSheetStore.ts:63-108
UI Structure and Responsiveness
The ToolsSidebar has a responsive design that adapts its width and content based on the isOpen prop.
- Expanded: The width is
w-64. Tool buttons show both an icon and a text label. Section titles are visible. - Collapsed: The width is
w-14. Tool buttons show only an icon, with the label available as a nativetitletooltip. Section titles are hidden.
A floating button positioned on the edge of the sidebar is used to trigger the toggle function, switching between these two states.
Sources: src/components/layout/ToolsSidebar.tsx:32-51, 80-83, 91-94
Helper Components
To maintain a consistent look and feel, ToolsSidebar uses internal helper components:
ToolBtn: A wrapper around theButtoncomponent that standardizes the appearance and behavior of all block-creation buttons. It dynamically adjusts its justification and hides the text label when the sidebar is collapsed.SectionTitle: A simple<h3>element for grouping tools. It uses CSS transitions to hide itself when the sidebar is collapsed.
Sources: src/components/layout/ToolsSidebar.tsx:28-51, 65-73
Tool Groups
The tools are organized into logical groups, each with a specific purpose.
Sheet Style
This section allows the user to apply a global theme to the character sheet.
- It dynamically renders a button for each theme defined in the
THEMESobject fromsrc/lib/themes.ts. - When a theme button is clicked, it calls the
setTheme(themeKey)action fromuseSheetStore. - The button for the currently active theme receives a different styling (
variant="default"). - When the sidebar is collapsed, the buttons display only the first letter of the theme's name.
Sources: src/components/layout/ToolsSidebar.tsx:100-125, src/lib/themes.ts:25-115
The available themes are:
| Theme Key | Name |
|---|---|
simple | Modern Clean |
medieval | Ancient Scroll |
cyberpunk | Neon Future |
Sources: src/lib/themes.ts:28, 60, 87
The following diagram shows the sequence of changing a theme.
Content Creation Tools
These sections provide buttons to add various types of content blocks to the canvas. Each ToolBtn calls the addBlock action from useSheetStore with a specific type and, in some cases, a config object.
The following diagram shows the flow for adding a new block.
The available tools are summarized below:
| Group | Icon | Label | addBlock call |
|---|---|---|---|
| Text | Heading1 | Big Title | addBlock("header", { level: 1 }) |
Heading2 | Subtitle | addBlock("header", { level: 2 }) | |
Type | Paragraph | addBlock("text") | |
List | List | addBlock("list") | |
| Content | ImageIcon | Image | addBlock("image") |
LayoutTemplate | Input | addBlock("form-box") | |
Minus | Divisor | addBlock("divider") | |
| Shapes & Groups | Layers | Group Container | addBlock("container", { zIndex: "back" }) |
Square | Square | addBlock("shape", { shapeType: "square" }) | |
Circle | Circle | addBlock("shape", { shapeType: "circle" }) |
Sources: src/components/layout/ToolsSidebar.tsx:128-167
Physics (Footer)
The footer of the sidebar contains a control for the grid layout's "physics". This corresponds to the compactType property of the react-grid-layout component used in the Canvas.
- A single button toggles the
isCompactboolean inuseSheetStoreby callingtoggleCompact(). - The button's text and icon change to reflect the current state ("Gravity On" vs. "Free Mode").
- A status indicator (
ON/OFF) is also displayed when the sidebar is expanded. - In
Canvas.tsx, theisCompactstate determines whethercompactTypeis set to"vertical"ornull, and ifpreventCollisionisfalseortrue.
Sources: src/components/layout/ToolsSidebar.tsx:170-202, src/store/useSheetStore.ts:88, src/components/sheet/Canvas.tsx:40, 44
Conclusion
The ToolsSidebar component is the primary user interface for building and styling a character sheet. Through its clear organization, responsive design, and tight integration with the useSheetStore global state, it provides a powerful and intuitive set of tools. It effectively decouples the action triggers (the tool buttons) from the state logic and the final rendering on the Canvas, creating a clean and maintainable architecture for the editor.