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

Color Scheme Bundle Laravel Package

idci/color-scheme-bundle

A Symfony bundle for managing color schemes in your application. Define named palettes, organize colors centrally, and reuse them across templates and configuration so themes stay consistent and easy to update. Useful for theming and design-system work.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this repository as a read-only spec, not a dependency. The single most important first step is confirming that in composer.json: the require block will pin symfony/symfony at a 2.x range (EOL since November 2018), which is mutually unsatisfiable with any maintained Laravel release. Do not run composer require idci/color-scheme-bundle — it will cascade your dependency tree into an unresolvable state.

Minimal path to first value, in order:

  1. Clone read-only and inventory (~1 hour).
    git clone <repo> /tmp/color-scheme-ref && cd /tmp/color-scheme-ref
    cat composer.json          # what it depends on; is there a wrapped core lib?
    find . -type f -name '*.php' | head -50
    ls -R Resources/config     # services.xml + doctrine mappings
    
  2. Read the DI extension first. The DependencyInjection/*Extension.php file contains the Configuration tree — that is the authoritative list of what dimensions a "color scheme" has in this package (name, palette entries, defaults, maybe an entity class). This is the schema you actually want to port.
  3. Read the Twig extension second. It reveals the public API surface — typically getScheme(name), getColors(), getComplementary(), getAnalogous(), getTriadic(). That method list is your interface contract.
  4. Check for a wrapped core library. Bundles of this shape often thin-wrap a standalone idci/color-scheme package. If that core library is framework-agnostic and still on Packagist, that is installable in Laravel; the bundle is just Symfony glue.

First use case to target: a tenant-branded color scheme resolved per request. Concretely — a config/color-scheme.php with named palettes, a ColorSchemeManager singleton, a ResolveColorScheme middleware, and a @colorScheme Blade directive that emits CSS custom properties into your layout. That is ~200 lines and covers the same ground as the bundle's entire feature set. Budget 3–5 engineer-days including tests.

If you genuinely maintain a frozen Symfony 2.8 app, the steps are different: register the bundle in AppKernel::registerBundles(), add idci_color_scheme: { ... } to config.yml, and inject the manager service. But that is the only scenario where the code runs as shipped.

Implementation Patterns

Pattern 1 — Config-defined palettes (the portable core). The bundle models schemes as named sets in configuration. Re-express that directly as a Laravel config file, which gets you config:cache support for free:

// config/color-scheme.php
return [
    'default' => 'neutral',
    'schemes' => [
        'neutral' => ['primary' => '#1a1a1a', 'accent' => '#0066cc', 'surface' => '#ffffff'],
        'dark'    => ['primary' => '#f5f5f5', 'accent' => '#66b3ff', 'surface' => '#111111'],
    ],
];

Pattern 2 — Resolution precedence chain. This is where the bundle's design is worth copying: it separates scheme definition from scheme resolution. Implement an explicit cascade so behavior is never ambiguous:

// explicit override → user preference → tenant default → app default
public function resolve(Request $request): array
{
    $name = $request->query('scheme')
        ?? optional($request->user())->color_scheme
        ?? optional($request->user()?->tenant)->default_color_scheme
        ?? config('color-scheme.default');

    return config("color-scheme.schemes.{$name}", config('color-scheme.schemes.'.config('color-scheme.default')));
}

Bind it once, resolve once per request via middleware, share via View::share or a view composer so Blade doesn't re-resolve.

Pattern 3 — Persistence. The bundle associates schemes with your entities via Doctrine mappings under Resources/config/doctrine. The Laravel equivalent is a single additive column and no pivot table:

Schema::table('users', fn (Blueprint $t) => $t->string('color_scheme')->nullable()->index());

Store the scheme name, never serialized colors — otherwise config changes require a data migration.

Pattern 4 — Presentation layer. The bundle's Twig extension becomes a Blade component that emits design tokens rather than inline styles, so the scheme is consumable by Tailwind/CSS:

{{-- resources/views/components/color-scheme.blade.php --}}
<style>
  :root {
    @foreach ($scheme as $token => $hex)
      --color-{{ $token }}: {{ $hex }};
    @endforeach
  }
</style>

Pattern 5 — Extension point parity. The bundle's extensibility comes from overriding its manager service in the container. In Laravel the analogue is a contract plus contextual binding:

$this->app->singleton(ColorSchemeManager::class, fn ($app) => new ColorSchemeManager($app['config']));
// and for tests:
$this->app->instance(ColorSchemeManager::class, new FakeColorSchemeManager());

Symfony-native usage, for reference only: services are declared in Resources/config/services.xml and injected by id; the Twig extension is registered with a twig.extension tag; scheme entities use Doctrine annotations in Model/. Compiler passes and XML service definitions have no Laravel analogue — do not reproduce that structure in a provider. Over-engineering the provider to mirror Symfony's container model is the most common way this port goes wrong.

Gotchas and Tips

  • The framework mismatch is the headline. No ServiceProvider, no auto-discovery, no config/ publish tag, no Blade directives. Any "integration" is a clean-room port. Estimate accordingly and set the expectation up front so nobody budgets for a shortcut.
  • Syntax archaeology. Expect PHP 5.5–7.0 idioms: no declare(strict_types=1), no return types, array() literals, possibly Twig_Extension and other pre-namespace or early-namespace class references. Do not paste files and let the linter "fix" them — reimplement from the schema summary and avoid license contamination from unverified copied code.
  • Configuration tree defaults are silent. Symfony's TreeBuilder will fill unspecified keys with defaults and never warn. When extracting the schema, read ->defaultValue() calls explicitly — that's where implicit contract lives (e.g. what "default scheme" means when the DB column is null). Reproduce those defaults deliberately in config/color-scheme.php.
  • Color math is computed, not validated. Helper methods like getComplementary() / getAnalogous() derive colors algorithmically from an HSL rotation. They do not check contrast. If WCAG 2.1 AA is a requirement, the algorithmic helpers are unusable as-is — you must constrain selection to pre-validated palettes and add a contrast assertion in tests (a unit-testable contrastRatio() helper is cheap insurance against white-on-white regressions).
  • Silent fallback is the production failure mode. An unknown scheme name that returns [] renders an unstyled page that looks broken but throws nothing. Always terminate the resolution chain with an explicit default and assert non-empty in a feature test.
  • Doctrine mapping quirks in the original. Mappings may live in XML/YAML under Resources/config/doctrine rather than annotations, and the entity directory may not be PSR-4. Don't assume src/; don't trust autoload paths. In the port, prefer Eloquent's conventional migration over replicating a mapping layer.
  • Cache the resolved token map, keyed correctly. Resolve once per request (middleware + container singleton). If you cache across requests, key by (tenant, user_preference) — not by user id — to keep cardinality bounded and avoid an unbounded cache key space.
  • N+1 on tenant lookup. If the tenant default lives on a related model, eager-load or cache it. This is the one place a trivially cheap manager can become a per-request query storm.
  • Debugging the original (Symfony context). php bin/console debug:container idci_color_scheme and debug:config are your tools; the container dump shows whether the manager service is public. In the Laravel port, php artisan tinker plus config('color-scheme.schemes') after php artisan config:clear — remember that config:cache will freeze your palettes and make runtime overrides invisible.
  • Two sources of truth. If a design-token layer (CSS custom properties, Tailwind theme) already exists or is planned, make the manager a consumer of those tokens. Defining a parallel palette here guarantees a reconciliation task later.
  • Archive with a warning. Put a "do not install — reference only" note in your internal package records. The realistic failure mode isn't a bad integration; it's a future engineer rediscovering this repo and running composer require against a modern Laravel app.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager