123
This commit is contained in:
@ -0,0 +1,8 @@
|
||||
import { Checkbox, CheckboxProps } from '@mantine/core';
|
||||
|
||||
type Props = CheckboxProps;
|
||||
|
||||
const BooleanField = (props: Props) => {
|
||||
return <Checkbox {...props} />;
|
||||
};
|
||||
export default BooleanField;
|
||||
9
components/ObjectForm/Fields/NumberField/NumberField.tsx
Normal file
9
components/ObjectForm/Fields/NumberField/NumberField.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { NumberInput, NumberInputProps } from '@mantine/core';
|
||||
|
||||
type Props = NumberInputProps;
|
||||
|
||||
const NumberField = (props: Props) => {
|
||||
return <NumberInput hideControls {...props} />;
|
||||
};
|
||||
|
||||
export default NumberField;
|
||||
9
components/ObjectForm/Fields/StringField/StringField.tsx
Normal file
9
components/ObjectForm/Fields/StringField/StringField.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { TextInput, TextInputProps } from '@mantine/core';
|
||||
|
||||
type Props = TextInputProps;
|
||||
|
||||
const StringField = (props: Props) => {
|
||||
return <TextInput {...props} />;
|
||||
};
|
||||
|
||||
export default StringField
|
||||
74
components/ObjectForm/ObjectForm.tsx
Normal file
74
components/ObjectForm/ObjectForm.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
import { ZodObject } from 'zod';
|
||||
import { Flex, rem } from '@mantine/core';
|
||||
import BooleanField from '@/components/ObjectForm/Fields/BooleanField/BooleanField';
|
||||
import NumberField from '@/components/ObjectForm/Fields/NumberField/NumberField';
|
||||
import StringField from '@/components/ObjectForm/Fields/StringField/StringField';
|
||||
|
||||
type EditProps<T> = {
|
||||
object: T;
|
||||
onChange: (item: T) => void;
|
||||
};
|
||||
type CreateProps<T> = {
|
||||
onCreate: (item: T) => void;
|
||||
};
|
||||
type SchemaLabels<S extends ZodObject<any>> = Partial<Record<keyof S['shape'], string>>;
|
||||
type RestProps<S extends ZodObject<any>> =
|
||||
| {
|
||||
schema: S;
|
||||
labels?: SchemaLabels<S>;
|
||||
excludeKeys?: (keyof S['shape'])[];
|
||||
includeKeys?: never;
|
||||
}
|
||||
| {
|
||||
schema: S;
|
||||
labels?: SchemaLabels<S>;
|
||||
includeKeys?: (keyof S['shape'])[];
|
||||
excludeKeys?: never;
|
||||
};
|
||||
|
||||
type Props<ObjectType, ObjectSchema extends ZodObject> = (
|
||||
| EditProps<ObjectType>
|
||||
| CreateProps<ObjectType>
|
||||
) &
|
||||
RestProps<ObjectSchema>;
|
||||
|
||||
const RenderField = (key: string, value: any, label?: string) => {
|
||||
const getField = () => {
|
||||
switch (value.type) {
|
||||
case 'string':
|
||||
return <StringField label={label ? label : key} />;
|
||||
case 'number':
|
||||
return <NumberField label={label ? label : key} />;
|
||||
case 'boolean':
|
||||
return <BooleanField label={label ? label : key} />;
|
||||
default:
|
||||
return <></>;
|
||||
}
|
||||
};
|
||||
return <div key={key}>{getField()}</div>;
|
||||
};
|
||||
|
||||
function ObjectForm<ObjectType, ObjectSchema extends ZodObject<any, any>>(
|
||||
props: Props<ObjectType, ObjectSchema>
|
||||
) {
|
||||
const processKeyValue = (key: string, val: any) => {
|
||||
const keyTyped = key as keyof typeof props.schema.shape;
|
||||
if (props.excludeKeys && props.excludeKeys.includes(keyTyped)) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
if (props.includeKeys && !props.includeKeys.includes(keyTyped)) {
|
||||
return <></>;
|
||||
}
|
||||
const label = props.labels ? props.labels[keyTyped] : undefined;
|
||||
return RenderField(key, val, label);
|
||||
};
|
||||
return (
|
||||
<Flex gap={rem(10)} direction="column">
|
||||
{Object.entries(props.schema.shape).map(([key, val]) => {
|
||||
return processKeyValue(key, val);
|
||||
})}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
export default ObjectForm;
|
||||
Reference in New Issue
Block a user