/** * Moves one thing — the launcher or the panel — around the viewport. * * What a gesture produces is not a position but a displacement: how far the * reader has dragged the widget from wherever the theme put it, in screen * pixels. The host keeps one such displacement for the whole widget and hands * it to both controllers, which is what makes the two states travel together: * drag the launcher into a corner and the panel opens in that same corner, * because both are the theme's position plus the same shift. * * Each controller then turns the displacement into the terms its own corner * uses — at a right-hand corner, moving right means a smaller offset — and * writes it into the two custom properties the stylesheet already reads. The * offset lives on the host as an inline property, which outranks the theme's * sheet and the page's CSS: a reader who dragged the widget somewhere means * it, and until the drag is cleared theirs is the most specific word on where * it goes. * * @implements {ReactiveController} */ export class DragController implements ReactiveController { /** * @param {LitElement} host * @param {DragOptions} options */ constructor(host: LitElement, options: DragOptions); hostConnected(): void; hostDisconnected(): void; /** * True when the gesture that just ended was a drag. Reading it clears it, so * the click a pointer-up fires can be skipped exactly once. * * @returns {boolean} */ consumeDrag(): boolean; /** * Put this thing where the displacement says, within the viewport. * * @param {{ x: number, y: number } | null} displacement * @returns {{ x: number, y: number } | undefined} Where it ended up, when it is on screen. */ place(displacement: { x: number; y: number; } | null): { x: number; y: number; } | undefined; /** * Begin a drag. * * @param {PointerEvent} event * @returns {void} */ start(event: PointerEvent): void; /** * Move with the arrow keys, so the same thing can be done without a pointer. * * @param {KeyboardEvent} event * @returns {boolean} True when the key was used. */ nudge(event: KeyboardEvent): boolean; #private; } export type DragOptions = { name: "launcher" | "panel"; enabled: () => boolean; /** * What moves. */ element: () => HTMLElement | null; /** * How big it means to be. */ size: () => { width: number; height: number; }; /** * Which corner the offset counts from. */ corner: () => Position; /** * The theme's offset, before any drag. */ base: () => { x: number; y: number; }; /** * The widget's displacement now. */ current: () => { x: number; y: number; } | null; /** * A new displacement. */ onMove: (displacement: { x: number; y: number; }) => void; /** * The gesture ended here. */ onSettle: (name: "launcher" | "panel") => void; /** * The custom properties to write. */ vars: { x: string; y: string; }; }; import type { ReactiveController } from 'lit'; import type { LitElement } from 'lit'; import type { Position } from '../types.js';