mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 01:18:23 +00:00
Added support for arrow key navigation in Dropdown and Multiselect component.
This commit is contained in:
parent
37f76e386b
commit
d68565b43c
3 changed files with 51 additions and 6 deletions
|
|
@ -88,6 +88,7 @@ export const DropdownV2 = ({
|
|||
padding,
|
||||
} = styles;
|
||||
const isInitialRender = useRef(true);
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const [currentValue, setCurrentValue] = useState(() => findDefaultItem(schema));
|
||||
const isMandatory = validation?.mandatory ?? false;
|
||||
const options = properties?.options;
|
||||
|
|
@ -353,15 +354,16 @@ export const DropdownV2 = ({
|
|||
...provided,
|
||||
padding: '0px',
|
||||
}),
|
||||
option: (provided) => ({
|
||||
option: (provided, _state) => ({
|
||||
...provided,
|
||||
backgroundColor: 'var(--surfaces-surface-01)',
|
||||
backgroundColor: _state.isFocused ? 'var(--interactive-overlays-fill-hover)' : 'var(--surfaces-surface-01)',
|
||||
color:
|
||||
selectedTextColor !== '#1B1F24'
|
||||
? selectedTextColor
|
||||
: isDropdownDisabled || isDropdownLoading
|
||||
? 'var(--text-disabled)'
|
||||
: 'var(--text-primary)',
|
||||
borderRadius: _state.isFocused && '8px',
|
||||
padding: '8px 6px 8px 38px',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--interactive-overlays-fill-hover)',
|
||||
|
|
@ -431,6 +433,7 @@ export const DropdownV2 = ({
|
|||
/>
|
||||
<div className="w-100 px-0 h-100 dropdownV2-widget" ref={ref}>
|
||||
<Select
|
||||
menuIsOpen={isMenuOpen}
|
||||
isDisabled={isDropdownDisabled}
|
||||
value={selectOptions.filter((option) => option.value === currentValue)[0] ?? null}
|
||||
onChange={(selectedOption, actionProps) => {
|
||||
|
|
@ -460,6 +463,7 @@ export const DropdownV2 = ({
|
|||
ClearIndicator: CustomClearIndicator,
|
||||
}}
|
||||
isClearable
|
||||
tabSelectsValue={false}
|
||||
icon={icon}
|
||||
doShowIcon={iconVisibility}
|
||||
iconColor={iconColor}
|
||||
|
|
@ -467,8 +471,24 @@ export const DropdownV2 = ({
|
|||
darkMode={darkMode}
|
||||
optionsLoadingState={optionsLoadingState && advanced}
|
||||
menuPlacement="auto"
|
||||
onMenuOpen={() => fireEvent('onFocus')}
|
||||
onMenuClose={() => fireEvent('onBlur')}
|
||||
onMenuOpen={() => {
|
||||
setIsMenuOpen(true);
|
||||
fireEvent('onFocus');
|
||||
}}
|
||||
onMenuClose={() => {
|
||||
setIsMenuOpen(false);
|
||||
fireEvent('onBlur');
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !isMenuOpen) {
|
||||
setIsMenuOpen(true);
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.key === 'Escape' && isMenuOpen) {
|
||||
setIsMenuOpen(false);
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import * as Icons from '@tabler/icons-react';
|
|||
const { ValueContainer, Placeholder } = components;
|
||||
import './multiselectV2.scss';
|
||||
|
||||
const CustomValueContainer = ({ ...props }) => {
|
||||
const CustomValueContainer = ({ children, ...props }) => {
|
||||
const selectProps = props.selectProps;
|
||||
const values = Array.isArray(selectProps?.value) && selectProps?.value?.map((option) => option.label);
|
||||
const isAllOptionsSelected = selectProps?.value.length === selectProps.options.length;
|
||||
|
|
@ -39,6 +39,13 @@ const CustomValueContainer = ({ ...props }) => {
|
|||
{isAllOptionsSelected ? 'All items are selected.' : values.join(', ')}
|
||||
</span>
|
||||
)}
|
||||
{/* Rendering children except Placeholder component to preserve the default behavior of react-select like focus
|
||||
handling */}
|
||||
{React.Children.map(children, (child) => {
|
||||
if (child.type !== Placeholder) {
|
||||
return child;
|
||||
}
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</ValueContainer>
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ export const MultiselectV2 = ({
|
|||
}),
|
||||
option: (provided, _state) => ({
|
||||
...provided,
|
||||
backgroundColor: 'var(--surfaces-surface-01)',
|
||||
backgroundColor: _state.isFocused ? 'var(--interactive-overlays-fill-hover)' : 'var(--surfaces-surface-01)',
|
||||
color: _state.isDisabled
|
||||
? 'var(_--text-disbled)'
|
||||
: selectedTextColor !== '#1B1F24'
|
||||
|
|
@ -394,6 +394,7 @@ export const MultiselectV2 = ({
|
|||
: isMultiSelectDisabled || isMultiSelectLoading
|
||||
? 'var(--text-disabled)'
|
||||
: 'var(--text-primary)',
|
||||
borderRadius: _state.isFocused && '8px',
|
||||
padding: '8px 6px 8px 12px',
|
||||
'&:hover': {
|
||||
backgroundColor: 'var(--interactive-overlays-fill-hover)',
|
||||
|
|
@ -490,10 +491,27 @@ export const MultiselectV2 = ({
|
|||
isMulti
|
||||
hideSelectedOptions={false}
|
||||
closeMenuOnSelect={false}
|
||||
tabSelectsValue={false}
|
||||
controlShouldRenderValue={false}
|
||||
isSearchable={false}
|
||||
onMenuOpen={() => {
|
||||
fireEvent('onFocus');
|
||||
setIsMultiselectOpen(true);
|
||||
}}
|
||||
onMenuClose={() => {
|
||||
setIsMultiselectOpen(false);
|
||||
fireEvent('onBlur');
|
||||
}}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !isMultiselectOpen) {
|
||||
setIsMultiselectOpen(true);
|
||||
e.preventDefault();
|
||||
}
|
||||
if (e.key === 'Escape' && isMultiselectOpen) {
|
||||
setIsMultiselectOpen(false);
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
// select props
|
||||
icon={icon}
|
||||
doShowIcon={iconVisibility}
|
||||
|
|
|
|||
Loading…
Reference in a new issue