Skip to content

Commit e2e5c0b

Browse files
authored
Picker - fieldType - fix and align to UX guidelines (#3175)
* Picker - fieldType - fix and align to UX guidelines * fix label when undefined
1 parent 34186d0 commit e2e5c0b

File tree

4 files changed

+37
-33
lines changed

4 files changed

+37
-33
lines changed

demo/src/screens/componentScreens/PickerScreen.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ export default class PickerScreen extends Component {
9595
wheelPickerValue: 'java',
9696
dialogPickerValue: 'java',
9797
customModalValues: [],
98-
filter: filters[0].value,
99-
scheme: schemes[0].value,
98+
filter: undefined,
99+
scheme: undefined,
100100
contact: 0
101101
};
102102

@@ -266,6 +266,7 @@ export default class PickerScreen extends Component {
266266
<Picker
267267
value={this.state.filter}
268268
onChange={value => this.setState({filter: value})}
269+
label="Your Posts"
269270
placeholder="Filter posts"
270271
fieldType={Picker.fieldTypes.filter}
271272
marginB-s3
@@ -275,7 +276,7 @@ export default class PickerScreen extends Component {
275276
value={this.state.scheme}
276277
onChange={value => this.setState({scheme: value})}
277278
label="Color Scheme"
278-
placeholder="Filter posts"
279+
placeholder="Select scheme"
279280
fieldType={Picker.fieldTypes.settings}
280281
items={schemes}
281282
/>

src/components/picker/__tests__/index.spec.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import React, {useState} from 'react';
22
import {act, render, waitFor, screen} from '@testing-library/react-native';
33
import Picker from '../index';
44
import {PickerDriver} from '../Picker.driver.new';
5+
56
const countries = [
67
{label: 'Israel', value: 'IL'},
78
{label: 'United States', value: 'US'},
89
{label: 'Germany', value: 'DE'},
910
{label: 'Italy', value: 'IT'},
1011
{label: 'Spain', value: 'ES '}
1112
];
12-
1313
const testID = 'picker';
1414

1515
const TestCase = (props?: any) => {
@@ -159,6 +159,7 @@ describe('Picker', () => {
159159

160160
describe('Dialog', () => {
161161
const dialogProps = {useDialog: true, customPickerProps: {migrateDialog: true}};
162+
162163
describe('Test value', () => {
163164
it('Get correct value of a single item', () => {
164165
const driver = getDriver({
@@ -257,6 +258,7 @@ describe('Picker', () => {
257258
describe('Picker field types', () => {
258259
describe('Test filter field type', () => {
259260
const placeholderText = 'Select a Filter';
261+
260262
it('should render a filter picker', () => {
261263
const driver = getDriver({fieldType: 'filter', placeholder: placeholderText});
262264
expect(driver.isOpen()).toBeFalsy();
@@ -265,28 +267,32 @@ describe('Picker', () => {
265267
expect(label.props.children).toEqual(placeholderText);
266268
});
267269
});
270+
268271
describe('Test settings field type', () => {
269272
const labelText = 'Settings';
270273
const placeholderText = 'Select a setting';
274+
271275
it('should render a settings picker with label', async () => {
272276
const driver = getDriver({fieldType: 'settings', label: labelText, placeholder: placeholderText});
273-
expect(driver.isOpen()).toBeFalsy();
274277
const label = screen.getByTestId(`${testID}.settings.type.label`);
275278
const placeholder = screen.getByTestId(`${testID}.settings.type.placeholder`);
279+
280+
expect(driver.isOpen()).toBeFalsy();
276281
expect(label).toBeTruthy();
277282
expect(placeholder).toBeTruthy();
278283
expect(label.props.children).toEqual(labelText);
279-
expect(placeholder.props.children).toEqual(labelText);
284+
expect(placeholder.props.children).toEqual(placeholderText);
280285
});
281286

282287
it('should render a settings picker with placeholder', async () => {
283288
const driver = getDriver({fieldType: 'settings', placeholder: placeholderText});
284-
expect(driver.isOpen()).toBeFalsy();
285289
const label = screen.getByTestId(`${testID}.settings.type.label`);
286290
const placeholder = screen.getByTestId(`${testID}.settings.type.placeholder`);
291+
292+
expect(driver.isOpen()).toBeFalsy();
287293
expect(label).toBeTruthy();
288294
expect(placeholder).toBeTruthy();
289-
expect(label.props.children).toEqual(undefined);
295+
expect(label.props.children).toEqual(placeholderText);
290296
expect(placeholder.props.children).toEqual(placeholderText);
291297
});
292298
});

src/components/picker/helpers/useFieldType.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
import _ from 'lodash';
22
import React, {useMemo} from 'react';
3-
import Icon from '../../icon';
4-
import Text from '../../text';
3+
import {Typography, Colors} from '../../../style';
54
import View from '../../view';
5+
import Text from '../../text';
6+
import Icon from '../../icon';
67
import {PickerProps, PickerFieldTypes} from '../types';
7-
import {Typography} from '../../../style';
88

99
type UseFieldTypeProps = Pick<
1010
PickerProps,
11-
'fieldType' | 'preset' | 'trailingAccessory' | 'label' | 'placeholder' | 'style' | 'labelStyle' | 'testID'
11+
'fieldType' | 'preset' | 'trailingAccessory' | 'value' | 'label' | 'placeholder' | 'style' | 'labelStyle' | 'testID'
1212
>;
1313

1414
const dropdown = require('../assets/dropdown.png');
1515

1616
const useFieldType = (props: UseFieldTypeProps) => {
17-
const {fieldType, preset, trailingAccessory, label, placeholder, style, labelStyle, testID} = props;
17+
const {fieldType, preset, trailingAccessory, value, placeholder, style, label, labelStyle, testID} = props;
1818

1919
const propsByFieldType = useMemo(() => {
2020
if (fieldType === PickerFieldTypes.filter) {
2121
return {
2222
preset: preset || null,
2323
containerStyle: {flexDirection: 'row'},
24-
labelStyle: Typography.text70,
24+
label: label && `${label}: `,
25+
labelStyle: {...Typography.text70, color: Colors.$textNeutral},
2526
trailingAccessory: trailingAccessory ?? <Icon marginL-s1 source={dropdown}/>
2627
};
2728
} else if (fieldType === PickerFieldTypes.settings) {
@@ -30,28 +31,28 @@ const useFieldType = (props: UseFieldTypeProps) => {
3031
label: undefined
3132
};
3233
}
33-
}, [fieldType, preset, trailingAccessory]);
34+
}, [fieldType, preset, trailingAccessory, label]);
3435

3536
const pickerInnerInput = useMemo(() => {
3637
if (fieldType === PickerFieldTypes.filter) {
3738
return (
3839
<Text text70 numberOfLines={1} style={style} testID={`${testID}.filter.type.label`}>
39-
{_.isEmpty(label) ? placeholder : label}
40+
{_.isEmpty(value) ? placeholder : value}
4041
</Text>
4142
);
4243
} else if (fieldType === PickerFieldTypes.settings) {
4344
return (
4445
<View flexG row spread>
4546
<Text text70 style={labelStyle} testID={`${testID}.settings.type.label`}>
46-
{label}
47+
{label || placeholder}
4748
</Text>
4849
<Text text70 $textPrimary style={style} testID={`${testID}.settings.type.placeholder`}>
49-
{_.isEmpty(label) ? placeholder : label}
50+
{_.isEmpty(value) ? placeholder : value}
5051
</Text>
5152
</View>
5253
);
5354
}
54-
}, [style, labelStyle, fieldType, placeholder, label]);
55+
}, [style, labelStyle, fieldType, placeholder, value, label, testID]);
5556

5657
return {propsByFieldType, pickerInnerInput};
5758
};

src/components/picker/index.tsx

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
// TODO: deprecate all places where we check if _.isPlainObject
2-
// TODO: deprecate getItemValue prop
3-
// TODO: deprecate getItemLabel prop
42
// TODO: Add initialValue prop
53
// TODO: consider deprecating renderCustomModal prop
64
import _ from 'lodash';
@@ -80,29 +78,28 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
8078
items: propItems,
8179
...others
8280
} = themeProps;
83-
const {preset} = others;
81+
const {preset, placeholder, style, trailingAccessory, label: propsLabel} = others;
8482
const {renderHeader, renderInput, renderOverlay, customPickerProps} = useNewPickerProps(themeProps);
85-
8683
const [selectedItemPosition, setSelectedItemPosition] = useState<number>(0);
8784
const [items, setItems] = useState<PickerItemProps[]>(propItems || extractPickerItems(themeProps));
88-
85+
const pickerExpandable = useRef<ExpandableOverlayMethods>(null);
86+
const pickerRef = useImperativePickerHandle(ref, pickerExpandable);
87+
88+
// TODO: Remove this when migration is completed, starting of v8
89+
// usePickerMigrationWarnings({children, migrate, getItemLabel, getItemValue});
90+
8991
useEffect(() => {
9092
if (propItems) {
9193
setItems(propItems);
9294
}
9395
}, [propItems]);
9496

95-
const pickerExpandable = useRef<ExpandableOverlayMethods>(null);
96-
97-
// TODO: Remove this when migration is completed, starting of v8
98-
// usePickerMigrationWarnings({children, migrate, getItemLabel, getItemValue});
99-
100-
const pickerRef = useImperativePickerHandle(ref, pickerExpandable);
10197
const {
10298
filteredChildren,
10399
setSearchValue,
104100
onSearchChange: _onSearchChange
105101
} = usePickerSearch({showSearch, onSearchChange, getItemLabel, children});
102+
106103
const {multiDraftValue, onDoneSelecting, toggleItemSelection, cancelSelect} = usePickerSelection({
107104
migrate,
108105
value,
@@ -114,8 +111,6 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
114111
mode
115112
});
116113

117-
const {placeholder, style, trailingAccessory, label: propsLabel} = themeProps;
118-
119114
const {label, accessibilityInfo} = usePickerLabel({
120115
value,
121116
items,
@@ -133,7 +128,8 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
133128
style,
134129
placeholder,
135130
labelStyle,
136-
label: label || propsLabel,
131+
label: propsLabel,
132+
value: label,
137133
testID
138134
});
139135

0 commit comments

Comments
 (0)