From 4699a60ab0c7f2c9afce33b43eed5e2273ac2481 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Thu, 16 Jun 2022 16:08:18 -0400 Subject: [PATCH 1/2] chore(Modal): convert examples to TypeScript --- .../src/components/Modal/examples/Modal.md | 472 +----------------- .../components/Modal/examples/ModalBasic.tsx | 37 ++ .../examples/ModalCustomHeaderFooter.tsx | 56 +++ .../Modal/examples/ModalCustomWidth.tsx | 38 ++ .../components/Modal/examples/ModalLarge.tsx | 38 ++ .../components/Modal/examples/ModalMedium.tsx | 38 ++ .../Modal/examples/ModalNoHeader.tsx | 40 ++ .../components/Modal/examples/ModalSmall.tsx | 38 ++ .../Modal/examples/ModalTopAligned.tsx | 38 ++ .../Modal/examples/ModalWithDescription.tsx | 38 ++ .../Modal/examples/ModalWithForm.tsx | 16 +- 11 files changed, 376 insertions(+), 473 deletions(-) create mode 100644 packages/react-core/src/components/Modal/examples/ModalBasic.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalCustomWidth.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalLarge.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalMedium.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalSmall.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalTopAligned.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalWithDescription.tsx diff --git a/packages/react-core/src/components/Modal/examples/Modal.md b/packages/react-core/src/components/Modal/examples/Modal.md index e4e167d8fbd..e39519f44f4 100644 --- a/packages/react-core/src/components/Modal/examples/Modal.md +++ b/packages/react-core/src/components/Modal/examples/Modal.md @@ -15,496 +15,47 @@ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; ### Basic -```js -import React from 'react'; -import { Modal, Button } from '@patternfly/react-core'; - -class SimpleModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalBasic.tsx" ``` ### With description -```js -import React from 'react'; -import { Modal, Button } from '@patternfly/react-core'; - -class SimpleModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalWithDescription.tsx" ``` ### Top aligned -```js -import React from 'react'; -import { Modal, ModalVariant, Button } from '@patternfly/react-core'; - -class TopModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalTopAligned.tsx" ``` ### Small -```js -import React from 'react'; -import { Modal, ModalVariant, Button } from '@patternfly/react-core'; - -class SmallModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalSmall.tsx" ``` ### Medium -```js -import React from 'react'; -import { Modal, ModalVariant, Button } from '@patternfly/react-core'; - -class MediumModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalMedium.tsx" ``` ### Large -```js -import React from 'react'; -import { Modal, ModalVariant, Button } from '@patternfly/react-core'; - -class LargeModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalLarge.tsx" ``` -### Width - -```js -import React from 'react'; -import { Modal, Button } from '@patternfly/react-core'; +### Custom width -class WidthModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - Confirm - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. - - - ); - } -} +```ts file="./ModalCustomWidth.tsx" ``` ### Custom header and footer -```js -import React from 'react'; -import { Modal, ModalVariant, Button, Title, TitleSizes } from '@patternfly/react-core'; -import WarningTriangleIcon from '@patternfly/react-icons/dist/esm/icons/warning-triangle-icon'; - -class CustomHeaderFooter extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - const header = ( - - - With custom modal header/footer - -

Allows for custom content in the header and/or footer by passing components.

