|
| 1 | +/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */ |
1 | 2 | import React from 'react'; |
2 | 3 | import { |
3 | 4 | DropdownMenuCheckboxItem, |
4 | 5 | DropdownMenuCheckboxItemProps, |
5 | 6 | } from '@radix-ui/react-dropdown-menu'; |
| 7 | +import { PrioritySelector, PrioritySelectorProps } from '../../../PrioritySelector'; |
6 | 8 | import { bem } from '../../../../utils'; |
7 | 9 | import { VisualCheckbox } from '../../../Checkbox'; |
8 | 10 | import { Text } from '../../../Text'; |
9 | 11 | import styles from './MultiSelectItem.scss'; |
| 12 | +import { stopPropagation } from '../../../../utils/misc'; |
10 | 13 |
|
11 | | -export interface Props extends DropdownMenuCheckboxItemProps { |
| 14 | +export interface Props<PriorityItemValue> extends DropdownMenuCheckboxItemProps { |
12 | 15 | /** Id for the checkbox */ |
13 | 16 | id?: string; |
14 | 17 | /** a variant to determine the look and feel of component */ |
15 | 18 | variant?: 'option' | 'select-all' | 'group-title'; |
16 | | - /** to add a priority badge before the label */ |
17 | | - hasPriority?: boolean; |
| 19 | + /** props for PrioritySelector */ |
| 20 | + priority?: PrioritySelectorProps<PriorityItemValue>; |
18 | 21 | /** Checkbox status */ |
19 | 22 | isSelected?: boolean; |
20 | 23 | } |
21 | 24 |
|
22 | 25 | const { block } = bem('MultiSelectItem', styles); |
23 | 26 |
|
24 | | -export const MultiSelectItem = React.forwardRef<HTMLLIElement, Props>( |
25 | | - ( |
| 27 | +export const MultiSelectItem = React.forwardRef( |
| 28 | + <PriorityItemValue extends unknown>( |
26 | 29 | { |
27 | 30 | children, |
28 | 31 | isSelected = false, |
29 | 32 | disabled = false, |
30 | 33 | variant = 'option', |
31 | | - hasPriority = false, // eslint-disable-line @typescript-eslint/no-unused-vars |
32 | 34 | onCheckedChange, |
| 35 | + priority, |
33 | 36 | ...rest |
34 | | - }, |
35 | | - ref |
36 | | - ) => ( |
37 | | - <DropdownMenuCheckboxItem |
38 | | - ref={ref} |
39 | | - role="option" |
40 | | - aria-selected={isSelected} |
41 | | - tabIndex={disabled ? -1 : 0} |
42 | | - checked={isSelected} |
43 | | - onSelect={(e) => { |
44 | | - e.preventDefault(); |
45 | | - }} |
46 | | - onCheckedChange={onCheckedChange} |
47 | | - {...rest} |
48 | | - {...block({ |
49 | | - isSelected, |
50 | | - disabled, |
51 | | - variant, |
52 | | - ...rest, |
53 | | - })} |
54 | | - > |
55 | | - <VisualCheckbox checked={isSelected} /> |
56 | | - <Text inline>{children}</Text> |
57 | | - </DropdownMenuCheckboxItem> |
58 | | - ) |
59 | | -); |
| 37 | + }: Props<PriorityItemValue>, |
| 38 | + ref: React.Ref<HTMLDivElement> |
| 39 | + ) => { |
| 40 | + const priorityRef = React.useRef<HTMLDivElement>(null); |
| 41 | + |
| 42 | + const hasPriorityList = priority && priority.list.length > 0; |
| 43 | + |
| 44 | + const handleKeyDown = (e: React.KeyboardEvent) => { |
| 45 | + if (e.key === 'Tab' && !e.shiftKey) { |
| 46 | + if (priorityRef.current) { |
| 47 | + priorityRef.current.focus(); |
| 48 | + } |
| 49 | + } |
| 50 | + }; |
| 51 | + |
| 52 | + return ( |
| 53 | + <DropdownMenuCheckboxItem |
| 54 | + ref={ref} |
| 55 | + role="option" |
| 56 | + aria-selected={isSelected} |
| 57 | + onKeyDown={handleKeyDown} |
| 58 | + checked={isSelected} |
| 59 | + onSelect={(e) => { |
| 60 | + e.preventDefault(); |
| 61 | + }} |
| 62 | + onCheckedChange={onCheckedChange} |
| 63 | + {...rest} |
| 64 | + {...block({ |
| 65 | + isSelected, |
| 66 | + disabled, |
| 67 | + variant, |
| 68 | + ...rest, |
| 69 | + })} |
| 70 | + > |
| 71 | + <VisualCheckbox checked={isSelected} /> |
| 72 | + {hasPriorityList && ( |
| 73 | + <div role="none" onClick={stopPropagation} onKeyDown={stopPropagation}> |
| 74 | + <PrioritySelector {...priority} buttonRef={priorityRef} /> |
| 75 | + </div> |
| 76 | + )} |
| 77 | + <Text inline>{children}</Text> |
| 78 | + </DropdownMenuCheckboxItem> |
| 79 | + ); |
| 80 | + } |
| 81 | +) as <PriorityItemValue extends unknown>( |
| 82 | + p: Props<PriorityItemValue> & { ref?: React.Ref<HTMLDivElement> } |
| 83 | +) => React.ReactElement; |
0 commit comments