GlyphfieldDocs
Documentation/System reference

Shared editor components

Reuse the shared shell, color, canvas, layer, source, select and storage components when you build or change a Studio tool in the Glyphfield codebase.

Maintained with source

Studio tools in the Glyphfield codebase are built from shared components and hooks for the tool shell, color fields, zoom, layer editing, select menus, source editing and draft storage. A contributor who builds a tool from them gets the same interaction, accessibility, automation and export behavior as the other tools.

Design Lab showing shared library, canvas viewport, inspector, and layer dock systems
Layered editor componentsSelection · zoom · source · persistence
Brand Elements showing identity-aware artifact controls
Identity-aware controlsShared assets · color · output

Component map

Component or moduleResponsibilityUsed by
ToolShell (src/components/tools/ToolShell.tsx)Tool header, left and right sidebars, the File menu, the lazily loaded source drawer and Browser API registrationColor tokens, Typography, Component library and the five expression tools
StudioToolHeaderHeader with the tool icon, title, description, a status slot and an actions slotToolShell and the tools that build their own shell
StudioFileMenuThe File menu: optional Open project file and Download project file, tool-specific sections, and Edit source code under AdvancedEvery tool with a source document
StudioActionMenu (src/components/ui/)A named toolbar button that opens the shared StudioContextMenu in a portal. Arrow keys also open itFile, More exports and the Studio header
LabInspectorSection (src/components/LabWorkspace.tsx)Collapsible inspector section with an icon. Collapsed content stays mountedDesign Lab, Animation, Lottie, Moodboard, Brand elements and Brand book, and every ControlSection from src/components/tools/ToolFields.tsx
ColorControl (src/components/ui/ColorControl.tsx)Swatch, picker, HEX, OKLCH, optional opacity and the screen eyedropper. The parent owns the valueBrand identity, Color tokens, Component library, Design Lab, Brand elements, Lottie, the expression tools and Visual settings
CanvasViewportZoom, fit, view reset, pan, and optional Undo, Redo and Action history. Zoom is saved per project and toolDesign Lab, Animation, Lottie, Moodboard, Brand elements and the expression tools
EditableCanvasLayerSelection, move, resize, keyboard nudge, snapping guides and an optional rotate handle. The parent owns the transformDesign Lab, Animation and the expression tools
SourceCodeDrawer and LazySourceCodeDrawerThe JSON source drawer. Tools mount LazySourceCodeDrawer, which loads the editor and its syntax grammar the first time a drawer opensEvery tool with a source document
src/lib/sourceCode.tsJSON parsing and diagnostics, rich-text space cleanup, formatting, and readers for constrained strings, numbers, Booleans, arrays and objectsSource validators in every tool
src/lib/canvasDocument.tsCanvasDocument schema 2: pages, elements, assets, parsing, serialization, mutations, history helpers and preflightDesign Lab, Animation, Lottie and the expression tools
StudioSelect (src/components/ui/)Select trigger and popover built on Radix Select, with keyboard navigationFonts, assets, materials, layouts, formats, languages and presets
MaterialFinishControlsFinish preset, Shadow, Border, Reflection and Liquid glassAnimation frames and backgrounds
LogoAppearanceControlsInvert, dither, outline and shadow for logos, images and stickersDesign Lab, Brand elements and the expression tools
useStudioDraft (src/hooks/usePersistentState.ts)Field state saved in localStorage under one key per project, tool and fieldTool fields, zoom, layers, surfaces, layouts and export settings
usePortableCanvasWorkspace (src/hooks/)Embeds assets, serializes the CanvasDocument, restores and writes autosave, and registers the project snapshot used when a project is duplicatedDesign Lab, Animation, Lottie and the expression tools
src/lib/studioAutomation.tsThe Browser API registry (window.glyphfield.studio): accessible controls, source round trips, tool actions and Blob downloadsEvery Studio tool

Color control

ColorControl is one component with optional features. By default it is compact: a row with the swatch, the label, the HEX value and the opacity opens a picker popover. compact={false} shows the swatch, HEX and OKLCH fields inline for dedicated color-editing surfaces.

StateBehavior
RestingThe swatch, label, normalized HEX and optional opacity
OpenSaturation and brightness area, hue slider, Pick screen color, H, S and V readouts, HEX, OKLCH and optional opacity
HEX editingCommits on blur or Enter. Escape cancels. Invalid input leaves the color unchanged
OKLCH editingParses OKLCH input and converts it to the stored HEX value
With opacityAdds a 0–100% range. Color and opacity change independently
DraggingPicker and preview updates are grouped into animation frames. Releasing the pointer commits the final value
Eyedropper activePick screen color samples any visible pixel on the screen, including outside the browser. A sample commits one HEX edit and leaves opacity unchanged. Escape cancels

