From ac2f4e223d544c913cd8a61abc9212acf78389a8 Mon Sep 17 00:00:00 2001 From: ltaoo Date: Fri, 10 Jan 2025 14:26:20 +0800 Subject: [PATCH] feat: update InputCore component --- src/biz/user_settings/index.ts | 118 +++++++++++++++++++++++++++++ src/domains/ui/form/index.ts | 4 + src/domains/ui/form/input/index.ts | 78 +++++++++++++++---- src/domains/ui/switch/index.ts | 68 +++++++++++++++++ 4 files changed, 255 insertions(+), 13 deletions(-) create mode 100644 src/biz/user_settings/index.ts create mode 100644 src/domains/ui/switch/index.ts diff --git a/src/biz/user_settings/index.ts b/src/biz/user_settings/index.ts new file mode 100644 index 0000000..bac7517 --- /dev/null +++ b/src/biz/user_settings/index.ts @@ -0,0 +1,118 @@ +import { base } from "@/domains/base"; +import { ButtonCore, FormCore, InputCore } from "@/domains/ui"; +import { FormFieldCore } from "@/domains/ui/form/field"; +import { ListContainerCore } from "@/domains/ui/form/list"; + +type UserSettingsCoreProps = {}; +export function UserSettingsCore(props: UserSettingsCoreProps) { + const $tmdb_form = FormCore({ + fields: { + hostname: new FormFieldCore({ + label: "域名", + name: "hostname", + input: new InputCore({ defaultValue: "" }), + }), + token: new FormFieldCore({ + label: "token", + name: "token", + input: new InputCore({ defaultValue: "" }), + }), + }, + }); + const $tmdb_form_btn = new ButtonCore({}); + const $message_push_form = FormCore({ + fields: { + push_deer_token: new FormFieldCore({ + label: "PushDeer Token", + name: "push_deer_token", + input: new InputCore({ defaultValue: "" }), + }), + telegram_bot_token: new FormFieldCore({ + label: "Telegram 机器人 token", + name: "telegram_bot_token", + input: new InputCore({ defaultValue: "" }), + }), + wx_push_token: new FormFieldCore({ + label: "WxPush token", + name: "wx_push_token", + input: new InputCore({ defaultValue: "" }), + }), + message: new FormFieldCore({ + label: "测试消息", + name: "message", + input: new InputCore({ defaultValue: "测试消息推送" }), + }), + }, + }); + const $message_push_btn = new ButtonCore({}); + const $filename_parse_rules = FormCore({ + fields: { + rules: new FormFieldCore({ + label: "文件名解析规则", + name: "rules", + input: ListContainerCore({ + defaultValue: [{ text: "", replace: "" }], + factory() { + return FormCore({ + fields: { + text: new FormFieldCore({ + label: "匹配内容", + name: "text", + input: new InputCore({ defaultValue: "" }), + }), + replace: new FormFieldCore({ + label: "替换为", + name: "replace", + input: new InputCore({ defaultValue: "" }), + }), + }, + }); + }, + }), + }), + }, + }); + + const _state = {}; + + enum Events { + Change, + StateChange, + } + type TheTypesOfEvents = { + [Events.Change]: {}; + [Events.StateChange]: typeof _state; + }; + const bus = base(); + + $tmdb_form_btn.onClick(async () => { + const r = await $tmdb_form.validate(); + if (r.error) { + bus.tip({ + text: ["校验失败", r.error.message], + }); + return; + } + const values = r.data; + console.log(values); + }); + $message_push_btn.onClick(async () => { + const r = await $message_push_form.validate(); + if (r.error) { + bus.tip({ + text: ["校验失败", r.error.message], + }); + return; + } + const values = r.data; + console.log(values); + }); + + return { + ui: { + $message_push_form, + }, + }; +} + +export type UserSettingsCore = ReturnType; diff --git a/src/domains/ui/form/index.ts b/src/domains/ui/form/index.ts index 6c29f1c..706ca91 100644 --- a/src/domains/ui/form/index.ts +++ b/src/domains/ui/form/index.ts @@ -5,6 +5,7 @@ import { base, Handler } from "@/domains/base"; import { FormFieldCore } from "./field"; import { ValueInputInterface } from "./types"; +import { Result } from "@/domains/result"; type FormProps>> = { fields: F; @@ -115,6 +116,9 @@ export function FormCore< submit() { bus.emit(Events.Submit, _state.value); }, + validate() { + return Result.Ok(_values); + }, onSubmit(handler: Handler>[Events.Submit]>) { bus.on(Events.Submit, handler); }, diff --git a/src/domains/ui/form/input/index.ts b/src/domains/ui/form/input/index.ts index 171db95..4d90ccd 100644 --- a/src/domains/ui/form/input/index.ts +++ b/src/domains/ui/form/input/index.ts @@ -8,14 +8,16 @@ enum Events { Focus, Blur, Enter, + Clear, } type TheTypesOfEvents = { - [Events.StateChange]: InputState; [Events.Mounted]: void; [Events.Change]: T; [Events.Blur]: T; [Events.Enter]: T; [Events.Focus]: void; + [Events.Clear]: void; + [Events.StateChange]: InputState; }; type InputProps = { @@ -25,9 +27,13 @@ type InputProps = { defaultValue: T; placeholder?: string; type?: string; + autoFocus?: boolean; + autoComplete?: boolean; onChange?: (v: T) => void; onEnter?: (v: T) => void; onBlur?: (v: T) => void; + onClear?: () => void; + onMounted?: () => void; }; type InputState = { value: T; @@ -35,18 +41,26 @@ type InputState = { disabled: boolean; loading: boolean; type: string; + tmpType: string; + allowClear: boolean; + autoFocus: boolean; + autoComplete: boolean; }; export class InputCore extends BaseDomain> implements ValueInputInterface { shape = "input" as const; - defaultValue: T; + _defaultValue: T; value: T; placeholder: string; disabled: boolean; + allowClear: boolean = true; + autoComplete: boolean = false; + autoFocus: boolean = false; type: string; loading = false; /** 被消费过的值,用于做比较判断 input 值是否发生改变 */ - valueUsed: T; + valueUsed: unknown; + tmpType = ""; get state() { return { @@ -55,36 +69,57 @@ export class InputCore extends BaseDomain> implements Val disabled: this.disabled, loading: this.loading, type: this.type, + tmpType: this.tmpType, + autoComplete: this.autoComplete, + autoFocus: this.autoFocus, + allowClear: this.allowClear, }; } - constructor(options: Partial<{ _name: string }> & InputProps) { - super(options); + constructor(props: { unique_id?: string } & InputProps) { + super(props); const { + unique_id, defaultValue, placeholder = "请输入", type = "string", disabled = false, + autoFocus = false, + autoComplete = false, onChange, onBlur, onEnter, - } = options; + onClear, + onMounted, + } = props; + if (unique_id) { + this.unique_id = unique_id; + } this.placeholder = placeholder; this.type = type; this.disabled = disabled; - this.defaultValue = defaultValue; + this.autoComplete = autoComplete; + this.autoFocus = autoFocus; + this._defaultValue = defaultValue; this.value = defaultValue; - this.valueUsed = defaultValue; if (onChange) { this.onChange(onChange); } if (onEnter) { - this.onEnter(onEnter); + this.onEnter(() => { + onEnter(this.value); + }); } if (onBlur) { this.onBlur(onBlur); } + if (onClear) { + this.onClear(onClear); + } + if (onMounted) { + this.onMounted(onMounted); + } } setMounted() { this.emit(Events.Mounted); @@ -108,7 +143,7 @@ export class InputCore extends BaseDomain> implements Val this.emit(Events.StateChange, { ...this.state }); } focus() { - console.log("请在 connect 中实现该方法"); + console.log("请在 connect 中实现 focus 方法"); } handleChange(event: unknown) { // console.log("[DOMAIN]ui/input - handleChange", event); @@ -144,14 +179,28 @@ export class InputCore extends BaseDomain> implements Val this.disabled = false; this.emit(Events.StateChange, { ...this.state }); } + showText() { + this.tmpType = "text"; + this.emit(Events.StateChange, { ...this.state }); + } + hideText() { + this.tmpType = ""; + this.emit(Events.StateChange, { ...this.state }); + } clear() { - this.value = this.defaultValue; + console.log("[COMPONENT]ui/input/index - clear", this._defaultValue); + this.value = this._defaultValue; + // this.emit(Events.Change, this.value); + this.emit(Events.Clear); this.emit(Events.StateChange, { ...this.state }); } reset() { - this.value = this.defaultValue; + this.value = this._defaultValue; this.emit(Events.StateChange, { ...this.state }); } + enter() { + this.emit(Events.Enter); + } onChange(handler: Handler[Events.Change]>) { return this.on(Events.Change, handler); @@ -171,6 +220,9 @@ export class InputCore extends BaseDomain> implements Val onEnter(handler: Handler[Events.Enter]>) { return this.on(Events.Enter, handler); } + onClear(handler: Handler[Events.Clear]>) { + return this.on(Events.Clear, handler); + } } type InputInListProps = { @@ -188,7 +240,7 @@ export class InputInListCore extends BaseDomain> = {} as Record>; values: Map = new Map(); - constructor(props: Partial<{ _name: string }> & InputInListProps) { + constructor(props: Partial<{ unique_id: string }> & InputInListProps) { super(props); const { defaultValue } = props; diff --git a/src/domains/ui/switch/index.ts b/src/domains/ui/switch/index.ts new file mode 100644 index 0000000..f51bc60 --- /dev/null +++ b/src/domains/ui/switch/index.ts @@ -0,0 +1,68 @@ +import { base, Handler } from "@/domains/base"; + +type SwitchCoreProps = { + defaultValue: boolean; + disabled?: boolean; +}; +export function SwitchCore(props: SwitchCoreProps) { + const { defaultValue, disabled } = props; + + let _value = defaultValue; + let _disabled = disabled; + + const _state = { + get value() { + return _value; + }, + get disabled() { + return _disabled; + }, + }; + enum Events { + Open, + Close, + Change, + StateChange, + } + type TheTypesOfEvents = { + [Events.Open]: void; + [Events.Close]: void; + [Events.Change]: typeof _value; + [Events.StateChange]: typeof _state; + }; + const bus = base(); + return { + shape: "switch" as const, + state: _state, + setValue(v: boolean) { + _value = v; + bus.emit(Events.Change, _value); + bus.emit(Events.StateChange, { ..._state }); + }, + disable() { + _disabled = true; + bus.emit(Events.StateChange, { ..._state }); + }, + enable() { + _disabled = false; + bus.emit(Events.StateChange, { ..._state }); + }, + handleChange(v: boolean) { + this.setValue(v); + }, + onOpen(handler: Handler) { + return bus.on(Events.Open, handler); + }, + onClose(handler: Handler) { + return bus.on(Events.Close, handler); + }, + onChange(handler: Handler) { + return bus.on(Events.Change, handler); + }, + onStateChange(handler: Handler) { + return bus.on(Events.StateChange, handler); + }, + }; +} + +export type SwitchCore = ReturnType;