DocDoeAI / src /components /study-chat /WorkspacePanelPrimitives.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
3.01 kB
"use client";
import type { ElementType, ReactNode } from "react";
import { Search, X } from "lucide-react";
export function WorkspaceSearch({
value,
onChange,
placeholder,
}: {
value: string;
onChange: (value: string) => void;
placeholder: string;
}) {
return (
<label className="flex min-h-10 items-center gap-2 rounded-2xl border border-white/[0.08] bg-white/[0.035] px-3 text-white/42 focus-within:border-white/[0.18] focus-within:text-white/70">
<Search className="size-3.5 shrink-0" />
<span className="sr-only">{placeholder}</span>
<input
value={value}
onChange={(event) => onChange(event.target.value)}
placeholder={placeholder}
className="min-w-0 flex-1 bg-transparent text-sm text-white outline-none placeholder:text-white/30"
/>
{value ? (
<button
type="button"
onClick={() => onChange("")}
aria-label="Clear search"
className="grid size-5 shrink-0 place-items-center rounded-full text-white/40 transition hover:bg-white/10 hover:text-white"
>
<X className="size-3.5" />
</button>
) : null}
</label>
);
}
export function ToolCard({
icon: Icon,
label,
description,
onClick,
disabled,
}: {
icon: ElementType;
label: string;
description: string;
onClick: () => void;
disabled?: boolean;
}) {
return (
<button
type="button"
onClick={onClick}
disabled={disabled}
className="group flex min-h-[4.4rem] items-start gap-3 rounded-2xl border border-white/[0.075] bg-white/[0.025] p-3 text-left transition hover:border-white/[0.16] hover:bg-white/[0.05] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/20 disabled:cursor-not-allowed disabled:opacity-42"
>
<span className="grid size-9 shrink-0 place-items-center rounded-xl border border-white/[0.08] bg-white/[0.035] text-white/62 transition group-hover:text-white">
<Icon className="size-4" />
</span>
<span className="min-w-0">
<span className="block text-sm font-semibold text-white/84">{label}</span>
<span className="mt-1 line-clamp-2 block text-xs leading-5 text-white/38">{description}</span>
</span>
</button>
);
}
export function PanelBlock({
title,
children,
actionLabel,
onAction,
}: {
title: string;
children: ReactNode;
actionLabel?: string;
onAction?: () => void;
}) {
return (
<section className="mb-3 rounded-[1.25rem] border border-white/[0.075] bg-[#080808]/88 p-3">
<div className="mb-3 flex items-center justify-between gap-3">
<p className="text-[11px] font-bold uppercase tracking-[0.16em] text-white/38">{title}</p>
{actionLabel && onAction ? (
<button type="button" onClick={onAction} className="text-[11px] font-bold text-white/62 transition hover:text-white">
{actionLabel}
</button>
) : null}
</div>
{children}
</section>
);
}