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