Skip to content

Commit 2765b54

Browse files
committed
feat: add intermediate checkbox value in group heading select picker
1 parent f853d79 commit 2765b54

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

src/Shared/Components/SelectPicker/common.tsx

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { CHECKBOX_VALUE } from '@Common/Types'
2121
import { Checkbox } from '@Common/Checkbox'
2222
import { ReactSelectInputAction } from '@Common/Constants'
2323
import { SelectPickerOptionType, SelectPickerProps } from './type'
24+
import { getGroupCheckboxValue } from './utils'
2425

2526
export const SelectPickerDropdownIndicator = (props: DropdownIndicatorProps<SelectPickerOptionType>) => {
2627
const { isDisabled } = props
@@ -207,24 +208,16 @@ export const SelectPickerGroupHeading = ({
207208
const selectedOptions = (selectProps.value as MultiValue<SelectPickerOptionType>) ?? []
208209
const groupHeadingOptions = data.options ?? []
209210

210-
const selectedOptionsMapByValue = selectedOptions.reduce<Record<string, true>>((acc, option) => {
211-
acc[selectProps.getOptionValue(option)] = true
212-
return acc
213-
}, {})
214-
215-
const isGroupSelected =
216-
isGroupHeadingSelectable &&
217-
groupHeadingOptions
218-
.map((option) => selectProps.getOptionValue(option))
219-
.every((value) => selectedOptionsMapByValue[value])
211+
const checkboxValue = getGroupCheckboxValue(groupHeadingOptions, selectedOptions, selectProps.getOptionValue)
220212

221213
const toggleGroupHeadingSelection = () => {
222214
const groupOptionsMapByValue = groupHeadingOptions.reduce<Record<string, true>>((acc, option) => {
223215
acc[selectProps.getOptionValue(option)] = true
224216
return acc
225217
}, {})
226218

227-
if (isGroupSelected) {
219+
// Clear all the selection(s) in the group if any of the option is selected
220+
if (checkboxValue) {
228221
selectProps?.onChange?.(
229222
selectedOptions.filter(
230223
(selectedOption) => !groupOptionsMapByValue[selectProps.getOptionValue(selectedOption)],
@@ -238,6 +231,7 @@ export const SelectPickerGroupHeading = ({
238231
return
239232
}
240233

234+
// Select all options
241235
selectProps?.onChange?.(
242236
[
243237
...selectedOptions.filter(
@@ -267,8 +261,8 @@ export const SelectPickerGroupHeading = ({
267261
<Checkbox
268262
onChange={noop}
269263
onClick={handleToggleCheckbox}
270-
isChecked={isGroupSelected}
271-
value={CHECKBOX_VALUE.CHECKED}
264+
isChecked={!!checkboxValue}
265+
value={checkboxValue}
272266
rootClassName="mb-0 w-20 p-2 dc__align-self-start dc__no-shrink"
273267
/>
274268
)}

src/Shared/Components/SelectPicker/utils.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
import { CHECKBOX_VALUE } from '@Common/Types'
12
import { ComponentSizeType } from '@Shared/constants'
2-
import { StylesConfig } from 'react-select'
3+
import { MultiValue, StylesConfig } from 'react-select'
34
import { SelectPickerOptionType, SelectPickerProps, SelectPickerVariantType } from './type'
45

56
const getMenuWidthFromSize = (menuSize: SelectPickerProps['menuSize']): string => {
@@ -270,3 +271,29 @@ export const getCommonSelectStyle = ({
270271
...(getVariantOverrides(variant)?.singleValue(base, state) || {}),
271272
}),
272273
})
274+
275+
export const getGroupCheckboxValue = (
276+
groupHeadingOptions: readonly SelectPickerOptionType[],
277+
selectedOptions: MultiValue<SelectPickerOptionType>,
278+
getOptionValue: (option: SelectPickerOptionType) => string,
279+
) => {
280+
const selectedOptionsMapByValue = selectedOptions.reduce<Record<string, true>>((acc, option) => {
281+
acc[getOptionValue(option)] = true
282+
return acc
283+
}, {})
284+
const groupOptionsComputedValue = groupHeadingOptions.map((option) => getOptionValue(option))
285+
286+
const isEveryOptionInGroupSelected = groupOptionsComputedValue.every((value) => selectedOptionsMapByValue[value])
287+
288+
if (isEveryOptionInGroupSelected) {
289+
return CHECKBOX_VALUE.CHECKED
290+
}
291+
292+
const isSomeOptionInGroupSelected = groupOptionsComputedValue.some((value) => selectedOptionsMapByValue[value])
293+
294+
if (isSomeOptionInGroupSelected) {
295+
return CHECKBOX_VALUE.INTERMEDIATE
296+
}
297+
298+
return null
299+
}

0 commit comments

Comments
 (0)