docs(changeset): feat(Former): add keep open functionality and update onClose behavior

This commit is contained in:
2026-02-08 00:12:14 +02:00
parent 6ff395e9be
commit 8928432fe0
4 changed files with 47 additions and 9 deletions

View File

@@ -0,0 +1,5 @@
---
'@warkypublic/oranguru': patch
---
feat(Former): add keep open functionality and update onClose behavior

View File

@@ -118,21 +118,38 @@ const { Provider: FormerProvider, useStore: useFormerStore } = createSyncStore<
if (get().afterSave) { if (get().afterSave) {
await get().afterSave!(newData, get()); await get().afterSave!(newData, get());
} }
if (keepOpen) {
const keyName = get()?.uniqueKeyField || 'id';
const clearedData = { ...newData };
delete clearedData[keyName];
set({ loading: false, values: clearedData });
get().onChange?.(clearedData, get());
formMethods.reset(clearedData);
return newData;
}
set({ loading: false, values: newData }); set({ loading: false, values: newData });
get().onChange?.(newData, get()); get().onChange?.(newData, get());
formMethods.reset(newData); //reset with saved data to clear dirty state formMethods.reset(newData); //reset with saved data to clear dirty state
if (!keepOpen) { get().onClose?.(newData);
get().onClose?.(newData);
}
return newData; return newData;
} }
if (keepOpen) {
const keyName = get()?.uniqueKeyField || 'id';
const clearedData = { ...data };
delete clearedData[keyName];
set({ loading: false, values: clearedData });
formMethods.reset(clearedData);
get().onChange?.(clearedData, get());
return data;
}
set({ loading: false, values: data }); set({ loading: false, values: data });
formMethods.reset(data); //reset with saved data to clear dirty state formMethods.reset(data); //reset with saved data to clear dirty state
get().onChange?.(data, get()); get().onChange?.(data, get());
if (!keepOpen) { get().onClose?.(data);
get().onClose?.(data);
}
return data; return data;
} }

View File

@@ -31,12 +31,13 @@ export interface FormerProps<T extends FieldValues = any> {
renderTop?: FormerSectionRender<T>; renderTop?: FormerSectionRender<T>;
saveButtonProps?: ButtonProps; saveButtonProps?: ButtonProps;
saveButtonTitle?: React.ReactNode; saveButtonTitle?: React.ReactNode;
showKeepOpenSwitch?: boolean;
title?: string; title?: string;
}; };
onAPICall?: FormerAPICallType<T>; onAPICall?: FormerAPICallType<T>;
onCancel?: () => void; onCancel?: () => void;
onChange?: (value: T, state: Partial<FormStateAndProps<T>>) => void; onChange?: (value: T, state: Partial<FormStateAndProps<T>>) => void;
onClose?: (data: T | undefined) => void; onClose?: (data?: T | undefined) => void;
onConfirmDelete?: (values?: T) => Promise<boolean>; onConfirmDelete?: (values?: T) => Promise<boolean>;
onError?: (error: Error | string, state: Partial<FormStateAndProps<T>>) => void; onError?: (error: Error | string, state: Partial<FormStateAndProps<T>>) => void;
onOpen?: (data?: T) => void; onOpen?: (data?: T) => void;

View File

@@ -1,4 +1,4 @@
import { Button, Group, Tooltip } from '@mantine/core'; import { Button, Group, Switch, Tooltip } from '@mantine/core';
import { IconDeviceFloppy, IconX } from '@tabler/icons-react'; import { IconDeviceFloppy, IconX } from '@tabler/icons-react';
import { useFormerStore } from './Former.store'; import { useFormerStore } from './Former.store';
@@ -9,21 +9,29 @@ export const FormerButtonArea = () => {
closeButtonProps, closeButtonProps,
closeButtonTitle, closeButtonTitle,
dirty, dirty,
getState,
keepOpen,
onClose, onClose,
request, request,
save, save,
saveButtonProps, saveButtonProps,
saveButtonTitle, saveButtonTitle,
setState,
showKeepOpenSwitch,
} = useFormerStore((state) => ({ } = useFormerStore((state) => ({
buttonAreaGroupProps: state.layout?.buttonAreaGroupProps, buttonAreaGroupProps: state.layout?.buttonAreaGroupProps,
closeButtonProps: state.layout?.closeButtonProps, closeButtonProps: state.layout?.closeButtonProps,
closeButtonTitle: state.layout?.closeButtonTitle, closeButtonTitle: state.layout?.closeButtonTitle,
dirty: state.dirty, dirty: state.dirty,
getState: state.getState,
keepOpen: state.keepOpen,
onClose: state.onClose, onClose: state.onClose,
request: state.request, request: state.request,
save: state.save, save: state.save,
saveButtonProps: state.layout?.saveButtonProps, saveButtonProps: state.layout?.saveButtonProps,
saveButtonTitle: state.layout?.saveButtonTitle, saveButtonTitle: state.layout?.saveButtonTitle,
setState: state.setState,
showKeepOpenSwitch: state.layout?.showKeepOpenSwitch,
})); }));
const disabledSave = const disabledSave =
@@ -47,12 +55,19 @@ export const FormerButtonArea = () => {
size="sm" size="sm"
{...closeButtonProps} {...closeButtonProps}
onClick={() => { onClick={() => {
onClose(); onClose(getState('values'));
}} }}
> >
{closeButtonTitle || 'Close'} {closeButtonTitle || 'Close'}
</Button> </Button>
)} )}
{showKeepOpenSwitch && (
<Switch
checked={keepOpen}
label="Keep Open"
onChange={(event) => setState('keepOpen', event.currentTarget.checked)}
/>
)}
<Tooltip <Tooltip
label={ label={
disabledSave ? ( disabledSave ? (