Skip to content

Commit

Permalink
BREAKING CHANGE(web-react): Remove old Modal and rename ModalComposed…
Browse files Browse the repository at this point in the history
… to Modal #DS-617

 ## Migration Guide

1. **Discontinue the old `Modal` component:** The old `Modal`
component has been entirely removed and is no longer available
for use.

2. **Adopt the new `Modal` in place of `ModalComposed`:** The
`ModalComposed` component has been renamed to `Modal`. Thus,
replace all instances of `ModalComposed` in your codebase with
`Modal`.

3. **Update Component Tags:** Make sure to modify the component
tags in your codebase as outlined below:

   - `<ModalComposed …>` → `<Modal …>`
   - `<ModalComposedBody …>` → `<ModalBody …>`
   - `<ModalComposedDialog …>` → `<ModalDialog …>`
   - `<ModalComposedFooter …>` → `<ModalFooter …>`
   - `<ModalComposedHeader …>` → `<ModalHeader …>`

Please refer back to this guide or reach out to our team
if you encounter any issues during migration.
  • Loading branch information
tomassychra authored and literat committed Jul 21, 2023
1 parent 44a9fd7 commit f323e9b
Show file tree
Hide file tree
Showing 47 changed files with 461 additions and 936 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Icon,
Pill,
Modal,
ModalDialog,
ModalHeader,
ModalBody,
UncontrolledAccordion,
Expand Down Expand Up @@ -32,31 +33,39 @@ export const ModalWithAccordion = () => {
{isOpen ? 'Close' : 'Open'} Modal
</Button>
<Modal id="ModalExample" isOpen={isOpen} onClose={handleClose}>
<ModalHeader>
<Button isSquare color="tertiary" onClick={toggleModal} aria-expanded={isOpen} aria-controls="#ModalExample">
<Icon name="close" />
</Button>
</ModalHeader>
<ModalBody>
<UncontrolledAccordion id="AccordionExample" defaultOpen="AccordionItemExample1">
<AccordionItem id="AccordionItemExample0">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #0</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample1">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #1</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample2">
<AccordionHeader>Accordion Header #2</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample3">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #3</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
</UncontrolledAccordion>
</ModalBody>
<ModalDialog>
<ModalHeader>
<Button
isSquare
color="tertiary"
onClick={toggleModal}
aria-expanded={isOpen}
aria-controls="#ModalExample"
>
<Icon name="close" />
</Button>
</ModalHeader>
<ModalBody>
<UncontrolledAccordion id="AccordionExample" defaultOpen="AccordionItemExample1">
<AccordionItem id="AccordionItemExample0">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #0</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample1">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #1</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample2">
<AccordionHeader>Accordion Header #2</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
<AccordionItem id="AccordionItemExample3">
<AccordionHeader slot={<Pill>3</Pill>}>Accordion Header #3</AccordionHeader>
<AccordionContent>{content}</AccordionContent>
</AccordionItem>
</UncontrolledAccordion>
</ModalBody>
</ModalDialog>
</Modal>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Button, Icon, Modal, ModalHeader, ModalBody, UncontrolledCollapse } from '../../../src/components';
import { Button, Modal, ModalDialog, ModalHeader, ModalBody, UncontrolledCollapse } from '../../../src/components';
import { content } from '../../../src/components/Accordion/stories/Accordion';
import { CollapseTrigger } from '../../../src/components/Collapse/stories/Collapse';

