Skip to content

Commit

Permalink
Add size prop; deprecate width prop for ModalDialog
Browse files Browse the repository at this point in the history
  • Loading branch information
lyzadanger committed Apr 12, 2023
1 parent aaf1b2c commit 5297be5
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 15 deletions.
26 changes: 21 additions & 5 deletions src/components/feedback/ModalDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ import Overlay from '../layout/Overlay';
import Dialog from './Dialog';
import type { DialogProps } from './Dialog';

type ModalWidth = 'sm' | 'md' | 'lg' | 'custom';

type ComponentProps = {
width?: 'sm' | 'md' | 'lg' | 'custom';
/**
* @deprecated - use `size` instead
*/
width?: ModalWidth;

/**
* Do not close the modal when the Escape key is pressed
Expand All @@ -26,6 +31,11 @@ type ComponentProps = {
* the dialog is closed.
*/
disableRestoreFocus?: boolean;

/**
* Relative size (width) of modal dialog
*/
size?: ModalWidth;
};

export type ModalDialogProps = Omit<
Expand All @@ -39,10 +49,11 @@ export type ModalDialogProps = Omit<
*/
const ModalDialogNext = function ModalDialog({
children,
width = 'md',
disableCloseOnEscape = false,
disableFocusTrap = false,
disableRestoreFocus = false,
size,
width,

classes,
elementRef,
Expand All @@ -54,6 +65,8 @@ const ModalDialogNext = function ModalDialog({

...htmlAndPanelAttributes
}: ModalDialogProps) {
// Prefer `size` prop but support deprecated `width` if present
const modalSize = size ?? width ?? 'md';
const modalRef = useSyncedRef(elementRef);

useTabKeyNavigation(modalRef, { enabled: !disableFocusTrap });
Expand Down Expand Up @@ -83,14 +96,17 @@ const ModalDialogNext = function ModalDialog({
'tall:fixed tall:max-h-[80vh] tall:top-[10vh]',
{
// Max-width rules will ensure actual width never exceeds 90vw
'w-[30rem]': width === 'sm',
'w-[36rem]': width === 'md', // default
'w-[42rem]': width === 'lg',
'w-[30rem]': modalSize === 'sm',
'w-[36rem]': modalSize === 'md', // default
'w-[42rem]': modalSize === 'lg',
// No width classes are added if width is 'custom'
},
classes
)}
elementRef={downcastRef(modalRef)}
// Testing affordance. TODO: Remove once deprecated `width` prop
// no longer supported.
data-modal-size={modalSize}
>
{children}
</Dialog>
Expand Down
43 changes: 43 additions & 0 deletions src/components/feedback/test/ModalDialog-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,47 @@ describe('ModalDialog', () => {
});
});
});

describe('modal size', () => {
function sizedModal(props) {
return mount(
<ModalDialog title="Test modal dialog" {...props}>
This is my dialog
</ModalDialog>
);
}

function modalSize(wrapper) {
return wrapper
.find('Dialog')
.getDOMNode()
.getAttribute('data-modal-size');
}

it('sets a default size if neither `size` nor `width` provided', () => {
const wrapper = mount(
<ModalDialog title="Test modal dialog">This is my dialog</ModalDialog>
);

assert.equal(modalSize(wrapper), 'md');
});

it('sets size from size prop', () => {
const wrapper = sizedModal({ size: 'lg' });

assert.equal(modalSize(wrapper), 'lg');
});

it('accepts deprecated `width` prop to set size', () => {
const wrapper = sizedModal({ width: 'lg' });

assert.equal(modalSize(wrapper), 'lg');
});

it('prefers `size` over `width` to set size', () => {
const wrapper = sizedModal({ size: 'lg', width: 'sm' });

assert.equal(modalSize(wrapper), 'lg');
});
});
});
37 changes: 27 additions & 10 deletions src/pattern-library/components/patterns/feedback/DialogPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,9 @@ export default function DialogPage() {
pressed, but you can disable this behavior by setting the{' '}
<code>disableCloseOnEscape</code> prop.
</Library.ChangelogItem>
<Library.ChangelogItem status="deprecated">
<code>width</code> prop → use <code>size</code> instead
</Library.ChangelogItem>
</Library.Changelog>
</Library.Example>
</Library.Pattern>
Expand Down Expand Up @@ -578,53 +581,57 @@ export default function DialogPage() {
</p>
</Library.Example>

<Library.Example title="width">
<Library.Demo title="width='sm'" withSource>
<Library.Example title="size">
<p>
The <code>size</code> prop establishes the width of the modal
dialog.
</p>
<Library.Demo title="size='sm'" withSource>
<ModalDialog_
buttons={<DialogButtons />}
onClose={() => {}}
title="Small modal"
width="sm"
size="sm"
>
<LoremIpsum size="sm" />
</ModalDialog_>
</Library.Demo>

<Library.Demo title="width='md' (default)" withSource>
<Library.Demo title="size='md' (default)" withSource>
<ModalDialog_
buttons={<DialogButtons />}
onClose={() => {}}
title="Medium-width modal"
width="md"
size="md"
>
<LoremIpsum size="md" />
</ModalDialog_>
</Library.Demo>

<Library.Demo title="width='lg'" withSource>
<Library.Demo title="size='lg'" withSource>
<ModalDialog_
buttons={<DialogButtons />}
onClose={() => {}}
title="Wide modal"
width="lg"
size="lg"
>
<LoremIpsum size="md" />
</ModalDialog_>
</Library.Demo>

<p>
To style your <code>ModalDialog</code> with a custom width, set{' '}
<code>width</code> to <code>{"'custom'"}</code> and provide sizing
<code>size</code> to <code>{"'custom'"}</code> and provide sizing
CSS class(es) via the <code>classes</code> prop.
</p>

<Library.Demo title="width='custom'" withSource>
<Library.Demo title="size='custom'" withSource>
<ModalDialog_
buttons={<DialogButtons />}
classes="w-[40em]"
onClose={() => {}}
title="Custom-width modal"
width="custom"
size="custom"
>
<LoremIpsum size="md" />
</ModalDialog_>
Expand Down Expand Up @@ -665,6 +672,16 @@ export default function DialogPage() {
</Library.Demo>
</Library.Example>

<Library.Example title="width">
<p>
The{' '}
<s>
<code>width</code>
</s>{' '}
prop is deprecated: use <code>size</code> instead.
</p>
</Library.Example>

<Library.Example title="Forwarded Props: Dialog">
<p>
<code>ModalDialog</code> forwards the following props (defaults in
Expand Down

0 comments on commit 5297be5

Please sign in to comment.