Skip to content

Commit

Permalink
feat(ComposedModal): support 3 button modals
Browse files Browse the repository at this point in the history
  • Loading branch information
emyarod committed Feb 12, 2021
1 parent 25e5295 commit 8ab38b0
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 16 deletions.
57 changes: 45 additions & 12 deletions packages/react/src/components/ComposedModal/ComposedModal-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
import React, { useState } from 'react';
import ReactDOM from 'react-dom';
import { action } from '@storybook/addon-actions';
import { withKnobs, boolean, select, text } from '@storybook/addon-knobs';
import {
boolean,
object,
optionsKnob as options,
select,
text,
withKnobs,
} from '@storybook/addon-knobs';
import ComposedModal, {
ModalHeader,
ModalBody,
Expand All @@ -28,14 +35,17 @@ const sizes = {
};

const buttons = {
'None (0)': 0,
'One (1)': 1,
'Two (2)': 2,
'None (0)': '0',
'One (1)': '1',
'Two (2)': '2',
'Three (3)': '3',
};

const props = {
composedModal: ({ titleOnly } = {}) => ({
numberOfButtons: select('Number of Buttons', buttons, 2),
numberOfButtons: options('Number of Buttons', buttons, '2', {
display: 'inline-radio',
}),
open: boolean('Open (open in <ComposedModal>)', true),
onKeyDown: action('onKeyDown'),
selectorPrimaryFocus: text(
Expand Down Expand Up @@ -72,6 +82,35 @@ const props = {
'aria-label': text('ARIA label for content', 'Example modal content'),
}),
modalFooter: (numberOfButtons) => {
const secondaryButtons = () => {
switch (numberOfButtons) {
case '2':
return {
secondaryButtonText: text(
'Secondary button text (secondaryButtonText in <ModalFooter>)',
'Secondary button'
),
};
case '3':
return {
secondaryButtons: object(
'Secondary button config array (secondaryButtons)',
[
{
buttonText: 'Keep both',
onClick: action('onClick'),
},
{
buttonText: 'Rename',
onClick: action('onClick'),
},
]
),
};
default:
return null;
}
};
return {
danger: boolean('Primary button danger (danger)', false),
primaryButtonText: text(
Expand All @@ -82,13 +121,7 @@ const props = {
'Primary button disabled (primaryButtonDisabled in <ModalFooter>)',
false
),
secondaryButtonText:
numberOfButtons === 2
? text(
'Secondary button text (secondaryButtonText in <ModalFooter>)',
'Secondary button'
)
: null,
...secondaryButtons(numberOfButtons),
onRequestClose: action('onRequestClose'),
onRequestSubmit: action('onRequestSubmit'),
};
Expand Down
62 changes: 58 additions & 4 deletions packages/react/src/components/ComposedModal/ComposedModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,38 @@ export class ModalFooter extends Component {
*/
secondaryButtonText: PropTypes.string,

/**
* Specify an array of config objects for secondary buttons
*/
secondaryButtons: (props, propName, componentName) => {
if (props.secondaryButtons) {
if (
!Array.isArray(props.secondaryButtons) ||
props.secondaryButtons.length !== 2
) {
return new Error(
`${propName} needs to be an array of two button config objects`
);
}

const shape = {
buttonText: PropTypes.string,
onClick: PropTypes.func,
};

props[propName].forEach((secondaryButton) => {
PropTypes.checkPropTypes(
shape,
secondaryButton,
propName,
componentName
);
});
}

return null;
},

/**
* Specify a custom className to be applied to the secondary button
*/
Expand All @@ -583,6 +615,7 @@ export class ModalFooter extends Component {
const {
className,
primaryClassName,
secondaryButtons,
secondaryClassName,
secondaryButtonText,
primaryButtonText,
Expand All @@ -599,6 +632,8 @@ export class ModalFooter extends Component {
const footerClass = classNames({
[`${prefix}--modal-footer`]: true,
[className]: className,
[`${prefix}--modal-footer--three-button`]:
Array.isArray(secondaryButtons) && secondaryButtons.length === 2,
});

const primaryClass = classNames({
Expand All @@ -609,17 +644,36 @@ export class ModalFooter extends Component {
[secondaryClassName]: secondaryClassName,
});

return (
<ButtonSet className={footerClass} {...other}>
{secondaryButtonText && (
const SecondaryButtonSet = () => {
if (Array.isArray(secondaryButtons) && secondaryButtons.length <= 2) {
return secondaryButtons.map(
({ buttonText, onClick: onButtonClick }, i) => (
<Button
key={`${buttonText}-${i}`}
className={secondaryClass}
kind="secondary"
onClick={onButtonClick || this.handleRequestClose}>
{buttonText}
</Button>
)
);
}
if (secondaryButtonText) {
return (
<Button
className={secondaryClass}
onClick={this.handleRequestClose}
kind="secondary">
{secondaryButtonText}
</Button>
)}
);
}
return null;
};

return (
<ButtonSet className={footerClass} {...other}>
<SecondaryButtonSet />
{primaryButtonText && (
<Button
onClick={onRequestSubmit}
Expand Down

0 comments on commit 8ab38b0

Please sign in to comment.