| ... | ... | @@ -1,5 +1,5 @@ |
| 1 | 1 | import { type ProjectEntry, type ProviderKind } from "@t3tools/contracts"; |
| 2 | | import { memo } from "react"; |
| 2 | import { memo, useLayoutEffect, useRef } from "react"; |
| 3 | 3 | import { type ComposerSlashCommand, type ComposerTriggerKind } from "../../composer-logic"; |
| 4 | 4 | import { BotIcon } from "lucide-react"; |
| 5 | 5 | import { cn } from "~/lib/utils"; |
| ... | ... | @@ -41,6 +41,16 @@ export const ComposerCommandMenu = memo(function ComposerCommandMenu(props: { |
| 41 | 41 | onHighlightedItemChange: (itemId: string | null) => void; |
| 42 | 42 | onSelect: (item: ComposerCommandItem) => void; |
| 43 | 43 | }) { |
| 44 | const listRef = useRef<HTMLDivElement>(null); |
| 45 | |
| 46 | useLayoutEffect(() => { |
| 47 | if (!props.activeItemId || !listRef.current) return; |
| 48 | const el = listRef.current.querySelector<HTMLElement>( |
| 49 | `[data-composer-item-id="${CSS.escape(props.activeItemId)}"]`, |
| 50 | ); |
| 51 | el?.scrollIntoView({ block: "nearest" }); |
| 52 | }, [props.activeItemId]); |
| 53 | |
| 44 | 54 | return ( |
| 45 | 55 | <Command |
| 46 | 56 | autoHighlight={false} |
| ... | ... | @@ -51,7 +61,10 @@ export const ComposerCommandMenu = memo(function ComposerCommandMenu(props: { |
| 51 | 61 | ); |
| 52 | 62 | }} |
| 53 | 63 | > |
| 54 | | <div className="relative overflow-hidden rounded-xl border border-border/80 bg-popover/96 shadow-lg/8 backdrop-blur-xs"> |
| 64 | <div |
| 65 | ref={listRef} |
| 66 | className="relative overflow-hidden rounded-xl border border-border/80 bg-popover/96 shadow-lg/8 backdrop-blur-xs" |
| 67 | > |
| 55 | 68 | <CommandList className="max-h-64"> |
| 56 | 69 | {props.items.map((item) => ( |
| 57 | 70 | <ComposerCommandMenuItem |
| ... | ... | @@ -88,8 +101,9 @@ const ComposerCommandMenuItem = memo(function ComposerCommandMenuItem(props: { |
| 88 | 101 | return ( |
| 89 | 102 | <CommandItem |
| 90 | 103 | value={props.item.id} |
| 104 | data-composer-item-id={props.item.id} |
| 91 | 105 | className={cn( |
| 92 | | "cursor-pointer select-none gap-2 data-highlighted:bg-transparent data-highlighted:text-inherit", |
| 106 | "cursor-pointer select-none gap-2 hover:bg-transparent hover:text-inherit data-highlighted:bg-transparent data-highlighted:text-inherit", |
| 93 | 107 | props.isActive && "bg-accent! text-accent-foreground!", |
| 94 | 108 | )} |
| 95 | 109 | onMouseMove={() => { |