diff options
author | Samuel Newman <mozzius@protonmail.com> | 2025-05-06 20:27:05 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-05-06 10:27:05 -0700 |
commit | 973538d246a3f76550611e438152f1a6cad75f49 (patch) | |
tree | 83c7547eb9ba1123bac8ab8ef30f37d5164b3ce2 /src/components/Select/types.ts | |
parent | 25f8506c4152840e83ba9210452b60ea5cc0987f (diff) | |
download | voidsky-973538d246a3f76550611e438152f1a6cad75f49.tar.zst |
New `Select` component (#8323)
* radix select component on web * native implementation (wip) * fix sheet height/padding * tone down web styles * react 19 cleanup * replace primary language select * change style on native * get auto placeholder working * more style tweaks * replace app language dropdown * replace rnpickerselect with native select * rm react-native-picker-select dependency * rm placeholder, since a value is always selected * docblock for renderItem * add more docblocks * add style prop to item * pass selectedValue through renderItem * fix context * Style overflow buttons --------- Co-authored-by: Eric Bailey <git@esb.lol>
Diffstat (limited to 'src/components/Select/types.ts')
-rw-r--r-- | src/components/Select/types.ts | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/src/components/Select/types.ts b/src/components/Select/types.ts new file mode 100644 index 000000000..5c1b80a3b --- /dev/null +++ b/src/components/Select/types.ts @@ -0,0 +1,185 @@ +import { + type AccessibilityProps, + type StyleProp, + type TextStyle, + type ViewStyle, +} from 'react-native' + +import {type TextStyleProp} from '#/alf' +import {type DialogControlProps} from '#/components/Dialog' +import {type Props as SVGIconProps} from '#/components/icons/common' + +export type RootProps = { + children?: React.ReactNode + value?: string + onValueChange?: (value: string) => void + disabled?: boolean + /** + * @platform web + */ + defaultValue?: string + /** + * @platform web + */ + open?: boolean + /** + * @platform web + */ + defaultOpen?: boolean + /** + * @platform web + */ + onOpenChange?(open: boolean): void + /** + * @platform web + */ + name?: string + /** + * @platform web + */ + autoComplete?: string + /** + * @platform web + */ + required?: boolean +} + +export type RadixPassThroughTriggerProps = { + id: string + type: 'button' + disabled: boolean + ['data-disabled']: boolean + ['data-state']: string + ['aria-controls']?: string + ['aria-haspopup']?: boolean + ['aria-expanded']?: AccessibilityProps['aria-expanded'] + onPress: () => void +} + +export type TriggerProps = { + children: React.ReactNode | ((props: TriggerChildProps) => React.ReactNode) + label: string +} + +export type TriggerChildProps = + | { + isNative: true + control: DialogControlProps + state: { + /** + * Web only, `false` on native + */ + hovered: false + focused: boolean + pressed: boolean + } + /** + * We don't necessarily know what these will be spread on to, so we + * should add props one-by-one. + * + * On web, these properties are applied to a parent `Pressable`, so this + * object is empty. + */ + props: { + onPress: () => void + onFocus: () => void + onBlur: () => void + onPressIn: () => void + onPressOut: () => void + accessibilityLabel: string + } + } + | { + isNative: false + state: { + hovered: boolean + focused: boolean + /** + * Native only, `false` on web + */ + pressed: false + } + props: RadixPassThroughTriggerProps & { + onPress: () => void + onFocus: () => void + onBlur: () => void + onMouseEnter: () => void + onMouseLeave: () => void + accessibilityLabel: string + } + } + +/* + * For use within the `Select.Trigger` component. + * Shows the currently selected value. You can also + * provide a placeholder to show when no value is selected. + * + * If you're passing items of a different shape than {value: string, label: string}, + * you'll need to pass a function to `children` that extracts the label from an item. + */ +export type ValueProps = { + /** + * Only needed for native. Extracts the label from an item. Defaults to `item => item.label` + */ + children?: (value: any) => string + placeholder?: string + style?: StyleProp<TextStyle> +} + +/* + * Icon for use within the `Select.Trigger` component. + * Changes based on platform - chevron down on web, up/down chevrons on native + * + * `style` prop is web only + */ +export type IconProps = TextStyleProp + +export type ContentProps<T> = { + /** + * Items to render. Recommended to be in the form {value: string, label: string} - if not, + * you need to provide a `valueExtractor` function to extract the value from an item and + * customise the `Select.ValueText` component. + */ + items: T[] + /** + * Renders an item. You should probably use the `Select.Item` component. + * + * @example + * ```tsx + * renderItem={({label, value}) => ( + * <Select.Item value={value} label={label}> + * <Select.ItemIndicator /> + * <Select.ItemText>{label}</Select.ItemText> + * </Select.Item> + * )} + * ``` + */ + renderItem: ( + item: T, + index: number, + selectedValue?: string | null, + ) => React.ReactElement + /* + * Extracts the value from an item. Defaults to `item => item.value` + */ + valueExtractor?: (item: T) => string +} + +/* + * An item within the select dropdown + */ +export type ItemProps = { + ref?: React.Ref<HTMLDivElement> + value: string + label: string + children: React.ReactNode + style?: StyleProp<ViewStyle> +} + +export type ItemTextProps = { + children: React.ReactNode +} + +export type ItemIndicatorProps = { + icon?: React.ComponentType<SVGIconProps> +} |