finos / finos/vuu

UI Tiled Container Component

Open
#952 0 comments 0 reactions 0 assignees View on GitHub
UI
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;

![Screenshot 2023-11-10 at 10 00 49](https://github.com/finos/vuu/assets/40262/a2c95e04-6d55-4484-868a-cffc4d163808)

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.