UNPKG

now-design-organisms

Version:

Organism components for the Now Design System

126 lines (121 loc) 4.45 kB
import React from 'react'; import PropTypes from 'prop-types'; import AccordionSelectableListContainer from '../AccordionSelectableListContainer'; import { LogoMetalCloud } from 'now-design-atoms'; import './LeftPanel.css'; /** * LeftPanel Organism Component * A reusable left panel navigation organism using AccordionSelectableListContainer * * Props: * - items: array (required) - Array of accordion configurations * - onItemSelect: function (optional) - Enhanced callback when any item is selected * Receives: (itemId, parentAccordionId, selectedItemLabel) * - selectedItem: string (optional) - Selected item ID * - logo: element|component (optional) - Custom logo component or element to replace LogoMetalCloud * - logoSize: object (optional) - Logo dimensions {width, height} (default: {width: 64, height: 32}) * - onLogoClick: function (optional) - Callback when logo is clicked * - contentClassName: string (optional) - Additional CSS classes for content container * - contentStyle: object (optional) - Additional inline styles for content container * - className: string (optional) - Additional CSS classes * - style: object (optional) - Additional inline styles (includes layout, visual, and positioning styles) */ const LeftPanel = ({ items = [], onItemSelect, selectedItem, logo, logoSize = { width: 64, height: 32 }, onLogoClick, contentClassName = '', contentStyle = {}, className = '', style = {} }) => { // Warning for missing or empty items if (!items || items.length === 0) { console.warn('LeftPanel: items is empty or missing. Component may not render properly.'); } const handleItemSelect = itemId => { if (onItemSelect) { // Find the parent accordion for this item const parentAccordion = items.find(accordion => accordion.items.some(item => item.id === itemId)); // Find the selected item details const selectedItemDetails = parentAccordion?.items.find(item => item.id === itemId); // Enhanced callback with essential data only onItemSelect(itemId, parentAccordion?.id || null, selectedItemDetails?.label || null); } }; const handleLogoClick = e => { if (onLogoClick) { onLogoClick(e); } }; // Build content styles const contentStyles = { flex: 1, ...contentStyle }; // Render logo - handle both React elements and components const renderLogo = () => { if (logo) { // If logo is a React element (already rendered), return it as is if (/*#__PURE__*/React.isValidElement(logo)) { return logo; } // If logo is a component function, render it with props if (typeof logo === 'function') { const LogoComponent = logo; return /*#__PURE__*/React.createElement(LogoComponent, logoSize); } } // Default logo return /*#__PURE__*/React.createElement(LogoMetalCloud, logoSize); }; return /*#__PURE__*/React.createElement("div", { className: `left-panel ${className}`, style: style }, /*#__PURE__*/React.createElement("div", { className: "left-panel-logo", style: { cursor: onLogoClick ? 'pointer' : 'default' }, onClick: handleLogoClick }, renderLogo()), /*#__PURE__*/React.createElement("div", { className: `left-panel-content ${contentClassName}`, style: contentStyles }, /*#__PURE__*/React.createElement(AccordionSelectableListContainer, { accordionData: items, onItemSelect: handleItemSelect, defaultSelectedItemId: selectedItem }))); }; LeftPanel.propTypes = { items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired, triggerLabel: PropTypes.string.isRequired, triggerIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), items: PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.string.isRequired, label: PropTypes.string.isRequired, icon: PropTypes.oneOfType([PropTypes.string, PropTypes.element]), disabled: PropTypes.bool })).isRequired })).isRequired, onItemSelect: PropTypes.func, selectedItem: PropTypes.string, logo: PropTypes.oneOfType([PropTypes.element, PropTypes.func]), logoSize: PropTypes.shape({ width: PropTypes.number, height: PropTypes.number }), onLogoClick: PropTypes.func, contentClassName: PropTypes.string, contentStyle: PropTypes.object, className: PropTypes.string, style: PropTypes.object }; export default LeftPanel;