lucid-ui
Version:
A UI component library from Xandr.
131 lines • 4.99 kB
JavaScript
import _, { omit } from 'lodash';
import React from 'react';
import PropTypes from 'prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { findTypes } from '../../util/component-types';
import { buildModernHybridComponent } from '../../util/state-management';
import ChevronIcon from '../Icon/ChevronIcon/ChevronIcon';
import Collapsible from '../Collapsible/Collapsible';
import * as reducers from './Expander.reducers';
import Button from '../Button/Button';
const cx = lucidClassNames.bind('&-Expander');
const { any, bool, func, node, object, oneOf, string } = PropTypes;
const Label = (_props) => null;
Label.displayName = 'Expander.Label';
Label.peek = {
description: `Renders a \`<span>\` to be shown next to the \`ExpanderIcon\`.`,
};
Label.propName = 'Label';
Label.propTypes = {
/**
Used to identify the purpose of this switch to the user -- can be any
renderable content.
*/
children: node,
};
const AdditionalLabelContent = (_props) => null;
AdditionalLabelContent.displayName = 'Expander.AdditionalLabelContent';
AdditionalLabelContent.peek = {
description: `Renders a \`<span>\` to be shown next to the expander label.`,
};
AdditionalLabelContent.propName = 'AdditionalLabelContent';
AdditionalLabelContent.propTypes = {
/**
Used to display additional information or/and actions next to expander label.
*/
children: node,
};
const nonPassThroughs = [
'isExpanded',
'onToggle',
'style',
'Label',
'AdditionalLabelContent',
'kind',
'initialState',
'callbackId',
];
const defaultProps = {
isExpanded: false,
onToggle: _.noop,
kind: 'simple',
};
class Expander extends React.Component {
constructor() {
super(...arguments);
this.handleToggle = (event) => {
this.props.onToggle(!this.props.isExpanded, {
event,
props: this.props,
});
};
}
render() {
const { children, className, isExpanded, style, kind, ...passThroughs } = this.props;
const labelChildProp = _.first(_.map(findTypes(this.props, Expander.Label), 'props'));
const additionalLabelContentChildProp = _.first(_.map(findTypes(this.props, Expander.AdditionalLabelContent), 'props'));
return (React.createElement("div", { ...omit(passThroughs, nonPassThroughs), className: cx('&', {
'&-is-expanded': isExpanded,
'&-kind-highlighted': kind === 'highlighted',
}, className), style: style },
React.createElement("header", { className: cx('&-header') },
React.createElement("div", { className: cx('&-header-toggle'), onClick: this.handleToggle },
React.createElement(Button, { className: cx('&-icon'), kind: 'invisible', hasOnlyIcon: true },
React.createElement(ChevronIcon, { direction: isExpanded ? 'up' : 'down' })),
labelChildProp && (React.createElement("span", { className: cx('&-text') }, labelChildProp.children))),
additionalLabelContentChildProp && (React.createElement("div", { className: cx('&-additional-content') }, additionalLabelContentChildProp.children))),
React.createElement(Collapsible, { isExpanded: isExpanded, rootType: 'section', className: cx('&-content') }, children)));
}
}
Expander.displayName = 'Expander';
Expander.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,
/**
Called when the user clicks on the component's header. Signature:
\`(isExpanded, { event, props }) => {}\`
*/
onToggle: func,
/**
Passed through to the root element.
*/
style: object,
/**
Child element whose children represents content to be shown next to the
expander icon.
*/
Label: any,
/**
Child element whose children respresent content to be shown inside
Expander.Label and to the right of it
*/
AdditionalLabelContent: node,
/**
Renders different variants of Expander. 'simple' is default.
'highlighted' is more prominant.
*/
kind: oneOf(['simple', 'highlighted']),
};
Expander.defaultProps = defaultProps;
Expander.reducers = reducers;
Expander.Label = Label;
Expander.AdditionalLabelContent = AdditionalLabelContent;
Expander.peek = {
description: `\`Expander\` is a container that provides a toggle that controls when the \`Panel\` content is shown.`,
categories: ['layout'],
madeFrom: ['ChevronIcon'],
};
export default buildModernHybridComponent(Expander, { reducers });
export { Expander as ExpanderDumb };
//# sourceMappingURL=Expander.js.map