Icon
Content & statusBrick 0.1.2

Icon

Icon gives one consumer-supplied SVG a consistent Brick size, semantic color, alignment, direction, and accessibility mode. Brick supplies no icon catalog or string registry.

Live example

Built from the published package

Interactive
Choose with confidence

Know when Icon is the right part

Use it when

Use Icon for custom inline SVGs and React icon-library components that render SVG. It works for decorative icons beside text, icons inside named controls, standalone informative symbols, semantic status color, and explicitly directional glyphs.

Choose another path when

Use IconButton or another control for interaction, Image for raster media and loading/fallback behavior, and the owning component's internal indicator or spinner for component anatomy. Do not use Icon for photos, emoji, font icons, complex illustrations, logos requiring independent semantics, or arbitrary SVG construction.

Installation and imports

tsx
import { Icon } from "@flowstack-ui/brick";
// or
import { Icon } from "@flowstack-ui/brick/icon";

import "@flowstack-ui/brick/styles.css";

The complete stylesheet above is the recommended default. For a measured route-aware build, replace it with the shared foundation and this component's stylesheet:

tsx
import "@flowstack-ui/brick/styles/core.css"; // once at the application root
import "@flowstack-ui/brick/styles/icon.css";

Add the modular stylesheet for every other Brick component the route renders. Do not combine modular styles with styles.css or tokens.css.

Public exports are Icon, IconProps, IconSize, and IconTone.

Quick start

tsx
function CheckIcon() {
  return <svg fill="none" viewBox="0 0 20 20"><path d="m4 10 4 4 8-8" stroke="currentColor" /></svg>;
}

<Icon tone="success"><CheckIcon /></Icon>

The SVG uses currentColor, so the semantic success tone controls its stroke.

Visual recipes and states

Sizes resolve to 12, 16, 20, 24, 32, and 40 pixels. Icon has no padding, background, border, radius, shadow, touch target, or interaction state.

tone="inherit" follows the parent's currentColor. Other tones resolve to Brick semantic foreground tokens. A single-color SVG must use fill="currentColor" or stroke="currentColor" to consume the tone. Fixed authored fills remain unchanged, which preserves multicolor artwork.

directional mirrors the graphic horizontally only under an RTL ancestor. Use it for arrows, chevrons, forward/back, undo/redo, and similar glyphs. Most objects, status symbols, logos, checks, clocks, and media controls must not opt in.

Examples

Visible text owns the meaning

tsx
<HStack gap="2">
  <Icon tone="success"><CheckIcon /></Icon>
  <Text>Published</Text>
</HStack>

Visible label reference

tsx
<Text id="sync-state">Sync paused</Text>
<Icon aria-labelledby="sync-state" tone="warning"><PauseIcon /></Icon>

Directional navigation glyph

tsx
<Icon directional><ArrowForwardIcon /></Icon>
Public contract

API

Start with the public parts and root options below. Components with multiple parts separate each area into its own named subsection.

PropValuesDefault
childrenone SVG element/componentrequired
size2xs, xs, sm, md, lg, xlmd
toneinherit, primary, secondary, muted, accent, info, success, warning, dangerinherit
directionalbooleanfalse
labelnonempty contextual stringdecorative when absent
aria-labelledbyID referencedecorative when absent
asChilddirect SVG compositionfalse
slotstringicon

label and aria-labelledby are mutually exclusive. Icon controls role, aria-label, and aria-hidden; contradictory native props are not accepted. Native global/data attributes, className, style, and an HTMLElement | SVGSVGElement ref pass through.

Shared responsibility

Accessibility

Decorative Icon sets aria-hidden="true". Supply label or aria-labelledby only when the standalone graphic conveys information not already present in nearby text. Informative output uses role="img" and the authored name.

For icon-only controls, label the Button, IconButton, Link, or Toggle and leave Icon decorative:

tsx
<IconButton aria-label="Search">
  <Icon size="sm"><SearchIcon /></Icon>
</IconButton>

Icon never guesses meaning, receives focus, adds keyboard handling, creates a tooltip, or announces tone changes. Semantic color cannot be the only carrier of state meaning.

Responsive behavior

Icon is an intrinsic square and does not choose breakpoints. It remains non-shrinking in inline and flex composition. Owning controls may normalize a nested Icon to their icon-slot dimensions. Icon adds no overflow or layout around siblings.

Stable visual contract

Styling and tokens

Customization

Use recipes first, then variables for a deliberate exception:

tsx
<Icon
  style={{
    "--brick-icon-size": "1.75rem",
    "--brick-icon-color": "rebeccapurple",
  }}
>
  <CustomSvg />
</Icon>

Arbitrary colors and dimensions are escape-hatch CSS, not additional recipe values.

Tokens and CSS hooks

Stable hooks are .brick-icon, data-slot ([data-slot="icon"]), data-size, data-tone, and the presence-only data-directional attribute.

Public variables:

  • --brick-icon-size-2xs
  • --brick-icon-size-xs
  • --brick-icon-size-sm
  • --brick-icon-size-md
  • --brick-icon-size-lg
  • --brick-icon-size-xl
  • --brick-icon-size
  • --brick-icon-color
  • --brick-icon-vertical-align
  • --brick-icon-direction-scale

Advanced reference

Open these details only when you need to inspect DOM ownership, native forwarding, or lower-level composition.

Maintainer resources

Tests, playground evidence, source notes, and release history remain available without crowding the plug-and-play guide.