Overview
The frontend is a React 18 single-page application (SPA) built with TypeScript and Vite. It provides a visual editor for customizing HubSpot forms with drag-and-drop functionality and live preview.Tech Stack
- React 18.3 - UI library with concurrent features
- TypeScript 5.5 - Type-safe JavaScript
- Vite 5.4 - Fast build tool and dev server
- Zustand 4.5 - Lightweight state management
- @dnd-kit - Modern drag-and-drop library
- JSZip 3.10 - ZIP file generation for module export
Component Architecture
Main Application Component
File: frontend/src/App.tsx The root component orchestrates all major features:Component Hierarchy
Core Components
1. HubSpotConnect
File: frontend/src/components/HubSpotConnect.tsx Handles OAuth connection to HubSpot.2. FormSelector
File: frontend/src/components/FormSelector.tsx Dropdown for selecting a HubSpot form.3. Sidebar
File: frontend/src/components/Sidebar.tsx Left panel containing connection status, form selector, layout options, and field palette. Key Features:- Shows available fields (not yet added to layout)
- Fields are draggable using
useDraggablefrom @dnd-kit - Layout mode toggle (single-step / multi-step)
- Add step button
4. LayoutBuilder
File: frontend/src/components/LayoutBuilder.tsx Drag-and-drop canvas for building form layout. Key Features:- Multi-step support
- Sortable steps (drag to reorder)
- Sortable fields within steps
- Up to 3 fields per row
- Visual drop indicators
5. PreviewPanel
File: frontend/src/components/PreviewPanel.tsx Renders live preview of form using Shadow DOM for style isolation. Key Features:- Shadow DOM isolation (no style conflicts)
- Multi-step navigation
- Form validation
- Checkbox/radio support
- Responsive field groups
Custom Hooks
useHubSpotForms
File: frontend/src/hooks/useHubSpotForms.ts Manages HubSpot API interactions.useLayoutStore
File: frontend/src/hooks/useLayoutStore.ts Zustand store for managing layout state.initializeFromSchema- Creates initial layout from form schemasetMode- Switches between single-step and multi-stepaddStep- Adds a new stepremoveStep- Removes a step (moves fields to first step)renameStep- Updates step titlemoveFieldBetweenSteps- Moves field from one step to anotheraddFieldToNewRow- Adds field from palette to new rowaddFieldToRow- Adds field to existing row (max 3 per row)moveFieldToNewRow- Splits field into its own rowmoveFieldWithinStep- Reorders fields within a step
useLayoutDnd
File: frontend/src/hooks/useLayoutDnd.ts Manages drag-and-drop logic using @dnd-kit.palette-field- Field from sidebar (not yet in layout)field- Field already in layoutstep- Entire step (for reordering steps)
step-drop- Drop zone for each step (adds to end)field- Drop on existing field (combine or insert)
before- Create new row before targetafter- Create new row after targetinside- Add to same row (left/right/center)
Module Generation
Export Flow
fields.json- HubSpot module field definitionsmodule.html- HubL template with form markupmodule.css- Form stylesmodule.js- Multi-step navigation logicmeta.json- Module metadata
State Management Flow
Styling Approach
- Pure CSS (no framework like Tailwind)
- BEM-like naming (e.g.,
multistep-form__tabs-item) - CSS custom properties for theming
- Responsive design with media queries
- Shadow DOM styles isolated in PreviewPanel
API Endpoints
File: frontend/src/config.tsBuild Configuration
File:frontend/vite.config.ts
Performance Considerations
- React 18 concurrent features - Automatic batching, transitions
- Memoization - useMemo/useCallback where appropriate
- Virtualization - Can be added for large forms
- Code splitting - Dynamic imports for heavy components
- Shadow DOM - Prevents style recalculation in preview
