import React from "react"; import { DropdownBox } from "../dropdown"; import { VirtualizedList as List, VirtualizedListProps, VirtualizedListItem, } from "../list/VirtualizedList"; import { SelectOptionWithGroup } from "../select/SelectOption"; import { StyledProps } from "../_type"; import { SimulateSelectProps } from "../select"; import { useConfig } from "../util"; import { useIsomorphicLayoutEffect } from "../_util/use-isomorphic-layout-effect"; export interface TagSelectBoxProps extends StyledProps { items: VirtualizedListItem[]; width: number; onChange: ( value: string, context: { event: React.MouseEvent; option: SelectOptionWithGroup } ) => void; scheduleUpdate: () => void; tips: React.ReactNode; currentIndex: number; listRef: VirtualizedListProps["virtualizedRef"]; onScrollBottom: VirtualizedListProps["onScrollBottom"]; footer: React.ReactNode; } export function TagSelectBox({ listRef, items, onChange, width, scheduleUpdate, className, style = {}, currentIndex, onScrollBottom, footer, }: TagSelectBoxProps) { useIsomorphicLayoutEffect(() => { scheduleUpdate(); }, [scheduleUpdate, items]); const { classPrefix } = useConfig(); const count = items.length; if (count === 0) { return null; } const hasGroup = !!items.find(item => item.type === "group"); const boxStyle = { ...style, width }; return ( e.stopPropagation()} className={className} style={boxStyle} footer={footer} > { if (item.type === "option") { const { option } = item; return { ...item, props: { disabled: option.disabled, current: currentIndex % count === index, onClick: event => { onChange(option.value, { event, option, }); }, tooltip: option.tooltip, className: hasGroup && !option.groupKey ? `${classPrefix}-list__item--single` : "", }, }; } return item; })} onScrollBottom={onScrollBottom} /> ); } TagSelectBox.displayName = "TagSelectBox"; export function getListItems({ tips, options, groups, }: Pick< SimulateSelectProps, "tips" | "options" | "groups" >): VirtualizedListItem[] { const items: VirtualizedListItem[] = []; if (tips) { items.push({ type: "tips", key: "__tips", text: tips }); } options.forEach((option, index) => { if ( option.groupKey && (index === 0 || option.groupKey !== options[index - 1].groupKey) ) { items.push({ type: "group", key: `${option.groupKey}-${option.value}`, text: groups[option.groupKey], }); } items.push({ type: "option", key: option.value, text: typeof option.text === "undefined" ? option.value : option.text, option, }); }); return items; }