UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: заливка перенесенной карточки внутреннего контура

This commit is contained in:
DCCONSTRUCTIONS 2026-04-24 15:49:20 +03:00
parent eff71d7258
commit b3c6b37399
4 changed files with 62 additions and 12 deletions

View File

@ -23,7 +23,12 @@ import { ControlLink, DropIndicator } from "@plane/ui";
import { cn, generateWorkItemLink } from "@plane/utils";
// components
import RenderIfVisible from "@/components/core/render-if-visible-HOC";
import { HIGHLIGHT_CLASS, getIssueBlockId } from "@/components/issues/issue-layouts/utils";
import {
HIGHLIGHT_CLASS,
HIGHLIGHT_WITH_LINE,
NODEDC_DROP_FILL_HIGHLIGHT_CLASS,
getIssueBlockId,
} from "@/components/issues/issue-layouts/utils";
// helpers
// hooks
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
@ -87,9 +92,7 @@ const KanbanIssueDetailsBlock = observer(function KanbanIssueDetailsBlock(props:
const { isMobile } = usePlatformOS();
const customActionButton = (
<div
className="flex h-full w-full cursor-pointer items-center rounded-sm p-1 text-secondary hover:bg-layer-1 hover:text-primary"
>
<div className="flex h-full w-full cursor-pointer items-center rounded-sm p-1 text-secondary hover:bg-layer-1 hover:text-primary">
<MoreHorizontal className="h-3.5 w-3.5" />
</div>
);
@ -226,7 +229,7 @@ export const KanbanIssueBlock = observer(function KanbanIssueBlock(props: IssueB
});
useOutsideClickDetector(cardRef, () => {
cardRef?.current?.classList?.remove(HIGHLIGHT_CLASS);
cardRef?.current?.classList?.remove(HIGHLIGHT_CLASS, HIGHLIGHT_WITH_LINE, NODEDC_DROP_FILL_HIGHLIGHT_CLASS);
});
// Make Issue block both as as Draggable and,
@ -297,15 +300,16 @@ export const KanbanIssueBlock = observer(function KanbanIssueBlock(props: IssueB
className={cn(
"block w-full text-13 transition-all",
cardVariant === "internal-contour"
? "rounded-[28px] border-0 p-0 shadow-none outline-none ring-0 hover:border-0 hover:outline-none hover:ring-0"
? "rounded-[28px] border-0 p-0 shadow-none ring-0 outline-none hover:border-0 hover:ring-0 hover:outline-none focus:!ring-0 focus:!outline-none focus-visible:!ring-0 focus-visible:!outline-none active:!outline-none"
: "rounded-lg border border-subtle bg-layer-2 p-3 shadow-raised-100 outline-[0.5px] outline-transparent hover:border-strong hover:shadow-raised-200",
{ "hover:cursor-pointer": isDragAllowed },
{
"border border-accent-strong hover:border-accent-strong": cardVariant !== "internal-contour" && isPeeked,
},
{ "z-[100] bg-layer-1": isCurrentBlockDragging && cardVariant !== "internal-contour" },
{ "z-[100] bg-[rgb(var(--nodedc-card-active-rgb))]": isCurrentBlockDragging && cardVariant === "internal-contour" }
{ "z-[100]": isCurrentBlockDragging && cardVariant === "internal-contour" }
)}
data-card-variant={cardVariant}
onClick={() => handleIssuePeekOverview(issue)}
disabled={!!issue?.tempId}
>
@ -325,7 +329,7 @@ export const KanbanIssueBlock = observer(function KanbanIssueBlock(props: IssueB
quickActions={quickActions}
isReadOnly={!canEditIssueProperties}
isEpic={isEpic}
isActive={isPeeked}
isActive={isPeeked || (cardVariant === "internal-contour" && isCurrentBlockDragging)}
cardVariant={cardVariant}
/>
</RenderIfVisible>

View File

@ -25,7 +25,9 @@ export const getNodedcWorkItemCardAppearance = (isActive: boolean) => ({
surfaceClassName: isActive
? "bg-[rgb(var(--nodedc-card-active-rgb))] text-[rgb(var(--nodedc-on-card-active-rgb))]"
: "bg-[rgb(var(--nodedc-card-passive-rgb))] text-white",
foregroundClasses: isActive ? "text-[rgb(var(--nodedc-on-card-active-rgb))]" : "text-[rgb(var(--nodedc-on-card-passive-rgb))]",
foregroundClasses: isActive
? "text-[rgb(var(--nodedc-on-card-active-rgb))]"
: "text-[rgb(var(--nodedc-on-card-passive-rgb))]",
subtleTextClasses: isActive ? "text-[#2F4721]" : "text-[#B3B3B8]",
pillBackgroundClasses: isActive
? "bg-black/10 text-[rgb(var(--nodedc-on-card-active-rgb))]"
@ -51,7 +53,7 @@ export const NodedcWorkItemCard = ({
return (
<div
className={cn(
"rounded-[28px] border-0 p-4 shadow-none outline-none ring-0",
"nodedc-work-item-card rounded-[28px] border-0 p-4 shadow-none ring-0 outline-none",
appearance.surfaceClassName,
surfaceClassName
)}
@ -60,14 +62,20 @@ export const NodedcWorkItemCard = ({
<div className="space-y-0.5">
{header}
{subtitle && (
<div className={cn("truncate -mt-0.5 pl-8 text-[11px] font-medium leading-4", appearance.subtleTextClasses, subtitleClassName)}>
<div
className={cn(
"-mt-0.5 truncate pl-8 text-[11px] leading-4 font-medium",
appearance.subtleTextClasses,
subtitleClassName
)}
>
{subtitle}
</div>
)}
</div>
<div className={cn("flex flex-1 items-center justify-center px-5 py-4 text-center", titleContainerClassName)}>
<div className={cn("line-clamp-4 max-w-full text-lg font-semibold leading-6", titleClassName)}>{title}</div>
<div className={cn("text-lg line-clamp-4 max-w-full leading-6 font-semibold", titleClassName)}>{title}</div>
</div>
<div className={cn("flex items-center justify-between gap-3", footerClassName)}>{footer}</div>

View File

@ -46,6 +46,7 @@ import { DEFAULT_DISPLAY_PROPERTIES } from "@/store/issue/issue-details/sub_issu
export const HIGHLIGHT_CLASS = "highlight";
export const HIGHLIGHT_WITH_LINE = "highlight-with-line";
export const NODEDC_DROP_FILL_HIGHLIGHT_CLASS = "nodedc-drop-fill-highlight";
const getAllItemsGroupLabel = (isEpic: boolean): string => {
const locale =
@ -355,6 +356,18 @@ export const highlightIssueOnDrop = (
setTimeout(async () => {
const sourceElementId = elementId ?? "";
const sourceElement = document.getElementById(sourceElementId);
if (sourceElement?.dataset.cardVariant === "internal-contour") {
sourceElement.classList.remove(HIGHLIGHT_CLASS, HIGHLIGHT_WITH_LINE);
sourceElement.classList.add(NODEDC_DROP_FILL_HIGHLIGHT_CLASS);
window.setTimeout(() => sourceElement.classList.remove(NODEDC_DROP_FILL_HIGHLIGHT_CLASS), 1600);
if (shouldScrollIntoView)
await scrollIntoView(sourceElement, { behavior: "smooth", block: "center", duration: 1500 });
return;
}
sourceElement?.classList?.add(shouldHighLightWithLine ? HIGHLIGHT_WITH_LINE : HIGHLIGHT_CLASS);
if (shouldScrollIntoView && sourceElement)
await scrollIntoView(sourceElement, { behavior: "smooth", block: "center", duration: 1500 });

View File

@ -190,6 +190,31 @@
}
}
@keyframes nodedcDropFillHighlight {
0%,
72% {
background-color: rgb(var(--nodedc-card-active-rgb));
color: rgb(var(--nodedc-on-card-active-rgb));
}
100% {
background-color: rgb(var(--nodedc-card-passive-rgb));
color: rgb(var(--nodedc-on-card-passive-rgb));
}
}
[data-card-variant="internal-contour"].nodedc-drop-fill-highlight {
border: 0 !important;
outline: none !important;
box-shadow: none !important;
}
[data-card-variant="internal-contour"].nodedc-drop-fill-highlight .nodedc-work-item-card {
border: 0 !important;
outline: none !important;
box-shadow: none !important;
animation: nodedcDropFillHighlight 1.6s ease-out;
}
/* Progress Bar Styles */
:root {
--bprogress-color: var(--background-color-accent-primary);