Documentation index for AI agents (llms.txt). Markdown versions of every page are available by appending .md to the page URL. The full corpus is at /llms-full.txt.

Icon

The Icon component renders one glyph from the Lucide icon set: import it from lucide-react and pass it as icon. Only the glyphs you import end up in your bundle, and they render on the server. It is the same component Cherry uses internally (for example in Dropzone tiles and the Modal close button), and renderIcon powers the $icon props on components like Avatar, Dropzone and Callout.

lucide-react is a peer dependency, so install it alongside Cherry (see Installation).

For design guidelines and all interactive states, see the Icons design page.

import React from "react";
import { Icon } from "cherry-styled-components";
import { Cherry } from "lucide-react";

export default function Page() {
  return <Icon icon={Cherry} size={24} />;
}

Icons are decorative by default: without an aria-label they render with aria-hidden, so screen readers skip them. Pass an aria-label to make an icon meaningful; it then gets role="img" and the label is announced:

<Icon icon={TriangleAlert} color="#ef4444" aria-label="Warning" />

Any component that accepts the same props (size, color, className and the aria attributes) works as icon, so a custom SVG component or a glyph from another set can stand in for a Lucide one.

Properties

iconIconComponentrequired

The icon component to render: an import from lucide-react such as Cherry or FileUp, or any component that accepts IconGlyphProps.

colorstring

Icon color. Defaults to the inherited text color.

sizenumber

Icon size in pixels. Defaults to 24, from Lucide's default attributes.

classNamestring

Class name applied to the rendered SVG.

aria-labelstring

Accessible label. When set, the icon gets role="img" and is announced by screen readers; when omitted, the icon is aria-hidden.

Icon props on other components

Avatar, AvatarDropzone, Dropzone, Callout and ChatPanel ($titleIcon) take an IconSource: the imported component, which the component renders through Icon at the size it chooses, or a rendered element, used as given. The exported renderIcon(source, props) helper does the same for components of your own.

<Avatar $icon={Bot} />
<Callout $type="note" $icon={Lightbulb}>Tip: press Cmd+K.</Callout>

DynamicIcon

When the icon is only known at runtime, from CMS content or a user setting, import DynamicIcon from the cherry-styled-components/dynamic subpath. It takes a Lucide name, either the PascalCase export name ("ArrowRight") or the kebab-case id ("arrow-right"), resolves it on demand through lucide-react/dynamic, and renders nothing for a name Lucide does not have. The glyph appears after hydration once its chunk has loaded, so it is never part of server-rendered HTML. It accepts the same color, size, className and aria-label props as Icon.

import { DynamicIcon } from "cherry-styled-components/dynamic";

<DynamicIcon name={post.icon} size={16} />;

Importing the subpath brings Lucide's dynamic import map into your app, one dynamic import per icon, which most bundlers turn into one small chunk per icon. Nothing on the main cherry-styled-components entry references it, so apps that never import the subpath never pay for it. Use Icon for every glyph the code already knows. In an $icon prop, pass it as an element: $icon={<DynamicIcon name={name} />}.

nameIconNamerequired

The Lucide icon, by PascalCase export name or kebab-case id. An unknown name renders nothing.

Internal usage

Cherry renders this same Icon component inside its own form controls, so their glyphs stay consistent with any icons you add yourself: the checkbox check mark in Input uses Check, the dropdown arrow in Select uses ChevronDown, and the calendar glyph on date and time inputs uses CalendarDays. These are colored with the theme's primary color through CSS (currentColor), so they follow the active palette in light and dark mode.