Skip to content

Commit ec1fc79

Browse files
rob-gordonclaude
andcommitted
docs: Add Examples, Themes & Layouts section to CLAUDE.md
Document the templates system, FFTheme schema, available layouts, Cytoscape CSS pipeline, utility classes, screenshot generation, and how templates integrate with the AI pipeline and chart creation UI. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 21e2cb8 commit ec1fc79

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed

CLAUDE.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,161 @@ Pro access is determined by Stripe subscription status (`active` or `trialing`)
180180

181181
The sandbox warning modal (`SandboxWarning.tsx`) appears after 3 minutes of editing to encourage upgrade.
182182

183+
## Examples, Themes & Layouts
184+
185+
### Templates Overview
186+
187+
13 templates defined in `shared/src/templates.ts` (single source of truth, `as const` array). Each template is a file at `app/src/lib/templates/{name}-template.ts` exporting three things:
188+
189+
- `content: string` — starter DSL text for the editor
190+
- `theme: FFTheme` — layout + visual config object (26 properties)
191+
- `cytoscapeStyle: string` — Cytoscape CSS with variables, color/shape class definitions, and advanced selectors
192+
193+
Template names: code-flow, default, process-flow, flowchart, org-chart, network-diagram-dark, decision-flow, pert-light, knowledge-graph, network-diagram-icons, mindmap, playful-mindmap, mindmap-dark.
194+
195+
### FFTheme Schema
196+
197+
- Type definition at `app/src/lib/FFTheme.ts`
198+
- **If you change FFTheme, run `pnpm -F app theme:schema:generate`** to regenerate `FFTheme.schema.json`
199+
- 26 properties in 4 groups:
200+
- **Global:** fontFamily, background, lineHeight
201+
- **Layout:** layoutName (10 options), direction (RIGHT/LEFT/DOWN/UP), spacingFactor
202+
- **Node:** shape, textMaxWidth, padding, borderWidth, borderColor, nodeBackground, nodeForeground, textMarginY, curveStyle, useFixedHeight, fixedHeight
203+
- **Edge:** edgeWidth, edgeColor, sourceArrowShape, targetArrowShape, sourceDistanceFromNode, targetDistanceFromNode, arrowScale, edgeTextSize, rotateEdgeLabel
204+
- Edited via ThemeTab UI (`app/src/components/Tabs/ThemeTab.tsx`) using the formulaic library
205+
- Stored in document metadata as `meta.themeEditor`
206+
- Conversion: `toTheme(themeEditor)` in `app/src/lib/toTheme.ts` → returns `{ layout, style, postStyle }`
207+
208+
### Available Layouts
209+
210+
10 layout algorithms (from `LayoutName` type in `FFTheme.ts`):
211+
212+
| Layout | Engine | Best For |
213+
|--------|--------|----------|
214+
| dagre | dagre | Hierarchical flowcharts |
215+
| klay | klayjs | Hierarchical (alternative) |
216+
| layered | ELK | Hierarchical with balanced alignment |
217+
| mrtree | ELK | Tree structures |
218+
| stress | ELK | Force-directed, interactive |
219+
| radial | ELK | Radial/spoke layouts |
220+
| cose | fcose | Force-directed with animation |
221+
| breadthfirst | cytoscape | Breadth-first tree |
222+
| concentric | cytoscape | Concentric circles |
223+
| circle | cytoscape | Simple circle |
224+
225+
Direction property maps to layout-specific direction configs (dagre: rankDir TB/LR/RL/BT; klay: klay.direction; ELK: elk.direction). Reference: https://js.cytoscape.org/ for Cytoscape layout/CSS docs.
226+
227+
### Cytoscape CSS (Not Browser CSS)
228+
229+
All CSS in `cytoscapeStyle` is **Cytoscape CSS** — different property names, selectors, and values from browser CSS. Reference: https://js.cytoscape.org/#style
230+
231+
Key features:
232+
- **Variables:** `$varname: value;` — preprocessed by `app/src/lib/preprocessStyle.ts`, substituted throughout
233+
- **Font imports:** `@import url(...)` — extracted and loaded via FontFace API
234+
- **Dynamic class detection:** classes matching `type_name` pattern (e.g., `color_blue`, `shape_diamond`) auto-detected and made available in the right-click context menu on nodes/edges (`GraphContextMenu.tsx`)
235+
- **Selectors:** `:childless` (leaf nodes), `:parent` (group nodes), `edge`, `[in_degree < 1]` (data attributes)
236+
- **Three-stage pipeline:** themeStyle (generated from FFTheme) → customCss (user's cytoscapeStyle) → postStyle (utility classes). All concatenated unless `customCssOnly: true` in metadata.
237+
238+
Example from flowchart-template.ts cytoscapeStyle:
239+
```css
240+
$blue: #e3f2fd;
241+
:childless.color_blue {
242+
background-color: $blue;
243+
color: $color;
244+
}
245+
:childless[in_degree > 0][out_degree > 1] {
246+
shape: diamond;
247+
height: $width;
248+
}
249+
```
250+
251+
### Built-in Utility Classes
252+
253+
From `app/src/lib/graphUtilityClasses.ts` (generated as postStyle, always available):
254+
255+
- **Shape classes** (`.shape_*`): All Cytoscape shapes (rectangle, roundrectangle, ellipse, triangle, diamond, star, hexagon, etc.) + "smart shapes" (circle, square, roundsquare) that enforce 1:1 aspect ratio
256+
- **Border classes** (`.border_*`): none, solid, dashed, dotted, double — works on both nodes and edges
257+
- **Color classes** (`.color_*`): **Defined per-template** in cytoscapeStyle, NOT global. Common set across most templates: red, orange, yellow, green, blue, pink, grey, white, black. Each template defines its own color values.
258+
- **Text size classes** (from `getSize.ts`): text-sm (0.75x), text-base (1x), text-lg (1.5x), text-xl (2x)
259+
260+
Applied in the DSL with dot notation: `Node Name .color_blue .shape_diamond`
261+
262+
### How to Add a New Template
263+
264+
1. Create `app/src/lib/templates/{name}-template.ts` exporting `content`, `theme` (FFTheme), and `cytoscapeStyle`
265+
2. Add the template name string to the array in `shared/src/templates.ts`
266+
3. Rebuild shared: `pnpm -F shared build`
267+
4. Generate screenshots (requires dev server running on port 3000 + ImageMagick installed):
268+
```bash
269+
# Terminal 1:
270+
pnpm start
271+
# Terminal 2:
272+
pnpm -F app screenshot-templates {name}
273+
```
274+
5. Verify: `app/public/template-screenshots/thumb_{name}.png` (275x275) and `{name}.png` (full) exist
275+
6. The template will automatically appear in LoadTemplateDialog, New chart page, and AI template chooser
276+
277+
### How to Edit an Existing Template
278+
279+
1. Modify the template file in `app/src/lib/templates/`
280+
2. If visual changes were made, regenerate its screenshot: `pnpm -F app screenshot-templates {name}`
281+
3. If FFTheme type was changed: `pnpm -F app theme:schema:generate`
282+
283+
### How to Remove a Template
284+
285+
1. Delete the template file from `app/src/lib/templates/`
286+
2. Remove the name from `shared/src/templates.ts`
287+
3. Rebuild shared: `pnpm -F shared build`
288+
4. Delete the screenshot files from `app/public/template-screenshots/` ({name}.png and thumb_{name}.png)
289+
290+
### Screenshot System
291+
292+
- **Script:** `app/scripts/screenshot-templates.mjs`
293+
- **Command:** `pnpm -F app screenshot-templates [optional-filter]`
294+
- **Prerequisites:** Dev server on port 3000 (`pnpm start`), ImageMagick installed (`convert` command)
295+
- **Process:**
296+
1. Playwright launches Chromium (1000x1000 viewport)
297+
2. Navigates to localhost:3000
298+
3. Calls `window.__load_template__(name, true)` to load each template
299+
4. Waits 3s for render, gets fullscreen link via `window.__get_screenshot_link__()`
300+
5. Navigates to fullscreen URL, screenshots the `[data-flowchart-fun-canvas="true"]` element
301+
6. ImageMagick resizes to 275x275 centered thumbnails
302+
- **Output:** `app/public/template-screenshots/{name}.png` + `thumb_{name}.png`
303+
- **Filter:** Pass a string to only screenshot matching templates (e.g., `pnpm -F app screenshot-templates mindmap` screenshots all mindmap variants)
304+
- **Window globals** set up by `app/src/lib/loadTemplate.ts` (`useEnsureLoadTemplate` hook) and `app/src/lib/useEnsureGetScreenshotLink.ts`
305+
306+
### Templates in the AI Pipeline
307+
308+
- When user runs AI "prompt" or "convert", `runAi()` (`app/src/lib/runAi.ts`) first calls `/api/prompt/choose-template` to auto-select the best template for the user's prompt
309+
- The choose-template endpoint uses a short system prompt to pick from the 13 template names (avoids "default"); the specific model is documented in the AI Integration table
310+
- Selected template's `theme` and `cytoscapeStyle` are applied to the document **before** the AI streams generated text — so the graph looks right as text arrives
311+
- Edit mode does NOT use template selection (it edits existing text in-place, preserving the current theme)
312+
313+
### Templates in Chart Creation UI
314+
315+
- **LoadTemplateDialog** (`app/src/components/LoadTemplateDialog.tsx`): "Examples" button in toolbar; shows grid of 13 thumbnails; user can independently toggle "Load layout and styles" and "Load default content" checkboxes
316+
- **New hosted chart** (`app/src/pages/New.tsx`): template selector during creation; template content+theme baked into the chart at insert time
317+
- **loadTemplate()** (`app/src/lib/loadTemplate.ts`): dynamically imports template module, merges theme into doc metadata, unfreezes nodePositions, unmounts/remounts graph for clean re-layout
318+
319+
### Key File Reference
320+
321+
| Component | File |
322+
|-----------|------|
323+
| Template names (source of truth) | `shared/src/templates.ts` |
324+
| Template data files | `app/src/lib/templates/{name}-template.ts` |
325+
| FFTheme type definition | `app/src/lib/FFTheme.ts` |
326+
| Theme → Cytoscape conversion | `app/src/lib/toTheme.ts` |
327+
| CSS preprocessing (variables, fonts, dynamic classes) | `app/src/lib/preprocessStyle.ts` |
328+
| Utility classes (shapes, borders) | `app/src/lib/graphUtilityClasses.ts` |
329+
| Node sizing + text size classes | `app/src/lib/getSize.ts` |
330+
| Template loading function | `app/src/lib/loadTemplate.ts` |
331+
| Screenshot script | `app/scripts/screenshot-templates.mjs` |
332+
| Screenshot assets | `app/public/template-screenshots/` |
333+
| ThemeTab UI | `app/src/components/Tabs/ThemeTab.tsx` |
334+
| LoadTemplateDialog UI | `app/src/components/LoadTemplateDialog.tsx` |
335+
| AI template chooser endpoint | `api/prompt/choose-template.ts` |
336+
| AI runner (template integration) | `app/src/lib/runAi.ts` |
337+
183338
## Tech Stack Details
184339

185340
### Frontend (app/)

0 commit comments

Comments
 (0)