import {createContext, forwardRef, useContext, useMemo} from 'react' import {View} from 'react-native' import {Select as RadixSelect} from 'radix-ui' import {flatten, useTheme} from '#/alf' import {atoms as a} from '#/alf' import {useInteractionState} from '#/components/hooks/useInteractionState' import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check' import { ChevronBottom_Stroke2_Corner0_Rounded as ChevronDownIcon, ChevronTop_Stroke2_Corner0_Rounded as ChevronUpIcon, } from '#/components/icons/Chevron' import {Text} from '#/components/Typography' import { type ContentProps, type IconProps, type ItemIndicatorProps, type ItemProps, type RadixPassThroughTriggerProps, type RootProps, type TriggerProps, type ValueProps, } from './types' const SelectedValueContext = createContext(null) export function Root(props: RootProps) { return ( ) } const RadixTriggerPassThrough = forwardRef( ( props: { children: ( props: RadixPassThroughTriggerProps & { ref: React.Ref }, ) => React.ReactNode }, ref, ) => { // @ts-expect-error Radix provides no types of this stuff return props.children?.({...props, ref}) }, ) RadixTriggerPassThrough.displayName = 'RadixTriggerPassThrough' export function Trigger({children, label}: TriggerProps) { const t = useTheme() const { state: hovered, onIn: onMouseEnter, onOut: onMouseLeave, } = useInteractionState() const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() if (typeof children === 'function') { return ( {props => children({ isNative: false, state: { hovered, focused, pressed: false, }, props: { ...props, onPress: props.onClick, onFocus: onFocus, onBlur: onBlur, onMouseEnter, onMouseLeave, accessibilityLabel: label, }, }) } ) } else { return ( {children} ) } } export function ValueText({children: _, style, ...props}: ValueProps) { return ( ) } export function Icon({style}: IconProps) { const t = useTheme() return ( ) } export function Content({items, renderItem}: ContentProps) { const t = useTheme() const selectedValue = useContext(SelectedValueContext) const scrollBtnStyles: React.CSSProperties[] = [ a.absolute, a.flex, a.align_center, a.justify_center, a.rounded_sm, a.z_10, ] const up: React.CSSProperties[] = [ ...scrollBtnStyles, a.pt_sm, a.pb_lg, { top: 0, left: 0, right: 0, borderBottomLeftRadius: 0, borderBottomRightRadius: 0, background: `linear-gradient(to bottom, ${t.atoms.bg.backgroundColor} 0%, transparent 100%)`, }, ] const down: React.CSSProperties[] = [ ...scrollBtnStyles, a.pt_lg, a.pb_sm, { bottom: 0, left: 0, right: 0, borderBottomLeftRadius: 0, borderBottomRightRadius: 0, background: `linear-gradient(to top, ${t.atoms.bg.backgroundColor} 0%, transparent 100%)`, }, ] return ( {items.map((item, index) => renderItem(item, index, selectedValue))} ) } const ItemContext = createContext<{ hovered: boolean focused: boolean pressed: boolean selected: boolean }>({ hovered: false, focused: false, pressed: false, selected: false, }) export function useItemContext() { return useContext(ItemContext) } export function Item({ref, value, style, children}: ItemProps) { const t = useTheme() const { state: hovered, onIn: onMouseEnter, onOut: onMouseLeave, } = useInteractionState() const selected = useContext(SelectedValueContext) === value const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState() const ctx = useMemo( () => ({hovered, focused, pressed: false, selected}), [hovered, focused, selected], ) return ( {children} ) } export const ItemText = RadixSelect.ItemText export function ItemIndicator({icon: Icon = CheckIcon}: ItemIndicatorProps) { return ( ) }