mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
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 isNative: 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 isNative: 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) => string
127 placeholder?: string
128 style?: StyleProp<TextStyle>
129}
130
131/*
132 * Icon for use within the `Select.Trigger` component.
133 * Changes based on platform - chevron down on web, up/down chevrons on native
134 *
135 * `style` prop is web only
136 */
137export type IconProps = TextStyleProp
138
139export type ContentProps<T> = {
140 /**
141 * Items to render. Recommended to be in the form {value: string, label: string} - if not,
142 * you need to provide a `valueExtractor` function to extract the value from an item and
143 * customise the `Select.ValueText` component.
144 */
145 items: T[]
146 /**
147 * Renders an item. You should probably use the `Select.Item` component.
148 *
149 * @example
150 * ```tsx
151 * renderItem={({label, value}) => (
152 * <Select.Item value={value} label={label}>
153 * <Select.ItemIndicator />
154 * <Select.ItemText>{label}</Select.ItemText>
155 * </Select.Item>
156 * )}
157 * ```
158 */
159 renderItem: (
160 item: T,
161 index: number,
162 selectedValue?: string | null,
163 ) => React.ReactElement
164 /*
165 * Extracts the value from an item. Defaults to `item => item.value`
166 */
167 valueExtractor?: (item: T) => string
168}
169
170/*
171 * An item within the select dropdown
172 */
173export type ItemProps = {
174 ref?: React.Ref<HTMLDivElement>
175 value: string
176 label: string
177 children: React.ReactNode
178 style?: StyleProp<ViewStyle>
179}
180
181export type ItemTextProps = {
182 children: React.ReactNode
183}
184
185export type ItemIndicatorProps = {
186 icon?: React.ComponentType<SVGIconProps>
187}