import React, { useReducer, createRef, Fragment, useCallback, ReactElement, } from 'react'; import { Collapsible } from './Collapsible'; import classnames from 'classnames'; import './LeftNav.scss'; export interface Item { key: string; label: string; count?: number; isSelected?: boolean; isHeader?: boolean; } export interface State { searchText: string; collapsed: boolean; } export type Action = | { type: 'SetSearch'; searchValue: string } | { type: 'SetCollapsed'; collapsedValue: boolean }; export interface Props { name: string; onChange(key: string): void; onClear(): void; onSearch?(searchQuery: string): void; onToggleCollapsed?(isToggled: boolean): void; items: Item[]; collapsible?: boolean; defaultCollapsed?: boolean; collapseOnOutsideClick?: boolean; compact?: boolean; multiSelect?: boolean; showSearch?: boolean; showClear?: boolean; disabled?: boolean; } export const Section: React.FC = ({ name, onChange, onClear, onSearch = (): void => {}, onToggleCollapsed = (): void => {}, items, collapsible = false, defaultCollapsed = true, collapseOnOutsideClick = true, compact = false, multiSelect = false, showSearch = false, showClear = false, disabled = false, }) => { const initialState: State = { searchText: '', collapsed: false, }; const reducer = (state: State, action: Action): State => { switch (action.type) { case 'SetSearch': return { ...state, searchText: action.searchValue }; case 'SetCollapsed': return { ...state, collapsed: action.collapsedValue }; } }; const [state, dispatch] = useReducer(reducer, initialState); const searchRef = createRef(); const handleChange = useCallback( (event: React.ChangeEvent): void => { dispatch({ type: 'SetSearch', searchValue: event.target.value }); onSearch(event.target.value); }, [onSearch], ); const sectionDetails = (): ReactElement => (
{showSearch && (
)}
    {items .filter(item => item.label.toLowerCase().includes(state.searchText.toLowerCase()), ) .map((item, index: number) => item.isHeader ? (
    {item.label}
    ) : (
  • !disabled && onChange(item.key)} > {multiSelect && ( !disabled && onChange(item.key)} onClick={(event): void => event.stopPropagation()} checked={item.isSelected} /> )} {item.label} { {item.count >= 1000 ? item.count.toLocaleString() : item.count} }
  • ), )}
{showClear && items.some(item => item.isSelected) && (
{ if (!disabled) { dispatch({ type: 'SetSearch', searchValue: '' }); searchRef.current.focus(); onClear(); } }} > Clear
)}
); return (
{collapsible ? ( {name}
} onToggle={onToggleCollapsed} > {sectionDetails()} ) : (
{name}
{sectionDetails()}
)} ); };