enhancement
major
minor
major
minor
major
#29906
Design System wave 5c: calendar, kanban, dashboard and value list read the design system package
Continues #29904 (wave 5b, media). 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
TLCalendar, TLKanbanBoard, the dashboard, TLValueList and the table cells that still hold legacy controls are styled by the old stylesheet tlReactControls.css. The design system package's forecast (docs/migration/altlast.md, "Welle 5", V5, V6, V8, V12, V19, V20) found:
- Drag and drop: the kanban board has its own drop state and a second copy of the drop hint (z-index: 13000), the dashboard its own drag machine without touch and keyboard, the calendar its own dragging opacity — three looks for "insert here".
- Grids without keyboard: mini month, moving kanban cards and dashboard tiles work with the mouse only.
- Calendar: no role/`aria` at all, eight category colors as hex values (the package has category-1..8), the now line as a hex literal, outline: none on the create field.
- The dashboard rebuilds visually hidden text with nine declarations and measures its grid itself.
- Two checks for interactive targets (controls/interactive.ts and bridge/interactive.ts).
Solution
Spec in the package: docs/superpowers/specs/2026-10-19-welle-5c-planen-und-ziehen-design.md. No new interaction concept (that comes with the UI pass after wave 5); the keyboard only does what the pointer can do.
- Calendar: events are a list box of options (arrows select, Enter opens), days are buttons named by their full date, the view choice is a segmented radio group, today is the same brand circle in every view. Events are filled in the theme's category (category-N-surface, text computed by derive); a server color is drawn inline with a readable text chosen in the browser (textOn), an unreadable one falls back to the category or the brand. Working time lies on surface-layer, the rest on surface-base. Escape in the create field discards only the placeholder, also inside a window.
- Kanban: cards are selectable items (ring and check like every item list), one tab stop per column; Alt+Up/Down reorders within a column, Alt+Left/Right moves to the neighbouring column via the existing drop command, announced. While dragging, the column under the pointer is highlighted and an insertion line shows the place between two cards; a refused drop (a forbidden action) is marked in the error color with the reason in the drop hint.
- Dashboard: tiles are cards; in edit mode the hide button floats over the tile, tiles move with Alt+Left/Right; the tile action is a visually hidden button whose focus ring the tile shows.
- Value list and table cells: reading as one line with a real ", " separator (copied as seen) or one value per line; editing with part buttons (handle, remove, add).
- One interactive-target check, one option selection (useOptionSelection), one drop hint (tl-drop-hint), one name-to-category mapping (categoryOf).
- Package: filled category roles category-1-surface … category-8-surface with derived text-on-category-N; the label candidates as roles text-contrast-light/`text-contrast-dark`; derive computes both for customer themes.
Migration
The planning and drag controls now draw with the design system package. Application stylesheets that address the old classes must move to the new ones.
Removed classes: tlCal* and tlCalendar, tlKanbanBoard*, tlDashboard*, tlValueList*, tlRowCommandCell (now tl-table__cell--command, RowCommandColumn.CSS_CLASS), tl-table__hint (now tl-drop-hint), the custom property --cal-ev-bg.
States are attributes, not classes: selected [aria-selected="true"], today [aria-current="date"], non-working day [data-tl-state~="nonworking"], other month [data-tl-state~="other"], day with events [data-tl-state~="event"], preview [data-tl-state~="preview"], dragging [data-tl-state~="dragging"], drop [data-tl-state~="drop-before"]/`drop-after`/`drop-onto`/`drop-refused`, dashboard in edit mode [data-tl-state~="edit"], category [data-tl-role="category-N"].
Old → new:
| = Old = | = New = |
| .tlCalendar, tlCalToolbar, tlCalNav, tlCalBtn, tlCalTitle, tlCalGranularity, tlCalBtn--active | .tl-calendar, .tl-toolbar.tl-calendar__toolbar, part Button, __title, .tl-segmented ([aria-checked="true"]) |
| tlCalTimeGrid, tlCalTimeHeader, tlCalDayHead, tlCalDayName, tlCalDayNum, tlCalGutter | __time-grid, __head, __day-head, __weekday, __day-number, __gutter |
| tlCalAllDayRow, tlCalAllDayLabel, tlCalAllDayCell, tlCalAllDayEvent | __all-day, __all-day-label, __all-day-cell, __event |
| tlCalScroll, tlCalTimeBody, tlCalHourAxis, tlCalHourLabel, tlCalColumns, tlCalCol, tlCalHourLine, tlCalWorkBand, tlCalNowLine | __scroll, __time-body, __hours, __hour, __columns, __column, __hour-line, __work, __now |
| tlCalEvent, --c<N>, --default, --selected, --preview, --dragging, tlCalEventTime, tlCalEventTitle, tlCalResizeHandle, tlCalCreateInput, tlCalMonthCreate | __event ([data-tl-role="category-N"], states above), __event-time, __event-title, __resize, .tl-field.tl-calendar__create |
| tlCalMonth, tlCalMonthHead, tlCalMonthWeekday, tlCalMonthBody, tlCalMonthWeek, tlCalMonthDays, tlCalMonthCell, tlCalMonthDayNum, tlCalMonthOverlay, tlCalMonthBar, tlCalChip, tlCalChipDot, tlCalChipTime, tlCalChipTitle, tlCalMore | __month, __month-head, __month-weekday, __month-body, __week, __days, __day, __day-number, __overlay, __event, __chip, __chip-dot, __event-time, __event-title, __more |
| tlCalYear, tlCalMini, tlCalMiniTitle, tlCalMiniGrid, tlCalMiniWd, tlCalMiniDay | __year, __mini, __mini-title, __mini-grid, __mini-weekday, __mini-day |
| .tlKanbanBoard, __column, __header, __label, __count, __cards, __card, __dropHint | .tl-board, __column, __header, __label, part Badge, __cards (role="listbox"), .tl-item.tl-board__card (role="option"), .tl-popover.tl-drop-hint |
| .tlDashboard, --edit, __grid, __tile, __tile--action, __tileAction, __overlay, __hide | .tl-dashboard, [data-tl-state~="edit"], __grid, .tl-card.tl-dashboard__tile.tl-overlay.tl-overlay--fill, __action (.tl-visually-hidden), __cover, .tl-overlay__action with part Button |
| .tlValueList, --inline, --block, __item, __separator, __row, __handle, __remove, __add | .tl-value-list, --block, __item, .tl-select__separator, __row, part Button |
The complete table is in the design system repository, docs/migration/altlast.md, section "Welle 5c".
Bridge API (tl-react-bridge): avatarCategory is renamed categoryOf; new textOn, isInteractiveTarget, isOperableTarget, kindAccepted, ICON_PREVIOUS, ICON_NEXT. A customer adapter calling avatarCategory must switch to categoryOf (same mapping).
Visible changes: calendar events are filled in their category with white or dark text (no white inner border), the selected event shows a ring in its text color; the now line is in the error color; days of another month are secondary text, not disabled; kanban columns are a well on surface-base with cards on top, a selected card shows ring and check; while dragging, the column under the pointer is highlighted and an insertion line marks the place between two cards; dashboard tiles are cards without shadow; the value list separator has the text color.