Base layout implementation for Windows 8 like live tiles in HTML5.
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
orlarge
).
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).
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();
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).
tiles.on("addedgroup", ({ detail: { group, div, labelDiv, labelTextDiv, tilesDiv } }) => {
//
});
Dispatched when a new tile is added. Event is given a CustomEvent<{ tile: Tile, button: HTMLButtonElement, contentDiv: HTMLDivElement }>
object.
tiles.on("addedtile", ({ detail: { tile, button, contentDiv } }) => {
//
});
Dispatched whenever the state is updated. Event is given a CustomEvent<State>
object.
tiles.on("stateupdate", ({ detail: state }) => {
//
});
Event is given a CustomEvent<{ tile: HTMLButtonElement }>
object.
tiles.on("dragstart", ({ detail: { tile } }) => {
//
});
Event is given a CustomEvent<{ tile: HTMLButtonElement }>
object.
tiles.on("drag", ({ detail: { tile } }) => {
//
});
Event is given a CustomEvent<{ tile: HTMLButtonElement }>
object.
tiles.on("dragend", ({ detail: { tile } }) => {
//
});
Event is given a CustomEvent<{ group: HTMLDivElement }>
object.
tiles.on("groupdragstart", ({ detail: { group } }) => {
//
});
Event is given a CustomEvent<{ group: HTMLDivElement }>
object.
tiles.on("groupdrag", ({ detail: { group } }) => {
//
});
Event is given a CustomEvent<{ group: HTMLDivElement }>
object.
tiles.on("groupdragend", ({ detail: { group } }) => {
//
});
Event is given a CustomEvent<{ tiles: string[] }>
object.
tiles.on("selectionchange", ({ detail: { tiles } }) => {
//
});
Event is given a CustomEvent<{ tile: string }>
object.
tiles.on("click", ({ detail: { tile } }) => {
//
});
- 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 inclassNames.tileContent
. - Outline mayn't work well in
className.tile
, as it may be clipped off; prefer a border.
If your container starts at zero scale, then it is necessary to manually call .rearrangeOverMinimumScale()
for the first time the container opens.
For example:
const aborter = base_tiles.current!.rearrangeOverMinimumScale();
// Abort when necessary
aborter.abort();
Apache 2.0