-
- ); - - const footer = ( - - <WarningTriangleIcon /> - <span className="pf-u-pl-sm">Custom modal footer.</span> - - ); - - return ( - - - - - When static text describing the modal is available, it can be wrapped with an ID referring to the modal's - aria-describedby value. - -
-
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis - aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint - occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
-
- ); - } -} +```ts file="./ModalCustomHeaderFooter.tsx" ``` ### No header -```js -import React from 'react'; -import { Modal, ModalVariant, Button } from '@patternfly/react-core'; - -class NoHeader extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - const footer = Modal Footer; - - return ( - - - - - When static text describing the modal is available, it can be wrapped with an ID referring to the modal's - aria-describedby value. - -
-
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis - aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint - occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
-
- ); - } -} +```ts file="./ModalNoHeader.tsx" ``` ### Custom Icon @@ -867,12 +418,11 @@ class HelpModal extends React.Component { ### With form ```ts file="ModalWithForm.tsx" - ``` ### With overflowing content -If the content that you're passing to the modal is likely to overflow the modal content area, pass tabIndex={0} to the modal to enable keyboard accessible scrolling. +If the content that you're passing to the modal is likely to overflow the modal content area, pass `tabIndex={0}` to the modal to enable keyboard accessible scrolling. ```ts file="ModalWithOverflowingContent.tsx" ``` diff --git a/packages/react-core/src/components/Modal/examples/ModalBasic.tsx b/packages/react-core/src/components/Modal/examples/ModalBasic.tsx new file mode 100644 index 00000000000..3f584aff168 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalBasic.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; + +export const ModalBasic: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx b/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx new file mode 100644 index 00000000000..e3730cd2068 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { Modal, ModalVariant, Button, Title, TitleSizes } from '@patternfly/react-core'; +import WarningTriangleIcon from '@patternfly/react-icons/dist/esm/icons/warning-triangle-icon'; + +export const ModalCustomHeaderFooter: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + const header = ( + + + Custom header/footer modal + +

Allows for custom content in the header and/or footer by passing components.

