Components · General
Icon
One glyph set, called by name — 259 icons imported from Figma, rendered by the shared <aha-icon>, never inline SVG.
Examples
Size
Glyph
Smart widget · one live
<aha-icon> — the Size / Glyph controls below drive itSize scale · 12 · 16 · 24 · 32 (the only sanctioned sizes)
The set · one
system-* outline family — call any glyph by nameState · outline = neutral, filled = active
Active/“on” state = the dedicated
-filled asset — a solid glyph survives greyscale, so state never rides on colour alone.Colour · inherits currentColor / semantic token
Icon + text · match cap height, 4px gap, leading side
Beyond system-* · slide-type & file-type families
Every glyph is called by
name from the shared registry — … icons imported from Figma Design System V3, no inline SVG at the call site. Browse and copy any name in the Icon library →. Size derives the paired stroke; colour follows currentColor; icon-only buttons carry an aria-label.
<!-- Paste-and-run: save as .html and open in a browser. No build step.
Call any glyph BY NAME — never inline an <svg>. One import loads <aha-icon> +
the 259-glyph registry; colour follows currentColor, size is 12 | 16 | 24 | 32. -->
<script type="module">
import 'https://cdn.jsdelivr.net/gh/ahaslides-product/ahaslides-design@master/lib/icons.js'; // registers <aha-icon> + registry
</script>
<!-- Icon + text — match the label's cap height (16 beside body text), glyph leading. -->
<button style="display:inline-flex; align-items:center; gap:8px">
<aha-icon name="system-plus" size="16" decorative></aha-icon>
Add slide
</button>
<!-- Icon-only — MUST carry an accessible name (+ a tooltip when the glyph isn't obvious). -->
<button aria-label="Search" title="Search">
<aha-icon name="system-magnifying-glass" size="16" decorative></aha-icon>
</button>
<!-- Colour is set on the wrapper; the glyph inherits it via currentColor. State = -filled asset. -->
<span style="color: var(--aha-color-primary, #6A1EBB)">
<aha-icon name="system-bookmark-simple-filled" size="24" label="Saved"></aha-icon>
</span>
import '@ahaslides-product/design/icons'; // registers <aha-icon> + loads the glyph registry (259 icons)
// Call any glyph BY NAME — never inline an <svg>. Browse names in the Icon library,
// or read icons.agent.json / icons.llms.txt. Colour follows currentColor; size is 12/16/24/32.
// Icon-only button — MUST carry an accessible name (+ a tooltip when the glyph isn't obvious).
<button aria-label="Search" title="Search">
<aha-icon name="system-magnifying-glass" size={16} decorative />
</button>
// Icon + text — match the label's cap height (16 beside body text), glyph on the leading side.
<button className="add">
<aha-icon name="system-plus" size={16} decorative />
Add slide
</button>
// State: outline = neutral, filled = active (use the dedicated -filled asset).
// Colour is set on the wrapper — the glyph inherits it via currentColor.
<span style={{ color: 'var(--aha-color-primary)' }}>
<aha-icon name={saved ? 'system-bookmark-simple-filled' : 'system-bookmark-simple'} size={24} label="Save" />
</span>
// Slide-type / file-type families are the same call, different name:
<aha-icon name="slidetype-poll" size={24} label="Poll" />
<aha-icon name="filetype-course" size={24} label="Course" />
// main.ts — register the element + registry, and mark aha-* as custom elements
import '@ahaslides-product/design/icons'; // registers <aha-icon> + loads the glyph registry (259 icons)
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith('aha-');
// Component.vue — presenter-app renders every glyph through the shared Icon, BY NAME.
// Browse names in the Icon library / icons.llms.txt. Colour follows currentColor; size 12/16/24/32.
<template>
<!-- Icon-only button — MUST have an accessible name (+ tooltip when unclear) -->
<button aria-label="Settings" title="Settings">
<aha-icon name="system-gear" :size="16" decorative />
</button>
<!-- Icon + text — cap-height match, 4px gap, glyph leading -->
<button class="add">
<aha-icon name="system-plus" :size="16" decorative />
Add slide
</button>
<!-- State: outline ↔ -filled asset is the toggle; colour = currentColor on the wrapper -->
<span :style="{ color: 'var(--aha-color-primary)' }">
<aha-icon :name="saved ? 'system-bookmark-simple-filled' : 'system-bookmark-simple'" :size="24" label="Save" />
</span>
<!-- Slide-type / file-type families are the same call, different name -->
<aha-icon name="slidetype-word-cloud" :size="24" label="Word cloud" />
<aha-icon name="filetype-lesson" :size="24" label="Lesson" />
</template>
API
| Prop | Type | Default | Notes |
|---|---|---|---|
name | string | — | Registry glyph name, e.g. system-bell, slidetype-poll, filetype-course |
size | 12 | 16 | 24 | 32 | 24 | On-grid pixel size; the master stroke scales with it |
label | string | — | Accessible name (role=img). Omit for a decorative icon |
decorative | boolean | false | aria-hidden — for an icon that only repeats adjacent text |
Install
# .npmrc — once: point the @ahaslides-product scope at GitHub Packages
@ahaslides-product:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} # a GitHub token with read:packages
npm i @ahaslides-product/design
import '@ahaslides-product/design/tokens.css'; // once, at the app root
import '@ahaslides-product/design/icons'; // registers <aha-icon>
Agent feed for this component (absolute, fetchable anywhere): icon.agent.json · icon.md · icon.llms.txt
When to use
When to use
- system-* glyph — the default for all product-UI chrome, buttons, menus, list rows, status
- -filled asset — a selected/active/on state — e.g. system-bookmark-simple-filled; a solid glyph survives greyscale
- slide-type / file-type — labelling a slide kind or a file kind; file-type glyphs keep their baked brand colour
Call by name from the registry — never inline an <svg>, never pull a second icon set (Lucide/Heroicons/FontAwesome/@ant-design/icons). Off-grid sizes (no 20px) aren't supported. Icon-only buttons need an aria-label (and a tooltip when the meaning isn't obvious). If a glyph is genuinely missing, add the SVG under icons/svg and re-run build-icons.mjs.
Surfaces
editor dashboard settings audience
Spec
Set 259 glyphs · system · slide-type · file-type · Source Figma Design System V3 · node 50699-7126 · Sizes 12 · 16 · 24 · 32 (only) · Colour currentColor / semantic token (254 recolorable) · State outline = neutral · -filled asset = active