now-design-organisms
Version:
Organism components for the Now Design System
376 lines (299 loc) • 9.65 kB
Markdown
# LeftPanel Organism Component
A reusable left panel navigation organism component that provides a consistent layout for filtering and navigation using the AccordionSelectableListContainer from the molecules package.
## Overview
The `LeftPanel` component is an organism-level component that combines:
- **Logo Section**: Centered METAL Cloud logo
- **Accordion Navigation**: Using AccordionSelectableListContainer for complex navigation
- **Responsive Design**: Adapts to different screen sizes
- **Theme Support**: Supports light/dark theme switching
- **Accessibility**: Proper focus states and keyboard navigation
## Features
- ✅ **Organism-Level Component**: Reusable across different applications
- ✅ **Clean API**: Minimal props focused on functionality
- ✅ **Flexible Styling**: All layout and visual properties via `style` prop
- ✅ **Responsive Design**: Mobile-first approach with breakpoints
- ✅ **Theme Integration**: Uses design tokens for consistent theming
- ✅ **Accessibility**: Proper focus states and semantic markup
- ✅ **TypeScript Ready**: Full PropTypes validation
- ✅ **Customizable**: Flexible props for different use cases
- ✅ **Developer Friendly**: Helpful warnings for missing data
## Installation
```bash
npm install now-design-organisms
```
## Usage
### Basic Usage
```jsx
import { LeftPanel } from 'now-design-organisms';
import { SystemAddFill, MetalcloudMeltingFurnaceLine } from 'now-design-icons';
const items = [
{
id: 'accordion-1',
triggerLabel: 'ChargeMix',
triggerIcon: MetalcloudMeltingFurnaceLine,
items: [
{ id: 'charge-mix-item-1', label: 'Charge Mix Item 1', icon: SystemAddFill },
{ id: 'charge-mix-item-2', label: 'Charge Mix Item 2', icon: SystemAddFill },
]
},
// ... more accordions
];
function App() {
const handleItemSelect = (itemId) => {
console.log('Selected:', itemId);
};
return (
<LeftPanel
items={items}
onItemSelect={handleItemSelect}
/>
);
}
```
### Advanced Usage with Styling
```jsx
<LeftPanel
items={items}
onItemSelect={handleItemSelect}
logoSize={{ width: 80, height: 40 }}
className="custom-left-panel"
style={{
width: '250px',
height: '100vh',
backgroundColor: '#f5f5f5',
borderRadius: '8px',
padding: '20px',
margin: '10px',
flexDirection: 'column',
gap: '16px',
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
}}
/>
```
## Props
| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `items` | `array` | `[]` | ✅ | Array of accordion configurations |
| `onItemSelect` | `function` | - | ❌ | Enhanced callback when any item is selected. Receives: (itemId, parentAccordionId, selectedItemLabel) |
| `selectedItem` | `string` | - | ❌ | ID of item to be selected by default |
| `logo` | `element` | - | ❌ | Custom logo component to replace LogoMetalCloud |
| `logoSize` | `object` | `{width: 64, height: 32}` | ❌ | Logo dimensions {width, height} |
| `onLogoClick` | `function` | - | ❌ | Callback when logo is clicked |
| `contentClassName` | `string` | `''` | ❌ | CSS classes for content container |
| `contentStyle` | `object` | `{}` | ❌ | Inline styles for content container |
| `className` | `string` | `''` | ❌ | Additional CSS classes |
| `style` | `object` | `{}` | ❌ | Inline styles (layout, visual, and positioning properties) |
### onItemSelect Callback Parameters
The `onItemSelect` callback receives three simple parameters:
```jsx
onItemSelect: (itemId, parentAccordionId, selectedItemLabel) => {
// itemId: string - The ID of the selected item
// parentAccordionId: string | null - Parent accordion ID
// selectedItemLabel: string | null - Selected item label
}
```
#### Parameter Details:
- **`itemId`** (string): The ID of the selected item
- **`parentAccordionId`** (string | null): Parent accordion ID
- **`selectedItemLabel`** (string | null): Selected item label
### Style Prop Properties
The `style` prop accepts all standard CSS properties. Common use cases include:
#### Layout Properties
- `width`, `minWidth`, `maxWidth`
- `height`, `minHeight`, `maxHeight`
- `flexDirection`, `justifyContent`, `alignItems`
- `gap`, `padding`, `margin`
#### Visual Properties
- `backgroundColor`, `color`
- `borderRadius`, `border`
- `boxShadow`, `opacity`
#### Positioning Properties
- `position`, `top`, `left`, `right`, `bottom`
- `zIndex`, `transform`
### Items Structure
```jsx
const items = [
{
id: 'unique-accordion-id',
triggerLabel: 'Accordion Title',
triggerIcon: IconComponent,
items: [
{
id: 'unique-item-id',
label: 'Item Label',
icon: IconComponent,
disabled: false // optional
}
]
}
];
```
## Developer Warnings
The component provides helpful warnings in the console when:
### Missing or Empty items
```jsx
// These will trigger a warning:
<LeftPanel /> // Missing items
<LeftPanel items={[]} /> // Empty array
<LeftPanel items={null} /> // Null value
<LeftPanel items={undefined} /> // Undefined value
```
**Warning Message:**
```
LeftPanel: items is empty or missing. Component may not render properly.
```
### When to Expect Warnings
- **Development**: When `items` is not provided or is empty
- **Production**: Component will still render but may not display content properly
- **Debugging**: Helps identify configuration issues quickly
## CSS Classes
### Main Classes
- `.left-panel` - Main container
- `.left-panel-logo` - Logo section wrapper
- `.left-panel-content` - Content section wrapper
### Responsive Breakpoints
- **Desktop**: Default (200px width)
- **Tablet**: `@media (max-width: 768px)` (280px max-width)
- **Mobile**: `@media (max-width: 480px)` (100% width)
### Theme Support
- **Light Theme**: Uses `var(--normal-surface-page, #FFF)`
- **Dark Theme**: Uses `var(--dark-surface-page, #1a1a1a)`
- **Auto-detection**: `@media (prefers-color-scheme: dark)`
## Accessibility
- **Focus States**: Proper outline on focus-within
- **Keyboard Navigation**: Full keyboard support through AccordionSelectableListContainer
- **Semantic Markup**: Proper HTML structure
- **Screen Reader Support**: ARIA labels and roles
## Examples
### Basic Left Panel
```jsx
<LeftPanel items={items} />
```
### Custom Logo Size
```jsx
<LeftPanel
items={items}
logoSize={{ width: 80, height: 40 }}
/>
```
### With Layout Styling
```jsx
<LeftPanel
items={items}
style={{
width: '250px',
height: '100vh',
flexDirection: 'column',
gap: '16px',
padding: '20px'
}}
/>
```
### With Visual Styling
```jsx
<LeftPanel
items={items}
style={{
backgroundColor: '#f8f9fa',
borderRadius: '12px',
boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
border: '1px solid #e9ecef'
}}
/>
```
### With Responsive Styling
```jsx
<LeftPanel
items={items}
style={{
width: '200px',
minWidth: '180px',
maxWidth: '300px',
height: '100%',
minHeight: '400px'
}}
/>
```
### With Simple Selection Handler
```jsx
<LeftPanel
items={items}
onItemSelect={(itemId) => {
console.log('User selected:', itemId);
// Handle navigation or filtering
}}
/>
```
### With Enhanced Selection Handler
```jsx
<LeftPanel
items={items}
onItemSelect={(itemId, parentAccordionId, selectedItemLabel) => {
console.log('Selected item ID:', itemId);
console.log('Parent accordion ID:', parentAccordionId);
console.log('Selected item label:', selectedItemLabel);
// Handle complex state management
updateGlobalState({
selectedItemId: itemId,
parentAccordionId: parentAccordionId,
selectedItemLabel: selectedItemLabel
});
}}
/>
```
### With Default Selection
```jsx
<LeftPanel
items={items}
selectedItem="charge-mix-item-1"
onItemSelect={(itemId) => {
console.log('User selected:', itemId);
}}
/>
```
### With Custom Logo
```jsx
<LeftPanel
items={items}
logo={CustomLogo}
logoSize={{ width: 100, height: 50 }}
onLogoClick={() => console.log('Logo clicked!')}
/>
```
### With Custom Styling Classes
```jsx
<LeftPanel
items={items}
className="my-custom-left-panel"
contentClassName="custom-content"
style={{
width: '280px',
backgroundColor: 'var(--primary-color)',
color: 'white'
}}
/>
```
## Integration with Design System
This component integrates with the design system by:
1. **Using Molecules**: Leverages `AccordionSelectableListContainer` from molecules package
2. **Using Atoms**: Uses `LogoMetalCloud` from atoms package
3. **Design Tokens**: All colors, spacing, and typography use design tokens
4. **Consistent Theming**: Supports theme switching seamlessly
5. **Organism Layer**: Represents complex UI patterns that combine multiple molecules
## Performance Considerations
- **Minimal Re-renders**: Uses React.memo for optimization
- **Efficient Styling**: CSS classes with optional inline styles
- **Lazy Loading**: Can be code-split if needed
## Browser Support
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (latest 2 versions)
- **CSS Features**: CSS Grid, Flexbox, CSS Custom Properties
- **JavaScript**: ES6+ features
## Contributing
When contributing to this component:
1. **Keep Props Minimal**: Focus on functionality, use `style` prop for styling
2. **Use Design Tokens**: All colors and spacing from tokens
3. **Test Responsiveness**: Verify all breakpoints
4. **Check Accessibility**: Ensure keyboard navigation works
5. **Update Documentation**: Keep README current
## License
This component is part of the design system and follows the same licensing terms.