Tags are used to categorize items, display metadata, and create filterable lists. They support icons, removal functionality, and interactive states.
Import
import { Tag } from '@/components/ui/Tag';
Usage
Basic Tag
Variants
Tag supports eight different variants:
<Tag variant="default">Default</Tag>
<Tag variant="primary">Primary</Tag>
<Tag variant="secondary">Secondary</Tag>
<Tag variant="success">Success</Tag>
<Tag variant="warning">Warning</Tag>
<Tag variant="danger">Danger</Tag>
<Tag variant="outline">Outline</Tag>
<Tag variant="filled">Filled</Tag>
Sizes
Three sizes are available:
<Tag size="sm">Small</Tag>
<Tag size="md">Medium</Tag>
<Tag size="lg">Large</Tag>
With Icons
Add icons to the left or right side of tags:
import { Hash, Star, User, Calendar } from 'lucide-react';
<Tag leftIcon={<Hash size={14} />}>Category</Tag>
<Tag leftIcon={<User size={14} />}>User</Tag>
<Tag leftIcon={<Calendar size={14} />}>Date</Tag>
<Tag rightIcon={<Star size={14} />}>Favorite</Tag>
Make tags removable with a close button:
<Tag
variant="primary"
removable
onRemove={() => console.log('Tag removed')}
>
Removable Tag
</Tag>
Example with state management:
const [tags, setTags] = useState([
{ id: 1, label: 'React', variant: 'primary' },
{ id: 2, label: 'TypeScript', variant: 'secondary' },
{ id: 3, label: 'Design System', variant: 'success' },
]);
const removeTag = (id) => {
setTags(tags.filter((tag) => tag.id !== id));
};
return (
<div className="flex gap-2">
{tags.map((tag) => (
<Tag
key={tag.id}
variant={tag.variant}
removable
onRemove={() => removeTag(tag.id)}
>
{tag.label}
</Tag>
))}
</div>
);
Make tags clickable for selection or filtering:
const [selectedTags, setSelectedTags] = useState([]);
const toggleTag = (tag) => {
setSelectedTags((prev) =>
prev.includes(tag) ? prev.filter((t) => t !== tag) : [...prev, tag]
);
};
const tags = ['React', 'Vue', 'Angular', 'Svelte'];
return (
<div className="flex gap-2">
{tags.map((tag) => (
<Tag
key={tag}
variant={selectedTags.includes(tag) ? 'primary' : 'outline'}
interactive
onClick={() => toggleTag(tag)}
>
{tag}
</Tag>
))}
</div>
);
Examples
Skills & Technologies
import { Hash } from 'lucide-react';
<div className="flex flex-wrap gap-2">
<Tag variant="primary" leftIcon={<Hash size={12} />}>JavaScript</Tag>
<Tag variant="primary" leftIcon={<Hash size={12} />}>TypeScript</Tag>
<Tag variant="secondary" leftIcon={<Hash size={12} />}>React</Tag>
<Tag variant="success" leftIcon={<Hash size={12} />}>Node.js</Tag>
<Tag variant="warning" leftIcon={<Hash size={12} />}>Python</Tag>
</div>
Project Status
<div className="flex gap-2">
<Tag variant="success" size="sm">Active</Tag>
<Tag variant="warning" size="sm">In Progress</Tag>
<Tag variant="danger" size="sm">Blocked</Tag>
<Tag variant="outline" size="sm">On Hold</Tag>
</div>
User Roles
import { User } from 'lucide-react';
<div className="flex gap-2">
<Tag variant="filled" leftIcon={<User size={14} />}>Admin</Tag>
<Tag variant="primary" leftIcon={<User size={14} />}>Editor</Tag>
<Tag variant="secondary" leftIcon={<User size={14} />}>Viewer</Tag>
<Tag variant="outline" leftIcon={<User size={14} />}>Guest</Tag>
</div>
<div className="flex gap-2">
<Tag
variant="primary"
removable
onRemove={() => console.log('Removed')}
>
Category: Design
</Tag>
<Tag
variant="secondary"
removable
onRemove={() => console.log('Removed')}
>
Author: John Doe
</Tag>
<Tag
variant="success"
removable
onRemove={() => console.log('Removed')}
>
Status: Published
</Tag>
</div>
Props
The visual style variant. Options: default, primary, secondary, success, warning, danger, outline, filled.
The size of the tag. Options: sm, md, lg.
Whether the tag can be removed. When true, displays a close button.
Callback function called when the remove button is clicked. Only works when removable is true.
Whether the tag is clickable. Adds hover effects and cursor pointer.
Icon or element to display on the left side of the tag.
Icon or element to display on the right side of the tag. Not shown when removable is true.
onClick
(event: React.MouseEvent) => void
Click handler for the tag. Automatically makes the tag interactive.
Additional CSS classes to apply to the tag.
The content to display inside the tag.
Semantic Tokens
Tag uses the following semantic tokens from the Stride Design System:
--bg-secondary, --bg-brand-muted, --bg-tertiary, --bg-brand
--text-primary, --text-brand, --text-secondary, --text-inverse
--border-primary, --border-brand, --border-secondary
--status-success, --status-warning, --status-danger (and their -bg and -text variants)
--tag-height-sm, --tag-height-md, --tag-height-lg
--font-size-xs, --font-size-sm, --font-size-md
--interactive-ghost-hover
--transition-normal, --font-weight-medium
Accessibility
- Tag is rendered as a
<span> element with proper semantic structure
- Remove button has
aria-label="Remove tag" for screen readers
- Remove button includes focus management with ring on focus
- Interactive tags receive proper hover and active states
- Icon sizes scale appropriately with tag size for readability
- Close button is properly sized for touch targets (minimum 44x44px on mobile)