Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shape Laravel Package

onelegstudios/shape

Shape offers a simple, expressive way to define and transform structured data in Laravel, so you can build consistent arrays, DTOs, and API payloads with less boilerplate and clearer intent. It helps keep validation, casting, and output formatting predictable across your app.

View on GitHub
Deep Wiki
Context7

Getting Started

Shape is a Blade component library for Livewire apps with no build step: no compiled CSS, no publishable config, no asset pipeline.

composer require onelegstudios/shape
php artisan shape:install   # tokens, script, component set

shape:install is the only required step. It writes the theme tokens and the single overlay script into your app; after that <x-shape::button>, <x-shape::input>, <x-shape::modal> and the rest resolve against your existing Tailwind setup. If you already run Tailwind, verify the tokens landed where your CSS entrypoint imports them — that is the first thing to check if components look unstyled.

First use case: replace a hand-rolled form. Take one field-to-input group, one button, and one modal in a single screen, then run php artisan shape:doctor before you commit. That gives you a working vertical slice and proves the Blaze-safety story early, when it is cheap to react to.

Read the docs in docs/ on GitHub, and run the workbench locally to see rendered examples of every prop. Because the docs examples are compiled by the test suite, they are a more reliable API reference than your IDE autocomplete will be — anonymous Blade components have no signatures to introspect.

Implementation Patterns

Compose forms around field context. field carries the name once; input, textarea, select, checkbox, radio and switch pick it up as context rather than repeating it. Build a form as a set of <x-shape::field name="..."> blocks and let the children inherit — this is the pattern the library is optimised for and the one that keeps error state and labels consistent.

Treat variant and tone as orthogonal axes. variant is hierarchy (primary, secondary, ghost); tone is semantics (neutral, danger, success). A destructive action should usually be a quiet variant with a danger tone until the moment it matters, then swap to the prominent variant. Reach for both props rather than inventing bespoke classes for "red button".

Use the platform primitives for overlays. Modal and drawer are <dialog>; dropdown, popover and tooltip use popover. The focus trap, Escape, light dismiss and scrim are the browser's — do not layer Alpine x-trap or a JS focus library on top, and do not fight the top layer with z-index classes. The shipped script is one dependency-free file; load it once from your layout.

Route feedback through Shape::toast() and Shape::confirm() in Livewire actions. They dispatch a browser event when there is a Livewire request to ride on, and flash to the session otherwise, arriving as the same event. One handler in your layout builds the toast either way:

Shape::toast('Saved', tone: 'success');
Shape::confirm('Delete this?')->then('post-deleted');

then() names a window event, which is exactly what #[On('post-deleted')] already listens for — no bespoke callback plumbing.

Eject before you fork. When a component needs behaviour the props don't cover, php artisan shape:eject modal pulls the component and its dependency graph, recording the package's version of each file. You own the copy; shape:eject:status later tells you which files you edited and which the package changed underneath you. shape:eject:all is a legitimate adoption strategy for a team that wants the library as a starting point rather than a dependency, but do it deliberately — you lose upstream fixes.

Generate icons instead of hand-writing SVG. php artisan shape:icon bell trash writes an icon component per name from your chosen set (Heroicons, Lucide, Tabler, Phosphor, Bootstrap, Remix, Material Symbols, or any directory of SVGs), pinning the upstream commit into every file. The fourteen icons Shape draws itself are named by role (shape-close, shape-warning), so shape:icon:replace --set=lucide swaps the visual set without touching a single call site.

Gotchas and Tips

Folded components cannot read request-scoped state. This is the failure mode worth internalising. Under Blaze, a component is pre-rendered while Blade compiles; auth(), session(), config() or __() inside one resolves once and is then served to everybody. There is no stack trace and nothing looks wrong in development — a single developer's session renders fine. Always compute permissions and translations in the Livewire component or the page, pass them in as props, and run shape:doctor in CI (it exits non-zero) so an ejected component that drifts into this trap fails the build.

Blaze is optional, so the annotations are not load-bearing for correctness. Without it, components render normally and the annotations compile away. Do not assume a component is broken because it is not folding — check with Blaze installed and enabled before you start refactoring.

Zero-specificity defaults cut both ways. App classes win without !important, which is the point, but two Tailwind utilities that set the same property still resolve by source order in the generated stylesheet. If your override "doesn't work", it is usually ordering, not specificity — move the utility class or use a component prop.

Shape::confirm() from outside a request never lands. The Livewire path needs a Livewire request to ride on; the flash path needs a subsequent request to read the session. Calling it from a queued job or a console command will silently produce nothing visible. Dispatch it from the component action that the user triggered.

Theming is aliases, not copies. Retinting Tailwind's colours retints Shape with them, so do not hardcode palette values in your own CSS and expect consistency. The per-surface foreground contract matters: if you introduce a new surface (a custom card background, a coloured banner), define its foreground alongside it or contrast will break in one theme and not another.

The seed stylesheet is a starting point, not a colour picker. Each ramp step pins its own OKLCH lightness and takes only hue and chroma from your seed, which is what makes the contrast guarantee hue-independent. Overriding individual steps by hand throws that away — if a seed's brand feels wrong, change the seed, don't patch step 600.

shape:eject:status needs the recorded baseline. It compares against what the package held when the file was copied, so it is only meaningful for files ejected through the command. Files you copied manually or moved after ejection are invisible to it — keep ejected components where the command put them.

0.x means pin. Component APIs may still change before 1.0, and because these are anonymous Blade components, a renamed prop fails at render time rather than at analysis time. Constrain the version in composer.json, and read the upgrade notes before bumping. The docs-example test suite is your best signal that a prop rename happened — if your own views aren't covered by a similar smoke test, add one that renders each Shape-heavy page.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo