@alttiri/popup-enhance
v1.2.0-20240821
Published
A pretty simple JavaScript (TS) library to enhance a popup to make it movable and resizable
Downloads
2
Readme
PopupEnhance
It's a pretty simple JavaScript (TS) library (mostly, for personal use) to enhance a popup to make it movable and resizable.
It's only 34 lines to make it movable: makeMovable
↓ and 38 lines to make it resizable: makeResizable
↓
Also, there is en extra code to store the move / resize state in localStorage
(popup-enh-extra.ts
).
The required CSS is located here: popup.css
.
It's available on npm:
npm i @alttiri/popup-enhance
Demo
https://alttiri.github.io/popup-enhance/ (see: main.ts
).
How to use
import {getPopupEnh, makeFocusable} from "@alttiri/popup-enhance";
const {makeMovableEx} = getPopupEnh("fancy-demo-app");
const popupElem = document.querySelector(".popup");
const handleElem = popupElem.querySelector(".popup-header");
const {reset} = makeMovableEx(popupElem, "popup-1", {handle: handleElem});
makeFocusable(popupElem, handleElem);
"fancy-demo-app"
—localStorage
' prefix for keys"popup-1"
—localStorage
' key
The recommended HTML:
<body>
<div id="app"> ... </div>
<div class="popup-root">
<div class="popup" id="popup-1">
<div class="popup-header">Popup Title</div>
<div class="popup-content"> ... </div>
</div>
<div class="popup" id="popup-2"> ... </div>
</div>
</body>
The recommended CSS:
// JS imports:
import "@alttiri/popup-enhance/css/popup.css";
import "@alttiri/popup-enhance/css/popup-content.css";
// Or CSS import:
// @import "@alttiri/popup-enhance/css/popup.css";
// @import "@alttiri/popup-enhance/css/popup-content.css";
makeMovable
https://github.com/AlttiRi/popup-enhance/blob/606e39414083c47ebf6a1d2d5457ccf3f5e08c65/src/popup-enh-core.ts#L29-L63
makeResizable
https://github.com/AlttiRi/popup-enhance/blob/606e39414083c47ebf6a1d2d5457ccf3f5e08c65/src/popup-enh-core.ts#L76-L114
See also
- https://github.com/AlttiRi/drag-select-demo
*.d.ts
export type MoveStyleProps = "top" | "left";
export type MoveState = Record<MoveStyleProps, `${string}px`>;
export type ResizeStyleProps = "width" | "height";
export type ResizeState = Record<ResizeStyleProps, `${string}px`>;
export type AnyStyleProps = MoveStyleProps | ResizeStyleProps;
export type AnyState = MoveState | ResizeState;
export type MovableOpts = {
handle?: HTMLElement;
onMove?: (state: MoveState) => void;
onStop?: (state: MoveState) => void;
state?: MoveState;
reset?: Function;
position?: "absolute" | "relative";
};
export declare function makeMovable(element: HTMLElement, { handle: hdl, onMove, onStop, state, reset, position }?: MovableOpts): {
reset: () => void;
};
export type ResizableOpts = {
minW?: number;
minH?: number;
size?: number;
onMove?: (state: ResizeState) => void;
onStop?: (state: ResizeState) => void;
state?: ResizeState;
reset?: Function;
};
export declare function makeResizable(element: HTMLElement, { minW, minH, size, onMove, onStop, state, reset }?: ResizableOpts): {
reset: () => void;
};
type StoreStateOpt<T extends AnyState, S extends string> = {
id: S extends "" ? never : S;
onMove?: (state: T) => void;
onStop?: (state: T) => void;
};
type StoreStateReturn<T extends AnyState> = {
onMove?: (state: T) => void;
onStop?: (state: T) => void;
state?: T;
reset: () => void;
};
export declare function storeStateInLS<T extends AnyState, S extends string>({ id: lsName, onMove, onStop }: StoreStateOpt<T, S>): StoreStateReturn<T>;
export declare function getPopupEnh<S extends string>(appName: S extends "" ? never : S): {
/**
* Use `position: "relative"` option if you want to open multiple popups at once,
* and you do not want they overlap each other. However, don't use it with resizable popups.
*/
makeMovableEx<S_1 extends string>(element: HTMLElement, id: S_1 extends "" ? never : S_1, opt?: MovableOpts): {
reset: () => void;
};
makeResizableEx<S_1 extends string>(element: HTMLElement, id: S_1 extends "" ? never : S_1, opt?: ResizableOpts): {
reset: () => void;
};
};
/**
* Makes the element focusable, adds `"focus"` class.
* Specify the drag `handle` (if exists) to run `"focus"` listener callback on `"pointerdown"` on it.
*/
export declare function makeFocusable(element: HTMLElement, handle?: HTMLElement): void;