UNPKG

@talend/react-components

Version:
191 lines (190 loc) 5.74 kB
import { createRef, useEffect, useLayoutEffect, useState } from 'react'; import { withTranslation } from 'react-i18next'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import tokens from '@talend/design-tokens'; import ActionList from '../ActionList'; import Action from '../Actions/Action'; import I18N_DOMAIN_COMPONENTS from '../constants'; import Inject from '../Inject'; import '../translate'; import theme from './SidePanel.module.scss'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const DOCKED_MIN_WIDTH = '3.75rem'; const LARGE_DOCKED_MIN_WIDTH = '4.375rem'; function getInitialWidth(docked, large) { if (docked && large) { return LARGE_DOCKED_MIN_WIDTH; } else if (docked) { return DOCKED_MIN_WIDTH; } return undefined; } /** * This component aims to display links as a menu. * @param {object} props react props * @example const actions = [ { label: 'Preparations', icon: 'fa fa-asterisk', onClick: action('Preparations clicked') }, { label: 'Datasets', icon: 'fa fa-file-excel-o', onClick: action('Datasets clicked') }, { label: 'Favorites', icon: 'fa fa-star', onClick: action('Favorites clicked') } ]; <SidePanel actions={ actions } docked={ isDocked } selected= { selectedItem } onToggleDock={ action('Toggle dock clicked') } onSelect={ action('onItemSelect') } /> * */ function SidePanel({ backgroundIcon, id, selected, onSelect, actions, getComponent, components, docked: dockedProp, reverse, minimised, large, dockable, onToggleDock, t }) { const [dockState, setDockState] = useState(dockedProp); const docked = onToggleDock ? dockedProp : dockState; const [width, setWidth] = useState(() => getInitialWidth(docked, large)); const [animation, setAnimation] = useState(false); const ref = /*#__PURE__*/createRef(); useLayoutEffect(() => { if (docked || minimised) { setWidth(large ? LARGE_DOCKED_MIN_WIDTH : DOCKED_MIN_WIDTH); } else if (ref) { const actionList = ref.current.querySelector('.tc-action-list'); setWidth(actionList.offsetWidth); } }, [ref, docked, minimised, large]); useEffect(() => { // animation is disabled at first to avoid the panel to be animated at first render // when the width is initialized, then we enable animation if (!animation && width) { setAnimation(true); } }, [animation, width]); const onToggle = (...args) => { if (onToggleDock) { onToggleDock(...args); } else { setDockState(!dockState); } }; const injected = Inject.all(getComponent, components); const navCSS = classNames(theme['tc-side-panel'], 'tc-side-panel', { docked, [theme.docked]: docked || minimised, large, [theme.large]: large, reverse, [theme.reverse]: reverse, [theme.animate]: animation }); const listCSS = classNames(theme['tc-side-panel-list'], 'tc-side-panel-list'); const expandLabel = t('SIDEPANEL_EXPAND', { defaultValue: 'Expand menu' }); const collapseTitle = t('SIDEPANEL_COLLAPSE', { defaultValue: 'Collapse menu' }); const toggleButtonTitle = docked ? expandLabel : collapseTitle; const Components = Inject.getAll(getComponent, { Action, ActionList }); return /*#__PURE__*/_jsxs("nav", { id: id, className: navCSS, role: "navigation", ref: ref, style: { width }, children: [backgroundIcon && /*#__PURE__*/_jsx("style", { children: `#${id}::before { content: ''; position: absolute; left: 0; bottom: -50px; height: 19.375rem; width: 19.375rem; background-repeat: no-repeat; opacity: 0.1; background-color: ${tokens.coralColorBrandIcon}; mask-image: url('${backgroundIcon}'); -webkit-mask-image: url('${backgroundIcon}'); }` }), dockable && !minimised && /*#__PURE__*/_jsx("div", { className: classNames(theme['toggle-btn'], 'tc-side-panel-toggle-btn'), children: /*#__PURE__*/_jsx(Components.Action, { id: id && `${id}-toggle-dock`, bsStyle: "link", onClick: onToggle, icon: "talend-opener", "aria-controls": id, label: toggleButtonTitle, tooltipPlacement: "right", hideLabel: true }) }), injected('before-actions'), actions && /*#__PURE__*/_jsx("div", { className: classNames(theme['action-list-container'], 'tc-side-panel-action-list-container'), children: /*#__PURE__*/_jsx(Components.ActionList, { className: listCSS, onSelect: onSelect, selected: selected, actions: actions, reverse: !reverse, id: id, isNav: true }) }), injected('actions')] }); } SidePanel.displayName = 'SidePanel'; SidePanel.defaultProps = { actions: [], reverse: false, large: false, dockable: true, minimised: false }; if (process.env.NODE_ENV !== 'production') { const actionPropType = PropTypes.shape({ id: PropTypes.string, active: PropTypes.bool, icon: PropTypes.string, key: PropTypes.string, label: PropTypes.string, onClick: PropTypes.func }); SidePanel.propTypes = { id: PropTypes.string, backgroundIcon: PropTypes.string, actions: PropTypes.arrayOf(actionPropType), components: PropTypes.object, getComponent: PropTypes.func, onSelect: PropTypes.func, onToggleDock: PropTypes.func, docked: PropTypes.bool, reverse: PropTypes.bool, large: PropTypes.bool, dockable: PropTypes.bool, minimised: PropTypes.bool, selected: actionPropType, t: PropTypes.func }; } export default withTranslation(I18N_DOMAIN_COMPONENTS)(SidePanel); //# sourceMappingURL=SidePanel.component.js.map