@davaux/tabler-icons
v0.9.0
Published
Tabler Icons component for Davaux
Readme
@davaux/tabler-icons
Renders Tabler Icons as inline SVG strings for Davaux. Reads the SVG source from @tabler/icons directly, so there's no icon font, no sprite sheet, and no separate icon-component build step — just the ~5900 icons in that package, addressed by name.
Installation
npm install @davaux/tabler-iconsUsage
TablerIcon is async — it reads the SVG file and returns the finished markup as a string, so it must be awaited (or rendered from a definePage/component that Davaux already awaits for you):
import { TablerIcon } from '@davaux/tabler-icons'
export default definePage(() => (
<button>
<TablerIcon name="home" size={20} />
Home
</button>
))<TablerIcon name="heart" variant="filled" color="var(--dv-color-red-6)" />
<TablerIcon name="settings" size={32} stroke={1.5} class="nav-icon" />Props
| Prop | Type | Default | Description |
|---|---|---|---|
| name | string | — | Icon name from the Tabler set, e.g. 'home', 'user', 'settings' |
| variant | 'outline' \| 'filled' | 'outline' | Icon style |
| size | number \| string | 24 | Width and height in pixels |
| stroke | number | 2 | Stroke width (outline variant only) |
| color | string | 'currentColor' | Any CSS color, applied via style="color:…" so it drives both stroke and fill |
| class | string | — | Additional CSS class names appended to the root <svg> |
An unknown name (or one that doesn't match [a-z0-9-]) resolves to an empty string rather than throwing — check tabler.io/icons for exact names.
Server-only
TablerIcon reads icon files from disk via node:fs at render time. Davaux bundles every davaux/client-pragma'd file's full import graph for the browser (platform: 'browser', no node:* external) to produce the islands bundle, so importing @davaux/tabler-icons from inside one of those files fails the client build itself — esbuild can't resolve node:fs/node:path/node:url for a browser target — not just at runtime.
To use an icon inside a reactive/client component, render it on the server first and pass the resulting SVG string down as a plain string prop, not an unawaited JSX call: island props are JSON.stringify'd for the hydration payload, and a Promise (what <TablerIcon /> produces if it isn't awaited) serializes to {}, losing the icon on the client.
// server component
import { TablerIcon } from '@davaux/tabler-icons'
import { MyIsland } from './MyIsland.js'
export default definePage(async () => (
<MyIsland icon={await TablerIcon({ name: 'star' })} />
))/** @jsxImportSource davaux/client */
import { reactive } from "davaux";
import { Icon } from "@davaux/ui";
// MyIsland.tsx — reactive component, no @davaux/tabler-icons import here
function MyIsland({ icon }: { icon: string }) {
return <span dangerouslySetInnerHTML={{ __html: icon }} />
}
export default reactive(MyIsland);Caching
Each (name, variant) pair's raw SVG content is cached in memory after the first read, including misses, so repeated renders of the same icon don't re-hit the filesystem.
