feat(web): update mention components to use Button component and enhance styling

This commit is contained in:
Anish Sarkar 2026-05-26 16:50:40 +05:30
parent d445974838
commit 9cd3de9ec1
4 changed files with 19 additions and 10 deletions

View file

@ -21,6 +21,7 @@ import {
useRef, useRef,
} from "react"; } from "react";
import { FOLDER_MENTION_DOCUMENT_TYPE } from "@/atoms/chat/mentioned-documents.atom"; import { FOLDER_MENTION_DOCUMENT_TYPE } from "@/atoms/chat/mentioned-documents.atom";
import { Button } from "@/components/ui/button";
import { getConnectorIcon } from "@/contracts/enums/connectorIcons"; import { getConnectorIcon } from "@/contracts/enums/connectorIcons";
import type { Document } from "@/contracts/types/document.types"; import type { Document } from "@/contracts/types/document.types";
import { getMentionDocKey } from "@/lib/chat/mention-doc-key"; import { getMentionDocKey } from "@/lib/chat/mention-doc-key";
@ -160,8 +161,10 @@ const MentionElement: FC<PlateElementProps<MentionElementNode>> = ({
)} )}
</span> </span>
{ctx ? ( {ctx ? (
<button <Button
type="button" type="button"
variant="ghost"
size="icon"
aria-label={`Remove mention ${element.title}`} aria-label={`Remove mention ${element.title}`}
title={`Remove ${element.title}`} title={`Remove ${element.title}`}
onMouseDown={(e) => e.preventDefault()} onMouseDown={(e) => e.preventDefault()}
@ -169,10 +172,10 @@ const MentionElement: FC<PlateElementProps<MentionElementNode>> = ({
e.stopPropagation(); e.stopPropagation();
ctx.removeChip(element.id, element.document_type); ctx.removeChip(element.id, element.document_type);
}} }}
className="absolute inset-0 flex items-center justify-center rounded-sm opacity-0 transition-opacity hover:text-primary focus-visible:opacity-100 focus-visible:outline-none group-hover:opacity-100" className="absolute inset-0 size-3 rounded-sm p-0 opacity-0 transition-opacity hover:bg-transparent hover:text-primary focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-0 group-hover:opacity-100 [&_svg]:size-3"
> >
<XIcon className="h-3 w-3" /> <XIcon />
</button> </Button>
) : null} ) : null}
</span> </span>
</span> </span>

View file

@ -1,6 +1,7 @@
"use client"; "use client";
import type { MouseEventHandler, ReactNode } from "react"; import type { MouseEventHandler, ReactNode } from "react";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@ -60,13 +61,15 @@ export function MentionChip({
const isInteractive = Boolean(onClick) && !disabled; const isInteractive = Boolean(onClick) && !disabled;
const chip = ( const chip = (
<button <Button
type="button" type="button"
variant="ghost"
size="sm"
onClick={onClick} onClick={onClick}
disabled={disabled} disabled={disabled}
aria-label={ariaLabel ?? label} aria-label={ariaLabel ?? label}
className={cn( className={cn(
"inline-flex h-5 items-center gap-1 rounded bg-primary/10 px-1 align-middle text-xs font-bold text-primary/60 leading-none focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "h-5 gap-1 rounded bg-primary/10 px-1 align-middle text-xs font-bold text-primary/60 leading-none hover:bg-primary/10 hover:text-primary/60 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
isInteractive ? "cursor-pointer" : "cursor-default", isInteractive ? "cursor-pointer" : "cursor-default",
disabled && "opacity-60", disabled && "opacity-60",
className className
@ -74,7 +77,7 @@ export function MentionChip({
> >
<span className="inline-flex shrink-0 text-muted-foreground">{icon}</span> <span className="inline-flex shrink-0 text-muted-foreground">{icon}</span>
<span className="max-w-[120px] truncate leading-none">{label}</span> <span className="max-w-[120px] truncate leading-none">{label}</span>
</button> </Button>
); );
if (!tooltip) return chip; if (!tooltip) return chip;

View file

@ -564,7 +564,7 @@ const Composer: FC = () => {
setSuggestionAnchorPoint(null); setSuggestionAnchorPoint(null);
return; return;
} }
setSuggestionAnchorPoint(anchorPoint); setSuggestionAnchorPoint((current) => current ?? anchorPoint);
setShowDocumentPopover(true); setShowDocumentPopover(true);
setMentionQuery(trigger.query); setMentionQuery(trigger.query);
}, []); }, []);
@ -596,7 +596,7 @@ const Composer: FC = () => {
setSuggestionAnchorPoint(null); setSuggestionAnchorPoint(null);
return; return;
} }
setSuggestionAnchorPoint(anchorPoint); setSuggestionAnchorPoint((current) => current ?? anchorPoint);
setShowPromptPicker(true); setShowPromptPicker(true);
setActionQuery(trigger.query); setActionQuery(trigger.query);
}, [clipboardInitialText]); }, [clipboardInitialText]);
@ -866,7 +866,7 @@ const Composer: FC = () => {
onDocumentRemove={handleDocumentRemove} onDocumentRemove={handleDocumentRemove}
onSubmit={handleSubmit} onSubmit={handleSubmit}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
className="min-h-[24px]" className="min-h-[24px] **:data-slate-placeholder:font-semibold"
/> />
</div> </div>
<ComposerAction isBlockedByOtherUser={isBlockedByOtherUser} /> <ComposerAction isBlockedByOtherUser={isBlockedByOtherUser} />

View file

@ -14,6 +14,7 @@ function ComposerSuggestionPopoverContent({
collisionPadding = 12, collisionPadding = 12,
onOpenAutoFocus, onOpenAutoFocus,
onCloseAutoFocus, onCloseAutoFocus,
style,
...props ...props
}: React.ComponentProps<typeof PopoverContent>) { }: React.ComponentProps<typeof PopoverContent>) {
return ( return (
@ -31,8 +32,10 @@ function ComposerSuggestionPopoverContent({
}} }}
className={cn( className={cn(
"w-[280px] overflow-hidden rounded-md border border-popover-border bg-popover p-0 text-popover-foreground shadow-md sm:w-[320px]", "w-[280px] overflow-hidden rounded-md border border-popover-border bg-popover p-0 text-popover-foreground shadow-md sm:w-[320px]",
"data-[state=open]:!animate-none data-[state=closed]:!animate-none data-[state=open]:!duration-0 data-[state=closed]:!duration-0",
className className
)} )}
style={{ ...style, animation: "none" }}
{...props} {...props}
/> />
); );