The conversion functions (normalizeHex, formatOklch, parseOklch, oklchToHex, hexToHsv and hsvToHex) live in src/lib/color.ts.

The eyedropper (src/components/ui/ScreenColorPicker.tsx) uses the browser's EyeDropper API, which needs a supporting browser on HTTPS or localhost. Without it, the button is disabled with an explanation, and the other color controls keep working. Closing the picker or unmounting it cancels an unfinished sample. Browser API control discovery lists the button as <color label> pick screen color. Screen sampling needs a real user gesture and a native screen selection, so agents set colors through the HEX or OKLCH fields and re-read the source to confirm the change.

Canvas viewport

CanvasViewport wraps the artifact without changing its aspect ratio. The stage scales on screen, and exports keep the artifact's declared pixel size.

  • Zoom runs from 40% to 200% by default. Hosts can change the range: Design Lab uses 5% to 800%.
  • The percentage button restores 100%. Reset view restores 100% and the starting pan. Fit canvas (F) fits the content at no more than 100%. Zoom in (+) and Zoom out (−) step by 10%.
  • The mouse wheel or trackpad zooms around the pointer. Dragging on empty workspace, middle-button dragging or Space + drag pans the view.
  • Zoom is stored with useStudioDraft for each project and tool. Pan resets when the tool remounts.
  • When the host passes actionHistory, the toolbar shows Undo, Redo and Action history, and ⌘/Ctrl + Z and Shift + ⌘/Ctrl + Z work while the pointer is over the canvas or the canvas has focus.

These gestures change only the view transform. The document and its export geometry stay the same.

Source drawer

SourceCodeDrawer keeps source editing next to the canvas. The host controls it through four props:

  • source is the current serialized document of the tool.
  • onApply parses and validates the edited text, then updates the host state. An error it throws appears in the drawer and leaves the visual document unchanged.
  • format and title label the drawer.
  • onClose closes it. The tool and the canvas position stay as they were.

The drawer is a shared editing shell, and each tool owns its schema. Each tool checks its own fields and converts valid source into the same state that its visual controls use. Lottie and Animation use CanvasDocument envelopes with their own metadata, the expression tools use expression documents, and the foundation and component tools use their own versioned objects.

See Source code editing, the Source format reference and the Studio Browser API.

Direct manipulation

EditableCanvasLayer draws one movable object on the artboard. The host gives it a base box and a CanvasLayerTransform (offset, scale, optional width and height scale, and rotation) and receives the new transform in onChange.

StateBehavior
IdleNo selection frame or handles
SelectedA selection frame, the layer label and resize handles. resizeMode: 'scale' shows one scale handle, and resizeMode: 'box' shows edge and corner handles
MovingPointer capture moves the layer in canvas coordinates. Within 6 screen pixels it snaps to the canvas edges and center, to the edges and centers of other layers, and to the lines in snapTargets
ResizingEdge and corner drags change the scale or the box. The minimum scale is 0.02, and there is no fixed maximum
RotatingWith onRotate, a rotate handle appears. Shift snaps the angle to 15° steps
KeyboardArrow keys nudge by 1 px, and Shift + arrow nudges by 10 px. Shift + F10 or the context menu key opens the host's menu
LockedWith interactive={false}, the layer is inert on the canvas. Inspector controls still work

The host owns the selection. The expression tools start with nothing selected and select a layer when it is added. Design Lab passes onRotate, rotation and canvasThirdsSnapTargets (rule-of-thirds lines on artboards). The expression tools rotate layers through the inspector and use the default snap lines.

CanvasDocument model

src/lib/canvasDocument.ts defines the portable document model that people and agents share. It is separate from React component state and records:

  • The schema version, brand binding, capabilities, revision and metadata.
  • Pages with dimensions, safe area, bleed, background, notes and ordered element IDs.
  • Elements of the kinds text, image, logo, shape, line, frame, group, gradient, texture, shader, effect, video and component.
  • Bounds, rotation, anchors, locks for position, dimensions, aspect ratio and rotation, visibility, blend mode, border, radius, opacity and shadow.
  • Font bindings, text roles and text style.
  • Non-destructive image crop, focal point, fit, saturation, dither, grain, blur, posterization and halation.
  • Asset and font records that elements reference by ID.

applyCanvasMutation supports these mutations: move several elements, resize, lock, delete, reorder, update and replace an asset. Replacing an asset changes only the source reference and keeps geometry, crop, image treatment, effects and constraints.

