web-ui-pack
Version:
Web package with UI elements
193 lines (192 loc) • 8.74 kB
TypeScript
import { AttributeMap } from "./baseElement";
import WUPBaseModal from "./baseModal";
export declare const enum ModalOpenCases {
/** When $open() is called programmatically */
onManualCall = 0,
/** On init (when appended to layout) */
onInit = 1,
/** When click on target @see {@link WUP.Modal.Options.target} */
onTargetClick = 2
}
export declare const enum ModalCloseCases {
/** When $close() is called programmatically */
onManualCall = 0,
/** When was click on button[close] */
onCloseClick = 1,
/** When was click outside modal */
onOutsideClick = 2,
/** When user pressed Escape button */
onPressEsc = 3,
onSubmitEnd = 4
}
declare const tagName = "wup-modal";
declare const attrConfirm = "w-confirm";
declare global {
namespace WUP.Modal {
interface ConfirmOptions {
/** Message appended to confirm modal as question */
question?: string;
/** Options to override defaults of modal */
defaults?: Partial<WUP.Modal.Options>;
/** Called when element is already rendered; so possible to change innerHTML */
onRender?: (el: WUPModalElement) => void;
/** Default class that appended to confirm modal */
className?: string;
}
interface Options {
/** Element that modal need to listen for click. If `target` missed then modal will be opened on init
* @defaultValue null */
target?: Element | null;
/** Position on the screen
* @defaultValue 'center' */
placement: "center" | "top" | "left" | "right";
/** Auto focus first possible content with skipping focus on button[close] if there is another focusable content
* Point `false` to autofocus on button[close].
* If you don't need any visual focus by default override method focus() and call `HTMLElement.prototype.focus.call(this)` to focus modal-box itself
* @defaultValue true */
autoFocus: boolean;
/** Auto close on successful wup-form.$onSubmitEnd: @see {@link WUP.Form.EventMap.$submitEnd}
* @defaultValue true */
autoClose: boolean;
/** Remove itself after closing
* @defaultValue false */
selfRemove: boolean;
/** Modal-in-modal behavior; by default new modal overflows previously opened modal
* @defaultValue false */
replace: boolean;
/** Show confirm modal if user closes modal with `wup-form` with unsaved changes (isChanged & option autoStore is off)
* @defaultValue true */
confirmUnsaved: boolean;
}
interface EventMap extends WUP.BaseModal.EventMap<ModalOpenCases, ModalCloseCases> {
}
interface JSXProps extends WUP.BaseModal.JSXProps, WUP.Base.OnlyNames<Options> {
/** QuerySelector to find target - element that modal need to listen for click. If `target` missed modal will be opened on init
* @tutorial rules
* * point 'prev' to select previousSibling */
"w-target"?: string;
"w-placement"?: Options["placement"];
"w-autoFocus"?: boolean | "";
"w-autoClose"?: boolean | "";
"w-selfRemove"?: boolean | "";
}
}
interface HTMLElement {
/** Called when related modalElement is already rendered before opening; so possible to change innerHTML */
$onRenderModal?: (modal: WUPModalElement) => void;
}
interface HTMLElementTagNameMap {
[tagName]: WUPModalElement;
}
namespace React {
interface ButtonHTMLAttributes<T> {
/** Point message for confirm-modal then`click` event will be fired only after btn-confirm click
* @see {@link WUPModalElement.$useConfirmHook} */
[attrConfirm]?: string;
}
}
}
declare module "react" {
namespace JSX {
interface IntrinsicElements {
/** Modal element
* @see {@link WUPModalElement} */
[tagName]: WUP.Base.ReactHTML<WUPModalElement> & WUP.Modal.JSXProps;
}
}
}
declare module "preact/jsx-runtime" {
namespace JSX {
interface HTMLAttributes<RefType> {
/** Point message for confirm-modal then`click` event will be fired only after btn-confirm click
* @see {@link WUPModalElement.$useConfirmHook} */
[attrConfirm]?: string;
}
interface IntrinsicElements {
/** Modal element
* @see {@link WUPModalElement} */
[tagName]: HTMLAttributes<WUPModalElement> & WUP.Modal.JSXProps;
}
}
}
/** Modal element
* @see demo {@link https://yegorich555.github.io/web-ui-pack/modal}
* @example
* JS/TS
* ```js
* WUPModalElement.$defaults.placement = ...;
*
* const el = document.createElement('wup-modal');
* el.textContent = ...;
* document.body.append(el);
* el.$onClose = () => el.remove(); // self-remove after close
*```
* HTML
* ```html
* <wup-modal>Some content here</wup-modal>
* ```
* @tutorial Troubleshooting known issues:
* * for very long content with 1st focusable item at the bottom it won't be visible because user must see top of the modal at first
* To fix the issue set `<h2 tabindex="-1">...</h2>` and hide focus frame via styles OR disable `$options.autoFocus`
* * accessibility: NVDA reads modal content twice. To fix follow the recommendations: https://github.com/nvaccess/nvda/issues/8971 */
export default class WUPModalElement<TOptions extends WUP.Modal.Options = WUP.Modal.Options, Events extends WUP.Modal.EventMap = WUP.Modal.EventMap> extends WUPBaseModal<TOptions, Events> {
#private;
/** Call it to enable attribute [w-confirm] for buttons
* @tutorial Rules
* * to override default render: redefine `WUPModalElement.prototype.gotRenderConfirm` method OR use `onRender` callback; @see {@link WUPModalElement.$showConfirm}
* @example
* ```html
* <button w-confirm="Do you want to do it?">
* I will fire click event only when confirmButton will be pressed in the confirm-modal
* </button>
* ``` */
static $useConfirmHook(opts?: WUP.Modal.ConfirmOptions): void;
/** Show confirm modal and return Promise(true) if user pressed button[data-close=confirm] and before modal is closed itself
* @tutorial Troubleshooting
* * ConfirmModal ignores option `placement` if it overflow existed modal
* * On close modal self-removed */
static $showConfirm(opts?: WUP.Modal.ConfirmOptions): Promise<boolean>;
/** Default class used for fade - blurring background for main content
* @defaultValue "wup-modal-fade" */
static $classFade: string;
/** Default class that appended to body when modal opened (required to hide body scroll)
* @defaultValue "wup-modal-open" */
static $classOpened: string;
static get $styleRoot(): string;
static get $style(): string;
static $defaults: WUP.Modal.Options;
static get mappedAttributes(): Record<string, AttributeMap>;
/** Reference to fade element */
$refFade?: HTMLElement;
/** Reference to button[close] */
$refClose?: HTMLButtonElement;
/** Called once on opening */
protected gotRender(isOpening?: boolean): void;
/** Override it to change default render for modalConfirm */
gotRenderConfirm(headerContent: string): void;
/** Related button that need to listen for click event to open modal */
_target?: Element | null;
/** Click event related to _target */
_targetClick?: (e: MouseEvent) => void;
protected gotChanges(propsChanged: string[] | null): void;
/** Id of last focused item on item itself */
_lastFocused?: Element | string | null;
/** Number of opened modal */
_mid?: number;
gotOpen(openCase: ModalOpenCases, e: MouseEvent | null): void;
goClose(closeCase: ModalCloseCases, ev: Event | null, immediately?: boolean): Promise<boolean>;
gotClose(closeCase: ModalCloseCases, ev: MouseEvent | KeyboardEvent | WUP.Form.EventMap["$submitEnd"] | null): void;
/** Called when modal handles click to check if was close-click */
gotClick(e: MouseEvent): void;
/** Called on keydown event */
gotKeyDown(e: KeyboardEvent): void;
/** Called on close to return focus to previously focused item */
focusBack(): void;
/** Focus any content excluding button[close] if possible */
focusAny(): void;
protected resetState(): void;
protected dispose(): void;
/** Singleton array with opened elements */
get _openedItems(): Array<WUPModalElement>;
}
export {};