diff options
| author | Danilo M. <danix@danix.xyz> | 2026-04-17 15:51:27 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-04-17 15:51:27 +0200 |
| commit | e2737855a3d3544e7a44ba8384be1e206e96c40f (patch) | |
| tree | 5635887371b871f56303e46b5cda75de7ff0b85c /FORM-COMPONENT-GUIDE.md | |
| parent | d46c976137540831468ba5811184356cf1cdf0c1 (diff) | |
| download | danixxyz-e2737855a3d3544e7a44ba8384be1e206e96c40f.tar.gz danixxyz-e2737855a3d3544e7a44ba8384be1e206e96c40f.zip | |
cleanup of the working tree. Created docs/{policies,reports} folders to keep documentation organized
Diffstat (limited to 'FORM-COMPONENT-GUIDE.md')
| -rw-r--r-- | FORM-COMPONENT-GUIDE.md | 646 |
1 files changed, 0 insertions, 646 deletions
diff --git a/FORM-COMPONENT-GUIDE.md b/FORM-COMPONENT-GUIDE.md deleted file mode 100644 index a916152..0000000 --- a/FORM-COMPONENT-GUIDE.md +++ /dev/null @@ -1,646 +0,0 @@ -# Form Component Guide - -Quick reference for all form components with usage examples. - ---- - -## Table of Contents - -1. [Input Fields](#input-fields) -2. [Textareas](#textareas) -3. [Select Dropdowns](#select-dropdowns) -4. [Checkboxes](#checkboxes) -5. [Radio Buttons](#radio-buttons) -6. [Form Groups](#form-groups) -7. [Form Layouts](#form-layouts) -8. [Modals](#modals) -9. [Notifications](#notifications) -10. [Tooltips](#tooltips) - ---- - -## Input Fields - -### Basic Input - -```html -<input type="text" class="form-input" placeholder="Enter text..."> -``` - -### Email Input with Validation - -```html -<div class="form-group"> - <label for="email">Email</label> - <input type="email" id="email" class="form-input" placeholder="user@example.com"> -</div> -``` - -### Password Input - -```html -<div class="form-group"> - <label for="password">Password</label> - <input type="password" id="password" class="form-input" placeholder="••••••"> - <div class="form-group-help">Must be at least 8 characters</div> -</div> -``` - -### Number Input - -```html -<div class="form-group"> - <label for="quantity">Quantity</label> - <input type="number" id="quantity" class="form-input" value="1" min="1"> -</div> -``` - -### Disabled Input - -```html -<input type="text" class="form-input" value="Cannot edit" disabled> -``` - -### Input with Error - -```html -<div class="form-group error"> - <label for="username">Username</label> - <input type="text" id="username" class="form-input error" value="invalid"> - <div class="form-error">Username must be 3-20 characters</div> -</div> -``` - ---- - -## Textareas - -### Basic Textarea - -```html -<textarea class="form-textarea" placeholder="Enter message..."></textarea> -``` - -### Textarea with Label and Help Text - -```html -<div class="form-group"> - <label for="bio">Bio</label> - <textarea id="bio" class="form-textarea" placeholder="Tell us about yourself..."></textarea> - <div class="form-group-help">Maximum 500 characters</div> -</div> -``` - -### Auto-Expanding Textarea - -```html -<div class="form-group"> - <label for="auto-textarea">Auto-expanding Textarea</label> - <textarea - id="auto-textarea" - class="form-textarea auto-expand" - placeholder="Grows as you type..." - @input="autoExpandTextarea($event)"> - </textarea> -</div> -``` - ---- - -## Select Dropdowns - -### Basic Select - -```html -<select class="form-select"> - <option>Choose an option...</option> - <option>Option 1</option> - <option>Option 2</option> - <option>Option 3</option> -</select> -``` - -### Select with Label - -```html -<div class="form-group"> - <label for="country">Country</label> - <select id="country" class="form-select"> - <option>Select a country...</option> - <option value="us">United States</option> - <option value="uk">United Kingdom</option> - <option value="de">Germany</option> - </select> -</div> -``` - -### Multi-Select - -```html -<select class="form-select" multiple> - <option>Python</option> - <option>JavaScript</option> - <option>Go</option> - <option>Rust</option> -</select> -``` - ---- - -## Checkboxes - -### Single Checkbox - -```html -<label class="flex items-center gap-3 cursor-pointer"> - <input type="checkbox" class="form-checkbox"> - <span>I agree to the terms and conditions</span> -</label> -``` - -### Checkbox Group - -```html -<fieldset> - <legend class="font-semibold">Select your interests</legend> - <div class="space-y-2 mt-3"> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="checkbox" class="form-checkbox" name="interests" value="tech"> - <span>Technology</span> - </label> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="checkbox" class="form-checkbox" name="interests" value="design"> - <span>Design</span> - </label> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="checkbox" class="form-checkbox" name="interests" value="business"> - <span>Business</span> - </label> - </div> -</fieldset> -``` - -### Disabled Checkbox - -```html -<label class="flex items-center gap-3 cursor-pointer opacity-50"> - <input type="checkbox" class="form-checkbox" disabled> - <span>This option is not available</span> -</label> -``` - ---- - -## Radio Buttons - -### Radio Button Group - -```html -<fieldset> - <legend class="font-semibold">Choose an option</legend> - <div class="space-y-2 mt-3"> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="radio" name="option" class="form-radio" value="a"> - <span>Option A</span> - </label> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="radio" name="option" class="form-radio" value="b"> - <span>Option B</span> - </label> - <label class="flex items-center gap-3 cursor-pointer"> - <input type="radio" name="option" class="form-radio" value="c"> - <span>Option C</span> - </label> - </div> -</fieldset> -``` - -### Inline Radio Buttons - -```html -<div class="flex gap-6"> - <label class="flex items-center gap-2 cursor-pointer"> - <input type="radio" name="size" class="form-radio" value="sm"> - <span>Small</span> - </label> - <label class="flex items-center gap-2 cursor-pointer"> - <input type="radio" name="size" class="form-radio" value="md"> - <span>Medium</span> - </label> - <label class="flex items-center gap-2 cursor-pointer"> - <input type="radio" name="size" class="form-radio" value="lg"> - <span>Large</span> - </label> -</div> -``` - ---- - -## Form Groups - -### Basic Form Group - -```html -<div class="form-group"> - <label for="name">Name</label> - <input type="text" id="name" class="form-input"> -</div> -``` - -### Required Form Group - -```html -<div class="form-group required"> - <label for="email">Email</label> - <input type="email" id="email" class="form-input" required> -</div> -``` - -### Form Group with Help Text - -```html -<div class="form-group"> - <label for="username">Username</label> - <input type="text" id="username" class="form-input"> - <div class="form-group-help">3-20 characters, alphanumeric only</div> -</div> -``` - -### Form Group with Error - -```html -<div class="form-group error"> - <label for="password">Password</label> - <input type="password" id="password" class="form-input error"> - <div class="form-error">Password must be at least 8 characters</div> -</div> -``` - ---- - -## Form Layouts - -### Single Column Form - -```html -<form class="space-y-4"> - <div class="form-group"> - <label for="name">Name</label> - <input type="text" id="name" class="form-input"> - </div> - - <div class="form-group"> - <label for="email">Email</label> - <input type="email" id="email" class="form-input"> - </div> - - <div class="form-group"> - <label for="message">Message</label> - <textarea id="message" class="form-textarea"></textarea> - </div> - - <button type="submit" class="btn btn-primary">Submit</button> -</form> -``` - -### Two-Column Form (Responsive) - -```html -<form class="space-y-4"> - <div class="form-row"> - <div class="form-group"> - <label for="first">First Name</label> - <input type="text" id="first" class="form-input"> - </div> - <div class="form-group"> - <label for="last">Last Name</label> - <input type="text" id="last" class="form-input"> - </div> - </div> - - <div class="form-row"> - <div class="form-group"> - <label for="phone">Phone</label> - <input type="tel" id="phone" class="form-input"> - </div> - <div class="form-group"> - <label for="country">Country</label> - <select id="country" class="form-select"> - <option>Select...</option> - </select> - </div> - </div> - - <button type="submit" class="btn btn-primary">Submit</button> -</form> -``` - -### Inline Form (Search) - -```html -<div class="form-inline"> - <div class="form-group"> - <label for="search">Search</label> - <input type="search" id="search" class="form-input" placeholder="Type..."> - </div> - <button class="btn btn-primary">Search</button> -</div> -``` - ---- - -## Modals - -### Alert Modal - -```html -<div class="modal" :class="{ active: showAlert }" x-show="showAlert" x-data="{ showAlert: false }"> - <div class="modal-backdrop" @click="showAlert = false"></div> - <div class="modal-content modal-sm"> - <div class="modal-header"> - <h3 class="modal-title">Alert</h3> - <div class="modal-close" @click="showAlert = false"></div> - </div> - <div class="modal-body"> - <p>This is an important message.</p> - </div> - <div class="modal-footer"> - <button class="btn btn-primary" @click="showAlert = false">OK</button> - </div> - </div> -</div> - -<button @click="showAlert = true" class="btn btn-primary">Open Alert</button> -``` - -### Confirm Modal - -```html -<div class="modal" :class="{ active: showConfirm }" x-show="showConfirm" x-data="{ showConfirm: false }"> - <div class="modal-backdrop" @click="showConfirm = false"></div> - <div class="modal-content modal-sm"> - <div class="modal-header"> - <h3 class="modal-title">Confirm Action</h3> - <div class="modal-close" @click="showConfirm = false"></div> - </div> - <div class="modal-body"> - <p>Are you sure you want to delete this item? This action cannot be undone.</p> - </div> - <div class="modal-footer"> - <button class="btn btn-outline" @click="showConfirm = false">Cancel</button> - <button class="btn btn-primary" @click="handleDelete()">Delete</button> - </div> - </div> -</div> -``` - -### Modal with Form - -```html -<div class="modal" :class="{ active: showModal }" x-show="showModal" x-data="{ showModal: false, form: {} }"> - <div class="modal-backdrop" @click="showModal = false"></div> - <div class="modal-content modal-md"> - <div class="modal-header"> - <h3 class="modal-title">Edit Profile</h3> - <div class="modal-close" @click="showModal = false"></div> - </div> - <form @submit.prevent="saveProfile()"> - <div class="modal-body space-y-4"> - <div class="form-group"> - <label for="name">Name</label> - <input type="text" id="name" class="form-input" x-model="form.name"> - </div> - <div class="form-group"> - <label for="bio">Bio</label> - <textarea id="bio" class="form-textarea" x-model="form.bio"></textarea> - </div> - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-outline" @click="showModal = false">Cancel</button> - <button type="submit" class="btn btn-primary">Save</button> - </div> - </form> - </div> -</div> -``` - ---- - -## Notifications - -### Toast Notification - -```html -<!-- Container in layout --> -<div class="toast-container" x-data="formComponentsData()"> - <template x-for="toast in toasts" :key="toast.id"> - <div class="toast" :class="`toast-${toast.type}`"> - <span x-text="toast.message"></span> - <div class="toast-close" @click="removeToast(toast.id)"></div> - </div> - </template> -</div> - -<!-- Trigger toast --> -<button @click="showToast('success', 'Item saved!')">Save</button> -<button @click="showToast('error', 'Failed to delete.')">Delete</button> -<button @click="showToast('info', 'Welcome back!')">Info</button> -<button @click="showToast('warning', 'Unsaved changes.')">Warning</button> -``` - -### Toast Usage in Forms - -```html -<form @submit.prevent="submitForm()"> - <!-- Form fields --> - <button type="submit" class="btn btn-primary" :disabled="isSubmitting"> - {{ isSubmitting ? 'Submitting...' : 'Submit' }} - </button> -</form> - -<script> -function formData() { - return { - isSubmitting: false, - async submitForm() { - this.isSubmitting = true; - try { - await fetch('/api/submit', { method: 'POST' }); - this.showToast('success', 'Form submitted successfully!'); - } catch (error) { - this.showToast('error', 'Failed to submit form.'); - } finally { - this.isSubmitting = false; - } - } - }; -} -</script> -``` - ---- - -## Tooltips - -### Top Tooltip (Default) - -```html -<div class="tooltip"> - <span>Hover me</span> - <span class="tooltip-text">I'm a tooltip on top!</span> -</div> -``` - -### Bottom Tooltip - -```html -<div class="tooltip tooltip-bottom"> - <span>Hover me</span> - <span class="tooltip-text">I'm below!</span> -</div> -``` - -### Left Tooltip - -```html -<div class="tooltip tooltip-left"> - <span>Hover me</span> - <span class="tooltip-text">I'm on the left!</span> -</div> -``` - -### Right Tooltip - -```html -<div class="tooltip tooltip-right"> - <span>Hover me</span> - <span class="tooltip-text">I'm on the right!</span> -</div> -``` - -### Tooltip with Icon - -```html -<div class="tooltip" title="Click to copy email"> - <button class="btn btn-icon"> - <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> - <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path> - </svg> - </button> - <span class="tooltip-text">Copy to clipboard</span> -</div> -``` - ---- - -## Loading States - -### Button with Spinner - -```html -<button class="btn btn-primary" :disabled="isLoading"> - <span x-show="isLoading" class="spinner mr-2"></span> - {{ isLoading ? 'Submitting...' : 'Submit' }} -</button> -``` - -### Spinner Sizes - -```html -<div class="spinner spinner-sm"></div> -<div class="spinner"></div> -<div class="spinner spinner-lg"></div> -``` - ---- - -## Complete Contact Form Example - -```html -<form x-data="formComponentsData()" @submit.prevent="submitForm()" class="space-y-4 max-w-md"> - <div class="form-group required"> - <label for="name">Name</label> - <input - type="text" - id="name" - class="form-input" - x-model="form.name" - @blur="validateName()" - :class="{ error: errors.name }" - required> - <div x-show="errors.name" class="form-error" x-text="errors.name"></div> - </div> - - <div class="form-group required"> - <label for="email">Email</label> - <input - type="email" - id="email" - class="form-input" - x-model="form.email" - @blur="validateEmail()" - :class="{ error: errors.email }" - required> - <div x-show="errors.email" class="form-error" x-text="errors.email"></div> - </div> - - <div class="form-group required"> - <label for="message">Message</label> - <textarea - id="message" - class="form-textarea auto-expand" - x-model="form.message" - @input="autoExpandTextarea($event)" - required - placeholder="Your message..."></textarea> - </div> - - <div class="form-group"> - <label class="flex items-center gap-3"> - <input type="checkbox" class="form-checkbox" x-model="form.subscribe"> - <span>Subscribe to our newsletter</span> - </label> - </div> - - <button - type="submit" - class="btn btn-primary w-full" - :disabled="isSubmitting"> - <span x-show="isSubmitting" class="spinner mr-2"></span> - {{ isSubmitting ? 'Submitting...' : 'Send Message' }} - </button> -</form> -``` - ---- - -## Keyboard Shortcuts - -| Key | Action | -|-----|--------| -| Tab | Focus next form field | -| Shift+Tab | Focus previous form field | -| Space | Toggle checkbox/radio | -| Enter | Submit form / Confirm dialog | -| Escape | Close modal / Cancel dialog | -| Arrow Up/Down | Navigate select options | - ---- - -## Best Practices - -1. **Always use labels** — Associate with `for` attribute -2. **Group related fields** — Use `.form-group` wrapper -3. **Provide help text** — Use `.form-group-help` for guidance -4. **Show errors clearly** — Use `.form-error` with specific messages -5. **Test keyboard navigation** — Use Tab, Shift+Tab, Enter, Space, Escape -6. **Verify contrast** — Check both dark and light modes -7. **Respect motion preferences** — Use `prefers-reduced-motion` media query -8. **Validate early** — Real-time feedback, but allow recovery -9. **Disable during submission** — Prevent duplicate submissions -10. **Use semantic HTML** — `<fieldset>`, `<legend>`, `<label>` elements - ---- - -**Last Updated:** 2026-04-16 -**Version:** 1.0 |
