tipowerup/ti-theme-toolkit
Shared PHP + frontend toolkit for TastyIgniter themes. Build a custom theme with minimal PHP via AbstractThemeServiceProvider, plus palettes, field schema, widgets, Livewire auth/contact/newsletter components, dark mode, and Tailwind/Vite/Alpine presets.
AbstractThemeServiceProvider::registerStorefrontErrorViews() pushes the
theme's resources/views onto config('view.paths') so Laravel's
exception handler resolves errors::404 / errors::500 etc. to the
theme's templates instead of TastyIgniter core's minimal fallback. Gated
on ! Igniter::runningInAdmin() so admin-area exceptions keep rendering
the admin error UI, and a no-op when the theme ships no errors/
directory. Also binds a composer that injects themeBrandStyle /
themeNeutralStyle into errors.layout (the wildcard composer can't,
since the exception handler renders outside any TI controller).AbstractThemeServiceProvider::registerAutoVendorPublish() listens on
main.theme.activated and runs igniter:theme-vendor-publish --theme=<code> --force
in-process when the theme matching the SP's themeCode() is activated.
Closes the gap where TastyIgniter only auto-publishes during
igniter:install — themes installed and activated afterwards no longer
ship with missing favicons / fallback logos / static assets until an
admin remembers to run the command. Listener is scoped to the active
theme (so other toolkit-using themes don't cross-publish), skipped under
runningUnitTests(), and wraps the artisan call in a try/catch — a
failed publish logs a warning instead of breaking activation.Two unrelated lines of work shipped together in this minor bump.
.d.ts companions for vite-preset and dark-mode
(same pattern Vite and Tailwind use). No build step required — full
IntelliSense for consuming themes, with TS opt-in detected automatically.app.ts over app.js in the Vite preset so themes
can switch to TypeScript without changing config.ColorHelper / ThemePayloadResolver
with a light-mode-scoped <style> block for tokens that can't ride on
the <html> style attribute.themeBrandStyle and themeNeutralStyle exposed on the view
composer, plus bound to TI's controller var bag for non-Livewire page
renders.theme.css directly via [@import](https://github.com/import). No more PostCSS
/ JS preset layer.vite-preset.js switches to [@tailwindcss](https://github.com/tailwindcss)/vite with deterministic
output paths.AbstractThemeServiceProvider::phpNamespace() defaults via
reflection of the concrete child SP. Themes only need to override if
their classes live under a different namespace from the SP itself.tailwind-preset.js — Tailwind v4 doesn't need it.resources/src/css/tokens.css — superseded by theme.css.Login, Register,
ResetPassword, Socialite) plus Contact and NewsletterSubscribeForm
now live in the toolkit. Themes only own the corresponding blade views;
business logic is single-source.Forms\LoginForm and Forms\RegisterForm.loadLivewireComponentsFrom() now
accepts an optional $livewireNamespace argument. The toolkit scans its
own src/Livewire/ first under the active theme's view namespace, then
the theme's src/Livewire/. Livewire registration is last-writer-wins,
so themes can override any toolkit component by dropping a class with the
same relative path.{ns} / {lang} placeholder substitution in componentMeta().
Toolkit Livewire classes return placeholder-formatted descriptors
(e.g. '{ns}::login', '{lang}::default.component_login_title'); the
auto-loader's new resolveComponentMeta() substitutes them with the
active theme's viewNamespace() and translationNamespace() at
registration time.tipowerup.theme.viewNamespace. Bound at SP boot;
toolkit Livewire components fall back to it when controller() is null
(e.g. under testbench / Livewire tests).registerStaticPageResolverPatch() registers a corrective
pages.menuitem.resolveItem listener so static-page menu items resolve
to the page matching their reference id instead of the alphabetically-
first cached page. Becomes a redundant override once upstream merges;
marked with a TODO: remove once #21 is merged.*Form.php filter regression.AbstractThemeServiceProvider::loadLivewireComponentsFrom() signature.
Now accepts ?string $livewireNamespace = null as a second argument
(defaults to phpNamespace().'\\Livewire\\'). Existing callers are
unaffected.AbstractThemeServiceProvider::loadLivewireComponentsFrom() filename
filter. Removed the overly-broad notName('*Form.php') rule, which
was excluding real Livewire components whose class name ends in Form
(e.g. NewsletterSubscribeForm). Forms helper classes are still
excluded via notPath('Forms').AbstractThemeServiceProvider::registerMobileMenuViewComposer(). The
composer was hardcoded to query main-menu and unconditionally override
$menuItems for the includes.navs.mobile-menu partial, clobbering items
passed by the <x-nav> component. Themes that need a mobile-menu now
seed it via resources/meta/menus/mobile-menu.php and the Nav view
component owns the data flow.History prior to this release lives in git log.
How can I help you explore Laravel packages today?