style(webui): clarify surface hierarchy (#5029)
This commit is contained in:
@@ -170,8 +170,8 @@ export function PromptRail({
|
||||
aria-hidden
|
||||
className={cn(
|
||||
"pointer-events-none absolute left-10 top-1/2 z-30 w-[34rem] max-w-[calc(100vw-4rem)] -translate-y-1/2 rounded-[20px] px-4 py-3 text-left",
|
||||
"border border-border/70 bg-popover/95 text-popover-foreground shadow-[0_18px_45px_rgba(0,0,0,0.12)] backdrop-blur-xl",
|
||||
"dark:border-white/10 dark:bg-[#2f2f2f]/95 dark:text-white dark:shadow-[0_18px_45px_rgba(0,0,0,0.45)]",
|
||||
"bg-popover/95 text-popover-foreground shadow-[0_18px_45px_rgba(0,0,0,0.12)] backdrop-blur-xl",
|
||||
"dark:bg-[#2f2f2f]/95 dark:text-white dark:shadow-[0_18px_45px_rgba(0,0,0,0.45)]",
|
||||
"-translate-x-2 scale-[0.98] opacity-0 transition-[opacity,transform] duration-150",
|
||||
"group-hover/marker:translate-x-0 group-hover/marker:scale-100 group-hover/marker:opacity-100",
|
||||
"group-focus-visible/marker:translate-x-0 group-focus-visible/marker:scale-100 group-focus-visible/marker:opacity-100",
|
||||
|
||||
@@ -1822,11 +1822,9 @@ export function ThreadComposer({
|
||||
<div
|
||||
className={cn(
|
||||
"group/composer relative mx-auto flex w-full flex-col overflow-visible transition-all duration-200",
|
||||
"after:pointer-events-none after:absolute after:inset-[-1px] after:rounded-[inherit] after:border after:border-blue-300/75 after:opacity-0 after:transition-opacity after:duration-200 focus-within:after:opacity-100 dark:after:border-blue-400/55",
|
||||
isHero
|
||||
? "max-w-[58rem] rounded-[28px] border border-black/[0.035] bg-card shadow-[0_20px_55px_rgba(15,23,42,0.08)] dark:border-white/[0.06] dark:shadow-[0_24px_55px_rgba(0,0,0,0.34)]"
|
||||
: "max-w-[49.5rem] rounded-[22px] border border-black/[0.035] bg-card shadow-[0_12px_30px_rgba(15,23,42,0.07)] dark:border-white/[0.06] dark:shadow-[0_16px_34px_rgba(0,0,0,0.28)]",
|
||||
"focus-within:border-blue-300/75 dark:focus-within:border-blue-400/55",
|
||||
? "max-w-[58rem] rounded-[28px] bg-muted/30 focus-within:bg-muted/50 dark:bg-card dark:focus-within:bg-white/[0.06]"
|
||||
: "max-w-[49.5rem] rounded-[22px] bg-muted/30 focus-within:bg-muted/50 dark:bg-card dark:focus-within:bg-white/[0.06]",
|
||||
disabled && "opacity-60",
|
||||
isDragging && "ring-2 ring-primary/40 motion-reduce:ring-0 motion-reduce:border-primary",
|
||||
goalState?.active &&
|
||||
|
||||
@@ -140,6 +140,7 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
|
||||
const [atBottom, setAtBottom] = useState(true);
|
||||
const [composerDockHeight, setComposerDockHeight] = useState(0);
|
||||
const [keyboardInsetBottom, setKeyboardInsetBottom] = useState(0);
|
||||
const [hasVerticalOverflow, setHasVerticalOverflow] = useState(false);
|
||||
const [visibleMessageCount, setVisibleMessageCount] =
|
||||
useState(INITIAL_HISTORY_WINDOW);
|
||||
const hasMessages = messages.length > 0;
|
||||
@@ -474,6 +475,29 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
|
||||
return () => observer.disconnect();
|
||||
}, [hasMessages, measureComposerDock]);
|
||||
|
||||
const measureVerticalOverflow = useCallback(() => {
|
||||
const el = scrollRef.current;
|
||||
if (!el) return;
|
||||
const next = el.scrollHeight > el.clientHeight + 1;
|
||||
setHasVerticalOverflow((current) => (current === next ? current : next));
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const el = scrollRef.current;
|
||||
const content = contentRef.current;
|
||||
if (!el) return;
|
||||
|
||||
measureVerticalOverflow();
|
||||
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(measureVerticalOverflow);
|
||||
observer?.observe(el);
|
||||
if (content) observer?.observe(content);
|
||||
window.addEventListener("resize", measureVerticalOverflow);
|
||||
return () => {
|
||||
observer?.disconnect();
|
||||
window.removeEventListener("resize", measureVerticalOverflow);
|
||||
};
|
||||
}, [composerDockHeight, hasMessages, measureVerticalOverflow, visibleMessages.length]);
|
||||
|
||||
useEffect(() => {
|
||||
const el = scrollRef.current;
|
||||
if (!el) return;
|
||||
@@ -507,7 +531,8 @@ export const ThreadViewport = forwardRef<ThreadViewportHandle, ThreadViewportPro
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className={cn(
|
||||
"thread-viewport-scrollbar absolute inset-0 overflow-y-auto scroll-auto scrollbar-thin",
|
||||
"thread-viewport-scrollbar absolute inset-0 scroll-auto scrollbar-thin",
|
||||
hasMessages && hasVerticalOverflow ? "overflow-y-auto" : "overflow-hidden",
|
||||
"[&::-webkit-scrollbar]:w-1.5",
|
||||
"[&::-webkit-scrollbar-thumb]:rounded-full",
|
||||
"[&::-webkit-scrollbar-thumb]:bg-muted-foreground/30",
|
||||
|
||||
@@ -106,7 +106,7 @@ export function WorkspaceProjectPicker({
|
||||
|
||||
if (nativeProjectPicker) {
|
||||
return (
|
||||
<div className="flex min-w-0 items-center rounded-b-[28px] border-t border-border/25 bg-muted/60 px-3 py-1.5 dark:bg-white/[0.055] sm:px-4">
|
||||
<div className="flex min-w-0 items-center rounded-b-[28px] bg-muted/45 px-3 py-1.5 dark:bg-white/[0.045] sm:px-4">
|
||||
<button
|
||||
type="button"
|
||||
disabled={disabled || pickingFolder}
|
||||
@@ -133,7 +133,7 @@ export function WorkspaceProjectPicker({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex min-w-0 items-center rounded-b-[28px] border-t border-border/25 bg-muted/60 px-3 py-1.5 dark:bg-white/[0.055] sm:px-4">
|
||||
<div className="flex min-w-0 items-center rounded-b-[28px] bg-muted/45 px-3 py-1.5 dark:bg-white/[0.045] sm:px-4">
|
||||
<DropdownMenu open={open} onOpenChange={setOpen}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user