Default
import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Default() {
return <PixelBareTextarea placeholder="Write something..." rows={4} />;
}Unstyled escape-hatch <textarea> passthrough for building custom multi-line inputs without the opinionated PixelTextarea chrome.
$el in Vue, the textarea[pxlBareTextarea] element in Angularimport { PixelBareTextarea } from '@pxlkit/ui-kit';No props of its own.
Also takes the native attributes and event handlers of <textarea> (TextareaHTMLAttributes<HTMLTextAreaElement>).
ref points to <textarea>.
WCAG target: 2.1 AA
textboxRenders a native <textarea> so screen readers announce the textbox role with multiline semantics automatically. Because no chrome is applied, callers MUST supply a visible <label> (for) or an aria-label so the field has an accessible name. Pair with aria-required, aria-invalid, and aria-describedby for validation flows.
| Key | Action | When |
|---|---|---|
| Tab | Moves focus into and out of the textarea | — |
| Enter | Inserts a newline within the textarea | — |
| Shift+Tab | Moves focus to the previous focusable element | — |
import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Default() {
return <PixelBareTextarea placeholder="Write something..." rows={4} />;
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Default() {
return <PixelBareTextarea placeholder="Write something..." rows={4} />;
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Uncontrolled() {
return (
<PixelBareTextarea
defaultValue="Initial draft text"
rows={4}
aria-label="Notes"
/>
);
}import { useState } from 'react';
import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Controlled() {
const [value, setValue] = useState('');
return (
<div className="flex flex-col gap-2">
<PixelBareTextarea
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Type to see live updates"
rows={4}
aria-label="Message"
/>
<span className="text-xs text-retro-muted">{value.length} chars</span>
</div>
);
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Disabled() {
return (
<PixelBareTextarea
disabled
defaultValue="Cannot edit this field"
rows={3}
aria-label="Disabled textarea"
/>
);
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function ReadOnly() {
return (
<PixelBareTextarea
readOnly
defaultValue="Read-only content for reference"
rows={3}
aria-label="Read-only textarea"
/>
);
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function WithCustomStyling() {
return (
<PixelBareTextarea
className="w-full rounded border border-retro-border bg-retro-card p-3 font-mono text-sm text-retro-text"
placeholder="Escape-hatch: bring your own styles"
rows={5}
aria-label="Custom styled textarea"
/>
);
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function WithMaxLength() {
return (
<PixelBareTextarea
maxLength={140}
placeholder="Up to 140 characters"
rows={3}
aria-label="Short bio"
/>
);
}import { PixelBareTextarea } from '@pxlkit/ui-kit';
export function Required() {
return (
<PixelBareTextarea
required
placeholder="This field is required"
rows={3}
aria-label="Required textarea"
aria-required="true"
/>
);
}