Repository navigation
feat(Board): add a dashboard board of movable, resizable items; prepare 0.2.0-alpha.18 - #63
Merged
Merged
Conversation
Board is ui-common's replacement for @cloudscape-design/board-components: a grid of items the user moves and resizes by pointer or keyboard, with every step announced in a live region. It adds no dependency: the drag and resize handling is the component's own, and the handle glyphs are inline SVG on currentColor. The data model is Cloudscape's, so a layout a product persisted from that board renders and persists the same. An item is its spans plus a columnOffset per column count; the column count follows the board's width (1 under 688px, 2 under 912px, 4 under 2100px, else 6). interpretItems and transformItems are ports of Cloudscape's algorithms: default placement packs into column heights, columnOffset[columns] is honoured when it fits, and a commit keeps the offsets stored for other column counts up to the first index whose order changed (or the resized item) and drops them from there on. The engine is simpler than Cloudscape's solver. The active item goes where the user put it; each item it covers takes the space it vacated when it fits there without touching anything, else drops to the row below the item that displaced it, keeping its column, and pushes in turn; then everything but the active item floats up. Each preview is computed from the layout the operation started with, so it depends on the target, not the path. A pointer drag reads the pointer in viewport coordinates and adds back how far the grid's origin travelled since the drag started, so an ancestor scrolling under a still pointer (the product's content area is the scroll container, not the window) moves neither the target nor the dragged item off the pointer; a window-level scroll listener re-applies the last pointer position. While the pointer is held within 48px of an edge of the nearest scroll container (computed overflow auto or scroll; else the document's scrolling element), a requestAnimationFrame loop scrolls it, faster the closer to the edge, so a long board can be dragged end to end. Prepare 0.2.0-alpha.18 (library and CLI).
Resize by pointer sizes the item in px as the pointer moves and snaps to the grid on release. A handle clicked, or given Enter or Space, is activated: direction buttons appear around it and they or the arrow keys step one cell at a time; Enter, Space or leaving the handle commits, Escape discards. Arrows do nothing on a handle that is not activated. The layout engine is a port of Cloudscape's path-based solution search (scored directions, swaps, refloat, conflicts), so the other items make room the same way. The handles draw no surface on hover or press.
The slide transition applied to every item at all times, so when a move or resize committed and the transforms came off in the same render that re-placed the items, each displaced item was drawn at its new cell plus its old translation and slid back. The transition now exists only while an operation is on, as in the board this one replaces.
…focused When a commit reorders the items, React moves the active item's node in the DOM. The focused handle inside it loses focus, and the browser recomputes styles for that before the board's own class changes: an item's transform is gone but the ancestor-scoped transition is still there, so the item slides in from where its transform had it. The transition is now the item's own class, which leaves in the same update as the transform. The handle that lost focus to the move is focused again after the render, as the replaced board did.
There was a problem hiding this comment.
🟡 Changes recommended
Direction controls are inaccessible, off-grid drops announce an incorrect result, and release links are incomplete.
3 open findings
What changed in this PR
Adds a movable, resizable dashboard Board compatible with Cloudscape layouts and prepares the alpha.18 release.
Changes:
- Implements Board layout, interaction, scrolling, styling, and tests.
- Adds localized accessibility messages and public exports.
- Updates documentation and package versions.
| File | Description |
|---|---|
src/index.ts |
Exports the Board API. |
src/i18n/catalog.ts |
Registers Board messages. |
src/i18n/locales/zh-TW.json |
Adds Traditional Chinese strings. |
src/i18n/locales/zh-CN.json |
Adds Simplified Chinese strings. |
src/i18n/locales/vi-VN.json |
Adds Vietnamese strings. |
src/i18n/locales/tr-TR.json |
Adds Turkish strings. |
src/i18n/locales/th-TH.json |
Adds Thai strings. |
src/i18n/locales/ru-RU.json |
Adds Russian strings. |
src/i18n/locales/pt-PT.json |
Adds European Portuguese strings. |
src/i18n/locales/pt-BR.json |
Adds Brazilian Portuguese strings. |
src/i18n/locales/pl-PL.json |
Adds Polish strings. |
src/i18n/locales/ms-MY.json |
Adds Malay strings. |
src/i18n/locales/mn-MN.json |
Adds Mongolian strings. |
src/i18n/locales/ko-KR.json |
Adds Korean strings. |
src/i18n/locales/ja-JP.json |
Adds Japanese strings. |
src/i18n/locales/it-IT.json |
Adds Italian strings. |
src/i18n/locales/id-ID.json |
Adds Indonesian strings. |
src/i18n/locales/fr-FR.json |
Adds French strings. |
src/i18n/locales/fi-FI.json |
Adds Finnish strings. |
src/i18n/locales/es-ES.json |
Adds Spanish strings. |
src/i18n/locales/el-GR.json |
Adds Greek strings. |
src/i18n/locales/de-DE.json |
Adds German strings. |
src/components/Board/Board.tsx |
Implements the Board component and interactions. |
src/components/Board/Board.css |
Styles the grid, handles, and transitions. |
src/components/Board/Board.messages.ts |
Defines accessibility messages. |
src/components/Board/Board.test.tsx |
Tests component interactions and behavior. |
src/components/Board/engine.ts |
Implements layout conflict resolution. |
src/components/Board/index.ts |
Defines Board subpath exports. |
src/components/Board/layout.ts |
Converts persisted and rendered layouts. |
src/components/Board/layout.test.ts |
Tests layout transformations and engine behavior. |
src/components/Board/scroll.ts |
Implements scroll compensation and auto-scroll. |
src/components/Board/scroll.test.ts |
Tests scrolling utilities. |
README.md |
Lists Board among custom components. |
CONTRIBUTING.md |
Documents Board dependencies. |
CHANGELOG.md |
Adds the alpha.18 release notes. |
package.json |
Bumps the library to alpha.18. |
packages/cli/package.json |
Bumps the CLI to alpha.18. |
exports.customs.json |
Adds the Board package export. |
astryx/docs/ui-common.doc.mjs |
Adds Board to aggregate documentation. |
astryx/components/Board.tsx |
Adds the Astryx documentation export shim. |
astryx/components/Board.doc.mjs |
Documents the Board API and usage. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
A click that activates a handle focuses it, so Escape, the arrows and leaving the handle end the activation in browsers that do not focus a clicked button. The direction controls are named buttons out of the tab order, so a touch screen reader can find them. A pointer drag released off the grid is announced as discarded. The changelog links the alpha.18 release.
Member
Author
Ready-gate agent review (Opus) — blocking issues only
Copilot: reviewed (3 threads, all applied in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Adds
Board, a dashboard grid of items the user moves and resizes, and prepares0.2.0-alpha.18.It stands in for
@cloudscape-design/board-componentsin the Backend.AI WebUI, which ships it today (itsBAIBoardbecomes an adapter over this component; the WebUI PR follows this release). The data model is Cloudscape's — spans plus acolumnOffsetper column count,onItemsChangereporting the whole board in reading order — so a layout a product persisted from that board renders and persists the same here (layout.tsis a faithful port ofinterpretItems/transformItems).Interaction follows the replaced board: a handle dragged by pointer moves the item under the pointer, or sizes it live in px, and snaps to the grid on release; a handle clicked, or given Enter / Space, is activated — direction buttons appear and they or the arrow keys step one cell, Enter / Space / leaving the handle commits, Escape discards. How the other items make room is a port of Cloudscape's path-based solution search (
engine.ts: scored directions, swaps, refloat, conflicts). A pointer drag follows the pointer through ancestor scrolling and auto-scrolls the nearest scroll container near its edge.uic.Board.*keys in every locale.isMovable,isResizable,variant="bordered",renderItem,emptyContent,columnBreakpoints,itemClassName, handle icons / labels, announcement builders). CSS knobs:--board-row-height,--board-gap,--board-item-radius,--board-transition-duration,--board-handle-z./dashboardfirst board item −13% (−483 ms, TBT −55%), login page first render unchanged.Verification
pnpm run verify: tsc, eslint, prettier, boundary, theme:check, 1523 tests, build, check:pack,astryx doctor integration validate0 errors.