Skip to content

Commit 8ea0089

Browse files
feat(ui): disable Modal close button (#1253)
* allow disabling of close modal * changeset * tests * update changeset * fix disabled cancel button and add story * fix misspelling * update stories
1 parent 416d83f commit 8ea0089

4 files changed

Lines changed: 48 additions & 3 deletions

File tree

.changeset/fresh-jokes-move.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudoperators/juno-ui-components": minor
3+
---
4+
5+
Allow disabling of close button with `disableCloseButton` in `Modal`.

packages/ui-components/src/components/Modal/Modal.component.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ export const Modal: React.FC<ModalProps> = ({
9494
closeable = true,
9595
closeOnEsc = true,
9696
closeOnBackdropClick = false,
97+
disableCloseButton,
9798
size = "small",
9899
unpad = false,
99100
className = "",
@@ -212,7 +213,15 @@ export const Modal: React.FC<ModalProps> = ({
212213
className={`juno-modal-header ${headerstyles} ${modalTitle ? `jn:justify-between` : `jn:justify-end`}`}
213214
>
214215
{renderModalTitle()}
215-
{isCloseable ? <Icon icon="close" onClick={handleCancelClick} aria-label="close" /> : ""}
216+
{isCloseable ? (
217+
<Icon
218+
icon="close"
219+
onClick={handleCancelClick}
220+
disabled={disableCancelButton || disableCloseButton}
221+
/>
222+
) : (
223+
""
224+
)}
216225
</div>
217226
<div className={`juno-modal-content ${contentstyles} ${unpad ? "" : contentpaddingstyles}`}>
218227
{children}
@@ -261,6 +270,8 @@ export interface ModalProps extends Omit<React.HTMLProps<HTMLDivElement>, "size"
261270
closeOnEsc?: boolean
262271
/** The Modal size */
263272
closeOnBackdropClick?: boolean
273+
/** Determines whether the close button should be disabled */
274+
disableCloseButton?: boolean
264275
/** Whether the modal can be closed by hitting the ESC key */
265276
size?: ModalSize
266277
/** Pass to remove default padding from the content area of the modal */

packages/ui-components/src/components/Modal/Modal.stories.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,12 @@ export const SimpleConfirmDialog: Story = {
102102
export const SimpleConfirmDialogWithDisabledButtons: Story = {
103103
render: Template,
104104
args: {
105-
children: <p>Are you sure you want to proceed?</p>,
105+
children: (
106+
<p>
107+
This modal has a disabled Confirm and Cancel button. Note that disableCancelButton also disables the top-right
108+
Close button.
109+
</p>
110+
),
106111
cancelButtonLabel: "Cancel",
107112
confirmButtonLabel: "Yes, Proceed",
108113
disableConfirmButton: true,
@@ -223,6 +228,16 @@ export const CloseOnBackdropClick: Story = {
223228
},
224229
}
225230

231+
export const DisabledCloseButton: Story = {
232+
render: Template,
233+
args: {
234+
title: "Disabled Close Button Modal",
235+
children: <p>This Modal has a disabled top-right close button.</p>,
236+
disableCloseButton: true,
237+
cancelButtonLabel: "Cancel",
238+
},
239+
}
240+
226241
export const Login: Story = {
227242
render: Template,
228243
args: {

packages/ui-components/src/components/Modal/Modal.test.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ describe("Modal", () => {
386386
expect(mockOnConfirm).not.toHaveBeenCalled()
387387
})
388388

389-
test("renders a disabled cancel action button and ensures onCancel is not triggered", async () => {
389+
test("renders a disabled cancel action button, ensures onCancel isn't triggered and that the close button is disabled", async () => {
390390
await waitFor(() =>
391391
render(
392392
<PortalProvider>
@@ -399,7 +399,21 @@ describe("Modal", () => {
399399
expect(cancelButton).toBeInTheDocument()
400400
expect(cancelButton).toHaveAttribute("disabled")
401401

402+
expect(screen.getByRole("button", { name: "close" })).toBeDisabled()
403+
402404
await waitFor(() => userEvent.click(cancelButton))
403405
expect(mockOnCancel).not.toHaveBeenCalled()
404406
})
407+
408+
test("renders a modal with a disabled close button if disableCloseButton is true", async () => {
409+
await waitFor(() =>
410+
render(
411+
<PortalProvider>
412+
<Modal open onCancel={mockOnCancel} disableCloseButton />
413+
</PortalProvider>
414+
)
415+
)
416+
expect(screen.getByRole("dialog")).toBeInTheDocument()
417+
expect(screen.getByRole("button", { name: "close" })).toBeDisabled()
418+
})
405419
})

0 commit comments

Comments
 (0)