@rdna/pixel
v0.3.0
Published
Framework-neutral pixel grids, masks, corners, patterns and static icons, with an optional React adapter
Downloads
133
Readme
@rdna/pixel
Framework-neutral one-bit grids, masks, corners, patterns and static icon data.
React rendering is optional and lives only at @rdna/pixel/react. Pixel supplies
style-producing utilities and assets; Radiants supplies ready-made styled
components, semantic theme tokens and the corresponding CSS.
Package status: public 0.3.0 candidate; publication and asset clearance are separate.
The installed package.json exports and built declarations define the public API.
The repository TypeScript source under src/ requires repository access; consumers use the built ESM/typing output from
dist/.
Public API
@rdna/pixel publishes built TypeScript/ESM subpaths from dist/:
| Subpath | Provides |
| --- | --- |
| @rdna/pixel | Neutral grids, masks, canvas/transition helpers, corners, patterns, lightweight Bayer/ramp/band helpers, pure icon preparation/conversion and types. No React, icon inventory, editor or Dither Studio closure. |
| @rdna/pixel/core | Grid parsing, validation, mirroring, hex conversion, and bit diff helpers. |
| @rdna/pixel/renderer | Canvas rendering helpers: paintGrid, paintTiledGrid, and createGridCanvas. |
| @rdna/pixel/import | SVG-to-grid import helpers and import report types. |
| @rdna/pixel/transition | Transition frame interpolation and flip ordering helpers. |
| @rdna/pixel/corners | Corner authoring, preparation, runtime materialization, shape registration, and concave helpers. |
| @rdna/pixel/dither | Bayer/ramp/band helpers plus the retained advanced Dithering Studio algorithms/palettes/integration. Import explicitly when needed. |
| @rdna/pixel/patterns | Pattern registry access and pattern preparation helpers. |
| @rdna/pixel/icons | Neutral icon definition/entry types, pure preparation, SVG conversion and path/mask helpers. |
| @rdna/pixel/icons/16px/<name> | One immutable default BitmapIconEntry for the exact canonical 16px name. |
| @rdna/pixel/icons/24px/<name> | One immutable default entry for the exact canonical 24px name, including its 21px live grid. |
| @rdna/pixel/icons/inventory | Explicit baked maps/lookups/source arrays and the separate authored definitions/name types. |
| @rdna/pixel/react | BitmapIcon icon={entry} and its span/accessibility props. No name lookup or inventory dependency. |
Public root types include PixelGrid, corner recipe/materialization types,
MaskAsset, MaskHostStyle, dither types such as BayerMatrixSize,
DitherDirection, and DitherRampOptions, pattern types, and pixel icon types.
Static icons and pure preparation
Install @rdna/pixel alone for neutral usage. React is an optional peer required
only if importing /react; no Next.js or editor package is required.
import close from '@rdna/pixel/icons/16px/close';
import { preparePixelIcon } from '@rdna/pixel/icons';
const custom = preparePixelIcon({
name: 'custom', width: 2, height: 2, bits: '1001',
});
// Both expose bits, path and maskImage. Preparation uses these supplied pixels,
// without a registry, global cache or mutation. Same-name grids stay independent.
console.log(close.size, custom.path);To render in React:
import { BitmapIcon } from '@rdna/pixel/react';
import close from '@rdna/pixel/icons/16px/close';
import music from '@rdna/pixel/icons/24px/coding-apps-websites-music-player';
<BitmapIcon icon={close} aria-label="Close" />;
<span id="music-label">Music</span>;
<BitmapIcon icon={music} aria-labelledby="music-label" />;
<BitmapIcon icon={music} displaySize={21} />;The span renders its currentColor SVG mask during SSR, with no effect or asset
request. Canonical 24px hosts position the 21px live mask at 1px 1px; other
display sizes center the unscaled authored mask. Classes and span/data/ARIA
attributes are forwarded. A label or aria-labelledby creates a named image;
unnamed icons are decorative by default. Explicit role and aria-hidden override
those defaults. The adapter owns geometry/mask styles, so it does not expose
style or children props; use a wrapper to set color and surrounding layout.
Inventory browsing is an explicit cost:
import {
bitmapIconSource, getBitmapIcon, pixelIconRegistry, preparePixelIconRegistry,
} from '@rdna/pixel/icons/inventory';
getBitmapIcon('close', 16); // same object as the static close export
getBitmapIcon('close', 24); // undefined; no implicit cross-size fallback
// bitmapIconSource contains all 305 + 662 converted entries.
// pixelIconRegistry retains the separate authored grid definitions.
// preparePixelIconRegistry() prepares those definitions with the neutral helper.Canonical filenames and case are preserved, including Business-Products-treasure.
The deterministic generator compiles only its converter dependencies, reads the
canonical Radiants SVGs and writes one payload per icon. Inventory maps import
those same payloads. scripts/icon-conversion-report.json records counts/skips;
conversion failures or unexplained source losses stop generation. No icons are
silently removed, redrawn or simplified.
Migration: replace name-based BitmapIcon with an explicit static icon entry;
move maps/lookups/source arrays and authored name types to /icons/inventory;
pass a definition to preparePixelIcon. There is no compatibility name adapter.
Pixel Corners
The current corner model is normalize -> prepare -> materialize.
prepareCornerProfile(shape, radiusPx)builds reusable cover and border mask assets.prepareCornerRecipe(recipe)normalizes per-corner authoring data and prepares fixed-shape corners.materializeCornerRecipe(prepared, { themeShape })returns CSS custom properties for the.pixel-cornerruntime host.- Radiants uses the same prepared profile path to generate static CSS utilities.
Corner helpers are exported from @rdna/pixel:
import { corner, px } from '@rdna/pixel';Runtime Corners
Use px() when corners are dynamic, per-corner, mixed-shape, or theme-driven.
px() accepts the canonical object config only and returns { className, style }.
CSS prerequisite: px()/concave() return classes and custom properties;
they do not install the host rules. With Radiants, load its normal CSS root in
your Tailwind v4 stylesheet before using these helpers or static corner/pattern
classes:
@import "tailwindcss";
@import "@rdna/radiants";Neutral consumers may supply equivalent host CSS themselves. Importing Pixel alone never loads Radiants CSS, React, or theme tokens.
<div {...px({
corners: corner.map(corner.themed(8)),
})}>
Theme-shaped corners
</div>Per-corner overrides are explicit:
<div {...px({
corners: corner.map(corner.themed(5), {
tl: corner.fixed('chamfer', 5),
tr: corner.fixed('circle', 5),
br: corner.flat,
}),
themeShape: 'scallop',
})}>
Mixed corners
</div>In that example:
tlis always chamfered.tris always rounded.bris flat.blfollows the live theme shape, materialized withthemeShape: 'scallop'.
Supported built-in shapes are circle, chamfer, and scallop. Custom shapes can
be registered with registerCornerDefinition().
Runtime Concave Corners
Use concave() for inverse/inner corner patches. It generates the used radius at
runtime from the same prepared corner profile as px().
import { concave } from '@rdna/pixel';
const patch = concave({
corner: 'br',
radiusPx: 11,
themeShape: 'chamfer',
});
<div className={`${patch.className} absolute right-0 bottom-0 bg-page`} style={patch.style} />;Omit shape for theme-bound output, or pass shape for a fixed override:
concave({ corner: 'tl', radiusPx: 11, themeShape: 'scallop' });
concave({ corner: 'tl', radiusPx: 11, shape: 'circle' });Radiants also exports useConcaveCorner(), which reads the live
<html data-corner-shape> value and passes it as themeShape.
Static CSS Utilities
Radiants generates static corner utilities from @rdna/pixel/corners.
<div className="pixel-rounded-8 bg-surface-primary">
Static rounded corner
</div>Current generated classes are numeric:
pixel-rounded-2
pixel-rounded-4
pixel-rounded-6
pixel-rounded-8
pixel-rounded-12
pixel-rounded-16
pixel-rounded-20
pixel-rounded-24
pixel-rounded-32
pixel-rounded-40
pixel-rounded-48
pixel-rounded-64
pixel-rounded-fullThere are no pixel-rounded-xs/sm/md/lg/xl aliases.
Cache Behavior
Prepared corner profiles are cached for radiusPx <= 32. Larger radii bypass the
profile cache so editor sessions can explore large values without unbounded cache
growth.
Dither
Dither lives under @rdna/pixel/dither and stays separate from the corner
prepare/materialize contract. It has its own prepared outputs for threshold and band
generation rather than CSS corner masks.
Package checks and rights
pnpm --filter @rdna/pixel build clears disposable dist first and emits typed
ESM. node packages/pixel/scripts/check-package-boundary.mjs resolves every
wildcard member and checks runtime/declaration closures. Packed files include
only emitted code/types and documentation/licenses, excluding tests, tooling
and source payloads.
Project-owned code is MIT; see LICENSE. The 24px Streamline family
and twelve beauty- authored definitions are CC BY 4.0 adaptations. Retained
Dithering Studio vendor code is Apache-2.0. The separate 16px collection and
small authored definitions retain an explicit origin-verification item. See
NOTICE.md and licenses/ for credit, source links and the exact
scope; the package does not claim all assets are MIT originals. Preserve
credits/license links and describe modifications when exporting edited assets.
