UI Tiled Container Component
- Dominant language
- TypeScript
- Stars
- 58
- Forks
- 47
- Avg merge
- 13h 3m
- Merged PRs (30d)
- 110
Description
Create a new container component for the Vuu layout system, TiledContainer. This container manages the display of a collection of children of equal size (the Tiles). An example of such a component , InstrumentTiles from the Vuu Demo App Figma, can be seen below;

Another commonly seen use case would be a Panel of FX tiles.
The container will need to manage overflow and have some responsive behaviour:
- it should not show partial Tiles in the event of wrapping
- it will not be scrollable
- it can be multi row
- it should support an option to render Tiles in more than one size - maybe normal, small and condensed ? Or some configurable combination of those. Another configuration option would be the size thresholds of the outer container at which those Tile variants are applied.
- The Tile itself can be implemented as a Container component, which would be little more than a div with some CSS, which would then be used in concrete Tile implementations eg FxTile
- There might be some value in using the existing MeasuredContainer
- Toolbar has code that detects wrapping of child components, might also be useful as a reference.
- Tiles and the Container should accept props that control whether all tiles / individual tiles can be removed (see similar API features in Tabstrip)
- a mechanism to select and add new Tiles will be specified separately
Characteristics of a Tiled Container
- the size of container is fixed, irrespective of content, determined by the Vuu layout system
- the container can be resized by the user at runtime
- the size of each Tile is fixed
- all tiles are the same size
- if the container is not large enough to display all child tiles, we have two options:
-- only render as many tiles as fit within the container (do not render partial tiles)
-- reduce size of tiles to accommodate more
The choice of the two strategies should probably be a configuration option. The second option assumes that a reduced size tile is an option.
- Support an option to render tiles at a reduced size - the Container should simply implement a className, the actual sizing of Tiles should be users responsibility.
How to manage Tile sizing
The challenge here is very similar to the problem of rowHeight in a List. We want it to be determined by CSS to the greatest extent possible, so that theming can control the appearence. Having Tile size as a prop on the Container API undermines this. At the same time, the container will almost certainly need to know the Tile size, in order to make layout decisions.
CSS Variables are probably the best way to accommodate this.
```CSS
.TiledContainer {
--tile-height: var(--vuuTile-height, 100px);
--tile-width: var(--vuuTile-width, 100px);
}
.Tile {
height: var(--tile-height);
width: var(--tile-width);
}
```
On mount, the TiledContainer can measure the first tile and determine from that the current size. It can also manage a ResizeObserver that watches the tile to detect runtime changes (eg user switches density) . Because a TiledContainer might be empty initially, a dummy tile could be rendered for this purpose (not visible, this is exactly how List manages runtime changes to rowHeight). WIth this approach, its easy to implement the density switching - a CSS selector with a className for the specific density choice can reassign different values to these CSS variables.
To use MeasuredContainer, the following pattern would work (see TableNext for existing example). Using this pattern, the TiledContainerCore is guaranteed to receive current size (width, height) as a prop and would be rerendered if size changes.The advantage of encapsulating the TiledContainer functionality in an inner component like (`TiledContainerCore`) this is that any hooks invoked by this component wil also not be called until the measurement is complete.
```javascript
const TiledContainer = () => {
const [size, setSize] = useState()
return (
{size ? (
{tiles}
) : null}
)
}
```
-
Contributor guide
Research direction
Start by reading the existing MeasuredContainer usage in TableNext and the wrapping logic in Toolbar, then compare the removal API in Tabstrip. Define the TiledContainer and TiledContainerCore entry points from the issue, and verify that equal-sized tiles handle wrapping, resizing, overflow, density classes, and removal options without showing partial tiles.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, react, typescript
- Domain
- design, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100