Skip to content

Commit 6633295

Browse files
committed
feat: add support for icon
1 parent 4637dfb commit 6633295

File tree

4 files changed

+70
-13
lines changed

4 files changed

+70
-13
lines changed

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
SelectPickerLoadingIndicator,
1111
SelectPickerMenu,
1212
SelectPickerOption,
13+
SelectPickerValueContainer,
1314
} from './common'
1415
import { SelectPickerOptionType, SelectPickerProps } from './type'
1516

@@ -20,6 +21,7 @@ const SelectPicker = ({
2021
helperText,
2122
placeholder = 'Select a option',
2223
label,
24+
showSelectedOptionIcon = true,
2325
...props
2426
}: SelectPickerProps) => {
2527
const { inputId, required } = props
@@ -33,15 +35,26 @@ const SelectPicker = ({
3335
)
3436

3537
const renderControl = useCallback(
36-
(controlProps: ControlProps) => <SelectPickerControl {...controlProps} icon={icon} />,
37-
[icon],
38+
(controlProps: ControlProps<SelectPickerOptionType>) => (
39+
<SelectPickerControl {...controlProps} icon={icon} showSelectedOptionIcon={showSelectedOptionIcon} />
40+
),
41+
[icon, showSelectedOptionIcon],
3842
)
3943

4044
const renderMenu = useCallback(
41-
(menuProps: MenuProps) => <SelectPickerMenu {...menuProps} renderMenuListFooter={renderMenuListFooter} />,
45+
(menuProps: MenuProps<SelectPickerOptionType>) => (
46+
<SelectPickerMenu {...menuProps} renderMenuListFooter={renderMenuListFooter} />
47+
),
4248
[],
4349
)
4450

51+
const renderValueContainer = useCallback(
52+
(valueContainerProps) => (
53+
<SelectPickerValueContainer {...valueContainerProps} showSelectedOptionIcon={showSelectedOptionIcon} />
54+
),
55+
[showSelectedOptionIcon],
56+
)
57+
4558
return (
4659
<div className="flex column left top dc__gap-4">
4760
{/* TODO Eshank: Common out for fields */}
@@ -73,7 +86,7 @@ const SelectPicker = ({
7386
Option: SelectPickerOption,
7487
Menu: renderMenu,
7588
ClearIndicator: SelectPickerClearIndicator,
76-
// TODO Eshank: need to export variants of ValueContainer: Icon, No Icon etc
89+
ValueContainer: renderValueContainer,
7790
}}
7891
styles={selectStyles}
7992
className="w-100"

src/Shared/Components/SelectPicker/common.tsx

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import {
55
OptionProps,
66
MenuProps,
77
ClearIndicatorProps,
8+
ValueContainerProps,
89
} from 'react-select'
910
import { Progressing } from '@Common/Progressing'
1011
import { ReactComponent as ICCaretDown } from '@Icons/ic-caret-down.svg'
1112
import { ReactComponent as ICClose } from '@Icons/ic-close.svg'
1213
import { SelectPickerOptionType, SelectPickerProps } from './type'
1314

14-
export const SelectPickerDropdownIndicator = (props: DropdownIndicatorProps) => {
15+
export const SelectPickerDropdownIndicator = (props: DropdownIndicatorProps<SelectPickerOptionType>) => {
1516
const { isDisabled } = props
1617

1718
return (
@@ -21,23 +22,52 @@ export const SelectPickerDropdownIndicator = (props: DropdownIndicatorProps) =>
2122
)
2223
}
2324

24-
export const SelectPickerClearIndicator = (props: ClearIndicatorProps) => (
25+
export const SelectPickerClearIndicator = (props: ClearIndicatorProps<SelectPickerOptionType>) => (
2526
<components.ClearIndicator {...props}>
2627
<ICClose className="icon-dim-16 fcn-6 dc__no-shrink" />
2728
</components.ClearIndicator>
2829
)
2930

30-
export const SelectPickerControl = ({ icon, ...props }: ControlProps & Pick<SelectPickerProps, 'icon'>) => {
31-
const { children } = props
31+
export const SelectPickerControl = ({
32+
icon,
33+
showSelectedOptionIcon,
34+
...props
35+
}: ControlProps<SelectPickerOptionType> & Pick<SelectPickerProps, 'icon' | 'showSelectedOptionIcon'>) => {
36+
const { children, getValue } = props
37+
const { startIcon, endIcon } = getValue()?.[0] ?? {}
38+
// Show the display icon if either the selected option icon is not to be shown or not available
39+
const showDisplayIcon = !!(icon && (!showSelectedOptionIcon || !(startIcon || endIcon)))
3240

3341
return (
3442
<components.Control {...props}>
35-
{icon && <div className="dc__no-shrink icon-dim-20 flex dc__fill-available-space">{icon}</div>}
43+
{showDisplayIcon && <div className="dc__no-shrink icon-dim-20 flex dc__fill-available-space">{icon}</div>}
3644
{children}
3745
</components.Control>
3846
)
3947
}
4048

49+
export const SelectPickerValueContainer = ({
50+
showSelectedOptionIcon,
51+
...props
52+
}: ValueContainerProps<SelectPickerOptionType> & Pick<SelectPickerProps, 'showSelectedOptionIcon'>) => {
53+
const { children, getValue, hasValue } = props
54+
const { startIcon, endIcon } = getValue()?.[0] ?? {}
55+
const showIcon = !!(showSelectedOptionIcon && hasValue && (startIcon || endIcon))
56+
57+
return (
58+
<components.ValueContainer {...props}>
59+
<div className="flex left dc__gap-8">
60+
{showIcon && (
61+
<div className="dc__no-shrink icon-dim-20 flex dc__fill-available-space">
62+
{startIcon || endIcon}
63+
</div>
64+
)}
65+
{children}
66+
</div>
67+
</components.ValueContainer>
68+
)
69+
}
70+
4171
export const SelectPickerLoadingIndicator = () => <Progressing />
4272

4373
export const SelectPickerOption = (props: OptionProps<SelectPickerOptionType>) => {
@@ -65,7 +95,7 @@ export const SelectPickerOption = (props: OptionProps<SelectPickerOptionType>) =
6595
export const SelectPickerMenu = ({
6696
renderMenuListFooter,
6797
...props
68-
}: MenuProps & Pick<SelectPickerProps, 'renderMenuListFooter'>) => {
98+
}: MenuProps<SelectPickerOptionType> & Pick<SelectPickerProps, 'renderMenuListFooter'>) => {
6999
const { children } = props
70100

71101
return (

src/Shared/Components/SelectPicker/type.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { OptionType } from '@Common/Types'
22
import { ReactElement, ReactNode } from 'react'
33
import { Props as ReactSelectProps } from 'react-select'
44

5-
// TODO Eshank: Add customization using generics
65
export interface SelectPickerOptionType extends OptionType<number | string, ReactNode> {
76
description?: string
87
startIcon?: ReactElement
@@ -11,6 +10,7 @@ export interface SelectPickerOptionType extends OptionType<number | string, Reac
1110

1211
type SelectProps = ReactSelectProps<SelectPickerOptionType>
1312

13+
// TODO Eshank: Add support for border less
1414
export interface SelectPickerProps
1515
extends Pick<
1616
SelectProps,
@@ -28,11 +28,17 @@ export interface SelectPickerProps
2828
| 'isLoading'
2929
| 'required'
3030
>,
31-
Required<Pick<SelectProps, 'classNamePrefix' | 'inputId'>> {
31+
Required<Pick<SelectProps, 'classNamePrefix' | 'inputId' | 'name'>> {
3232
icon?: ReactElement
3333
error?: ReactNode
3434
renderMenuListFooter?: () => ReactNode
3535
helperText?: ReactNode
3636
label?: ReactNode
37-
// TODO Eshank: Add support for border less
37+
/**
38+
* If true, the selected option icon is shown in the container.
39+
* startIcon has higher priority than endIcon.
40+
*
41+
* @default 'true'
42+
*/
43+
showSelectedOptionIcon?: boolean
3844
}

src/Shared/Components/SelectPicker/utils.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,12 @@ export const getCommonSelectStyle = ({ hasError }: { hasError: boolean }) => ({
122122
gap: '4px',
123123
flexShrink: 0,
124124
}),
125+
singleValue: (base) => ({
126+
...base,
127+
margin: 0,
128+
color: 'var(--N900)',
129+
fontSize: '13px',
130+
fontWeight: 400,
131+
lineHeight: '20px',
132+
}),
125133
})

0 commit comments

Comments
 (0)