@hydroperx/tiles
Version:
Metro tile layout
259 lines (179 loc) • 5.44 kB
Markdown
# @hydroperx/tiles
<p align="center">
<a href="./docs/globals.md"><img src="https://img.shields.io/badge/TypeScript%20API%20Documentation-gray"></a>
</p>
Base layout implementation for Windows 8 like live tiles in HTML5.
## Documentation
### Structure
Positioning style:
- Cascading `transform: translateX(...) translateY(...)`
- Uses the cascading `em` unit for measurement everywhere (which means the (?inherited) `font-size`).
Group element tag:
- `div`
Group element attribute:
- `Tiles.ATTR_ID`: the group ID.
Group element attribute:
- `Tiles.ATTR_DRAGGING`: false or true.
Group element:
- Consists of:
- A group label div (contains a group label text div)
- A group tiles div (where the tiles float).
Tile element tag:
- A `button`, consisting of a content div where the user may apply custom transforms such as tilting.
Tile element attribute:
- `Tiles.ATTR_ID`: the tile ID.
Tile element attribute
- `Tiles.ATTR_SIZE`: the tile size (`small`, `medium`, `wide` or `large`).
Tile element attribute
- `Tiles.ATTR_DRAGGING`: false or true.
Tile element attribute:
- `Tiles.ATTR_CHECKED`: false or true.
Tile size:
- Supports small (1x1), medium (2x2), wide (4x2) and large tiles (4x4).
### Getting started
```ts
import { Tiles } from "@hydroperx/tiles";
const container = document.querySelector("#container")!;
// Create layout
const tiles = new Tiles({
element: container,
direction: "horizontal",
classNames: {
group: "group",
groupLabel: "group-label",
groupLabelText: "group-label-text",
groupTiles: "group-tiles",
tile: "tile",
tileContent: "tile-content",
},
smallSize: 3.625,
tileGap: 0.6,
groupGap: 3,
labelHeight: 2,
height: 6,
});
// Handle click in a tile
tiles.on("click", ({ detail: { tile } }) => {
if (tile == "purple1") {
alert("one!");
}
});
// Handle tile addition
tiles.on("addedtile", ({ detail: { tile, button, contentDiv } }) => {
if (tile.id.startsWith("purple")) {
button.style.background = "purple";
}
});
// Group 1
tiles.addGroup({
id: "group1",
label: "Group 1",
});
// Tile 1
tiles.addTile({
id: "purple1",
group: "group1",
size: "large",
});
// Tile 2
tiles.addTile({
id: "purple2",
group: "group1",
size: "wide",
});
// Disposal
tiles.destroy();
```
### Events
#### addedgroup
Dispatched when a new group is added. Event is given a `CustomEvent<{ group: Group, div: HTMLDivElement, labelDiv: HTMLDivElement, tilesDiv: HTMLDivElement }>` object. This is also dispatched when automatic groups are created (such as when a tile is dropped far away in no existing group).
```ts
tiles.on("addedgroup", ({ detail: { group, div, labelDiv, labelTextDiv, tilesDiv } }) => {
//
});
```
#### addedtile
Dispatched when a new tile is added. Event is given a `CustomEvent<{ tile: Tile, button: HTMLButtonElement, contentDiv: HTMLDivElement }>` object.
```ts
tiles.on("addedtile", ({ detail: { tile, button, contentDiv } }) => {
//
});
```
#### stateupdate
Dispatched whenever the state is updated. Event is given a `CustomEvent<State>` object.
```ts
tiles.on("stateupdate", ({ detail: state }) => {
//
});
```
#### dragstart
Event is given a `CustomEvent<{ tile: HTMLButtonElement }>` object.
```ts
tiles.on("dragstart", ({ detail: { tile } }) => {
//
});
```
#### drag
Event is given a `CustomEvent<{ tile: HTMLButtonElement }>` object.
```ts
tiles.on("drag", ({ detail: { tile } }) => {
//
});
```
#### dragend
Event is given a `CustomEvent<{ tile: HTMLButtonElement }>` object.
```ts
tiles.on("dragend", ({ detail: { tile } }) => {
//
});
```
#### groupdragstart
Event is given a `CustomEvent<{ group: HTMLDivElement }>` object.
```ts
tiles.on("groupdragstart", ({ detail: { group } }) => {
//
});
```
#### groupdrag
Event is given a `CustomEvent<{ group: HTMLDivElement }>` object.
```ts
tiles.on("groupdrag", ({ detail: { group } }) => {
//
});
```
#### groupdragend
Event is given a `CustomEvent<{ group: HTMLDivElement }>` object.
```ts
tiles.on("groupdragend", ({ detail: { group } }) => {
//
});
```
#### selectionchange
Event is given a `CustomEvent<{ tiles: string[] }>` object.
```ts
tiles.on("selectionchange", ({ detail: { tiles } }) => {
//
});
```
#### click
Event is given a `CustomEvent<{ tile: string }>` object.
```ts
tiles.on("click", ({ detail: { tile } }) => {
//
});
```
### Style recommendations
- Do not add border, margin, padding or scale to `classNames.group` to avoid inconsistencies in grid-snapping.
- Do not add border, margin, padding or scale to `classNames.groupTiles` to avoid inconsistencies in grid-snapping.
- Do not add margin or scale to `classNames.tile`. Scale may be used in `classNames.tileContent`.
- Outline mayn't work well in `className.tile`, as it may be clipped off; prefer a border.
### Rearranging
If your container starts at zero scale, then it is necessary to manually call `.rearrangeOverMinimumScale()` for the first time the container opens.
For example:
```js
const aborter = base_tiles.current!.rearrangeOverMinimumScale();
// Abort when necessary
aborter.abort();
```
## License
Apache 2.0