Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions Documentation/CommandDialog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ const CreateProjectDialog = () => {
const { closeDialog } = useDialogContext<CommandResult<CreateProjectResponse>>();

return (
<CommandDialog<CreateProject, CreateProjectResponse>
<CommandDialog<CreateProject>
command={CreateProject}
header='Create project'
onConfirm={async result => closeDialog(DialogResult.Ok, result as CommandResult<CreateProjectResponse>)}
title='Create project'
okLabel='Create'
onConfirm={async () => closeDialog(DialogResult.Ok)}
onCancel={() => closeDialog(DialogResult.Cancelled)}
/>
);
Expand Down Expand Up @@ -77,28 +78,39 @@ function MyComponent() {
### Required Props

- `command`: Constructor for the command type
- `header`: Dialog title text
- `onConfirm`: Callback function when command succeeds
- `onCancel`: Callback function when dialog is cancelled
- `title`: Dialog title text

### Optional Props

- `visible`: Boolean controlling dialog visibility (defaults to `true`)
- `initialValues`: Initial values for the command form
- `currentValues`: Current values to populate the form
- `confirmLabel`: Custom text for confirm button (default: "OK")
- `onConfirm`: Confirm callback from `Dialog` (called only after successful command execution)
- `onCancel`: Cancel callback from `Dialog`
- `onClose`: Fallback close callback from `Dialog`
- `okLabel`: Custom text for confirm button (default: "Ok")
- `cancelLabel`: Custom text for cancel button (default: "Cancel")
- `confirmIcon`: Icon for confirm button
- `cancelIcon`: Icon for cancel button
- `yesLabel`, `noLabel`: Labels for `YesNo` and `YesNoCancel` button modes
- `buttons`: `DialogButtons` value or custom footer content
- `resizable`: Whether dialog can be resized
- `isValid`: Additional validity gate combined with command form validity
- `onFieldValidate`: Custom validation function for fields
- `onFieldChange`: Callback when field values change
- `onBeforeExecute`: Transform command values before execution
- `style`: Custom CSS styles
- `width`: Dialog width

## Callback Behavior

- `onConfirm` is executed only after command execution succeeds.
- If `onConfirm` returns `true`, the dialog closes; otherwise it stays open.
- If `onConfirm` is not provided, `onClose(DialogResult.Ok)` is used.
- `onCancel` follows the same behavior as `Dialog` (`true` closes).
- `onClose` closes unless it returns `false`.

## Context

`CommandDialog` is built on top of `CommandForm` and uses the command form context internally for values, validation, and execution state.
`CommandDialog` is built on top of `CommandForm` and `Dialog`, and uses command form context internally for values, validation, and execution state.

When used as an awaitable dialog, pair it with `useDialogContext<CommandResult<TResponse>>()` in a wrapping dialog component.

Expand Down
3 changes: 3 additions & 0 deletions Documentation/Dialogs/dialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,14 @@ const MyComponent = () => {
- `onClose`: Fallback close callback
- `buttons`: Predefined `DialogButtons` or custom footer content
- `width`: Dialog width
- `style`: Custom dialog style forwarded to PrimeReact `Dialog`
- `resizable`: Enables resize
- `isValid`: Enables or disables confirm actions
- `okLabel`, `cancelLabel`, `yesLabel`, `noLabel`: Button labels

## Notes

- Prefer `onConfirm` and `onCancel` over `onClose` for clear intent.
- `onConfirm` and `onCancel` should return `true` to close when used.
- `onClose` closes unless it returns `false`.
- For typed, awaitable dialogs, let the dialog call `closeDialog(...)` from `useDialogContext<T>()`.
60 changes: 29 additions & 31 deletions Source/CommandDialog/CommandDialog.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,11 @@ const ServerValidationWrapper = () => {
<CommandDialog<UpdateUserCommandWithServer>
command={UpdateUserCommandWithServer}
visible={visible}
header="Update User Information (with Server Validation)"
confirmLabel="Save"
title="Update User Information (with Server Validation)"
okLabel="Save"
cancelLabel="Cancel"
onConfirm={async (commandResult) => {
setResult(JSON.stringify(commandResult));
onConfirm={async () => {
setResult('Command executed successfully');
setVisible(false);
}}
onCancel={() => setVisible(false)}
Expand Down Expand Up @@ -162,11 +162,11 @@ const AwaitableWithResultWrapper = () => {
return (
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
header="Update User Information (awaitable result)"
confirmLabel="Save"
title="Update User Information (awaitable result)"
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
onConfirm={async commandResult => closeDialog(DialogResult.Ok, commandResult)}
onConfirm={async () => closeDialog(DialogResult.Ok)}
onCancel={() => closeDialog(DialogResult.Cancelled)}
>
<InputTextField value={(c: UpdateUserCommand) => c.name} title="Name" placeholder="Enter name (min 2 chars)" />
Expand Down Expand Up @@ -252,8 +252,8 @@ const EditUserWrapper = () => {
key={selectedUser?.email ?? 'empty'}
initialValues={selectedUser}
visible={visible}
header={`Edit User: ${selectedUser?.name ?? ''}`}
confirmLabel="Save"
title={`Edit User: ${selectedUser?.name ?? ''}`}
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
onConfirm={async () => {
Expand Down Expand Up @@ -299,8 +299,8 @@ const CustomValidationWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Add User (with Custom Validation)"
confirmLabel="Save"
title="Add User (with Custom Validation)"
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
onConfirm={async () => {
Expand Down Expand Up @@ -350,8 +350,8 @@ const ValidationOnBlurWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Validation on Blur"
confirmLabel="Save"
title="Validation on Blur"
okLabel="Save"
cancelLabel="Cancel"
validateOn="blur"
autoServerValidate={false}
Expand Down Expand Up @@ -381,8 +381,8 @@ const ValidationOnChangeWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Validation on Change"
confirmLabel="Save"
title="Validation on Change"
okLabel="Save"
cancelLabel="Cancel"
validateOn="change"
autoServerValidate={false}
Expand Down Expand Up @@ -412,8 +412,8 @@ const ValidateOnInitWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Validate on Initialization"
confirmLabel="Save"
title="Validate on Initialization"
okLabel="Save"
cancelLabel="Cancel"
validateOnInit={true}
autoServerValidate={false}
Expand Down Expand Up @@ -444,8 +444,8 @@ const ValidateAllFieldsWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Validate All Fields on Change"
confirmLabel="Save"
title="Validate All Fields on Change"
okLabel="Save"
cancelLabel="Cancel"
validateOn="blur"
validateAllFieldsOnChange={true}
Expand Down Expand Up @@ -485,20 +485,18 @@ const BeforeExecuteWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Before Execute Callback"
confirmLabel="Save"
title="Before Execute Callback"
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
initialValues={{ name: '', email: '', age: 18 }}
onBeforeExecute={(command) => {
command.name = command.name.trim().replace(/\s+/g, ' ');
command.email = command.email.toLowerCase().trim();
setPreprocessedData(JSON.stringify(command, null, 2));
return command;
}}
onConfirm={async (result) => {
setPreprocessedData(JSON.stringify(result, null, 2));
setVisible(false);
}}
onConfirm={async () => setVisible(false)}
onCancel={() => setVisible(false)}
>
<InputTextField value={(c: UpdateUserCommand) => c.name} title="Name" placeholder='Try " Extra Spaces "' />
Expand All @@ -524,8 +522,8 @@ const WithIconsWrapper = () => {
<CommandDialog<UpdateUserCommand>
command={UpdateUserCommand}
visible={visible}
header="Fields with Icons"
confirmLabel="Save"
title="Fields with Icons"
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
onConfirm={async () => setVisible(false)}
Expand Down Expand Up @@ -619,8 +617,8 @@ const MultiColumnWrapper = () => {
<CommandDialog<UpdateProfileCommand>
command={UpdateProfileCommand}
visible={visible}
header="Edit Profile"
confirmLabel="Save"
title="Edit Profile"
okLabel="Save"
cancelLabel="Cancel"
width="70vw"
autoServerValidate={false}
Expand Down Expand Up @@ -658,8 +656,8 @@ const MixedChildrenWrapper = () => {
<CommandDialog<UpdateProfileCommand>
command={UpdateProfileCommand}
visible={visible}
header="Edit Profile (Mixed Children)"
confirmLabel="Save"
title="Edit Profile (Mixed Children)"
okLabel="Save"
cancelLabel="Cancel"
autoServerValidate={false}
onConfirm={async () => setVisible(false)}
Expand Down
Loading
Loading