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

Statamic Color Swatches Laravel Package

rias/statamic-color-swatches

Statamic Color Swatches adds a configurable color picker fieldtype for the Statamic control panel, letting editors choose from predefined swatches and palettes instead of typing hex values. Keep brand colors consistent across entries and simplify content editing.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and the addon auto-registers through Statamic's package discovery:

composer require rias/statamic-color-swatches

No publish step or config file is needed — the AddonServiceProvider registers the color_swatches fieldtype and its Vite assets automatically. The committed dist/ build means you don't need to run npm install/npm run build on the consuming site.

Your first use case is a color picker on a page or global set. Add the fieldtype to a blueprint:

fields:
  -
    handle: brand_color
    field:
      type: color_swatches
      display: Brand Color
      colors:
        - label: Primary Blue
          value: ['#0066cc']
        - label: Sunset
          value: ['#ff7e5f', '#feb47b']

The editor sees one clickable swatch per entry (gradients are rendered automatically when an entry has multiple values via createCssBackgroundFromColors). Saved data lands in your content as:

{ "label": "Primary Blue", "value": ["#0066cc"] }

Where to look first:

  • src/ColorSwatchesFieldtype.php — the $configFields array is the real API surface; it tells you exactly which YAML keys (colors, label, value) are accepted.
  • resources/js/ColorSwatchesFieldtype.vue — to understand how the selected value is emitted via this.update(value).
  • README / agents/AGENTS.md — the data shape and handle naming.

For templating, remember the stored value is an object, not a plain string:

{{ if brand_color }}
  <span style="background: {{ brand_color:value | join(',') }}">{{ brand_color:label }}</span>
{{ /if }}

Implementation Patterns

Single-value swatches for UI tokens. Keep the value array to a single hex for things like button colors, and read brand_color:value:0 directly in Antlers. This is the most common pattern and the one GraphQL optimizes for (see Gotchas).

Gradient / multi-stop values. Supply multiple CSS strings in value and the component composes a linear-gradient swatch. The same array round-trips to your front end, so you can reuse it as a CSS background:

<div style="background: linear-gradient(to right, {{ brand_color:value | join(', ') }})"></div>

Pair the fieldtype with a palette source of truth. Because colors are declared per-blueprint in YAML, teams often duplicate the same palette across blueprints. A maintainable pattern is to define the palette once in a config file and inject it into the blueprint at boot via a Blueprint::saving/Blueprint::loaded listener, or a custom fieldtype extension. This avoids drift between page, global, and component blueprints.

Index/listing views. The addon ships ColorSwatchesFieldtypeIndex.vue, so the swatch renders as a colored chip in collection listings without extra work — just declare the field in the blueprint's list of columns. Use this for editorial dashboards where scanning color usage matters.

GraphQL-driven headless setups. ColorSwatchType exposes label and value. In a headless build, query it and resolve the CSS client-side:

{ entry { brand_color { label value } } }

Treat value as an array (see Gotchas for the resolver caveat) and build the gradient in your front-end framework rather than trusting a single string.

Augmentation for derived fields. The fieldtype's augment() passes data through unchanged, so if you need a pre-computed css string, add your own accessor on the entry/blueprint rather than relying on the fieldtype.

Gotchas and Tips

GraphQL collapses multi-value swatches. ColorSwatchType resolves value to Arr::first(), so a gradient stored as ['#a', '#b'] returns only '#a' over GraphQL. If gradients matter in a headless context, add your own type or read the raw field through a custom resolver — don't assume parity with the CP/REST output.

process() normalizes comma-separated strings to arrays. Existing content or imported data that stores '#a, #b' becomes an array on save. Be careful with idempotent importers: run imports through the fieldtype or normalize yourself, or you'll get double-wrapping.

The stored shape is an object, not a scalar. Unlike a color field, {{ brand_color }} in Antlers prints nothing useful. Always reach into :value (a string list) and :label. Watch for falsey checks — {{ if brand_color }} is true when the object key exists even if value is empty; check {{ if brand_color:value }} instead.

Fieldtype handle is derived, not declared. ColorSwatchesFieldtype → color_swatches. If you alias or extend the class to add behavior, the handle changes and the Vue component registration (color_swatches-fieldtype) must match. The safest extension point is the class itself plus keeping the same handle; renaming requires you to register a matching component.

No tests, no lint config. The repo intentionally ships without PHPUnit/Pint/PHPStan. If you fork or vendor-patch it, add your own vendor/bin/pint and a small ColorSwatchesFieldtypeTest for process()/augment(); the normalization logic is the part most likely to bite during upgrades.

dist/ is committed — don't run npm run build blindly. If you modify JS, rebuild and commit dist/, because Composer consumers never run Vite. For local development, npm run dev starts Vite with HMR disabled, so you'll hard-refresh the CP. If the CP shows a stale/blank swatch after an update, the most common cause is a dist/ that doesn't match resources/.

Vue is externalized. Don't import Vue or Pinia into your components — they're provided by Statamic's CP runtime. A second Vue copy breaks mixins like Fieldtype and IndexFieldtype, so avoid adding conflicting dependencies to the Vite config.

CSS is scoped to .color_swatches-fieldtype. Override swatch styles by targeting that wrapper plus the color-swatches- prefixed classes. Use Statamic's CSS custom properties (e.g. var(--color-zinc-800)) so your overrides survive dark mode and theme changes.

Value validation is your responsibility. There's no schema validation of the colors config — a typo in label or a missing value renders an empty swatch rather than erroring loudly. Validate palettes in a CI check or an addon boot guard; debugging a blank swatch in the CP usually means a malformed blueprint entry.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel