Skip to content

Commit 8505bbf

Browse files
authored
Feat/Picker selectionLimit prop (#1270)
1 parent 6c27caf commit 8505bbf

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

demo/src/screens/componentScreens/PickerScreen.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,11 @@ export default class PickerScreen extends Component {
101101

102102
<Picker
103103
marginT-20
104-
placeholder="Favorite Languages"
104+
placeholder="Favorite Languages (up to 3)"
105105
value={this.state.languages}
106106
onChange={items => this.setState({languages: items})}
107107
mode={Picker.modes.MULTI}
108+
selectionLimit={3}
108109
rightIconSource={dropdown}
109110
>
110111
{_.map(options, option => (

src/components/picker/PickerItem.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ const PickerItem = props => {
3434
const itemValue = !migrate && _.isPlainObject(value) ? value?.value : value;
3535
const isSelected = isItemSelected(itemValue, context.value);
3636
const itemLabel = getItemLabel(label, value, props.getItemLabel || context.getItemLabel);
37+
const selectedCounter = context.selectionLimit && context.value?.length;
3738
const accessibilityProps = {
3839
accessibilityState: isSelected ? {selected: true} : undefined,
3940
accessibilityHint: 'Double click to select this suggestion',
4041
...Modifiers.extractAccessibilityProps(props)
4142
};
4243

44+
const isItemDisabled = useMemo(() => {
45+
return disabled || (!isSelected && context.selectionLimit && context.selectionLimit === selectedCounter);
46+
}, [selectedCounter]);
47+
4348
useEffect(() => {
4449
if (_.isPlainObject(value)) {
4550
LogService.warn('UILib Picker.Item will stop supporting passing object as value & label (e.g {value, label}) in the next major version. Please pass separate label and value props');
@@ -48,9 +53,9 @@ const PickerItem = props => {
4853

4954
const selectedIndicator = useMemo(() => {
5055
if (isSelected) {
51-
return <Image source={selectedIcon} tintColor={disabled ? Colors.dark60 : selectedIconColor}/>;
56+
return <Image source={selectedIcon} tintColor={isItemDisabled ? Colors.dark60 : selectedIconColor}/>;
5257
}
53-
}, [isSelected, disabled, selectedIcon, selectedIconColor]);
58+
}, [isSelected, isItemDisabled, selectedIcon, selectedIconColor]);
5459

5560
const _onPress = useCallback(() => {
5661
if (migrate) {
@@ -67,7 +72,7 @@ const PickerItem = props => {
6772
const _renderItem = () => {
6873
return (
6974
<View style={styles.container} flex row spread centerV>
70-
<Text numberOfLines={1} style={[styles.labelText, disabled && styles.labelTextDisabled]}>
75+
<Text numberOfLines={1} style={[styles.labelText, isItemDisabled && styles.labelTextDisabled]}>
7176
{itemLabel}
7277
</Text>
7378
{selectedIndicator}
@@ -84,7 +89,7 @@ const PickerItem = props => {
8489
activeOpacity={0.5}
8590
onPress={_onPress}
8691
onLayout={isSelected ? onSelectedLayout : undefined}
87-
disabled={disabled}
92+
disabled={isItemDisabled}
8893
testID={testID}
8994
throttleTime={0}
9095
{...accessibilityProps}

src/components/picker/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ class Picker extends Component {
5959
* SINGLE mode or MULTI mode
6060
*/
6161
mode: PropTypes.oneOf(Object.keys(PICKER_MODES)),
62+
/**
63+
* Limit the number of selected items
64+
*/
65+
selectionLimit: PropTypes.number,
6266
/**
6367
* Adds blur effect to picker modal (iOS only)
6468
*/
@@ -217,7 +221,7 @@ class Picker extends Component {
217221

218222
getContextValue = () => {
219223
const {value, searchValue} = this.state;
220-
const {migrate, mode, getItemValue, getItemLabel, renderItem, showSearch} = this.props;
224+
const {migrate, mode, getItemValue, getItemLabel, renderItem, showSearch, selectionLimit} = this.props;
221225
const pickerValue = !migrate && _.isPlainObject(value) ? value?.value : value;
222226
return {
223227
migrate,
@@ -229,7 +233,8 @@ class Picker extends Component {
229233
onSelectedLayout: this.onSelectedItemLayout,
230234
renderItem,
231235
showSearch,
232-
searchValue
236+
searchValue,
237+
selectionLimit
233238
};
234239
};
235240

0 commit comments

Comments
 (0)