import { useRef, useEffect, KeyboardEventHandler, useCallback, ReactNode, useState, useId, } from 'react' import classNames from 'classnames' import { useSelect } from 'downshift' import { useTranslation } from 'react-i18next' import { Form } from 'react-bootstrap' import FormControl from '@/shared/components/form/form-control' import MaterialIcon from '@/shared/components/material-icon' import { CaretUp, CaretDown, Check } from '@phosphor-icons/react' import { DropdownItem } from '@/shared/components/dropdown/dropdown-menu' import OLOverlay from '@/shared/components/ol/ol-overlay' import OLSpinner from './ol/ol-spinner' import DSFormLabel from '@/shared/components/ds/ds-form-label' import DSFormGroup from '@/shared/components/ds/ds-form-group' import DSFormControl from '@/shared/components/ds/ds-form-control' import { DropdownItemProps } from '@/shared/components/types/dropdown-menu-props' function SelectMenuPopover({ show, target, onHide, children, }: { show: boolean target: HTMLElement | null onHide: () => void children: ReactNode }) { const id = useId() return ( {({ ref, style }) => (
{children}
)}
) } export type SelectProps = { // The items rendered as dropdown options. items: T[] // Stringifies an item of type T. The resulting string is rendered as a dropdown option. itemToString: (item: T | null | undefined) => string // Caption for the dropdown. label?: ReactNode // Attribute used to identify the component inside a Form. This name is used to // retrieve FormData when the form is submitted. The value of the FormData entry // is the string returned by `itemToString(selectedItem)`. name?: string // Hint text displayed in the initial render. defaultText?: string // Initial selected item, displayed in the initial render. When both `defaultText` // and `defaultItem` are set the latter is ignored. defaultItem?: T | null // Stringifies an item. The resulting string is rendered as a subtitle in a dropdown option. itemToSubtitle?: (item: T | null | undefined) => string // Stringifies an item. The resulting string is rendered as a React `key` for each item. itemToKey: (item: T) => string // Maps an item to a leading icon. itemToLeadingIcon?: ( item: T | null | undefined ) => DropdownItemProps['leadingIcon'] // Callback invoked after the selected item is updated. onSelectedItemChanged?: (item: T | null | undefined) => void // Optionally directly control the selected item. selected?: T | null // When `true` item selection is disabled. disabled?: boolean // Determine which items should be disabled itemToDisabled?: (item: T | null | undefined) => boolean // When `true` displays an "Optional" subtext after the `label` caption. optionalLabel?: boolean // When `true` displays a spinner next to the `label` caption. loading?: boolean // Show a checkmark next to the selected item selectedIcon?: boolean // testId for the input element dataTestId?: string // CIAM-specific layout isCiam?: boolean size?: React.ComponentProps['size'] // Renders the menu in a portal so it escapes overflow-clipping ancestors. portal?: boolean // Optional id for the toggle button element. When provided, enables association // with an external