Work in progress
— Form components are currently being reworked. APIs and markup may change.
Input
Text-like form control with optional before/after slots, help text, and error messaging.
Examples
Default preview
Default + help text
We'll only use this for account updates.
Before/after slots
Public profile handle.
Error + disabled
Password must be at least 12 characters.
This field is managed by your organization admin.
1<div class="space-y-8">
2 <section class="space-y-4">
3 {{ partial:docs/components/label content="Default + help text" }}
4 <div class="grid gap-4 md:grid-cols-2">
5 {{ partial:components/forms/input name="first_name" placeholder="Ada" }}
6 {{ slot:label }}First name{{ /slot:label }}
7 {{ /partial:components/forms/input }}
8
9 {{ partial:components/forms/input name="email" type="email" placeholder="name@kern.dev" }}
10 {{ slot:label }}Email{{ /slot:label }}
11 {{ slot:help }}We'll only use this for account updates.{{ /slot:help }}
12 {{ /partial:components/forms/input }}
13 </div>
14 </section>
15
16 <section class="space-y-4">
17 {{ partial:docs/components/label content="Before/after slots" }}
18 <div class="grid gap-4 md:grid-cols-2">
19 {{ partial:components/forms/input name="amount" type="number" value="120" placeholder="0" }}
20 {{ slot:label }}Amount{{ /slot:label }}
21 {{ slot:before }}CHF{{ /slot:before }}
22 {{ slot:after }}.00{{ /slot:after }}
23 {{ /partial:components/forms/input }}
24
25 {{ partial:components/forms/input name="username" placeholder="kern-user" }}
26 {{ slot:label }}Username{{ /slot:label }}
27 {{ slot:before }}@{{ /slot:before }}
28 {{ slot:help }}Public profile handle.{{ /slot:help }}
29 {{ /partial:components/forms/input }}
30 </div>
31 </section>
32
33 <section class="space-y-4">
34 {{ partial:docs/components/label content="Error + disabled" }}
35 <div class="grid gap-4 md:grid-cols-2">
36 {{ partial:components/forms/input name="password" type="password" error="true" value="short" }}
37 {{ slot:label }}Password{{ /slot:label }}
38 {{ slot:error }}Password must be at least 12 characters.{{ /slot:error }}
39 {{ /partial:components/forms/input }}
40
41 {{ partial:components/forms/input name="company" value="Kern Labs" disabled="true" }}
42 {{ slot:label }}Company{{ /slot:label }}
43 {{ slot:help }}This field is managed by your organization admin.{{ /slot:help }}
44 {{ /partial:components/forms/input }}
45 </div>
46 </section>
47</div>
<div class="space-y-8">
<section class="space-y-4">
{{ partial:docs/components/label content="Default + help text" }}
<div class="grid gap-4 md:grid-cols-2">
{{ partial:components/forms/input name="first_name" placeholder="Ada" }}
{{ slot:label }}First name{{ /slot:label }}
{{ /partial:components/forms/input }}
{{ partial:components/forms/input name="email" type="email" placeholder="name@kern.dev" }}
{{ slot:label }}Email{{ /slot:label }}
{{ slot:help }}We'll only use this for account updates.{{ /slot:help }}
{{ /partial:components/forms/input }}
</div>
</section>
<section class="space-y-4">
{{ partial:docs/components/label content="Before/after slots" }}
<div class="grid gap-4 md:grid-cols-2">
{{ partial:components/forms/input name="amount" type="number" value="120" placeholder="0" }}
{{ slot:label }}Amount{{ /slot:label }}
{{ slot:before }}CHF{{ /slot:before }}
{{ slot:after }}.00{{ /slot:after }}
{{ /partial:components/forms/input }}
{{ partial:components/forms/input name="username" placeholder="kern-user" }}
{{ slot:label }}Username{{ /slot:label }}
{{ slot:before }}@{{ /slot:before }}
{{ slot:help }}Public profile handle.{{ /slot:help }}
{{ /partial:components/forms/input }}
</div>
</section>
<section class="space-y-4">
{{ partial:docs/components/label content="Error + disabled" }}
<div class="grid gap-4 md:grid-cols-2">
{{ partial:components/forms/input name="password" type="password" error="true" value="short" }}
{{ slot:label }}Password{{ /slot:label }}
{{ slot:error }}Password must be at least 12 characters.{{ /slot:error }}
{{ /partial:components/forms/input }}
{{ partial:components/forms/input name="company" value="Kern Labs" disabled="true" }}
{{ slot:label }}Company{{ /slot:label }}
{{ slot:help }}This field is managed by your organization admin.{{ /slot:help }}
{{ /partial:components/forms/input }}
</div>
</section>
</div>
Props
| Name | Type | Default | Description |
|---|---|---|---|
name
|
string
|
|
Name attribute used for form submissions (and id when present) |
type
|
string
|
text
|
Input type (text, email, password, search, ...) |
value
|
string
|
|
Input value |
placeholder
|
string
|
|
Placeholder text |
disabled
|
boolean
|
false
|
Disabled state |
error
|
boolean
|
false
|
Enables destructive visual state |
class
|
string
|
|
Additional classes merged via tw_merge (root element only) |
Source
1{{#
2 @name Input
3 @desc Text-like form control with optional before/after slots, help text, and error messaging.
4 @param name string - Name attribute used for form submissions (and id when present)
5 @param type string [text] - Input type (text, email, password, search, ...)
6 @param value string - Input value
7 @param placeholder string - Placeholder text
8 @param disabled boolean [false] - Disabled state
9 @param error boolean [false] - Enables destructive visual state
10 @param class string - Additional classes merged via tw_merge (root element only)
11#}}
12{{ _label_slot = slot:label }}
13{{ _help_slot = slot:help }}
14{{ _error_slot = slot:error }}
15{{ _before_slot = slot:before }}
16{{ _after_slot = slot:after }}
17{{ _type = type ?? 'text' }}
18{{ _field_id = name ?? '' }}
19{{ _input_classes = 'text-foreground placeholder:text-muted-foreground disabled:text-muted-foreground h-10 min-w-0 flex-1 bg-transparent text-sm focus:outline-none disabled:cursor-not-allowed'
20 | tw_merge }}
21{{ partial:components/forms/_field-wrapper for="{_field_id}" error="{error}" disabled="{disabled}" class="{class}" }}
22 {{ if _label_slot }}
23 {{ slot:label }}
24 {{ _label_slot }}
25 {{ /slot:label }}
26 {{ /if }}
27 {{ if _help_slot }}
28 {{ slot:help }}
29 {{ _help_slot }}
30 {{ /slot:help }}
31 {{ /if }}
32 {{ if _error_slot }}
33 {{ slot:error }}
34 {{ _error_slot }}
35 {{ /slot:error }}
36 {{ /if }}
37 <div class="flex h-10 items-center gap-2 px-3">
38 {{ if _before_slot }}
39 <span class="text-muted-foreground flex shrink-0 items-center text-sm" aria-hidden="true">
40 {{ _before_slot }}
41 </span>
42 {{ /if }}
43 <input
44 class="{{ _input_classes }}"
45 type="{{ _type }}"
46 {{ if name }}name="{{ name }}" id="{{ _field_id }}"{{ /if }}
47 value="{{ value }}"
48 placeholder="{{ placeholder }}"
49 {{ if disabled }}disabled{{ /if }}
50 {{ if error }}aria-invalid="true"{{ /if }}
51 />
52 {{ if _after_slot }}
53 <span class="text-muted-foreground flex shrink-0 items-center text-sm" aria-hidden="true">
54 {{ _after_slot }}
55 </span>
56 {{ /if }}
57 </div>
58{{ /partial:components/forms/_field-wrapper }}
{{#
@name Input
@desc Text-like form control with optional before/after slots, help text, and error messaging.
@param name string - Name attribute used for form submissions (and id when present)
@param type string [text] - Input type (text, email, password, search, ...)
@param value string - Input value
@param placeholder string - Placeholder text
@param disabled boolean [false] - Disabled state
@param error boolean [false] - Enables destructive visual state
@param class string - Additional classes merged via tw_merge (root element only)
#}}
{{ _label_slot = slot:label }}
{{ _help_slot = slot:help }}
{{ _error_slot = slot:error }}
{{ _before_slot = slot:before }}
{{ _after_slot = slot:after }}
{{ _type = type ?? 'text' }}
{{ _field_id = name ?? '' }}
{{ _input_classes = 'text-foreground placeholder:text-muted-foreground disabled:text-muted-foreground h-10 min-w-0 flex-1 bg-transparent text-sm focus:outline-none disabled:cursor-not-allowed'
| tw_merge }}
{{ partial:components/forms/_field-wrapper for="{_field_id}" error="{error}" disabled="{disabled}" class="{class}" }}
{{ if _label_slot }}
{{ slot:label }}
{{ _label_slot }}
{{ /slot:label }}
{{ /if }}
{{ if _help_slot }}
{{ slot:help }}
{{ _help_slot }}
{{ /slot:help }}
{{ /if }}
{{ if _error_slot }}
{{ slot:error }}
{{ _error_slot }}
{{ /slot:error }}
{{ /if }}
<div class="flex h-10 items-center gap-2 px-3">
{{ if _before_slot }}
<span class="text-muted-foreground flex shrink-0 items-center text-sm" aria-hidden="true">
{{ _before_slot }}
</span>
{{ /if }}
<input
class="{{ _input_classes }}"
type="{{ _type }}"
{{ if name }}name="{{ name }}" id="{{ _field_id }}"{{ /if }}
value="{{ value }}"
placeholder="{{ placeholder }}"
{{ if disabled }}disabled{{ /if }}
{{ if error }}aria-invalid="true"{{ /if }}
/>
{{ if _after_slot }}
<span class="text-muted-foreground flex shrink-0 items-center text-sm" aria-hidden="true">
{{ _after_slot }}
</span>
{{ /if }}
</div>
{{ /partial:components/forms/_field-wrapper }}
Dependencies
Packages
marcorieser/tailwind-merge-statamic
1composer require marcorieser/tailwind-merge-statamic
composer require marcorieser/tailwind-merge-statamic
Internal dependencies
- components/forms/_field-wrapper
- Slots: label, help, error, before, after