galho
Version:
galho is js library for create and manipulate dom elements without need compiling, configuration or VirtualDom
343 lines (342 loc) • 16.7 kB
TypeScript
import type { Properties } from "csstype";
import { EventObject, EventTargetCallback, Options } from "./event.js";
import { AnyDic, Arr, Dic, Key, bool, falsy, int, str } from "./util.js";
export type { Properties, Property } from "csstype";
export type HTMLTag = keyof HTMLElementTagNameMap;
export type SVGTag = keyof SVGElementTagNameMap;
export type HSElement = HTMLElement | SVGElement;
export type One<T extends HSElement = HTMLElement> = T | G<T> | Render<G<T>>;
export type NotRender = bool | null | undefined | "";
export type Content<T> = NotRender | T | PromiseLike<Content<T>> | (() => Content<T>);
export interface Render<T = any> {
render(): T;
}
export type HTMLEventMap<T> = {
[K in keyof HTMLElementEventMap]?: (this: T, e: HTMLElementEventMap[K]) => any;
};
export type SVGEventMap<T> = {
[K in keyof SVGElementEventMap]?: (this: T, e: SVGElementEventMap[K]) => any;
};
export type Styles = Dic<Style>;
export type Style = Properties | Styles | {
":hover": Style;
":active": Style;
":focus": Style;
":focus-within": Style;
":autofill": Style;
":checked": Style;
":invalid": Style;
":empty": Style;
":root": Style;
":enabled": Style;
":disabled": Style;
":link": Style;
":visited": Style;
":lang": Style;
":first-child": Style;
":last-child": Style;
":only-child": Style;
};
/**
* create new element and append content to it
* @param tagName tag name of element to create
* @param content elements, string, number, function, PromiseLike or anything that can be append to an element. true, false, null and undefined will be ignored
*/
export declare function g<K extends HTMLTag>(tagName: K, content: any[] | (() => any)): G<HTMLElementTagNameMap[K]>;
/**
* create new element define a class attribute and append content to it
* @param tagName tag name of element to create
* @param className a class or a space separted list of classes, {@link falsy} values will be ignored
* @param content elements, string, number, function, PromiseLike or anything that can be append to an element. true, false, null and undefined will be ignored
*/
export declare function g<K extends HTMLTag>(tagName: K, className?: str | falsy, content?: any): G<HTMLElementTagNameMap[K]>;
/**
* create new element define a class attribute and append content to it
* @param tagName tag name of element to create
* @param properties an object contain properties (not attributes) to assigned to it.
* @param content elements, string, number, function, PromiseLike or anything that can be append to an element. true, false, null and undefined will be ignored
*/
export declare function g<K extends HTMLTag>(tagName: K, properties: Partial<HTMLElementTagNameMap[K]>, content?: any): G<HTMLElementTagNameMap[K]>;
/**
* create a wrapper around an element, set properties to it and append content
* @param element element to wrap
* @param properties an object contain properties (not attributes) to assigned to it.
* @param content elements, string, number, function, PromiseLike or anything that can be append to an element. true, false, null and undefined will be ignored
*/
export declare function g<T extends HTMLElement = HTMLElement>(element: Element | One<T>, properties: Partial<T>, content?: any): G<T>;
/**
*
* @param element
* @param className
* @param content
*/
export declare function g<T extends HTMLElement = HTMLElement>(element: Element | One<T>, className?: str | falsy, content?: any): G<T>;
export declare function g<T extends HTMLElement = HTMLElement>(element: Element | One<T>, content: any[] | (() => any)): G<T>;
export default g;
export declare const m: <T extends HSElement = HSElement>(...elements: (G<T> | T | falsy)[]) => M<T>;
/** create div element
* @param properties if is string or string array will the class if not will be set as props of created element
* @param content elements, string, number or anything that can be append to an element */
export declare function div(properties?: Partial<HTMLDivElement>, content?: any): G<HTMLDivElement>;
export declare function div(className?: str | falsy, content?: any): G<HTMLDivElement>;
export declare function div(content: any[] | (() => any)): G<HTMLDivElement>;
/**html empty char */
export declare const empty = "​";
/**get `document.activeElement` */
export declare const active: () => G<HTMLElement>;
/** @ignore */
export declare const isE: (v: any) => v is G<any>;
/** convert to DOM Element @ignore */
export declare const asE: <T extends HSElement>(v: T | G<T>) => HTMLElement | T;
/**create an element using ns:`http://www.w3.org/1999/xhtml` */
export declare function html<T extends keyof HTMLElementTagNameMap>(tag: T, props?: string | Partial<HTMLElement>, child?: any): G<HTMLElement>;
/**
* create an svg element
* @param tag
* @param attrs
* @param child
* @returns
*/
export declare function svg<T extends keyof SVGElementTagNameMap>(tag: T, attrs?: string | Dic<string | number> | 0 | string | string[], child?: any): G<SVGElementTagNameMap[T]>;
/**convert html string to svg element */
export declare function toSVG<T extends SVGElement = SVGElement>(text: string): M<T>;
export declare function onfocusout(e: G, handler: (e: FocusEvent) => any): G<HTMLElement>;
export declare function wrap<T extends HSElement = HTMLElement>(content: any, properties: Partial<T>, tag?: keyof HTMLElementTagNameMap): G<T>;
export declare function wrap<T extends HSElement = HTMLElement>(content: any, properties?: falsy | str, tag?: keyof HTMLElementTagNameMap): G<T>;
/** select first element that match query same as `document.querySelect` */
export declare const get: <T extends HSElement = HTMLElement>(selectors: string) => G<HTMLElement>;
/** select all element that match query same as `document.querySelectAll` */
export declare const getAll: <T extends HSElement = HTMLElement>(selectors?: string) => M<T>;
/**fire event after specified amount of time */
export declare function delay<T extends HSElement, K extends keyof HTMLElementEventMap>(e: G<T>, action: K, delay: number, listener: (this: T, e: HTMLElementEventMap[K]) => any): G<T>;
export declare function delay<T extends HSElement, K extends keyof SVGElementEventMap>(e: G<T>, action: K, delay: number, listener: (this: T, e: SVGElementEventMap[K]) => any): G<T>;
/** wrap for stopImmediatePropagation and preventDefault on Event */
export declare function clearEvent(e: Event): void;
export type CSSSep = ">" | " " | ":" | "~" | "+";
/** simple style builder */
export declare function css(props: Style, defSubSelector?: CSSSep, selector?: string): str;
/**
* A Wrapper for an HTML OR SVG Element
*/
export declare class G<T extends HSElement = HTMLElement> {
readonly e?: T;
constructor();
constructor(e: T);
constructor(e: EventTarget);
static empty: G<any>;
get active(): boolean;
get parent(): G<HTMLElement>;
/**get previus element sibling */
get prev(): G<HTMLElement>;
/**get next element sibling */
get next(): G<HTMLElement>;
/**first children element */
get first(): G<HTMLElement>;
/**last children element */
get last(): G<HTMLElement>;
/**get bounding client rect */
get rect(): DOMRect;
/** @ignore */
toJSON(): void;
/** check if `this` contains `child` */
contains(child: G<any> | HSElement): boolean;
/** get Input value */
v(): str;
/** set Input value */
v(value: Key): this;
/** add listener to one or more HTML Event */
on(actions: HTMLEventMap<T>, options?: AddEventListenerOptions): this;
/** add listener to one or more SVG Event */
on(actions: SVGEventMap<T>, options?: AddEventListenerOptions): this;
/** add listener to one HTML Event if `listener` is {@link falsy} do not anything*/
on<K extends keyof HTMLElementEventMap>(action: K, listener: ((this: T, e: HTMLElementEventMap[K]) => any) | falsy, options?: AddEventListenerOptions): this;
on<K extends keyof SVGElementEventMap>(action: K, listener: ((this: T, e: SVGElementEventMap[K]) => any) | falsy, options?: AddEventListenerOptions): this;
on<K extends keyof HTMLElementEventMap>(action: K[], listener: (this: T, e: HTMLElementEventMap[K]) => any, options?: AddEventListenerOptions): this;
/** add event listener with `once` option, E.g: remove alement after it has been dispached */
one<K extends keyof HTMLElementEventMap>(event: K, listener: (this: HTMLElement, e: HTMLElementEventMap[K]) => any): this;
one<K extends keyof SVGElementEventMap>(event: K, listener: (this: SVGElement, e: SVGElementEventMap[K]) => any): this;
emit(name: str, event?: EventInit): this;
emit(event: Event): this;
/**remove event listener */
off<K extends keyof HTMLElementEventMap>(event: K | K[], listener: EventListener): this;
/** insert adjacent content to `this`
* @param child can be any valid content
*/
put(position: InsertPosition, child: any): this;
/**insert adjacent after end */
after(child: any): this;
/**insert adjacent before begin */
before(child: any): this;
putText(pos: InsertPosition, text: string | number): this;
putHTML(pos: InsertPosition, html: string): this;
/**append child */
add(child: any): this;
/**(begin add) add child at begin of element */
badd(child: any): this;
/**
* insert content at an specified index
* @throws `invalid index` if index is outside [0, `children.length`[
* @param index
* @param content
* @returns `this`
*/
place(index: int, content: any): this;
/**remove child at an specified index @returns `this` */
unplace(index: int): this;
addHTML(html: string): this;
/**clear content and append new content */
set(content?: any): this;
is<T extends G>(filter: T): this is T;
is<T extends HSElement>(filter: T): this is G<T>;
is<T extends HTMLTag>(filter: T): this is G<HTMLElementTagNameMap[T]>;
is(filter: string): bool;
/**get id */
id(): string;
/**set id */
id(value: string | number): this;
text(): string;
text(text: number | string): this;
/** add `this` to another element
* @param parent element to insert into
*/
addTo(parent: HSElement | G): this;
html(): string;
html(content: string): this;
replace(child: any): this;
focus(options?: FocusOptions): this;
blur(): this;
/**get child element at specified index */
child<C extends HSElement = T>(index: number): G<C>;
/**get first child element that match filter */
child<K extends keyof HTMLElementTagNameMap>(filter: K): G<HTMLElementTagNameMap[K]>;
child(filter: string): G;
/**get all children element */
childs(): M;
childs<T extends HSElement = HSElement>(from: number, to?: number): M<T>;
childs<K extends keyof HTMLElementTagNameMap>(filter: K): M<HTMLElementTagNameMap[K]>;
childs<T extends HSElement = HTMLElement>(filter: string): M<T>;
childs<T extends HSElement = HTMLElement>(filter: (child: G) => boolean): M<T>;
query<K extends keyof HTMLElementTagNameMap>(filter: K): G<HTMLElementTagNameMap[K]>;
query<U extends HTMLElement | SVGElement = HTMLElement>(filter: string): G<U>;
queryAll<K extends keyof HTMLElementTagNameMap>(filter: K): M<HTMLElementTagNameMap[K]>;
queryAll<U extends HTMLElement | SVGElement = HTMLElement>(filter: string): M<U>;
closest<K extends keyof HTMLElementTagNameMap>(filter: K): G<HTMLElementTagNameMap[K]>;
closest(filter: string): G;
parents(filter: string): M<HSElement>;
clone(deep?: boolean): G<HTMLElement>;
/**get property */
p<K extends keyof T>(key: K): T[K];
/**set property */
p<K extends keyof T>(key: K, value: T[K]): this;
/**set multiple properties undefined value are ignored if `keepUndefined` is set to `false` or not defined*/
p(props: Partial<T>, keepUndefined?: bool): this;
call<K extends keyof T>(key: K, ...args: any[]): this;
/**get */
css<T extends keyof Properties>(property: T): string;
css<T extends keyof Properties>(property: T, value: Properties[T], important?: bool): this;
css(styles: Properties, important?: bool): this;
/**remove all inline style */
uncss(): this;
/**remove a list of inline style */
uncss(...properties: Array<keyof Properties>): this;
/**add classes */
c(classes: Arr<str>): this;
/**add or remove classes */
c(classes: Arr<str>, set: bool): this;
/**toggle class */
tcls(names: string): this;
/**get attribute */
attr(name: string): string;
/**set attribute
* `false` value will remove the attribute
* `true` value will set attribute value to a blank string eg:
* ```html
* <div attr></div>
* ```
*/
attr(name: string, value: string | boolean | number): this;
attr(attrs: Dic<string | boolean | number>): this;
/**attach data to `this` element
* an element can only have one data attached to it
*/
d(data: any): this;
/**retrive data attached to this element if no data is attachad try get data attached with his parent */
d<T = unknown>(): T;
remove(): this;
}
/**
* Represent Multiples {@link Element} have part of the functions of {@link G} but applied to multple element at once
*/
export declare class M<T extends HSElement = HSElement> extends Array<T> {
constructor(...elements: (G<T> | T | falsy)[]);
constructor(lenght: int);
e(i: number): G<T>;
on<K extends keyof HTMLElementEventMap>(action: K, listener: (this: T, e: HTMLElementEventMap[K]) => any, options?: AddEventListenerOptions): M<T>;
on<K extends keyof SVGElementEventMap>(action: K, listener: (this: T, e: SVGElementEventMap[K]) => any, options?: AddEventListenerOptions): M<T>;
emit(name: keyof HTMLElementEventMap | keyof SVGElementEventMap, event?: EventInit): this;
emit(event: Event): this;
css(props: Properties, important?: bool): this;
/**remove all inline css */
uncss(): this;
/**remove inline css */
uncss(properties: Array<keyof Properties>): this;
/**add classes */
c(names: str[] | str): this;
/**add or remove classes
* @param set if `false` remove classes otherwise add
*/
c(names: str[] | str, set: boolean): this;
p<K extends keyof T>(prop: K, value: T[K]): this;
remove(): this;
child(): M;
child(filter: string): M;
child(index: number): M;
next(): M<HTMLElement | SVGElement>;
prev(): M<HTMLElement | SVGElement>;
do(cb: (v: G<T>, index: number) => any): this;
eachS(callbackfn: (value: G<T>, index: number) => void): this;
push(...items: (Element | One<T> | keyof HTMLElementTagNameMap)[]): number;
}
export interface M<T extends HSElement = HSElement> {
/** @ignore */
slice: (start?: number, end?: number) => M<T>;
}
export type BindHandler<T, P, B> = (this: T, s: B, p: P) => void;
export declare abstract class Component<P = {}, Ev extends AnyDic<any[]> = {}, T extends HSElement = HTMLElement> implements Render<G<T>>, EventObject<Ev & {
set: [P];
}> {
/**properties */
p: P;
$: G<T>;
validators: Dic<Array<(value: any, field: any) => boolean | void>>;
constructor(i?: P);
protected view?(): One<T>;
focus(): this;
render(): G<T>;
dispose(): void;
addValidators<K extends keyof P>(field: K, validator: (value: P[K], field: K) => boolean | void): this;
private _valid;
set(): this;
set<K extends keyof P>(key: K[]): this;
set<K extends keyof P>(key: K, value: Pick<P, K>): this;
set<K extends keyof P>(key: K, value: P[K]): this;
set(values: Partial<P>): this;
toggle(key: keyof P): this;
clone(): this;
readonly eh: {
[K in keyof Ev | 'set']?: EventTargetCallback<this, (Ev & {
set: [P];
})[K]>[];
};
on<K extends keyof Ev>(event: K, callback: EventTargetCallback<this, Ev[K]>, options?: Options): this;
on(callback: EventTargetCallback<this, [Partial<P>]>, options?: Options): this;
off<K extends keyof Ev | 'set'>(event: K, callback?: EventTargetCallback<this, (Ev & {
set: [P];
})[K]>): this;
emit(event: "set", arg: P): this;
emit<K extends keyof Ev>(event: K, ...args: Ev[K]): this;
onset<K extends keyof P>(props: K[] | K, callback: EventTargetCallback<this, [Partial<P>]>, options?: Options): this;
bind<R extends Render, K extends keyof P>(e: R, handler: (this: this, s: R, p: Partial<P>) => void, prop?: K, noInit?: bool): G;
bind<T extends HSElement, K extends keyof P>(s: G<T>, handler: (this: this, s: G<T>, p: P) => void, prop?: K, noInit?: bool): G<T>;
private toJSON;
}