import { default as React } from 'react'; import { EmptyStateProps } from '../EmptyState/EmptyState'; import { FormLabelProps } from '../FormLabel/FormLabel'; import { SearchBarProps } from '../SearchBar/SearchBar'; import { DateCheckState, GroupScrollConfig, IgnoreNodeHierarchyProps, TableColumnConfigProps } from '../Form/NestedCheckboxHelper'; type DisabledItemsSection = { /** Hide Disabled items section */ enabled: false; } | { /** Show Disabled items section */ enabled: true; /** Title displayed at the left side of the section header */ primaryTitle?: string; /** Title displayed at the right side of the section header */ secondaryTitle?: string; /** Optionally determine which key in DataItem to use for placing items in the disabled items section. */ disabledItemsKey?: keyof DataItem; }; type SearchProps = Omit & { /** Optional function that will make a callout with the search `value` passed back */ onChange?: (value: string) => void; /** Boolean value to indicate if search bar to be shown */ show?: boolean; }; export type MultiSelectDataItemBase = { /** Required prop that will be used as a "label". This prop must remain flexible as we do not know what an api response will look like. This will force at least one field to passed into the `DataItem` generic. */ [key: string]: unknown; /** Optional text that needs to be shown near the actual text */ secondaryOption?: React.ReactNode; /** Optional flag to indicate if the option cannot be checked or unchecked */ disabled?: boolean; }; type MultiSelectBaseProps = { /** Array of options displayed in the UI */ options: DataItem[]; /** Array of user selected options that we want selected when the component mounts. These strings should come from the strings provided in the `options` prop. */ selectedOptions: DataItem[]; /** Key that is used to populate the selectable text */ labelKey: keyof DataItem; /** Function to set the array of selected options */ callout: (selectedList: DataItem[]) => void; /** Optionally add FormLabel props */ formLabelProps?: FormLabelProps; /** Search Bar props. Can be used to override dynamically */ searchBarProps?: Omit & { /** The value should be optional */ value?: string; }; /** Custom text that will display if no items match the search input */ emptyStateProps?: EmptyStateProps; /** Optional prop to disabled the use of this component */ disabled?: boolean; /** Optionally show the ListLoading component when options are not readily available */ loading?: boolean; /** Optionally hide the Select All */ hideSelectAll?: boolean; /** Optionally make the selected items reorderable using the DraggableList component. */ isReorderable?: boolean; /** Optionally opt-out of alphaetical sorting */ sortAlphabetically?: boolean; /** Optionally opt-out for showing disabled items in disabled section below unselected items*/ disabledItemsSection?: DisabledItemsSection; /** Optional function to run when the MultiSelect receives focus */ onFocus?: () => void; /** Optional prop to add a test id to the MultiSelect for QA testing */ qaTestId?: string; }; type MultiSelectWithOptionsProps = MultiSelectBaseProps & { fetchData?: never; hasMore?: never; searchValue?: never; isFetching?: never; dropdownState?: never; }; type MultiSelectWithAPIOptionsProps = MultiSelectBaseProps & { /** To trigger API call initially and on pagination */ fetchData: () => void; /** Boolean value to indicate if pagination exists */ hasMore: boolean; /** Optionally used to indicate API fetch status. */ isFetching?: boolean; /** Callback that gives the current open / closed state of the Tippy */ dropdownState?: (status: 'open' | 'close') => void; }; type MultiSelectOptionsProps = MultiSelectWithAPIOptionsProps | MultiSelectWithOptionsProps; export type ExposedProps = MultiSelectOptionsProps & { /** Optionally make the component "exposed" by not needing a click to view the options. */ exposed: boolean; /** Optionally override the maxHeight for the exposed container. */ maxHeight?: number | string; appendTo?: never; selectPlaceholder?: never; /** Option to reset list search on callout */ resetSearch?: boolean; nestedConfig?: never; /** Optionally remove the border for the exposed MultiSelect. */ removeBorder?: boolean; }; type StandardProps = MultiSelectOptionsProps & { /** Useful when we want to attach this to another component making use of Tippy */ appendTo?: 'parent' | ((element: Element) => Element); /** Custom placeholder text for the Select Dropdown */ selectPlaceholder: string; exposed?: never; maxHeight?: never; resetSearch?: never; nestedConfig?: never; removeBorder?: never; }; type NestedPropsBase = MultiSelectOptionsProps & (Omit, 'nestedConfig'> | Omit, 'nestedConfig'>); type NestedProps = NestedPropsBase & { /** Useful for showing nested hierarchy selection experience */ nestedConfig: { /** Data to be displayed in the nested hierarchy */ data: DataItem[]; /** Table configuration that will handle column headers and rendering column children. */ tableConfig: TableColumnConfigProps[]; /** Array of objects to keep the track of selected or unselected options */ itemStates: DateCheckState[]; /** Function to set the array of selected options */ setItemStates: React.Dispatch>; /** Object containing keys to identify the data and its parent child relationship */ identifierKeys: { displayKey: string; idKey: string; parentKey: string; }; /** Optional per-group scroll and infinite-scroll pagination config */ groupScrollConfig?: GroupScrollConfig; /** Optional predicate to exclude items from rendering in CheckboxList without affecting the empty-state check */ filterItems?: (item: DataItem) => boolean; } & IgnoreNodeHierarchyProps; }; export type MultiSelectProps = ExposedProps | StandardProps | NestedProps; export type MultiSelectHeaders = { id: number; label: string; isChecked: boolean; }; declare const MultiSelect: ({ appendTo, dropdownState, labelKey, selectedOptions, options, callout, isFetching, isReorderable, fetchData, selectPlaceholder, searchBarProps, emptyStateProps, exposed, maxHeight, resetSearch, disabled, loading, hideSelectAll, hasMore, formLabelProps, sortAlphabetically, disabledItemsSection, nestedConfig, removeBorder, onFocus, qaTestId, }: MultiSelectProps) => React.JSX.Element; export default MultiSelect;