Repository navigation
Make KPI tiles frameless and consistently movable across Dashboard layouts #340
Description
Summary
Unify KPI tile presentation and movement across every editable Dashboard style.
- Flow layouts (
Report,2 columns,3 columns): KPI-band members move with Command/Ctrl-drag and have no grip. - Grid Tiles and transient Full view: KPI tiles are frameless in edit mode as well as view mode.
- Both engines use the same normal appearance and transient editing feedback.
- Plain drag selects text; Command/Ctrl-drag moves the KPI tile.
- Reuse Use command-drag for Dashboard tile moves and add cell-detail preview to table/log tiles #332 movement, Auto-scroll long Dashboards while Command/Ctrl-dragging tiles #338 auto-scroll, floating preview, cancellation, destination resolution, and exact-once
move-tilecommit.
This supersedes #316's decision to retain a persistent Grid Tiles KPI edit frame.
Product behavior
KPI cards should look the same across Dashboard styles: the KPI cards or KPI state card are the only persistent visible framed surfaces.
The query tile still exists structurally and owns order, placement, accessibility, movement, deletion, and Grid Tiles resizing, but its outer frame is normally transparent.
Flow KPI movement
Flow KPI tiles render as .dash-kpi-member hosts inside a KPI band rather than the normal .dash-tile card.
Requirements:
- wire Command/Ctrl-drag directly to each KPI band member;
- no grip is shown;
- plain drag inside KPI content selects text and never moves the tile;
- include KPI members in flow destination hit testing;
- give the member a real temporary box while floating because its normal wrapper may use
display: contents; - preserve canonical
dashboard.tiles[]ordering and normal KPI-band regrouping after commit; - dispatch one
move-tilecommand on successful release; - cancelled gestures change nothing.
Frameless Grid Tiles edit mode
Keep .dash-gg-tile.is-kpi as the real CSS-grid item. Do not use display: contents.
The wrapper must continue to own:
- grid span and height;
- responsive placement and semantic order;
- accessible query title;
- Command/Ctrl-drag gesture;
- delete action;
- resize handle;
- floating and placeholder behavior during movement.
In the normal edit state remove:
- outer border, background, radius, and shadow;
- persistent header row and reserved header height;
- grip;
- footer and footer separator;
- outer body padding.
The KPI cards remain arranged by the existing equal-width responsive KPI layout from #316.
Transient editing chrome
Because the structural tile boundary is normally invisible, expose it transiently when the tile is being edited.
Show a non-layout-shifting overlay or outline on:
- pointer hover;
- keyboard focus within the tile;
- Command/Ctrl modifier hover;
- active move;
- active resize.
The transient chrome should provide:
- a thin outline around the complete query tile;
- the query title in a compact overlay;
- delete action at the upper edge;
- Grid Tiles resize handle at the lower-right;
- stronger feedback while moving or resizing.
Controls must be absolutely positioned or otherwise overlaid so appearing chrome does not move KPI content or change tile height.
A query may render multiple KPI cards. The transient boundary must surround the complete query tile, not each KPI card separately.
Unified movement rules
Across flow, Grid Tiles, and Full view:
- plain pointer drag remains available for text selection;
- Command on macOS or Ctrl on Windows/Linux starts movement after the existing threshold;
- no KPI grip is shown;
- movement may start from KPI content except interactive edit controls;
- synthesized click after movement is suppressed;
- Escape, pointer cancellation, blur, lost capture, rerender, or teardown cancels cleanly;
- Auto-scroll long Dashboards while Command/Ctrl-dragging tiles #338 vertical auto-scroll works while moving through a long Dashboard;
- successful release commits exactly one
move-tilecommand; - read-only Dashboard mode remains non-movable and visually frameless.
Floating state
When moving a KPI tile in either layout engine:
- create a visible temporary outer box around the complete query tile;
- retain its measured width and height;
- keep it under the pointer while the page auto-scrolls;
- show a clear destination indicator;
- restore all inline styles and temporary DOM state after completion or cancellation.
For flow KPI members, this temporary box creates the physical surface that does not exist in the normal display: contents presentation.
For Grid Tiles, it visually exposes the otherwise transparent structural wrapper.
Resize and delete behavior
Grid Tiles and Full view retain existing resize semantics:
- Grid Tiles: two-dimensional span and height resize;
- Full view: vertical-only height resize with persisted span unchanged.
Requirements:
- resize remains discoverable through the transient handle;
- resize begins only from the handle and never starts movement;
- delete remains keyboard reachable and has the existing accessible name;
- delete and resize controls remain hidden in read-only mode;
- controls appearing on hover/focus do not cover essential KPI values where avoidable.
Flow layouts do not gain resize or delete controls beyond their existing capabilities; this issue only adds movement to KPI-band members.
Loading, error, unfilled, and zero-data states
Frameless behavior applies in every KPI state.
- Loading and unfilled states render the existing visible status card.
- Failures render the existing alert card.
- Zero-data retains its existing quiet state semantics.
- The generic outer tile frame must not temporarily reappear during refresh or failure.
- The query title remains available through the tile's accessible group name and state-card accessible name.
Accessibility
- Plain drag never moves a KPI tile.
- Command/Ctrl movement is described by title/help text.
- The transparent Grid Tiles wrapper remains a named group.
- Hidden persistent headers do not remove the query title from the accessibility tree.
- Delete and resize controls are reachable on keyboard focus, not hover-only.
- Focus indication exposes the same structural boundary as pointer hover.
- Loading/unfilled states remain
status; failures remainalert. - No meaningful state depends only on color.
Tests
Flow KPI movement
- Command-drag and Ctrl-drag move a KPI band member in Report, 2-column, and 3-column layouts;
- plain drag selects KPI text and dispatches no move;
- no grip is rendered;
- member receives a real temporary floating box;
- destination hit testing includes KPI members;
- auto-scroll works across a long flow Dashboard;
- successful release dispatches one command and the band regroups correctly;
- cancellation restores DOM and order.
Grid Tiles presentation
- edit-mode KPI tile has no persistent outer frame, header, grip, footer, or body padding;
- structural wrapper retains span, height, order, role, and accessible name;
- hover, focus, modifier hold, move, and resize expose transient boundary chrome;
- overlay controls do not change layout dimensions;
- multiple KPI cards remain grouped by one tile boundary;
- non-KPI tiles retain their normal shell.
Grid Tiles interaction
- Command/Ctrl-drag works without a grip;
- plain drag selects text;
- delete and resize remain functional and do not initiate movement;
- Full view retains vertical-only resizing;
- auto-scroll, destination preview, click suppression, and exact-once commit continue to work;
- cancellation and teardown remove all transient classes, styles, listeners, and overlays.
State and browser coverage
Verify loading, unfilled, error, zero-data, and refreshed states in:
- Grid Tiles;
- Full view;
- Report;
- 2 columns;
- 3 columns;
- edit and read-only modes;
- light and dark themes;
- narrow mobile viewport;
- Chrome, Firefox, and WebKit.
Acceptance criteria
- KPI cards have the same frameless normal presentation across Dashboard styles.
- Flow KPI-band members move with Command/Ctrl-drag and show no grip.
- Grid Tiles KPI edit mode removes the persistent outer frame and grip.
- Grid Tiles keeps a real transparent structural wrapper for placement, resize, delete, movement, and accessibility.
- Transient editing chrome exposes the complete query-tile boundary without layout shift.
- Plain drag selects text; modifier drag moves.
- Auto-scroll long Dashboards while Command/Ctrl-dragging tiles #338 auto-scroll and destination feedback work for KPI movement.
- A successful move commits one
move-tile; cancellation commits none. - Delete and resize remain discoverable and keyboard accessible.
- KPI loading/error/unfilled states remain visible without restoring the generic frame.
- Non-KPI tiles and KPI calculation/formatting semantics are unchanged.
- Unit and real-browser tests pass.
Non-goals
- changing KPI calculations, formatting, units, descriptions, or deltas;
- changing Dashboard schemas, persisted placement, or packing algorithms;
- adding touch-only reorder;
- adding resize controls to flow KPI bands;
- removing the structural Grid Tiles wrapper;
- changing ordinary chart, table, logs, text, or image tile chrome;
- introducing a second movement or auto-scroll implementation.
Activity
[-]Flow-layout KPI band tiles have no drag surface (can't be reordered in flow)[/-][+]Move flow-layout KPI band tiles via ⌘/Ctrl-drag (no grip)[/+][-]Move flow-layout KPI band tiles via ⌘/Ctrl-drag (no grip)[/-][+]Make KPI tiles frameless and consistently movable across Dashboard layouts[/+]feat(#340): unify frameless KPI movement (#388)