Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Doc] Add "standalaone usage" doc section in dialog views #10241

Merged
merged 2 commits into from
Sep 27, 2024
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
114 changes: 114 additions & 0 deletions docs/CreateDialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,117 @@ const CompanyShow = () => (
{% endraw %}

In the above example, `<CreateInDialogButton>` is used to create a new employee for the current company. [The `<WithRecord>` component](./WithRecord.md) helps to set the new employee company id by default.

## Standalone Usage

`<CreateDialog>` also offer the ability to work standalone, without using the Router's location.

To allow for standalone usage, they require the following props:

- `isOpen`: a boolean holding the open/close state
- `open`: a function that will be called when a component needs to open the dialog (e.g. a button)
- `close`: a function that will be called when a component needs to close the dialog (e.g. the dialog's close button)

**Tip:** These props are exactly the same as what is stored inside a `FormDialogContext`. This means that you can also rather provide your own `FormDialogContext` with these values, and render your dialog component inside it, to activate standalone mode.

Below is an example of an `<Edit>` page, including a 'create a new customer' button, that opens a fully controlled `<CreateDialog>`.

<video controls autoplay playsinline muted loop>
<source src="https://react-admin-ee.marmelab.com/assets/FullyControlledCreateDialog.mp4" type="video/mp4"/>
Your browser does not support the video tag.
</video>

{% raw %}

```tsx
import React, { useCallback, useState } from 'react';
import {
Button,
Datagrid,
DateField,
DateInput,
Edit,
ReferenceManyField,
required,
SelectField,
SelectInput,
SimpleForm,
TextField,
TextInput,
useRecordContext,
} from 'react-admin';
import { CreateDialog } from '@react-admin/ra-form-layout';

const sexChoices = [
{ id: 'male', name: 'Male' },
{ id: 'female', name: 'Female' },
];

const CustomerForm = (props: any) => (
<SimpleForm defaultValues={{ firstname: 'John', name: 'Doe' }} {...props}>
<TextInput source="first_name" validate={required()} />
<TextInput source="last_name" validate={required()} />
<DateInput source="dob" label="born" validate={required()} />
<SelectInput source="sex" choices={sexChoices} />
</SimpleForm>
);

const EmployerSimpleFormWithFullyControlledDialogs = () => {
const record = useRecordContext();

const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);
const openCreateDialog = useCallback(() => {
setIsCreateDialogOpen(true);
}, []);
const closeCreateDialog = useCallback(() => {
setIsCreateDialogOpen(false);
}, []);

return (
<SimpleForm>
<TextInput source="name" validate={required()} />
<TextInput source="address" validate={required()} />
<TextInput source="city" validate={required()} />
<Button
label="Create a new customer"
onClick={() => openCreateDialog()}
size="medium"
variant="contained"
sx={{ mb: 4 }}
/>
<CreateDialog
fullWidth
maxWidth="md"
record={{ employer_id: record?.id }} // pre-populates the employer_id to link the new customer to the current employer
isOpen={isCreateDialogOpen}
open={openCreateDialog}
close={closeCreateDialog}
resource="customers"
>
<CustomerForm />
</CreateDialog>
<ReferenceManyField
label="Customers"
reference="customers"
target="employer_id"
>
<Datagrid>
<TextField source="id" />
<TextField source="first_name" />
<TextField source="last_name" />
<DateField source="dob" label="born" />
<SelectField source="sex" choices={sexChoices} />
</Datagrid>
</ReferenceManyField>
</SimpleForm>
);
};

const EmployerEdit = () => (
<Edit>
<EmployerSimpleFormWithFullyControlledDialogs />
</Edit>
);
```

{% endraw %}
114 changes: 114 additions & 0 deletions docs/EditDialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,117 @@ const CompanyShow = () => (
```

Check [the `<EditInDialogButton>` component](./EditInDialogButton.md) for more details.

## Standalone Usage

`<EditDialog>` also offer the ability to work standalone, without using the Router's location.

To allow for standalone usage, they require the following props:

- `isOpen`: a boolean holding the open/close state
- `open`: a function that will be called when a component needs to open the dialog (e.g. a button)
- `close`: a function that will be called when a component needs to close the dialog (e.g. the dialog's close button)

**Tip:** These props are exactly the same as what is stored inside a `FormDialogContext`. This means that you can also rather provide your own `FormDialogContext` with these values, and render your dialog component inside it, to activate standalone mode.

Below is an example of an `<Edit>` page, including a 'create a new customer' button, that opens a fully controlled `<EditDialog>`.

<video controls autoplay playsinline muted loop>
<source src="https://react-admin-ee.marmelab.com/assets/FullyControlledCreateDialog.mp4" type="video/mp4"/>
Your browser does not support the video tag.
</video>

{% raw %}

```tsx
import React, { useCallback, useState } from 'react';
import {
Button,
Datagrid,
DateField,
DateInput,
Edit,
ReferenceManyField,
required,
SelectField,
SelectInput,
SimpleForm,
TextField,
TextInput,
useRecordContext,
} from 'react-admin';
import { EditDialog } from '@react-admin/ra-form-layout';

const sexChoices = [
{ id: 'male', name: 'Male' },
{ id: 'female', name: 'Female' },
];

const CustomerForm = (props: any) => (
<SimpleForm defaultValues={{ firstname: 'John', name: 'Doe' }} {...props}>
<TextInput source="first_name" validate={required()} />
<TextInput source="last_name" validate={required()} />
<DateInput source="dob" label="born" validate={required()} />
<SelectInput source="sex" choices={sexChoices} />
</SimpleForm>
);

const EmployerSimpleFormWithFullyControlledDialogs = () => {
const record = useRecordContext();

const [isEditDialogOpen, setIsEditDialogOpen] = useState(false);
const openEditDialog = useCallback(() => {
setIsEditDialogOpen(true);
}, []);
const closeEditDialog = useCallback(() => {
setIsEditDialogOpen(false);
}, []);

return (
<SimpleForm>
<TextInput source="name" validate={required()} />
<TextInput source="address" validate={required()} />
<TextInput source="city" validate={required()} />
<ReferenceManyField
label="Customers"
reference="customers"
target="employer_id"
>
<Datagrid>
<TextField source="id" />
<TextField source="first_name" />
<TextField source="last_name" />
<DateField source="dob" label="born" />
<SelectField source="sex" choices={sexChoices} />
<Button
label="Edit customer"
onClick={() => openEditDialog()}
size="medium"
variant="contained"
sx={{ mb: 4 }}
/>
</Datagrid>
</ReferenceManyField>
<EditDialog
fullWidth
maxWidth="md"
record={{ employer_id: record?.id }} // pre-populates the employer_id to link the new customer to the current employer
isOpen={isEditDialogOpen}
open={openEditDialog}
close={closeEditDialog}
resource="customers"
>
<CustomerForm />
</EditDialog>
</SimpleForm>
);
};

const EmployerEdit = () => (
<Edit>
<EmployerSimpleFormWithFullyControlledDialogs />
</Edit>
);
```

{% endraw %}
Loading