Skip to content

Commit

Permalink
style(Modal): update typings and propTypes usage (Semantic-Org#1331)
Browse files Browse the repository at this point in the history
  • Loading branch information
layershifter authored and harel committed Feb 18, 2017
1 parent 4ef3bbd commit 6164e51
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 70 deletions.
54 changes: 23 additions & 31 deletions src/modules/Modal/Modal.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import cx from 'classnames'
import _ from 'lodash'
import React, { PropTypes } from 'react'
import cx from 'classnames'

import ModalHeader from './ModalHeader'
import ModalContent from './ModalContent'
import ModalActions from './ModalActions'
import ModalDescription from './ModalDescription'
import Icon from '../../elements/Icon'
import Portal from '../../addons/Portal'

import {
AutoControlledComponent as Component,
Expand All @@ -19,20 +12,17 @@ import {
META,
useKeyOnly,
} from '../../lib'
import Icon from '../../elements/Icon'
import Portal from '../../addons/Portal'
import ModalHeader from './ModalHeader'
import ModalContent from './ModalContent'
import ModalActions from './ModalActions'
import ModalDescription from './ModalDescription'

const debug = makeDebugger('modal')

const _meta = {
name: 'Modal',
type: META.TYPES.MODULE,
props: {
size: ['fullscreen', 'large', 'small'],
dimmer: ['inverted', 'blurring'],
},
}

/**
* A modal displays content that temporarily blocks interactions with the main view of a site
* A modal displays content that temporarily blocks interactions with the main view of a site.
* @see Confirm
* @see Portal
*/
Expand All @@ -50,16 +40,14 @@ class Modal extends Component {
/** Additional classes. */
className: PropTypes.string,

/** Icon */
/** Icon. */
closeIcon: PropTypes.oneOfType([
PropTypes.node,
PropTypes.object,
PropTypes.bool,
]),

/**
* Whether or not the Modal should close when the dimmer is clicked.
*/
/** Whether or not the Modal should close when the dimmer is clicked. */
closeOnDimmerClick: PropTypes.bool,

/** Whether or not the Modal should close when the document is clicked. */
Expand All @@ -68,41 +56,41 @@ class Modal extends Component {
/** Initial value of open. */
defaultOpen: PropTypes.bool,

/** A modal can appear in a dimmer */
/** A modal can appear in a dimmer. */
dimmer: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(_meta.props.dimmer),
PropTypes.oneOf(['inverted', 'blurring']),
]),

/** The node where the modal should mount. Defaults to document.body. */
/** The node where the modal should mount. Defaults to document.body. */
mountNode: PropTypes.any,

/**
* Called when a close event happens
* Called when a close event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onClose: PropTypes.func,

/**
* Called when the portal is mounted on the DOM
* Called when the portal is mounted on the DOM.
*
* @param {null}
* @param {object} data - All props.
*/
onMount: PropTypes.func,

/**
* Called when an open event happens
* Called when an open event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onOpen: PropTypes.func,

/**
* Called when the portal is unmounted from the DOM
* Called when the portal is unmounted from the DOM.
*
* @param {null}
* @param {object} data - All props.
Expand All @@ -113,7 +101,7 @@ class Modal extends Component {
open: PropTypes.bool,

/** A modal can vary in size */
size: PropTypes.oneOf(_meta.props.size),
size: PropTypes.oneOf(['fullscreen', 'large', 'small']),

/**
* NOTE: Any unhandled props that are defined in Portal are passed-through
Expand All @@ -131,7 +119,11 @@ class Modal extends Component {
'open',
]

static _meta = _meta
static _meta = {
name: 'Modal',
type: META.TYPES.MODULE,
}

static Header = ModalHeader
static Content = ModalContent
static Description = ModalDescription
Expand Down
7 changes: 5 additions & 2 deletions src/modules/Modal/ModalActions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropTypes } from 'react'
import cx from 'classnames'
import React, { PropTypes } from 'react'

import {
customPropTypes,
Expand All @@ -8,9 +8,12 @@ import {
META,
} from '../../lib'

/**
* A modal can contain a row of actions.
*/
function ModalActions(props) {
const { children, className } = props
const classes = cx(className, 'actions')
const classes = cx('actions', className)
const rest = getUnhandledProps(ModalActions, props)
const ElementType = getElementType(ModalActions, props)

Expand Down
5 changes: 4 additions & 1 deletion src/modules/Modal/ModalContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import {
useKeyOnly,
} from '../../lib'

/**
* A modal can contain content.
*/
function ModalContent(props) {
const {
children,
Expand Down Expand Up @@ -53,7 +56,7 @@ ModalContent.propTypes = {
/** Shorthand for primary content. */
content: customPropTypes.contentShorthand,

/** A modal can contain image content */
/** A modal can contain image content. */
image: PropTypes.bool,
}

Expand Down
7 changes: 5 additions & 2 deletions src/modules/Modal/ModalDescription.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropTypes } from 'react'
import cx from 'classnames'
import React, { PropTypes } from 'react'

import {
customPropTypes,
Expand All @@ -8,9 +8,12 @@ import {
META,
} from '../../lib'

/**
* A modal can have a header.
*/
function ModalDescription(props) {
const { children, className } = props
const classes = cx(className, 'description')
const classes = cx('description', className)
const rest = getUnhandledProps(ModalDescription, props)
const ElementType = getElementType(ModalDescription, props)

Expand Down
3 changes: 3 additions & 0 deletions src/modules/Modal/ModalHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import {
META,
} from '../../lib'

/**
* A modal can have a header.
*/
function ModalHeader(props) {
const { children, className, content } = props
const classes = cx(className, 'header')
Expand Down
75 changes: 41 additions & 34 deletions src/modules/Modal/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SemanticSIZES } from '../..';
import * as React from 'react';
import {PortalProps} from '../../addons/Portal';

interface ModalProps {
interface ModalProps extends PortalProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;
Expand All @@ -15,75 +16,74 @@ interface ModalProps {
/** Additional classes. */
className?: string;

/** Icon */
closeIcon?:any;
/** Icon. */
closeIcon?: any;

/**
* Whether or not the Modal should close when the dimmer is clicked.
*/
/** Whether or not the Modal should close when the dimmer is clicked. */
closeOnDimmerClick?: boolean;

/** Whether or not the Modal should close when the document is clicked. */
closeOnDocumentClick?: boolean;

/** Initial value of open. */
defaultOpen?:boolean;
defaultOpen?: boolean;

/** A modal can appear in a dimmer */
/** A modal can appear in a dimmer. */
dimmer?: boolean | 'blurring' | 'inverted';

/** The node where the modal should mount. Defaults to document.body. */
mountNode?: any;

/**
* Called when a close event happens
* Called when a close event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onClose?: Function;
onClose?: (event: React.MouseEvent<HTMLElement>, data: ModalProps) => void;

/**
* Called when the portal is mounted on the DOM
* Called when the portal is mounted on the DOM.
*
* @param {null}
* @param {object} data - All props.
*/
onMount?: Function;
onMount?: (nothing: null, data: ModalProps) => void;

/**
* Called when an open event happens
* Called when an open event happens.
*
* @param {SyntheticEvent} event - React's original SyntheticEvent.
* @param {object} data - All props.
*/
onOpen?:Function;
onOpen?: (event: React.MouseEvent<HTMLElement>, data: ModalProps) => void;

/**
* Called when the dropdown is unmounted from the DOM
* Called when the portal is unmounted from the DOM.
*
* @param {null}
* @param {object} data - All props.
*/
onUnmount?: Function;
onUnmount?: (nothing: null, data: ModalProps) => void;

/** Controls whether or not the Modal is displayed. */
open?: boolean;

/** The node where the modal should mount.. */
mountNode?: any;

/** A modal can vary in size */
size?: SemanticSIZES;

/** A modal can vary in size. */
size?: 'fullscreen' | 'large' | 'small';
}

interface ModalClass extends React.ComponentClass<ModalProps> {
Header: typeof ModalHeader;
interface ModalComponent extends React.ComponentClass<ModalProps> {
Actions: typeof ModalActions;
Content: typeof ModalContent;
Description: typeof ModalDescription;
Actions: typeof ModalActions;
Header: typeof ModalHeader;
}

export const Modal: ModalClass;
export const Modal: ModalComponent;

interface ModalHeaderProps {
interface ModalActionsProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;
Expand All @@ -95,9 +95,10 @@ interface ModalHeaderProps {
className?: string;
}

export const ModalHeader: React.ComponentClass<ModalHeaderProps>;
export const ModalActions: React.StatelessComponent<ModalActionsProps>;

interface ModalContentProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;
Expand All @@ -108,13 +109,14 @@ interface ModalContentProps {
/** Additional classes. */
className?: string;

/** A modal can contain image content */
/** A modal can contain image content. */
image?: boolean;
}

export const ModalContent: React.ComponentClass<ModalContentProps>;
export const ModalContent: React.StatelessComponent<ModalContentProps>;

interface ModalDescriptionProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;
Expand All @@ -126,9 +128,10 @@ interface ModalDescriptionProps {
className?: string;
}

export const ModalDescription: React.ComponentClass<ModalDescriptionProps>;
export const ModalDescription: React.StatelessComponent<ModalDescriptionProps>;

interface ModalActionsProps {
interface ModalHeaderProps {
[key: string]: any;

/** An element type to render as (string or function). */
as?: any;
Expand All @@ -138,6 +141,10 @@ interface ModalActionsProps {

/** Additional classes. */
className?: string;

/** Shorthand for primary content. */
content?: React.ReactNode;
}

export const ModalActions: React.ComponentClass<ModalActionsProps>;
export const ModalHeader: React.StatelessComponent<ModalHeaderProps>;

2 changes: 2 additions & 0 deletions test/specs/modules/Modal/ModalContent-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ describe('ModalContent', () => {
common.isConformant(ModalContent)
common.rendersChildren(ModalContent)

common.implementsCreateMethod(ModalContent)

common.propKeyOnlyToClassName(ModalContent, 'image')
})
2 changes: 2 additions & 0 deletions test/specs/modules/Modal/ModalHeader-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ import * as common from 'test/specs/commonTests'
describe('ModalHeader', () => {
common.isConformant(ModalHeader)
common.rendersChildren(ModalHeader)

common.implementsCreateMethod(ModalHeader)
})

0 comments on commit 6164e51

Please sign in to comment.