Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfisher committed Aug 20, 2024
1 parent 53adc3a commit 17a87ce
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 25 deletions.
2 changes: 1 addition & 1 deletion example/src/forms/network/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const Network = createForm({
})
},
cancelableSubmit: { // 这是一个动作,
title: "可取消的提交",
title: "可取消的提交",
execute:action(async (fields,{abortSignal})=>{
console.log("formData=",fields)
return new Promise<void>((resolve,reject)=>{
Expand Down
6 changes: 3 additions & 3 deletions example/src/forms/network/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ const NetworkForm = ()=>{
return <Network.Form className="panel">
<div data-loader="circle"></div>
<Card title="网络配置">
<Network.Field<string> name="title">
<Network.Field2 name="title">
{({name,title,value,visible,validate,placeholder,sync})=>{
return <Field name="title" visible={visible} label={title}>
<Input name={name} className={classnames({invalid:validate===false})} placeholder={placeholder} value={value} onChange={sync()}/>
</Field>
} }
</Network.Field>
</Network.Field2>

<Network.Field2 name="wifi.password">
<Network.Field2 name="wifi.cancelableSubmit">
{({title,value,required,visible,validate,enable,placeholder,sync})=>{
console.log(required,visible,validate,enable)
return <Field visible={visible} label={title}>
Expand Down
49 changes: 28 additions & 21 deletions packages/core/src/field2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,37 +78,44 @@ function createFieldProps(name:string,value:any,syncer:any,filedUpdater:any){
},[])
}

// 提取表单中的的有效字段,如fields.xxx.value => fields.xxx,用在Field.props.name是指定字段
type FormFinalState<State extends Dict> = {
[K in keyof State]: State[K] extends FormFieldBase<infer V> ? V :
( State[K] extends { execute:any } ? never
: (
State[K] extends Dict ? FormFinalState<State[K]>: never
)
)
}

/**
*
* 实现一个字段组件根据name属性自动推断children的类型
*
* 比较复杂,思路如下:
*
* 1. 首先是Name泛型 = Paths<FormFinalState<State>['fields']>,根据状态推断出所有的字段路径,比如
* {fields:{name:{value:"zhang"},age:{value:18}}} => "fields.name" | "fields.age"
* 2. 使用FormFieldState将State转换为只包含字段值的对象,如{fields:{name:string,age:number}}
* 3. FormFieldNames用来生成每一个字段路径对应的声明类型,如{fields.xxx:{value,...}}
* 4. MutableRecord<FormFieldNames,'name'>用根据name值推断FormFieldNames成员的类型
*
*/

// 提取表单中的的有效字段,如fields.xxx.value => fields.xxx,用在Field.props.name是指定字段
type FormFieldState<Fields extends Dict> = {
[K in keyof Fields]: Fields[K] extends Dict ? (
Fields[K] extends FormFieldBase<infer V> ? V :
(
Fields[K] extends { execute: any } ? never : FormFieldState<Fields[K]>
)
) : never
}
// 生成每一个字段路径对应的声明类型,如{fields.xxx:{value,...}}
type FormFieldNames<State extends Dict> = {
[Key in keyof Record<Paths<FormFinalState<State>['fields']>,any>]: {
[Key in keyof Record<Paths<FormFieldState<State>['fields']>,any>]: {
render?:FieldRender<GetTypeByPath<State,`fields.${Key}`>>
children?: FieldRender<GetTypeByPath<State,`fields.${Key}`>> | FieldRender<GetTypeByPath<State,`fields.${Key}`>>[];
}
}

export type FieldProps2<State extends Dict,Name extends string | number | bigint | boolean | null | undefined> = {
name: Name
render?:FieldRender<GetTypeByPath<State,`fields.${Name}`>>
children?: FieldRender<GetTypeByPath<State,`fields.${Name}`>> | FieldRender<GetTypeByPath<State,`fields.${Name}`>>[];
}
export type FieldProps3<State extends Dict,Name> = MutableRecord<FormFieldNames<State>,'name'> & {
name: Name
}


export type FieldProps3<State extends Dict> = MutableRecord<FormFieldNames<State>,'name'> & {
name: Paths<FormFieldState<State['fields']>>
}

export function createFieldComponent2<State extends Dict >(store: FormStore<State>,formOptions:RequiredFormOptions<State>) {
return React.memo(<Name extends Paths<FormFinalState<State>['fields']>>(props: FieldProps3<FormState<State>,Name>):ReactNode=>{
return React.memo((props: FieldProps3<FormState<State>>):ReactNode=>{
const { name } = props;
// 不含fields前缀的字段路径
const fieldPath = Array.isArray(name) ? name : String(name).split(".")
Expand Down

0 comments on commit 17a87ce

Please sign in to comment.