formique-css
Advanced tools
+266
-103
@@ -1,35 +0,80 @@ | ||
| /* Formique CSS */ | ||
| @import url('https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap'); | ||
| .dark-theme { | ||
| --background-dark: #0A0A0A; | ||
| --background-light: #1A1A1A; | ||
| --text-light: #E5E5E5; | ||
| --border-color: #333333; | ||
| --input-background: #1C1C1C; | ||
| --input-background-disabled: #2A2A2A; | ||
| --label-color: #999999; | ||
| --radio-checkbox-accent: #4A90E2; | ||
| --button-background: #444444; | ||
| --button-background-hover: #555555; | ||
| --button-text-color: #E5E5E5; | ||
| --input-border-color: #444444; | ||
| --input-border-color-focus: #666666; | ||
| --secondary-text-color: #B3B3B3; | ||
| } | ||
| /* Dark Theme */ | ||
| :root { | ||
| --background-dark: #1e1e1e; | ||
| --background-light: #2e2e2e; | ||
| --text-light: #e0e0e0; | ||
| --border-color: #444; | ||
| --input-background: #333; | ||
| --input-background-disabled: #444; | ||
| --label-color: #b0b0b0; | ||
| --radio-checkbox-accent: #b0b0b0; | ||
| --button-background: #b0b0b0; | ||
| --button-background-hover: #9e9e9e; | ||
| .light-theme { | ||
| --background-light: #ffffff; | ||
| --background-dark: #1a1a1a; | ||
| --text-light: #333333; | ||
| --border-color: #cccccc; | ||
| --input-background: #ffffff; | ||
| --input-background-disabled: #e0e0e0; | ||
| --label-color: #555555; | ||
| --radio-checkbox-accent: #4A90E2; | ||
| --button-background: #888888; | ||
| --button-background-hover: #666666; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #cccccc; | ||
| --input-border-color-focus: #4A90E2; | ||
| --secondary-text-color: #777777; | ||
| } | ||
| /* Pink Theme | ||
| :root { | ||
| --background-dark: #2c2c2c; | ||
| --background-light: #3d3d3d; | ||
| --text-light: #f1f1f1; | ||
| --border-color: #555; | ||
| --input-background: #444; | ||
| --input-background-disabled: #666; | ||
| --label-color: #ff4081; | ||
| --radio-checkbox-accent: #ff4081; | ||
| --button-background: #ff4081; | ||
| --button-background-hover: #e91e63; | ||
| .pink-theme { | ||
| --background-dark: red; | ||
| --background-light: #05051e; | ||
| --text-light: #fe8bbb; | ||
| --border-color: pink; | ||
| --input-background: #ffffff; | ||
| --input-background-disabled: #f1f8e9; | ||
| --label-color: #fe8bbb; /* #c2185b; */ | ||
| --radio-checkbox-accent: #c2185b; | ||
| --button-background: #c2185b; /*#e91e63;*/ | ||
| --button-background-hover: #f01ff0; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #05051e; | ||
| --input-border-color-focus: #c2185b; | ||
| --secondary-text-color: #880e4f; | ||
| } | ||
| /* Indigo Theme | ||
| :root { | ||
| .light-blue-theme { | ||
| --background-light: #f0f8ff; | ||
| --background-dark: #003b5c; | ||
| --text-light: #fff; | ||
| --text-dark: #000; | ||
| --border-color: #0077b6; | ||
| --input-background: #ffffff; | ||
| --input-background-disabled: #d1e4f4; | ||
| --label-color: #4a6572; | ||
| --radio-checkbox-accent: #0091d3; | ||
| --button-background: #1e3a8a; | ||
| --button-background-hover: #0f2a5f; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #0077b6; | ||
| --input-border-color-focus: #00aaff; | ||
| --secondary-text-color: #4f5b62; | ||
| --dropdown-option-text-color: #003b5c; | ||
| --legend-text-color: #1d3557; | ||
| } | ||
| .indigo-theme { | ||
| --background-dark: #2c2c2c; | ||
@@ -41,10 +86,16 @@ --background-light: #3d3d3d; | ||
| --input-background-disabled: #555; | ||
| --label-color: #3f51b5; | ||
| --label-color: #7986cb; | ||
| --radio-checkbox-accent: #3f51b5; | ||
| --button-background: #3f51b5; | ||
| --button-background-hover: #303f9f; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #3f51b5; | ||
| --input-border-color-focus: #303f9f; | ||
| --secondary-text-color: #b3b3b3; | ||
| } | ||
| /* Blue Theme | ||
| :root { | ||
| .dark-blue-theme { | ||
| --background-dark: #0a0a0a; | ||
@@ -56,6 +107,10 @@ --background-light: #1a1a1a; | ||
| --input-background-disabled: #444; | ||
| --label-color: #2196f3; | ||
| --label-color: #81d4fa; | ||
| --radio-checkbox-accent: #2196f3; | ||
| --button-background: #2196f3; | ||
| --button-background-hover: #1976d2; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #2196f3; | ||
| --input-border-color-focus: #1976d2; | ||
| --secondary-text-color: #b3b3b3; | ||
| } | ||
@@ -65,5 +120,4 @@ | ||
| /* Dark and Orange | ||
| :root { | ||
| .dark-orange-theme { | ||
| --background-dark: #121212; | ||
@@ -75,119 +129,238 @@ --background-light: #1e1e1e; | ||
| --input-background-disabled: #444; | ||
| --label-color: #ff9800; | ||
| --radio-checkbox-accent: #ff9800; | ||
| --button-background: #ff9800; | ||
| --button-background-hover: #e68900; | ||
| --label-color: #f96743; | ||
| --radio-checkbox-accent: #f96743; | ||
| --button-background: #f96743; | ||
| --button-background-hover: #f24e2e; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #f96743; | ||
| --input-border-color-focus: #f24e2e; | ||
| --secondary-text-color: #b3b3b3; | ||
| } | ||
| */ | ||
| .green-theme { | ||
| --background-dark: #001700; | ||
| --background-light: #011f01; | ||
| --text-light: #e0e0e0; | ||
| --border-color: #333; | ||
| --input-background: #333; | ||
| --input-background-disabled: #444; | ||
| --label-color: #4caf50; | ||
| --radio-checkbox-accent: #4caf50; | ||
| --button-background: #4caf50; | ||
| --button-background-hover: #388e3c; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #4caf50; | ||
| --input-border-color-focus: #388e3c; | ||
| --secondary-text-color: #b3b3b3; | ||
| } | ||
| .purple-theme { | ||
| --background-dark: #121212; | ||
| --background-light: #f3e5f5; | ||
| --text-light: #4a148c; | ||
| --border-color: #333; | ||
| --input-background: #ffffff; | ||
| --input-background-disabled: #f1f8e9; | ||
| --label-color: #9c27b0; | ||
| --radio-checkbox-accent: #9c27b0; | ||
| --button-background: #9c27b0; | ||
| --button-background-hover: #7b1fa2; | ||
| --button-text-color: #ffffff; | ||
| --input-border-color: #9c27b0; | ||
| --input-border-color-focus: #7b1fa2; | ||
| --secondary-text-color: #880e4f; | ||
| } | ||
| .midnight-blush-theme { | ||
| --background-light: #05051e; | ||
| --background-dark: #05051e; | ||
| --text-light: #ffbd7a; | ||
| --text-dark: #ffffff; | ||
| --border-color: #ffbd7a; /* #9e7aff;*/ | ||
| --input-background: #ffffff; | ||
| --input-background-disabled: #d9d9d9; | ||
| --label-color: #9e7aff; | ||
| --radio-checkbox-accent: #fe8bbb; | ||
| --button-background: #ffbd7a; | ||
| --button-background-hover: #9e7aff; /*#fe8bbb*/; | ||
| --button-text-color: #05051e; | ||
| --input-border-color: #9e7aff; | ||
| --input-border-color-focus: #fe8bbb; | ||
| --secondary-text-color: #ffbd7a; | ||
| --dropdown-option-text-color: #05051e; | ||
| --legend-text-color: #9e7aff; | ||
| } | ||
| #formique { | ||
| max-width: 600px; /* Limit the width for better mobile view */ | ||
| /* Formique Container */ | ||
| .formique { | ||
| max-width: 600px; | ||
| margin: auto; | ||
| padding: 1rem; | ||
| background-color: var(--background-light); /* Slightly lighter dark background */ | ||
| background: var(--background-light); | ||
| border-radius: 8px; | ||
| color: var(--text-light); /* Light text color for readability */ | ||
| font-family: Arial, sans-serif; /* Font for the form */ | ||
| color: var(--text-light); | ||
| /*font-family: 'Montserrat', sans-serif;*/ | ||
| font-family: 'Lato', sans-serif; | ||
| margin-bottom: 200px; | ||
| border: 1px solid var(--border-color); | ||
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.7); | ||
| } | ||
| /* Input Block Styling */ | ||
| #formique .input-block { | ||
| .formique .input-block { | ||
| margin-bottom: 1rem; | ||
| position: relative; | ||
| } | ||
| #formique .input-block label { | ||
| .formique .input-block label { | ||
| display: block; | ||
| margin-bottom: 0.5rem; | ||
| color: var(--label-color); /* Orange color for labels */ | ||
| color: var(--label-color); | ||
| } | ||
| #formique .input-block .form-input, | ||
| #formique .input-block .form-control { | ||
| .formique .input-block .form-input, | ||
| .formique .input-block .form-control { | ||
| width: 100%; | ||
| padding: 0.75rem; | ||
| border: 1px solid var(--border-color); | ||
| border-radius: 4px; | ||
| background-color: var(--input-background); /* Background for inputs */ | ||
| padding: 0.75rem 1rem 0.75rem 2.5rem; | ||
| border: none; | ||
| border-bottom: 1px solid var(--border-color); | ||
| border-radius: 0; | ||
| background-color: var(--background-light); | ||
| color: var(--text-light); | ||
| box-sizing: border-box; | ||
| font-size: 1rem; | ||
| } | ||
| #formique .input-block .form-input:disabled { | ||
| background-color: var(--input-background-disabled); /* Background for disabled inputs */ | ||
| cursor: not-allowed; | ||
| } | ||
| /* Radio Group Styling */ | ||
| #formique .radio-group { | ||
| margin-bottom: 1rem; | ||
| .formique .input-block .form-input:focus { | ||
| outline: none; | ||
| border-bottom: 1px solid var(--button-background); | ||
| } | ||
| #formique .radio-group legend { | ||
| margin-bottom: 0.5rem; | ||
| font-weight: bold; | ||
| color: var(--label-color); /* Orange color for legend */ | ||
| } | ||
| #formique .radio-group div { | ||
| margin-bottom: 0.5rem; | ||
| .formique .input-block .form-input-icon { | ||
| position: absolute; | ||
| left: 1rem; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| color: var(--label-color); | ||
| } | ||
| #formique .radio-group .form-radio-input { | ||
| margin-right: 0.5rem; | ||
| accent-color: var(--radio-checkbox-accent); /* Orange color for radio buttons */ | ||
| /* Input Disabled */ | ||
| .formique .input-block .form-input:disabled { | ||
| background-color: var(--input-background-disabled); | ||
| cursor: not-allowed; | ||
| border-bottom: 1px solid var(--label-color); | ||
| } | ||
| /* Checkbox Group Styling */ | ||
| #formique .checkbox-group { | ||
| /* Fieldset Styling for Radio, Checkbox, and Select Groups */ | ||
| .formique .radio-group, | ||
| .formique .checkbox-group, | ||
| .formique .form-select { | ||
| margin-bottom: 1rem; | ||
| padding: 1rem 0; | ||
| border-radius: 8px; | ||
| background-color: transparent; | ||
| border: 1px solid var(--border-color); | ||
| } | ||
| #formique .checkbox-group legend { | ||
| /* Radio and Checkbox Group Styling */ | ||
| .formique .radio-group legend, | ||
| .formique .checkbox-group legend { | ||
| margin-bottom: 0.5rem; | ||
| font-weight: bold; | ||
| color: var(--label-color); /* Orange color for legend */ | ||
| color: var(--label-color); | ||
| } | ||
| #formique .checkbox-group div { | ||
| .formique .radio-group div, | ||
| .formique .checkbox-group div { | ||
| margin-bottom: 0.5rem; | ||
| display: flex; | ||
| align-items: center; | ||
| } | ||
| #formique .checkbox-group .form-checkbox-input { | ||
| .formique .radio-group .form-radio-input, | ||
| .formique .checkbox-group .form-checkbox-input { | ||
| margin-right: 0.5rem; | ||
| accent-color: var(--radio-checkbox-accent); /* Orange color for checkboxes */ | ||
| accent-color: var(--radio-checkbox-accent); | ||
| } | ||
| /* Select Styling */ | ||
| #formique .form-select { | ||
| .formique .form-select { | ||
| margin-bottom: 1rem; | ||
| padding: 1rem 2rem; | ||
| border-radius: 8px; | ||
| background-color: transparent; | ||
| border: 1px solid var(--border-color); /* Reduced thickness */ | ||
| } | ||
| #formique .form-select label { | ||
| .formique .form-select legend { | ||
| color: var(--legend-text-color); | ||
| } | ||
| .formique .form-select select option { | ||
| background-color: #000!important; | ||
| } | ||
| /* Label for Select */ | ||
| .formique .form-select label { | ||
| display: block; | ||
| margin-bottom: 0.5rem; | ||
| color: var(--label-color); /* Orange color for labels */ | ||
| color: var(--label-color); | ||
| } | ||
| #formique .form-select .form-select-input { | ||
| /* The Select Input Styling */ | ||
| .formique .form-select select { | ||
| width: 100%; | ||
| padding: 0.75rem; | ||
| border: 1px solid var(--border-color); | ||
| border-radius: 4px; | ||
| background-color: var(--input-background); /* Background for selects */ | ||
| color: var(--text-light); | ||
| padding: 0.75rem 1rem 0.75rem 2.5rem; | ||
| border: none; | ||
| background-color: transparent; | ||
| color: var(--legend-text-color); | ||
| font-size: 1rem; | ||
| box-sizing: border-box; | ||
| } | ||
| /* Submit Button Styling */ | ||
| #formique .form-submit-btn { | ||
| /* Focus Effect for Select */ | ||
| .formique .form-select select:focus { | ||
| outline: none; | ||
| } | ||
| /* Icon for Select, Radio, and Checkbox Inputs */ | ||
| .formique .radio-group .form-radio-input + label, | ||
| .formique .checkbox-group .form-checkbox-input + label { | ||
| margin-left: 0.5rem; | ||
| } | ||
| .formique .radio-group label, | ||
| .formique .checkbox-group label { | ||
| color: var(--label-color); | ||
| font-weight: normal; | ||
| } | ||
| .formique .form-select .form-select-icon { | ||
| position: absolute; | ||
| left: 1rem; | ||
| top: 50%; | ||
| transform: translateY(-50%); | ||
| color: var(--label-color); | ||
| } | ||
| .formique .radio-group div, | ||
| .formique .checkbox-group div { | ||
| padding-left: 2.5rem; | ||
| } | ||
| .formique .form-submit-btn { | ||
| padding: 0.75rem 1.5rem; | ||
| border: none; | ||
| border: 1px solid var(--background-light); | ||
| border-radius: 4px; | ||
| background-color: var(--button-background); /* Orange background */ | ||
| color: var(--background-dark); /* Dark text color for contrast */ | ||
| background-color: var(--button-background); | ||
| color: var(--button-text-color); | ||
| font-size: 1rem; | ||
@@ -198,16 +371,6 @@ cursor: pointer; | ||
| #formique .form-submit-btn:hover { | ||
| background-color: var(--button-background-hover); /* Darker orange on hover */ | ||
| .formique .form-submit-btn:hover { | ||
| background-color: var(--button-background-hover); | ||
| color: var(--button-text-color); | ||
| } | ||
| /* General Styles */ | ||
| body { | ||
| background-color: var(--background-dark); /* Dark background for the page */ | ||
| color: var(--text-light); /* Light text color for readability */ | ||
| font-family: Arial, sans-serif; | ||
| margin: 0; | ||
| padding: 0; | ||
| } | ||
+4
-4
| { | ||
| "name": "formique-css", | ||
| "version": "1.0.5", | ||
| "description": "Formique CSS styles", | ||
| "version": "1.0.6", | ||
| "description": "Formique JS form builder CSS styles", | ||
| "main": "formique.css", | ||
@@ -10,4 +10,4 @@ "files": [ | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC" | ||
| "author": "Gugulethu Nyoni", | ||
| "license": "MIT" | ||
| } |
+240
-91
| # Formique | ||
| <!-- <img src="https://github.com/thincmedia/anyGridJs/blob/main/images/anyGridJs_Example.png" alt="anyGridJs Example"> --> | ||
| <img src="https://github.com/Gugulethu-Nyoni/formique/blob/main/images/formique-js-form-builder-anyframework.png" alt="Formique JS Form Builder Example"> | ||
| Formique: A lightweight, declarative JavaScript syntax library for generating WCAG acceAccessibility compliant forms. Suited for vanilla js and Semantq JS framework. Formique simplifies the process of creating and managing forms with a variety of input types, built-in validation, and customizable attributes. Open-source & MIT licensed. | ||
| Formique is a robust and elegant WCAG and ARIA compliant form-building library tailored for JavaScript enthusiasts. It supports a wide array of input types, features JS-driven themes, and offers advanced functionalities like nested conditional logic and dynamic dropdowns. Highly customizable and extensible, Formique is built for the Semantq JS Framework but seamlessly integrates with Vanilla JS, React, Vue, Angular, and Svelte. | ||
| ## Accessibility Compliance | ||
| Formique is Open-source & MIT licensed. | ||
| Formique is designed with a laser focus on usability and accessibility, ensuring that the generated form HTML markup meets the highest standards of web accessibility, such as the Web Content Accessibility Guidelines (WCAG) 2.1. | ||
| ## Accessibility Compliance - | ||
| Formique is designed with a laser focus on WAI-ARIA and WCAG usability and accessibility, ensuring that the generated form HTML markup meets the highest standards of web accessibility. | ||
| With minimal declarative form input definitions, Formique takes care of the rest to ensure the final markup is comprehensive enough to meet [official](https://www.w3.org/WAI/tutorials/forms/) usability and accessibility standards. | ||
@@ -20,18 +23,28 @@ | ||
| - Declarative Syntax: Define forms using a simple and intuitive schema. | ||
| - Wide Range of Inputs: Supports text, email, number, password, date, time, file uploads, and more. | ||
| - Validation and Attributes: Easily specify validation rules and attributes for each form field. | ||
| - Dynamic Form Generation: Generate forms dynamically based on your schema. | ||
| - Framework Agnostic: Currently works Semantq and vanilla JS. | ||
| - **Declarative Syntax:** Define forms using a simple and intuitive schema. | ||
| - **Wide Range of Inputs:** Supports text, email, number, password, date, time, file uploads, and more. | ||
| - **Validation and Attributes:** Easily specify validation rules and attributes for each form field. | ||
| - **Dynamic Form Generation:** Generate forms dynamically based on your schema. | ||
| - **Framework Agnostic:** Currently works with Semantq and vanilla JS. (More frameworks to be added) | ||
| - **Accessibility and Usability Compliant:** Formique yields form markup compliant with WCAG. | ||
| - **Mobile Responsive:** Forms are mobile responsive out of the box. | ||
| - **Nested Dynamic Conditional Logic:** Implement complex conditional logic to show or hide form fields based on user input. | ||
| - **Dynamic Dropdowns:** Create dropdowns whose options change dynamically based on other field selections. | ||
| - **JavaScript-Driven Themes:** Apply themes dynamically using JavaScript for a customizable user interface. | ||
| - **WAI-ARIA and WCAG-Compliant HTML:** Ensure all form elements are accessible and meet WCAG standards. | ||
| - **Progressive Enhancement:** Forms function with or without JavaScript, ensuring accessibility and functionality across all environments. | ||
| ## Why Choose Formique? | ||
| - **Vanilla JS:** No dependencies; works seamlessly with vanilla JS and Semantq JS framework. (More frameworks to be added) | ||
| - **Lightweight:** Minimal footprint optimized for performance. | ||
| - **Customizable:** Adapt the library to fit your project's unique needs for functionality and style. | ||
| - **Declarative:** Write your forms in JavaScript and define forms with a concise schema for better readability and maintainability. | ||
| - **Usability and Accessibility Compliant:** You just need to focus on defining form fields data. Formique handles WCAG compliance for you. | ||
| - **Mobile Responsive:** Formique forms are mobile responsive out of the box. | ||
| - **Dynamic Features:** Implement nested conditional logic, dynamic dropdowns, and JavaScript-driven themes to enhance user experience. | ||
| - **Progressive Enhancement:** Forms are designed to function with or without JavaScript, ensuring broad compatibility. | ||
| ## Why Choose Formique? | ||
| - Vanilla JS: No dependencies; works seamlessly with vanilla JS and Semantq JS framework.(More frameworks to be added) | ||
| - Lightweight: Minimal footprint optimized for performance. | ||
| - Customizable: Adapt the library to fit your project's unique needs. | ||
| - Declarative: Write your forms in JavaScript and define forms with a concise schema for better readability and maintainability. | ||
| ## Form Input Types Covered | ||
@@ -59,2 +72,3 @@ | ||
| - Select (Single & Multiple): ```html <select> ``` | ||
| - Dynamic Single Select: Displays a single-select dropdown of subcategories based on a selected category. For example, it dynamically shows a dropdown of states when a country is selected from a list of countries: ```html <select> ``` | ||
| - Submit: ```html <input type="submit"> ``` | ||
@@ -70,4 +84,3 @@ | ||
| - Input validation (optional) | ||
| - Input attributes (optional) | ||
| - Binding syntax (optional) | ||
| - Input attributes (optional, including binding attribute (optional) | ||
| - Options (applicable to single select, multiple select, radio and check box inputs) | ||
@@ -83,9 +96,17 @@ | ||
| `{ 'text', 'firstname', 'First Name' }` | ||
| `['text', 'firstname', 'First Name' ]` | ||
| In the example above: | ||
| - The first item (text) defines the type of the input - this will yield: `<input type="text"` | ||
| - The second item (firstname) defines the name value of the input - this will yield: `<input name="firstname"` | ||
| - The first item (text) defines the type of the input - this will yield: `<input type="text" ...` | ||
| - The second item (firstname) defines the name value of the input - this will yield: `<input name="firstname" ...` | ||
| - The third item (First Name) defines the Label value- this will yield: `<label for="firstname">First Name</label>` | ||
| - Final html output will be: | ||
| ```html | ||
| <div class="input-block" id="firstname-block"> | ||
| <label for="firstname">First Name</label> | ||
| <input type="text" name="firstname" id="firstname" class="form-input" placeholder="First | ||
| Name"> | ||
| </div> | ||
| ``` | ||
@@ -97,5 +118,5 @@ | ||
| - Example: `required: true` | ||
| - **MinLength**: Specifies the minimum number of characters allowed. | ||
| - **Minlength**: Specifies the minimum number of characters allowed. | ||
| - Example: `minlength: 5` | ||
| - **MaxLength**: Specifies the maximum number of characters allowed. | ||
| - **Maxlength**: Specifies the maximum number of characters allowed. | ||
| - Example: `maxlength: 50` | ||
@@ -105,5 +126,13 @@ - **Pattern**: A regex pattern the input must match. | ||
| **Formique will filter out any invalid validation defined and throw warnings on the browser console.E.g. you define min and max validations for a text field Formique will filter these out.** | ||
| ### Number Field Specific Validation: | ||
| - **Min**: Specifies the minimum numeric value allowed. | ||
| - Example: `min: 1` | ||
| - **Max**: Specifies the maximum numeric value allowed. | ||
| - Example: `max: 100` | ||
| - **Step**: Specifies the increment step for numeric values. | ||
| - Example: `step: 0.01` (for decimal increments) | ||
| **Formique will filter out any invalid validation defined and throw warnings on the browser console.E.g. when you define min and max validations (instead of minlength and maxlength) for a text field, Formique will filter these out.** | ||
| ## Input Attributes | ||
@@ -114,5 +143,9 @@ - **Attributes**: Object specifying additional attributes like `id`, `class`, `style`, etc. | ||
| ## Binding | ||
| - **Binding**: Optional binding syntax for dynamic data. It can use `bind:value` or `::inputName`. | ||
| - Example: `'bind:value'` or `'::inputName'` - inputName must be the value defined as the input name (second item) in the input definition object. | ||
| - **Binding:** Optional binding syntax for dynamic data. The binding object has been moved to the attributes object, allowing for inclusion directly within the attributes. Two syntax formats are supported: | ||
| - `binding: '::nameOfField'` | ||
| - `binding: 'bind-value'` | ||
| - Example: `'::inputName'` or `'bind-value'` | ||
| *Note:* `inputName` must be the value defined as the input name (the second item) in the input definition object. | ||
| ## Options | ||
@@ -132,33 +165,43 @@ - **Options**: For singleSelect,, multipleSelect, radio, and checkbox inputs. This is an array of options, each with a `value` and `label`. | ||
| There are two ways to install and use Formique in your project: | ||
| There are two primary ways to install and use Formique in your project: | ||
| ## Option A: Use Formique as a Universal Module Definition (UMD) Module | ||
| ### Option A: Use Formique in a Browser Context (No Bundler Required) | ||
| 1. Include the CSS and JavaScript in the head section of your HTML file: | ||
| 1. **Include the CSS** in the head section of your HTML file: | ||
| ```html | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css"> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css" formique-style> | ||
| ``` | ||
| 2. Insert the js script tag just before the closing tag ```html </body> ``` of your html file. | ||
| 2. **Include the JavaScript** before the closing `</body>` tag of your HTML file: | ||
| ```html | ||
| <script src="https://cdn.jsdelivr.net/npm/formique@1.0.1/formique.umd.js"></script> | ||
| <script src="https://cdn.jsdelivr.net/npm/formique@1.0.1/formique.mjs.js"></script> | ||
| ``` | ||
| ## Usage Example | ||
| 1. Define the form container somewhere in the html body: | ||
| ### Usage Example: | ||
| ```html | ||
| <div id="formique"></div> | ||
| ``` | ||
| 1. Define the form container somewhere in the HTML body: | ||
| ```html | ||
| <div id="formique"></div> | ||
| ``` | ||
| 2. Define your form parameters (formParams), form schema (formSchema) and then initialize Formique in script which should go below this script tag: | ||
| Alternatively, you can use a different container ID by setting `containerId: 'someelementid'` in the `formSettings` object. | ||
| 2. Define your `formParams`, `formSchema`, and initialize Formique in a `<script>` block (placed below the previous script tag): | ||
| ```html | ||
| <script src="https://cdn.jsdelivr.net/npm/formique@1.0.1/formique.umd.js"></script> | ||
| ```html | ||
| <script> | ||
| const formSchema = [ | ||
| ['text', 'name', 'Name', { required: true }, {}], | ||
| ['email', 'email', 'Email', { required: true }, {}], | ||
| ['singleSelect', 'diet', 'Dietary Requirements', { required: true }, {}, [ | ||
| { value: 'gluten-free', label: 'Gluten-free' }, | ||
| { value: 'vegetarian', label: 'Vegetarian' }, | ||
| // Additional options here... | ||
| ]], | ||
| ['submit', 'submitButton', 'Submit'] | ||
| ]; | ||
| <script> | ||
| const formParams = { | ||
@@ -169,41 +212,24 @@ method: 'post', | ||
| class: 'form', | ||
| semantq: true, | ||
| style: 'width: 100%; font-size: 14px;' | ||
| }; | ||
| const formSchema = [ | ||
| ['text', 'name', 'Name', { required: true }, {}, ''], | ||
| ['email', 'email', 'Email', { required: true }, {}, ''], | ||
| [ | ||
| 'singleSelect', 'diet', 'Dietary Requirements', {required: true}, {}, '', | ||
| [ | ||
| {value: 'gluten-free', label: 'Gluten-free'}, | ||
| {value: 'dairy-free', label: 'Dairy-free'}, | ||
| {value: 'keto', label: 'Ketogenic'}, | ||
| {value: 'low-carb', label: 'Low-carb'}, | ||
| {value: 'pescatarian', label: 'Pescatarian'}, | ||
| {value: 'halal', label: 'Halal'}, | ||
| {value: 'kosher', label: 'Kosher'}, | ||
| {value: 'vegetarian', label: 'Vegetarian'}, | ||
| {value: 'lacto-ovo-vegetarian', label: 'Lacto-ovo-vegetarian'}, | ||
| {value: 'raw-food', label: 'Raw food'}, | ||
| {value: 'macrobiotic', label: 'Macrobiotic'}, | ||
| {value: 'flexitarian', label: 'Flexitarian'} | ||
| ] | ||
| ], | ||
| ['submit', 'submitButton', 'Submit', {}, {}, ''] | ||
| ]; | ||
| const formSettings = { | ||
| requiredFieldIndicator: true, | ||
| framework: 'semantq', | ||
| placeholders: true, | ||
| containerid: 'form-div' | ||
| }; | ||
| // Initialize the form | ||
| const form = new Formique(formSchema, formParams, formSettings); | ||
| </script> | ||
| ``` | ||
| (function(formParams, formSchema) { | ||
| const form = new Formique(formParams, formSchema); | ||
| const formHTML = form.renderFormHTML(); | ||
| })(formParams, formSchema); | ||
| **Note:** You can also use this instantiation with just the `formSchema`, leaving out the `formParams` and `formSettings`. This will apply the default dark theme and render the form inputs without the surrounding `<form>` element. | ||
| </script> | ||
| ``` | ||
| --- | ||
| ## Option B: Use Formique as an ESM Module | ||
| ### Option B: Use Formique in a Node.js (Bundler) Environment | ||
| 1. Install Formique via npm: | ||
| 1. **Install Formique via npm:** | ||
@@ -214,6 +240,33 @@ ```bash | ||
| 2. **Import and Use Formique in Your JavaScript File:** | ||
| ```javascript | ||
| import Formique from 'formique'; | ||
| const formSchema = [ | ||
| // Define your schema as shown above... | ||
| ]; | ||
| const formParams = { | ||
| // Optional parameters... | ||
| }; | ||
| const formSettings = { | ||
| // Optional settings... | ||
| }; | ||
| const form = new Formique(formSchema, formParams, formSettings); | ||
| ``` | ||
| --- | ||
| ### Other Formats | ||
| Formique is also available in additional formats like **ESM (ES Modules)** and **IIFE (Immediately Invoked Function Expression)** for specific use cases. For most projects, we recommend using **UMD** for browser contexts and **ESM** for Node.js environments. Refer to the Formique CDN for all available formats. | ||
| 2. Include the CSS and import Formique in the head section of your HTML file: | ||
| ```html | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css"> | ||
| <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/formique-css@1.0.1/formique.min.css" formique-style> | ||
| ``` | ||
@@ -242,6 +295,6 @@ 3. Define form container somewhere in the html body: | ||
| const formSchema = [ | ||
| ['text', 'name', 'Name', { required: true }, {}, ''], | ||
| ['email', 'email', 'Email', { required: true }, {}, ''], | ||
| ['text', 'name', 'Name', { required: true }], | ||
| ['email', 'email', 'Email', { required: true }], | ||
| [ | ||
| 'singleSelect', 'diet', 'Dietary Requirements', {required: true}, {}, '', | ||
| 'singleSelect', 'diet', 'Dietary Requirements', {required: true}, {}, | ||
| [ | ||
@@ -262,7 +315,7 @@ {value: 'gluten-free', label: 'Gluten-free'}, | ||
| ], | ||
| ['submit', 'submitButton', 'Submit', {}, {}, ''], | ||
| ['submit', 'submitButton', 'Submit'], | ||
| ]; | ||
| const form = new Formique(formParams, formSchema); | ||
| const formHTML = form.renderFormHTML(); | ||
@@ -288,3 +341,2 @@ </script> | ||
| { value: "John", id: 'firstNameInput', class: 'form-input', style: 'width: 100%;', oninput: "incrementer()" }, // Attributes | ||
| '::firstName' // Binding syntax | ||
| ], | ||
@@ -298,4 +350,3 @@ | ||
| { required: true }, // Validation options | ||
| { id: 'websiteUrlInput', class: 'form-control', style: 'width: 100%;' }, // Attributes | ||
| 'bind:value' // Binding syntax | ||
| { id: 'websiteUrlInput', class: 'form-control', style: 'width: 100%;', binding: 'bind:value' } | ||
| ], | ||
@@ -309,4 +360,3 @@ | ||
| { required: true }, // Validation options | ||
| { id: 'genderRadio', class: 'form-radio-input', style: 'margin-left: 1rem;', onchange: 'actioner()' }, // Attributes | ||
| '::gender', // Binding syntax | ||
| { id: 'genderRadio', class: 'form-radio-input', style: 'margin-left: 1rem;', onchange: 'actionFunction()' } | ||
| [ | ||
@@ -325,4 +375,3 @@ { value: 'male', label: 'Male' }, // Options | ||
| { required: true }, // Validation options | ||
| { id: 'preferencesCheckbox', class: 'form-checkbox-input', style: 'margin-left: 1rem;', onchange: 'submit' }, // Attributes | ||
| '::preferences', // Binding syntax | ||
| { id: 'preferencesCheckbox', binding: '::preferences', class: 'form-checkbox-input', style: 'margin-left: 1rem;', onchange: 'submit' } | ||
| [ | ||
@@ -341,4 +390,3 @@ { value: 'news', label: 'Newsletter' }, // Options | ||
| { required: true }, // Validation options | ||
| { id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'trigger' }, // Attributes | ||
| '::colors', // Binding syntax | ||
| { id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'trigger' }, // the onchange: 'trigger' format works with (framework: semantq) set in your formSettings object so that the syntax can be transformed as per framework specs | ||
| [ | ||
@@ -357,4 +405,3 @@ { value: 'red', label: 'Red' }, // Options | ||
| { required: true, min: 2, max: 3 }, // Validation options | ||
| { id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'alerter' }, // Attributes | ||
| '::colors', // Binding syntax | ||
| { id: 'colorsSelect', class: 'form-select-input', style: 'margin-left: 1rem;', onchange: 'alerter' } | ||
| [ | ||
@@ -373,4 +420,4 @@ { value: 'red', label: 'Red' }, // Options | ||
| 'Submit', | ||
| { required: true }, // Validation options | ||
| { id: 'submitBtn', class: 'form-submit-btn', style: 'margin-top: 1rem;' } // Attributes | ||
| {}, // Validation options | ||
| { id: 'submitBtn', class: 'form-submit-btn', style: 'margin-top: 1rem; width: 100%;' } | ||
| ] | ||
@@ -413,3 +460,3 @@ ]; | ||
| novalidate: true, // Disable form validation | ||
| accept_charset: 'UTF-8' // this will be transformed to: accept-charset: 'UTF-8' Character set for form data | ||
| accept_charset: 'UTF-8' // this will be transformed to: accept-charset: 'UTF-8' Character set for form data | ||
| }; | ||
@@ -607,2 +654,104 @@ ``` | ||
| ## Dynamic Drop-Down Schema | ||
| The `dynamicSingleSelect` input type in Formique is used for generating dynamic dropdowns based on predefined options. It allows you to define multi-level select options (e.g., categories and subcategories) that change based on user selections. Below is an example of the schema format for implementing dynamic drop-downs. | ||
| ### Common Use Cases: | ||
| - **Country-State Dropdowns**: A common implementation where selecting a country dynamically updates the list of states/provinces. | ||
| - **Product Categories**: A dropdown where the first selection (e.g., a product category) updates the second dropdown to show relevant product subcategories. | ||
| - **Job Roles & Departments**: Selecting a department dynamically shows job roles related to that department (e.g., selecting "IT" shows job roles like "Software Developer", "Network Engineer", etc.). | ||
| - **Course & Subjects**: In educational systems, choosing a course can display relevant subjects or modules available for that course. | ||
| - **Location-Based Services**: When selecting a country or city, a second dropdown can list local services or offices relevant to the location chosen. | ||
| ### Dynamic Drop Downs Schema Definition: | ||
| The code below goes into your | ||
| ```javascript | ||
| [ | ||
| 'dynamicSingleSelect', // Input type (required) | ||
| 'languages', // Field name (required) | ||
| 'Programming Scope-Programming Languages', // Labels for both primary drop down and secondary (dynamic) drop down seperated by a hyphen - e.g. Country-States | ||
| { required: true }, // Validation rules (optional) but the curly braces {} must always be included | ||
| {}, // Field attributes (optional) but the curly braces {} must always be included | ||
| // Dropdown Options | ||
| [ | ||
| { | ||
| id: 'frontend', // Option group ID (required) | ||
| label: 'Front End', // Option group label (required) | ||
| options: [ // List of options (required) | ||
| { value: 'javascript', label: 'JavaScript' }, | ||
| { value: 'html', label: 'HTML' }, | ||
| { value: 'css', label: 'CSS' }, | ||
| { value: 'typescript', label: 'TypeScript' }, | ||
| { value: 'semantq', label: 'Semantq' }, | ||
| { value: 'svelte', label: 'Svelte' }, | ||
| { value: 'vue', label: 'Vue' }, | ||
| { value: 'react', label: 'React' }, | ||
| { value: 'angular', label: 'Angular' }, | ||
| ] | ||
| }, | ||
| { | ||
| id: 'backend', // Option group ID (required) | ||
| label: 'Back End', // Option group label (required) | ||
| options: [ // List of options (required) | ||
| { value: 'nodejs', label: 'Node.js' }, | ||
| { value: 'python', label: 'Python' }, | ||
| { value: 'java', label: 'Java' }, | ||
| { value: 'php', label: 'PHP' }, | ||
| { value: 'ruby', label: 'Ruby' }, | ||
| { value: 'csharp', label: 'C#' }, | ||
| { value: 'golang', label: 'Go' } | ||
| ] | ||
| } | ||
| ] | ||
| ] | ||
| ``` | ||
| ## Nested Conditionality Logic - Schema Definition | ||
| Formique allows for dynamic form generation with powerful conditional logic based on the values of other form fields. This allows you to create forms where the options in one field depend on the selection made in another field. | ||
| ### Key Features: | ||
| - **Dynamic Field Display**: Show or hide fields based on previous selections. | ||
| - **Conditional Logic**: Use conditions such as specific values in other fields to control the availability of options or visibility of fields. | ||
| - **Multiple Dependencies**: Fields can have more than one dependents | ||
| ### Schema Definition Example: | ||
| The following schema demonstrates how to implement dynamic dropdowns with nested conditional logic in Formique. | ||
| ```js | ||
| [ | ||
| // Role field - Single Select (required) | ||
| ['singleSelect', 'role', 'Role', { required: true }, { dependents: ['topic', 'mode'] }, | ||
| // in the attributes object of the parent field add dependents (array) by field names to the dependents: item | ||
| [ | ||
| { value: 'conference attendee', label: 'Conference Attendee' }, | ||
| { value: 'conference presenter', label: 'Conference Presenter' } | ||
| ] | ||
| ], | ||
| // Topic field - Text input (dependent on 'role' being 'conference presenter') | ||
| ['text', 'topic', 'Topic', {}, { dependsOn: 'role', condition: 'conference presenter' }], | ||
| // in the attributes object of the child field add the dependsOn: 'role' item where the key is dependsOn: and the value is name of the parent field: e.g. 'role in this case' | ||
| // also add the condition this way: condition: 'conference presenter' | ||
| // you can use the string 'conference presenter' as the condition to be met | ||
| // so this if the user select Conference Presenter in the role field - then dependents of that field (mode and topic) will be displayed. If the selected is changed to something else that doesn't meet the defined condtion - the dependents will be hidden. | ||
| // Mode field - Single Select (required, dependent on 'role' being 'conference presenter') | ||
| ['singleSelect', 'mode', 'Mode', { required: true }, { dependsOn: 'role', condition: (value) => value === 'conference presenter' }, // you can use an arrow function to evaluate the condition - this is useful for more comprex evaluations | ||
| [ | ||
| { value: 'physical', label: 'Physical' }, | ||
| { value: 'virtual', label: 'Virtual' } | ||
| ] | ||
| ] | ||
| ] | ||
| ``` | ||
| ## Styling the Form | ||
@@ -609,0 +758,0 @@ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
39109
47.5%317
85.38%1
-50%769
24.03%2
Infinity%