+
+ ); + + const footer = ( + + <WarningTriangleIcon /> + <span className="pf-u-pl-sm">Custom modal footer.</span> + + ); + + return ( + + + + + When static text describing the modal is available outside of the modal header, it can be wrapped with an ID + referring to the modal's aria-describedby value. + +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. +
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalCustomWidth.tsx b/packages/react-core/src/components/Modal/examples/ModalCustomWidth.tsx new file mode 100644 index 00000000000..1b554587039 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalCustomWidth.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; + +export const ModalCustomWidth: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalLarge.tsx b/packages/react-core/src/components/Modal/examples/ModalLarge.tsx new file mode 100644 index 00000000000..624642c829a --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalLarge.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, ModalVariant, Button } from '@patternfly/react-core'; + +export const ModalLarge: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalMedium.tsx b/packages/react-core/src/components/Modal/examples/ModalMedium.tsx new file mode 100644 index 00000000000..b2a96d61fcb --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalMedium.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, ModalVariant, Button } from '@patternfly/react-core'; + +export const ModalMedium: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx b/packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx new file mode 100644 index 00000000000..556c6e45235 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Modal, ModalVariant, Button } from '@patternfly/react-core'; + +export const ModalNoHeader: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + const footer = Modal Footer; + + return ( + + + + + When static text describing the modal is available outside of the modal header, it can be wrapped with an ID + referring to the modal's aria-describedby value. + +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. +
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalSmall.tsx b/packages/react-core/src/components/Modal/examples/ModalSmall.tsx new file mode 100644 index 00000000000..0005e0ea141 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalSmall.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, ModalVariant, Button } from '@patternfly/react-core'; + +export const ModalSmall: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalTopAligned.tsx b/packages/react-core/src/components/Modal/examples/ModalTopAligned.tsx new file mode 100644 index 00000000000..1ff515a137b --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalTopAligned.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; + +export const ModalTopAligned: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalWithDescription.tsx b/packages/react-core/src/components/Modal/examples/ModalWithDescription.tsx new file mode 100644 index 00000000000..fb40d7e53c9 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalWithDescription.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; + +export const ModalWithDescription: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. + + + ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalWithForm.tsx b/packages/react-core/src/components/Modal/examples/ModalWithForm.tsx index 06ce3e45a24..6b2554fb552 100644 --- a/packages/react-core/src/components/Modal/examples/ModalWithForm.tsx +++ b/packages/react-core/src/components/Modal/examples/ModalWithForm.tsx @@ -7,33 +7,26 @@ export const ModalWithForm: React.FunctionComponent = () => { const [nameValue, setNameValue] = React.useState(''); const [emailValue, setEmailValue] = React.useState(''); const [addressValue, setAddressValue] = React.useState(''); - const nameInputRef = React.useRef(); const handleModalToggle = () => { setModalOpen(!isModalOpen); }; - const handleNameInputChange = value => { + const handleNameInputChange = (value: string) => { setNameValue(value); }; - const handleEmailInputChange = value => { + const handleEmailInputChange = (value: string) => { setEmailValue(value); }; - const handleAddressInputChange = value => { + const handleAddressInputChange = (value: string) => { setAddressValue(value); }; - React.useEffect(() => { - if (isModalOpen && nameInputRef && nameInputRef.current) { - (nameInputRef.current as HTMLInputElement).focus(); - } - }, [isModalOpen]); - return ( { name="modal-with-form-form-name" value={nameValue} onChange={handleNameInputChange} - ref={nameInputRef} /> Date: Fri, 17 Jun 2022 10:25:24 -0400 Subject: [PATCH 2/2] Convert remaining examples --- .../src/components/Modal/examples/Modal.md | 352 +----------------- .../examples/ModalCustomHeaderFooter.tsx | 4 +- .../Modal/examples/ModalCustomTitleIcon.tsx | 46 +++ ...alNoHeader.tsx => ModalNoHeaderFooter.tsx} | 13 +- .../Modal/examples/ModalTitleIcon.tsx | 45 +++ .../Modal/examples/ModalWithDropdown.tsx | 97 +++++ .../Modal/examples/ModalWithHelp.tsx | 54 +++ .../Modal/examples/ModalWithWizard.tsx | 45 +++ 8 files changed, 304 insertions(+), 352 deletions(-) create mode 100644 packages/react-core/src/components/Modal/examples/ModalCustomTitleIcon.tsx rename packages/react-core/src/components/Modal/examples/{ModalNoHeader.tsx => ModalNoHeaderFooter.tsx} (79%) create mode 100644 packages/react-core/src/components/Modal/examples/ModalTitleIcon.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalWithDropdown.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalWithHelp.tsx create mode 100644 packages/react-core/src/components/Modal/examples/ModalWithWizard.tsx diff --git a/packages/react-core/src/components/Modal/examples/Modal.md b/packages/react-core/src/components/Modal/examples/Modal.md index e39519f44f4..5b293073272 100644 --- a/packages/react-core/src/components/Modal/examples/Modal.md +++ b/packages/react-core/src/components/Modal/examples/Modal.md @@ -53,366 +53,34 @@ import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; ```ts file="./ModalCustomHeaderFooter.tsx" ``` -### No header +### No header or footer -```ts file="./ModalNoHeader.tsx" +```ts file="./ModalNoHeaderFooter.tsx" ``` -### Custom Icon +### Title icon -```js -import React from 'react'; -import { Modal, Button } from '@patternfly/react-core'; -import BullhornIcon from '@patternfly/react-icons/dist/esm/icons/bullhorn-icon'; - -class NoHeader extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - - When static text describing the modal is available, it can be wrapped with an ID referring to the modal's - aria-describedby value. - -
-
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis - aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint - occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
-
- ); - } -} +```ts file="./ModalTitleIcon.tsx" ``` -### Warning Alert - -```js -import React from 'react'; -import { Modal, Button } from '@patternfly/react-core'; - -class NoHeader extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - - - When static text describing the modal is available, it can be wrapped with an ID referring to the modal's - aria-describedby value. - -
-
- Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis - aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint - occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -
-
- ); - } -} +### Custom title icon + +```ts file="./ModalCustomTitleIcon.tsx" ``` ### With wizard -```js -import React from 'react'; -import { Modal, Button, Wizard } from '@patternfly/react-core'; - -class WithWizard extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - const steps = [ - { name: 'Step 1', component:

