stremio-web/src/components/MultiselectMenu/Dropdown/Dropdown.tsx
2025-06-03 12:39:08 +03:00

80 lines
2.6 KiB
TypeScript

// Copyright (C) 2017-2024 Smart code 203358507
import React, { useRef, useEffect, useCallback } from 'react';
import { Button } from 'stremio/components';
import { useTranslation } from 'react-i18next';
import classNames from 'classnames';
import Option from './Option';
import Icon from '@stremio/stremio-icons/react';
import styles from './Dropdown.less';
type Props = {
options: MultiselectMenuOption[];
value?: string | number;
menuOpen: boolean | (() => void);
level: number;
setLevel: (level: number) => void;
onSelect: (value: string | number) => void;
};
const Dropdown = ({ level, setLevel, options, onSelect, value, menuOpen }: Props) => {
const { t } = useTranslation();
const optionsRef = useRef(new Map());
const containerRef = useRef(null);
const selectedOption = options.find((opt) => opt.value === value);
const handleSetOptionRef = useCallback((optionValue: string | number) => (node: HTMLButtonElement | null) => {
if (node) {
optionsRef.current.set(optionValue, node);
} else {
optionsRef.current.delete(optionValue);
}
}, []);
const handleBackClick = useCallback(() => {
setLevel(level - 1);
}, [setLevel, level]);
useEffect(() => {
if (menuOpen && selectedOption && containerRef.current) {
const selectedNode = optionsRef.current.get(selectedOption.value);
if (selectedNode) {
selectedNode.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
}
}
}, [menuOpen, selectedOption]);
return (
<div
className={classNames(styles['dropdown'], { [styles['open']]: menuOpen })}
role={'listbox'}
ref={containerRef}
>
{level > 0 ?
<Button className={styles['back-button']} onClick={handleBackClick}>
<Icon name={'caret-left'} className={styles['back-button-icon']} />
{t('BACK')}
</Button>
: null
}
{options
.filter((option: MultiselectMenuOption) => !option.hidden)
.map((option: MultiselectMenuOption) => (
<Option
key={option.value}
ref={handleSetOptionRef(option.value)}
option={option}
onSelect={onSelect}
selectedValue={value}
/>
))
}
</div>
);
};
export default Dropdown;