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
|
||||
: $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) {
|
||||
if (!args.length) return value();
|
||||
action();
|
||||
return instance;
|
||||
}
|
||||
|
||||
export function multableResolve<T>(multable: OrArray<T>) {
|
||||
export function orArrayResolve<T>(multable: OrArray<T>) {
|
||||
if (multable instanceof Array) return multable;
|
||||
else return [multable];
|
||||
}
|
||||
|
||||
export function mixin(target: any, constructors: OrArray<any>) {
|
||||
multableResolve(constructors).forEach(constructor => {
|
||||
orArrayResolve(constructors).forEach(constructor => {
|
||||
Object.getOwnPropertyNames(constructor.prototype).forEach(name => {
|
||||
if (name === 'constructor') return;
|
||||
Object.defineProperty(
|
||||
@ -140,15 +148,24 @@ export namespace $ {
|
||||
})
|
||||
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 instanceof $State && object instanceof Node) {
|
||||
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;
|
||||
}
|
||||
object[key] = value;
|
||||
object[key] = value as any;
|
||||
}
|
||||
|
||||
export function state<T>(value: T) {
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { $Container, $ContainerOptions } from "./$Container";
|
||||
import { FormElementMethod, $FormElementMethod } from "./$Form";
|
||||
import { $State } from "./$State";
|
||||
export interface $ButtonOptions extends $ContainerOptions {}
|
||||
//@ts-expect-error
|
||||
export interface $Button extends $FormElementMethod {}
|
||||
@FormElementMethod
|
||||
export class $Button extends $Container<HTMLButtonElement> {
|
||||
constructor(options?: $ButtonOptions) {
|
||||
super('button', options);
|
||||
@ -16,8 +12,28 @@ export class $Button extends $Container<HTMLButtonElement> {
|
||||
|
||||
type(): ButtonType;
|
||||
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() }
|
||||
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(children: $ContainerContentBuilder<this>): this { return $.fluent(this, arguments, () => this, () => {
|
||||
if (children instanceof Function) children = children(this);
|
||||
children = $.multableResolve(children);
|
||||
children = $.orArrayResolve(children);
|
||||
for (const child of children) {
|
||||
if (child === undefined) continue;
|
||||
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);
|
||||
}
|
||||
|
||||
autocomplete(): AutoFillBase;
|
||||
autocomplete(): AutoFill;
|
||||
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(action: string | undefined): this;
|
||||
@ -44,42 +44,3 @@ export class $Form extends $Container<HTMLFormElement> {
|
||||
get length() { return this.dom.length }
|
||||
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 { $FormElementMethod, FormElementMethod } from "./$Form";
|
||||
import { $State } from "./$State";
|
||||
|
||||
export interface $InputOptions extends $ElementOptions {}
|
||||
//@ts-expect-error
|
||||
export interface $Input extends $FormElementMethod {}
|
||||
@FormElementMethod
|
||||
export class $Input extends $Element<HTMLInputElement> {
|
||||
constructor(options?: $InputOptions) {
|
||||
super('input', options);
|
||||
@ -152,4 +149,39 @@ export class $Input extends $Element<HTMLInputElement> {
|
||||
reportValidity() { return this.dom.reportValidity() }
|
||||
get files() { return this.dom.files }
|
||||
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 { $FormElementMethod, FormElementMethod } from "./$Form";
|
||||
import { $OptGroup } from "./$OptGroup";
|
||||
import { $Option } from "./$Option";
|
||||
import { $State } from "./$State";
|
||||
|
||||
export interface $SelectOptions extends $ContainerOptions {}
|
||||
//@ts-expect-error
|
||||
export interface $Select extends $FormElementMethod {}
|
||||
@FormElementMethod
|
||||
export class $Select extends $Container<HTMLSelectElement> {
|
||||
constructor() {
|
||||
super('select')
|
||||
@ -42,6 +38,20 @@ export class $Select extends $Container<HTMLSelectElement> {
|
||||
get options() { return Array.from(this.dom.options).map($option => $($option)) }
|
||||
get selectedIndex() { return this.dom.selectedIndex }
|
||||
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;
|
@ -17,7 +17,7 @@ export class Router {
|
||||
|
||||
/**Add route to Router. @example Router.addRoute(new Route('/', 'Hello World')) */
|
||||
addRoute(routes: OrArray<Route<any>>) {
|
||||
routes = $.multableResolve(routes);
|
||||
routes = $.orArrayResolve(routes);
|
||||
for (const route of routes) this.routeMap.set(route.path, route);
|
||||
return this;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "fluentx",
|
||||
"description": "Fast, fluent, simple web builder",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.5",
|
||||
"type": "module",
|
||||
"module": "index.ts",
|
||||
"author": {
|
||||
|
Loading…
Reference in New Issue
Block a user