Control
Form control as it should be!
This component supports input, select and textarea including all input types
text,color,date,datetime-local,email,file,hidden,month,number,password,search,tel,time,url,week
Other input types are supported in other components
checkbox,radio- included in Check, Switch, Color or Ratingrange- included in Rangebutton,reset,submit- included in Button
Installation
Follow instructions for individual framework usage below
Styles
Variants
defaultinteractiveinvalidfloatingfloating-interactivefilecolorselectselect-multipleselect-pickertel-country-codeicon
Props
Scripts
The Control script keeps data-active in sync with the control value and adds helper actions for steppers, picker opening and tel country code mirroring.
Examples
Basic
<div class="x-control">
<input type="text">
</div><x-control class="x-control">
<input type="text">
</x-control><div class="x-control" data-controller="x-control">
<input type="text">
</div><script setup lang="ts">
import { Control } from '@/components/control'
</script>
<template>
<Control>
<input type="text">
</Control>
</template>import { Control } from '@/components/control'
export function Example() {
return (
<Control>
<input type="text" />
</Control>
)
}Icon
You can position any content to start and end of the control.
Padding is automatically handled by CSS up to two icons, or you can do it manually.
--x-control-icon-count-start- number of icons at the start of the control--x-control-icon-count-end- number of icons at the end of the control--x-control-start- manually change start padding in px according to content--x-control-end- manually change end padding in px according to content
<div class="x-control">
<input type="text" placeholder="Enter a value.." required>
<div class="ms-auto">
<svg class="text-error" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
</svg>
<span>EUR</span>
</div>
</div>
<div class="x-control">
<input type="text" placeholder="Enter a value.." required>
<svg class="me-auto" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5" />
</svg>
</div><div class="x-control">
<select>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<svg class="ms-auto text-error" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z" />
</svg>
<label>Select</label>
</div>
<div class="x-control">
<select>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<svg class="me-auto" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 13.5V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m12-3V3.75m0 9.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 3.75V16.5m-6-9V3.75m0 3.75a1.5 1.5 0 010 3m0-3a1.5 1.5 0 000 3m0 9.75V10.5" />
</svg>
<label>Select</label>
</div>Textarea
<div class="x-control">
<textarea id="textarea"></textarea>
</div>Select
<div class="x-control">
<select>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>Tel Country Code
Combine a country calling code selector with a national phone number. The Control script mirrors the selected code into the adjacent span while keeping the full country names available in the native select.
<div class="grid gap-2">
<label class="x-label">Phone number</label>
<div class="x-group">
<x-control class="x-control w-22 shrink-0">
<select
autocomplete="tel-country-code"
required
aria-label="Country code"
>
<option value="+420" selected>Česko +420</option>
<option value="+421">Slovensko +421</option>
</select>
<span aria-hidden="true">+420</span>
</x-control>
<x-control class="x-control grow">
<input
type="tel"
pattern="^[0-9]{6,14}$"
placeholder="777 666 555"
autocomplete="tel-national"
aria-label="National number"
required
>
</x-control>
</div>
</div>Placeholder
<div class="x-control">
<input type="text" placeholder="Enter a value..">
</div>Label
<label class="x-label">Label</label><div class="x-field">
<label class="x-label mb-2" for="select">Select</label>
<div class="x-control">
<select id="select">
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
</div>Floating Label
<div class="x-control">
<input type="text" id="input" placeholder=" ">
<label for="input">Label</label>
</div><div class="x-control">
<select>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<label>Select</label>
</div>Time
<div class="x-control">
<input type="time">
</div>Date
<div class="x-control">
<input type="date">
</div>Datetime
<div class="x-control">
<input type="datetime-local">
</div>Number
<div class="x-control">
<input type="number">
</div>Color
<div class="x-control">
<input type="color" id="color" oninput="this.nextElementSibling.textContent = this.value">
<label for="color">#ffffff</label>
</div>File
<div class="x-control">
<input type="file">
</div>Required
<div class="x-control">
<input type="text" id="input" placeholder=" " required>
<label for="input">Label</label>
</div>Validation
<div class="x-control">
<input type="text" id="input" placeholder=" " required>
<label for="input">Label</label>
</div><div class="x-control">
<select id="select" required>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<label for="select">Select</label>
</div>Disabled
<div class="x-control">
<input type="text" disabled placeholder="Disabled input ..">
</div><div class="x-control">
<select disabled>
<option selected="" value="">- select an option -</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>Group
You can group controls into groups via x-group component and combine them with other components like Button
<div class="x-group">
<div class="x-control bg-body-secondary w-(--x-control-block-size) flex items-center justify-center">
@
</div>
<div class="x-control">
<input type="tel" required>
</div>
<button class="x-button">Button</button>
</div>