Chip
UpdatedUsage
To display a chip, pass a label
to <Chip>
.
import { Chip } from "stylus-ui/Chip";
export default () => ( <div className="flex flex-wrap gap-1.5"> <Chip label="Chip 1" /> <Chip label="Chip 2" /> <Chip label="Chip 3" /> </div>);
Avatars
To display an avatar with the chip, pass an avatar
prop. It takes an AvatarProps
object.
import { Chip } from "stylus-ui/Chip";
const users = [ { id: "1", name: "Nam-Chi Van", }, { id: "2", name: "Ivan Salim", }, { id: "3", name: "Ryan Bach", },];
export default () => ( <div className="flex flex-wrap gap-1.5"> {users.map((user) => ( <Chip label={user.name} avatar={{ children: user.name, uuid: user.id }} /> ))} </div>);
Icons
Import a FontAwesome icon and pass it to the icon
prop.
import { Chip } from "stylus-ui/Chip";import { faTag, faStar, faFolder } from "@fortawesome/pro-regular-svg-icons";
export default () => ( <div className="flex flex-wrap gap-1.5"> <Chip icon={faTag} label="Tags" /> <Chip icon={faStar} label="Favorites" /> <Chip icon={faFolder} label="Folders" /> </div>);
Images
Arbitrary images can be displayed by passing in an img
object with src
and alt
properties.
import { Chip } from "stylus-ui/Chip";
export default () => ( <Chip img={{ src: "https://developer.mozilla.org/favicon.ico", alt: "MDN Favicon", }} label="MDN" />);
Dark mode
Set theme
to dark
to use the dark theme.
import { Chip } from "stylus-ui/Chip";import { faTag } from "@fortawesome/pro-regular-svg-icons";
export default () => ( <div className="flex flex-wrap gap-1.5"> <Chip label="Dark mode" theme="dark" /> <Chip label="With avatar" avatar={{ children: "NS", uuid: "1" }} theme="dark" /> <Chip label="With icon" icon={faTag} theme="dark" /> <Chip label="With image" img={{ src: "https://scribehow.com/favicon.ico", alt: "Scribe Favicon", }} theme="dark" /> <Chip label="Clickable" onClick={() => null} onRemove={() => null} theme="dark" /> </div>);
Click events
To make the chip clickable, pass an onClick
prop. Clickable chips have hover styles and a pointer cursor.
Passing an onRemove
prop will add a remove button to the chip.
import { useState } from "react";import { Chip } from "stylus-ui/Chip";import { useToast } from "stylus-ui/Toast";import { faArrowsRotate } from "@fortawesome/pro-regular-svg-icons";
const chips = [ { label: "Google", favicon: "https://www.google.com/favicon.ico" }, { label: "GitHub", favicon: "https://github.com/favicon.ico" }, { label: "Scribe", favicon: "https://scribehow.com/favicon.ico" },];
export default () => { const { toast } = useToast(); const [hiddenChips, setHiddenChips] = useState<number[]>([]);
return ( <div className="flex flex-wrap gap-1.5"> {chips.map( (chip, i) => !hiddenChips.includes(i) && ( <Chip label={chip.label} img={{ src: chip.favicon, alt: `${chip.label} favicon` }} onClick={() => toast({ title: `Clicked ${chip.label}` })} onRemove={() => setHiddenChips((prev) => [...prev, i])} /> ), )} {hiddenChips.length > 0 && ( <Chip icon={faArrowsRotate} label="Reset" onClick={() => setHiddenChips([])} /> )} </div> );};
Editable
To create an editable chip, import <EditableChip>
. Under the hood, EditableChip
is a regular HTML input
element—you can pass in any HTML input attributes.
import { Chip, EditableChip } from "stylus-ui/Chip";
export default () => ( <div className="flex flex-wrap gap-1.5"> <Chip label="Chip" /> <EditableChip placeholder="Edit me!" /> </div>);
Editable list
Here’s a minimal example of how to create an editable list of Chips.
import { useState } from "react";import { Chip, EditableChip } from "stylus-ui/Chip";
export default () => { const [chips, setChips] = useState<string[]>(["Chip 1", "Chip 2", "Chip 3"]); const [value, setValue] = useState<string>("");
const handleRemove = (chip: string) => { setChips((prev) => prev.filter((c) => c !== chip)); };
// Clear the input on `escape` const handleCancel = () => { setValue(""); };
// Add the new chip to the list on `enter` const handleSave = () => { if (value) { setChips((prev) => [...prev, value]); setValue(""); } };
return ( <div className="flex flex-wrap gap-1.5"> {chips.map((chip) => ( <Chip label={chip} onRemove={() => handleRemove(chip)} /> ))} <EditableChip placeholder="Add a chip" value={value} onChange={setValue} onCancel={handleCancel} onSave={handleSave} /> </div> );};
Editable toggle
Sometimes you may want to toggle between an editable and non-editable chip. Use <EditableToggleChip>
and pass in chipProps
and editableProps
. The component will automatically handle toggling between states when the chip is clicked. Pressing enter or clicking away will save the value.
import { useState } from "react";import { EditableToggleChip } from "stylus-ui/Chip";
export default () => { const [chips, setChips] = useState<string[]>([ "https://google.com", "https://github.com", "https://scribehow.com", ]);
const handleSave = (value: string, index: number) => { setChips((prev) => { const newChips = [...prev]; newChips[index] = value; return newChips; }); };
return ( <div className="flex flex-wrap gap-1.5"> {chips.map((chip, index) => ( <EditableToggleChip key={chip} chipProps={{ label: chip, img: { src: `${chip}/favicon.ico`, alt: `${chip} favicon` }, }} editableProps={{ defaultValue: chip, onSave: (value) => handleSave(value, index), }} /> ))} </div> );};
API Reference
Chip
Inherits properties from HTMLElement
.
Prop | Type | Default |
---|---|---|
label | string | |
avatar | AvatarProps | |
icon | IconProps | |
img | { src: string; alt: string } | |
onClick | MouseEventHandler<HTMLButtonElement> | |
onRemove | MouseEventHandler<HTMLButtonElement> | |
theme | "light" "dark" | "light" |
EditableChip
Inherits properties from HTMLInputElement
.
Prop | Type | Default |
---|---|---|
className | string | |
defaultValue | string | |
onCancel | () => void | |
onChange | (value: string) => void | |
onSubmit | React.FormEventHandler<HTMLFormElement> | |
theme | "light" "dark" | "light" |
value | string |
EditableToggleChip
Prop | Type | Default |
---|---|---|
chipProps | ChipProps | |
editableProps | EditableChipProps | |
theme | "light" "dark" | "light" |