Skip to content

Commit bf5a566

Browse files
committed
feat: use ActionMenu for DynamicTabsSelect
1 parent c62e20b commit bf5a566

File tree

1 file changed

+41
-83
lines changed

1 file changed

+41
-83
lines changed

src/components/common/DynamicTabs/DynamicTabsSelect.tsx

Lines changed: 41 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -17,115 +17,73 @@
1717
import { useMemo, useState } from 'react'
1818

1919
import {
20+
ActionMenu,
21+
ActionMenuItemType,
2022
Button,
2123
ButtonStyleType,
2224
ButtonVariantType,
2325
ComponentSizeType,
2426
DynamicTabType,
25-
PopupMenu,
26-
SelectPicker,
27-
SelectPickerOptionType,
28-
SelectPickerProps,
27+
Icon,
2928
} from '@devtron-labs/devtron-fe-common-lib'
3029

31-
import { ReactComponent as ICArrowLeft } from '@Icons/ic-arrow-left.svg'
32-
import { ReactComponent as ICCross } from '@Icons/ic-cross.svg'
33-
3430
import { DynamicTabsSelectProps } from './types'
3531

36-
const DynamicTabsSelect = ({
37-
tabs,
38-
getMarkTabActiveHandler,
39-
selectedTab,
40-
handleTabCloseAction,
41-
}: DynamicTabsSelectProps) => {
32+
const DynamicTabsSelect = ({ tabs, getMarkTabActiveHandler, handleTabCloseAction }: DynamicTabsSelectProps) => {
4233
const [isMenuOpen, setIsMenuOpen] = useState(false)
4334

44-
const handleToggleOpenMenuState = (isOpen: boolean) => {
45-
setIsMenuOpen(isOpen)
46-
}
47-
48-
const options: SelectPickerOptionType<DynamicTabType>[] = useMemo(
35+
const options = useMemo(
4936
() =>
5037
tabs.map((tab) => {
5138
const [kind, name] = tab.title.split('/')
5239

5340
return {
5441
label: kind,
42+
id: tab.id,
5543
value: tab,
5644
description: name,
57-
endIcon: (
58-
<div className="flex top">
59-
<Button
60-
dataTestId="close-dynamic-tab-option"
61-
icon={<ICCross />}
62-
variant={ButtonVariantType.borderLess}
63-
style={ButtonStyleType.negativeGrey}
64-
data-id={tab.id}
65-
onClick={handleTabCloseAction}
66-
size={ComponentSizeType.xs}
67-
ariaLabel={`Close dynamic tab ${kind}`}
68-
showAriaLabelInTippy={false}
69-
/>
70-
</div>
71-
),
72-
}
45+
trailingItem: {
46+
type: 'button',
47+
config: {
48+
dataTestId: 'close-dynamic-tab-option',
49+
icon: <Icon name="ic-close-small" color={null} />,
50+
variant: ButtonVariantType.borderLess,
51+
style: ButtonStyleType.negativeGrey,
52+
'data-id': tab.id,
53+
onClick: handleTabCloseAction,
54+
size: ComponentSizeType.xs,
55+
ariaLabel: `Close dynamic tab ${kind}`,
56+
showAriaLabelInTippy: false,
57+
},
58+
},
59+
} as ActionMenuItemType & Record<'value', DynamicTabType>
7360
}),
7461
[tabs],
7562
)
7663

77-
const onChangeTab = (option: SelectPickerOptionType<DynamicTabType>): void => {
78-
setIsMenuOpen(false)
79-
getMarkTabActiveHandler(option.value)()
80-
}
81-
82-
const handleCloseMenu = () => {
83-
setIsMenuOpen(false)
64+
const onClick = (item: (typeof options)[number]) => {
65+
getMarkTabActiveHandler(item.value)()
8466
}
8567

86-
// NOTE: by default react select compares option references
87-
// therefore if we don't wrap value and options in useMemo we need to provide isOptionSelected
88-
const isOptionSelected = (option: SelectPickerOptionType<DynamicTabType>) => option.value.id === selectedTab.id
89-
90-
const handleOnEscPress = (e: React.KeyboardEvent) => {
91-
if (e.key !== 'Escape') {
92-
return
93-
}
94-
95-
handleCloseMenu()
96-
}
97-
98-
const selectFilter: SelectPickerProps<DynamicTabType>['filterOption'] = (option, searchText) =>
99-
option.data.value.id.toLowerCase().includes(searchText.toLowerCase())
100-
10168
return (
102-
<PopupMenu autoClose autoPosition onToggleCallback={handleToggleOpenMenuState}>
103-
<PopupMenu.Button rootClassName="flex">
104-
<ICArrowLeft
105-
className={`rotate icon-dim-18 ${isMenuOpen ? 'fcn-9' : 'fcn-7'}`}
106-
style={{ ['--rotateBy' as string]: isMenuOpen ? '90deg' : '-90deg' }}
107-
/>
108-
</PopupMenu.Button>
109-
{/* NOTE: Since we can't control open state of popup menu through prop we can control it by simply
110-
hooking a state using onToggleCallback and rendering the PopupMenu.Body conditionally through that state */}
111-
{isMenuOpen && (
112-
<PopupMenu.Body rootClassName="w-300 mt-8 dynamic-tabs-select-popup-body" style={{ right: '12px' }}>
113-
<SelectPicker<DynamicTabType, false>
114-
inputId="dynamic-tabs-select"
115-
placeholder="Search tabs"
116-
options={options}
117-
onChange={onChangeTab}
118-
isOptionSelected={isOptionSelected}
119-
filterOption={selectFilter}
120-
onKeyDown={handleOnEscPress}
121-
shouldMenuAlignRight
122-
menuPosition="absolute"
123-
menuIsOpen
124-
autoFocus
125-
/>
126-
</PopupMenu.Body>
127-
)}
128-
</PopupMenu>
69+
<ActionMenu
70+
id="dynamic-tabs-select"
71+
onClick={onClick}
72+
position="bottom"
73+
isSearchable
74+
onOpen={setIsMenuOpen}
75+
options={[{ items: options }]}
76+
>
77+
<Button
78+
dataTestId="close-dynamic-tab-option"
79+
icon={<Icon name="ic-caret-down-small" color={null} rotateBy={isMenuOpen ? 180 : 0} />}
80+
variant={ButtonVariantType.secondary}
81+
style={ButtonStyleType.neutral}
82+
size={ComponentSizeType.xxs}
83+
ariaLabel="Open dynamic tabs select menu"
84+
showAriaLabelInTippy={false}
85+
/>
86+
</ActionMenu>
12987
)
13088
}
13189

0 commit comments

Comments
 (0)