wix-style-react
Version:
wix-style-react
97 lines • 5.43 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { st, classes } from './ComposerSidebar.st.css';
import { dataHooks } from './constants';
import Box from '../Box';
import ToggleButton from '../ToggleButton';
import Text from '../Text';
/** ComposerSidebar */
class ComposerSidebar extends React.PureComponent {
constructor() {
super(...arguments);
this._renderSection = ({ section: { items, sectionTitle }, showSectionTitles = false, }) => {
const { selectedId, labelPlacement } = this.props;
return (React.createElement(React.Fragment, null,
showSectionTitles ? (React.createElement(Text, { className: classes.title, size: "small", weight: "bold", ellipsis: true }, sectionTitle ?? 'Undefined')) : null,
React.createElement("ul", { role: "menu", "data-hook": "composer-sidebar-items-container", "data-selected-id": selectedId, "data-label-placement": labelPlacement, className: classes.itemsContainer }, items.map(item => this._renderItem(item)))));
};
this._renderSections = sections => {
const { labelPlacement, size } = this.props;
const withSections = sections.length > 1 ||
(sections.length === 1 && sections[0].sectionTitle);
return (React.createElement("div", { role: withSections ? 'menu' : undefined, direction: "vertical", className: st(classes.container, {
withSections,
labelPlacement,
size,
}) }, withSections
? sections.map((section, index) => (React.createElement("div", { key: index, role: "menuitem", className: classes.section }, this._renderSection({ section, showSectionTitles: true }))))
: this._renderSection({ section: sections[0] })));
};
this._separateToSections = items => {
const sectionTitles = Array.from(new Set(items.map(({ sectionTitle }) => sectionTitle ? sectionTitle : undefined)));
const sections = sectionTitles.map(sectionTitle => ({
sectionTitle,
items: items.filter(({ sectionTitle: itemSectionTitle }) => (!sectionTitle && !itemSectionTitle) ||
sectionTitle === itemSectionTitle),
}));
return sections;
};
}
_renderItem(item) {
const { selectedId, labelPlacement, size, onClick, className, labelTooltipProps, } = this.props;
const { label, id, icon, disabled, sectionTitle, ...rest } = item;
const selected = selectedId === id;
const onClickHandler = item.onClick || onClick;
return (React.createElement("li", { role: "menuitem", "data-hook": `composer-sidebar-item-container-${id}`, key: `sidebar-item-${id}`, "data-section-title": sectionTitle, className: st(classes.item, { labelPlacement, size }, className) },
React.createElement(ToggleButton, { ...rest, dataHook: `composer-sidebar-item-${id}`, onClick: e => onClickHandler(e, { id, label }), shape: "round", size: size, border: true, skin: "inverted", labelEllipsis: true, disabled: disabled, selected: selected, labelValue: label, labelPlacement: labelPlacement, tooltipProps: labelTooltipProps }, icon)));
}
render() {
const { items, className, dataHook } = this.props;
const sections = this._separateToSections(items);
return (React.createElement(Box, { height: "100%", maxHeight: "100%", className: className, dataHook: dataHook || dataHooks.composerSidebarContainer }, sections.length ? this._renderSections(sections) : null));
}
}
ComposerSidebar.displayName = 'ComposerSidebar';
ComposerSidebar.propTypes = {
/** Applies a data-hook HTML attribute to be used in the tests */
dataHook: PropTypes.string,
/** Specifies a CSS class name to be appended to the component’s root element */
className: PropTypes.string,
/** Controls the items’ label placement */
labelPlacement: PropTypes.oneOf(['bottom', 'end', 'tooltip']),
/** Controls the items’ label tooltip when labelPlacement is set to tooltip */
labelTooltipProps: PropTypes.object,
/** Sets the size of the component */
size: PropTypes.oneOf(['medium', 'large', 'small']),
/** Defines which item is currently selected */
selectedId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/** Defines an array of items (buttons and labels) to show on the sidebar:
* - `label`: text string next to a button
* - `icon`: icon shown in the toggle button
* - `disabled`: disables the item
* - `onClick`: defines what happens when the item is clicked on
* - `sectionTitle`: defines a section under which each item is placed
*/
items: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
label: PropTypes.string,
icon: PropTypes.node,
disabled: PropTypes.bool,
onClick: PropTypes.func,
sectionTitle: PropTypes.string,
})),
/** Defines a default on click handler for items */
onClick: PropTypes.func,
};
ComposerSidebar.defaultProps = {
labelPlacement: 'end',
selectedId: null,
items: [],
size: 'medium',
onClick: () => { },
labelTooltipProps: {
placement: 'right',
},
};
export default ComposerSidebar;
//# sourceMappingURL=ComposerSidebar.js.map