Skip to content

Commit

Permalink
Feat/picker custom top element (#3465)
Browse files Browse the repository at this point in the history
* Picker types - customTopElement, onItemSelection

* add customTopElement support in Picker component

* PickerScreen example

* refactor: rename customTopElement, types fix

* remove onItemSelection prop

* remove unused setValue from Picker context

* use optional chaining for renderCustomTopElement

* renderCustomTopElement added to api.json
  • Loading branch information
adids1221 authored Jan 19, 2025
1 parent c2bc66c commit ee21567
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 2 deletions.
46 changes: 45 additions & 1 deletion demo/src/screens/componentScreens/PickerScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ const dialogOptions = [
{label: 'Option 8', value: 6}
];

const statusOptions = [
{label: 'Overview', value: 'overview'},
{label: 'In Progress', value: 'inProgress'},
{label: 'Completed', value: 'completed'},
{label: 'Pending Review', value: 'pendingReview'},
{label: 'Approved', value: 'approved'},
{label: 'Rejected', value: 'rejected'}
];

export default class PickerScreen extends Component {
picker = React.createRef<PickerMethods>();
state = {
Expand All @@ -96,6 +105,7 @@ export default class PickerScreen extends Component {
dialogPickerValue: 'java',
customModalValues: [],
filter: undefined,
statOption: [],
scheme: undefined,
contact: 0
};
Expand All @@ -122,6 +132,15 @@ export default class PickerScreen extends Component {
);
};

onTopElementPress = (allOptionsSelected: boolean) => {
if (allOptionsSelected) {
this.setState({statOption: []});
} else {
const allValues = statusOptions.map(option => option.value);
this.setState({statOption: allValues});
}
};

render() {
return (
<ScrollView keyboardShouldPersistTaps="always">
Expand Down Expand Up @@ -195,7 +214,32 @@ export default class PickerScreen extends Component {
searchPlaceholder={'Search a language'}
items={dialogOptions}
/>


<Text text70 $textDefault>
Custom Top Element:
</Text>
<Picker
placeholder="Status"
floatingPlaceholder
value={this.state.statOption}
onChange={items => this.setState({statOption: items})}
topBarProps={{title: 'Status'}}
mode={Picker.modes.MULTI}
items={statusOptions}
renderCustomTopElement={value => {
const allOptionsSelected = Array.isArray(value) && value.length === statusOptions.length;
return (
<View margin-s3>
<Button
label={allOptionsSelected ? 'Unselect All' : 'Select All'}
onPress={() => this.onTopElementPress(allOptionsSelected)}
size="small"
/>
</View>
);
}}
/>

<Text marginB-10 text70 $textDefault>
Custom Picker:
</Text>
Expand Down
4 changes: 3 additions & 1 deletion src/components/picker/PickerItemsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ const PickerItemsList = (props: PickerItemsListProps) => {
mode,
testID,
showLoader,
customLoaderElement
customLoaderElement,
renderCustomTopElement
} = props;
const context = useContext(PickerContext);

Expand Down Expand Up @@ -167,6 +168,7 @@ const PickerItemsList = (props: PickerItemsListProps) => {
) : (
<>
{renderSearchInput()}
{renderCustomTopElement?.(context.value)}
{renderList()}
</>
);
Expand Down
5 changes: 5 additions & 0 deletions src/components/picker/api/picker.api.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@
"type": "(value, {{...props, isSelected}}, itemLabel) => void",
"description": "Render custom picker item"
},
{
"name": "renderCustomTopElement",
"type": "(value?: PickerValue) => React.ReactElement",
"description": "Render custom top element"
},
{
"name": "renderCustomModal",
"type": "({visible, children, toggleModal}) => void)",
Expand Down
2 changes: 2 additions & 0 deletions src/components/picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
items: propItems,
showLoader,
customLoaderElement,
renderCustomTopElement,
...others
} = themeProps;
const {preset, placeholder, style, trailingAccessory, label: propsLabel} = others;
Expand Down Expand Up @@ -245,6 +246,7 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
useSafeArea={useSafeArea}
showLoader={showLoader}
customLoaderElement={customLoaderElement}
renderCustomTopElement={renderCustomTopElement}
>
{filteredItems}
</PickerItemsList>
Expand Down
5 changes: 5 additions & 0 deletions src/components/picker/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ export type PickerBaseProps = Omit<TextFieldProps, 'value' | 'onChange'> &
itemProps: PickerItemProps & {isSelected: boolean; isItemDisabled: boolean},
label?: string
) => React.ReactElement;
/**
* Render custom top element
*/
renderCustomTopElement?: (value?: PickerValue) => React.ReactElement;
/**
* Add onPress callback for when pressing the picker
*/
Expand Down Expand Up @@ -315,6 +319,7 @@ export type PickerItemsListProps = Pick<
| 'useSafeArea'
| 'showLoader'
| 'customLoaderElement'
| 'renderCustomTopElement'
| 'showSearch'
| 'searchStyle'
| 'searchPlaceholder'
Expand Down

0 comments on commit ee21567

Please sign in to comment.