hp-pixel
Box-shadow pixel art. Ships built-in morphing icon sets (type), renders custom
ASCII art (art), or takes consumer-supplied state records (states);
sprite-sheet frames come later. Every state of an icon shares the same logical pixels, so
the browser interpolates each pixel's path smoothly.
Built-in sets need no wiring beyond type + interactive. All three
idle as the dotted square; hover previews the action, and a click toggles the committed
state — click them: menu holds its cross, expandable and
dropside flip their chevrons, until clicked again. The committed state rides
aria-pressed, which interactive maps to the active
frame — the demo's only script is the toggle.
Custom art comes in two flavours: a static ASCII grid, or your own named state record for bespoke morphs — the built-ins use exactly the same mechanism.
Install
bun add @hexpunk/core lit import "@hexpunk/core"; Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
art | art | string | undefined | — | Static ASCII grid. `#` = lit, `.` = empty, digits index into `palette`. |
type | type | "menu" | "expandable" | "dropside" | undefined | — | Built-in icon set by name — no JS wiring needed. Explicit `.states` / `.palette` win when both are set. |
state | state | string | undefined | — | Current state when `.states` is set. Falls back to `"idle"`. |
pixelSize | pixel-size | number | 3 | Pixel size in CSS px. Default `3`. |
interactive | interactive | boolean | false | Auto-swap to `hover` / `focus` / `active` named states on the matching pseudo-classes. No JS state-flip required. |
When to use
type first — menu for
navigation/overflow triggers, expandable for expand/collapse affordances.
No JS wiring, and the sets follow the system's state vocabulary.
interactive wires CSS-only swaps for :hover /
:focus-visible / :active / [aria-pressed]; keep
every state the same pixel count so the interpolation stays smooth.
--hp-pixel-<name> custom property, so a parent's selector can set
--hp-pixel-shadow: var(--hp-pixel-active). The stats trigger on the
hp-background page composes type="expandable" this way.
--hp-pixel-shadow inline while interactive is enabled —
the inline override beats the CSS-driven swaps and locks the art to one frame.
<hp-pixel> when you need stroke-icon parity. Use
<hp-icon> for Lucide-style icons that should match icon-sm/md/lg
tokens.
- 0.1.1-alpha 2026-08-10
Added
<hp-pixel>typeattribute — built-in morphing icon sets resolved by name, no JS wiring:menu(dotted square → plus on hover → cross toggled),expandable(square → down-chevron → up-chevron),dropside(square → right-chevron → left-chevron). Faithful to the CodePen reference, including the parked corner pixels that fly outward and fade during arrow morphs (icons can now bundle a palette). Precedence: explicitstates>type>art.