Step 1

}, - { name: 'Step 2', component:

Step 2

}, - { name: 'Step 3', component:

Step 3

}, - { name: 'Step 4', component:

Step 4

}, - { name: 'Review', component:

Review Step

, nextButtonText: 'Finish' } - ]; - - return ( - - - - - - - ); - } -} +```ts file="./ModalWithWizard.tsx" ``` ### With dropdown -```js -import React from 'react'; -import { Modal, Button, Dropdown, DropdownToggle, DropdownItem, KebabToggle } from '@patternfly/react-core'; -import CaretDownIcon from '@patternfly/react-icons/dist/esm/icons/caret-down-icon'; - -class WithDropdown extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false, - isDropdownOpen: false - }; - this.handleModalToggle = () => { - const { isModalOpen } = this.state; - this.setState({ - isModalOpen: !isModalOpen, - isDropdownOpen: false - }); - }; - this.onToggle = isDropdownOpen => { - this.setState({ - isDropdownOpen - }); - }; - this.onSelect = event => { - this.setState({ - isDropdownOpen: !this.state.isDropdownOpen - }); - this.onFocus(); - }; - this.onFocus = () => { - const element = document.getElementById('toggle-id-menu-document-body'); - element.focus(); - }; - this.onEscapePress = () => { - const { isDropdownOpen } = this.state; - if (isDropdownOpen) { - this.setState( - { - isDropdownOpen: !isDropdownOpen - }, - () => { - this.onFocus(); - } - ); - } else { - this.handleModalToggle(); - } - }; - } - - render() { - const { isModalOpen, isDropdownOpen } = this.state; - - const dropdownItems = [ - Link, - - Action - , - - Disabled Link - , - - Disabled Action - , - Separated Link, - - Separated Action - - ]; - - return ( - - - - Confirm - , - - ]} - onEscapePress={this.onEscapePress} - > -
- Set the dropdown menuAppendTo prop to parent in order to allow the dropdown menu - break out of the modal container. You'll also want to handle closing of the modal yourself, by listening to - the onEscapePress callback on the Modal component, so you can close the Dropdown first if - it's open. -
-
- - Dropdown with a menu that can break out - - } - isOpen={isDropdownOpen} - dropdownItems={dropdownItems} - menuAppendTo="parent" - /> -
-
-
- ); - } -} +```ts file="./ModalWithDropdown.tsx" ``` ### With help -```js -import React from 'react'; -import { Modal, Button, Popover } from '@patternfly/react-core'; -import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; - -class HelpModal extends React.Component { - constructor(props) { - super(props); - this.state = { - isModalOpen: false - }; - this.handleModalToggle = () => { - this.setState(({ isModalOpen }) => ({ - isModalOpen: !isModalOpen - })); - }; - } - - render() { - const { isModalOpen } = this.state; - - return ( - - - Help Popover} - bodyContent={ -
- Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla - turpis. -
- } - footerContent="Popover Footer" - > - - - } - isOpen={isModalOpen} - onClose={this.handleModalToggle} - actions={[ - , - - ]} - > - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore - magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id - est laborum. -
-
- ); - } -} +```ts file="./ModalWithHelp.tsx" ``` ### With form diff --git a/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx b/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx index e3730cd2068..d222df5d3c6 100644 --- a/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx +++ b/packages/react-core/src/components/Modal/examples/ModalCustomHeaderFooter.tsx @@ -40,8 +40,8 @@ export const ModalCustomHeaderFooter: React.FunctionComponent = () => { footer={footer} > - When static text describing the modal is available outside of the modal header, it can be wrapped with an ID - referring to the modal's aria-describedby value. + When static text describing the modal is available outside of the modal header, it can be given an ID that is + then passed in as the modal's aria-describedby value.

