refactor(former): 🔄 restructure form components and stores
* Remove unused FormLayout and SuperForm stores. * Consolidate form logic into Former component. * Implement new Former layout and types. * Update stories for new Former component. * Clean up unused styles and types across the project.
This commit is contained in:
115
src/Former/Former.tsx
Normal file
115
src/Former/Former.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import { forwardRef, type PropsWithChildren, useEffect, useImperativeHandle } from 'react';
|
||||
import { type FieldValues, FormProvider, useForm } from 'react-hook-form';
|
||||
|
||||
import type { FormerProps, FormerRef } from './Former.types';
|
||||
|
||||
import { FormerProvider, useFormerStore } from './Former.store';
|
||||
import { FormerLayout } from './FormerLayout';
|
||||
|
||||
const FormerInner = forwardRef<FormerRef<any>, Partial<FormerProps<any>> & PropsWithChildren>(
|
||||
function FormerInner<T extends FieldValues>(
|
||||
props: Partial<FormerProps<T>> & PropsWithChildren<T>,
|
||||
ref: any
|
||||
) {
|
||||
const {
|
||||
getState,
|
||||
onChange,
|
||||
onClose,
|
||||
onOpen,
|
||||
opened,
|
||||
primeData,
|
||||
reset,
|
||||
save,
|
||||
setState,
|
||||
useFormProps,
|
||||
validate,
|
||||
values,
|
||||
wrapper,
|
||||
} = useFormerStore((state) => ({
|
||||
getState: state.getState,
|
||||
onChange: state.onChange,
|
||||
onClose: state.onClose,
|
||||
onOpen: state.onOpen,
|
||||
opened: state.opened,
|
||||
primeData: state.primeData,
|
||||
reset: state.reset,
|
||||
save: state.save,
|
||||
setState: state.setState,
|
||||
useFormProps: state.useFormProps,
|
||||
validate: state.validate,
|
||||
values: state.values,
|
||||
wrapper: state.wrapper,
|
||||
}));
|
||||
|
||||
const formMethods = useForm<T>({
|
||||
defaultValues: primeData,
|
||||
mode: 'all',
|
||||
shouldUseNativeValidation: true,
|
||||
values: values,
|
||||
...useFormProps,
|
||||
});
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ({
|
||||
close: async () => {
|
||||
//console.log('close called');
|
||||
onClose?.();
|
||||
setState('opened', false);
|
||||
},
|
||||
getValue: () => {
|
||||
return getState('values');
|
||||
},
|
||||
reset: () => {
|
||||
reset();
|
||||
},
|
||||
save: async () => {
|
||||
return await save();
|
||||
},
|
||||
setValue: (value: T) => {
|
||||
onChange?.(value);
|
||||
},
|
||||
show: async () => {
|
||||
//console.log('show called');
|
||||
setState('opened', true);
|
||||
onOpen?.();
|
||||
},
|
||||
validate: async () => {
|
||||
return await validate();
|
||||
},
|
||||
}),
|
||||
[getState, onChange]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setState('getFormMethods', () => formMethods);
|
||||
}, [formMethods]);
|
||||
|
||||
return (
|
||||
<FormProvider {...formMethods}>
|
||||
{typeof wrapper === 'function' ? (
|
||||
wrapper(<FormerLayout>{props.children}</FormerLayout>, opened, onClose, onOpen, getState)
|
||||
) : (
|
||||
<FormerLayout>{props.children || null}</FormerLayout>
|
||||
)}
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const Former = forwardRef<FormerRef<any>, FormerProps<any> & PropsWithChildren>(
|
||||
function Former<T extends FieldValues = any>(
|
||||
props: FormerProps<T> & PropsWithChildren<T>,
|
||||
ref: any
|
||||
) {
|
||||
//if opened is false and wrapper is defined as function, do not render anything
|
||||
if (!props.opened && typeof props.wrapper === 'function') {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<FormerProvider {...props}>
|
||||
<FormerInner ref={ref}>{props.children}</FormerInner>
|
||||
</FormerProvider>
|
||||
);
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user