ComponentRegistry — Programmatic Discovery
Pushery\WireKit\ComponentRegistry is the canonical PHP-side surface for
discovering every component WireKit ships. Use it when your app needs the
component catalog at runtime — generating an autocomplete list in a
search widget, validating a CMS field against shipped components, building
a custom admin tool, or feeding an AI tool the full component schema.
The registry is the single source of truth. Every CLI command (wirekit:list,
wirekit:show, wirekit:export-json, wirekit:export-api-map) is a thin
wrapper around it — the same data shape, just formatted differently.
Quick Reference
use Pushery\WireKit\ComponentRegistry;
// Every component, keyed by name.
$all = ComponentRegistry::all();
// → ['button' => ['category' => 'Display', 'description' => '...'], ...]
// Just the count.
$count = count(ComponentRegistry::all());
// Just the names.
$names = array_keys(ComponentRegistry::all());
// → ['accordion', 'action-bar', 'alert', 'alert-dialog', ...]
// One component by name.
$meta = ComponentRegistry::get('button');
// → ['category' => 'Display', 'description' => 'Action button with variants and loading state']
// Every component in one category.
$formComponents = ComponentRegistry::category('Form');
// → ['checkbox' => [...], 'combobox' => [...], 'date-picker' => [...], ...]
// Every category that has at least one component.
$categories = ComponentRegistry::categories();
// → ['Form', 'Layout', 'Typography', 'Navigation', 'Overlay', 'Display', 'System']
// Props for a single component (the @props([...]) block, parsed).
$props = ComponentRegistry::extractProps('stat');
// → [
// ['name' => 'label', 'default' => 'null', 'default_normalized' => 'null', 'type_hint' => null, 'comment' => null],
// ['name' => 'value', 'default' => 'null', ...],
// ...
// ]
Methods
ComponentRegistry::all()
Returns every component keyed by its slug name. Stable shape across releases — adding a new component appends an entry; renaming requires a major-version bump.
/** @return array<string, array{category: string, description: string}> */
public static function all(): array;
ComponentRegistry::get(string $name)
Returns the metadata for one component, or null when the name isn't
registered. Same shape per-entry as all().
/** @return array{category: string, description: string}|null */
public static function get(string $name): ?array;
ComponentRegistry::category(string $category)
Returns every component in a category. Empty array when the category doesn't exist.
/** @return array<string, array{category: string, description: string}> */
public static function category(string $category): array;
ComponentRegistry::categories()
Returns every unique category name across the registry. Order is insertion-order, which matches the source-file declaration sequence.
/** @return list<string> */
public static function categories(): array;
ComponentRegistry::extractProps(string $name)
Returns the structured @props([...]) block for a component. Routes
through Pushery\WireKit\Support\PropsParser, which uses PHP's own
tokenizer — no regex parsing of the prop expressions, so config(...)
defaults, multi-line array literals, match(...) expressions, and
heredoc / nowdoc values all parse cleanly.
/**
* @return list<array{
* name: string,
* default: ?string,
* default_normalized: ?string,
* type_hint: ?string,
* comment: ?string,
* }>
*/
public static function extractProps(string $name): array;
Per-record fields:
| Field | Purpose |
|---|---|
name |
Prop name (string-key from the @props array, quote-stripped). |
default |
Raw default expression as it appears in source. null when the prop has no => default clause. |
default_normalized |
Same expression with whitespace collapsed and comments stripped. Stable for string comparison. |
type_hint |
Reserved for future @phpdoc-driven augmentation. Currently always null. |
comment |
The trailing same-line // … comment after the prop's comma, if any. Leading // stripped + trimmed. |
AI Tooling / LLM Consumption
This page is the canonical programmatic API for component discovery.
AI tools (Cursor, Claude Code, MCP servers, Aider) should prefer the PHP
surface above OR the matching CLI flags below — both are stable across
releases. Do not parse wirekit:show output programmatically — it's
optimized for human reading and isn't shape-stable.
Machine-readable CLI surface
| Need | Use |
|---|---|
| Total component count | php artisan wirekit:list --as=count |
| Component name list | php artisan wirekit:list --as=slugs |
| Per-category count map | php artisan wirekit:list --as=categories |
| Full per-component metadata | php artisan wirekit:list --as=json |
| Single component schema (props + sub-components) | php artisan wirekit:show <name> --as=json |
| Full manifest with slots | php artisan wirekit:export-json --pretty |
All output is plain-stdout JSON with no decoration, suitable for jq
pipes. The schemas are stable for v2.x — additive new fields may appear,
existing field shapes won't change without a major-version bump.
Categories
The canonical category enum across ComponentRegistry:
| Category | Definition | Examples |
|---|---|---|
Form |
Inputs and form-related controls. Carries focus/validation semantics. | input, select, combobox, date-picker, file-upload, checkbox, toggle |
Layout |
Structural primitives that compose page chrome and content regions. No conversion intent. | app-shell, container, grid, stack, header, main, sidebar, footer |
Typography |
Text-rendering primitives — body copy, headings, inline marks. | heading, text, prose, link, code, code-block, blockquote, kbd |
Navigation |
Wayfinding chrome and link surfaces. | navbar, tabs, breadcrumb, sidebar, pagination, stepper, brand-bar |
Overlay |
Layered surfaces that float above content (modal, drawer, popover, tooltip). | modal, drawer, dropdown, popover, tooltip, command-palette, alert-dialog |
Display |
Generic content presentation — cards, alerts, badges, charts. | card, alert, badge, button, stat, chart, calendar, avatar |
Marketing |
Components whose PRIMARY purpose is marketing / conversion. Narrow scope, clear semantic — added in v2.1.0. | cta, feature, feature-grid, hero |
System |
Infrastructure / glue primitives — icon resolution, font registration, structured-data emitters. | chart, icon, fonts, glass, structured-data |
Usage criteria. When deciding which category a new component belongs to, ask: "What is the component's primary use-case?"
- A
ctaprimitive lives or dies by its conversion-funnel role →Marketing. - A
revealanimation primitive serves marketing landing pages but is also generic →Display. - A
footeris used on every page including non-marketing →Layout. - A
brand-baris header chrome reused across marketing, app, and docs sites →Navigation.
The Marketing category was added in v2.1.0 with four canonical entries. Reserve it for components whose conversion intent is their defining trait — not every component USED on a marketing page belongs here.
Categories are stable for v2.x. Re-categorization is a ### Changed
entry in the public CHANGELOG.
See Also
- Authoring Custom Components — how to
write your own
@props([...])blocks and have them parse cleanly. - Authoring Custom Alpine Plugins — defensive-cleanup pattern for plugins that drive your components.
- CLI Reference — the full command surface.