import { Icon } from "chakra-ui-solid";
import { HeartIcon } from "../components/site/icons";
export default function IconBasic() {
return <Icon as={HeartIcon} size="lg" color="pink.700" />;
}Usage
import { Icon } from "chakra-ui-solid";<Icon />Chakra ships no icons of its own, and neither do we.
Iconstyles a glyph you bring — from an icon library, from a pastedsvg, or fromcreateIconbelow.
Examples
Icon libraries
Pass the glyph component as as, and Icon sizes and colours it.
import { HStack, Icon } from "chakra-ui-solid";
import { BellIcon, BoxIcon, TerminalIcon } from "../components/site/icons";
export default function IconWithIconLibrary() {
return (
<HStack gap="4">
<Icon as={BellIcon} size="lg" color="teal.600" />
<Icon as={BoxIcon} size="lg" color="orange.500" />
<Icon as={TerminalIcon} size="lg" color="purple.600" />
</HStack>
);
}No icon package supports SolidJS 2.0 yet, so the glyphs above are this site’s own — SVG path data copied out of Lucide, each one a small component wrapping a leaf
svg. That is the same shape a published icon package would have, so this page changes only its imports the day one exists.
as is where Chakra’s React version writes the glyph as a child. Both spellings mean the same thing
there — the child one is asChild, which re-creates the child element with Icon’s computed props
merged in. SolidJS has no equivalent: a child is an already-constructed DOM node by the time Icon
sees it, so a glyph nested as a child keeps its own svg and ignores size, and as is the
spelling that puts the recipe on the element that actually draws.
// ✅ one svg, and the recipe is on the element that draws
<Icon as={HeartIcon} size="lg" />
// ❌ two svgs, and `size` sizes the outer one while the glyph inside ignores it
<Icon size="lg">
<HeartIcon />
</Icon>Custom svg
Use the render prop to render your own svg rather than nesting one inside Icon’s.
import type { JSX } from "@solidjs/web";
import { Icon } from "chakra-ui-solid";
export default function IconWithCustomSvg() {
return (
<Icon
size="lg"
color="red.500"
render={(props) => (
// `aria-hidden` before the spread, which overwrites it with the same `"true"` Icon already
// computed. It is here for the linter, which cannot see an attribute arriving in a spread
// and reports the svg as unlabelled.
<svg
aria-hidden="true"
{...(props as JSX.SvgSVGAttributes<SVGSVGElement>)}
viewBox="0 0 32 32"
>
<g fill="currentColor">
<path d="M16,11.5a3,3,0,1,0-3-3A3,3,0,0,0,16,11.5Z" />
<path d="M16.868.044A8.579,8.579,0,0,0,16,0a15.99,15.99,0,0,0-.868,31.956A8.579,8.579,0,0,0,16,32,15.99,15.99,0,0,0,16.868.044ZM16,26.5a3,3,0,1,1,3-3A3,3,0,0,1,16,26.5ZM16,15A8.483,8.483,0,0,0,8.788,27.977,13.986,13.986,0,0,1,16,2a6.5,6.5,0,0,1,0,13Z" />
</g>
</svg>
)}
/>
);
}This is what Chakra’s React version spells
asChild. The callback is handed the computed props — the recipe’s class, the style props, the ref — and places them on the element you write.
Create Icon
Use the createIcon utility for a glyph you reuse enough to name.
import { createIcon } from "chakra-ui-solid";
const HeartIcon = createIcon({
displayName: "HeartIcon",
path: () => (
<>
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
fill="currentColor"
d="M19.5 13.572l-7.5 7.428l-7.5 -7.428m0 0a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572"
/>
</>
),
});
export default function IconWithCreateIcon() {
return <HeartIcon size="lg" color="blue.400" />;
}path is a function returning the glyph’s elements, where Chakra’s React version takes the
elements directly. A JSX value there would be built when the module loads rather than when the
component renders, which takes a server-rendered route down before anything reaches the page.
For a single-path glyph, d is the shorthand:
const DotIcon = createIcon({ d: "M12 12h.01" });viewBox defaults to 0 0 24 24, and defaultProps supplies any Icon prop the caller leaves
unset:
const WideIcon = createIcon({
viewBox: "0 0 32 32",
d: "M16 16h.01",
defaultProps: { size: "sm" },
});Props
| Prop | Default | Type |
|---|---|---|
focusable | false | 'true' | 'false'Whether the glyph can take focus. Chakra sets it, so we do — it is the attribute that keeps a decorative `svg` out of the tab order in engines that put it there. Declared here rather than inherited because SolidJS's SVG attribute types do not carry it: it is an SVG 1.1 attribute that SVG 2 dropped, and React's types kept. |
size | 'inherit' | ConditionalValue<'inherit' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl'>The glyph's box, as a scale step. `inherit` sets no box at all — the glyph keeps the one it draws itself, which for the `1em` an icon library ships is the surrounding font size. That is how an icon inside a button or a menu item matches its label, and it is the default, because an icon almost always belongs to some text. |
Plus everything it inherits — HTMLChakraProps<"svg">, the whole style-prop surface and the DOM attributes of the element it renders, several hundred names listed as their sources rather than expanded — and the three every component takes: as, render and unstyled.