Use icons in an app built with @allxsmith/bestax-bulma — the Icon/IconText components and the five supported libraries (Font Awesome, Material Design Icons, Ionicons, Google Material Icons, Material Symbols). Use when adding an icon, choosing or configuring the app-wide icon library, fixing an icon that renders blank, pairing icons with text, or making icons accessible (decorative vs labeled).
12 stars
0 votes
0 copies
0 views
Added October 10, 2026
developmentgoreactnodeapi
Works with
api
Security analysis
B84/100
mediumInstalls packages at runtime which could introduce malicious dependenciesin examples/icon-usage.tsx
mediumInstalls packages at runtime which could introduce malicious dependenciesin references/icon-libraries.md
Installs into .claude/skills of the current project.
Are you the author of bestax-icons?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/allxsmith-bestax-icons)
---
name: bestax-icons
description: Use icons in an app built with @allxsmith/bestax-bulma — the Icon/IconText components and the five supported libraries (Font Awesome, Material Design Icons, Ionicons, Google Material Icons, Material Symbols). Use when adding an icon, choosing or configuring the app-wide icon library, fixing an icon that renders blank, pairing icons with text, or making icons accessible (decorative vs labeled).
license: MIT
---
# Icons with @allxsmith/bestax-bulma
`Icon` renders a Bulma icon container (`span.icon`) around a glyph from any of five icon
libraries behind one normalized API. `IconText` pairs icons with text. The library ships **no
icon fonts** — the chosen library's package (or CDN script) must be installed in the app.
## Quick start
```tsx
import { ConfigProvider, Icon, IconText } from '@allxsmith/bestax-bulma';
// Set the library ONCE at the app root; <Icon> then never needs `library`.
<ConfigProvider iconLibrary="fa">
<App />
</ConfigProvider>;
// Inside the app:
<Icon name="rocket" ariaLabel="Launch" />;
<IconText iconProps={{ name: 'star', 'aria-hidden': 'true' }}>
Starred
</IconText>;
```
## The five libraries
| Library | `iconLibrary` / `library` value | Name format | Example `name` |
| ---------------------- | ------------------------------- | ---------------------------- | --------------- |
| Font Awesome (default) | `'fa'` | kebab-case, no `fa-` prefix | `rocket` |
| Material Design Icons | `'mdi'` | kebab-case, no `mdi-` prefix | `rocket-launch` |
| Ionicons | `'ion'` | kebab-case | `rocket` |
| Google Material Icons | `'material-icons'` | snake_case (a text ligature) | `rocket_launch` |
| Material Symbols | `'material-symbols'` | snake_case (a text ligature) | `rocket_launch` |
⚠️ **The Ionicons value is `'ion'`, not `'ionicons'`.** The `npm create bestax` scaffold's
`--icon ionicons` flag maps to `iconLibrary="ion"` — passing `'ionicons'` to `ConfigProvider`
or `library` silently renders nothing.
**The same glyph has a different name per library** (`rocket` vs `rocket-launch` vs
`rocket_launch`). When an icon renders blank, the name format for the active library is the
first thing to check. A redundant `fa-`/`mdi-` prefix in `name` is tolerated (stripped), but
don't rely on it.
## Styling
- `size` — `'small' | 'medium' | 'large'` sizes the Bulma **container** (`is-small` ≈ 1rem,
`is-medium` ≈ 2rem, `is-large` ≈ 3rem box). To scale the **glyph**, use `features`
(Font Awesome `'fa-lg'`/`'fa-2x'`) or a Bulma text-size class (`'is-size-3'`).
- `variant` — per-library style: Font Awesome `solid` (default) / `regular` / `brands` /
`light` / `duotone` / `thin`; Material Icons `filled` (default) / `outlined` / `round` /
`sharp`; Material Symbols `outlined` (default) / `rounded` / `sharp`; Ionicons `outline` /
`sharp`. MDI has no variants. Note Material **Icons** uses `round`, Material **Symbols**
uses `rounded`.
- `features` — extra library classes, string or array: `'fa-spin'`, `['fa-lg', 'fa-border']`.
- Color via the helper props: `textColor="primary"`, `textColor="danger"`, etc.
## Custom node (SVG, react-icons, FontAwesome React)
`Icon` also accepts `children` instead of `name` — an inline SVG, a `react-icons` component, a
Font Awesome React `<FontAwesomeIcon>`, … — rendered in place of a class-based glyph. `name`
and `children` are mutually exclusive (the type rejects passing both, or neither). `size`,
`textColor`, `bgColor`, `ariaLabel` and `containerClassName` behave identically; `library`,
`variant`, `features` and `libraryFeatures` are ignored since there's no class-based glyph to
style.
```tsx
<Icon ariaLabel="Custom icon">
<MyReactIconsComponent />
</Icon>
```
`IconText`'s `iconProps` / `items[].iconProps` and `Control`'s `iconLeft`/`iconRight` accept
the same escape hatch — pass a node directly (instead of an `IconProps` object) and it is
wrapped in an `Icon` for you: `<IconText iconProps={<MySvg />}>Starred</IconText>`.
`Panel.Icon` takes the same `children`, but its container is `panel-icon` rather than `icon` —
it always overrides `containerClassName`, so style and query that class instead.
⚠️ **`children` excludes `undefined`.** Write a conditional icon as `cond ? <MySvg /> : null`
(or `cond && <MySvg />`), never `cond ? <MySvg /> : undefined` — the latter is a type error,
because the renderer would fall through to the `name` path with no name. In the `IconText` and
`Control` slots a falsy node counts as "no icon": nothing is rendered, and `Control` falls back
to `iconLeftName`/`iconRightName` if one is given, otherwise leaving the icon column unreserved.
## Accessibility
An `Icon` is decorative unless it is named: with no `ariaLabel` it renders `aria-hidden="true"`
and no name. Name it with its camelCase `ariaLabel` prop, and it renders `role="img"` with that
`aria-label`. Only a few components declare that prop (`Icon`, `Delete`, `Slider`, `Carousel`):
everything else takes the standard `aria-label` attribute, e.g.
`<Navbar.Burger aria-label="menu" />`.
- **Meaningful icon** (stands alone, conveys information): pass a descriptive
`ariaLabel="Delete item"`.
- **Decorative icon** (next to visible text that says the same thing, e.g. inside `IconText`
or a labeled `Button`): leave `ariaLabel` off, and the icon stays out of the accessible
name. An explicit `aria-hidden="true"`, as in the examples here, says the same thing.
- **Icon-only control:** name the control (`<Button aria-label="Delete item">`), not the icon.
## References
- `references/icon-libraries.md` — per-library setup (install/import/CDN), the full
name-format and variant tables, `features` values, and the blank-icon troubleshooting list.
- `examples/icon-usage.tsx` — runnable example: ConfigProvider setup, sizes, variants,
colors, IconText, and decorative-vs-labeled patterns.