galho
Version:
galho is js library for create and manipulate dom elements without need compiling, configuration or VirtualDom
256 lines (255 loc) • 9.14 kB
TypeScript
/**
* # Observable aRRAY
*
* this is module have a collection of class and functions to help with list
* with tasks like events, binds, subgroups and tags
*
* @module
*/
import type { EventObject, EventTargetCallback, Options } from "./event.js";
import type { G } from "./galho.js";
import type { Dic, Key, bool, int, str } from "./util.js";
type CalcOptions = {
vars: Dic;
};
type Exp = {
calc(opts: CalcOptions): any;
};
export interface Tag<T = any> {
/**value */
v: T;
/**index */
i: number;
replace: bool;
}
export interface ListPlaceEvent<T> {
old: int;
new: int;
item: T;
}
export type UpdateEvent<T> = {
tp: "push";
items: T[];
start: int;
} | {
tp: "pop";
items: T[];
start: int;
} | {
tp: "place";
} | {
tp: "edit";
} | {
tp: "set";
items: T[];
removed: T[];
} | {
tp: "tag";
tag: str;
newI: number;
oldI: number;
} | {
tp: "reload";
start: int;
items: T[];
};
export interface EventMap<T> extends Dic<any[]> {
update: [UpdateEvent<T>];
push: [T[]];
edit: [EditEvent<T>[]];
pop: [T[]];
place: [ListPlaceEvent<T>];
}
export interface ListEditItem<T = Dic> {
item: Key | T;
props: Partial<T>;
}
export interface EditEvent<T = Dic> {
item: T;
props: Partial<T>;
}
type Parse<T, A> = (this: L<T, A>, value: T | A, index: number) => void | T;
export type IList<T, A = T> = {
key?: keyof T;
child?: str;
parse?: Parse<T, A>;
/**@deprecated */
converter?: Parse<T, A>;
g?: str[];
sorts?: Exp[];
clear?: bool;
} | Parse<T, A>;
/**
* An Array with suport for events, binds, subgroups and tags
* @template T type of element this array store
* @template A type of element this array accept
*/
export declare class L<T = any, A = T, K extends keyof T = any> extends Array<T> implements EventObject<EventMap<T>> {
put(start: number, ...values: Array<T | A>): this;
removeAt(start: number, length?: number): T[];
push(...values: Array<T | A>): number;
pop(): T;
shift(): T;
unshift(...values: Array<T | A>): number;
/**
* clear array and insert new elements
* @param values
*/
set(values?: Array<T | A>): this;
has(id: T[K], fromIndex?: number): boolean;
includes(searchElement: T[K], fromIndex?: number): boolean;
includes(searchElement: T, fromIndex?: number): boolean;
addGroup(key: str): Group<T, K>;
/**
* get a group from id if it not exist create new
*/
group(key: str): Group<T, K>;
on(callback: EventTargetCallback<L<T, A>, [UpdateEvent<T>]>): L<T, A>;
on<K extends keyof EventMap<T>>(event: K, callback: EventTargetCallback<this, EventMap<T>[K]>, options?: Options): this;
find<S extends T>(predicate: (value: T, index: number, obj: T[]) => value is S, thisArg?: any): S | undefined;
find(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): T | undefined;
find(key: T | T[K]): T | undefined;
findIndex(predicate: (value: T, index: number, obj: T[]) => unknown, thisArg?: any): number;
findIndex(key: T | K): number;
sort(compareFn?: (a: T, b: T) => number): this;
remove(...items: (K | T)[]): this;
place(item: K | T, newIndex: number): this;
/**get tag */
tag(key: str): T;
/**set tag */
tag(key: str, value: T | K, replace?: bool): this;
/**remove tag */
tag(key: str, value: null): this;
/**reload tag */
retag(k: str, o?: int): void;
ontag(key: str, callback: (this: L<T, A>, e: T | undefined) => any): this;
unbind(s: G): this;
bind<TS extends G = G>(s: TS, opts?: LBond<T, A, TS>): TS;
bind<TS extends G = G>(s: TS, opts?: LBondInsert<T, A, TS>): TS;
reload(item: T | K): this;
/** volta a chamar o bind do elemento */
reloadAt(index: int): this;
reloadAll(): this;
/**events handlers*/
eh: {
[P in keyof EventMap<T>]?: EventTargetCallback<this, EventMap<T>[P]>[];
};
/**when true this List do not raise events */
slip?: bool;
tags?: Dic<Tag<T>>;
sorts?: Exp[];
/**groups */
g: Dic<Group<T, K>>;
/**no update */
nu?: bool;
key?: K;
childKey?: str;
parse?: Parse<T, A>;
binds?: [s: G, fn: Function][];
}
export type Alias<T = any, A = T> = Array<T | A> | L<T, A>;
export declare function copy<S>(src: L<S, any>, dest: L<S, any>, fill?: bool): void;
export declare function copy<S, D, A = D>(src: L<S, any>, dest: L<D, A>, fill: bool, parse: (value: S, index: number) => D | A): void;
export declare function tryPush<T, A = T>(l: L<T, A>, item: T): void;
/**
* edit properties of an element of collection
* @param item
* @param prop
* @param value
*/
export declare function edit<T, A = T>(l: L<T, A>, item: ListEditItem<T>): L<T, A>;
export declare function editItems<T, A = T>(l: L<T, A>, ...items: T[]): L<T, A>;
export type LBondInsert<T, A = T, TS extends G = G> = (this: L<T, A>, value: T, index?: number, container?: TS) => any;
export interface LBond<T = any, A = T, TS extends G = G> {
/**
* metodo que sera chamado no clear, caso n�ot tenha removera um item de cada vez*/
clear?: false | ((container: G) => void);
/**inset an element in arbitrary position
se retornar um valor inserira este elemento n�o posi��o do item adicionado*/
insert?: LBondInsert<T, A, TS>;
reload?: (this: L<T, A>, value: T, index?: number, container?: TS) => any;
/**
* remove an arbitrary element
* se retornar true remove o item naquela posi��o
* se não definido remove o item automaticamente
* @param this
* @param pos
*/
remove?: (this: L<T, A>, item: T, index: number, container?: TS) => true | void;
/**
*
* @param this
* @param value
* @param props
* @param container
*/
edit?: (this: L<T, A>, item: T, index: number, props: Partial<T>, container: G) => G | void;
/**chamado quando tenta se reposicionar um elemento */
place?: (this: L<T, A>, oldPlace: number, newPlace: number, container: TS) => bool | void;
/**
*
* @param this
* @param empty
* @param container
*/
empty?: (this: L<T, A>, empty: bool, container?: TS) => any;
/**
* */
groups?: Dic<GroupBind<T, A, TS>> | GroupBind<T, A, TS>;
/** */
tag?: (this: L<T, A>, active: bool, index: number, parent: TS, tag: str, value: T) => void;
}
export declare function extend<T = any, A = T>(l?: Alias<T, A>, opts?: IList<T, A>): L<T, A, any>;
export declare function orray<T = any, A = T>(options: IList<T, A>): L<T, A>;
export declare function orray<T = any, A = T>(array?: L<T, A>, options?: Parse<T, A>): L<T, A>;
export declare function orray<T = any, A = T>(array?: Alias<T, A>, options?: IList<T, A>): L<T, A>;
export default orray;
interface GroupEvents<T = any> extends Dic<any[]> {
push: [T[]];
remove: [T[]];
set: GroupSetEvent<T>;
}
export type GroupSetEvent<T> = [add?: T[], addId?: int[], remove?: T[], removeId?: int[]];
export declare class Group<T, K extends keyof T> extends Array<T> implements EventObject<GroupEvents<T>> {
eh: {
[P in keyof GroupEvents<T>]?: EventTargetCallback<this, GroupEvents<T>[P]>[];
};
slip?: boolean;
/**no update */
nu?: boolean;
l: L<T, any>;
push(...items: (T | K)[]): number;
toggle(item: T): void;
pushRange(start: int, end: int): number[];
pushAll(): number[];
remove(...items: T[]): int[];
removeAt(index: number, count?: number): void;
clear(): number[];
removeRange(from: number, to?: number): number[];
set(add: (T | K)[]): this;
invert(): this;
setRange(start: number, end: number): void;
indexes(): number[];
keyField(): K[];
/**on update */
on(callback: EventTargetCallback<Group<T, K>, GroupSetEvent<T>>): this;
reload(v: T, i?: number): this;
static get [Symbol.species](): ArrayConstructor;
}
export type GroupBind<T, A = T, TS extends G = G> = (this: L<T, A>, state: boolean, index: number, parent: TS, groupKey: string, item: T) => void;
export declare function bind<T, A = T, TS extends G = G>(l: L<T, A>, s: TS, groupKey: string, bond: GroupBind<T, A, TS>): TS;
export declare namespace range {
type Tp = "set" | "add" | "range" | "addR";
function pivot<T, A = T>(l: L<T, A>, tag: str): number;
function add<T, A = T>(l: L<T, A>, key: str, value: T | int | str, tp: Tp): L<T, A, any>;
/**select all elements */
function addAll<T, A = T>(l: L<T, A>, tag: str): L<T, A, any>;
/** remove focus */
function clear<T, A = T>(l: L<T, A>, tag: str): L<T, A, any>;
function onchange<T, A = T, K extends keyof T = any>(l: L<T, A>, tag: str, listener?: (this: L<T, A>, active: T, selected?: Group<T, K>) => void): L<T, A, any>;
/**select type */
const tp: (control: boolean, shift: boolean) => Tp;
function move(l: L, tag: str, distance: number, tp: Tp): L<any, any, any>;
function movePivot(l: L, tag: str, distance: number, revert?: boolean): L<any, any, any>;
function list<T, A = T>(l: L<T, A>, key: str): T[];
}