fix: profile bio

This commit is contained in:
gosangam
2026-08-08 00:49:39 +05:30
parent 9b7758da99
commit ce373e3e03
2 changed files with 90 additions and 74 deletions
+30 -2
View File
@@ -69,6 +69,7 @@ export const MentionTextarea = forwardRef<
const [pos, setPos] = useState<PanelPos | null>(null);
const reqRef = useRef(0);
const blurTimer = useRef<number | null>(null);
const listRef = useRef<HTMLDivElement>(null);
// Detect the active @token from the text up to the caret.
function detect(el: HTMLTextAreaElement) {
@@ -78,8 +79,10 @@ export const MentionTextarea = forwardRef<
setMention(null);
return;
}
setMention({ start: caret - m[2].length - 1, query: m[2] });
setActive(0);
const next = { start: caret - m[2].length - 1, query: m[2] };
// Reposition unconditionally — the field grows as text wraps, so the panel
// has to stay pinned to it even when the token itself hasn't changed.
const r = el.getBoundingClientRect();
// Prefer opening ABOVE the field: that's what the comment composer needs
// (it sits at the bottom of a drawer, often above the on-screen keyboard).
@@ -94,6 +97,18 @@ export const MentionTextarea = forwardRef<
? { bottom: window.innerHeight - r.top + 6 }
: { top: r.bottom + 6 }),
});
// Bail out if the token is byte-for-byte what we already have. detect()
// also runs on keyup and click, so re-seeding an identical mention would:
// • reset `active` to 0 — which cancelled the ↑/↓ highlight the instant
// the key came back up, making arrow navigation look dead; and
// • hand the fetch effect a fresh object identity, re-requesting
// suggestions on every single keystroke.
if (mention && mention.start === next.start && mention.query === next.query) {
return;
}
setMention(next);
setActive(0);
}
// Fetch suggestions (debounced) whenever the active token changes.
@@ -136,6 +151,17 @@ export const MentionTextarea = forwardRef<
const listOpen = !!mention && (loading || items.length > 0);
// Keep the highlighted row visible: the panel caps at max-h-56, which holds
// ~5 of the 8 suggestions, so arrowing past the fifth would otherwise move
// the highlight out of sight. `block: "nearest"` scrolls the panel the
// minimum amount and never scrolls the page behind it.
useEffect(() => {
if (!listOpen) return;
listRef.current
?.querySelector<HTMLElement>(`[data-idx="${active}"]`)
?.scrollIntoView({ block: "nearest" });
}, [active, listOpen]);
function onKeyDown(e: React.KeyboardEvent<HTMLTextAreaElement>) {
if (listOpen && items.length > 0) {
if (e.key === "ArrowDown") {
@@ -195,6 +221,7 @@ export const MentionTextarea = forwardRef<
{listOpen && pos && typeof document !== "undefined"
? createPortal(
<div
ref={listRef}
role="listbox"
aria-label="Mention suggestions"
style={{
@@ -216,6 +243,7 @@ export const MentionTextarea = forwardRef<
key={u.id ?? u.handle}
type="button"
role="option"
data-idx={i}
aria-selected={i === active}
// Keep textarea focus + cancel the pending blur-close so the
// click registers before the list would otherwise close.