Expand All @@ -22,14 +22,12 @@ export const ModalWithCollapse = () => {
{isOpen ? 'Close' : 'Open'} Modal
</Button>
<Modal id="ModalExample" isOpen={isOpen} onClose={handleClose}>
<ModalHeader>
<Button isSquare color="tertiary" onClick={toggleModal} aria-expanded={isOpen} aria-controls="#ModalExample">
<Icon name="close" />
</Button>
</ModalHeader>
<ModalBody>
<UncontrolledCollapse renderTrigger={CollapseTrigger}>{content}</UncontrolledCollapse>
</ModalBody>
<ModalDialog>
<ModalHeader />
<ModalBody>
<UncontrolledCollapse renderTrigger={CollapseTrigger}>{content}</UncontrolledCollapse>
</ModalBody>
</ModalDialog>
</Modal>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
import React, { useState } from 'react';
import {
Button,
ModalComposed,
ModalComposedDialog,
ModalComposedHeader,
ModalComposedBody,
ModalComposedFooter,
ScrollView,
} from '../../../src/components';
import { Button, Modal, ModalDialog, ModalHeader, ModalBody, ModalFooter, ScrollView } from '../../../src/components';

export default {
title: 'Examples/Compositions',
};

export const ModalComposedWithScrollView = () => {
export const ModalWithScrollView = () => {
const [isOpen, setOpen] = useState(false);

const toggleModalComposed = () => setOpen(!isOpen);
const toggleModal = () => setOpen(!isOpen);

const handleClose = () => {
setOpen(false);
};

return (
<>
<Button onClick={toggleModalComposed} aria-expanded={isOpen} aria-controls="#ModalComposedExample">
{isOpen ? 'Close' : 'Open'} ModalComposed
<Button onClick={toggleModal} aria-expanded={isOpen} aria-controls="#ModalExample">
{isOpen ? 'Close' : 'Open'} Modal
</Button>
<ModalComposed id="ModalExample" isOpen={isOpen} onClose={handleClose}>
<ModalComposedDialog>
<ModalComposedHeader>Modal with ScrollView </ModalComposedHeader>
<Modal id="ModalExample" isOpen={isOpen} onClose={handleClose}>
<ModalDialog>
<ModalHeader>Modal with ScrollView </ModalHeader>
<ScrollView overflowDecorators="borders">
<ModalComposedBody>
<ModalBody>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aliquam at excepturi laudantium magnam
mollitia mollitia perferendis reprehenderit, voluptate. Cum delectus dicta ducimus eligendi excepturi
Expand Down Expand Up @@ -72,18 +64,18 @@ export const ModalComposedWithScrollView = () => {
mollitia perferendis reprehenderit, voluptate. Cum delectus dicta ducimus eligendi excepturi natus
perferendis provident unde. Eveniet, iste, molestiae?
</p>
</ModalComposedBody>
</ModalBody>
</ScrollView>
<ModalComposedFooter>
<ModalFooter>
<Button color="primary" onClick={handleClose}>
Confirm
</Button>
<Button color="tertiary" onClick={handleClose}>
Cancel
</Button>
</ModalComposedFooter>
</ModalComposedDialog>
</ModalComposed>
</ModalFooter>
</ModalDialog>
</Modal>
</>
);
};
1 change: 0 additions & 1 deletion packages/web-react/scripts/entryPoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const entryPoints = [
{ dirs: ['components', 'Icon'] },
{ dirs: ['components', 'Link'] },
{ dirs: ['components', 'Modal'] },
{ dirs: ['components', 'ModalComposed'] },
{ dirs: ['components', 'Pagination'] },
{ dirs: ['components', 'Pill'] },
{ dirs: ['components', 'RadioField'] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default {
} as ComponentMeta<typeof Modal>;

export { default as Modal } from './stories/Modal';
export { default as ModalWithCustomHeight } from './stories/ModalWithCustomHeight';
export { default as ModalWithLongText } from './stories/ModalWithLongText';
export { default as HTML } from './stories/ModalHtml';
export { default as Props } from './stories/ModalProps';
48 changes: 24 additions & 24 deletions packages/web-react/src/components/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import React from 'react';
import classNames from 'classnames';
import { ModalProps } from '../../types';
import { useStyleProps, useLastActiveFocus } from '../../hooks';
import { SpiritModalProps } from '../../types';
import { useModalStyleProps } from './useModalStyleProps';
import { useLastActiveFocus, useStyleProps, useDeprecationMessage } from '../../hooks';
import { ModalProvider } from './ModalContext';
import Dialog from '../Dialog/Dialog';

const Modal = (props: ModalProps): JSX.Element => {
const { children, isOpen, onClose, ...restProps } = props;
const Modal = (props: SpiritModalProps) => {
const { children, isOpen, onClose, id, ...restProps } = props;
const { classProps } = useModalStyleProps();
const { styleProps, props: otherProps } = useStyleProps(restProps);

useLastActiveFocus(isOpen);
const contextValue = {
id,
isOpen,
onClose,
};

useDeprecationMessage({
method: 'component',
trigger: true,
componentName: 'Modal',
componentProps: {
delete: true,
},
});
useLastActiveFocus(isOpen);

return (
<Dialog
{...otherProps}
{...styleProps}
isOpen={isOpen}
onClose={onClose}
className={classNames(classProps.root, styleProps.className)}
>
<div className={classProps.content}>
<div className={classProps.dialog}>{children}</div>
</div>
</Dialog>
<ModalProvider value={contextValue}>
<Dialog
{...otherProps}
{...styleProps}
id={id}
isOpen={isOpen}
onClose={onClose}
className={classNames(classProps.root, styleProps.className)}
aria-labelledby={`${id}__title`}
>
{children}
</Dialog>
</ModalProvider>
);
};

Expand Down
11 changes: 5 additions & 6 deletions packages/web-react/src/components/Modal/ModalBody.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import React from 'react';
import classNames from 'classnames';
import { ModalMemberProps } from '../../types';
import { useModalStyleProps } from './useModalStyleProps';
import { useStyleProps } from '../../hooks';
import { ModalBodyProps } from '../../types';
import { useModalStyleProps } from './useModalStyleProps';

const ModalBody = (props: ModalMemberProps): JSX.Element => {
const { children, elementType: ElementTag = 'div', ...restProps } = props;
const ModalBody = ({ children, ...restProps }: ModalBodyProps) => {
const { classProps } = useModalStyleProps();
const { styleProps, props: otherProps } = useStyleProps(restProps);

return (
<ElementTag {...otherProps} {...styleProps} className={classNames(classProps.body, styleProps.className)}>
<div {...otherProps} {...styleProps} className={classNames(classProps.body, styleProps.className)}>
{children}
</ElementTag>
</div>
);
};

Expand Down
20 changes: 20 additions & 0 deletions packages/web-react/src/components/Modal/ModalContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createContext, useContext } from 'react';
import { ModalDialogHandlingProps } from '../../types';

export type ModalContextProps = {
id: string;
} & ModalDialogHandlingProps;

const defaultContext: ModalContextProps = {
id: '',
isOpen: false,
onClose: () => null,
};

const ModalContext = createContext<ModalContextProps>(defaultContext);
const ModalProvider = ModalContext.Provider;
const ModalConsumer = ModalContext.Consumer;
const useModalContext = (): ModalContextProps => useContext(ModalContext);

export default ModalContext;
export { ModalProvider, ModalConsumer, useModalContext };
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React, { CSSProperties, ElementType, ForwardedRef, forwardRef } from 'react';
import classNames from 'classnames';
import { useStyleProps } from '../../hooks';
import { ModalComposedDialogProps, ModalComposedDialogElementType } from '../../types/modalComposed';
import { useModalComposedStyleProps } from './useModalComposedStyleProps';
import { ModalDialogProps, ModalDialogElementType } from '../../types';
import { useModalStyleProps } from './useModalStyleProps';

interface CustomizedHeightCSSProperties extends CSSProperties {
'--modal-max-height-tablet'?: string;
'--modal-preferred-height-mobile'?: string;
'--modal-preferred-height-tablet'?: string;
}

const ModalComposedDialog = <E extends ElementType = ModalComposedDialogElementType>(
props: ModalComposedDialogProps<E>,
const ModalDialog = <E extends ElementType = ModalDialogElementType>(
props: ModalDialogProps<E>,
ref: ForwardedRef<HTMLDivElement>,
) => {
const {
Expand All @@ -24,7 +24,7 @@ const ModalComposedDialog = <E extends ElementType = ModalComposedDialogElementT
...restProps
} = props;

const { classProps } = useModalComposedStyleProps({ isExpandedOnMobile });
const { classProps } = useModalStyleProps({ isExpandedOnMobile });
const { styleProps, props: otherProps } = useStyleProps(restProps);

const customizedHeightStyle: CustomizedHeightCSSProperties = {
Expand All @@ -50,4 +50,4 @@ const ModalComposedDialog = <E extends ElementType = ModalComposedDialogElementT
);
};

export default forwardRef(ModalComposedDialog);
export default forwardRef(ModalDialog);
28 changes: 20 additions & 8 deletions packages/web-react/src/components/Modal/ModalFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import React from 'react';
import classNames from 'classnames';
import { ModalMemberProps } from '../../types';
import { useStyleProps, useDeprecationMessage } from '../../hooks';
import { ModalFooterProps } from '../../types';
import { useModalStyleProps } from './useModalStyleProps';
import { useStyleProps } from '../../hooks';

const ModalFooter = (props: ModalMemberProps): JSX.Element => {
const { children, elementType: ElementTag = 'div', ...restProps } = props;
const { classProps } = useModalStyleProps();
const ModalFooter = (props: ModalFooterProps) => {
const { children, alignmentX = 'right', align = 'right', description, ...restProps } = props;

const { classProps } = useModalStyleProps({ footerAlignment: alignmentX || align });
const { styleProps, props: otherProps } = useStyleProps(restProps);

useDeprecationMessage({
method: 'property',
trigger: !!align,
componentName: 'ModalFooter',
propertyProps: {
deprecatedName: 'align',
newName: 'alignmentX',
},
});

return (
<ElementTag {...otherProps} {...styleProps} className={classNames(classProps.footer, styleProps.className)}>
{children}
</ElementTag>
<footer {...otherProps} {...styleProps} className={classNames(classProps.footer.root, styleProps.className)}>
{description && <div className={classProps.footer.description}>{description}</div>}
<div className={classProps.footer.actions}>{children}</div>
</footer>
);
};

Expand Down
Loading

0 comments on commit f323e9b

Please sign in to comment.