mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-03-11 21:27:05 +00:00
80 lines
2.6 KiB
TypeScript
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;
|