Components
Input
Inputs take a short line of text. In Flint, an input always lives in a form field with a visible label, optional helper text and an error message.
CSS
For Astro, EJS and plain HTML. These rules read only component tokens.
HTML
<label for="nights">Nights</label>
<input id="nights" class="flint-input" type="text"
aria-invalid="true" aria-describedby="nights-error" />
<span id="nights-error">Enter a number from 1 to 14.</span> CSS
.flint-input {
box-sizing: border-box; width: 100%; height: var(--input-height); padding: 0 var(--space-12);
border: 1px solid var(--input-border); border-radius: var(--input-radius);
background: var(--input-bg); color: var(--input-fg); font: 400 var(--font-size-md) / 1.5 var(--font-sans);
}
.flint-input::placeholder { color: var(--input-placeholder); opacity: 1; }
.flint-input:hover { border-color: var(--input-border-hover); }
.flint-input:focus-visible { border-color: var(--input-border-focus); outline: var(--focus-ring-width) solid var(--focus-ring-color); outline-offset: var(--focus-ring-offset); }
.flint-input[aria-invalid="true"] { border-color: var(--input-border-error); }
.flint-input:disabled { background: var(--color-action-disabled-bg); color: var(--color-action-disabled); border-color: var(--color-border-disabled); } MUI
React (MUI)
import TextField from '@mui/material/TextField';
<TextField label="Nights" error helperText="Enter a number from 1 to 14." /> Known gap
The MUI theme leaves the outlined input edge at MUI's default, about 1.6:1 (under 3:1), and its placeholder is dimmer than Flint's (ASDS-44).
shadcn/ui
The Flint version of the shadcn component. Same API as upstream; every value reads a Flint token.
components/ui/input.jsx
// shadcn/ui Input, restyled to Flint input tokens. Error state follows aria-invalid, as upstream.
// Gap: Flint has no input.disabled tokens yet, so disabled reads the semantic disabled colors.
import { cn } from '../cn';
export function Input({ className, type = 'text', ...props }) {
return (
<input
type={type}
data-slot="input"
className={cn(
'flex h-[var(--input-height)] w-full min-w-0 rounded-[var(--input-radius)] border border-[var(--input-border)] bg-[var(--input-bg)] px-3 text-base text-[var(--input-fg)] placeholder:text-[var(--input-placeholder)] hover:border-[var(--input-border-hover)] outline-none focus-visible:border-[var(--input-border-focus)] focus-visible:[outline:var(--focus-ring-width)_solid_var(--focus-ring-color)] focus-visible:[outline-offset:var(--focus-ring-offset)] aria-[invalid=true]:border-[var(--input-border-error)] disabled:cursor-not-allowed disabled:border-[var(--color-border-disabled)] disabled:bg-[var(--color-action-disabled-bg)] disabled:text-[var(--color-action-disabled)]',
className,
)}
{...props}
/>
);
} SwiftUI
SwiftUI
TextField("Nights", text: $nights)
.flintText(Flint.Typography.bodyMd)
.padding(.horizontal, Flint.Space.s12)
.frame(minHeight: Flint.Target.touch)
.overlay(RoundedRectangle(cornerRadius: Flint.Component.inputRadius)
.strokeBorder(hasError ? Flint.Component.inputBorderError : Flint.Component.inputBorder)) A ready-made SwiftUI input is moving into the Flint package (ASDS-38). Until then, build it from the component tokens as above.