UNPKG

web-ui-pack

Version:
193 lines (192 loc) 8.74 kB
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 {};