| description | Migrates a v6 Theme class to the v7 unified struct() architecture using fluent builder pattern
|
| name | upgrade-theme-v6-to-v7 |
What I do
- Read a legacy v6 theme class (Bootstrap, DaisyUI, a custom third-party theme) from GitHub or local disk.
- Create a v7 theme class implementing the unified
struct() fluent builder plus the separate editable(), toggleable(), and filter() token methods.
- Map every legacy v6 array method (
table(), header(), checkbox(), searchBox(), filter*(), ...) onto the correct v7 builder chain.
- Verify the migrated theme defines every token the base
Tailwind theme defines.
This skill is the canonical owner of the complete v6 -> v7 mapping table, which lives in REFERENCE.md.
When to use me
- Porting a legacy PowerGrid v6 theme to the v7 architecture.
- Upgrading a custom theme that still returns arrays from
table(), checkbox(), footer(), etc. instead of building a struct().
How to use me
Use the 'upgrade-theme-v6-to-v7' skill to migrate the v6 Bootstrap theme at
https://raw.githubusercontent.com/Power-Components/livewire-powergrid/6.x/src/Themes/Bootstrap5.php
The three things that change in v7
- Arrays become a fluent builder. Instead of many methods each returning an array, one
struct(): Components\ThemeBuilder builds the whole tree with typed closures.
- The hierarchy is re-nested:
checkbox and radio move under table.
searchBox moves under header.
footer gains a nested layout sub-builder; the old footer_with_pagination becomes pagination().
editable(), toggleable(), and filter() stay separate methods (they are merged in via themeTokenMethods() in Theme.php), and each was reworked:
editable() adds clickable and error.
toggleable() is now five CSS color tokens (colorOn, colorOff, colorOnDark, colorOffDark, knobOn) set via ->fill([...]). The old view/base/label/input/role keys are gone.
filter() adds a label and a global input, and every filter type carries view/base (+ select or input).
Token keys are snake_cased by the builder's toArray(), so the fluent method ->thActions() is stored as the token table.layout.th_actions. You write camelCase; the resolved token path is snake_case.
Full builder-class method lists, the complete mapping table, and a full worked example are in REFERENCE.md.
Migration workflow
- Read the v7 base. Open
src/Themes/Tailwind.php. Its struct() is the source of truth: 41 struct tokens, plus editable() (4), toggleable() (5), and filter() (21). Do not rely on a memorized count -- diff against this file (see Validation).
- Read the v6 theme. Collect the CSS classes from every method:
table(), cols(), footer(), checkbox(), radio(), editable(), toggleable(), searchBox(), and each filter*().
- Create
src/Themes/[ThemeName].php extending \PowerComponents\LivewirePowerGrid\Themes\Theme and use PowerComponents\LivewirePowerGrid\Themes\Components;.
- Build
struct(): Components\ThemeBuilder, translating each v6 value with the mapping table in REFERENCE.md. Point baseView() at livewire-powergrid::components.themes.<name>.
- Add
editable(), toggleable(), filter() as separate methods (see the mini-example below).
- Validate the token set against
Tailwind (below), then update any references to the old theme class and run the tests.
Worked mini-example (v6 Bootstrap5 -> v7)
The struct() below shows all three structural moves. The complete class (with the full filter()) is in REFERENCE.md.
<?php
namespace PowerComponents\LivewirePowerGrid\Themes;
use PowerComponents\LivewirePowerGrid\Themes\Components;
class Bootstrap5 extends Theme
{
public function struct(): Components\ThemeBuilder
{
return Components\ThemeBuilder::make($this->name())
->baseView('livewire-powergrid::components.themes.bootstrap5')
->layout(fn (Components\Layout $layout) => $layout
->wrapper('')
->outsideFilters('')
)
->header(fn (Components\Header $header) => $header
->view('header')
->layout(fn (Components\Layout $layout) => $layout
->container('d-flex justify-content-between align-items-center mb-3')
->subContainer()
->()
->()
)
->(fn (Components\SearchBox ) =>
->()
->()
->()
->()
->()
->()
->()
->()
)
)
->(fn (Components\Table ) =>
->(fn (Components\Layout ) =>
->()
->()
->()
->()
->()
->()
->()
->()
->()
)
->(fn (Components\Body ) =>
->(fn (Components\Tr ) =>
->()
->()
)
)
->(fn (Components\Checkbox ) =>
->()
->()
->()
->()
)
->(fn (Components\Radio ) =>
->()
->()
->()
->()
)
)
->(fn (Components\Cols ) =>
->()
)
->(fn (Components\Footer ) =>
->()
->(fn (Components\Layout ) =>
->()
->()
)
->()
);
}
{
[
=> ( ())
->()
->()
->()
->()
->(),
];
}
{
[
=> ( ())
->([
=> ,
=> ,
=> ,
=> ,
=> ,
])
->(),
];
}
{
[
=> ( ())
->()
->(
->()
->()
->()
)
->(fn (Components\Component ) =>
->()
->()
->()
->()
)
->()
->(),
];
}
}
Validation
This is a package with no artisan console, so there is no interactive REPL to poke tokens in. Verify the token set with a Pest test that diffs the migrated theme's keys against the base Tailwind theme (drop it in tests/, run with ./vendor/bin/pest):
<?php
use Illuminate\Support\Arr;
use PowerComponents\LivewirePowerGrid\Themes\Bootstrap5;
use PowerComponents\LivewirePowerGrid\Themes\Tailwind;
it('defines every token the base Tailwind theme defines', function () {
$base = array_keys(Arr::dot((new Tailwind())->struct()->toArray()));
$migrated = array_keys(Arr::dot((new Bootstrap5())->struct()->toArray()));
expect(array_diff($base, $migrated))->toBe([]);
});
Arr::dot(...) flattens the builder output to dot-notation leaf keys (e.g. table.layout.th_actions), and array_diff reports any base key the migrated theme forgot. Extend the same assertion to ->resolveTokens() if you also want to cover the merged editable()/toggleable()/filter() tokens. Fill any reported gap with the appropriate class (or '').
Run the suite:
composer test
./vendor/bin/pest --filter=Theme
Checklist