Skip to content

Repository files navigation

🧩 Dynamic Form Builder

A visual, drag-and-drop form designer built with Angular 20, Angular Material, and Tailwind CSS v4. Create complex enterprise forms in real time — no code required.


✨ Features

  • 🖱️ Drag & Drop Canvas — drag fields from the sidebar directly onto the form canvas; reorder within and across rows
  • 📐 Multi-Row Layout — add, remove, and reorder rows to create multi-column form layouts
  • 🔍 Live Preview — switch between Editor and Preview mode to see the rendered form instantly
  • ⚙️ Field-Level Settings — click any field to configure its label, placeholder, required state, type, options, and more in the right panel
  • 🧱 8 Field Types — covers the full range of common form inputs
  • 🎨 Angular Material + Tailwind — polished UI with a custom Material theme and utility-class styling
  • 🔄 Reactive State — built entirely on Angular Signals for fine-grained, performant reactivity

🗂️ Supported Field Types

Field Icon Configurable Settings
Text text_fields Label, Placeholder, Required, Input Type (text / email / number / password)
Textarea notes Label, Placeholder, Required
Checkbox check_box Label, Required
Radio radio_button_checked Label, Required, Options, Orientation (horizontal / vertical)
Dropdown arrow_drop_down_circle Label, Required, Options
Date Picker event Label, Required, Min Date, Max Date
Heading title Heading text, Heading Level (H1–H6), Subheading text, Subheading Level
Button smart_button Button text, Cancel text, Show/hide cancel, Alignment (left / right)

🏗️ Architecture

src/
├── app/
│   ├── components/
│   │   ├── form-elements-menu/       # Left sidebar — draggable field palette
│   │   │   └── field-button/         # Individual palette button
│   │   ├── main-canvas/              # Center — editor + preview toggle
│   │   │   ├── form-editor/          # Drag-drop canvas with rows and fields
│   │   │   ├── form-field-component/ # Single field wrapper (drag handle, selection)
│   │   │   ├── form-preview/         # Read-only rendered form view
│   │   │   └── field-preview/        # Single field rendered preview
│   │   └── field-settings/           # Right sidebar — dynamic settings panel
│   │       └── dynamic-setting-field/# Renders a single setting control
│   ├── models/
│   │   ├── field.ts                  # formField, fieldTypeDefinition, optionItem interfaces
│   │   ├── form.ts                   # formRow interface
│   │   └── field-definitions.ts     # Static metadata & default configs for all 8 types
│   └── services/
│       ├── form.ts                   # Signal-based form state (rows, selected field, mutations)
│       └── field-types-service.ts    # Registry — maps type string → fieldTypeDefinition

Data Flow

┌─────────────────────┐     drag        ┌──────────────────────┐
│  FormElementsMenu   │ ──────────────► │     FormEditor       │
│  (field palette)    │  fieldTypeDefn  │  (cdkDropList rows)  │
└─────────────────────┘                 └──────────┬───────────┘
                                                   │ addField / moveField
                                                   ▼
                                        ┌──────────────────────┐
                                        │    Form Service      │
                                        │  (Signal<formRow[]>) │
                                        └──────┬───────────────┘
                               read rows │     │ updateField(id, patch)
                                         │     │
                          ┌──────────────┘     └──────────────────┐
                          ▼                                        ▼
               ┌──────────────────┐                  ┌─────────────────────┐
               │   FormPreview    │                  │   FieldSettings     │
               │  (live render)   │                  │  (dynamic controls) │
               └──────────────────┘                  └─────────────────────┘

🛠️ Tech Stack

Layer Technology
Framework Angular 20 (standalone components)
UI Components Angular Material 20
Drag & Drop Angular CDK DragDropModule
Styling Tailwind CSS v4 + custom SCSS theme
State Management Angular Signals (signal, computed)
Language TypeScript 5.9
Build Angular CLI / Vite
Testing Karma + Jasmine

🚀 Getting Started

Prerequisites

  • Node.js ≥ 18
  • npm ≥ 9
  • Angular CLI ≥ 20
npm install -g @angular/cli

Install & Run

# 1. Clone the repository
git clone https://github.com/<your-username>/dynamic-form-builder.git
cd dynamic-form-builder

# 2. Install dependencies
npm install

# 3. Start the dev server
ng serve

Open http://localhost:4200 in your browser.

Build for Production

ng build
# Output: dist/form-designer/

Run Tests

ng test

🖼️ UI Layout

┌───────────────────────────────────────────────────────────────────────────────────────────────┐
│                                      Dynamic Form Builder                                     │
│                        Flexible, scalable form creation for modern apps                       | 
├──────────────────────┬─────────────────────────────────────────────────┬──────────────────────┤
│    Field Palette     │                   Form Canvas                   │    Field Settings    │
│ ─────────────        │ ───────────                                     │ ──────────────       │
│                      │                                                 │                      │
│ [T]  Text            │ [Editor]   [Preview]   [+ Add Row]              │ Label                │
│ [¶]  Textarea        │                                                 │ ┌──────────────────┐ │
│ [x]  Checkbox        │ ┌─ Row 1 ─────────────────────────────────────┐ │ │     My Label     │ │
│ [o]  Radio           │ │  ┌────────┐     ┌──────────────┐            │ │ └──────────────────┘ │
│ [v]  Dropdown        │ │  │  Text  │     │   Dropdown   │            │ │                      │
│ [#]  Date            │ │  └────────┘     └──────────────┘            │ │ Placeholder          │
│ [H]  Heading         │ └─────────────────────────────────────────────┘ │ ┌──────────────────┐ │
│ [B]  Button          │                                                 │ │  Enter text...   │ │
│                      │ ┌─ Row 2 ─────────────────────────────────────┐ │ └──────────────────┘ │
│ Drag any field       │ │                                             │ │                      │
│ to the canvas ↓      │ │             Drop fields here...             │ │ [ ] Required         │
│                      │ │                                             │ │                      │
│                      │ └─────────────────────────────────────────────┘ │                      │
└──────────────────────┴─────────────────────────────────────────────────┴──────────────────────┘

🔑 Key Design Decisions

JSON-driven field metadata — every field type is defined as a fieldTypeDefinition object that bundles its default config, settings schema, and rendering component together. Adding a new field type is a single object registration in field-definitions.ts with zero changes elsewhere.

Signal-based stateForm service exposes signal<formRow[]> and a computed selector for the active field. Components stay in sync automatically with no subscriptions to manage.

Dynamic settings panelFieldSettings reads settingsConfig from the active field's definition and passes each item to DynamicSettingField, which renders the appropriate control (text input, checkbox, select, options editor, date picker). New setting types only need one new @case branch.

CDK drag-drop — uses cdkDropListGroup at the app root so fields can be dragged across row boundaries. The field-selector drop list id distinguishes new-field drops from move operations.


📦 Scripts Reference

Command Description
ng serve Start dev server at localhost:4200
ng build Production build to dist/
ng build --watch --configuration development Dev build watcher
ng test Run unit tests with Karma

📄 License

MIT © 2024

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages