lucid-ui
Version:
A UI component library from Xandr.
130 lines • 4.8 kB
JavaScript
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