diff --git a/packages/react-core/src/components/Modal/examples/ModalCustomTitleIcon.tsx b/packages/react-core/src/components/Modal/examples/ModalCustomTitleIcon.tsx new file mode 100644 index 00000000000..1d1784da2d7 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalCustomTitleIcon.tsx @@ -0,0 +1,46 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; +import BullhornIcon from '@patternfly/react-icons/dist/esm/icons/bullhorn-icon'; + +export const ModalCustomTitleIcon: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + + When static text describing the modal is available outside of the modal header, it can be given an ID that is + then passed in as the modal's aria-describedby value. + +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. +
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx b/packages/react-core/src/components/Modal/examples/ModalNoHeaderFooter.tsx similarity index 79% rename from packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx rename to packages/react-core/src/components/Modal/examples/ModalNoHeaderFooter.tsx index 556c6e45235..f82b2df4e35 100644 --- a/packages/react-core/src/components/Modal/examples/ModalNoHeader.tsx +++ b/packages/react-core/src/components/Modal/examples/ModalNoHeaderFooter.tsx @@ -1,31 +1,28 @@ import React from 'react'; import { Modal, ModalVariant, Button } from '@patternfly/react-core'; -export const ModalNoHeader: React.FunctionComponent = () => { +export const ModalNoHeaderFooter: React.FunctionComponent = () => { const [isModalOpen, setIsModalOpen] = React.useState(false); const handleModalToggle = () => { setIsModalOpen(!isModalOpen); }; - const footer = Modal Footer; - return ( - When static text describing the modal is available outside of the modal header, it can be wrapped with an ID - referring to the modal's aria-describedby value. + When static text describing the modal is available outside of the modal header, it can be given an ID that is + then passed in as the modal's aria-describedby value.

diff --git a/packages/react-core/src/components/Modal/examples/ModalTitleIcon.tsx b/packages/react-core/src/components/Modal/examples/ModalTitleIcon.tsx new file mode 100644 index 00000000000..43026d48c0e --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalTitleIcon.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Modal, Button } from '@patternfly/react-core'; + +export const ModalTitleIcon: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + + Confirm + , + + ]} + > + + When static text describing the modal is available outside of the modal header, it can be given an ID that is + then passed in as the modal's aria-describedby value. + +
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. +
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalWithDropdown.tsx b/packages/react-core/src/components/Modal/examples/ModalWithDropdown.tsx new file mode 100644 index 00000000000..614377231c5 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalWithDropdown.tsx @@ -0,0 +1,97 @@ +import React from 'react'; +import { Modal, ModalVariant, Button, Dropdown, DropdownToggle, DropdownItem } from '@patternfly/react-core'; +import CaretDownIcon from '@patternfly/react-icons/dist/esm/icons/caret-down-icon'; + +export const ModalWithDropdown: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + const [isDropdownOpen, setIsDropdownOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + setIsDropdownOpen(false); + }; + + const handleDropdownToggle = (isDropdownOpen: boolean) => { + setIsDropdownOpen(isDropdownOpen); + }; + + const onSelect = () => { + setIsDropdownOpen(!isDropdownOpen); + onFocus(); + }; + + const onFocus = () => { + const element = document.getElementById('modal-dropdown-toggle'); + (element as HTMLElement).focus(); + }; + + const onEscapePress = () => { + if (isDropdownOpen) { + setIsDropdownOpen(!isDropdownOpen); + onFocus(); + } else { + handleModalToggle(); + } + }; + + const dropdownItems = [ + Link, + + Action + , + + Disabled Link + , + + Disabled Action + + ]; + + return ( + + + + Confirm + , + + ]} + onEscapePress={onEscapePress} + > +
+ Set the dropdown menuAppendTo prop to parent in order to allow the dropdown menu + break out of the modal container. You'll also want to handle closing of the modal yourself, by listening to + the onEscapePress callback on the Modal component, so you can close the Dropdown first if + it's open without closing the entire modal. +
+
+
+ + Dropdown with a menu that can break out + + } + isOpen={isDropdownOpen} + dropdownItems={dropdownItems} + menuAppendTo="parent" + /> +
+
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalWithHelp.tsx b/packages/react-core/src/components/Modal/examples/ModalWithHelp.tsx new file mode 100644 index 00000000000..f28c07b6af9 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalWithHelp.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { Modal, Button, Popover } from '@patternfly/react-core'; +import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; + +export const ModalWithHelp: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + return ( + + + Help Popover} + bodyContent={ +
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis. +
+ } + footerContent="Popover Footer" + > + + + } + isOpen={isModalOpen} + onClose={handleModalToggle} + actions={[ + , + + ]} + > + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore + magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo + consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + laborum. +
+
+ ); +}; diff --git a/packages/react-core/src/components/Modal/examples/ModalWithWizard.tsx b/packages/react-core/src/components/Modal/examples/ModalWithWizard.tsx new file mode 100644 index 00000000000..49521fa3410 --- /dev/null +++ b/packages/react-core/src/components/Modal/examples/ModalWithWizard.tsx @@ -0,0 +1,45 @@ +import React from 'react'; +import { Modal, ModalVariant, Button, Wizard } from '@patternfly/react-core'; + +export const ModalWithWizard: React.FunctionComponent = () => { + const [isModalOpen, setIsModalOpen] = React.useState(false); + + const handleModalToggle = () => { + setIsModalOpen(!isModalOpen); + }; + + const steps = [ + { name: 'Step 1', component:

Step 1

}, + { name: 'Step 2', component:

Step 2

}, + { name: 'Step 3', component:

Step 3

}, + { name: 'Step 4', component:

Step 4

}, + { name: 'Review', component:

Review Step

, nextButtonText: 'Finish' } + ]; + + return ( + + + + + + + ); +};