-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathContextSwitcher.tsx
More file actions
118 lines (107 loc) · 3.66 KB
/
ContextSwitcher.tsx
File metadata and controls
118 lines (107 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
* Copyright (c) 2024. Devtron Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useEffect, useRef } from 'react'
import { SelectInstance } from 'react-select'
import { useRegisterShortcut } from '@Common/Hooks/UseRegisterShortcut'
import {
getNoMatchingResultText,
SelectPicker,
SelectPickerOptionType,
SelectPickerProps,
SelectPickerVariantType,
} from '@Shared/Components'
import { ComponentSizeType } from '@Shared/constants'
import { ToastManager, ToastVariantType } from '@Shared/Services'
import { ContextSwitcherTypes } from './types'
import { customSelectFilterOption, getDisabledOptions } from './utils'
export const ContextSwitcher = ({
inputId,
options = [],
inputValue,
onInputChange,
isLoading,
value,
onChange,
placeholder,
filterOption,
formatOptionLabel,
optionListError,
reloadOptionList,
classNamePrefix,
resource,
}: ContextSwitcherTypes) => {
const selectRef = useRef<SelectInstance<SelectPickerOptionType>>(null)
const shouldShowToastRef = useRef<boolean>(true)
const selectedOptions = options?.map((section) => ({
...section,
options: section?.label === 'Recently Visited' ? section.options?.slice(1) : section.options,
}))
const { registerShortcut, unregisterShortcut } = useRegisterShortcut()
const handleOpenShortcutToast: SelectPickerProps['onMenuOpen'] = () => {
if (shouldShowToastRef.current) {
ToastManager.showToast({
variant: ToastVariantType.shortcut,
text: `to switch ${resource}`,
shortcuts: ['S'],
})
}
shouldShowToastRef.current = true
}
useEffect(() => {
registerShortcut({
keys: ['S'],
callback: () => {
shouldShowToastRef.current = false
selectRef.current?.focus()
selectRef.current?.openMenu('first')
},
})
return () => {
unregisterShortcut(['S'])
}
}, [])
const onKeyDown: SelectPickerProps['onKeyDown'] = (e) => {
if (e.key === 'Escape' || e.key === 'Esc') {
e.preventDefault()
selectRef.current?.blurInput()
selectRef.current?.blur()
}
}
return (
<SelectPicker
selectRef={selectRef}
inputId={inputId}
options={selectedOptions || []}
inputValue={inputValue}
onFocus={handleOpenShortcutToast}
onInputChange={onInputChange}
isLoading={isLoading}
noOptionsMessage={getNoMatchingResultText}
onChange={onChange}
value={value}
variant={SelectPickerVariantType.BORDER_LESS}
placeholder={placeholder}
isOptionDisabled={getDisabledOptions}
size={ComponentSizeType.xl}
filterOption={filterOption || customSelectFilterOption}
formatOptionLabel={formatOptionLabel}
optionListError={optionListError}
reloadOptionList={reloadOptionList}
classNamePrefix={classNamePrefix}
onKeyDown={onKeyDown}
/>
)
}