From 03688f556d5eaaaec21d4dc3b6e9f9325b9df6b4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 12:22:49 +0000 Subject: [PATCH 1/2] =?UTF-8?q?feat(create-bestax):=20bestax-icons=20skill?= =?UTF-8?q?=20=E2=80=94=20teach=20agents=20the=20icon=20system?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New Agent Skill covering Icon/IconText end to end, per #287: - SKILL.md: the five libraries and their ConfigProvider values (including the ionicons → 'ion' trap from #271), per-library name formats, variant and features guidance, container-vs-glyph sizing, and the decorative-vs-labeled ariaLabel/aria-hidden rules. - references/icon-libraries.md: per-library setup (npm import or the Ionicons CDN script pair), full variant tables (Material Icons 'round' vs Material Symbols 'rounded'), a one-glyph-five-names table, and a blank-icon troubleshooting checklist. - examples/icon-usage.tsx: runnable canonical example. - Listing surfaces: skills/README.md (row/install/tree), docs skills intro + new docs/docs/skills/icons.mdx page + sidebar entry, the create-bestax CLAUDE_MD template skills list, and a Storybook Skills/Icons showcase per the skill-examples sync rule. Scope is the current icon system; #67's new libraries would extend it. Fixes #287 Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Pohc8xLkdx4gwXkW3xd7up --- bulma-ui/src/skill-examples/Icons.stories.tsx | 98 +++++++++++++ create-bestax/src/constants.ts | 1 + docs/docs/skills/icons.mdx | 72 ++++++++++ docs/docs/skills/intro.md | 3 + docs/sidebars.js | 1 + skills/README.md | 8 ++ skills/bestax-icons/SKILL.md | 78 +++++++++++ skills/bestax-icons/examples/icon-usage.tsx | 80 +++++++++++ .../bestax-icons/references/icon-libraries.md | 131 ++++++++++++++++++ 9 files changed, 472 insertions(+) create mode 100644 bulma-ui/src/skill-examples/Icons.stories.tsx create mode 100644 docs/docs/skills/icons.mdx create mode 100644 skills/bestax-icons/SKILL.md create mode 100644 skills/bestax-icons/examples/icon-usage.tsx create mode 100644 skills/bestax-icons/references/icon-libraries.md diff --git a/bulma-ui/src/skill-examples/Icons.stories.tsx b/bulma-ui/src/skill-examples/Icons.stories.tsx new file mode 100644 index 000000000..a4be2d306 --- /dev/null +++ b/bulma-ui/src/skill-examples/Icons.stories.tsx @@ -0,0 +1,98 @@ +// Skills → Examples → Icons: the bestax-icons skill's canonical example, +// rendered live. Shows the app-root ConfigProvider, meaningful-vs-decorative +// accessibility, sizes/variants/features, and multi-segment IconText. +import React from 'react'; +import type { Meta, StoryObj } from '@storybook/react-vite'; +import { ExampleMeta } from './ExampleMeta'; +import { ConfigProvider, Icon, IconText, Box, Button, Title } from '../index'; + +const SKILL_HREF = + 'https://github.com/allxsmith/bestax/tree/main/skills/bestax-icons/SKILL.md'; + +const meta: Meta = { + title: 'Skills/Icons', + tags: ['autodocs'], + parameters: { layout: 'padded' }, +}; +export default meta; +type Story = StoryObj; + +function Meta_({ prompt }: { prompt: string }) { + return ( + + ); +} + +export const IconUsage: Story = { + name: 'Icon usage & accessibility', + render: function IconUsageExample() { + return ( + + + {/* One library for the whole app — 'fa' | 'mdi' | 'ion' | + 'material-icons' | 'material-symbols' (Ionicons is 'ion', + NOT 'ionicons'). */} + + Meaningful icons carry their own label + + + + + Decorative icons hide from screen readers + + + Starred + + + + + Sizes, variants, features, color + + + + + + + + Multi-segment icon text + + + + + ); + }, +}; diff --git a/create-bestax/src/constants.ts b/create-bestax/src/constants.ts index b4c8ae8a9..67c08dd3c 100644 --- a/create-bestax/src/constants.ts +++ b/create-bestax/src/constants.ts @@ -124,6 +124,7 @@ automatically when the task matches: - **bestax-form** — build forms with the bestax form components (no form library). - **bestax-theming** — colors, branding, and dark mode via the \`Theme\` component (\`colorMode\`). - **bestax-layout-scaffold** — scaffold full pages (app shell, landing, centered, card grid). +- **bestax-icons** — icons via \`Icon\`/\`IconText\`: library setup, name formats, variants, a11y. Prefer the library's components and these skills over hand-written Bulma markup or custom CSS. diff --git a/docs/docs/skills/icons.mdx b/docs/docs/skills/icons.mdx new file mode 100644 index 000000000..53e762c1f --- /dev/null +++ b/docs/docs/skills/icons.mdx @@ -0,0 +1,72 @@ +--- +title: Icons +sidebar_label: Icons +sidebar_position: 5 +--- + +# Icons skill + +The [`bestax-icons`](https://github.com/allxsmith/bestax/blob/main/skills/bestax-icons/SKILL.md) +skill teaches an agent to use icons in an app built with `@allxsmith/bestax-bulma`: the +`Icon`/`IconText` components, the five supported icon libraries and their setup, the +per-library name formats and variants, and decorative-vs-labeled accessibility. + +## Install + +```bash +npx skills add https://github.com/allxsmith/bestax --skill bestax-icons +``` + +## What it teaches + +- **One library, set once** — `ConfigProvider iconLibrary` (`'fa' | 'mdi' | 'ion' | +'material-icons' | 'material-symbols'`), so no per-`Icon` `library` prop. Including the + classic trap: the Ionicons value is **`'ion'`, not `'ionicons'`**. +- **Per-library name formats** — the same glyph is `rocket` (Font Awesome), + `rocket-launch` (MDI), and `rocket_launch` (Material Icons/Symbols, which render the name + as a font-ligature text node). The wrong format is the #1 cause of blank icons. +- **Variants and features** — Font Awesome's `solid`/`regular`/`brands`, Material Icons' + `round` vs Material Symbols' `rounded`, Ionicons' `outline`/`sharp` name suffixes, and + glyph scaling via `features` (`'fa-2x'`, `'fa-spin'`). +- **Accessibility** — a descriptive `ariaLabel` for meaningful standalone icons; + `aria-hidden` for decorative icons that sit next to visible text. + +## Meaningful vs decorative + +```tsx live + + + + Starred + + +``` + +## Sizes, variants, features + +```tsx live + + + + + + +``` + +## Reference material the agent reads on demand + +- [`references/icon-libraries.md`](https://github.com/allxsmith/bestax/blob/main/skills/bestax-icons/references/icon-libraries.md) + — per-library setup (npm package / CDN script), full name-format and variant tables, and + the blank-icon troubleshooting checklist. +- [`examples/icon-usage.tsx`](https://github.com/allxsmith/bestax/blob/main/skills/bestax-icons/examples/icon-usage.tsx) + — the canonical runnable example. + +## Related + +- [Icon API reference](../api/elements/icon.md) · [IconText API reference](../api/elements/icontext.md) +- [Configuration guide](../guides/features/configuration.md) — `ConfigProvider` in depth. diff --git a/docs/docs/skills/intro.md b/docs/docs/skills/intro.md index 1a3355b53..22de5df4e 100644 --- a/docs/docs/skills/intro.md +++ b/docs/docs/skills/intro.md @@ -16,6 +16,7 @@ npx skills add https://github.com/allxsmith/bestax --skill bestax-custom-compone npx skills add https://github.com/allxsmith/bestax --skill bestax-form npx skills add https://github.com/allxsmith/bestax --skill bestax-theming npx skills add https://github.com/allxsmith/bestax --skill bestax-layout-scaffold +npx skills add https://github.com/allxsmith/bestax --skill bestax-icons ``` Starting a new app? `pnpm create bestax@latest` offers to **preinstall these skills** into the @@ -32,3 +33,5 @@ Then explore each skill — what it does, how to install it, and live examples: `--bulma-*` variables with the `Theme` component. - **[Layout scaffold](./layout-scaffold)** — go from "build me a dashboard / landing page / catalog" to a complete responsive page using the layout archetypes. +- **[Icons](./icons)** — use `Icon`/`IconText` with any of the five supported icon libraries: + per-library setup, name formats, variants, and decorative-vs-labeled accessibility. diff --git a/docs/sidebars.js b/docs/sidebars.js index 5ad2cf780..769efa246 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -36,6 +36,7 @@ const sidebars = { 'skills/form', 'skills/theming', 'skills/layout-scaffold', + 'skills/icons', ], }, ], diff --git a/skills/README.md b/skills/README.md index a3de00107..24b616e04 100644 --- a/skills/README.md +++ b/skills/README.md @@ -15,6 +15,7 @@ directory the agent reads on demand. | [`bestax-form`](./bestax-form/SKILL.md) | Building **forms** — Field/Control composition, the full input inventory, and the validate-it-yourself error pattern (there is no form library). | | [`bestax-theming`](./bestax-theming/SKILL.md) | **Theming** — customize colors, branding, fonts/radius tokens, and dark mode by overriding Bulma's `--bulma-*` variables with the `Theme` component. | | [`bestax-layout-scaffold`](./bestax-layout-scaffold/SKILL.md) | **Layout scaffolding** — turn a high-level request (dashboard, landing page, auth page, catalog) into a complete responsive page from named layout archetypes. | +| [`bestax-icons`](./bestax-icons/SKILL.md) | **Icons** — the `Icon`/`IconText` components and the five supported libraries (Font Awesome, MDI, Ionicons, Material Icons/Symbols): setup, name formats, variants, and accessibility. | ## Install @@ -25,6 +26,7 @@ npx skills add https://github.com/allxsmith/bestax --skill bestax-custom-compone npx skills add https://github.com/allxsmith/bestax --skill bestax-form npx skills add https://github.com/allxsmith/bestax --skill bestax-theming npx skills add https://github.com/allxsmith/bestax --skill bestax-layout-scaffold +npx skills add https://github.com/allxsmith/bestax --skill bestax-icons ``` ## Layout @@ -64,6 +66,12 @@ skills/ centered.tsx # centered single column card-grid.tsx # multiline columns of cards content-page.tsx # hero + cards + CTA, helper props (no inline style) + bestax-icons/ + SKILL.md + references/ + icon-libraries.md # per-library setup, name formats, variants, troubleshooting + examples/ + icon-usage.tsx # ConfigProvider + sizes/variants/colors + a11y patterns ``` > `component-catalog.md` is generated from the API docs by `scripts/gen-component-catalog.mjs` diff --git a/skills/bestax-icons/SKILL.md b/skills/bestax-icons/SKILL.md new file mode 100644 index 000000000..05bc5ca36 --- /dev/null +++ b/skills/bestax-icons/SKILL.md @@ -0,0 +1,78 @@ +--- +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; then never needs `library`. + + +; + +// Inside the app: +; + + Starred +; +``` + +## 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. + +## Accessibility + +Every `Icon` renders `aria-label` (default `"icon"`). + +- **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`): hide it from screen readers with `aria-hidden`: + `