Skip to content

Commit

Permalink
Native form example
Browse files Browse the repository at this point in the history
  • Loading branch information
bedrich-schindler committed Jan 14, 2025
1 parent fe13200 commit 2514fd7
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
8 changes: 4 additions & 4 deletions src/components/Modal/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ export const Modal = ({
useModalScrollPrevention(preventScrollUnderneath);

const onCancel = useCallback(
(e) => dialogOnCancelHandler(e, closeButtonRef),
[closeButtonRef],
(e) => dialogOnCancelHandler(e, closeButtonRef, restProps.onCancel),
[closeButtonRef, restProps.onCancel],
);
const onClick = useCallback(
(e) => dialogOnClickHandler(e, closeButtonRef, internalDialogRef, allowCloseOnBackdropClick),
[allowCloseOnBackdropClick, closeButtonRef, internalDialogRef],
);
const onClose = useCallback(
(e) => dialogOnCloseHandler(e, closeButtonRef),
[closeButtonRef],
(e) => dialogOnCloseHandler(e, closeButtonRef, restProps.onClose),
[closeButtonRef, restProps.onClose],
);
const onKeyDown = useCallback(
(e) => dialogOnKeyDownHandler(
Expand Down
89 changes: 89 additions & 0 deletions src/components/Modal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ React.createElement(() => {
label="Launch modal as form"
onClick={() => setModalOpen(4)}
/>
<Button
label="Launch modal as native form"
onClick={() => setModalOpen(5)}
/>
<div>
{modalOpen === 1 && (
<Modal>
Expand Down Expand Up @@ -278,6 +282,91 @@ React.createElement(() => {
</ModalFooter>
</Modal>
)}
{modalOpen === 5 && (
<Modal
allowPrimaryActionOnEnterKey={false}
closeButtonRef={modalCloseButtonRef}
onCancel={(e) => {
console.log('cancel', e);
}}
onClose={(e) => {
console.log('close', e);
}}
primaryButtonRef={modalPrimaryButtonRef}
>
<ModalHeader>
<ModalTitle>Add new user using native form</ModalTitle>
<ModalCloseButton onClick={() => setModalOpen(false)} />
</ModalHeader>
<ModalBody>
<ModalContent>
<p>
This is an example of a native form inside a modal.
The difference is that the dialog is not controlled by React UI,
but using native <code>&lt;form&gt;</code> element.
This is useful when you need to use native form features
like validation, submission, etc.
</p>
<p>
First, you need to set <code>allowPrimaryActionOnEnterKey</code>
to <code>false</code> and remove <code>onClick</code> from the
primary button. Then, you need to set <code>form</code> attribute
on the primary button to the <code>id</code> of the form to
connect it with the form.
</p>
<p>
Although we do not encourage using this approach, it is still
possible to use it when needed.
</p>
<hr />
<form method="dialog" id="native-form">
<FormLayout fieldLayout="horizontal" labelWidth="limited">
<Toggle
label="Enabled"
/>
<TextField label="Username" required />
<TextField label="Password" type="password" />
<CheckboxField label="Force password on login" />
<Radio
label="Type of collaboration"
options={[
{ label: 'Internal', value: 'internal'},
{ label: 'External', value: 'external'},
]}
/>
<SelectField
label="Role"
options={[
{ label: 'Programmer', value: 'programmer' },
{ label: 'Team leader', value: 'team-leader' },
{ label: 'Project manager', value: 'project-manager' },
]}
/>
<FileInputField label="Photo" />
<TextArea
label="Additional info"
helpText={<p>Enter key is used for new line,<br />so <strong>Enter won't submit the form</strong>.</p>}
/>
</FormLayout>
</form>
</ModalContent>
</ModalBody>
<ModalFooter>
<Button
form="native-form"
label="Save"
ref={modalPrimaryButtonRef}
type="submit"
/>
<Button
label="Close"
onClick={() => setModalOpen(false)}
priority="outline"
ref={modalCloseButtonRef}
/>
</ModalFooter>
</Modal>
)}
</div>
</RUIProvider>
);
Expand Down
7 changes: 6 additions & 1 deletion src/components/Modal/_helpers/dialogOnCancelHandler.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const dialogOnCancelHandler = (e, closeButtonRef) => {
export const dialogOnCancelHandler = (e, closeButtonRef, onCancel = undefined) => {
// Prevent the default behaviour of the event as we want to close dialog manually.
e.preventDefault();

Expand All @@ -9,4 +9,9 @@ export const dialogOnCancelHandler = (e, closeButtonRef) => {
) {
closeButtonRef.current.click();
}

// This is a custom handler that is passed as a prop to the Modal component
if (onCancel) {
onCancel(e);
}
};
7 changes: 6 additions & 1 deletion src/components/Modal/_helpers/dialogOnCloseHandler.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
export const dialogOnCloseHandler = (e, closeButtonRef) => {
export const dialogOnCloseHandler = (e, closeButtonRef, onCloseHandler = undefined) => {
// Prevent the default behaviour of the event as we want to close dialog manually.
e.preventDefault();

// If the close button is not disabled, close the modal.
if (closeButtonRef?.current != null && closeButtonRef?.current?.disabled === false) {
closeButtonRef.current.click();
}

// This is a custom handler that is passed as a prop to the Modal component
if (onCloseHandler) {
onCloseHandler(e);
}
};

0 comments on commit 2514fd7

Please sign in to comment.