diff --git a/app/component-library/components/Pickers/PickerBase/PickerBase.stories.tsx b/app/component-library/components/Pickers/PickerBase/PickerBase.stories.tsx new file mode 100644 index 00000000000..e5a705d98dd --- /dev/null +++ b/app/component-library/components/Pickers/PickerBase/PickerBase.stories.tsx @@ -0,0 +1,57 @@ +/* eslint-disable react/display-name */ +/* eslint-disable react-native/no-inline-styles */ +// External dependencies. +import React from 'react'; +import { View, Text } from 'react-native'; + +// Internal dependencies. +import PickerBase from './PickerBase'; +import { IconSize } from '../../Icons/Icon'; + +const PickerBaseMeta = { + title: 'Component Library / Pickers', + component: PickerBase, + argTypes: { + children: { + control: { type: 'text' }, + defaultValue: 'Select an option', + }, + iconSize: { + options: Object.values(IconSize), + control: { type: 'select' }, + defaultValue: IconSize.Md, + }, + }, +}; + +export default PickerBaseMeta; + +export const Default = { + render: ({ + children, + iconSize, + }: { + children: string; + iconSize: IconSize; + }) => ( + + null} iconSize={iconSize}> + {children} + + + ), +}; + +export const WithCustomStyles = { + render: () => ( + + null} + style={{ width: 200 }} + dropdownIconStyle={{ marginLeft: 20 }} + > + Custom Styled Picker + + + ), +}; diff --git a/app/component-library/components/Pickers/PickerBase/PickerBase.styles.ts b/app/component-library/components/Pickers/PickerBase/PickerBase.styles.ts index 475e466e6b1..cad2a763c44 100644 --- a/app/component-library/components/Pickers/PickerBase/PickerBase.styles.ts +++ b/app/component-library/components/Pickers/PickerBase/PickerBase.styles.ts @@ -21,7 +21,8 @@ const styleSheet = (params: { }) => { const { vars, theme } = params; const { colors } = theme; - const { style } = vars; + const { style, dropdownIconStyle } = vars; + return StyleSheet.create({ base: Object.assign( { @@ -35,9 +36,12 @@ const styleSheet = (params: { } as ViewStyle, style, ) as ViewStyle, - dropdownIcon: { - marginLeft: 16, - }, + dropdownIcon: Object.assign( + { + marginLeft: 16, + } as ViewStyle, + dropdownIconStyle, + ), }); }; diff --git a/app/component-library/components/Pickers/PickerBase/PickerBase.test.tsx b/app/component-library/components/Pickers/PickerBase/PickerBase.test.tsx index 662319adb46..94ec1e73255 100644 --- a/app/component-library/components/Pickers/PickerBase/PickerBase.test.tsx +++ b/app/component-library/components/Pickers/PickerBase/PickerBase.test.tsx @@ -1,18 +1,78 @@ // Third party dependencies. import React from 'react'; -import { View } from 'react-native'; -import { render } from '@testing-library/react-native'; +import { Text } from 'react-native'; +import { render, fireEvent } from '@testing-library/react-native'; // Internal dependencies. import PickerBase from './PickerBase'; +import { IconName, IconSize } from '../../Icons/Icon'; describe('PickerBase', () => { it('should render correctly', () => { const { toJSON } = render( - - + + Test Content , ); expect(toJSON()).toMatchSnapshot(); }); + + it('should call onPress when pressed', () => { + const onPressMock = jest.fn(); + const { getByText } = render( + + Test Content + , + ); + + fireEvent.press(getByText('Test Content')); + expect(onPressMock).toHaveBeenCalledTimes(1); + }); + + it('should render children correctly', () => { + const { getByText } = render( + + Child Component + , + ); + + expect(getByText('Child Component')).toBeTruthy(); + }); + + it('should render dropdown icon', () => { + const { UNSAFE_getByProps } = render( + + Test Content + , + ); + + const icon = UNSAFE_getByProps({ name: IconName.ArrowDown }); + expect(icon).toBeTruthy(); + }); + + it('should apply custom icon size', () => { + const { UNSAFE_getByProps } = render( + + Test Content + , + ); + + const icon = UNSAFE_getByProps({ + name: IconName.ArrowDown, + size: IconSize.Lg, + }); + expect(icon).toBeTruthy(); + }); + + it('should apply custom dropdown icon style', () => { + const customStyle = { marginLeft: 20 }; + const { UNSAFE_getByProps } = render( + + Test Content + , + ); + + const icon = UNSAFE_getByProps({ name: IconName.ArrowDown }); + expect(icon.props.style).toEqual(expect.objectContaining(customStyle)); + }); }); diff --git a/app/component-library/components/Pickers/PickerBase/PickerBase.tsx b/app/component-library/components/Pickers/PickerBase/PickerBase.tsx index 5488138d687..10d39f7be7e 100644 --- a/app/component-library/components/Pickers/PickerBase/PickerBase.tsx +++ b/app/component-library/components/Pickers/PickerBase/PickerBase.tsx @@ -15,15 +15,18 @@ import styleSheet from './PickerBase.styles'; const PickerBase: React.ForwardRefRenderFunction< TouchableOpacity, PickerBaseProps -> = ({ style, children, ...props }, ref) => { - const { styles, theme } = useStyles(styleSheet, { style }); +> = ( + { iconSize = IconSize.Md, style, dropdownIconStyle, children, ...props }, + ref, +) => { + const { styles, theme } = useStyles(styleSheet, { style, dropdownIconStyle }); const { colors } = theme; return ( {children} ; +export type PickerBaseStyleSheetVars = Pick< + PickerBaseProps, + 'style' | 'dropdownIconStyle' +>; diff --git a/app/component-library/components/Pickers/PickerBase/README.md b/app/component-library/components/Pickers/PickerBase/README.md index 74ec00f6ba7..ea5b298becd 100644 --- a/app/component-library/components/Pickers/PickerBase/README.md +++ b/app/component-library/components/Pickers/PickerBase/README.md @@ -1,10 +1,10 @@ # PickerBase -PickerBase is a **wrapper** component used for providing a dropdown icon next to wrapped content. +PickerBase is a **wrapper** component used for providing a dropdown icon next to wrapped content. It's designed to be a flexible base for various picker-style components. ## Props -This component extends `TouchableOpacityProps` from React Native's [TouchableOpacityProps](https://reactnative.dev/docs/touchableOpacity) opacity. +This component extends `TouchableOpacityProps` from React Native's [TouchableOpacity](https://reactnative.dev/docs/touchableopacity). ### `onPress` @@ -22,11 +22,55 @@ Content to wrap in PickerBase. | :-------------------------------------------------- | :------------------------------------------------------ | | ReactNode | Yes | +### `iconSize` + +Size of the dropdown icon. + +| TYPE | REQUIRED | DEFAULT | +| :-------------------------------------------------- | :------------------------------------------------------ | :----------------------------------------------------- | +| IconSize | No | IconSize.Md | + +### `dropdownIconStyle` + +Custom styles for the dropdown icon. + +| TYPE | REQUIRED | +| :-------------------------------------------------- | :------------------------------------------------------ | +| ViewStyle | No | + +### `style` + +Custom styles for the main container. + +| TYPE | REQUIRED | +| :-------------------------------------------------- | :------------------------------------------------------ | +| ViewStyle | No | + +## Usage + ```javascript -// Replace import with relative path. +import React from 'react'; +import { Text } from 'react-native'; import PickerBase from 'app/component-library/components/Pickers/PickerBase'; +import { IconSize } from 'app/component-library/components/Icons/Icon'; + +const ExampleComponent = () => ( + console.log('Picker pressed')} + iconSize={IconSize.Lg} + dropdownIconStyle={{ marginLeft: 20 }} + style={{ backgroundColor: 'lightgray' }} + > + Select an option + +); - - -; +export default ExampleComponent; ``` + +## Notes + +- The component uses a `TouchableOpacity` as its base, providing press feedback. +- It automatically includes a dropdown icon (ArrowDown) to the right of the content. +- The component is designed to be flexible and can be customized using the `style` and `dropdownIconStyle` props. +- The dropdown icon color is determined by the theme's `colors.icon.default`. \ No newline at end of file diff --git a/app/component-library/components/Pickers/PickerBase/__snapshots__/PickerBase.test.tsx.snap b/app/component-library/components/Pickers/PickerBase/__snapshots__/PickerBase.test.tsx.snap index f93ccf2a438..21db5a5774a 100644 --- a/app/component-library/components/Pickers/PickerBase/__snapshots__/PickerBase.test.tsx.snap +++ b/app/component-library/components/Pickers/PickerBase/__snapshots__/PickerBase.test.tsx.snap @@ -2,7 +2,7 @@ exports[`PickerBase should render correctly 1`] = ` - + + Test Content +