Skip to content

LayrzColorInput

Kenny Mochizuki Escalona edited this page Aug 20, 2026 · 3 revisions

LayrzColorInput

A color selection field that composes LayrzTextInput and opens a color picker dialog to set a Color value.

Metadata
Mirrors: ThemedColorPicker (layrz_theme)
Phase: M4 (Pickers)
Domain: Pickers
Primitive: Custom implementation (color wheel and palette pickers hand-rolled)
Status: Derived from layrz_theme. Not yet team-confirmed.


⚠️ IMPORTANT: Specification Status

This page is derived from analysis of ThemedColorPicker in layrz_theme and represents planning assumptions only. The specification has not been reviewed or confirmed by the team. Implementation details, parameter names, and behavior may change during the M4 design phase.

All details below are subject to revision.


Overview

LayrzColorInput renders a read-only LayrzTextInput with a circular color swatch in the prefix slot. Tapping the field opens a color picker dialog where the user can select a color using either a color wheel or a palette picker (or both, depending on configuration). The selected color is displayed as hex code in the text field.

Composition

LayrzColorInput is not a standalone widget; it is a thin wrapper over LayrzTextInput configured as read-only with a color affordance in the prefix. The entire input family follows this pattern (see Input Contract).


Blocking Dependency

flex_color_picker Material Coupling

Status: ❌ Cannot be used

layrz_theme depends on flex_color_picker 3.8.0 to provide the color wheel and palette picker UI. This package is architecturally Material-built:

  • 23 files import package:flutter/material.dart
  • 2 files import package:flutter/cupertino.dart
  • Material widgets (dialogs, buttons, theming) are the public API

Consequence: layrz_ui cannot wrap or depend on flex_color_picker. Both the color wheel picker and the color palette picker must be implemented from scratch as Material-free, hand-rolled components.

See Dependencies for the full audit.


Conformance

LayrzColorInput conforms to the Layrz*Input family contract defined in Input Contract. Inherited parameters:

  • labelText (String) — the only label representation; a label Widget parameter is not supported.
  • placeholder — shown inside the field when no color is selected.
  • prefixIcon / prefixWidget / onPrefixTap — mutually exclusive icon or widget in the leading slot.
  • suffixIcon / suffixWidget / onSuffixTap — mutually exclusive icon or widget in the trailing slot.
  • helpTitleText / helpContentText — help affordance (tooltip).
  • onChanged — callback when the color value changes.
  • onSubmit — callback when the user submits the input.
  • onTap — callback when the field is tapped (opens the picker).
  • readOnly — always true for LayrzColorInput (displayed, not directly editable).
  • focusNode / controller — standard lifecycle management.
  • padding — customizable per-field; defaults to M1 spacing tokens.

See the input contract for the complete shared API and disposal guarantees.


Value Type and Selection Surface

Value Type

// Design sketch — illustrative only
class LayrzColorInput extends LayrzTextInput {
  /// The currently selected color.
  /// If null, the field displays no color swatch and the text field is empty.
  final Color? value;

  // ...
}

Stores a single Color value.

Selection Surface

Type: Modal dialog
Content: Color picker with both wheel and palette picker options (see Open Questions for configuration).
Buttons: Cancel and Save/OK buttons to confirm or discard the selection.

When the user taps the field:

  1. A dialog opens with the current color selected.
  2. The user adjusts the color using the wheel or palette picker.
  3. Cancel discards the change; Save/OK confirms and closes the dialog.
  4. onChanged is invoked with the new color.

Deltas from Base Contract

LayrzColorInput adds the following to the base LayrzTextInput contract:

// Design sketch — illustrative only
class LayrzColorInput extends LayrzTextInput {
  /// The currently selected color.
  /// If null, defaults to a theme color (e.g., primary color).
  final Color? value;

  /// Callback invoked when the user selects a new color.
  final ValueChanged<Color>? onChanged;

  /// Text displayed on the Save/OK button in the picker dialog.
  /// Defaults to "OK" or a localized equivalent.
  final String saveText;

  /// Text displayed on the Cancel button in the picker dialog.
  /// Defaults to "Cancel" or a localized equivalent.
  final String cancelText;

  /// Which color picker types are enabled in the dialog.
  /// 
  /// Options may include:
  /// - Wheel picker (continuous spectrum)
  /// - Palette picker (predefined colors)
  /// - Both (tabs or combined view)
  /// See [enabledTypes] section below.
  final List<ColorPickerType> enabledTypes;

