K

Core

Colors

The one resolver every coloured surface goes through — the vocabulary, the fallbacks, and why a badge and a button agree.

Colors preview
On this page

A colour in this framework is a semantic namesuccess, danger, a Tailwind palette name — resolved to utility classes by one owner. A badge, a button, a toast and a chart item all ask it, which is why they cannot drift, and why a new surface gets the whole palette for free.

Colors

->color() accepts the complete Tailwind palette on every surface. Two vocabularies resolve through the same canonical map:

Semantic roles

primaryyour accent
graysecondary
successemerald
danger
warningamber
info

Raw hue families

blue
green
red
yellow
cyan
slate
zinc
neutral
stone
orange
lime
teal
sky
indigo
violet
purple
fuchsia
pink
rose

Achromatic (adaptive)

white
black

Semantic roles — fixed brand hues that carry meaning:

Name Resolves to
primary Brand primary
success (alias emerald) Emerald
danger Red
warning (alias amber) Amber
info Cyan
gray (alias secondary) Neutral gray

Raw hue families — every Tailwind color, for finer control:

blue, green, red, yellow, cyan, slate, zinc, neutral, stone, orange, lime, teal, sky, indigo, violet, purple, fuchsia, pink, rose.

Literal hues are not aliases. blue, green and yellow are their own literal Tailwind hues — blue is distinct from the re-themeable brand primary, green from success/emerald, and yellow from warning/amber. red and cyan render the same hue as danger/info but stay available by name.

Achromatic endpointswhite and black. Tailwind has no numeric white/black scale, so these resolve adaptively: black is a dark ink/fill in light mode and flips to white in dark mode, white is the inverse — so they stay readable on both themes.

Action::make('delete')->color('danger'); // semantic role
Action::make('archive')->color('teal'); // raw hue
BadgeColumn::make('status')->colors([
'active' => 'success',
'pending' => 'warning',
'inactive' => 'danger',
]);

The type-safe Foundation\Colors\Color enum has a case for every one of these (Color::Danger, Color::Teal, …). Each color resolves to Tailwind utility classes for bg, text, border, ring, and hover variants — the same value renders identically on a badge, a solid/outlined/link button, a modal, a choice card, and a chart bar.

Canonical color resolvers (HasColor)

Foundation\Concerns\HasColor is the door every surface asks through. Ask it rather than re-encoding a match map, and a colour resolves the same way everywhere.

The rules themselves live in five classes under Foundation\Colors, one per surface — ButtonPalette, TintPalette, TextPalette, NoticePalette and ChartPalette — because a decision about an alert is a different decision from one about a chart. Keep calling HasColor: the palettes are where a rule is found and changed, not a second set of names to call.

A role is not a hue. success, danger, warning and info render as whatever wire-core.colors points them at, resolved once by Foundation\Colors\SemanticPalette at the top of every resolver — see Theming → Semantic roles. The literal hues stay first-class: green is literal green, distinct from a re-pointable success, and the adaptive white/black endpoints resolve to themselves.

Resolver Surface
getSolidColorClasses() filled button (bg + text + hover + focus + dark)
getOutlinedColorClasses() outlined button
getGhostColorClasses() dropdown / menu item
getIconButtonColorClasses() icon-only button
getLinkColorClasses() text/link button (underline on hover)
getSolidBgClass() / getSoftBgClass() bare fill only (toggle on/off track, count badge)
getBadgeColorClasses() soft "pill" badge (bg + text)
getTextColorClasses() foreground-only text tint
getChoiceColorClasses() radio/segmented/card selected state bundle
getModalSubmitButtonClasses() modal confirm/submit button
getModalIconBgClass() / getModalIconTextClass() modal icon chip
getGradientFillClasses() / getFillTextClasses() bar-chart fill + accent (literal chart hues)
getOutlinedClasses() the outlined vocabulary, callable outside a component
getRowTintClasses() / getRowHoverClasses() a clickable table row, at rest and under the pointer
getSoftTintClasses() the resting fill with no hover — a diff cell, a soft block
getAccentBgClass() the bright -500 accent — a live dot, a progress bar, a filled star

When adding a color or surface, extend the palette that owns it once — downstream columns, badges, actions, and toggles pick it up automatically. Keep utility names compatible with the lowest supported Tailwind version (see ADR 0005); use only standard hue names, never version-specific ones.

Canonical sizing & typography resolvers

Sibling single-source resolvers, used the same way as HasColor — extend once, every surface picks it up, and class strings stay literal for Tailwind's JIT scanner.

Resolver Surface
HasSize::getBadgeSizeClasses($size) soft "pill"/badge padding + font size
HasSize::getButtonSizeClasses($size, $iconOnly) button padding scale (action buttons, action-group triggers, ButtonColumn); $iconOnly returns square padding
HasFontWeight::getFontWeightClasses($weight) font-* weight utility (table columns, infolist entries); unknown weight → font-normal
Foundation\Concerns\HasModalProperties::getMaxWidthClass($width, $responsive) modal max-w-* (centered dialogs gate at sm:; slide-overs pass responsive: false)

Type-safe value enums

Every fluent setter that takes a string token also accepts a canonical enum from Foundation\Enums\->size('lg') and ->size(Size::Lg) are interchangeable, and the string form stays fully supported. Each enum is the single owner of its vocabulary (values() + resolve()), so a token resolves to the same utility on every surface, and unknown tokens fall back to a sensible default instead of emitting an unscannable class.

Enum Tokens Setters that accept it
Colors\Color semantic roles + every raw hue (see Colors) ->color() everywhere
Enums\Breakpoint sm md lg xl 2xl column ->visibleFrom() / ->hiddenFrom() / ->mobileBreakpoint(), Table::stackedOnMobile(), ->mobileBreakpoint() on sheets/modals, Grid per-breakpoint columns keys
Enums\Size xs sm md lg xl ->size() (+ ->sm()/->md()/… shortcuts) on actions, buttons, badge/icon columns
Enums\FontWeight thin extralight light normal medium semibold bold extrabold black column ->weight(), infolist TextEntry::weight()
Enums\Alignment left center right column ->alignment(), Table::actionsAlignment()
Enums\IconPosition before after ->icon($icon, $position) on actions, buttons, fields
Enums\Placement bottom-start bottom-end top-start top-end ActionGroup::dropdownPosition()
Enums\ModalWidth sm md lg xl 2xl7xl full ->width() / ->modalWidth() on modals, slide-overs, action modals
use NyonCode\WireCore\Foundation\Enums\{Alignment, Breakpoint, ModalWidth, Size};
 
TextColumn::make('email')->visibleFrom(Breakpoint::Md)->alignment(Alignment::Right);
Action::make('edit')->size(Size::Lg)->modalWidth(ModalWidth::TwoXl);

The Breakpoint, Alignment and Placement enums additionally own the literal Tailwind classes their tokens map to (Breakpoint::Md->tableCellClass(), Alignment::Right->textClass(), Placement::TopEnd->originClass()), so the class map has one owner and Blade consumes a scannable utility instead of interpolating text-{$align}.

  • Icons — the other half of a surface's vocabulary
  • Enums — an enum naming its own colour
  • Theming — changing the palette an application uses
  • BadgeColumn — the resolution ladder in a real surface