> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scanova.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Base Custom Form Component

> Defines a fully configurable Custom Form Component that allows collecting user input through dynamic question blocks. Each form can include multiple question types (text, choice, rating, upload, etc.) with optional formatting and styling controls.

## Overview

The **Custom Form Component** enables the creation of interactive and dynamic forms within a QR Code landing page.\
Each form consists of a **title**, **description**, and a configurable array of **questions**.\
Questions support various input types — from short text to file uploads — allowing developers to capture structured user responses.

This schema also includes optional **formatting** references for customizing the visual presentation of form elements.

## Properties

| Property        | Type            | Required | Description                                                                                             |
| :-------------- | :-------------- | :------- | :------------------------------------------------------------------------------------------------------ |
| **title**       | `string`        | No       | Title of the form. Shown at the top of the form interface.                                              |
| **description** | `string`        | No       | A short description or subtitle to explain the form purpose.                                            |
| **questions**   | `array<object>` | ✅ Yes    | Array of question objects. Each defines the question, type, and validation rules. Maximum 40 questions. |
| **formatting**  | `object`        | No       | Defines style and layout formatting for form elements.                                                  |

### **Formatting Object**

| Sub-property  | Type     | Reference  | Description                                            |
| :------------ | :------- | :--------- | :----------------------------------------------------- |
| **textStyle** | `object` | Text Style | Controls font size, weight, and color of form text.    |
| **cardStyle** | `object` | Card Style | Defines container style for each question card.        |
| **iconStyle** | `object` | Icon Style | Manages icon appearance for interactive form elements. |

## Question Structure

Each item inside the `questions` array represents a single question block with the following structure:

| Property                | Type      | Required | Description                                                                      |
| :---------------------- | :-------- | :------- | :------------------------------------------------------------------------------- |
| **question**            | `string`  | ✅ Yes    | The question text (3–200 characters).                                            |
| **questionDescription** | `string`  | No       | Optional helper text below the question (max 300 characters).                    |
| **privacyNote**         | `string`  | No       | Privacy or consent note related to the question (max 300 characters).            |
| **answer**              | `object`  | ✅ Yes    | Defines the input type and configuration for the answer.                         |
| **isRequired**          | `boolean` | No       | Indicates if the question must be answered before submission (default: `false`). |

### **Answer Object**

| Field    | Type                          | Required    | Description                                                                              |
| :------- | :---------------------------- | :---------- | :--------------------------------------------------------------------------------------- |
| **type** | `string`                      | ✅ Yes       | Defines the input type (e.g., `shortAnswer`, `multipleChoice`, `uploadFile`).            |
| **data** | `object` / `array` / `string` | Conditional | Provides configuration data for the selected input type. Reference to `form_input.json`. |

Supported `type` values:

```
shortAnswer, paragraph, multipleChoice, checkbox, dropdown,
linearScale, dateFormat, timeFormat, email, phoneNumber,
starRating, emoji, likeDislike, uploadFile, signature
```

## Conditional References (by Input Type)

| Input Type                           | Data Schema Reference                         |
| :----------------------------------- | :-------------------------------------------- |
| `multipleChoice`, `checkbox`         | `form_input.json#/properties/multipleOptions` |
| `linearScale`                        | `form_input.json#/properties/linearScale`     |
| `dateFormat`                         | `form_input.json#/properties/dateFormat`      |
| `timeFormat`                         | `form_input.json#/properties/timeFormat`      |
| `starRating`, `emoji`, `likeDislike` | `form_input.json#/properties/feedback`        |
| `uploadFile`                         | `form_input.json#/properties/uploadFile`      |
| `signature`                          | `form_input.json#/properties/signature`       |

## Validation Rules

| Field         | Constraint               | Example                                                  |
| :------------ | :----------------------- | :------------------------------------------------------- |
| `title`       | 0–100 characters         | `"title": "Customer Feedback Form"`                      |
| `description` | 2–500 characters         | `"description": "Please share your experience with us."` |
| `questions`   | Max 40 items             | `"questions": [ { ... } ]`                               |
| `question`    | 3–200 characters         | `"question": "What is your name?"`                       |
| `answer.type` | Must be a supported type | `"type": "shortAnswer"`                                  |

## Example Schema

<CodeGroup>
  ```json Schema theme={null}
  {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "definitions": {},
    "title": "Custom Form Component",
    "type": "object",
    "required": [
      "questions"
    ],
    "properties": {
      "title": {
        "type": "string",
        "minLength": 0,
        "maxLength": 100,
        "description": "Form title"
      },
      "description": {
        "type": "string",
        "minLength": 2,
        "maxLength": 500,
        "description": "Form description"
      },
      "questions": {
        "type": "array",
        "maxItems": 40,
        "additionalProperties": false,
        "description": "Question block component",
        "$comment": "Allow upto 20 questions.",
        "items": {
          "type": "object",
          "required": [
            "question",
            "answer"
          ],
          "additionalProperties": false,
          "minProperties": 1,
          "properties": {
            "question": {
              "type": "string",
              "maxLength": 200,
              "minLength": 3
            },
            "questionDescription": {
              "type": "string",
              "maxLength": 300
            },
            "privacyNote": {
              "type": "string",
              "maxLength": 300
            },
            "answer": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "type": "string",
                  "enum": [
                    "shortAnswer",
                    "paragraph",
                    "multipleChoice",
                    "checkbox",
                    "dropdown",
                    "linearScale",
                    "dateFormat",
                    "timeFormat",
                    "email",
                    "phoneNumber",
                    "starRating",
                    "emoji",
                    "likeDislike",
                    "uploadFile",
                    "signature"
                  ]
                },
                "data": {
                  "type": [
                    "string",
                    "object",
                    "array"
                  ]
                }
              },
              "allOf": [
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "multipleChoice"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/multipleOptions"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "checkbox"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/multipleOptions"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "linearScale"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/linearScale"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "dateFormat"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/dateFormat"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "timeFormat"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/timeFormat"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "starRating"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/feedback"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "emoji"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/feedback"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "likeDislike"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/feedback"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "uploadFile"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/uploadFile"
                      }
                    }
                  }
                },
                {
                  "if": {
                    "properties": {
                      "type": {
                        "const": "signature"
                      }
                    }
                  },
                  "then": {
                    "properties": {
                      "data": {
                        "$ref": "form_input.json#/properties/signature"
                      }
                    }
                  }
                }
              ]
            },
            "isRequired": {
              "type": "boolean",
              "default": false
            }
          }
        }
      },
      "formatting": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "textStyle": {
            "$ref": "style/text.json"
          },
          "cardStyle": {
            "$ref": "style/card.json"
          },
          "iconStyle": {
            "$ref": "style/icon.json"
          }
        }
      }
    }
  }
  ```
</CodeGroup>

## Notes

* Each form can contain **up to 40 questions**.
* Each question must have both a **question** text and an **answer** object.
* **Conditional schemas** ensure validation consistency depending on `answer.type`.
* Formatting components reference the shared **style library**, ensuring consistent design across forms.
