74 lines
4 KiB
Markdown
74 lines
4 KiB
Markdown
|
|
# pen-react
|
||
|
|
|
||
|
|
React UI SDK for OpenPencil -- provider, hooks, panels, toolbar, and property editor components.
|
||
|
|
|
||
|
|
## Structure
|
||
|
|
|
||
|
|
### Core
|
||
|
|
|
||
|
|
- `src/context.ts` — `DesignEngineContext`: React context holding the `DesignEngine` instance
|
||
|
|
- `src/provider.tsx` — `DesignProvider`: provides engine to React tree. Supports uncontrolled mode (`initialDocument`) and controlled mode (`document` + `onDocumentChange`) with echo-loop prevention
|
||
|
|
|
||
|
|
### Hooks (`src/hooks/`)
|
||
|
|
|
||
|
|
- `use-design-engine.ts` — `useDesignEngine()`: gets engine from context, throws if outside provider
|
||
|
|
- `use-document.ts` — `useDocument()`: returns current `PenDocument`, re-renders on mutation
|
||
|
|
- `use-selection.ts` — `useSelection()`: returns `string[]` of selected node IDs
|
||
|
|
- `use-viewport.ts` — `useViewport()`: returns `ViewportState` (zoom, panX, panY)
|
||
|
|
- `use-active-tool.ts` — `useActiveTool()`: returns current `ToolType`
|
||
|
|
- `use-history.ts` — `useHistory()`: returns `{ canUndo, canRedo }`
|
||
|
|
- `use-active-node.ts` — `useActiveNode()`: returns the single active `PenNode` or null
|
||
|
|
- `use-active-page.ts` — `useActivePage()`: returns active page ID
|
||
|
|
- `use-hover.ts` — `useHover()`: returns hovered node ID
|
||
|
|
- `use-variables.ts` — `useVariables()`: returns document variables map
|
||
|
|
|
||
|
|
### Utilities (`src/utils/`)
|
||
|
|
|
||
|
|
- `use-engine-subscribe.ts` — `useEngineSubscribe(engine, event, getSnapshot)`: generic hook using `useSyncExternalStore` to subscribe to engine events with stable snapshot refs
|
||
|
|
|
||
|
|
### Stores (`src/stores/`)
|
||
|
|
|
||
|
|
- `ui-store.ts` — `useUIStore` (Zustand): pure UI state -- panel visibility, layer drag state, collapsed nodes. NOT engine state
|
||
|
|
|
||
|
|
### Components (`src/components/`)
|
||
|
|
|
||
|
|
- `design-canvas.tsx` — `DesignCanvas`: canvas element with CanvasKit rendering via `attachCanvas` + `attachInteraction` from pen-engine browser adapter
|
||
|
|
- `core-toolbar.tsx` — `CoreToolbar`: main tool selection bar
|
||
|
|
- `tool-button.tsx` — `ToolButton`: individual tool button with active state
|
||
|
|
- `shape-tool-dropdown.tsx` — `ShapeToolDropdown`: dropdown for shape tools (rectangle, ellipse, line, polygon)
|
||
|
|
- `layer-panel.tsx` — `LayerPanel`: document tree panel with drag-and-drop reordering
|
||
|
|
- `layer-item.tsx` — `LayerItem`: individual layer row with visibility/lock toggles
|
||
|
|
- `layer-context-menu.tsx` — `LayerContextMenu`: right-click context menu for layers
|
||
|
|
- `property-panel.tsx` — `PropertyPanel`: right-side property inspector (delegates to section components)
|
||
|
|
- `color-picker.tsx` — `ColorPicker`: color input with hex/opacity, gradient support
|
||
|
|
- `number-input.tsx` — `NumberInput`: numeric input with drag-to-adjust
|
||
|
|
- `section-header.tsx` — `SectionHeader`: collapsible section header
|
||
|
|
- `font-picker.tsx` — `FontPicker`: font family selector with search
|
||
|
|
- `variable-picker.tsx` — `VariablePicker`: design variable selector
|
||
|
|
- `icon-picker-dialog.tsx` — `IconPickerDialog`: icon search and selection
|
||
|
|
- `boolean-toolbar.tsx` — `BooleanToolbar`: union/subtract/intersect boolean operations
|
||
|
|
- `page-tabs.tsx` — `PageTabs`: multi-page tab bar
|
||
|
|
- `status-bar.tsx` — `StatusBar`: bottom status bar (zoom, selection info)
|
||
|
|
|
||
|
|
### Property sections (`src/components/sections/`)
|
||
|
|
|
||
|
|
- `size-section.tsx` — Width, height, x, y, rotation
|
||
|
|
- `fill-section.tsx` — Fill array editor (solid, gradient, image)
|
||
|
|
- `stroke-section.tsx` — Stroke properties (thickness, alignment, dash)
|
||
|
|
- `text-section.tsx` — Text content, font, size, weight, style
|
||
|
|
- `text-layout-section.tsx` — Text alignment, growth mode
|
||
|
|
- `corner-radius-section.tsx` — Corner radius (uniform or per-corner)
|
||
|
|
- `effects-section.tsx` — Blur and shadow effects
|
||
|
|
- `layout-section.tsx` — Auto-layout direction, gap, alignment
|
||
|
|
- `layout-padding-section.tsx` — Padding (uniform or per-side)
|
||
|
|
- `appearance-section.tsx` — Opacity, blend mode, visibility
|
||
|
|
- `icon-section.tsx` — Icon font name and family
|
||
|
|
- `image-section.tsx` — Image source, fit mode, adjustments
|
||
|
|
- `export-section.tsx` — Export format and code preview
|
||
|
|
|
||
|
|
## Testing
|
||
|
|
|
||
|
|
```bash
|
||
|
|
bun --bun vitest run packages/pen-react/src/__tests__/
|
||
|
|
```
|