Skip to content

Commit ed37b0e

Browse files
committed
feat: add support for menuListFooterConfig instead of renderMenuListFooter
1 parent 4f2db95 commit ed37b0e

File tree

4 files changed

+77
-16
lines changed

4 files changed

+77
-16
lines changed

src/Shared/Components/SelectPicker/SelectPicker.component.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import { SelectPickerOptionType, SelectPickerProps, SelectPickerVariantType } fr
4444
import { GenericSectionErrorState } from '../GenericSectionErrorState'
4545
import FormFieldWrapper from '../FormFieldWrapper/FormFieldWrapper'
4646
import { getFormFieldAriaAttributes } from '../FormFieldWrapper'
47+
import './selectPicker.scss'
4748

4849
/**
4950
* Generic component for select picker
@@ -83,16 +84,15 @@ import { getFormFieldAriaAttributes } from '../FormFieldWrapper'
8384
* <SelectPicker ... helperText="Help information" />
8485
* ```
8586
*
86-
* @example Menu list footer
87+
* @example Menu list footer config
8788
* The footer is sticky by default
8889
* ```tsx
8990
* <SelectPicker
9091
* ...
91-
* renderMenuListFooter={() => (
92-
* <div className="px-8 py-6 dc__border-top bg__secondary cn-6">
93-
* <div>Foot note</div>
94-
* </div>
95-
* )}
92+
* menuListFooterConfig={{
93+
* type: 'text',
94+
* value: 'Info text',
95+
* }}
9696
* />
9797
* ```
9898
*
@@ -206,7 +206,7 @@ const SelectPicker = <OptionValue, IsMulti extends boolean>({
206206
shouldMenuAlignRight = false,
207207
fullWidth = false,
208208
customSelectedOptionsCount = null,
209-
renderMenuListFooter,
209+
menuListFooterConfig,
210210
isCreatable = false,
211211
onCreateOption,
212212
closeMenuOnSelect = false,
@@ -460,7 +460,7 @@ const SelectPicker = <OptionValue, IsMulti extends boolean>({
460460
isValidNewOption={isValidNewOption}
461461
createOptionPosition="first"
462462
onCreateOption={handleCreateOption}
463-
renderMenuListFooter={!optionListError && renderMenuListFooter}
463+
menuListFooterConfig={!optionListError ? menuListFooterConfig : null}
464464
inputValue={props.inputValue ?? inputValue}
465465
onInputChange={handleInputChange}
466466
icon={icon}

src/Shared/Components/SelectPicker/common.tsx

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@ import { ReactSelectInputAction } from '@Common/Constants'
3939
import { isNullOrUndefined } from '@Shared/Helpers'
4040
import { Tooltip } from '@Common/Tooltip'
4141
import { TooltipProps } from '@Common/Tooltip/types'
42+
import { ComponentSizeType } from '@Shared/constants'
4243
import { SelectPickerGroupHeadingProps, SelectPickerOptionType, SelectPickerProps } from './type'
4344
import { getGroupCheckboxValue } from './utils'
45+
import { Icon } from '../Icon'
46+
import { Button, ButtonProps } from '../Button'
4447

4548
const getTooltipProps = (tooltipProps: SelectPickerOptionType['tooltipProps'] = {}): TooltipProps => {
4649
if (tooltipProps) {
@@ -242,12 +245,46 @@ export const SelectPickerOption = <OptionValue, IsMulti extends boolean>({
242245
)
243246
}
244247

248+
const SelectPickerMenuListFooter = ({
249+
menuListFooterConfig,
250+
}: Required<Pick<SelectPickerProps, 'menuListFooterConfig'>>) => {
251+
if (!menuListFooterConfig) {
252+
return null
253+
}
254+
255+
const { type } = menuListFooterConfig
256+
257+
if (type === 'text') {
258+
const { value } = menuListFooterConfig
259+
260+
return (
261+
<div className="flex left dc__gap-6">
262+
<Icon name="ic-info-outline" color="N700" size={16} />
263+
<p className="fs-12 fw-4 fs-16 cn-8 dc__truncate">{value}</p>
264+
</div>
265+
)
266+
}
267+
268+
if (type === 'button') {
269+
const { buttonProps } = menuListFooterConfig
270+
271+
return (
272+
// We are adding justify-content: flex-start for secondary variant
273+
<div className={`select-picker__menu-list-footer-button--${buttonProps.variant}`}>
274+
<Button {...(buttonProps as ButtonProps)} size={ComponentSizeType.small} fullWidth />
275+
</div>
276+
)
277+
}
278+
279+
return null
280+
}
281+
245282
export const SelectPickerMenuList = <OptionValue,>(props: MenuListProps<SelectPickerOptionType<OptionValue>>) => {
246283
const {
247284
children,
248285
selectProps: {
249286
inputValue,
250-
renderMenuListFooter,
287+
menuListFooterConfig,
251288
shouldRenderCustomOptions,
252289
renderCustomOptions,
253290
renderOptionsFooter,
@@ -270,9 +307,9 @@ export const SelectPickerMenuList = <OptionValue,>(props: MenuListProps<SelectPi
270307
</div>
271308
{/* Added to the bottom of menu list to prevent from hiding when the menu is opened close to the bottom of the screen */}
272309
</components.MenuList>
273-
{!shouldRenderCustomOptions && renderMenuListFooter && (
274-
<div className="dc__position-sticky dc__bottom-0 dc__bottom-radius-4 bg__menu--primary dc__zi-2">
275-
{renderMenuListFooter()}
310+
{!shouldRenderCustomOptions && menuListFooterConfig && (
311+
<div className="dc__position-sticky dc__bottom-0 dc__bottom-radius-4 bg__menu--primary dc__zi-2 p-8 dc__border-top-n1">
312+
<SelectPickerMenuListFooter menuListFooterConfig={menuListFooterConfig} />
276313
</div>
277314
)}
278315
</>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.select-picker {
2+
&__menu-list-footer-button {
3+
&--secondary {
4+
button {
5+
justify-content: flex-start;
6+
}
7+
}
8+
}
9+
}

src/Shared/Components/SelectPicker/type.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type {} from 'react-select/base'
2525
import { TooltipProps } from '@Common/Tooltip/types'
2626
import { ResizableTagTextAreaProps } from '@Common/CustomTagSelector'
2727
import { FormFieldWrapperProps } from '../FormFieldWrapper/types'
28+
import { ButtonProps, ButtonVariantType } from '../Button'
2829

2930
export interface SelectPickerOptionType<OptionValue = string | number> extends OptionType<OptionValue, ReactNode> {
3031
/**
@@ -54,17 +55,31 @@ type SelectProps<OptionValue, IsMulti extends boolean> = ReactSelectProps<
5455
GroupBase<SelectPickerOptionType<OptionValue>>
5556
>
5657

58+
export type MenuListFooterConfigType =
59+
| {
60+
type: 'text'
61+
value: string
62+
buttonProps?: never
63+
}
64+
| {
65+
type: 'button'
66+
value?: never
67+
buttonProps: {
68+
variant: ButtonVariantType.primary | ButtonVariantType.secondary
69+
} & Omit<ButtonProps, 'size' | 'fullWidth' | 'icon' | 'endIcon' | 'variant'>
70+
}
71+
5772
declare module 'react-select/base' {
5873
// eslint-disable-next-line @typescript-eslint/no-unused-vars
5974
export interface Props<Option, IsMulti extends boolean, Group extends GroupBase<Option>> {
6075
/**
61-
* Render function for the footer at the bottom of menu list. It is sticky by default
76+
* Config for the footer at the bottom of menu list. It is sticky by default
6277
*/
63-
renderMenuListFooter?: () => ReactNode
78+
menuListFooterConfig?: MenuListFooterConfigType
6479
/**
6580
* If true, custom options are rendered in the menuList component of react select
6681
*
67-
* Note: renderCustomOptions is required to be passed; renderMenuListFooter is also not called
82+
* Note: renderCustomOptions is required to be passed; menuListFooterConfig is also not used
6883
*
6984
* @default false
7085
*/
@@ -147,7 +162,7 @@ export type SelectPickerProps<OptionValue = number | string, IsMulti extends boo
147162
Partial<
148163
Pick<
149164
SelectProps<OptionValue, IsMulti>,
150-
| 'renderMenuListFooter'
165+
| 'menuListFooterConfig'
151166
| 'shouldRenderCustomOptions'
152167
| 'renderCustomOptions'
153168
| 'icon'

0 commit comments

Comments
 (0)