Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

style(Modal): update typings and propTypes usage #1331

Merged
merged 2 commits into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
})