  /// Callback to format the color for display text.
  /// 
  /// Called to convert the Color value to a human-readable string.
  /// If not supplied, defaults to hex code (e.g., "#FF0000").
  final String Function(Color)? valueFormatter;

  /// Callback to render a color swatch preview in the prefix slot.
  /// 
  /// If not supplied, a standard circular swatch (20×20 pixels) is rendered.
  final Widget Function(Color)? valueAffordanceBuilder;

  // ...
}

Picker Types (enabledTypes)

The color picker dialog can support multiple selection modes. Verify in layrz_theme which are exposed:

  • Wheel picker: Continuous HSV/HSL color wheel for fine-grained selection.
  • Palette picker: Grid of predefined colors.
  • Both: Tabbed or dual-pane view offering both.

Open question: Does layrz_theme expose any additional picker types (e.g., Material color swatches, custom palettes)?


Reference: layrz_theme API

ThemedColorPicker exposes these parameters (simplified):

class ThemedColorPicker extends StatefulWidget {
  final String? labelText;
  final Widget? label;
  final void Function(Color)? onChanged;
  final Color? value;
  final bool disabled;
  final List<String> errors;
  final bool hideDetails;
  final EdgeInsets? padding;
  final String? placeholder;
  final String saveText;      // "OK"
  final String cancelText;    // "Cancel"
  final List<ColorPickerType> enabledTypes;  // .both, .wheel by default
  final Widget? customChild;
  // ... Material-specific color/focus/splash parameters
}

Differences for layrz_ui:

  • Remove all Material-specific color/focus/splash parameters.
  • Inherit from base LayrzTextInput contract rather than re-declare shared parameters.
  • dense parameter is not supported (removed from the entire input family; see decision D47).
  • Remove customChild (M1 foundation does not support arbitrary wrapping).

Dependencies

  • M1 Theme System (LayrzTheme, LayrzThemeData) — primary and semantic colors.
  • M2 Tooltip Component (LayrzTooltip) — for help affordance.
  • M3 LayrzTextInput — base field chrome and behavior.
  • M4 Color Picker Implementations (hand-rolled):
    • Wheel Picker: HSV or HSL color wheel rendering. Must support:
      • Continuous spectrum selection.
      • Saturation and brightness/lightness sliders.
      • Current color indicator.
      • Hex code display and manual input.
    • Palette Picker: Grid of predefined colors from the M1 design tokens.
  • material_color_utilities (transitive, clean) — color math (tonal palette generation, color harmony).

Implementation Notes

Color Representation

layrz_theme stores colors as hex codes internally and converts between Color and hex for display. Verify whether layrz_ui should:

  • Store Color objects natively (recommended).
  • Convert to/from hex code for serialization only.

Palette Picker Source

Where do palette colors come from?

  • M1 design tokens (LayrzThemeData)?
  • Material 3 color system tonal palettes?
  • Custom palette defined in a separate data file?

Hex Code Input

layrz_theme allows manual hex code entry in the color field. Should layrz_ui support this?


Open Questions

  • Picker types configuration: Does layrz_ui expose the same ColorPickerType enum as layrz_theme? What are the exact options (.wheel, .palette, .both, .primary, .accent, .custom, .bw)?

  • Default enabledTypes: What is the sensible default? layrz_theme defaults to [.both, .wheel] — reasonable for layrz_ui?

  • Color formatting: Should the default formatter display hex code, RGB, HSL, or something else? Does the user have a preference?

  • Swatch size and appearance: Is the default 20×20 circular swatch correct, or should it be configurable? What border radius?

  • Dialog size constraints: What are the max-width and max-height for the picker dialog?

  • Opacity support: Should the color picker allow alpha channel adjustment, or is it locked to fully opaque?

  • Copy-paste support: layrz_theme's flex_color_picker supports copy/paste of hex codes. Should this be hand-rolled into the custom picker?


Design Reference Gap

Critical path item: A design reference (Figma, spec, or annotated screenshot) must be provided before M4 implementation begins, specifying:

  • Color wheel appearance (radius, gradient, indicator style).
  • Saturation/brightness/lightness slider placement and appearance.
  • Palette grid layout (columns, spacing, item size).
  • Hex code input field placement and styling.
  • Dialog chrome (padding, buttons, title).
  • Light and dark theme variants.
  • Accessibility: keyboard navigation, screen reader labels for sliders and grid.

Last updated: 2026-08-13
Related documents: Input Contract, Dependencies, Design Tokens, Architecture, Roadmap, Decisions

Clone this wiki locally