Skip to content

Commit

Permalink
feat: update InputCore component
Browse files Browse the repository at this point in the history
  • Loading branch information
ltaoo committed Jan 10, 2025
1 parent f1b4cbf commit ac2f4e2
Show file tree
Hide file tree
Showing 4 changed files with 255 additions and 13 deletions.
118 changes: 118 additions & 0 deletions src/biz/user_settings/index.ts
Original file line number Diff line number Diff line change
@@ -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<TheTypesOfEvents>();

$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<typeof UserSettingsCore>;
4 changes: 4 additions & 0 deletions src/domains/ui/form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<F extends Record<string, FormFieldCore<any>>> = {
fields: F;
Expand Down Expand Up @@ -115,6 +116,9 @@ export function FormCore<
submit() {
bus.emit(Events.Submit, _state.value);
},
validate() {
return Result.Ok(_values);
},
onSubmit(handler: Handler<TheTypesOfEvents<Value<F>>[Events.Submit]>) {
bus.on(Events.Submit, handler);
},
Expand Down
78 changes: 65 additions & 13 deletions src/domains/ui/form/input/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ enum Events {
Focus,
Blur,
Enter,
Clear,
}
type TheTypesOfEvents<T> = {
[Events.StateChange]: InputState<T>;
[Events.Mounted]: void;
[Events.Change]: T;
[Events.Blur]: T;
[Events.Enter]: T;
[Events.Focus]: void;
[Events.Clear]: void;
[Events.StateChange]: InputState<T>;
};

type InputProps<T> = {
Expand All @@ -25,28 +27,40 @@ type InputProps<T> = {
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<T> = {
value: T;
placeholder: string;
disabled: boolean;
loading: boolean;
type: string;
tmpType: string;
allowClear: boolean;
autoFocus: boolean;
autoComplete: boolean;
};

export class InputCore<T> extends BaseDomain<TheTypesOfEvents<T>> implements ValueInputInterface<T> {
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 {
Expand All @@ -55,36 +69,57 @@ export class InputCore<T> extends BaseDomain<TheTypesOfEvents<T>> 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<T>) {
super(options);
constructor(props: { unique_id?: string } & InputProps<T>) {
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);
Expand All @@ -108,7 +143,7 @@ export class InputCore<T> extends BaseDomain<TheTypesOfEvents<T>> 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);
Expand Down Expand Up @@ -144,14 +179,28 @@ export class InputCore<T> extends BaseDomain<TheTypesOfEvents<T>> 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<TheTypesOfEvents<T>[Events.Change]>) {
return this.on(Events.Change, handler);
Expand All @@ -171,6 +220,9 @@ export class InputCore<T> extends BaseDomain<TheTypesOfEvents<T>> implements Val
onEnter(handler: Handler<TheTypesOfEvents<T>[Events.Enter]>) {
return this.on(Events.Enter, handler);
}
onClear(handler: Handler<TheTypesOfEvents<T>[Events.Clear]>) {
return this.on(Events.Clear, handler);
}
}

type InputInListProps<T = unknown> = {
Expand All @@ -188,7 +240,7 @@ export class InputInListCore<K extends string, T> extends BaseDomain<TheTypesInL
cached: Record<K, InputCore<T>> = {} as Record<K, InputCore<T>>;
values: Map<K, T | null> = new Map();

constructor(props: Partial<{ _name: string }> & InputInListProps<T>) {
constructor(props: Partial<{ unique_id: string }> & InputInListProps<T>) {
super(props);

const { defaultValue } = props;
Expand Down
68 changes: 68 additions & 0 deletions src/domains/ui/switch/index.ts
Original file line number Diff line number Diff line change
@@ -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<TheTypesOfEvents>();
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<TheTypesOfEvents[Events.Open]>) {
return bus.on(Events.Open, handler);
},
onClose(handler: Handler<TheTypesOfEvents[Events.Close]>) {
return bus.on(Events.Close, handler);
},
onChange(handler: Handler<TheTypesOfEvents[Events.Change]>) {
return bus.on(Events.Change, handler);
},
onStateChange(handler: Handler<TheTypesOfEvents[Events.StateChange]>) {
return bus.on(Events.StateChange, handler);
},
};
}

export type SwitchCore = ReturnType<typeof SwitchCore>;

0 comments on commit ac2f4e2

Please sign in to comment.