Form prototype

This commit is contained in:
2026-01-11 09:45:03 +02:00
parent 71403289c2
commit b2817f4233
25 changed files with 2003 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
import React, {
forwardRef,
useCallback,
useImperativeHandle,
useRef,
useState,
type ReactElement,
type Ref,
} from 'react'
import { IconX } from '@tabler/icons-react'
import type { FieldValues } from 'react-hook-form'
import { ActionIcon, Drawer } from '@mantine/core'
import type { SuperFormDrawerProps, SuperFormDrawerRef, SuperFormRef } from '../../types'
import SuperForm from '../../components/SuperForm'
import { openConfirmModal } from '../../utils/openConfirmModal'
const SuperFormDrawer = <T extends FieldValues>(
{ drawerProps, noCloseOnSubmit, ...formProps }: SuperFormDrawerProps<T>,
ref: Ref<SuperFormDrawerRef<T>>
) => {
// Component Refs
const formRef = useRef<SuperFormRef<T>>(null)
const drawerRef = useRef<HTMLDivElement>(null)
// Component store State
// Tell drawer that form layout mounted to fix refs
const [layoutMounted, setLayoutMounted] = useState(false)
// Component Callback Functions
const onSubmit = (data: T, request, formData, form, closeForm: boolean = true) => {
formProps?.onSubmit?.(data, request, formData, form, closeForm)
if (request === 'delete') {
drawerProps?.onClose()
}
if (!noCloseOnSubmit) {
if (closeForm) {
drawerProps?.onClose()
}
}
}
const onCancel = (request) => {
if (formRef?.current?.getFormState().isDirty) {
openConfirmModal(() => {
drawerProps?.onClose()
formProps?.onCancel?.(request)
})
} else {
drawerProps?.onClose()
formProps?.onCancel?.(request)
}
}
const onLayoutMounted = useCallback(() => {
setLayoutMounted(true)
formProps?.onLayoutMounted?.()
}, [formProps?.onLayoutMounted])
const onLayoutUnMounted = useCallback(() => {
setLayoutMounted(false)
formProps?.onLayoutUnMounted?.()
}, [formProps?.onLayoutUnMounted])
// Component use Effects
useImperativeHandle<SuperFormDrawerRef<T>, SuperFormDrawerRef<T>>(
ref,
() => ({
...formRef.current,
drawer: drawerRef.current,
} as SuperFormDrawerRef<T>),
[layoutMounted]
)
return (
<Drawer
ref={drawerRef}
onClose={onCancel}
closeOnClickOutside={false}
onKeyDown={(e) => {
if (e.key === 'Escape' && drawerProps.closeOnEscape !== false) {
e.stopPropagation()
onCancel(formProps.request)
}
}}
overlayProps={{ backgroundOpacity: 0.5, blur: 0.5 }}
padding={6}
position='right'
transitionProps={{
transition: 'slide-left',
duration: 150,
timingFunction: 'linear',
}}
size={500}
styles={{
content: {
display: 'flex',
flexDirection: 'column',
justifyContent: 'stretch',
},
body: {
minHeight: '100px',
flexGrow: 1,
},
}}
keepMounted={false}
{...drawerProps}
closeOnEscape={false}
withCloseButton={false}
title={null}
>
<SuperForm<T>
{...formProps}
onCancel={onCancel}
onSubmit={onSubmit}
onLayoutMounted={onLayoutMounted}
onLayoutUnMounted={onLayoutUnMounted}
ref={formRef}
layoutProps={{
...formProps?.layoutProps,
rightSection: (
<ActionIcon
size='xs'
onClick={() => {
onCancel(formProps?.request)
}}
>
<IconX size={18} />
</ActionIcon>
),
title:
(drawerProps.title as string) ??
formProps?.layoutProps?.title ??
(formProps?.request as string),
}}
/>
</Drawer>
)
}
const FRSuperFormDrawer = forwardRef(SuperFormDrawer) as <T extends FieldValues>(
props: SuperFormDrawerProps<T> & { ref?: Ref<SuperFormDrawerRef<T>> }
) => ReactElement
export default FRSuperFormDrawer