Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
BackgroundsSelector.component.tsx 2.96 KiB
import { useSelect } from 'downshift';
import {
  backgroundsDataSelector,
  currentBackgroundSelector,
  mainBackgroundIdSelector,
} from '@/redux/backgrounds/background.selectors';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { twMerge } from 'tailwind-merge';
import { Icon } from '@/shared/Icon';
import { MapBackground } from '@/types/models';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { setMapBackground } from '@/redux/map/map.slice';

const DEFAULT_TOGGLE_BUTTON_TEXT = 'Background';

export const BackgroundSelector = (): JSX.Element => {
  const selectedBackground = useAppSelector(currentBackgroundSelector);
  const dispatch = useAppDispatch();
  const backgrounds = useAppSelector(backgroundsDataSelector);
  const mainBackgroundId = useAppSelector(mainBackgroundIdSelector);

  const onItemSelect = (background: MapBackground | undefined | null): void => {
    if (background) {
      dispatch(setMapBackground(background.id));
    }
  };

  const { isOpen, getToggleButtonProps, getMenuProps, highlightedIndex, getItemProps } = useSelect({
    items: backgrounds || [],
    selectedItem: selectedBackground,
    onSelectedItemChange: ({ selectedItem: newSelectedItem }) => onItemSelect(newSelectedItem),
  });

  const getToggleButtonName = (): string => {
    const isSelectedBackgroundMainBackground = selectedBackground?.id === mainBackgroundId;
    if (!selectedBackground || isSelectedBackgroundMainBackground) {
      return DEFAULT_TOGGLE_BUTTON_TEXT;
    }
    return selectedBackground.name;
  };

  return (
    <div
      data-testid="background-selector"
      className={twMerge('rounded-t bg-white text-xs shadow-primary', !isOpen && 'rounded-b')}
    >
      <div className={twMerge('flex w-72 flex-col rounded-t py-2 pl-4 pr-3')}>
        <div
          className="flex cursor-pointer flex-row items-center justify-between bg-white"
          {...getToggleButtonProps()}
        >
          <span data-testid="background-dropdown-button-name" className="font-medium">
            {getToggleButtonName()}
          </span>
          <Icon
            name="chevron-down"
            className={twMerge('arrow-button h-6 w-6 fill-primary-500', isOpen && 'rotate-180')}
          />
        </div>
      </div>
      <ul
        className={`absolute z-10 max-h-80 w-72 overflow-scroll rounded-b bg-white p-0 ${
          !isOpen && 'hidden'
        }`}
        {...getMenuProps()}
      >
        {isOpen &&
          backgrounds &&
          backgrounds.map((item, index) => (
            <li
              className={twMerge(
                'border-t',
                highlightedIndex === index && 'text-primary-500',
                selectedBackground === item && 'font-bold',
                'flex flex-col px-4 py-2 shadow-sm',
              )}
              key={item.id}
              {...getItemProps({ item, index })}
            >
              <span>{item.name}</span>
            </li>
          ))}
      </ul>
    </div>
  );
};