Skip to content

Commit fc12024

Browse files
committed
styling
1 parent 1559125 commit fc12024

6 files changed

Lines changed: 114 additions & 91 deletions

File tree

packages/ui/src/features/canvas/components/ChannelFeedView.tsx

Lines changed: 71 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,8 @@ import {
1010
AvatarFallback,
1111
AvatarGroup,
1212
Badge,
13-
Button,
14-
ButtonGroup,
1513
Card,
1614
CardContent,
17-
ChatMessage,
18-
ChatMessageAvatar,
19-
ChatMessageContent,
20-
ChatMessageHeader,
2115
ChatMessageScroller,
2216
ChatMessageScrollerButton,
2317
ChatMessageScrollerContent,
@@ -26,10 +20,18 @@ import {
2620
ChatMessageScrollerViewport,
2721
cn,
2822
Spinner,
29-
Tooltip,
30-
TooltipContent,
31-
TooltipProvider,
32-
TooltipTrigger,
23+
ThreadItem,
24+
ThreadItemAction,
25+
ThreadItemActions,
26+
ThreadItemAuthor,
27+
ThreadItemBody,
28+
ThreadItemContent,
29+
ThreadItemGutter,
30+
ThreadItemHeader,
31+
ThreadItemReplies,
32+
ThreadItemRepliesLabel,
33+
ThreadItemRepliesMeta,
34+
ThreadItemTimestamp,
3335
} from "@posthog/quill";
3436
import { formatRelativeTimeShort } from "@posthog/shared";
3537
import type { Task, TaskRunStatus } from "@posthog/shared/domain-types";
@@ -255,9 +257,9 @@ function TaskCard({ task, onOpen }: { task: Task; onOpen: () => void }) {
255257
<Card
256258
size="sm"
257259
className={cn(
258-
"mt-1.5 w-full cursor-pointer py-0 transition-colors hover:bg-fill-hover",
260+
"mt-1.5 w-full max-w-[820px] cursor-pointer rounded-sm py-0 transition-none hover:bg-fill-hover",
259261
statusDisplay.isMerged
260-
? "border-transparent bg-(--purple-a1) shadow-[0_0_0_1px_var(--purple-8)]"
262+
? "border-transparent bg-(--purple-a2) shadow-[0_0_0_1px_var(--purple-8)] hover:bg-(--purple-a3) dark:bg-(--purple-a1) dark:hover:bg-(--purple-a2)"
261263
: "hover:border-border-primary",
262264
)}
263265
onClick={onOpen}
@@ -328,25 +330,21 @@ function RepliesRow({
328330
const last = messages[messages.length - 1];
329331

330332
return (
331-
<button
332-
type="button"
333-
onClick={onOpenThread}
334-
className="mt-1 flex w-fit items-center gap-2 rounded-md px-1.5 py-1 hover:bg-fill-secondary"
335-
>
333+
<ThreadItemReplies onClick={onOpenThread} className="mt-1">
336334
<AvatarGroup size="xs" stacked>
337335
{authors.map((author, index) => (
338336
<Avatar key={author?.uuid ?? index} size="xs">
339337
<AvatarFallback>{getUserInitials(author)}</AvatarFallback>
340338
</Avatar>
341339
))}
342340
</AvatarGroup>
343-
<Text size="1" weight="medium" className="text-accent-11">
341+
<ThreadItemRepliesLabel>
344342
{messages.length} {messages.length === 1 ? "reply" : "replies"}
345-
</Text>
346-
<Text size="1" className="text-muted-foreground">
343+
</ThreadItemRepliesLabel>
344+
<ThreadItemRepliesMeta>
347345
Last reply {formatRelativeTimeShort(last.created_at)}
348-
</Text>
349-
</button>
346+
</ThreadItemRepliesMeta>
347+
</ThreadItemReplies>
350348
);
351349
}
352350

@@ -363,11 +361,8 @@ function FeedItem({
363361
const isAgent = !task.created_by || task.origin_product !== "user_created";
364362

365363
return (
366-
<ChatMessage className="group relative rounded-md px-3 py-2 hover:bg-fill-secondary/50">
367-
{/* Quill's avatar slot bottom-aligns for bubble chats; a Slack feed
368-
anchors it beside the name row. The slot draws its own circle, so
369-
drop its background and let the inner Avatar render. */}
370-
<ChatMessageAvatar className="self-start bg-transparent">
364+
<ThreadItem className="py-4 pr-8 hover:bg-fill-hover/10">
365+
<ThreadItemGutter>
371366
<Avatar>
372367
<AvatarFallback>
373368
{isAgent && !task.created_by ? (
@@ -377,64 +372,49 @@ function FeedItem({
377372
)}
378373
</AvatarFallback>
379374
</Avatar>
380-
</ChatMessageAvatar>
381-
<ChatMessageContent className="min-w-0 gap-0.5">
382-
<ChatMessageHeader className="items-baseline gap-2 px-0">
383-
<Text size="2" weight="bold" className="truncate">
375+
</ThreadItemGutter>
376+
377+
<ThreadItemContent className="min-w-0">
378+
<ThreadItemHeader>
379+
<ThreadItemAuthor>
384380
{task.created_by ? userDisplayName(task.created_by) : "Agent"}
385-
</Text>
381+
</ThreadItemAuthor>
386382
{isAgent && <Badge variant="info">Agent</Badge>}
387-
<Text size="1" className="shrink-0 text-muted-foreground">
383+
<ThreadItemTimestamp
384+
dateTime={new Date(task.created_at).toISOString()}
385+
>
388386
{formatRelativeTimeShort(task.created_at)}
389-
</Text>
390-
</ChatMessageHeader>
387+
</ThreadItemTimestamp>
388+
</ThreadItemHeader>
391389

392-
<Text size="2" className="line-clamp-4 whitespace-pre-wrap break-words">
390+
<ThreadItemBody className="wrap-break-word line-clamp-4 whitespace-pre-wrap">
393391
{prompt}
394-
</Text>
392+
</ThreadItemBody>
395393

396394
<TaskCard task={task} onOpen={() => onOpenTask(task)} />
397395
<RepliesRow taskId={task.id} onOpenThread={() => onOpenThread(task)} />
398-
</ChatMessageContent>
396+
</ThreadItemContent>
399397

400-
{/* Hover toolbar, storybook-style: floats top-right of the row. */}
401-
<div className="absolute top-1 right-2 opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100">
402-
<TooltipProvider delay={400}>
403-
<ButtonGroup className="rounded-md border border-border bg-surface shadow-sm">
404-
<Tooltip>
405-
<TooltipTrigger
406-
render={
407-
<Button
408-
variant="default"
409-
size="icon-sm"
410-
aria-label="Reply in thread"
411-
onClick={() => onOpenThread(task)}
412-
>
413-
<ChatCircleIcon size={15} />
414-
</Button>
415-
}
416-
/>
417-
<TooltipContent side="top">Reply in thread</TooltipContent>
418-
</Tooltip>
419-
<Tooltip>
420-
<TooltipTrigger
421-
render={
422-
<Button
423-
variant="default"
424-
size="icon-sm"
425-
aria-label="Open task"
426-
onClick={() => onOpenTask(task)}
427-
>
428-
<ArrowSquareOutIcon size={15} />
429-
</Button>
430-
}
431-
/>
432-
<TooltipContent side="top">Open task</TooltipContent>
433-
</Tooltip>
434-
</ButtonGroup>
435-
</TooltipProvider>
436-
</div>
437-
</ChatMessage>
398+
{/* Actions anchor to the row's top-right corner; a top tooltip there
399+
overhangs the panel edge and gets clipped by the scroll container, so
400+
open tooltips toward the content instead. */}
401+
<ThreadItemActions aria-label="Message actions" className="inset-bs-2">
402+
<ThreadItemAction
403+
label="Reply in thread"
404+
tooltipSide="left"
405+
onClick={() => onOpenThread(task)}
406+
>
407+
<ChatCircleIcon size={15} />
408+
</ThreadItemAction>
409+
<ThreadItemAction
410+
label="Open task"
411+
tooltipSide="left"
412+
onClick={() => onOpenTask(task)}
413+
>
414+
<ArrowSquareOutIcon size={15} />
415+
</ThreadItemAction>
416+
</ThreadItemActions>
417+
</ThreadItem>
438418
);
439419
}
440420

@@ -470,9 +450,22 @@ export function ChannelFeedView({
470450
<ChatMessageScrollerProvider defaultScrollPosition="end">
471451
<ChatMessageScroller className="min-h-0 flex-1">
472452
<ChatMessageScrollerViewport>
473-
<ChatMessageScrollerContent className="mx-auto w-full max-w-[820px] px-1 py-3">
453+
{/* Horizontal padding is load-bearing: ThreadItem's actions float at
454+
the row's top-right corner (absolute, past the row edge). Without a
455+
gutter they hug the scroll container and get clipped. */}
456+
<ChatMessageScrollerContent className="mx-auto w-full gap-0 py-4">
474457
{tasks.map((task) => (
475-
<ChatMessageScrollerItem key={task.id} messageId={task.id}>
458+
<ChatMessageScrollerItem
459+
key={task.id}
460+
messageId={task.id}
461+
// Rows already get `content-visibility:auto` from quill, but its
462+
// default `contain-intrinsic-size` (10rem) under-reserves a feed
463+
// row (message + task card + replies ≈ 13rem), so off-screen
464+
// rows collapse too small and the scrollbar jumps as they paint
465+
// in. A closer estimate keeps scrolling stable; `auto` still
466+
// remembers each row's real height after its first render.
467+
className="[contain-intrinsic-size:auto_13rem] hover:bg-fill-hover/50"
468+
>
476469
<FeedItem
477470
task={task}
478471
onOpenTask={onOpenTask}

packages/ui/src/features/canvas/components/WebsiteChannelHome.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export function WebsiteChannelHome({ channelId }: { channelId: string }) {
168168
onOpenTask={handleOpenTask}
169169
onOpenThread={handleOpenThread}
170170
/>
171-
<div className="mx-auto w-full max-w-[820px] px-4 pb-4">
171+
<div className="mx-auto w-full px-4 pb-4">
172172
<ChannelHomeComposer
173173
ref={composerRef}
174174
channelId={channelId}

packages/ui/src/features/message-editor/components/PromptInput.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ export const PromptInput = forwardRef<EditorHandle, PromptInputProps>(
359359
<InputGroup
360360
onClick={handleContainerClick}
361361
onContextMenu={handleContextMenu}
362-
className={`h-auto flex-1 cursor-text bg-card ${isBashMode ? "ring-1 ring-blue-9" : "focus-within:ring-1 focus-within:ring-purple-9"}`}
362+
className={`h-auto flex-1 cursor-text bg-card ${isBashMode ? "ring-1 ring-blue-9" : "focus-within:border-ring/50 focus-within:ring-3 focus-within:ring-ring/30"}`}
363363
{...(tourTarget && {
364364
"data-tour": `${tourTarget}-editor`,
365365
"data-tour-ready": !isEmpty ? "true" : undefined,

packages/ui/src/features/message-editor/components/message-editor.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* Tiptap placeholder - targets empty first paragraph */
22
.cli-editor p.is-editor-empty:first-child::before {
33
content: attr(data-placeholder);
4-
color: var(--gray-8);
4+
color: var(--muted-foreground);
55
pointer-events: none;
66
float: left;
77
height: 0;

pnpm-lock.yaml

Lines changed: 39 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ catalog:
88
'@hono/trpc-server': ^0.3.4
99
'@parcel/watcher': ^2.5.6
1010
'@phosphor-icons/react': ^2.1.10
11-
'@posthog/quill': 0.3.0-beta.21
11+
'@posthog/quill': 0.3.0-beta.22
1212
'@radix-ui/themes': ^3.2.1
1313
'@tanstack/react-query': ^5.100.14
1414
'@tanstack/react-router': ^1.170.10

0 commit comments

Comments
 (0)