Bluesky app fork with some witchin' additions 馃挮
at feat/tealfm 202 lines 4.8 kB view raw
1import { 2 type AccessibilityProps, 3 type StyleProp, 4 type TextStyle, 5 type ViewStyle, 6} from 'react-native' 7 8import {type TextStyleProp} from '#/alf' 9import {type DialogControlProps} from '#/components/Dialog' 10import {type Props as SVGIconProps} from '#/components/icons/common' 11 12export type RootProps = { 13 children?: React.ReactNode 14 value?: string 15 onValueChange?: (value: string) => void 16 disabled?: boolean 17 /** 18 * @platform web 19 */ 20 defaultValue?: string 21 /** 22 * @platform web 23 */ 24 open?: boolean 25 /** 26 * @platform web 27 */ 28 defaultOpen?: boolean 29 /** 30 * @platform web 31 */ 32 onOpenChange?(open: boolean): void 33 /** 34 * @platform web 35 */ 36 name?: string 37 /** 38 * @platform web 39 */ 40 autoComplete?: string 41 /** 42 * @platform web 43 */ 44 required?: boolean 45} 46 47export type RadixPassThroughTriggerProps = { 48 id: string 49 type: 'button' 50 disabled: boolean 51 ['data-disabled']: boolean 52 ['data-state']: string 53 ['aria-controls']?: string 54 ['aria-haspopup']?: boolean 55 ['aria-expanded']?: AccessibilityProps['aria-expanded'] 56 onClick: () => void 57 onPointerDown: () => void 58 onKeyDown: () => void 59} 60 61export type TriggerProps = { 62 children: React.ReactNode | ((props: TriggerChildProps) => React.ReactNode) 63 label: string 64} 65 66export type TriggerChildProps = 67 | { 68 IS_NATIVE: true 69 control: DialogControlProps 70 state: { 71 /** 72 * Web only, `false` on native 73 */ 74 hovered: false 75 focused: boolean 76 pressed: boolean 77 } 78 /** 79 * We don't necessarily know what these will be spread on to, so we 80 * should add props one-by-one. 81 * 82 * On web, these properties are applied to a parent `Pressable`, so this 83 * object is empty. 84 */ 85 props: { 86 onPress: () => void 87 onFocus: () => void 88 onBlur: () => void 89 onPressIn: () => void 90 onPressOut: () => void 91 accessibilityLabel: string 92 } 93 } 94 | { 95 IS_NATIVE: false 96 state: { 97 hovered: boolean 98 focused: boolean 99 /** 100 * Native only, `false` on web 101 */ 102 pressed: false 103 } 104 props: RadixPassThroughTriggerProps & { 105 onPress: () => void 106 onFocus: () => void 107 onBlur: () => void 108 onMouseEnter: () => void 109 onMouseLeave: () => void 110 accessibilityLabel: string 111 } 112 } 113 114/* 115 * For use within the `Select.Trigger` component. 116 * Shows the currently selected value. You can also 117 * provide a placeholder to show when no value is selected. 118 * 119 * If you're passing items of a different shape than {value: string, label: string}, 120 * you'll need to pass a function to `children` that extracts the label from an item. 121 */ 122export type ValueProps = { 123 /** 124 * Only needed for native. Extracts the label from an item. Defaults to `item => item.label` 125 */ 126 children?: (value: any) => React.ReactNode 127 placeholder?: string 128 style?: StyleProp<TextStyle> 129 /** 130 * By default, web just extracts the component from inside the dropdown and portals it in here. 131 * If you want to override this, pass a value that will then be rendered via `children(value)` 132 * 133 * @platform web 134 */ 135 webOverrideValue?: any 136} 137 138/* 139 * Icon for use within the `Select.Trigger` component. 140 * Changes based on platform - chevron down on web, up/down chevrons on native 141 * 142 * `style` prop is web only 143 */ 144export type IconProps = TextStyleProp 145 146export type ContentProps<T> = { 147 /** 148 * Label at the top of the sheet on native. 149 * 150 * @default "Select an option" 151 */ 152 label?: string 153 /** 154 * Items to render. Recommended to be in the form {value: string, label: string} - if not, 155 * you need to provide a `valueExtractor` function to extract the value from an item and 156 * customise the `Select.ValueText` component. 157 */ 158 items: T[] 159 /** 160 * Renders an item. You should probably use the `Select.Item` component. 161 * 162 * @example 163 * ```tsx 164 * renderItem={({label, value}) => ( 165 * <Select.Item value={value} label={label}> 166 * <Select.ItemIndicator /> 167 * <Select.ItemText>{label}</Select.ItemText> 168 * </Select.Item> 169 * )} 170 * ``` 171 */ 172 renderItem: ( 173 item: T, 174 index: number, 175 selectedValue?: string | null, 176 ) => React.ReactElement<any> 177 /* 178 * Extracts the value from an item. Defaults to `item => item.value` 179 */ 180 valueExtractor?: (item: T) => string 181} 182 183/* 184 * An item within the select dropdown 185 */ 186export type ItemProps = { 187 ref?: React.Ref<HTMLDivElement> 188 value: string 189 label: string 190 children: React.ReactNode 191 style?: StyleProp<ViewStyle> 192} 193 194export type ItemTextProps = { 195 children: React.ReactNode 196 style?: StyleProp<TextStyle> 197 emoji?: boolean 198} 199 200export type ItemIndicatorProps = { 201 icon?: React.ComponentType<SVGIconProps> 202}