* fix(@vben-core/form-ui): avoid stale form context access * fix(@vben/playground): constrain date range codec fields * test(@vben-core/form-ui): harden benchmark fixtures * docs(@vben/docs): document form runtime and benchmarks * fix(@vben/docs): 明确 getValues/submit 返回值及 submit 参数类型
82 lines
2.3 KiB
TypeScript
82 lines
2.3 KiB
TypeScript
import type { Dayjs } from 'dayjs';
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
type DateRange = [Dayjs, Dayjs];
|
|
|
|
type OptionalDateRangeField<
|
|
TFormValues extends Record<string, unknown>,
|
|
TRangeField extends keyof TFormValues,
|
|
> =
|
|
Record<never, never> extends Pick<TFormValues, TRangeField>
|
|
? [Exclude<TFormValues[TRangeField], undefined>] extends [never]
|
|
? never
|
|
: Exclude<TFormValues[TRangeField], undefined> extends DateRange
|
|
? TRangeField
|
|
: never
|
|
: never;
|
|
|
|
type DateRangeSubmitValues<
|
|
TFormValues extends Record<string, unknown>,
|
|
TRangeField extends keyof TFormValues,
|
|
TStartField extends string,
|
|
TEndField extends string,
|
|
> = Omit<TFormValues, TRangeField> &
|
|
Record<TEndField | TStartField, string | undefined>;
|
|
|
|
interface DateRangeCodecOptions<
|
|
TFormValues extends Record<string, unknown>,
|
|
TRangeField extends keyof TFormValues & string,
|
|
TStartField extends string,
|
|
TEndField extends string,
|
|
> {
|
|
endField: TEndField;
|
|
rangeField: OptionalDateRangeField<TFormValues, TRangeField> & TRangeField;
|
|
startField: TStartField;
|
|
}
|
|
|
|
export function createDateRangeCodec<
|
|
TFormValues extends Record<string, unknown>,
|
|
>() {
|
|
return function createCodec<
|
|
TRangeField extends keyof TFormValues & string,
|
|
TStartField extends string,
|
|
TEndField extends string,
|
|
>(
|
|
options: DateRangeCodecOptions<
|
|
TFormValues,
|
|
TRangeField,
|
|
TStartField,
|
|
TEndField
|
|
>,
|
|
) {
|
|
const { endField, startField } = options;
|
|
const rangeField = options.rangeField as TRangeField;
|
|
type SubmitValues = DateRangeSubmitValues<
|
|
TFormValues,
|
|
TRangeField,
|
|
TStartField,
|
|
TEndField
|
|
>;
|
|
|
|
return {
|
|
decode(values: Readonly<SubmitValues>): TFormValues {
|
|
const { [endField]: end, [startField]: start, ...formValues } = values;
|
|
return {
|
|
...formValues,
|
|
...(start && end ? { [rangeField]: [dayjs(start), dayjs(end)] } : {}),
|
|
} as TFormValues;
|
|
},
|
|
encode(values: Readonly<TFormValues>): SubmitValues {
|
|
const { [rangeField]: value, ...formValues } = values;
|
|
const range = value as DateRange | undefined;
|
|
return {
|
|
...formValues,
|
|
[endField]: range?.[1]?.format('YYYY-MM-DD'),
|
|
[startField]: range?.[0]?.format('YYYY-MM-DD'),
|
|
} as SubmitValues;
|
|
},
|
|
};
|
|
};
|
|
}
|