UNPKG

lucid-ui

Version:

A UI component library from Xandr.

131 lines 4.99 kB
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