v0.0.5
remove: $FormElementMethod
This commit is contained in:
parent
b51edda800
commit
1f052609a4
29
$index.ts
29
$index.ts
@ -116,19 +116,27 @@ export namespace $ {
|
|||||||
: H extends HTMLTextAreaElement ? $Textarea
|
: H extends HTMLTextAreaElement ? $Textarea
|
||||||
: $Container<H>;
|
: $Container<H>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper for fluent method design. Return the `instance` object when arguments length not equal 0. Otherwise, return the `value`.
|
||||||
|
* @param instance The object to return when arguments length not equal 0.
|
||||||
|
* @param args The method `arguments`.
|
||||||
|
* @param value The value to return when arguments length equal 0.
|
||||||
|
* @param action The action to execute when arguments length not equal 0.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function fluent<T, A, V>(instance: T, args: IArguments, value: () => V, action: (...args: any[]) => void) {
|
export function fluent<T, A, V>(instance: T, args: IArguments, value: () => V, action: (...args: any[]) => void) {
|
||||||
if (!args.length) return value();
|
if (!args.length) return value();
|
||||||
action();
|
action();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function multableResolve<T>(multable: OrArray<T>) {
|
export function orArrayResolve<T>(multable: OrArray<T>) {
|
||||||
if (multable instanceof Array) return multable;
|
if (multable instanceof Array) return multable;
|
||||||
else return [multable];
|
else return [multable];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mixin(target: any, constructors: OrArray<any>) {
|
export function mixin(target: any, constructors: OrArray<any>) {
|
||||||
multableResolve(constructors).forEach(constructor => {
|
orArrayResolve(constructors).forEach(constructor => {
|
||||||
Object.getOwnPropertyNames(constructor.prototype).forEach(name => {
|
Object.getOwnPropertyNames(constructor.prototype).forEach(name => {
|
||||||
if (name === 'constructor') return;
|
if (name === 'constructor') return;
|
||||||
Object.defineProperty(
|
Object.defineProperty(
|
||||||
@ -140,15 +148,24 @@ export namespace $ {
|
|||||||
})
|
})
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
export function set<O, K extends keyof O>(object: O, key: K, value: any, methodKey?: string) {
|
* A helper for $State.set() which apply value to target.
|
||||||
|
* @param object Target object.
|
||||||
|
* @param key The key of target object.
|
||||||
|
* @param value Value of target property or parameter of method(Using Tuple to apply parameter).
|
||||||
|
* @param methodKey Variant key name when apply value on $State.set()
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function set<O, K extends keyof O>(object: O, key: K, value: O[K] extends (...args: any) => any ? (Parameters<O[K]> | $State<Parameters<O[K]>>) : O[K] | undefined | $State<O[K]>, methodKey?: string) {
|
||||||
if (value === undefined) return;
|
if (value === undefined) return;
|
||||||
if (value instanceof $State && object instanceof Node) {
|
if (value instanceof $State && object instanceof Node) {
|
||||||
value.use(object.$, methodKey ?? key as any);
|
value.use(object.$, methodKey ?? key as any);
|
||||||
object[key] = value.value;
|
const prop = object[key];
|
||||||
|
if (prop instanceof Function) prop(value.value);
|
||||||
|
else object[key] = value.value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
object[key] = value;
|
object[key] = value as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function state<T>(value: T) {
|
export function state<T>(value: T) {
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import { $Container, $ContainerOptions } from "./$Container";
|
import { $Container, $ContainerOptions } from "./$Container";
|
||||||
import { FormElementMethod, $FormElementMethod } from "./$Form";
|
|
||||||
import { $State } from "./$State";
|
import { $State } from "./$State";
|
||||||
export interface $ButtonOptions extends $ContainerOptions {}
|
export interface $ButtonOptions extends $ContainerOptions {}
|
||||||
//@ts-expect-error
|
|
||||||
export interface $Button extends $FormElementMethod {}
|
|
||||||
@FormElementMethod
|
|
||||||
export class $Button extends $Container<HTMLButtonElement> {
|
export class $Button extends $Container<HTMLButtonElement> {
|
||||||
constructor(options?: $ButtonOptions) {
|
constructor(options?: $ButtonOptions) {
|
||||||
super('button', options);
|
super('button', options);
|
||||||
@ -16,8 +12,28 @@ export class $Button extends $Container<HTMLButtonElement> {
|
|||||||
|
|
||||||
type(): ButtonType;
|
type(): ButtonType;
|
||||||
type(type: ButtonType): this;
|
type(type: ButtonType): this;
|
||||||
type(type?: ButtonType) { return $.fluent(this, arguments, () => this.dom.type as ButtonType, () => $.set(this.dom, 'type', type))}
|
type(type?: ButtonType) { return $.fluent(this, arguments, () => this.dom.type as ButtonType, () => $.set(this.dom, 'type', type as any))}
|
||||||
|
|
||||||
checkValidity() { return this.dom.checkValidity() }
|
checkValidity() { return this.dom.checkValidity() }
|
||||||
reportValidity() { return this.dom.reportValidity() }
|
reportValidity() { return this.dom.reportValidity() }
|
||||||
|
|
||||||
|
formAction(): string;
|
||||||
|
formAction(action: string | undefined): this;
|
||||||
|
formAction(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))}
|
||||||
|
|
||||||
|
formEnctype(): string;
|
||||||
|
formEnctype(enctype: string | undefined): this;
|
||||||
|
formEnctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))}
|
||||||
|
|
||||||
|
formMethod(): string;
|
||||||
|
formMethod(method: string | undefined): this;
|
||||||
|
formMethod(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))}
|
||||||
|
|
||||||
|
formNoValidate(): boolean;
|
||||||
|
formNoValidate(boolean: boolean | undefined): this;
|
||||||
|
formNoValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))}
|
||||||
|
|
||||||
|
formTarget(): string;
|
||||||
|
formTarget(target: string | undefined): this;
|
||||||
|
formTarget(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))}
|
||||||
}
|
}
|
@ -23,7 +23,7 @@ export class $Container<H extends HTMLElement = HTMLElement> extends $Element<H>
|
|||||||
/**Insert element to this element */
|
/**Insert element to this element */
|
||||||
insert(children: $ContainerContentBuilder<this>): this { return $.fluent(this, arguments, () => this, () => {
|
insert(children: $ContainerContentBuilder<this>): this { return $.fluent(this, arguments, () => this, () => {
|
||||||
if (children instanceof Function) children = children(this);
|
if (children instanceof Function) children = children(this);
|
||||||
children = $.multableResolve(children);
|
children = $.orArrayResolve(children);
|
||||||
for (const child of children) {
|
for (const child of children) {
|
||||||
if (child === undefined) continue;
|
if (child === undefined) continue;
|
||||||
if (child instanceof Array) this.insert(child)
|
if (child instanceof Array) this.insert(child)
|
||||||
|
43
lib/$Form.ts
43
lib/$Form.ts
@ -7,9 +7,9 @@ export class $Form extends $Container<HTMLFormElement> {
|
|||||||
super('form', options);
|
super('form', options);
|
||||||
}
|
}
|
||||||
|
|
||||||
autocomplete(): AutoFillBase;
|
autocomplete(): AutoFill;
|
||||||
autocomplete(autocomplete: AutoFill | undefined): this;
|
autocomplete(autocomplete: AutoFill | undefined): this;
|
||||||
autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete, () => $.set(this.dom, 'autocomplete', autocomplete))}
|
autocomplete(autocomplete?: AutoFill) { return $.fluent(this, arguments, () => this.dom.autocomplete as AutoFill, () => $.set(this.dom, 'autocomplete', autocomplete as AutoFillBase))}
|
||||||
|
|
||||||
action(): string;
|
action(): string;
|
||||||
action(action: string | undefined): this;
|
action(action: string | undefined): this;
|
||||||
@ -43,43 +43,4 @@ export class $Form extends $Container<HTMLFormElement> {
|
|||||||
|
|
||||||
get length() { return this.dom.length }
|
get length() { return this.dom.length }
|
||||||
get elements() { return Array.from(this.dom.elements).map(ele => $(ele)) }
|
get elements() { return Array.from(this.dom.elements).map(ele => $(ele)) }
|
||||||
}
|
|
||||||
|
|
||||||
export function FormElementMethod(target: any) { return $Util.mixin(target, $FormElementMethod) }
|
|
||||||
export abstract class $FormElementMethod {
|
|
||||||
abstract dom: HTMLButtonElement | HTMLInputElement;
|
|
||||||
|
|
||||||
formAction(): string;
|
|
||||||
formAction(action: string | undefined): this;
|
|
||||||
formAction(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))}
|
|
||||||
|
|
||||||
formEnctype(): string;
|
|
||||||
formEnctype(enctype: string | undefined): this;
|
|
||||||
formEnctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))}
|
|
||||||
|
|
||||||
formMethod(): string;
|
|
||||||
formMethod(method: string | undefined): this;
|
|
||||||
formMethod(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))}
|
|
||||||
|
|
||||||
formNoValidate(): boolean;
|
|
||||||
formNoValidate(boolean: boolean | undefined): this;
|
|
||||||
formNoValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))}
|
|
||||||
|
|
||||||
formTarget(): string;
|
|
||||||
formTarget(target: string | undefined): this;
|
|
||||||
formTarget(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))}
|
|
||||||
|
|
||||||
name(): string;
|
|
||||||
name(name?: string | $State<string>): this;
|
|
||||||
name(name?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))}
|
|
||||||
|
|
||||||
value(): string;
|
|
||||||
value(value?: string | $State<string>): this;
|
|
||||||
value(value?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))}
|
|
||||||
|
|
||||||
get form() { return this.dom.form ? $(this.dom.form) : null }
|
|
||||||
get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) }
|
|
||||||
get validationMessage() { return this.dom.validationMessage }
|
|
||||||
get validity() { return this.dom.validity }
|
|
||||||
get willValidate() { return this.dom.willValidate }
|
|
||||||
}
|
}
|
@ -1,10 +1,7 @@
|
|||||||
import { $Element, $ElementOptions } from "./$Element";
|
import { $Element, $ElementOptions } from "./$Element";
|
||||||
import { $FormElementMethod, FormElementMethod } from "./$Form";
|
import { $State } from "./$State";
|
||||||
|
|
||||||
export interface $InputOptions extends $ElementOptions {}
|
export interface $InputOptions extends $ElementOptions {}
|
||||||
//@ts-expect-error
|
|
||||||
export interface $Input extends $FormElementMethod {}
|
|
||||||
@FormElementMethod
|
|
||||||
export class $Input extends $Element<HTMLInputElement> {
|
export class $Input extends $Element<HTMLInputElement> {
|
||||||
constructor(options?: $InputOptions) {
|
constructor(options?: $InputOptions) {
|
||||||
super('input', options);
|
super('input', options);
|
||||||
@ -152,4 +149,39 @@ export class $Input extends $Element<HTMLInputElement> {
|
|||||||
reportValidity() { return this.dom.reportValidity() }
|
reportValidity() { return this.dom.reportValidity() }
|
||||||
get files() { return this.dom.files }
|
get files() { return this.dom.files }
|
||||||
get webkitEntries() { return this.dom.webkitEntries }
|
get webkitEntries() { return this.dom.webkitEntries }
|
||||||
|
|
||||||
|
|
||||||
|
formAction(): string;
|
||||||
|
formAction(action: string | undefined): this;
|
||||||
|
formAction(action?: string) { return $.fluent(this, arguments, () => this.dom.formAction, () => $.set(this.dom, 'formAction', action))}
|
||||||
|
|
||||||
|
formEnctype(): string;
|
||||||
|
formEnctype(enctype: string | undefined): this;
|
||||||
|
formEnctype(enctype?: string) { return $.fluent(this, arguments, () => this.dom.formEnctype, () => $.set(this.dom, 'formEnctype', enctype))}
|
||||||
|
|
||||||
|
formMethod(): string;
|
||||||
|
formMethod(method: string | undefined): this;
|
||||||
|
formMethod(method?: string) { return $.fluent(this, arguments, () => this.dom.formMethod, () => $.set(this.dom, 'formMethod', method))}
|
||||||
|
|
||||||
|
formNoValidate(): boolean;
|
||||||
|
formNoValidate(boolean: boolean | undefined): this;
|
||||||
|
formNoValidate(boolean?: boolean) { return $.fluent(this, arguments, () => this.dom.formNoValidate, () => $.set(this.dom, 'formNoValidate', boolean))}
|
||||||
|
|
||||||
|
formTarget(): string;
|
||||||
|
formTarget(target: string | undefined): this;
|
||||||
|
formTarget(target?: string) { return $.fluent(this, arguments, () => this.dom.formTarget, () => $.set(this.dom, 'formTarget', target))}
|
||||||
|
|
||||||
|
name(): string;
|
||||||
|
name(name?: string | $State<string>): this;
|
||||||
|
name(name?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))}
|
||||||
|
|
||||||
|
value(): string;
|
||||||
|
value(value?: string | $State<string>): this;
|
||||||
|
value(value?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))}
|
||||||
|
|
||||||
|
get form() { return this.dom.form ? $(this.dom.form) : null }
|
||||||
|
get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) }
|
||||||
|
get validationMessage() { return this.dom.validationMessage }
|
||||||
|
get validity() { return this.dom.validity }
|
||||||
|
get willValidate() { return this.dom.willValidate }
|
||||||
}
|
}
|
@ -1,13 +1,9 @@
|
|||||||
import { $Container, $ContainerOptions } from "./$Container";
|
import { $Container, $ContainerOptions } from "./$Container";
|
||||||
import { $FormElementMethod, FormElementMethod } from "./$Form";
|
|
||||||
import { $OptGroup } from "./$OptGroup";
|
import { $OptGroup } from "./$OptGroup";
|
||||||
import { $Option } from "./$Option";
|
import { $Option } from "./$Option";
|
||||||
import { $State } from "./$State";
|
import { $State } from "./$State";
|
||||||
|
|
||||||
export interface $SelectOptions extends $ContainerOptions {}
|
export interface $SelectOptions extends $ContainerOptions {}
|
||||||
//@ts-expect-error
|
|
||||||
export interface $Select extends $FormElementMethod {}
|
|
||||||
@FormElementMethod
|
|
||||||
export class $Select extends $Container<HTMLSelectElement> {
|
export class $Select extends $Container<HTMLSelectElement> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('select')
|
super('select')
|
||||||
@ -42,6 +38,20 @@ export class $Select extends $Container<HTMLSelectElement> {
|
|||||||
get options() { return Array.from(this.dom.options).map($option => $($option)) }
|
get options() { return Array.from(this.dom.options).map($option => $($option)) }
|
||||||
get selectedIndex() { return this.dom.selectedIndex }
|
get selectedIndex() { return this.dom.selectedIndex }
|
||||||
get selectedOptions() { return Array.from(this.dom.selectedOptions).map($option => $($option)) }
|
get selectedOptions() { return Array.from(this.dom.selectedOptions).map($option => $($option)) }
|
||||||
|
|
||||||
|
name(): string;
|
||||||
|
name(name?: string | $State<string>): this;
|
||||||
|
name(name?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.name, () => $.set(this.dom, 'name', name))}
|
||||||
|
|
||||||
|
value(): string;
|
||||||
|
value(value?: string | $State<string>): this;
|
||||||
|
value(value?: string | $State<string>) { return $.fluent(this, arguments, () => this.dom.value, () => $.set(this.dom, 'value', value))}
|
||||||
|
|
||||||
|
get form() { return this.dom.form ? $(this.dom.form) : null }
|
||||||
|
get labels() { return Array.from(this.dom.labels ?? []).map(label => $(label)) }
|
||||||
|
get validationMessage() { return this.dom.validationMessage }
|
||||||
|
get validity() { return this.dom.validity }
|
||||||
|
get willValidate() { return this.dom.willValidate }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type $SelectContentType = $Option | $OptGroup | undefined;
|
export type $SelectContentType = $Option | $OptGroup | undefined;
|
@ -17,7 +17,7 @@ export class Router {
|
|||||||
|
|
||||||
/**Add route to Router. @example Router.addRoute(new Route('/', 'Hello World')) */
|
/**Add route to Router. @example Router.addRoute(new Route('/', 'Hello World')) */
|
||||||
addRoute(routes: OrArray<Route<any>>) {
|
addRoute(routes: OrArray<Route<any>>) {
|
||||||
routes = $.multableResolve(routes);
|
routes = $.orArrayResolve(routes);
|
||||||
for (const route of routes) this.routeMap.set(route.path, route);
|
for (const route of routes) this.routeMap.set(route.path, route);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "fluentx",
|
"name": "fluentx",
|
||||||
"description": "Fast, fluent, simple web builder",
|
"description": "Fast, fluent, simple web builder",
|
||||||
"version": "0.0.4",
|
"version": "0.0.5",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"author": {
|
"author": {
|
||||||
|
Loading…
Reference in New Issue
Block a user