Component reference
TagsInput
Create and remove tags for an article.
Preview
Live previewOptional six-digit hex. Clear to restore the preset. Check contrast with your brand color.
Changes apply to this preview only.
Width adapts to the available space
"use client";
import { useState } from "react";
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
TagsInput,
Badge,
Button
} from "@pimolu/react";
function ArticleTags() {
const [tags, setTags] = useState([
"design systems",
"accessibility",
]);
const [published, setPublished] = useState(false);
return (
<Card>
<CardHeader>
<CardTitle>Publish an article</CardTitle>
<CardDescription>
Add up to five topics. Enter or comma commits a tag; Backspace
removes the last one.
</CardDescription>
</CardHeader>
<CardContent>
<div className="grid gap-5 min-w-0">
<TagsInput
label="Topics"
placeholder="Add a topic"
value={tags}
onValueChange={(next: string[]) => {
setTags(next);
setPublished(false);
}}
maxTags={5}
fullWidth
error={tags.length === 0}
errorMessage={tags.length === 0
? "An article needs at least one topic."
: undefined}
helperText={`${tags.length} of 5 topics selected.`}
/>
<div className="flex flex-wrap items-center gap-3 min-w-0">
<Badge variant="primary">
{tags.length} topics
</Badge>
<Button
size="sm"
disabled={tags.length === 0}
onClick={() => setPublished(true)}
>
Publish
</Button>
{
published
? (<span className="text-sm text-muted leading-relaxed">
Published with {tags.join(", ")}.
</span>)
: null
}
</div>
</div>
</CardContent>
</Card>
);
}
export function DemoExample() {
return (<ArticleTags />);
}More examples
Different configurations and compositions using the real Pimolu API. Each preview runs independently and follows the site appearance.
Sizes
sm, md and lg follow the shared field scale.
Delimiters and paste
Enter always commits. A custom delimiters list replaces the default comma. Pasting a list splits, trims and deduplicates it.
Limits and duplicates
maxTags ignores extra values. Duplicates are rejected unless allowDuplicates is true.
Usage
Normalize and validate tags according to the application's domain before persisting them.
API reference
Generated from the public TypeScript declarations. Native HTML attributes are inherited where the component extends them; this reference includes Pimolu props and selected common native attributes.
PimoluTagsInputProps
Type source| Name | Type | Default | Description |
|---|---|---|---|
value | string[] | undefined | — | Controlled tags. |
defaultValue | string[] | undefined | — | Initial tags when uncontrolled. |
onValueChange | ((value: string[]) => void) | undefined | — | Called with the next tag list after adding or removing a tag. |
maxTags | number | undefined | — | Maximum number of tags. Extra tags are ignored. |
allowDuplicates | boolean | undefined | false | Allow the same tag more than once. Defaults to false. |
delimiters | string[] | undefined | `[","]`; Enter always works | Characters that commit the current draft, in addition to Enter. Defaults to `[","]`; Enter always works. |
label | ReactNode | — | Visible label, associated with the text input. |
helperText | ReactNode | — | Supporting text below the field. |
error | boolean | undefined | false | Invalid state without an error message. |
errorMessage | ReactNode | — | Error text, replacing the helper text. |
size | PimoluTagsInputSize | undefined | "md" | Visual size. Defaults to "md". |
fullWidth | boolean | undefined | false | Stretch to the parent width. |
className | string | undefined | — | Class applied to the outer field. |
style | CSSProperties | undefined | — | Standard React/HTML attribute. |
aria-label | string | undefined | — | Defines a string value that labels the current element. |
children | ReactNode | — | Standard React/HTML attribute. |
onClick | MouseEventHandler<HTMLInputElement> | undefined | — | Standard React/HTML attribute. |
disabled | boolean | undefined | false | Standard React/HTML attribute. |
name | string | undefined | — | Standard React/HTML attribute. |
required | boolean | undefined | false | Standard React/HTML attribute. |
valuestring[] | undefinedNo default extracted.
Controlled tags.
defaultValuestring[] | undefinedNo default extracted.
Initial tags when uncontrolled.
onValueChange((value: string[]) => void) | undefinedNo default extracted.
Called with the next tag list after adding or removing a tag.
maxTagsnumber | undefinedNo default extracted.
Maximum number of tags. Extra tags are ignored.
allowDuplicatesboolean | undefinedDefault: false
Allow the same tag more than once. Defaults to false.
delimitersstring[] | undefinedDefault: `[","]`; Enter always works
Characters that commit the current draft, in addition to Enter. Defaults to `[","]`; Enter always works.
labelReactNodeNo default extracted.
Visible label, associated with the text input.
helperTextReactNodeNo default extracted.
Supporting text below the field.
errorboolean | undefinedDefault: false
Invalid state without an error message.
errorMessageReactNodeNo default extracted.
Error text, replacing the helper text.
sizePimoluTagsInputSize | undefinedDefault: "md"
Visual size. Defaults to "md".
fullWidthboolean | undefinedDefault: false
Stretch to the parent width.
classNamestring | undefinedNo default extracted.
Class applied to the outer field.
styleCSSProperties | undefinedNo default extracted.
Standard React/HTML attribute.
aria-labelstring | undefinedNo default extracted.
Defines a string value that labels the current element.
childrenReactNodeNo default extracted.
Standard React/HTML attribute.
onClickMouseEventHandler<HTMLInputElement> | undefinedNo default extracted.
Standard React/HTML attribute.
disabledboolean | undefinedDefault: false
Standard React/HTML attribute.
namestring | undefinedNo default extracted.
Standard React/HTML attribute.
requiredboolean | undefinedDefault: false
Standard React/HTML attribute.
Accessibility
- Name the input and each removal action; check Enter and keyboard deletion.