UNPKG

lucid-ui

Version:

A UI component library from Xandr.

130 lines 4.8 kB
import _, { omit } from 'lodash'; import React from 'react'; import PropTypes from 'prop-types'; import { lucidClassNames } from '../../util/style-helpers'; import { getFirst } 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 = { /** Used to identify the purpose of this switch to the user -- can be any renderable content. */ children: node, }; /** TODO: Remove the nonPassThroughs when the component is converted to a functional component */ const nonPassThroughs = [ 'className', 'isExpanded', 'onToggle', 'onRest', 'onRestAppliedOnCollapse', 'Header', 'isDisabled', 'hasPadding', 'initialState', ]; 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, { ...omit(passThroughs, nonPassThroughs), 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", { ...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 = { /** Expandable content. */ children: node, /** Appended to the component-specific class names set on the root element. */ className: string, /** Indicates that the component is in the "expanded" state when true and in the "unexpanded" state when false. */ isExpanded: bool, /** Indicates that the component is in the "disabled" state when true and in the "enabled" state when false. */ isDisabled: bool, /** Controls the presence of padding on the inner content. */ hasPadding: bool, /** Called when the user clicks on the component's header. Signature: \`(isExpanded, { event, props }) => {}\` */ onToggle: func, /** Passed through to the root element. */ style: object, /** Optional. The callback that fires when the animation comes to a rest. */ onRest: func, /* Applies on onRest callback when rest state is closed. */ onRestAppliedOnCollapse: bool, /** prop alternative to Header child component passed through to the underlying ExpanderPanel */ Header: any, }; ExpanderPanel.peek = { description: `An expandable container that provides a toggle that controls when the \`Panel\` 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 }; //# sourceMappingURL=ExpanderPanel.js.map