UNPKG

@talend/react-components

Version:
310 lines (309 loc) 9.62 kB
import PropTypes from 'prop-types'; import classNames from 'classnames'; import { Panel, Button } from '@talend/react-bootstrap'; import { useTranslation } from 'react-i18next'; import { ButtonIcon } from '@talend/design-system'; import OverlayTrigger from '../OverlayTrigger'; import Action from '../Actions/Action'; import Status from '../Status'; import Tag from '../Tag'; import TooltipTrigger from '../TooltipTrigger'; import css from './CollapsiblePanel.module.scss'; import I18N_DOMAIN_COMPONENTS from '../constants'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const TYPE_STATUS = 'status'; const TYPE_ACTION = 'action'; const TYPE_BADGE = 'badge'; function getActionHandler(func, item) { return function actionHandler(e) { e.stopPropagation(); func(e, item); }; } const displayModes = [TYPE_ACTION, TYPE_BADGE, TYPE_STATUS]; const statusPropTypes = { displayMode: PropTypes.oneOf(displayModes), className: PropTypes.string, ...Status.propTypes }; const actionPropTypes = { displayMode: PropTypes.oneOf(displayModes), className: PropTypes.string, ...Action.propTypes }; const simplePropTypes = { displayMode: PropTypes.oneOf(displayModes), className: PropTypes.string, element: PropTypes.element, label: PropTypes.string, bsStyle: PropTypes.string, tooltipLabel: OverlayTrigger.propTypes.label, tooltipPlacement: OverlayTrigger.propTypes.placement }; function renderHeaderItem({ displayMode, className, ...headerItem }, key) { switch (displayMode) { case TYPE_STATUS: { const { actions, ...restStatus } = headerItem; const statusActions = actions && actions.map(action => ({ ...action, onClick: getActionHandler(action.onClick, headerItem) })); return /*#__PURE__*/_jsx(Status, { actions: statusActions, ...restStatus, className: css[className] }, key); } case TYPE_ACTION: { const { onClick, ...restAction } = headerItem; return /*#__PURE__*/_jsx(Action, { onClick: getActionHandler(onClick, headerItem), className: css[className], ...restAction }, key); } case TYPE_BADGE: { const { label, tooltipLabel, tooltipPlacement, ...rest } = headerItem; return /*#__PURE__*/_jsx(TooltipTrigger, { label: tooltipLabel || label, tooltipPlacement: tooltipPlacement, children: /*#__PURE__*/_jsx(Tag, { ...rest, className: css[className], children: label }) }, key); } default: { const { element, label, tooltipLabel, tooltipPlacement } = headerItem; const labelExist = tooltipLabel || label; if (labelExist) { return /*#__PURE__*/_jsx(TooltipTrigger, { label: labelExist, tooltipPlacement: tooltipPlacement, children: /*#__PURE__*/_jsx("div", { className: css[className], children: element || label }) }, key); } return /*#__PURE__*/_jsx("div", { className: css[className], children: element || label }); } } } renderHeaderItem.propTypes = PropTypes.oneOfType([PropTypes.shape(statusPropTypes), PropTypes.shape(actionPropTypes), PropTypes.shape(simplePropTypes), PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.shape(statusPropTypes), PropTypes.shape(actionPropTypes), PropTypes.shape(simplePropTypes)]))]); function CollapsiblePanelHeader(props) { const { t } = useTranslation(I18N_DOMAIN_COMPONENTS); const { header, content, id, onSelect, onToggle, expanded, dataFeature } = props; const headerColumnClass = `col-${header.length}`; const headerItems = header.map((headerItem, index) => { const isHeaderItemArray = Array.isArray(headerItem); const elements = isHeaderItemArray ? headerItem.map(renderHeaderItem) : renderHeaderItem(headerItem); const selectors = isHeaderItemArray ? classNames(css.group, css[headerColumnClass]) : classNames(css[headerItem.className], css[headerColumnClass]); return /*#__PURE__*/_jsx("div", { className: selectors, children: elements }, index); }); // Panel component needs an array for header props const wrappedHeader = [onSelect ? /*#__PURE__*/_jsx(Button, { className: classNames(css['panel-title']), bsStyle: "link", onClick: onSelect, children: /*#__PURE__*/_jsx("div", { className: classNames(css['panel-title']), children: headerItems }) }, "panel-toggle") : /*#__PURE__*/ /* eslint-disable jsx-a11y/no-static-element-interactions */ // eslint-disable-next-line jsx-a11y/click-events-have-key-events _jsx("div", { className: classNames(css['panel-title']), onClick: onToggle, children: headerItems }, "panel-toggle")]; if (content || props.children) { const caretText = expanded ? t('COLLAPSIBLE_PANEL_COLLAPSE', { defaultValue: 'Collapse panel' }) : t('COLLAPSIBLE_PANEL_EXPAND', { defaultValue: 'Expand panel' }); const defaultCaret = /*#__PURE__*/_jsx(ButtonIcon, { size: "M", "aria-expanded": expanded, className: classNames(css.toggle, 'toggle'), onClick: onToggle, id: id && `${id}__collapse`, type: "button", icon: expanded ? 'chevron-down-stroke' : 'chevron-up-filled', "data-feature": dataFeature, children: caretText }, `collapse_header_${id}`); wrappedHeader.push(defaultCaret); } return /*#__PURE__*/_jsx("div", { className: classNames(css['panel-header-content'], 'panel-header-content'), children: wrappedHeader }); } function getKeyValueContent(content) { return /*#__PURE__*/_jsx("dl", { className: css.content, children: content.map((item, index) => [/*#__PURE__*/_jsx("dt", { className: css.label, children: /*#__PURE__*/_jsx(Tag, { children: item.label }) }, `${index}_label`), /*#__PURE__*/_jsx("dd", { className: css.description, children: item.description }, `${index}_desc`)]) }); } function getTextualContent(content) { return /*#__PURE__*/_jsxs("div", { className: css.content, children: [/*#__PURE__*/_jsx("div", { className: css.head, children: content.head.map((item, index) => { const { label, tooltipPlacement, tooltipLabel, className } = item; return /*#__PURE__*/_jsx(TooltipTrigger, { label: tooltipLabel || label, tooltipPlacement: tooltipPlacement, children: /*#__PURE__*/_jsx("span", { className: className, children: label }) }, index); }) }), /*#__PURE__*/_jsx("div", { className: classNames(css['content-description'], 'content-description'), children: content.description })] }); } function CollapsiblePanel(props) { const { content, id, onToggle, status, expanded, theme, onEntered, onExited } = props; const className = classNames('panel panel-default', css['tc-collapsible-panel'], { [css['default-panel']]: !theme, [css[theme]]: !!theme, [css.open]: expanded, [css[Status.getBsStyleFromStatus(status) || status]]: !!status, status }); let children = null; if (content) { children = Array.isArray(content) ? getKeyValueContent(content) : getTextualContent(content); } return /*#__PURE__*/_jsxs(Panel, { id: id, className: className, expanded: expanded, onToggle: onToggle, children: [/*#__PURE__*/_jsx(Panel.Heading, { children: /*#__PURE__*/_jsx(Panel.Title, { toggle: (content || props.children) && !onToggle, children: /*#__PURE__*/_jsx(CollapsiblePanelHeader, { ...props }) }) }), /*#__PURE__*/_jsx(Panel.Collapse, { onEntered: onEntered, onExited: onExited, children: /*#__PURE__*/_jsxs(Panel.Body, { children: [children, props.children] }) })] }); } CollapsiblePanel.displayName = 'CollapsiblePanel'; if (process.env.NODE_ENV !== 'production') { CollapsiblePanelHeader.propTypes = { /** Content of the panel body * If content is an array a key value content list is rendered * otherwise it is a textual content */ content: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.shape({ label: PropTypes.string, description: PropTypes.string })), PropTypes.shape({ head: PropTypes.arrayOf(PropTypes.shape(simplePropTypes)), description: PropTypes.string })]), /** Expanded state for controlled panel */ expanded: PropTypes.bool, /** Header elements */ header: PropTypes.arrayOf(renderHeaderItem.propTypes).isRequired, id: PropTypes.string.isRequired, /** Header click callback function */ onSelect: PropTypes.func, /** Caret click callback function, needed for controlled panel */ onToggle: PropTypes.func }; CollapsiblePanel.propTypes = { ...CollapsiblePanelHeader.propTypes, /** Apply a status style */ status: PropTypes.string, /** Styling theme to apply */ theme: PropTypes.string }; } CollapsiblePanel.displayModes = { TYPE_STATUS, TYPE_ACTION, TYPE_BADGE }; export default CollapsiblePanel; //# sourceMappingURL=CollapsiblePanel.component.js.map