Layout: TopBar
Relevant source files
The following files were used as context for generating this wiki page:
The TopBar is a core React component that functions as the main header for the application's editor page. It provides essential global functionalities, including navigation, sheet titling, export options, and theme switching. Positioned at the top of the Editor page, it remains consistently visible, offering users access to high-level actions regardless of their position on the character sheet canvas.
This component is a key part of the main application layout, sitting alongside the ToolsSidebar and the main Canvas. It is composed of distinct sections for navigation/titling on the left and user actions on the right, using a flexbox layout for clean separation.
Sources: src/components/layout/TopBar.tsx, src/pages/Editor.tsx:10-13
Component Structure
The TopBar component is structured as an HTML <header> element. It has a fixed height of 14 units and a bottom border, ensuring a consistent look and feel. The layout is managed by flexbox (flex items-center justify-between) to organize its children into two main groups: a left-aligned section for navigation and title, and a right-aligned section for actions. It is assigned a z-index of 20 to ensure it renders above other page elements.
Sources: src/components/layout/TopBar.tsx:20
The diagram below illustrates the high-level structure of the TopBar component and its interactive elements.
Diagram showing the component hierarchy within TopBar.
Sources: src/components/layout/TopBar.tsx:21-74
Left Section: Navigation and Title
This section contains the primary navigation control and the sheet's title.
- Back Button: A
Linkcomponent fromreact-router-domthat navigates the user to the application's home page (/). It is styled as an icon-only ghost button containing anArrowLefticon. - Sheet Title: An
<Input>component that displays the sheet's title. It is pre-filled with "Character Sheet" and allows the user to edit the name directly in the top bar.
Sources: src/components/layout/TopBar.tsx:22-38, src/App.tsx:18
Right Section: Actions
This section groups together global actions available to the user.
Export Menu
An "Export" button triggers a dropdown menu with options to download the character sheet in different formats. This functionality is built using custom UI components based on Radix UI.
| Component | Library/Type | Purpose | Source File |
|---|---|---|---|
<DropdownMenu> | ui/dropdown-menu | The main container for the export options menu. | src/components/layout/TopBar.tsx:42 |
<DropdownMenuTrigger> | ui/dropdown-menu | The "Export" button that opens the menu. | src/components/layout/TopBar.tsx:43 |
<DropdownMenuContent> | ui/dropdown-menu | The panel that appears with the list of options. | src/components/layout/TopBar.tsx:56 |
<DropdownMenuItem> | ui/dropdown-menu | An individual, clickable option within the menu. | src/components/layout/TopBar.tsx:57,60 |
The menu provides the following options:
| Menu Item | Icon | Action |
|---|---|---|
Download PNG | FileImage | Calls downloadAsImage() to save the canvas as a PNG file. |
Download PDF | FileText | Calls downloadAsPDF() to save the canvas as a PDF file. |
Sources: src/components/layout/TopBar.tsx:42-63, src/components/ui/dropdown-menu.tsx |
The export functionality is handled by utility functions in src/lib/exportUtils.ts, which in turn rely on the html-to-image and jspdf libraries.
Sources: src/lib/exportUtils.ts, package.json:16-17
The sequence diagram below shows the process for exporting the sheet as a PNG image.
Sequence diagram for the PNG export flow.
Sources: src/components/layout/TopBar.tsx:57, src/lib/exportUtils.ts:4-18
The PDF export follows a similar process but adds a step to embed the generated image into a PDF document using jspdf.
Sequence diagram for the PDF export flow.
Sources: src/components/layout/TopBar.tsx:60, src/lib/exportUtils.ts:20-36
Theme Toggle
A circular ghost button allows the user to switch between light and dark color themes for the entire application.
The button's logic is driven by the useTheme hook, which provides the current theme state (theme) and a function to update it (toggleTheme). The implementation of the useTheme hook itself is not present in the provided source files, but its interface is consumed by the TopBar component.
Based on the current theme, the button conditionally renders one of two icons from the lucide-react library:
- Dark Mode: A
Sunicon is displayed. - Light Mode: A
Moonicon is displayed.
Sources: src/components/layout/TopBar.tsx:18, src/components/layout/TopBar.tsx:67-73
// src/components/layout/TopBar.tsx:67-73
<Button onClick={toggleTheme} variant="ghost" size="icon" className="rounded-full">
{theme === "dark" ? (
<Sun size={18} className="text-yellow-400" />
) : (
<Moon size={18} className="text-gray-600" />
)}
</Button>
Code snippet showing the conditional rendering for the theme toggle icon.
Summary
The TopBar component serves as a centralized and persistent header for the character sheet editor. It integrates navigation, titling, and critical user actions like exporting and theme switching into a single, cohesive UI element. Its clear structure and reliance on dedicated hooks and utility modules make it a robust and essential part of the user experience.
Sources: src/components/layout/TopBar.tsx, src/pages/Editor.tsx