NODEDC_TASKMANAGER/plane-src/packages/ui/src/breadcrumbs/navigation-search-dropdown.tsx

119 lines
3.5 KiB
TypeScript

/**
* Copyright (c) 2023-present Plane Software, Inc. and contributors
* SPDX-License-Identifier: AGPL-3.0-only
* See the LICENSE file for details.
*/
import * as React from "react";
import { useState } from "react";
import type { ICustomSearchSelectOption } from "@plane/types";
import { CustomSearchSelect } from "../dropdowns";
import { cn } from "../utils";
import { Breadcrumbs } from "./breadcrumbs";
type TBreadcrumbNavigationSearchDropdownProps = {
icon?: React.ReactNode;
title?: string;
selectedItem: string;
navigationItems: ICustomSearchSelectOption[];
onChange?: (value: string) => void;
navigationDisabled?: boolean;
isLast?: boolean;
handleOnClick?: () => void;
disableRootHover?: boolean;
shouldTruncate?: boolean;
openOnLabelClick?: boolean;
rotateChevronWhenLast?: boolean;
showLastChevron?: boolean;
};
export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationSearchDropdownProps) {
const {
icon,
title,
selectedItem,
navigationItems,
onChange,
navigationDisabled = false,
isLast = false,
handleOnClick,
shouldTruncate = false,
openOnLabelClick = false,
rotateChevronWhenLast = true,
showLastChevron = true,
} = props;
// state
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const shouldOpenOnItemClick = openOnLabelClick || !handleOnClick;
return (
<CustomSearchSelect
onOpen={() => {
setIsDropdownOpen(true);
}}
onClose={() => {
setIsDropdownOpen(false);
}}
options={navigationItems}
value={selectedItem}
onChange={(value: string) => {
if (value !== selectedItem) {
onChange?.(value);
}
}}
customButton={
<>
<div
onClick={(e) => {
if (!isLast && !shouldOpenOnItemClick) {
e.preventDefault();
e.stopPropagation();
handleOnClick?.();
}
}}
title={title}
className={cn(
"group flex h-full cursor-pointer items-center gap-2 rounded-sm rounded-r-none px-1.5 py-1 text-13 font-medium text-tertiary",
{
"hover:bg-layer-1 hover:text-primary": !isLast,
}
)}
>
{shouldTruncate && <div className="flex text-tertiary @4xl:hidden">...</div>}
<div
className={cn("flex gap-2", {
"hidden items-center gap-2 @4xl:flex": shouldTruncate,
})}
>
{icon && <Breadcrumbs.Icon>{icon}</Breadcrumbs.Icon>}
<Breadcrumbs.Label>{title}</Breadcrumbs.Label>
</div>
</div>
{(!isLast || showLastChevron) && (
<Breadcrumbs.Separator
className={cn("rounded-r-sm", {
"bg-layer-1": isDropdownOpen && !isLast,
"hover:bg-layer-1": !isLast,
})}
containerClassName="p-0"
iconClassName={cn("group-hover:rotate-90 hover:text-primary", {
"text-primary": isDropdownOpen,
"rotate-90": isDropdownOpen || (isLast && rotateChevronWhenLast),
})}
showDivider={!isLast}
/>
)}
</>
}
disabled={navigationDisabled}
className="h-full rounded-sm"
customButtonClassName={cn(
"group flex h-full cursor-pointer items-center gap-0.5 rounded-sm outline-none hover:bg-surface-2",
{
"bg-surface-2": isDropdownOpen,
}
)}
/>
);
}