@pineappleui/text-field
v0.1.2
Published
TextField primitive for @pineappleui — a thin wrapper around the @radix-ui/themes TextField.
Readme
@pineappleui/text-field
The single-line text input for
@pineappleui — a thin wrapper over
@radix-ui/themes' TextField, so call sites reach for the
design system rather than importing Radix directly.
No styling of its own, no state, no effects: it renders a native <input> and passes everything
through. The point is the indirection — a change of default, or a swap of the layer underneath,
happens here once instead of at every import site. Multi-line input is
@pineappleui/text-area.
npm install @pineappleui/text-fieldWhat it exports
import { TextField } from '@pineappleui/text-field';
<TextField.Root size="3" placeholder="[email protected]">
<TextField.Slot>@</TextField.Slot>
</TextField.Root>;| Export | What it is |
| --- | --- |
| TextField | The compound namespace — the same two parts Radix ships, and no third one. |
| TextField.Root | The field. A <div> wrapping a native <input>; takes every prop Radix's Root takes, including ref. |
| TextField.Slot | An adornment rendered inside the field — an icon, a unit, a prefix. side places it left or right. |
Each part is wrapped rather than re-exported, and the wrapper adds no behaviour: its whole job is to intersect Radix's props type with a local one that carries a sentence per prop, so the table below has no blank cells. The restatement is checked rather than trusted — every prop is an indexed access into Radix's own type, so a prop Radix renames or drops is a build error here rather than a stale row on the site.
The prop types ride along on the namespace as TextField.RootProps and TextField.SlotProps, so
consumers do not import those from Radix either. This README does not hand-write the prop set:
those types are the authoritative ones, your editor completes from them, and a second copy in prose
is a copy that goes stale without failing. The docs site generates the full table from those same
types — TextField on designpineapple.com.
The contract
- Radix Themes is a peer, and its stylesheet has to be loaded.
size,variant,colorandradiuscompile to Radix class names; without Radix's CSS in the page they resolve to nothing and the field renders as a bare browser input. Render this inside Radix's<Theme>. refreaches the<input>, not the wrapper. The<div>is Radix's own layout element for the slots; the ref is composed onto the input, which is the node you focus, select in, or readvaluefrom.- It is uncontrolled until you control it.
value,defaultValue,onChangeand the rest are the native input's, unchanged — this package holds no state of its own and never will. - A slot is decoration; the input is the control. Pointing at a slot focuses the input and puts the caret at the near end of the text, so an adornment never swallows a click. Put buttons inside a slot when you need one, not a click handler on the slot itself.
colortakes an accent name, not a CSS colour. Omit it to inherit the theme accent. A raw hex belongs instylefor the rare off-scale case, and reaching for it routinely means the palette is wrong and should change.- A field needs a label, and this does not render one. Pair it with a
<label htmlFor>— a placeholder disappears on the first keystroke and is not an accessible name.
Licence
MIT © David Zhang
