UNPKG

web-ui-pack

Version:
192 lines (191 loc) 11.1 kB
import { onEventType } from "./helpers/onEvent"; export interface AttributeMap { /** One of default types with defined parse */ type: AttributeTypes; /** Option[name] realted to related attribute. Point if attrName !== propName */ prop?: string; /** Custom parser for related attribute */ parse?: (attrValue: string) => any; } export declare const enum AttributeTypes { /** Value presented by `true`, `false` or '' (empty string) */ bool = 0, number = 1, string = 2, reference = 3, parsedObject = 4, parseCustom = 5, /** Element accessed via `document.querySelector` */ selector = 6 } /** Basic abstract class for every component in web-ui-pack */ export default abstract class WUPBaseElement<TOptions extends Record<string, any> = Record<string, any>, Events extends WUP.Base.EventMap = WUP.Base.EventMap> extends HTMLElement { #private; /** Register control in the web to allow to use */ static $use(): void; /** Reference to global style element used by web-ui-pack */ static get $refStyle(): HTMLStyleElement | null; static set $refStyle(v: HTMLStyleElement | null); /** StyleContent related to component */ static get $style(): string; /** StyleContent related to component & inherited components */ static get $styleRoot(): string; /** Get unique id for html elements; Every getter returns new id */ static get $uniqueId(): string; /** Returns default class name for visually hidden element */ static get classNameHidden(): string; /** Returns default class name for buttons with icons */ static get classNameBtnIcon(): string; /** Returns map-type based on value */ static mapAttribute(value: any): AttributeTypes; /** Returns map-model based on $defaults for mapping attributes & options */ static get mappedAttributes(): Record<string, AttributeMap>; /** Array of options names to listen for changes; @returns `undefined` if need to observe for every option * @defaultValue every option from $defaults` */ static get observedOptions(): Array<string> | null; /** Array of attribute names to listen for changes * @defaultValue every option from `observedOptions` OR $defaults (in `w-${k.toLowerCase()}`) */ static get observedAttributes(): Array<string>; /** Global default options applied to every element. Change it to configure default behavior OR use `element.$options` to change per item */ static $defaults: Record<string, any>; /** Used to clone single value (from defaults) */ static cloneValue<T>(v: T): T; /** Used to clone defaults to options on init; override it to clone */ static cloneDefaults<T extends Record<string, any>>(): T; /** Merge options with $defaults; Object.assign merges values 'undefined' by the method replace undefined with defaults */ static mergeDefaults<T extends Record<string, any>>(opts: T): T; /** Raw part of $options for internal usage (.$options is Proxy object and better avoid useless extra-calles via Proxy) */ protected _opts: TOptions; get $options(): Partial<TOptions>; /** Options inherited from `static.$defaults` and applied to element. Use this to change behavior per item OR use `$defaults` to change globally */ set $options(v: Partial<TOptions>); static findAllProtos(t: unknown, protos: (typeof WUPBaseElement)[]): (typeof WUPBaseElement)[]; /** Add common styles */ static firstInit(): void; constructor(); /** Returns true if element is appended (result of setTimeout on connectedCallback) */ get $isReady(): boolean; /** Returns if current element or some nested child is active/focused */ get $isFocused(): boolean; /** Try to focus self or first possible children; returns true if successful */ focus(): boolean; /** Remove focus from element on any nested active element */ blur(): void; /** Called when need to parse attribute */ parse(text: string): any; /** Clear this to prevent autofocus */ _willFocus?: ReturnType<typeof setTimeout>; /** Called when element is added to document (after empty timeout - at the end of call stack) */ protected gotReady(): void; /** Called when element is removed from document */ protected gotRemoved(): void; /** Called on Init (with propsChanged: null) and every time as options/attributes changed */ protected gotChanges(propsChanged: Array<string> | null): void; /** Called when element isReady and at least one of observedOptions is changed */ protected gotOptionsChanged(e: WUP.Base.OptionEvent): void; /** Called once on Init */ protected gotRender(): void; /** Browser calls this method when the element is added to the document */ protected connectedCallback(): void; /** Browser calls this method when the element is removed from the document; * (can be called many times if an element is repeatedly added/removed) */ protected disconnectedCallback(): void; /** Prevent gotChanges call during the some attribute or options custom changes */ _isStopChanges: boolean; /** Called when any of observedAttributes is changed */ protected gotAttributeChanged(name: string, value: string | null): void; /** Parse attribute & assign to related property * @returns defined propertyName */ protected attrToProp(name: string, value: string | null): string; /** Browser calls this method when attrs pointed in observedAttributes is changed */ protected attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void; addEventListener<K extends keyof Events>(type: K, listener: (this: WUPBaseElement, ev: Events[K]) => any, options?: boolean | AddEventListenerOptions): void; addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; removeEventListener<K extends keyof Events>(type: K, listener: (this: WUPBaseElement, ev: Events[K]) => any, options?: boolean | EventListenerOptions): void; removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; /** Inits customEvent & calls dispatchEvent and returns created event; by default `cancelable: false, bubbles: true` * @tutorial Troubleshooting * * Default event bubbling: el.event.click > el.onclick >>> parent.event.click > parent.onclick etc. * * Custom event bubbling: el.$onclick > el.event.$click >>> parent.event.$click otherwise impossible to stop propagation from on['event] of target directly */ fireEvent<K extends keyof Events, T extends Events[K]["detail"]>(type: K, eventInit?: CustomEventInit<T>): Event; /** Array of removeEventListener() that called on remove */ protected disposeLst: Array<() => void>; /** Add event listener and remove after component removed; @options.passive=true by default */ appendEvent<T extends keyof E, K extends HTMLElement | Document, E extends HTMLElementEventMap & Record<string, Event>>(...args: Parameters<onEventType<T, K, E>>): () => void; /** Remove events/functions that was appended */ protected dispose(): void; /** Returns true if el is instance of Node and contains pointed element * @tutorial Troubleshooting * * if element has position `fixed` or `absolute` then returns false */ includes(el: unknown): boolean; /** Returns true if element contains eventTarget or it's eventTarget * @tutorial Troubleshooting * * if element has position `fixed` or `absolute` then returns false */ includesTarget(e: Event): boolean; /** Find parent/self according with callback */ findParent(callback: (el: HTMLElement) => boolean, options?: { bubbleCount: number; }): HTMLElement | null; /** Returns true if contains pointed element or has itself * @tutorial Troubleshooting * * if element has position `fixed` or `absolute` then returns false */ itsMe(el: Element | EventTarget | null): boolean; /** Returns first element according to pointed selector * @tutorial rules * * point 'prev' to return previousElementSibling * * point 'next' to return nextElementSibling * * point ordinary selector to execute `document.querySelector(selector)` */ findBySelector<T extends HTMLElement>(selector: string): T | null; /** Returns parsed value according to pointed type OR current value if something wrong; * override method for implementation custom parsing OR static method mappedAttributes to redefine map-types */ parseAttr(type: AttributeTypes, attrValue: string, propName: string, attrName: string): any; /** Remove attr if value falseOrEmpty; set '' or 'true' if true for HTMLELement * @param isSetEmpty set if need '' instead of 'value' */ setAttr(attr: string, v: boolean | string | undefined | null, isSetEmpty?: boolean): void; /** Remove all children in fastest way */ removeChildren(): void; /** Throws unhandled error via empty setTimeout */ throwError(err: string | Error | unknown, details?: any, consoleOnly?: boolean): void; /** Removes empty attr [style] */ removeEmptyStyle(): void; } declare global { /** Translate function that need to replace to translate content according to requirements * @param text Text that must be translated * @param type Type of related text * @returns the same string by default */ const __wupln: WUP.Base.LangFunc; interface Window { /** Translate function that need to replace to translate content according to requirements * @param text Text that must be translated * @param type Type of related text * @returns the same string by default */ __wupln: WUP.Base.LangFunc; } namespace WUP.Base { interface LangFunc { (text: string, type: "aria" | "content" | "validation"): string; } /** Cast not-supported props to optional string */ type toJSX<T> = { [P in keyof T]?: T[P] extends number | boolean | string | undefined ? T[P] : string; }; type OnlyNames<T> = { [K in keyof T as K extends string ? `w-${K}` : never]?: unknown; }; type OptionEvent<T extends Record<string, any> = Record<string, any>> = { props: Array<Extract<keyof T, string>>; target: T; }; type EventMap<T = HTMLElementEventMap> = HTMLElementEventMap & Record<keyof T, Event>; type ReactHTML<T> = React.DetailedHTMLProps<Omit<React.HTMLAttributes<T>, "className"> & { class?: string | undefined; /** @deprecated isn't supported for React & WebComponents; use attr `class` instead * @see {@link https://react.dev/reference/react-dom/components#custom-html-elements} */ className?: never; }, T>; type JSXProps<T> = React.DetailedHTMLProps<Omit<React.HTMLAttributes<T>, "className"> & { class?: string | undefined; }, T>; } }