### Install Dependencies and Start Theme Development Source: https://formkit.com/guides/create-a-tailwind-theme Install project dependencies and start the development server for your FormKit theme. This command assumes you are using pnpm. ```bash # or npm or yarn pnpm install pnpm dev ``` -------------------------------- ### Install @formkit/addons Source: https://formkit.com/inputs/multi-step Install the addons package to use the multi-step plugin. This is the first step before registering the plugin. ```bash yarn add @formkit/addons ``` -------------------------------- ### Transfer List Full Example with Slots and Data Fetching Source: https://formkit.com/inputs/transfer-list Demonstrates a comprehensive transfer list setup with custom slots for displaying detailed option information and functions for fetching, paginating, and searching guest data. ```jsx (
{initials(option.label)}
{option.label}
{option.email}
{option.phone}
), }} />
``` ```javascript export async function getGuests() { try { const res = await fetch( 'https://api-formkit-docs-examples.formkit.workers.dev/guests' ) if (res.ok) { const data = await res.json() if (data.data) { return data.data.map((result) => { return { label: result.name, value: result.id, } }) } } } catch (e) { // Handle network errors gracefully } return [] } export async function paginateGuests({ page, hasNextPage }) { try { const res = await fetch( `https://api-formkit-docs-examples.formkit.workers.dev/guests?page=${page}` ) if (res.ok) { const data = await res.json() if (data.data) { if (data.current_page < data.total_pages) { hasNextPage() } return data.data.map((result) => { return { label: result.name, value: result.id, } }) } } } catch (e) { // Handle network errors gracefully } return [] } export async function searchGuests({ search }) { if (!search) { return [] } try { const res = await fetch( `https://api-formkit-docs-examples.formkit.workers.dev/guests?search=${search}` ) if (res.ok) { const data = await res.json() if (data.data) { return data.data.map((result) => { return { label: result.name, value: result.id, } }) } } } catch (e) { // Handle network errors gracefully } return [] } export async function getGuest(id, cachedOption) { if (cachedOption) return cachedOption try { const res = await fetch( `https://api-formkit-docs-examples.formkit.workers.dev/guests/${id}` ) if (res.ok) { const data = await res.json() if (data.data) { return { label: data.data.name, value: data.data.id, } } } } catch (e) { // Handle network errors gracefully } return null } export async function loadGuest(id, cachedOption) { if (cachedOption && cachedOption.hasLoaded) return cachedOption try { const res = await fetch( `https://api-formkit-docs-examples.formkit.workers.dev/guests/${id}` ) if (res.ok) { const data = await res.json() if (data.data) { return { name: data.data.name, label: data.data.name + ` (age ${data.data.age})`, value: data.data.id, age: data.data.age, phone: data.data.phone, email: data.data.email, hasLoaded: true, } } } } catch (e) { // Handle network errors gracefully } return null } ``` ```javascript export function initials(str) { return str .split(' ') .slice(0, 2) .map((item) => item.charAt(0).toUpperCase()) .join('') } export const michaelJordan = (node) => { return node.value[0] === '34' } ``` -------------------------------- ### Install FormKit Packages Source: https://formkit.com/getting-started/installation Install the core FormKit packages for React integration. ```bash npm install @formkit/react @formkit/core @formkit/inputs ``` -------------------------------- ### Install FormKit Theme and Icon Packages Source: https://formkit.com/getting-started/installation Install the necessary packages for Tailwind CSS integration and icon support. ```bash npm install @formkit/themes @formkit/icons ``` -------------------------------- ### Install FormKit Pro Package Source: https://formkit.com/getting-started/installation Install the FormKit Pro package to enable advanced input types. ```bash npm install @formkit/pro ``` -------------------------------- ### Install @formkit/zod Source: https://formkit.com/plugins/zod Install the Zod plugin for FormKit using yarn. ```bash yarn add @formkit/zod ``` -------------------------------- ### Dropdown Options Example Source: https://formkit.com/inputs/dropdown This example shows how to provide a list of options for a dropdown input. Ensure options are in the format of { label: 'Display Text', value: 'internal_value' }. ```javascript [ { label: 'Uruguay', value: 'UY' }, { label: 'Uzbekistan', value: 'UZ' }, { label: 'Vanuatu', value: 'VU' }, { label: 'Venezuela', value: 'VE' }, { label: 'Viet Nam', value: 'VN' }, { label: 'Virgin Islands, British', value: 'VG' }, { label: 'Virgin Islands, U.S.', value: 'VI' }, { label: 'Wallis and Futuna', value: 'WF' }, { label: 'Western Sahara', value: 'EH' }, { label: 'Yemen', value: 'YE' }, { label: 'Zambia', value: 'ZM' }, { label: 'Zimbabwe', value: 'ZW' }, ] ``` -------------------------------- ### Setup Vue Instance and Module Cache Source: https://formkit.com/playground Initializes the Vue instance, manages module caching for FormKit and local components, and handles style injection. This is the core setup for the playground environment. ```javascript async function setupVueInstance(sourceTemplate) { var addStyle = (textContent, id) => { const cssId = id ? id : "component-styles" var existingCSS = document.getElementById(cssId) if (existingCSS) { existingCSS.remove() } var css = document.createElement("style") css.id = cssId css.appendChild(document.createTextNode(textContent)) var ref = document.head.getElementsByTagName("style")[0] || null document.head.insertBefore(css, ref ? ref.nextSibling : ref) } window.moduleCache = { vue: window.Vue, hlj: hljs, '@formkit/vue': FormKitVue, '@formkit/core': FormKitCore, '@formkit/utils': FormKitUtils, '@formkit/dev': FormKitDev, '@formkit/i18n': FormKitI18n, '@formkit/inputs': FormKitInputs, '@formkit/observer': FormKitObserver, '@formkit/rules': FormKitRules, '@formkit/validation': FormKitValidation, '@formkit/pro': FormKitPro, '@formkit/themes': FormKitThemes, '@formkit/icons': FormKitIcons, '@formkit/addons': FormKitAddons, '@formkit/auto-animate': FormKitAutoAnimate, '@formkit/zod': FormKitZod, '@formkit/drag-and-drop': FormKitDragAndDrop, '@formkit/tempo': Tempo, } // add global window modules to moduleCache // these are files that originate from the editor itself if (window.localVueComponents) { Object.keys(window.localVueComponents).forEach(async (key) => { var fileContents = window.localVueComponents[key] window.moduleCache[key] = await window.Vue.defineAsyncComponent( () => loadModule("Component" + key, { moduleCache: window.moduleCache, getFile: () => fileContents, addStyle, log(type, ...args) { console[type]("Render: ", ...args) }, }) ) }) } if (window.localModules) { Object.keys(window.localModules).forEach(async (key) => { var moduleEntity = window.localModules[key] var moduleExports = moduleEntity ? Object.keys(moduleEntity) : undefined if (moduleExports) { var isOnlyDefault = moduleExports.length === 1 && moduleExports.includes("default") window.moduleCache[key] = isOnlyDefault ? moduleEntity.default : moduleEntity } }) } var lastPackageOrg = "" // used for tracking relative imports from CDNs such as jsdelivr var SourceOptions = { moduleCache: window.moduleCache, pathResolve({ refPath, relPath }) { let url = window.importMap[relPath] if (moduleCache[relPath]) { return relPath // return a string that will be respected by our import map } if (relPath.endsWith(".vue")) { url = relPath.replace("./", "") } else if ( !url && (relPath.startsWith("./") || relPath.startsWith("/")) ) { // if we did not have an exact match, and the relPath starts with a relative path, // then try loading from the last library that we were dealing with. let newPath = relPath.replace("./", "") newPath = newPath.replace(newPath.match(/@.*$/), "") newPath = newPath.replace(/(^\/)/, lastPackageOrg) url = window.importMap[newPath] || "" } else if (url && relPath.startsWith("@")) { // save the package org if it has one in case it requests a relative package within // the same organization - but with a relative path lastPackageOrg = relPath.match(/(@.*)\/g) || "" } return url }, getFile: (url) => { if (!url || url === "example.vue") { return sourceTemplate } else if (url.endsWith(".vue")) { return url } else { const type = /.*?.js|.mjs$/.test(url) ? ".mjs" : /.*?.vue$/.test(url) ? ".vue" : /.*?.css$/.test(url) ? ".css" : ".mjs" const getContentData = async (asBinary) => await fetch(url).then((res) => !res.ok ? Promise.reject(url) : asBinary ? res.arrayBuffer() : res.text()) return { getContentData, type } } }, addStyle, log(type, ...args) { console[type]("Render: ", ...args) }, } var HTMLOptions = { moduleCache: window.moduleCache, getFile: () => window.HTMLTemplate, addStyle, log(type, ...args) { console[type]("HTML: ", ...args) }, } const pro = createProPlugin("fk-52971f34220", inputs) window.vueApp = getNewApp(SourceOptions, HTMLOptions) // Allow time for other files to process if we have config if (window.hasFormKitConfig) { async function checkConfigIsLoaded() { return ( window.localModules["formkit.config.js"] && window.localModules["formkit.config.js"].default ) } let condition = false let shouldBreak = false setTimeout(() => { shouldBreak = true }, 5000) do { condition = await checkConfigIsLoaded() if (!condition && !shouldBreak) { await new Promise((resolve) => setTimeout(resolve, 250)) } } while (!condition && !shouldBreak) } const config = window.hasFormKitConfig && window.localModules["formkit.config.js"] ? window.localModules["formkit.config.js"].default : {} if (Array.isArray(config.plugins)) { config.plugins.push(pro) } else { config.plugins = [pro] } if ("en" !== "en") { config.locales = Object.assign({}, config.locales, { en }) config.config = config.config || {} config.config.locale = config.config.locale || "en" } window.vueApp.use(plugin, defaultConfig(config)) window.vueApp.mount(document.getElementById("app")) } function getNewApp(SourceOptions, HTMLOptions) { if (window.vueApp) { window.vueApp.unmount() resetCount() } return window.Vue.createApp({ components: { "source-template": win ``` -------------------------------- ### Basic Textarea Example Source: https://formkit.com/inputs/textarea This example demonstrates a basic textarea input with a label, placeholder, character count help text, and validation. ```html ``` -------------------------------- ### Search and Select Tag List Example Source: https://formkit.com/inputs/taglist Demonstrates a tag list component that allows users to search for and select items. The example shows the expected JSON output for selected tags. ```json { "taglist": [ "audi", "bmw" ] } ``` -------------------------------- ### Install Barcode Input Source: https://formkit.com/inputs/barcode Install the barcode input package using npm. This package has a dependency on `@zxing/library`. ```bash npm install @formkit/barcode ``` -------------------------------- ### Install and Import Legacy Genesis CSS Theme Source: https://formkit.com/essentials/styling Install the `@formkit/themes` package and import the Genesis `theme.css` file in your main JavaScript entry point. ```bash npm install @formkit/themes ``` ```javascript import '@formkit/themes/genesis' ``` -------------------------------- ### Full Feature Form Example Source: https://formkit.com/essentials/forms A comprehensive example demonstrating a form with various input types, labels, help text, custom validation messages, and submission handling. It includes state management for submission feedback and dynamically hides the form after submission. ```jsx import { useState } from 'react'import { FormKit } from '@formkit/react'const styles = ` #registration-example { width: 420px; padding: 1.5em 1.5em 0 1.5em; border: 1px solid #e4e4e4; border-radius: 1em; margin: 0 auto 1em auto; } #registration-example.hide { display: none; } #registration-example pre { margin-bottom: 10px; } @media (min-width: 400px) { #registration-example .double { display: flex; justify-content: space-between; } #registration-example .double > * { width: calc(50% - 0.25em); } #registration-example .double > *:first-child { margin-right: 0.5em; } }` function RegisterExample() { const [submitted, setSubmitted] = useState(false) async function submitHandler() { await new Promise((resolve) => setTimeout(resolve, 1000)) setSubmitted(true) } return ( <>