The module also exports history and checking helpers. commitCanvasChange takes one mutation or a batch, and a batch is one undo step. undoCanvasChange and redoCanvasChange restore cloned documents. saveCanvasVersion records an author, time, name, note and revision, and restoreCanvasVersion returns a clone. preflightCanvasDocument reports missing assets, missing fonts, assets and fonts that are not embedded, elements that extend beyond their page and text over its line limit. Tests cover these helpers, and no Studio tool calls them yet. Each editor keeps its own undo stack (the expression tools use useExpressionDocument, with 120 steps), and saved checkpoints live in src/lib/savedDesigns.ts.

Logo appearance

LogoAppearanceControls and src/lib/logoAppearance.ts keep logo treatment the same across tools. The CSS preview filter, the SVG export filter and the canvas renderer all read the same settings.

  • Invert reverses the colors of the resolved mark or image. No second file is needed.
  • Dither applies an ordered print pattern with an amount (0–100%), a cell size (2–18 px) and a direction (0–360°). The source file stays unchanged.
  • Outline follows the alpha of the SVG or transparent image, with its own color, opacity and width.
  • Shadow has a color, opacity, blur and horizontal and vertical offsets.
  • The outline and shadow colors use ColorControl with opacity.

The settings are stored with the layer or element that uses them. In Brand elements, one setting applies to every logo in the selected element.

Third-party libraries

Studio tools use third-party packages through local components, so a tool does not depend on each library's API.

PackageLocal boundaryUsed for
@radix-ui/react-selectStudioSelectAccessible select popovers, keyboard navigation and focus management
@radix-ui/react-slotButtonButtons that render as links or other elements with the same styles
three and @react-three/fiberLiveMaterialCanvas, ShaderGradientSurface and HoloClothSurfaceLive GPU materials
@shadergradient/reactShaderGradientSurfaceThe editable ShaderGradient sphere
@paper-design/shaders-reactThe Paper adapter (paperShaderRenderer.ts and its registries)Paper shader families and presets. /api/materials lists the ones the Shader Library shows
shadersShaderEffectsSurface and src/lib/shaderEffectProcessor.tsMIT-licensed Shaders.com WebGPU materials and the image effects on Design Lab Effect layers
WebGL Fluid Simulation by Pavel Dobryakovsrc/lib/fluidSimulationShaders.ts in LiveMaterialCanvasThe MIT-licensed fluid solver behind Fluid Energy
gifencsrc/lib/exportGif.ts and src/lib/canvasExport.tsGIF encoding and palettes
mediabunnysrc/lib/canvasExport.tsMP4 encoding, including the Animation audio track
@lottiefiles/dotlottie-webLottieStudio.lottie and Lottie JSON playback with exact frame seeking
prismjssrc/lib/codeHighlight.ts and src/lib/expressionSvg.tsJSON color in the source drawer and code color in Terminal card
@phosphor-icons/reactsrc/components/ui/SolidIcons.tsxControl icons
gt-next<T> and useGTTranslatable Studio labels and accessible names
FumadocsThe docs shell and MDX sourceThis documentation, its search and its navigation

Build a new tool

  1. Wrap the tool in ToolShell, or compose StudioToolHeader, StudioFileMenu and LazySourceCodeDrawer yourself.
  2. Store tool fields with useStudioDraft(identity.id, tool.id, field, initialValue).
  3. Use ColorControl for every editable color and opacity.
  4. Wrap the artifact in CanvasViewport and keep its declared aspect ratio.
  5. Represent every movable object with a CanvasLayerTransform and render it with EditableCanvasLayer.
  6. Use StudioSelect, Button and the fields in src/components/tools/ToolFields.tsx (ControlSection, Field, RangeField, UploadField and SegmentedChoice) instead of one-off controls.
  7. Build exports from the same resolved settings that drive the preview.
  8. Serialize the editable state for the source drawer and validate edits with the sourceCode.ts readers, so source edits go through the same validators and state setters as the visual controls. A tool that stores a CanvasDocument can use usePortableCanvasWorkspace for serialization and autosave.
  9. Register Browser API actions through the automation prop of ToolShell, add their contracts to STUDIO_TOOL_ACTION_CONTRACTS in src/lib/studioAgentCapabilities.ts, and document every action name. src/lib/__tests__/documentationCoverage.test.ts fails when an action is missing from the docs.

A tool built this way looks and behaves like the rest of the Studio, and its renderer can still be SVG, Canvas, HTML or WebGL.

On this page