UNPKG

lucid-ui

Version:

A UI component library from AppNexus.

109 lines (108 loc) 4.36 kB
import _ from 'lodash'; import React from 'react'; import PropTypes from 'react-peek/prop-types'; import { lucidClassNames } from '../../util/style-helpers'; import { getFirst, omitProps } from '../../util/component-types'; import { buildModernHybridComponent } from '../../util/state-management'; import ChevronIcon from '../Icon/ChevronIcon/ChevronIcon'; import Collapsible from '../Collapsible/Collapsible'; import Button from '../Button/Button'; import Panel from '../Panel/Panel'; import * as reducers from '../Expander/Expander.reducers'; const cx = lucidClassNames.bind('&-ExpanderPanel'); const { any, bool, func, node, object, string } = PropTypes; const Header = (_props) => null; Header.displayName = 'ExpanderPanel.Header'; Header.peek = { description: ` Renders a \`<span>\` of content next to the \`ChevronIcon\` in the \`Panel.Header\` `, }; Header.propName = 'Header'; Header.propTypes = { children: node ` Used to identify the purpose of this switch to the user -- can be any renderable content. `, }; class ExpanderPanel extends React.Component { constructor() { super(...arguments); this.handleToggle = (event) => { if (!this.props.isDisabled) { this.props.onToggle(!this.props.isExpanded, { event, props: this.props, }); } }; } render() { const { children, className, isExpanded, isDisabled, hasPadding, onRest, onRestAppliedOnCollapse, style, ...passThroughs } = this.props; const headerChildProps = _.get(getFirst(this.props, ExpanderPanel.Header), 'props'); const cleanedOnRest = (onRestAppliedOnCollapse || isExpanded) ? onRest : undefined; return (React.createElement(Panel, Object.assign({}, omitProps(passThroughs, undefined, _.keys(ExpanderPanel.propTypes), false), { className: cx('&', { '&-is-collapsed': !isExpanded, '&-is-disabled': isDisabled, }, className), style: style, isGutterless: !hasPadding }), React.createElement(Panel.Header, { className: cx('&-header'), onClick: this.handleToggle }, React.createElement(Button, { className: cx('&-icon'), kind: 'invisible', hasOnlyIcon: true }, React.createElement(ChevronIcon, { direction: isExpanded ? 'up' : 'down' })), React.createElement("span", Object.assign({}, headerChildProps))), React.createElement(Collapsible, { isExpanded: isExpanded, className: cx('&-content', { '&-content-is-expanded': isExpanded, }), onRest: cleanedOnRest }, React.createElement("div", { className: cx('&-content-inner') }, children)))); } } ExpanderPanel.displayName = 'ExpanderPanel'; ExpanderPanel.Header = Header; ExpanderPanel.propTypes = { children: node ` Expandable content. `, className: string ` Appended to the component-specific class names set on the root element. `, isExpanded: bool ` Indicates that the component is in the "expanded" state when true and in the "unexpanded" state when false. `, isDisabled: bool ` Indicates that the component is in the "disabled" state when true and in the "enabled" state when false. `, hasPadding: bool ` Controls the presence of padding on the inner content. `, onToggle: func ` Called when the user clicks on the component's header. Signature: \`(isExpanded, { event, props }) => {}\` `, style: object ` Passed through to the root element. `, onRest: func `Optional. The callback that fires when the animation comes to a rest.`, onRestAppliedOnCollapse: bool `Applies on onRest callback when rest state is closed.`, Header: any ` prop alternative to Header child component passed through to the underlying ExpanderPanel `, }; ExpanderPanel.peek = { description: ` This is a container that provides a toggle that controls when the content is shown. `, categories: ['layout'], madeFrom: ['ChevronIcon', 'Expander', 'Panel'], }; ExpanderPanel.defaultProps = { isExpanded: false, onToggle: _.noop, hasPadding: true, isDisabled: false, }; export default buildModernHybridComponent(ExpanderPanel, { reducers }); export { ExpanderPanel as ExpanderPanelDumb };