@talend/react-components
Version:
Set of react components.
310 lines (309 loc) • 9.62 kB
JavaScript
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