### Basic useForm Setup
Source: https://formwerk.dev/llms-full.txt
Demonstrates the minimal setup for useForm, including importing the composable and obtaining the handleSubmit function.
```typescript
import { useForm } from '@formwerk/core';
const { handleSubmit } = useForm();
const onSubmit = handleSubmit((data) => {
console.log(data);
});
```
--------------------------------
### Basic useForm Setup
Source: https://formwerk.dev/guides/forms
This is the most basic form setup using `useForm`. It initializes a reactive form context and provides a `handleSubmit` function for form submission.
```javascript
import { useForm } from '@formwerk/core';
const { handleSubmit } = useForm();
const onSubmit = handleSubmit((data) => { console.log(data);});
```
--------------------------------
### Install Formwerk Core with bun
Source: https://formwerk.dev/llms-full.txt
Install the core Formwerk package using bun. This is the first step to using Formwerk's headless composables.
```bash
bun add @formwerk/core
```
--------------------------------
### Basic File Field Component Setup
Source: https://formwerk.dev/llms-full.txt
Sets up a basic File Field component using the `useFileField` composable. This example shows how to import and use the composable within a Vue component.
```vue
```
--------------------------------
### Install Formwerk Core with yarn
Source: https://formwerk.dev/llms-full.txt
Install the core Formwerk package using yarn. This is the first step to using Formwerk's headless composables.
```bash
yarn add @formwerk/core
```
--------------------------------
### Install Formwerk Core with pnpm
Source: https://formwerk.dev/llms-full.txt
Install the core Formwerk package using pnpm. This is the first step to using Formwerk's headless composables.
```bash
pnpm add @formwerk/core
```
--------------------------------
### Dropzone Component Setup
Source: https://formwerk.dev/llms-full.txt
Sets up a Dropzone component for drag-and-drop file uploads using the `useFileField` composable. This example demonstrates integrating the composable into a Vue component designed for file drops.
```vue
```
--------------------------------
### Install Formwerk Core with npm
Source: https://formwerk.dev/llms-full.txt
Install the core Formwerk package using npm. This is the first step to using Formwerk's headless composables.
```bash
npm install @formwerk/core
```
--------------------------------
### Basic Form Validation Setup
Source: https://formwerk.dev/guides/forms/validation
This snippet shows the fundamental setup for form validation in Formwerk. It involves defining validation rules and applying them to form elements.
```javascript
const form = document.getElementById('myForm');
const validator = new FormwerkValidator(form, {
rules: {
email: {
required: true,
email: true
},
password: {
required: true,
minlength: 8
}
},
messages: {
email: {
required: 'Email is required.',
email: 'Enter a valid email address.'
},
password: {
required: 'Password is required.',
minlength: 'Password must be at least 8 characters long.'
}
}
});
```
--------------------------------
### Vue.js Stepped Form Flow Example
Source: https://formwerk.dev/llms-full.txt
This example demonstrates how to set up a multi-step form using `useStepFormFlow`. It includes navigation buttons, conditional submit/next text, and an `onDone` handler to process form data.
```vue
```
--------------------------------
### Complete Form Repeater Component Example
Source: https://formwerk.dev/llms-full.txt
A full Vue component example demonstrating how to use useFormRepeater to render a dynamic list of form fields with add, remove, and move functionality.
```vue
#{{ index + 1 }}
```
--------------------------------
### Live Validation Example
Source: https://formwerk.dev/guides/forms/validation
This snippet illustrates how to enable live validation, where errors are shown as the user types.
```javascript
const form = document.getElementById('myForm');
const validator = new FormwerkValidator(form, {
rules: {
username: {
required: true,
minlength: 3
}
},
highlight: function(element) {
// Add a class to invalid elements
$(element).addClass('is-invalid');
},
unhighlight: function(element) {
// Remove the class from valid elements
$(element).removeClass('is-invalid');
}
});
```
--------------------------------
### Radio Group and Radio Item Example (Native Input)
Source: https://formwerk.dev/llms-full.txt
This example demonstrates building a functional radio group and radio items using native HTML input elements as the base. It requires `RadioItem.vue`, `RadioGroup.vue`, and `App.vue` components.
```vue
```
--------------------------------
### Basic Select Field Example
Source: https://formwerk.dev/guides/fields/selects
Demonstrates a simple select field with options. This is a fundamental building block for form inputs.
```html
```
--------------------------------
### Multiple Select Field Example
Source: https://formwerk.dev/guides/fields/selects
Demonstrates how to create a multi-select field using the `useSelect` composable with the `multiple` prop. This example shows how to structure options using groups and individual items.
```vue
```
--------------------------------
### Basic Date Input
Source: https://formwerk.dev/guides/fields/date-fields
A simple example of a date input field. This is the most basic way to collect date information.
```html
```
--------------------------------
### Basic Time Field Usage
Source: https://formwerk.dev/llms-full.txt
Demonstrates the basic setup for a TimeField component in an App.vue file. Ensure TimeField.vue is in the same directory.
```vue
```
--------------------------------
### Vue App Setup for Slider Component
Source: https://formwerk.dev/llms-full.txt
This snippet shows the basic setup for using the Slider component in a Vue application. It imports the Slider component and renders it with a label.
```vue
```
--------------------------------
### ComboBox with Option Groups
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to implement a ComboBox with grouped options using `OptionGroup.vue`. This example shows structuring countries into continents.
```vue
```
--------------------------------
### App.vue Usage Example
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to use the custom TextField component in an App.vue file. It utilizes `v-model` for two-way data binding and passes a label prop.
```vue
```
--------------------------------
### Checkbox Group Checked State Example
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to use the `useCheckboxGroup` composable to get the `groupState` property, which indicates if the group is entirely checked, unchecked, or mixed. This example assumes visual representation using SVGs.
```vue
```
--------------------------------
### Search Field with Zod Schema Validation
Source: https://formwerk.dev/guides/fields/search-fields
This example demonstrates how to use the `zod` schema validation provider with a Formwerk SearchField component. Ensure zod is installed and imported.
```vue
```
--------------------------------
### NumberField Component with Zod Schema
Source: https://formwerk.dev/guides/fields/number-fields
This script setup defines a Zod schema for number field validation and uses it with the NumberField component. Ensure Zod is installed and imported correctly.
```javascript
import { z } from 'zod';
import NumberField from './NumberField.vue';
const schema = z
.number('Required')
.min(1, 'Must be greater than 0')
.max(14, 'Must be less than 14');
```
```html
```
--------------------------------
### Accessing Form Data with toJSON
Source: https://formwerk.dev/guides/forms
This example demonstrates using the `toJSON` method to get a JSON-serializable representation of the form data. This is useful when sending data to a server via `fetch` or `axios`, as it handles non-serializable values.
```javascript
import { useForm } from '@formwerk/core';
const { handleSubmit } = useForm();
const onSubmit = handleSubmit(async (data) => {
const response = await fetch('https://example.org/post', {
body: JSON.stringify(data.toJSON()),
});
});
```
--------------------------------
### Using Calendar as a Date Picker
Source: https://formwerk.dev/guides/fields/calendars
Integrates the Calendar component as a date picker using the `usePicker` composable. This example demonstrates pairing the Calendar with a date field for selecting dates. It utilizes Vue's script setup and template syntax.
```vue
Selected date: {{ date || 'none' }}
```
--------------------------------
### Basic OTP Field Component Setup
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to set up a basic OTP field component by importing and using the `useOtpField` composable. It binds the returned objects to DOM elements using `v-bind`.
```vue
```
--------------------------------
### Importing and Creating a Calendar Instance
Source: https://formwerk.dev/guides/fields/calendars
Demonstrates how to import and create a calendar instance using `@internationalized/date`. It shows both importing all calendars (larger bundle size) and importing a specific calendar for better tree-shaking.
```vue
```
--------------------------------
### Server-Side Validation Example (Conceptual)
Source: https://formwerk.dev/guides/forms/validation
This snippet illustrates a conceptual server-side validation approach using a hypothetical backend framework. It's not directly executable but shows the pattern.
```python
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/submit', methods=['POST'])
def submit_form():
name = request.form.get('name')
email = request.form.get('email')
if not name or len(name) < 3:
return jsonify({'error': 'Name is required and must be at least 3 characters.'}), 400
if not email or '@' not in email:
return jsonify({'error': 'Valid email is required.'}), 400
# Process the valid form data
return jsonify({'message': 'Form submitted successfully!'}), 200
if __name__ == '__main__':
app.run(debug=True)
```
--------------------------------
### Form with Input Fields and Submission
Source: https://formwerk.dev/llms-full.txt
An example of a complete form using useForm with TextField and Checkbox components. It shows how to bind form elements and handle submission by converting form data to a JSON string.
```vue
```
--------------------------------
### Vue Search Field Component Example
Source: https://formwerk.dev/llms-full.txt
Example of how to use the SearchField component with v-model binding in a Vue application. It demonstrates setting a label, placeholder, and displaying the bound search value.
```vue
Search value: {{ search }}
```
--------------------------------
### Initialize Theme and Language Selectors
Source: https://formwerk.dev/guides/fields/selects
Initializes theme and language selection components. It sets up event listeners for theme changes and updates the UI accordingly. It also handles language selection by redirecting the page.
```javascript
(() => {
const openBtn = document.querySelector('button[data-open-modal]');
const shortcut = openBtn?.querySelector('kbd');
if (!openBtn || !(shortcut instanceof HTMLElement)) return;
const platformKey = shortcut.querySelector('kbd');
if (platformKey && /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)) {
platformKey.textContent = '⌘';
openBtn.setAttribute('aria-keyshortcuts', 'Meta+K');
}
shortcut.style.display = '';
})();
```
```javascript
class s extends HTMLElement {
constructor() {
super();
this.btn = this.querySelector('button');
this.btn.addEventListener('click', () => this.toggleExpanded());
const t = this.closest('nav');
t && t.addEventListener('keyup', e => this.closeOnEscape(e));
}
setExpanded(t) {
this.setAttribute('aria-expanded', String(t));
document.body.toggleAttribute('data-mobile-menu-expanded', t);
}
toggleExpanded() {
this.setExpanded(this.getAttribute('aria-expanded') !== 'true');
}
closeOnEscape(t) {
t.code === 'Escape' && (this.setExpanded(!1), this.btn.focus());
}
}
customElements.define('starlight-menu-button', s);
```
```javascript
class s extends HTMLElement {
constructor() {
super();
t(c());
this.querySelector('select')?.addEventListener('change', a => {
a.currentTarget instanceof HTMLSelectElement && t(o(a.currentTarget.value));
});
}
}
customElements.define('starlight-theme-select', s);
```
```javascript
class s extends HTMLElement {
constructor() {
super();
const e = this.querySelector('select');
e && (
e.addEventListener('change', t => {
t.currentTarget instanceof HTMLSelectElement && (window.location.pathname = t.currentTarget.value);
}),
window.addEventListener('pageshow', t => {
if (!t.persisted) return;
const n = e.querySelector('option[selected]')?.index;
n !== e.selectedIndex && (e.selectedIndex = n ?? 0);
})
);
}
}
customElements.define('starlight-lang-select', s);
```
--------------------------------
### Theme Provider Initialization and Management
Source: https://formwerk.dev/extras/i18n
Manages the application's theme, persisting the choice in localStorage and applying it to the document. It also provides a method to update UI elements that display the current theme.
```javascript
window.StarlightThemeProvider = (() => {
const storedTheme = typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
const theme = storedTheme || (window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
return {
updatePickers(theme = storedTheme || 'auto') {
document.querySelectorAll('starlight-theme-select').forEach((picker) => {
const select = picker.querySelector('select');
if (select) select.value = theme;
/** @type {HTMLTemplateElement | null} */
const tmpl = document.querySelector(`#theme-icons`);
const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
if (newIcon) {
const oldIcon = picker.querySelector('svg.label-icon');
if (oldIcon) {
oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
}
}
});
},
};
})();
```
--------------------------------
### Custom On/Off Values Example
Source: https://formwerk.dev/llms-full.txt
Customize the `on` and `off` values using `trueValue` and `falseValue` props. These values can be of any type.
```vue
Value is: {{ value }}
```
--------------------------------
### Multiple Thumbs Slider Example
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to configure a slider with multiple thumbs by adding multiple `` components. This automatically handles min/max clamping for each thumb and value conversion to an array.
```vue
MultipleSlider value is: {{ value }}
```
--------------------------------
### Disabled Switch Example
Source: https://formwerk.dev/llms-full.txt
Use the `disabled` prop to make the switch non-interactive. Disabled switches are not validated or submitted.
```vue
```
--------------------------------
### Navigate to a Form Step by Index
Source: https://formwerk.dev/llms-full.txt
Navigate to a specific form step by providing its zero-based index to the `goToStep` function.
```typescript
goToStep(1);
```
--------------------------------
### Disabled Slider Example
Source: https://formwerk.dev/llms-full.txt
Shows how to disable a slider using the `disabled` prop. Disabled sliders are non-interactive, not validated, and not submitted.
```vue
```
--------------------------------
### Locale and Calendar Support
Source: https://formwerk.dev/guides/fields/date-fields
This snippet demonstrates the initialization of Astro's idle callback and the definition of custom elements for handling component hydration and rendering, including support for various data types and asynchronous operations.
```javascript
astro-island,astro-slot,astro-static-slot{display:contents}(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value=="object"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};"requestIdleCallback"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event("astro:idle"));})();(()=>{var A=Object.defineProperty;var g=(i,o,a)=>o in i?A(i,o,{enumerable:!0,configurable:!0,writable:!0,value:a}):i\[o\]=a;var d=(i,o,a)=>g(i,typeof o!="symbol"?o+"":o,a);{let i={0:t=>m(t),1:t=>a(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(a(t)),5:t=>new Set(a(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>1/0*t},o=t=>{let\[l,e\]=t;return l in i?i\[l\](e):void 0},a=t=>t.map(o),m=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map((\[l,e\])=>(\[l,o(e)\])));class y extends HTMLElement{constructor(){super(...arguments);d(this,"Component");d(this,"hydrator");d(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island\[ssr\]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let c=this.querySelectorAll("astro-slot"),n={},h=this.querySelectorAll("template\[data-astro-template\]");for(let r of h){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n\[r.getAttribute("data-astro-template")||"default"\]=r.innerHTML,r.remove())}for(let r of c){let s=r.closest(this.tagName);s!=null&&s.isSameNode(this)&&(n\[r.getAttribute("name")||"default"\]=r.innerHTML)}let p;try{p=this.hasAttribute("props")?m(JSON.parse(this.getAttribute("props"))):{}}catch(r){let s=this.getAttribute("component-url")||"",v=this.getAttribute("component-export");throw v&&(s+=\` (export ${v})"),console.error(\`[hydrate] Error parsing props for component ${s}\",this.getAttribute("props"),r),r}let u;await this.hydrator(this)(this.Component,p,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});d(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),c.disconnect(),this.childrenConnectedCallback()},c=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});c.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}async start(){let e=JSON.parse(this.getAttribute("opts")),c=this.getAttribute("client");if(Astro\[c\]===void 0){window.addEventListener(\`astro:${c}\",()=>this.start(),{once:!0});return}try{await Astro\[c\](async()=>{let n=this.getAttribute("renderer-url"),\[h,{default:p}\]=await Promise.all(\[import(this.getAttribute("component-url")),
n?import(n):()=>()=>{}\]),u=this.getAttribute("component-export")||"default";if(!u.includes("."))this.Component=h\[u\];else{this.Component=h;for(let f of u.split("."))this.Component=this.Component\[f\]}return this.hydrator=p,this.hydrate},e,this)}catch(n){console.error(\`[astro-island] Error hydrating ${this.getAttribute("component-url")}\",n)}}attributeChangedCallback(){this.hydrate()}}d(y,"observedAttributes",\["props"\]),customElements.get("astro-island")||customElements.define("astro-island",y)}})()
```
--------------------------------
### Integrating SelectField and OptionItem Components
Source: https://formwerk.dev/guides/fields/selects
Demonstrates how to use the custom SelectField and OptionItem components in an application. This example shows a basic select input for choosing a drink.
```vue
```
--------------------------------
### Using a Field Component
Source: https://formwerk.dev/llms-full.txt
Example of using a self-contained field component like `TextField`. This is the recommended approach for first-party code.
```vue-html
```
--------------------------------
### Nuxt Server Side Rendering Example
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to use Formwerk composables within a Nuxt application for server-side rendering. Requires Vue.js v3.5.0 or higher.
```Vue.js
```
--------------------------------
### Allow Picking Directories in Dropzone
Source: https://formwerk.dev/llms-full.txt
When `multiple` is enabled, use the `allow-directory` prop to permit users to select entire directories for upload.
```vue
```
--------------------------------
### Custom Validation with JavaScript
Source: https://formwerk.dev/guides/forms/validation
This example shows how to implement custom validation logic using JavaScript for more complex validation requirements.
```javascript
const form = document.querySelector('form');
form.addEventListener('submit', (event) => {
let isValid = true;
const nameInput = document.getElementById('name');
const errorMessage = nameInput.nextElementSibling;
if (nameInput.value.length < 3) {
isValid = false;
nameInput.classList.add('invalid');
if (errorMessage) {
errorMessage.textContent = 'Name must be at least 3 characters long.';
} else {
const errorMsg = document.createElement('span');
errorMsg.className = 'error-message';
errorMsg.textContent = 'Name must be at least 3 characters long.';
nameInput.parentNode.insertBefore(errorMsg, nameInput.nextSibling);
}
} else {
nameInput.classList.remove('invalid');
if (errorMessage) {
errorMessage.remove();
}
}
if (!isValid) {
event.preventDefault();
}
});
```
--------------------------------
### RTL Slider Example
Source: https://formwerk.dev/llms-full.txt
Demonstrates how to set a slider to Right-to-Left (RTL) direction using the `dir="rtl"` prop. This automatically handles thumb positioning and inverts horizontal arrow key behavior.
```vue
```
--------------------------------
### Search Field with HTML Constraints
Source: https://formwerk.dev/guides/fields/search-fields
Example of using a SearchField component with required, minLength, and maxLength HTML attributes. The component itself is defined below.
```html
```