File size: 2,046 Bytes
3201ca6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from "react";
import { cn } from "#/utils/utils";
import {
  dropdownInstantColorClassName,
  dropdownMenuRowGapClassName,
  dropdownMenuRowIconWrapperClassName,
} from "#/utils/dropdown-classes";

interface DropdownItemProps<T> {
  item: T;
  index: number;
  isSelected: boolean;
  getItemProps: <Options>(options: any & Options) => any; // eslint-disable-line @typescript-eslint/no-explicit-any
  getDisplayText: (item: T) => string;
  getItemKey: (item: T) => string;
  isProviderDropdown?: boolean;
  renderIcon?: (item: T) => React.ReactNode;
  itemClassName?: string;
  /**
   * Overrides the option's accessible name. Used to fold a group label into the
   * announced name (e.g. "Projects, alpha") when the visual group header is
   * presentational and therefore invisible to assistive tech.
   */
  ariaLabel?: string;
}

export function DropdownItem<T>({
  item,
  index,
  isSelected,
  getItemProps,
  getDisplayText,
  getItemKey,
  isProviderDropdown = false,
  renderIcon,
  itemClassName,
  ariaLabel,
}: DropdownItemProps<T>) {
  const itemProps = getItemProps({
    index,
    item,
    ...(ariaLabel ? { "aria-label": ariaLabel } : {}),
    className: cn(
      isProviderDropdown
        ? "group px-2 py-0 cursor-pointer text-xs rounded-md mx-0 my-0 h-6 flex items-center"
        : "group px-2 py-2 cursor-pointer text-sm rounded-md mx-0 my-0.5",
      "text-white focus:outline-none font-normal",
      dropdownInstantColorClassName,
      {
        "bg-[var(--oh-interactive-selected)] text-white": isSelected,
        "hover:bg-[var(--oh-interactive-hover)]": !isSelected,
      },
      itemClassName,
    ),
  });

  return (
    <li key={getItemKey(item)} {...itemProps}>
      <div className={cn("flex items-center", dropdownMenuRowGapClassName)}>
        {renderIcon ? (
          <span className={dropdownMenuRowIconWrapperClassName}>
            {renderIcon(item)}
          </span>
        ) : null}
        <span className="font-normal">{getDisplayText(item)}</span>
      </div>
    </li>
  );
}