GitHunt
GA

Gattalraouf/mini-form-builder-code-challenge

A dynamic and accessible drag-and-drop form builder built with Nuxt 3, Vue 3, Tailwind CSS, Element Plus, Pinia and Vuedraggable. Users can build forms visually, edit form fields, and preview or submit form data dynamically.

๐Ÿ“ README.md

๐Ÿงฉ Mini Form Builder Code Challenge

A dynamic and accessible drag-and-drop form builder built with Nuxt 3, Vue 3, Tailwind CSS, Element Plus, Pinia and Vuedraggable. Users can build forms visually, edit form fields, and preview or submit form data dynamically.


๐Ÿš€ Setup Instructions

1. ๐Ÿ“ฆ Clone the Repository

git clone https://github.com/Gattalraouf/mini-form-builder-code-challenge.git
cd mini-form-builder-code-challenge

2. ๐Ÿ›  Install Dependencies

Make sure you're using Node 18+

npm install
# or
yarn

3. ๐Ÿงช Run the Dev Server

npm run dev

4. ๐Ÿงฑ Build for Production

npm run build

5. ๐Ÿ” Preview Production Build

npm run preview

๐Ÿ“š Project Overview

Feature Description
๐ŸŽจ Drag-and-Drop Builder Users drag form fields from a palette into the form area
โœ๏ธ Field Editor Modal Click any field to edit label, type, placeholder, etc.
๐Ÿ“„ Form Preview Page Navigate to preview to test out the form inputs
โœ… Validation with Rules Supports required, email format, min length, etc.
โ™ฟ Accessibility First Keyboard navigation and ARIA support throughout
๐Ÿ” Form Reset & Submit Resets values or outputs submitted JSON data to console

๐Ÿงฑ Architecture Choices

1. Vue 3 Composition API + <script setup>

We chose the Composition API for its cleaner, scalable structure, especially for shared logic and reactive states.

2. Nuxt 3

Using Nuxt simplifies routing and SSR readiness, with automatic code-splitting and file-based routing.

3. Pinia (with persistence)

State management for form fields is handled globally with Pinia, allowing real-time sync and drag-drop reordering. pinia-plugin-persistedstate ensures changes persist across reloads.

4. Tailwind CSS

Tailwind enables a utility-first approach to styling, offering responsive, accessible, and customizable design without writing traditional CSS.

5. Element Plus

Provides accessible and customizable UI components like form inputs, checkboxes, validation, and modals.

6. Vuedraggable

Enables intuitive drag-and-drop functionality between the palette and form workspace.


๐Ÿ“ Project Structure

๐Ÿ“ฆ src/
โ”‚
โ”œโ”€โ”€ components/
โ”‚   โ”œโ”€โ”€ FieldPalette.vue         # Field selection sidebar
โ”‚   โ”œโ”€โ”€ FormBuilder.vue          # Drag-and-drop workspace
โ”‚   โ”œโ”€โ”€ DynamicForm.vue          # Form renderer with validation
โ”‚   โ”œโ”€โ”€ FormField.vue            # Single field item in the form
โ”‚   โ”œโ”€โ”€ FieldEditModal.vue       # Modal to edit individual field
โ”‚
โ”œโ”€โ”€ pages/
โ”‚   โ”œโ”€โ”€ index.vue                # Form builder main page
โ”‚   โ”œโ”€โ”€ preview.vue              # Form preview page
โ”‚
โ”œโ”€โ”€ stores/
โ”‚   โ””โ”€โ”€ formStore.ts             # Pinia store for managing form fields
โ”‚
โ”œโ”€โ”€ constants/
โ”‚   โ””โ”€โ”€ formElements.ts          # List of available field templates
โ”‚
โ”œโ”€โ”€ types/
โ”‚   โ””โ”€โ”€ formField.ts             # TypeScript interface for form fields
โ”‚
โ”œโ”€โ”€ plugins/
โ”‚   โ”œโ”€โ”€ element-plus.ts          # Plugin to register Element Plus
โ”‚   โ””โ”€โ”€ pinia.ts                 # Plugin to initialize Pinia with persistence
โ”‚
โ””โ”€โ”€ app.vue                      # Main layout

๐Ÿ“ฆ Tech Stack

  • Vue 3 + Nuxt 3
  • Pinia + pinia-plugin-persistedstate
  • Element Plus โ€“ UI components and validation
  • Vuedraggable โ€“ Drag and drop support
  • TypeScript โ€“ Type safety
  • Tailwind CSS โ€” for utility-first responsive UI design.

๐Ÿ› ๏ธ Development Notes

  • The app uses a computed field list from the store.
  • Each form field includes a unique id, label, type, value, and accessibility attributes.
  • Form preview dynamically renders input components based on their type.

๐Ÿ“ค Example Output

On submit, data is logged as:

{
    "Full Name": "Jhon Doe",
    "A lot of text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
    "Email Address": "some@email.com",
    "Are you certain?": true,
    "Do you want to click here?": false
}

On submit, form fields list is logged as:

{
 [
  {
    "id": "short-text-1760381499616",
    "name": "short-text",
    "label": "Full Name",
    "description": "Single-line text input for short responses.",
    "type": "text",
    "placeholder": "Enter your name here",
    "required": true,
    "value": "Jhon Doe"
  },
  {
    "id": "short-text-1760381505994",
    "name": "short-text",
    "label": "Middle Name",
    "description": "Single-line text input for short responses.",
    "type": "text",
    "placeholder": "Enter your middle name here",
    "required": false,
    "value": ""
  },
  {
    "id": "long-text-1760381507111",
    "name": "long-text",
    "label": "A lot of text",
    "description": "Multi-line text area for longer or formatted responses.",
    "type": "textarea",
    "placeholder": "Enter detailed information...",
    "required": true,
    "value": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "
  },
  {
    "id": "long-text-1760381509079",
    "name": "long-text",
    "label": "Some Long Text",
    "description": "Multi-line text area for longer or formatted responses.",
    "type": "textarea",
    "placeholder": "Enter detailed information...",
    "required": false,
    "value": ""
  },
  {
    "id": "email-1760381511343",
    "name": "email",
    "label": "Email Address",
    "description": "Email input field that validates email addresses.",
    "type": "email",
    "placeholder": "Enter your email address",
    "required": true,
    "value": "some@email.com"
  },
  {
    "id": "email-1760381510108",
    "name": "email",
    "label": "Secondary Email Address",
    "description": "Email input field that validates email addresses.",
    "type": "email",
    "placeholder": "Enter your email address",
    "required": false,
    "value": ""
  },
  {
    "id": "checkbox-1760381512862",
    "name": "checkbox",
    "label": "Are you certain?",
    "description": "Simple checkbox input for true/false or yes/no choices.",
    "type": "checkbox",
    "placeholder": "",
    "required": true,
    "value": true
  },
  {
    "id": "checkbox-1760381515284",
    "name": "checkbox",
    "label": "Do you want to click here?",
    "description": "Simple checkbox input for true/false or yes/no choices.",
    "type": "checkbox",
    "placeholder": "",
    "required": false,
    "value": false
  }
]
}
Gattalraouf/mini-form-builder-code-challenge | GitHunt