enhancement
major
minor
major
minor
major
#29875
Design System wave 5a: color input, icon select and slider read the design system package
Continues #29870 (wave 4c, containers). Wave 5 is cut into four parts with a ticket each (5a inputs, 5b media, 5c planning and drag, 5d foundation and removal of tlReactControls.css), so that a release between the merges does not close the ticket of an open part.
Problem
TLColorInput, TLIconSelect and TLSlider are styled by the old stylesheet tlReactControls.css (about 900 lines). The design system package's forecast (docs/migration/altlast.md, "Welle 5", V1, V6, V7, V9, V11) found:
- Picker popups: color and icon draw the same frame twice (fixed position, own surface), the same tab strip without tablist, and the same action row of bare buttons. Both position themselves by hand without following scroll or resize, have no focus trap and no focus return, and no role=dialog.
- Keyboard: the color palette cells and the color mixer (saturation/value field, hue strip) can only be used with a pointer.
- The "no color" checkerboard is drawn twice with literal colors.
- The slider draws its track with about 27 pseudo-element rules, marks error/warning with classes, and defines four --tlSlider-* properties in the package's namespace.
Solution
Spec in the package: docs/superpowers/specs/2026-10-17-welle-5a-eingaben-design.md. No new interaction concept (that comes with the UI pass after wave 5): the color and icon pickers share one shell (popover that follows scrolling and stays inside the window, role="dialog", focus trap and return to the field, Escape, outside press, tabs with one keyboard model shared with the tab bar, actions as a button bar). The color input, its palette cells and previews and the icon field are one swatch block; the field shows error, warning and mandatory like any field, and its accessible name carries the value ("no color" / "no icon" when empty). Palette and icon grid have one tab stop and arrow keys; the color mixer is two sliders (saturation/brightness, hue) usable by keyboard and keeps its hue over black and grey. The slider is a package component; its fill is an element.
Migration
The color input, icon select and slider now draw with the design system package. Application stylesheets that address the old classes must move to the new ones.
Removed classes: tlColorInput*, tlIconSelect*, tlSlider*. Removed custom properties: --tlSlider-thumb, --tlSlider-fill, --tlSlider-fill-color, --tlSlider-rest-color.
States are attributes, not classes: empty swatch [data-tl-state~="empty"]; selected tab, palette cell, icon cell [aria-selected="true"]; field error [aria-invalid="true"] (on the swatch button / the slider input), warning [data-tl-state~="warning"], mandatory [aria-required="true"]; read-only fields render a span instead of a button.
Old → new (selection):
| = Old = | = New = |
| .tlColorInput, __swatch, --noColor, --immutable | .tl-swatch.tl-swatch--color, [data-tl-state~="empty"], read-only span |
| .tlColorInput__popup, __tabs, __tab--active | .tl-popover.tl-picker, .tl-tabs, [aria-selected="true"] |
| .tlColorInput__palette, __paletteCell | .tl-color-picker__palette, .tl-swatch.tl-swatch--color[role="option"] |
| .tlColorInput__mixer, __svField, __hueSlider | .tl-color-picker__mixer, __field, __hue |
| .tlColorInput__actions, __btn--ok/cancel/reset | .tl-button-bar.tl-picker__actions |
| .tlIconSelect, __swatch | .tl-swatch |
| .tlIconSelect__popup, __grid, __iconCell--selected | .tl-popover.tl-picker.tl-icon-picker, .tl-icon-picker__grid, __cell[aria-selected="true"] |
| .tlIconSelect__loading, __noResults | .tl-status |
| .tlSlider, --error, --warning, __input, __value | .tl-slider, __input[aria-invalid="true"], [data-tl-state~="warning"], __input, __value |
The complete table is in the design system repository, docs/migration/altlast.md, section "Welle 5a".
Visible changes: the color popup is as wide as its content; both popups stay attached to the field while scrolling and stay inside the window (they overlap the field rather than leave the screen — this applies to all popovers); tabs without bold text; the selected icon cell in the system's selection color; icon cells 32 instead of 40px, the mixer field 256 instead of 192px; the hue strip runs from bottom (0°) to top; the empty color field without the red diagonal; color and icon fields show error and mandatory like other fields; the slider's focus ring surrounds the whole control.