@hydroperx/tiles
Version:
Metro tile layout
386 lines (385 loc) • 10.8 kB
TypeScript
import { TypedEventTarget } from "@hydroperx/event";
import Draggable from "@hydroperx/draggable";
import { EMObserver } from "./utils/EMObserver";
import { TileSizeMap, TileSize } from "./enum/TileSize";
import { State } from "./State";
import { Layout, LayoutGroup, LayoutTile } from "./Layout";
declare const Tiles_base: TypedEventTarget<TilesEventMap>;
/**
* Tiles layout.
*/
export declare class Tiles extends Tiles_base {
/**
* Attribute name used for identifying a tile's ID.
*/
static readonly ATTR_ID = "data-id";
/**
* Attribute name used for indicating a tile's size.
*/
static readonly ATTR_SIZE = "data-size";
/**
* Attribute name used for indicating that a tile is actively in drag.
*/
static readonly ATTR_DRAGGING = "data-dragging";
/**
* Attribute name used for indicating that a tile is checked.
*/
static readonly ATTR_CHECKED = "data-checked";
/** @hidden */
_state: State;
/** @hidden */
_container: HTMLElement;
/** @hidden */
_dir: "horizontal" | "vertical";
/** @hidden */
_class_names: {
group: string;
groupLabel: string;
groupLabelText: string;
groupTiles: string;
tile: string;
tileContent: string;
};
/** @hidden */
_small_size: number;
/** @hidden */
_tile_gap: number;
/** @hidden */
_group_gap: number;
/** @hidden */
_group_width: number;
/** @hidden */
_inline_groups: number;
/** @hidden */
_height: number;
/** @hidden */
_label_height: number;
/** @hidden */
_rearrange_timeout: number;
/** @hidden */
_state_update_timeout: number;
/** @hidden */
_drag_enabled: boolean;
/** @hidden */
_selection_enabled: boolean;
/** @hidden */
_em_observer: EMObserver;
/** @hidden */
_em: number;
/** @hidden */
_layout: Layout;
/** @hidden */
_buttons: Map<string, HTMLButtonElement>;
/** @hidden */
_group_draggables: Map<HTMLDivElement, Draggable>;
/** @hidden */
_tile_draggables: Map<HTMLButtonElement, Draggable>;
/** @hidden */
_tile_drag_end_handlers: WeakMap<HTMLButtonElement, (element: Element, x: number, y: number, event: Event) => void>;
/** @hidden */
_resize_observer: ResizeObserver | null;
/** @hidden */
_tile_removal_work: undefined | ((button: HTMLButtonElement) => Promise<void>);
/** @hidden */
_group_removal_work: undefined | ((div: HTMLDivElement) => Promise<void>);
/**
* Tile sizes in the cascading `em` unit.
* @hidden
*/
_tile_em: TileSizeMap;
constructor(params: {
/**
* Container.
*/
element: Element;
/**
* The direction of the tile container.
*/
direction: "horizontal" | "vertical";
/**
* Customisable class names.
*/
classNames: {
/**
* Class name used for identifying groups.
*/
group: string;
/**
* Class name used for identifying group labels.
*/
groupLabel: string;
/**
* Class name used for identifying group label texts.
*/
groupLabelText: string;
/**
* Class name used for identifying the group tiles container.
*/
groupTiles: string;
/**
* Class name used for identifying tiles.
*/
tile: string;
/**
* Class name used for identifying tile contents.
*/
tileContent: string;
};
/**
* Whether drag-n-drop is enabled.
* @default true
*/
dragEnabled?: boolean;
/**
* Whether tile selection is enabled.
* @default true
*/
selectionEnabled?: boolean;
/**
* The size of small tiles, in cascading `em` units.
*/
smallSize: number;
/**
* Gap between tiles, in cascading `em` units.
*/
tileGap: number;
/**
* Gap between groups, in cascading `em` units.
*/
groupGap: number;
/**
* Group width in small tiles, effective only
* in vertical containers (must be >= 4).
* @default 6
*/
groupWidth?: number;
/**
* Number of inline groups, effective only
* in vertical containers (must be >= 1).
* @default 1
*/
inlineGroups?: number;
/**
* Height in small tiles, effective only
* in horizontal containers (must be >= 4).
* @default 6
*/
height?: number;
/**
* Group label height in the cascading `em` unit.
*/
labelHeight: number;
/**
* Work to do before removing a group from the DOM.
* This is typically used for tweening the group view.
*/
groupRemovalWork?: (div: HTMLDivElement) => Promise<void>;
/**
* Work to do before removing a tile from the DOM.
* This is typically used for tweening the tile view.
*/
tileRemovalWork?: (button: HTMLButtonElement) => Promise<void>;
});
/**
* The overall tiles state.
*/
get state(): State;
/**
* Clears everything.
*/
clear(): void;
/**
* Destroys the `Tiles` instance, disposing
* of any observers and removing the container from the DOM.
*/
destroy(removeFromDOM?: boolean): void;
/**
* Adds a group to the end and returns its `div` element.
* @throws If group ID is duplicate.
*/
addGroup(params: AddGroupParams): void;
/**
* Removes a group.
* @throws If the group does not exist.
*/
removeGroup(id: string): void;
/**
* Attempts to add a tile.
*
* If both `x` and `y` are null, this method always succeeds,
* adding the tile to the best position available.
*
* @throws If tile ID is duplicate.
* @throws If group is specified and does not exist.
* @throws If either of `x` and `y` are `null`, but not both.
* @returns `true` if successfully added tile; `false` otherwise.
* It can fail depending on the `x` and `y` parameters.
*/
addTile(params: AddTileParams): boolean;
/**
* Removes a tile.
* @throws If the tile does not exist.
*/
removeTile(id: string): void;
/**
* Renames a group.
*/
renameGroup(id: string, label: string): void;
/**
* Attempts to resize a tile.
*/
resizeTile(id: string, size: TileSize): boolean;
/**
* Attempts to move a tile.
* @param x X coordinate in small tiles unit (1x1).
* @param y Y coordinate in small tiles unit (1x1).
*/
moveTile(id: string, x: number, y: number): boolean;
/**
* Returns which tiles are checked.
*/
checkedTiles(): string[];
/**
* Returns whether a tile is checked or not.
*/
getChecked(tile: string): boolean;
/**
* Sets whether a tile is checked or not.
*/
setChecked(tile: string, value: boolean): void;
/**
* Toggles whether a tile is checked or not.
*/
toggleChecked(tile: string): void;
/**
* Shorthand to `addEventListener()`.
*/
on<K extends keyof TilesEventMap>(type: K, listenerFn: (event: TilesEventMap[K]) => void, options?: AddEventListenerOptions): void;
on(type: string, listenerFn: (event: Event) => void, options?: AddEventListenerOptions): void;
/**
* Shorthand to `removeEventListener()`.
*/
off<K extends keyof TilesEventMap>(type: K, listenerFn: (event: TilesEventMap[K]) => void, options?: EventListenerOptions): void;
off(type: string, listenerFn: (event: Event) => void, options?: EventListenerOptions): void;
/**
* Returns the number of inline groups available for
* the given width (either in `px` or `em`).
* *Applies to vertical layouts only.*
*
* @throws If not in a vertical layout.
*/
inlineGroupsAvailable(width: string): number;
/**
* Indicates the number of inline groups in a vertical layout.
*
* @throws If not in a vertical layout.
*/
get inlineGroups(): number;
set inlineGroups(val: number);
/**
* Rearranges the layout.
*
* This call may be necessary if the container is scaled to zero, usable
* after the scale is greater than zero.
*/
rearrange(): void;
/**
* Rearranges the layout when the minimum scale to make it work
* is reached.
*
* This call may be necessary if the container is initially scaled to zero.
*/
rearrangeOverMinimumScale(): AbortController;
/** @hidden */
_keep_groups_contiguous(): void;
/** @hidden */
_deferred_rearrange(): void;
/** @hidden */
_deferred_state_update_signal(): void;
/** @hidden */
_state_update_signal(): void;
}
/**
* Tiles event map.
*/
export type TilesEventMap = {
addedgroup: CustomEvent<{
group: LayoutGroup;
div: HTMLDivElement;
labelDiv: HTMLDivElement;
tilesDiv: HTMLDivElement;
}>;
addedtile: CustomEvent<{
tile: LayoutTile;
button: HTMLButtonElement;
contentDiv: HTMLDivElement;
}>;
stateupdate: CustomEvent<State>;
dragstart: CustomEvent<{
tile: HTMLButtonElement;
}>;
drag: CustomEvent<{
tile: HTMLButtonElement;
}>;
dragend: CustomEvent<{
tile: HTMLButtonElement;
}>;
groupdragstart: CustomEvent<{
group: HTMLDivElement;
}>;
groupdrag: CustomEvent<{
group: HTMLDivElement;
}>;
groupdragend: CustomEvent<{
group: HTMLDivElement;
}>;
selectionchange: CustomEvent<{
tiles: string[];
}>;
click: CustomEvent<{
tile: string;
}>;
};
/**
* Parameters for adding a group.
*/
export type AddGroupParams = {
/**
* Unique group ID.
*/
id: string;
/**
* Initial label to display for the group.
* @default ""
*/
label?: string;
};
/**
* Parameters for adding a tile.
*/
export type AddTileParams = {
/**
* Tile ID.
*/
id: string;
/**
* Group to attach tile to. If unspecified,
* tile is attached to either the last group (if unlabeled)
* or a new last anonymous group.
*/
group?: string;
/**
* Horizontal position in small tiles.
*/
x?: number;
/**
* Vertical position in small tiles.
*/
y?: number;
/**
* Tile size.
* @default medium
*/
size?: TileSize;
};
export {};