UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: унификация крошек, предложений и quick-actions dropdown

This commit is contained in:
DCCONSTRUCTIONS
2026-04-22 12:06:19 +03:00
parent 7252d26f46
commit 9ab555f6cb
68 changed files with 2242 additions and 2105 deletions
@@ -6,7 +6,6 @@
import * as React from "react";
import { useState } from "react";
import { Tooltip } from "@plane/propel/tooltip";
import type { ICustomSearchSelectOption } from "@plane/types";
import { CustomSearchSelect } from "../dropdowns";
import { cn } from "../utils";
@@ -23,6 +22,9 @@ type TBreadcrumbNavigationSearchDropdownProps = {
handleOnClick?: () => void;
disableRootHover?: boolean;
shouldTruncate?: boolean;
openOnLabelClick?: boolean;
rotateChevronWhenLast?: boolean;
showLastChevron?: boolean;
};
export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationSearchDropdownProps) {
@@ -36,9 +38,13 @@ export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationS
isLast = false,
handleOnClick,
shouldTruncate = false,
openOnLabelClick = false,
rotateChevronWhenLast = true,
showLastChevron = true,
} = props;
// state
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
const shouldOpenOnItemClick = openOnLabelClick || !handleOnClick;
return (
<CustomSearchSelect
@@ -57,45 +63,46 @@ export function BreadcrumbNavigationSearchDropdown(props: TBreadcrumbNavigationS
}}
customButton={
<>
<Tooltip tooltipContent={title} position="bottom">
<button
onClick={(e) => {
if (!isLast) {
e.preventDefault();
e.stopPropagation();
handleOnClick?.();
}
}}
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,
}
)}
<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,
})}
>
{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>
</button>
</Tooltip>
<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,
})}
showDivider={!isLast}
/>
{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}