Skip to content

Commit

Permalink
Picker - fix usePickerLabel (#3162)
Browse files Browse the repository at this point in the history
* Picker - usePickerLabel - fix 'value' is not returned in case the are no 'items'

* format

* change condition

* check items first

* spaces

* remove redaundent check for undefined

* add hook tests
  • Loading branch information
Inbal-Tish authored Jul 7, 2024
1 parent 4232371 commit 03ca7ff
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 15 deletions.
5 changes: 5 additions & 0 deletions demo/src/screens/componentScreens/PickerScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const dialogOptions = [
{label: 'Option 7', value: 6},
{label: 'Option 8', value: 6}
];

export default class PickerScreen extends Component {
picker = React.createRef<PickerMethods>();
state = {
Expand Down Expand Up @@ -128,6 +129,7 @@ export default class PickerScreen extends Component {
<Text text40 $textDefault>
Picker
</Text>

<Picker
placeholder="Favorite Language"
floatingPlaceholder
Expand Down Expand Up @@ -194,6 +196,7 @@ export default class PickerScreen extends Component {
searchPlaceholder={'Search a language'}
items={dialogOptions}
/>

<Text marginB-10 text70 $textDefault>
Custom Picker:
</Text>
Expand All @@ -216,6 +219,7 @@ export default class PickerScreen extends Component {
}}
items={filters}
/>

<Text marginT-20 marginB-10 text70 $textDefault>
Custom Picker Items:
</Text>
Expand Down Expand Up @@ -252,6 +256,7 @@ export default class PickerScreen extends Component {
style={{alignSelf: 'flex-start'}}
onPress={() => this.picker.current?.openExpandable?.()}
/>

<Text text60 marginT-s5>
Different Field Types
</Text>
Expand Down
75 changes: 75 additions & 0 deletions src/components/picker/helpers/__tests__/usePickerLabel.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {renderHook} from '@testing-library/react-hooks';
import usePickerLabel from '../usePickerLabel';

const colors = [
{value: 'red', label: 'Red'},
{
value: 'green',
label: 'Green',
listItemProps: {subtitle: 'Subtitle'}
},
{
value: 'blue',
label: 'Blue',
listItemProps: {
subtitleLines: 2,
subtitle: 'Subtitle with\n2 lines of text'
}
},
{value: 'purple', label: 'Purple', disabled: true},
{value: 'yellow', label: 'Yellow'},
{value: 'grey', label: 'Grey'}
];

describe('usePickerLabel hook tests', () => {
const makeSUT = ({
value,
items,
getLabel
// getItemLabel,
// accessibilityLabel,
// accessibilityHint,
// placeholder
}) => {
return renderHook(() =>
usePickerLabel({
value,
items,
getLabel
// getItemLabel,
// accessibilityLabel,
// accessibilityHint,
// placeholder
}));
};

it('expect label to equal an empty string when value is undefined', () => {
const sut = makeSUT({items: colors, value: undefined, getLabel: undefined});
expect(sut.result.current.label).toEqual('');
});

it('expect label to equal an empty string when value is null', () => {
const sut = makeSUT({items: colors, value: null, getLabel: undefined});
expect(sut.result.current.label).toEqual('');
});

it('expect label to equal returned string when getLabel passed', () => {
const sut = makeSUT({items: colors, value: null, getLabel: () => 'Some label'});
expect(sut.result.current.label).toEqual('Some label');
});

it('expect label to equal array of values when value is array', () => {
const sut = makeSUT({items: colors, value: ['red', 'green'], getLabel: undefined});
expect(sut.result.current.label).toEqual('Red, Green');
});

it('expect label to equal selected item label when value equals item value', () => {
const sut = makeSUT({items: colors, value: 'red', getLabel: undefined});
expect(sut.result.current.label).toEqual('Red');
});

it('expect label to equal value when no items passed', () => {
const sut = makeSUT({items: undefined, value: 'Some string', getLabel: undefined});
expect(sut.result.current.label).toEqual('Some string');
});
});
26 changes: 11 additions & 15 deletions src/components/picker/helpers/usePickerLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {useCallback, useMemo} from 'react';
import _ from 'lodash';
import {useCallback, useMemo} from 'react';
import {PickerProps, PickerValue} from '../types';

interface UsePickerLabelProps
Expand All @@ -15,12 +15,10 @@ const usePickerLabel = (props: UsePickerLabelProps) => {

const getLabelsFromArray = useCallback((value: PickerValue) => {
const itemsByValue = _.keyBy(items, 'value');

return _.flow(arr =>
_.map(arr, item => (_.isPlainObject(item) ? getItemLabel?.(item) || item?.label : itemsByValue[item]?.label)),
arr => _.join(arr, ', '))(value);
},
[getItemLabel, items]);
}, [getItemLabel, items]);

const _getLabel = useCallback((value: PickerValue) => {
if (_.isFunction(getLabel) && !_.isUndefined(getLabel(value))) {
Expand All @@ -31,17 +29,15 @@ const usePickerLabel = (props: UsePickerLabelProps) => {
return getLabelsFromArray(value);
}

// TODO: Remove
// if (typeof value === 'object') {
// return value?.label;
// }

// otherwise, extract from picker items
const selectedItem = _.find(items, {value});
if (!_.isEmpty(items)) {
const selectedItem = _.find(items, {value});
return _.get(selectedItem, 'label');
}

return _.get(selectedItem, 'label');
},
[getLabelsFromArray, items]);
if (typeof value === 'string') {
return value;
}
}, [getLabel, getLabelsFromArray, items]);

const accessibilityInfo = useMemo(() => {
const label = _getLabel(value);
Expand All @@ -51,7 +47,7 @@ const usePickerLabel = (props: UsePickerLabelProps) => {
accessibilityHint:
accessibilityHint ?? (label ? 'Double tap to edit' : `Goes to ${placeholder}. Suggestions will be provided`)
};
}, [value, accessibilityLabel, accessibilityHint]);
}, [value, placeholder, accessibilityLabel, accessibilityHint, _getLabel]);

return {
getLabelsFromArray,
Expand Down

0 comments on commit 03ca7ff

Please sign in to comment.