Skip to content

hydroperx/tiles.js

Repository files navigation

@hydroperx/tiles

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

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).

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.

tiles.on("addedtile", ({ detail: { tile, button, contentDiv } }) => {
    //
});

stateupdate

Dispatched whenever the state is updated. Event is given a CustomEvent<State> object.

tiles.on("stateupdate", ({ detail: state }) => {
    //
});

dragstart

Event is given a CustomEvent<{ tile: HTMLButtonElement }> object.

tiles.on("dragstart", ({ detail: { tile } }) => {
    //
});

drag

Event is given a CustomEvent<{ tile: HTMLButtonElement }> object.

tiles.on("drag", ({ detail: { tile } }) => {
    //
});

dragend

Event is given a CustomEvent<{ tile: HTMLButtonElement }> object.

tiles.on("dragend", ({ detail: { tile } }) => {
    //
});

groupdragstart

Event is given a CustomEvent<{ group: HTMLDivElement }> object.

tiles.on("groupdragstart", ({ detail: { group } }) => {
    //
});

groupdrag

Event is given a CustomEvent<{ group: HTMLDivElement }> object.

tiles.on("groupdrag", ({ detail: { group } }) => {
    //
});

groupdragend

Event is given a CustomEvent<{ group: HTMLDivElement }> object.

tiles.on("groupdragend", ({ detail: { group } }) => {
    //
});

selectionchange

Event is given a CustomEvent<{ tiles: string[] }> object.

tiles.on("selectionchange", ({ detail: { tiles } }) => {
    //
});

click

Event is given a CustomEvent<{ tile: string }> object.

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:

const aborter = base_tiles.current!.rearrangeOverMinimumScale();

// Abort when necessary
aborter.abort();

License

Apache 2.0

About

Live tiles layout

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published