From 4ea9c949b5e3004ebd518980c0855dbae7590b86 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Tue, 18 Apr 2017 14:35:19 -0700 Subject: [PATCH 1/9] fix(Modal): update actions prop type --- src/modules/Modal/Modal.d.ts | 2 +- src/modules/Modal/Modal.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/Modal/Modal.d.ts b/src/modules/Modal/Modal.d.ts index db5fa71878..5f30c2626b 100644 --- a/src/modules/Modal/Modal.d.ts +++ b/src/modules/Modal/Modal.d.ts @@ -14,7 +14,7 @@ export interface ModalProps extends PortalProps { as?: any; /** A Modal can be passed action buttons via shorthand. */ - actions?: Array; + actions?: any; /** A Modal can reduce its complexity */ basic?: boolean; diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index 3287e50161..26e2d5d9a3 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -34,7 +34,7 @@ class Modal extends Component { as: customPropTypes.as, /** Elements to render as Modal action buttons. */ - actions: PropTypes.arrayOf(customPropTypes.itemShorthand), + actions: customPropTypes.itemShorthand, /** A modal can reduce its complexity */ basic: PropTypes.bool, From 4e3205b47902a8b45f8e5de8ae676125c1f9f187 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Tue, 18 Apr 2017 14:39:10 -0700 Subject: [PATCH 2/9] fix(Modal): update closeIcon prop types --- .../modules/Modal/Variations/ModalExampleCloseIcon.js | 2 +- src/modules/Modal/Modal.js | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/docs/app/Examples/modules/Modal/Variations/ModalExampleCloseIcon.js b/docs/app/Examples/modules/Modal/Variations/ModalExampleCloseIcon.js index bdc2ea3048..89f4737906 100644 --- a/docs/app/Examples/modules/Modal/Variations/ModalExampleCloseIcon.js +++ b/docs/app/Examples/modules/Modal/Variations/ModalExampleCloseIcon.js @@ -2,7 +2,7 @@ import React from 'react' import { Button, Header, Icon, Modal } from 'semantic-ui-react' const ModalExampleCloseIcon = () => ( - Show Modal} closeIcon='close'> + Show Modal} closeIcon>

Your inbox is getting full, would you like us to enable automatic archiving of old messages?

diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index 26e2d5d9a3..3f89a79dc2 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -45,12 +45,8 @@ class Modal extends Component { /** Additional classes. */ className: PropTypes.string, - /** Icon. */ - closeIcon: PropTypes.oneOfType([ - PropTypes.node, - PropTypes.object, - PropTypes.bool, - ]), + /** Shorthand for the close icon. Closes the modal on click. */ + closeIcon: customPropTypes.itemShorthand, /** Whether or not the Modal should close when the dimmer is clicked. */ closeOnDimmerClick: PropTypes.bool, From bbb80ea5e4e0d0658ff34d44dc1ec58281c86a1b Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Tue, 18 Apr 2017 15:27:52 -0700 Subject: [PATCH 3/9] wip --- .../Modal/Types/ModalExampleShorthand.js | 8 ++--- src/modules/Modal/Modal.js | 7 ++--- src/modules/Modal/ModalActions.js | 11 +++---- test/specs/modules/Modal/Modal-test.js | 30 +++++++++---------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js b/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js index a67d8ee0f6..4d03ef93fd 100644 --- a/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js +++ b/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js @@ -4,11 +4,11 @@ import { Button, Modal } from 'semantic-ui-react' const ModalShorthandExample = () => ( Show Modal} - header='Delete Your Account' - content='Are you sure you want to delete your account' + header='Reminder!' + content='Call Benjamin regarding the reports.' actions={[ - { key: 'no', content: 'No', color: 'red', triggerClose: true }, - { key: 'yes', content: 'Yes', color: 'green', triggerClose: true }, + 'Snooze', + { key: 'done', content: 'Done', positive: true }, ]} /> ) diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index 3f89a79dc2..3f262b95ef 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -14,6 +14,7 @@ import { META, useKeyOnly, } from '../../lib' +import Button from '../../elements/Button' import Icon from '../../elements/Icon' import Portal from '../../addons/Portal' import ModalHeader from './ModalHeader' @@ -33,7 +34,7 @@ class Modal extends Component { /** An element type to render as (string or function). */ as: customPropTypes.as, - /** Elements to render as Modal action buttons. */ + /** Shorthand for Modal.Actions. Typically an array of button shorthand. */ actions: customPropTypes.itemShorthand, /** A modal can reduce its complexity */ @@ -149,10 +150,8 @@ class Modal extends Component { handleActionsOverrides = predefinedProps => ({ onActionClick: (e, actionProps) => { - const { triggerClose } = actionProps - _.invoke(predefinedProps, 'onActionClick', e, actionProps) - if (triggerClose) this.handleClose(e) + this.handleClose(e) }, }) diff --git a/src/modules/Modal/ModalActions.js b/src/modules/Modal/ModalActions.js index 1f18269f57..193fbabd7a 100644 --- a/src/modules/Modal/ModalActions.js +++ b/src/modules/Modal/ModalActions.js @@ -21,11 +21,8 @@ export default class ModalActions extends Component { /** An element type to render as (string or function). */ as: customPropTypes.as, - /** Elements to render as Modal action buttons. */ - actions: customPropTypes.every([ - customPropTypes.disallow(['children']), - PropTypes.arrayOf(customPropTypes.itemShorthand), - ]), + /** Array of shorthand buttons. */ + actions: customPropTypes.collectionShorthand, /** Primary content. */ children: PropTypes.node, @@ -34,10 +31,10 @@ export default class ModalActions extends Component { className: PropTypes.string, /** - * onClick handler for an action. Mutually exclusive with children. + * Action onClick handler when using shorthand `actions`. * * @param {SyntheticEvent} event - React's original SyntheticEvent. - * @param {object} data - All item props. + * @param {object} data - All props from the clicked action. */ onActionClick: customPropTypes.every([ customPropTypes.disallow(['children']), diff --git a/test/specs/modules/Modal/Modal-test.js b/test/specs/modules/Modal/Modal-test.js index d151f61b7f..d69129842b 100644 --- a/test/specs/modules/Modal/Modal-test.js +++ b/test/specs/modules/Modal/Modal-test.js @@ -104,30 +104,30 @@ describe('Modal', () => { }) describe('actions', () => { - const actions = [ - { key: 'cancel', content: 'Cancel' }, - { key: 'ok', content: 'OK', triggerClose: true }, - ] + it('closes the modal on action click', () => { + wrapperMount() - it('handles onItemClick', () => { + assertBodyContains('.ui.modal') + domEvent.click('.ui.modal.actions .button') + assertBodyContains('.ui.modal', false) + }) + }) + + describe('onActionClick', () => { + it('is called when an action is clicked', () => { const onActionClick = sandbox.spy() const event = { target: null } - wrapperMount() + wrapperMount( + + + + ) domEvent.click('.button:last-child') onActionClick.should.have.been.calledOnce() onActionClick.should.have.been.calledWithMatch(event, { content: 'OK' }) }) - - it('handles triggerClose prop on an action', () => { - wrapperMount() - - domEvent.click('.button:first-child') - assertBodyContains('.ui.modal') - domEvent.click('.button:last-child') - assertBodyContains('.ui.modal', false) - }) }) describe('open', () => { From 5a713b253648e2705d1e987e13ced129e141716a Mon Sep 17 00:00:00 2001 From: Alexander Fedyashov Date: Tue, 23 May 2017 18:52:11 +0300 Subject: [PATCH 4/9] feat(Modal): add onItemClick prop --- src/modules/Modal/Modal.d.ts | 10 +++++++++- src/modules/Modal/Modal.js | 13 +++++++++++-- test/specs/modules/Modal/Modal-test.js | 15 ++++++--------- test/specs/modules/Modal/ModalActions-test.js | 2 +- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/modules/Modal/Modal.d.ts b/src/modules/Modal/Modal.d.ts index 5f30c2626b..2bf162538f 100644 --- a/src/modules/Modal/Modal.d.ts +++ b/src/modules/Modal/Modal.d.ts @@ -14,7 +14,7 @@ export interface ModalProps extends PortalProps { as?: any; /** A Modal can be passed action buttons via shorthand. */ - actions?: any; + actions?: Array; /** A Modal can reduce its complexity */ basic?: boolean; @@ -49,6 +49,14 @@ export interface ModalProps extends PortalProps { /** The node where the modal should mount. Defaults to document.body. */ mountNode?: any; + /** + * Action onClick handler when using shorthand `actions`. + * + * @param {SyntheticEvent} event - React's original SyntheticEvent. + * @param {object} data - All props. + */ + onActionClick?: (event: React.MouseEvent, data: ModalProps) => void; + /** * Called when a close event happens. * diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index 3f262b95ef..e1f83b3329 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -14,7 +14,6 @@ import { META, useKeyOnly, } from '../../lib' -import Button from '../../elements/Button' import Icon from '../../elements/Icon' import Portal from '../../addons/Portal' import ModalHeader from './ModalHeader' @@ -35,7 +34,7 @@ class Modal extends Component { as: customPropTypes.as, /** Shorthand for Modal.Actions. Typically an array of button shorthand. */ - actions: customPropTypes.itemShorthand, + actions: customPropTypes.collectionShorthand, /** A modal can reduce its complexity */ basic: PropTypes.bool, @@ -73,6 +72,14 @@ class Modal extends Component { /** The node where the modal should mount. Defaults to document.body. */ mountNode: PropTypes.any, + /** + * Action onClick handler when using shorthand `actions`. + * + * @param {SyntheticEvent} event - React's original SyntheticEvent. + * @param {object} data - All props. + */ + onActionClick: PropTypes.func, + /** * Called when a close event happens. * @@ -151,6 +158,8 @@ class Modal extends Component { handleActionsOverrides = predefinedProps => ({ onActionClick: (e, actionProps) => { _.invoke(predefinedProps, 'onActionClick', e, actionProps) + _.invoke(this.props, 'onActionClick', e, this.props) + this.handleClose(e) }, }) diff --git a/test/specs/modules/Modal/Modal-test.js b/test/specs/modules/Modal/Modal-test.js index d69129842b..f68a166620 100644 --- a/test/specs/modules/Modal/Modal-test.js +++ b/test/specs/modules/Modal/Modal-test.js @@ -105,10 +105,10 @@ describe('Modal', () => { describe('actions', () => { it('closes the modal on action click', () => { - wrapperMount() + wrapperMount() assertBodyContains('.ui.modal') - domEvent.click('.ui.modal.actions .button') + domEvent.click('.ui.modal .actions .button') assertBodyContains('.ui.modal', false) }) }) @@ -117,16 +117,13 @@ describe('Modal', () => { it('is called when an action is clicked', () => { const onActionClick = sandbox.spy() const event = { target: null } + const props = { actions: ['OK'], defaultOpen: true, onActionClick } - wrapperMount( - - - - ) + wrapperMount() + domEvent.click('.ui.modal .actions .button') - domEvent.click('.button:last-child') onActionClick.should.have.been.calledOnce() - onActionClick.should.have.been.calledWithMatch(event, { content: 'OK' }) + onActionClick.should.have.been.calledWithMatch(event, props) }) }) diff --git a/test/specs/modules/Modal/ModalActions-test.js b/test/specs/modules/Modal/ModalActions-test.js index caefdb9db6..c9949ca567 100644 --- a/test/specs/modules/Modal/ModalActions-test.js +++ b/test/specs/modules/Modal/ModalActions-test.js @@ -1,6 +1,6 @@ import React from 'react' -import ModalActions from 'src/modules/Modal/ModalActions' +import ModalActions from 'src/modules/Modal/ModalActions' import * as common from 'test/specs/commonTests' import { sandbox } from 'test/utils' From 0d7cbfd764bbff3165b2e99d101a31b579f19e3f Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Sun, 27 Aug 2017 10:15:18 -0700 Subject: [PATCH 5/9] docs(ModalExampleShorthand): fix default export name --- .../app/Examples/modules/Modal/Types/ModalExampleShorthand.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js b/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js index 4d03ef93fd..d2d9c5fbd7 100644 --- a/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js +++ b/docs/app/Examples/modules/Modal/Types/ModalExampleShorthand.js @@ -1,7 +1,7 @@ import React from 'react' import { Button, Modal } from 'semantic-ui-react' -const ModalShorthandExample = () => ( +const ModalExampleShorthand = () => ( Show Modal} header='Reminder!' @@ -13,4 +13,4 @@ const ModalShorthandExample = () => ( /> ) -export default ModalShorthandExample +export default ModalExampleShorthand From bea262842afd48d0450f14618ca73a22c585b832 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Sun, 27 Aug 2017 10:16:02 -0700 Subject: [PATCH 6/9] fix(customPropTypes): allow itemShorthand arrays --- src/lib/customPropTypes.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/lib/customPropTypes.js b/src/lib/customPropTypes.js index 8f0c515c19..1e12d14864 100644 --- a/src/lib/customPropTypes.js +++ b/src/lib/customPropTypes.js @@ -270,6 +270,12 @@ export const itemShorthand = (...args) => every([ PropTypes.oneOfType([ PropTypes.node, PropTypes.object, + PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.node, + PropTypes.object, + ]), + ), ]), ])(...args) From 5ed7d647ca6c957b596a01d64725aa049c75a341 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Sun, 27 Aug 2017 10:19:13 -0700 Subject: [PATCH 7/9] fix(Modal): fix actions shorthand types and tests --- src/modules/Modal/Modal.d.ts | 6 +++--- src/modules/Modal/Modal.js | 2 +- src/modules/Modal/ModalActions.d.ts | 5 +++-- test/specs/modules/Modal/Modal-test.js | 10 ++++++++++ 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/modules/Modal/Modal.d.ts b/src/modules/Modal/Modal.d.ts index 2bf162538f..dcb5d0afab 100644 --- a/src/modules/Modal/Modal.d.ts +++ b/src/modules/Modal/Modal.d.ts @@ -2,7 +2,7 @@ import * as React from 'react'; import { SemanticShorthandItem } from '../..'; import { PortalProps } from '../../addons/Portal'; -import { default as ModalActions } from './ModalActions'; +import { default as ModalActions, ModalActionsProps } from './ModalActions'; import { default as ModalContent, ModalContentProps } from './ModalContent'; import { default as ModalDescription } from './ModalDescription'; import { default as ModalHeader, ModalHeaderProps } from './ModalHeader'; @@ -13,8 +13,8 @@ export interface ModalProps extends PortalProps { /** An element type to render as (string or function). */ as?: any; - /** A Modal can be passed action buttons via shorthand. */ - actions?: Array; + /** Shorthand for Modal.Actions. Typically an array of button shorthand. */ + actions?: SemanticShorthandItem; /** A Modal can reduce its complexity */ basic?: boolean; diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index e1f83b3329..8dd92c410f 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -34,7 +34,7 @@ class Modal extends Component { as: customPropTypes.as, /** Shorthand for Modal.Actions. Typically an array of button shorthand. */ - actions: customPropTypes.collectionShorthand, + actions: customPropTypes.itemShorthand, /** A modal can reduce its complexity */ basic: PropTypes.bool, diff --git a/src/modules/Modal/ModalActions.d.ts b/src/modules/Modal/ModalActions.d.ts index 1277f0c236..cfa894c269 100644 --- a/src/modules/Modal/ModalActions.d.ts +++ b/src/modules/Modal/ModalActions.d.ts @@ -1,5 +1,6 @@ import * as React from 'react'; import { ButtonProps } from '../../elements/Button'; +import { SemanticShorthandCollection } from '../..' export interface ModalActionsProps { [key: string]: any; @@ -7,8 +8,8 @@ export interface ModalActionsProps { /** An element type to render as (string or function). */ as?: any; - /** An element type to render as (string or function). */ - actions?: Array; + /** Array of shorthand buttons. */ + actions?: SemanticShorthandCollection; /** Primary content. */ children?: React.ReactNode; diff --git a/test/specs/modules/Modal/Modal-test.js b/test/specs/modules/Modal/Modal-test.js index f68a166620..f16db4fa1c 100644 --- a/test/specs/modules/Modal/Modal-test.js +++ b/test/specs/modules/Modal/Modal-test.js @@ -111,6 +111,16 @@ describe('Modal', () => { domEvent.click('.ui.modal .actions .button') assertBodyContains('.ui.modal', false) }) + + it('calls shorthand onActionClick callback', () => { + const onActionClick = sandbox.spy() + const modalActions = { onActionClick, actions: [{ key: 'ok', content: 'OK' }] } + wrapperMount() + + onActionClick.should.not.have.been.called() + domEvent.click('.ui.modal .actions .button') + onActionClick.should.have.been.calledOnce() + }) }) describe('onActionClick', () => { From 36b71365c23c44ec6d9756614eee639225041ee4 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Sun, 27 Aug 2017 10:24:44 -0700 Subject: [PATCH 8/9] fix(Modal): fix closeIcon type --- src/modules/Modal/Modal.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modules/Modal/Modal.js b/src/modules/Modal/Modal.js index 8dd92c410f..19745eabed 100644 --- a/src/modules/Modal/Modal.js +++ b/src/modules/Modal/Modal.js @@ -46,7 +46,11 @@ class Modal extends Component { className: PropTypes.string, /** Shorthand for the close icon. Closes the modal on click. */ - closeIcon: customPropTypes.itemShorthand, + closeIcon: PropTypes.oneOfType([ + PropTypes.node, + PropTypes.object, + PropTypes.bool, + ]), /** Whether or not the Modal should close when the dimmer is clicked. */ closeOnDimmerClick: PropTypes.bool, From 169c2cfc3564113bf8c4bccedf7f84d7a751e074 Mon Sep 17 00:00:00 2001 From: Levi Thomason Date: Sun, 27 Aug 2017 10:35:12 -0700 Subject: [PATCH 9/9] typings(ModalActions): run lint fix --- src/modules/Modal/ModalActions.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Modal/ModalActions.d.ts b/src/modules/Modal/ModalActions.d.ts index cfa894c269..5f755f8cb9 100644 --- a/src/modules/Modal/ModalActions.d.ts +++ b/src/modules/Modal/ModalActions.d.ts @@ -1,6 +1,6 @@ import * as React from 'react'; import { ButtonProps } from '../../elements/Button'; -import { SemanticShorthandCollection } from '../..' +import { SemanticShorthandCollection } from '../..'; export interface ModalActionsProps { [key: string]: any;