fix(sidebar): align title/folder/item start position and stabilize status icon rendering
This commit is contained in:
@@ -143,7 +143,7 @@ export const SidebarConversationCard = memo(function SidebarConversationCard({
|
|||||||
"relative flex h-[1.9375rem] w-full items-center gap-[0.625rem] text-left outline-none",
|
"relative flex h-[1.9375rem] w-full items-center gap-[0.625rem] text-left outline-none",
|
||||||
"rounded-[0.375rem] text-sidebar-foreground",
|
"rounded-[0.375rem] text-sidebar-foreground",
|
||||||
"transition-colors duration-[120ms]",
|
"transition-colors duration-[120ms]",
|
||||||
"pr-[0.5rem] pl-[1.875rem]",
|
"pr-[0.5rem] pl-7",
|
||||||
isSelected
|
isSelected
|
||||||
? "bg-sidebar-primary/15"
|
? "bg-sidebar-primary/15"
|
||||||
: "hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]"
|
: "hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]"
|
||||||
@@ -152,7 +152,11 @@ export const SidebarConversationCard = memo(function SidebarConversationCard({
|
|||||||
<span
|
<span
|
||||||
aria-hidden
|
aria-hidden
|
||||||
className="pointer-events-none absolute top-0 bottom-0 rounded-[0.125rem] bg-sidebar-primary/5"
|
className="pointer-events-none absolute top-0 bottom-0 rounded-[0.125rem] bg-sidebar-primary/5"
|
||||||
style={{ left: "0.9375rem", width: "0.125rem" }}
|
style={{
|
||||||
|
left: "1rem",
|
||||||
|
width: "0.125rem",
|
||||||
|
transform: "translateX(-50%)",
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<SidebarStatusIcon status={beadStatus} />
|
<SidebarStatusIcon status={beadStatus} />
|
||||||
|
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const FolderHeader = memo(function FolderHeader({
|
|||||||
onClick={() => onToggle(folderId)}
|
onClick={() => onToggle(folderId)}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-[1.9375rem] w-full items-center gap-[0.5rem] cursor-pointer outline-none",
|
"flex h-[1.9375rem] w-full items-center gap-[0.5rem] cursor-pointer outline-none",
|
||||||
"rounded-[0.4375rem] px-[0.625rem]",
|
"rounded-[0.4375rem] px-2",
|
||||||
"text-sidebar-foreground hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]",
|
"text-sidebar-foreground hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]",
|
||||||
"transition-[background-color,color] duration-150",
|
"transition-[background-color,color] duration-150",
|
||||||
highlighted && "ring-2 ring-sidebar-primary ring-offset-1"
|
highlighted && "ring-2 ring-sidebar-primary ring-offset-1"
|
||||||
|
|||||||
@@ -9,44 +9,52 @@ interface SidebarStatusIconProps {
|
|||||||
className?: string
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function IconFrame({
|
||||||
|
children,
|
||||||
|
colorClass,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode
|
||||||
|
colorClass: string
|
||||||
|
className?: string
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"pointer-events-none absolute top-1/2",
|
||||||
|
"flex items-center justify-center",
|
||||||
|
colorClass,
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
style={{
|
||||||
|
left: "1rem",
|
||||||
|
width: "0.625rem",
|
||||||
|
height: "0.625rem",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
}}
|
||||||
|
aria-hidden
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function SidebarStatusIcon({
|
export function SidebarStatusIcon({
|
||||||
status,
|
status,
|
||||||
className,
|
className,
|
||||||
}: SidebarStatusIconProps) {
|
}: SidebarStatusIconProps) {
|
||||||
if (status === "running") {
|
if (status === "running") {
|
||||||
return (
|
return (
|
||||||
<div
|
<IconFrame
|
||||||
className={cn(
|
colorClass="text-amber-600 dark:text-amber-400"
|
||||||
"pointer-events-none absolute top-1/2",
|
className={className}
|
||||||
"flex items-center justify-center",
|
|
||||||
"text-amber-600 dark:text-amber-400",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
style={{
|
|
||||||
left: "0.625rem",
|
|
||||||
width: "0.75rem",
|
|
||||||
height: "0.75rem",
|
|
||||||
transform: "translateY(-50%)",
|
|
||||||
}}
|
|
||||||
aria-hidden
|
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
width="0.75rem"
|
width="0.625rem"
|
||||||
height="0.75rem"
|
height="0.625rem"
|
||||||
viewBox="0 0 12 12"
|
viewBox="0 0 10 10"
|
||||||
className="absolute inset-0"
|
preserveAspectRatio="xMidYMid meet"
|
||||||
>
|
>
|
||||||
<circle
|
|
||||||
cx="6"
|
|
||||||
cy="6"
|
|
||||||
r="5.4"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
strokeWidth="1"
|
|
||||||
opacity="0.18"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
<svg width="0.625rem" height="0.625rem" viewBox="0 0 10 10">
|
|
||||||
<circle
|
<circle
|
||||||
cx="5"
|
cx="5"
|
||||||
cy="5"
|
cy="5"
|
||||||
@@ -73,28 +81,19 @@ export function SidebarStatusIcon({
|
|||||||
/>
|
/>
|
||||||
</path>
|
</path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</IconFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === "failed") {
|
if (status === "failed") {
|
||||||
return (
|
return (
|
||||||
<div
|
<IconFrame colorClass="text-destructive" className={className}>
|
||||||
className={cn(
|
<svg
|
||||||
"pointer-events-none absolute top-1/2",
|
width="0.625rem"
|
||||||
"flex items-center justify-center",
|
height="0.625rem"
|
||||||
"text-destructive",
|
viewBox="0 0 10 10"
|
||||||
className
|
preserveAspectRatio="xMidYMid meet"
|
||||||
)}
|
>
|
||||||
style={{
|
|
||||||
left: "0.6875rem",
|
|
||||||
width: "0.625rem",
|
|
||||||
height: "0.625rem",
|
|
||||||
transform: "translateY(-50%)",
|
|
||||||
}}
|
|
||||||
aria-hidden
|
|
||||||
>
|
|
||||||
<svg width="0.625rem" height="0.625rem" viewBox="0 0 10 10">
|
|
||||||
<circle
|
<circle
|
||||||
cx="5"
|
cx="5"
|
||||||
cy="5"
|
cy="5"
|
||||||
@@ -111,28 +110,19 @@ export function SidebarStatusIcon({
|
|||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</IconFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status === "active") {
|
if (status === "active") {
|
||||||
return (
|
return (
|
||||||
<div
|
<IconFrame colorClass="text-sidebar-primary" className={className}>
|
||||||
className={cn(
|
<svg
|
||||||
"pointer-events-none absolute top-1/2",
|
width="0.625rem"
|
||||||
"flex items-center justify-center",
|
height="0.625rem"
|
||||||
"text-sidebar-primary",
|
viewBox="0 0 10 10"
|
||||||
className
|
preserveAspectRatio="xMidYMid meet"
|
||||||
)}
|
>
|
||||||
style={{
|
|
||||||
left: "0.6875rem",
|
|
||||||
width: "0.625rem",
|
|
||||||
height: "0.625rem",
|
|
||||||
transform: "translateY(-50%)",
|
|
||||||
}}
|
|
||||||
aria-hidden
|
|
||||||
>
|
|
||||||
<svg width="0.625rem" height="0.625rem" viewBox="0 0 10 10">
|
|
||||||
<circle
|
<circle
|
||||||
cx="5"
|
cx="5"
|
||||||
cy="5"
|
cy="5"
|
||||||
@@ -144,24 +134,22 @@ export function SidebarStatusIcon({
|
|||||||
/>
|
/>
|
||||||
<circle cx="5" cy="5" r="2" fill="currentColor" />
|
<circle cx="5" cy="5" r="2" fill="currentColor" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</IconFrame>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<IconFrame colorClass="text-sidebar-primary/40" className={className}>
|
||||||
className={cn(
|
<svg
|
||||||
"pointer-events-none absolute top-1/2 rounded-full bg-sidebar-primary/40",
|
width="0.45rem"
|
||||||
className
|
height="0.45rem"
|
||||||
)}
|
viewBox="0 0 12 12"
|
||||||
style={{
|
preserveAspectRatio="xMidYMid meet"
|
||||||
left: "0.8125rem",
|
style={{ overflow: "visible" }}
|
||||||
width: "0.375rem",
|
>
|
||||||
height: "0.375rem",
|
<circle cx="6" cy="6" r="5" fill="currentColor" />
|
||||||
transform: "translateY(-50%)",
|
</svg>
|
||||||
}}
|
</IconFrame>
|
||||||
aria-hidden
|
|
||||||
/>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export function Sidebar() {
|
|||||||
return (
|
return (
|
||||||
<aside className="flex h-full min-h-0 flex-col overflow-hidden bg-sidebar text-sidebar-foreground select-none">
|
<aside className="flex h-full min-h-0 flex-col overflow-hidden bg-sidebar text-sidebar-foreground select-none">
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<div className="flex h-10 shrink-0 items-center justify-between gap-2 pl-[1.25rem] pr-2">
|
<div className="flex h-10 shrink-0 items-center justify-between gap-2 pl-[1.125rem] pr-2">
|
||||||
<div className="flex min-w-0 items-baseline gap-[0.375rem]">
|
<div className="flex min-w-0 items-baseline gap-[0.375rem]">
|
||||||
<h2 className="truncate text-[0.875rem] font-bold tracking-[-0.00625rem] text-sidebar-foreground">
|
<h2 className="truncate text-[0.875rem] font-bold tracking-[-0.00625rem] text-sidebar-foreground">
|
||||||
{t("title")}
|
{t("title")}
|
||||||
|
|||||||
Reference in New Issue
Block a user