Icons and Logos
Icons and Logos: anatomy, keyboard behavior, state, and theming in Askr.
Example
import { GitHubLogo } from '@askrjs/logos';
import { SearchIcon } from '@askrjs/lucide';
<>
<SearchIcon size={18} aria-hidden="true" />
<a href={repositoryUrl}><GitHubLogo aria-label="GitHub repository" /></a>
</>Icon contract
Every icon from @askrjs/lucide and every logo from @askrjs/logos renders through the same shared contract from @askrjs/askr/foundations: data-slot="icon", a data-icon name, a data-size token (sm/md/lg/xl) when you use one of the named sizes, and data-decorative="true" when no title is set. Size and stroke width also resolve through CSS custom properties (--ak-icon-size, --ak-icon-stroke-width), so a theme can restyle icons globally without touching component code.
Lucide imports
Import icons by name from @askrjs/lucide, e.g. import { SearchIcon, XIcon, MenuIcon } from '@askrjs/lucide', or reach a single icon directly via @askrjs/lucide/icons/search if you want the narrowest possible import path. Each icon is a generated Askr component function with a size, strokeWidth, color, and title prop — there's no string-based icon registry to look up names against.
Brand logos
@askrjs/logos currently covers five marks — GitHub, Facebook, Microsoft, Apple, and Google — each exported by name (GitHubLogo, FacebookLogo, and so on) or reachable individually through @askrjs/logos/logos/*. Apple and GitHub inherit currentColor so they follow surrounding text; Facebook, Google, and Microsoft keep fixed brand colors so the marks stay recognizable regardless of theme.
Accessible labeling
Icons and logos render aria-hidden="true" and skip a <title> element until you pass one — that's the decorative default. Passing title="Search" (or similar) drops aria-hidden and adds a real <title> node inside the SVG, which is what you want on a mark that carries meaning on its own. For icon-only buttons, prefer an aria-label on the button itself over relying on the icon's title.