import { c, classy, m, SelectProps as BaseProps } from '@onfido/castor'; import React, { ForwardedRef, useEffect, useMemo, useState } from 'react'; import { MaybeIcon } from '../../internal'; import { useForwardedRef, withRef } from '../../utils'; import { CustomSelect, CustomSelectProps } from './custom'; import { NativeSelect, NativeSelectProps } from './native'; import { SelectProvider } from './useSelect'; export type SelectProps = (Native | Custom) & { icon?: JSX.Element; selectedIcon?: JSX.Element; }; type Native = { native: true } & BaseProps & NativeSelectProps; type Custom = { native?: false } & BaseProps & Omit; /** * `Select` by default uses two `Icon` that require `Icons` (SVG sprite) to be * included in your app. * * https://github.com/onfido/castor-icons#use-with-plain-code * * You may also provide any other SVG element via the `icon` and `selectedIcon` * props, but using Castor iconography is recommended. */ export const Select = withRef(function Select( { id: initialId, borderless, className, icon, native, onChange, ...restProps }: SelectProps, ref: ForwardedRef ) { const { defaultValue, value } = restProps; const selectRef = useForwardedRef(ref); const [empty, setEmpty] = useState(!(value ?? defaultValue)); const [open, setOpen] = useState(false); const id = useMemo( () => initialId || `castor_select_${++idCount}`, [initialId] ); // on every re-render, check for "empty" just after a DOM cycle useEffect(() => void setTimeout(() => setEmpty(!selectRef.current?.value))); useEffect(() => { if (value != null) setEmpty(!value); }, [value]); return (
{ setEmpty(!event.currentTarget.value); onChange?.(event); }} onOpenChange={setOpen} />
); }); interface ContentProps extends CustomSelectProps { borderless?: boolean; native?: boolean; open?: boolean; onOpenChange: (open: boolean) => void; selectedIcon?: JSX.Element; } const Content = withRef(function Content( { borderless, native, open, onOpenChange, ...restProps }: ContentProps, ref: ForwardedRef ) { if (native) return ; return ( ); }); let idCount = 0;