import cn from 'classnames'; import { FocusEvent, KeyboardEvent, MouseEvent, ReactNode, RefObject } from 'react'; import { Checkbox, Switch } from '@snack-uikit/toggles'; import { extractSupportProps } from '@snack-uikit/utils'; import { ItemContent } from '../../../helperComponents'; import { useCollapseLevelContext, useNewListContext, useOpenListContext, useSelectionContext, } from '../../Lists/contexts'; import commonStyles from '../styles.module.scss'; import { FlattenBaseItem } from '../types'; import { isContentItem } from '../utils'; import { CHECKBOX_SIZE_MAP } from './constants'; import styles from './styles.module.scss'; type AllBaseItemProps = FlattenBaseItem & { expandIcon?: ReactNode; open?: boolean; indeterminate?: boolean; onSelect?(): void; isParentNode?: boolean; onOpenNestedList?(e?: KeyboardEvent): void; }; export function BaseItem({ beforeContent, afterContent, content, onClick, onMouseDown, id, expandIcon, disabled, open, itemRef, switch: switchProp, showSwitchIcon, onKeyDown, onFocus, indeterminate, checked: checkedProp, onSelect, onOpenNestedList, isParentNode, className, inactive, itemWrapRender, ...rest }: AllBaseItemProps) { const interactive = !inactive; const { size = 's', marker, contentRender, firstItemId, focusFlattenItems } = useNewListContext(); const { level = 0 } = useCollapseLevelContext(); const { closeDroplist, closeDroplistOnItemClick } = useOpenListContext(); const { value, onChange, mode, isSelectionSingle, isSelectionMultiple } = useSelectionContext(); const isChecked = isSelectionSingle ? (checkedProp ?? value === id) : (checkedProp ?? value?.includes(id ?? '')); const handleChange = () => { onChange?.(id); }; const handleItemMouseDown = (e: MouseEvent) => { if (disabled) return; onMouseDown?.(e); }; const handleItemFocus = (e: FocusEvent) => { onFocus?.(e); e.stopPropagation(); }; const handleCheckboxChange = () => { if (isParentNode && onSelect) { onSelect(); } else { handleChange(); } }; const handleItemClick = (e: MouseEvent) => { if (!disabled) { onClick?.(e); if (interactive) { if (!isParentNode) { handleChange(); } } if (!isSelectionMultiple && closeDroplistOnItemClick) { closeDroplist(); } } }; const handleItemKeyDown = (e: KeyboardEvent) => { onKeyDown?.(e); if (e.key === 'ArrowRight' && onOpenNestedList) { onOpenNestedList(e); e.preventDefault(); e.stopPropagation(); return; } if (e.code === 'Space' || e.key === 'Enter' || e.key === ' ') { if (isSelectionMultiple && isParentNode && onSelect) { onSelect(); } !isParentNode && handleChange(); // TODO: should pass an event here? !isParentNode && handleItemClick?.(e as unknown as MouseEvent); e.stopPropagation(); e.preventDefault(); } }; const handleCheckboxClick = (e: MouseEvent) => { if (isParentNode) { e.stopPropagation(); } }; const props = extractSupportProps(rest); const itemJSX = (
  • } className={cn(commonStyles.listItem, styles.droplistItem)} data-size={size} onClick={handleItemClick} onMouseDown={handleItemMouseDown} tabIndex={firstItemId && id === focusFlattenItems[firstItemId].originalId ? 0 : -1} data-non-pointer={inactive && !onClick} data-variant={mode || undefined} data-open={open || undefined} onKeyDown={handleItemKeyDown} onFocus={handleItemFocus} style={{ '--level': level }} data-level-one={level === 1 || undefined} data-level-more-one={level > 1 || undefined} data-checked={(isParentNode && (indeterminate || isChecked)) || (isChecked && !switchProp) || undefined} > {!switchProp && isSelectionSingle && marker && !isParentNode && interactive && (
    )} {!switchProp && isSelectionMultiple && interactive && (
    )} {beforeContent &&
    {beforeContent}
    } {content && isContentItem(content) ? ( (contentRender?.({ id, content, disabled }) ?? ) ) : (
    {content}
    )} {afterContent} {switchProp && interactive && ( )} {!switchProp && expandIcon && {expandIcon}}
  • ); if (!itemWrapRender) { return itemJSX; } return itemWrapRender(itemJSX); }