Merge ticket branch t088

This commit is contained in:
Hugh Kaznowski
2026-09-07 10:36:17 +01:00
3 changed files with 19 additions and 17 deletions
+2 -8
View File
@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from 'react' import { useEffect, useRef, useState } from 'react'
import { metricPrimitiveToDisplayString, type LogEntry, type ParamDeclaration } from '../lib/api' import { metricPrimitiveToDisplayString, type LogEntry, type ParamDeclaration } from '../lib/api'
import { useClickOutside } from '../lib/useClickOutside'
import { sectionHeaderClassName, sectionHeaderLeftClassName } from './CollapsibleSection' import { sectionHeaderClassName, sectionHeaderLeftClassName } from './CollapsibleSection'
import { HelpIcon } from './HelpIcon' import { HelpIcon } from './HelpIcon'
@@ -37,14 +38,7 @@ function ColumnPicker({
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
useEffect(() => { useClickOutside(ref, () => setOpen(false), open)
if (!open) return
function onClickOutside(e: MouseEvent) {
if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)
}
document.addEventListener('mousedown', onClickOutside)
return () => document.removeEventListener('mousedown', onClickOutside)
}, [open])
return ( return (
<div ref={ref} className="relative"> <div ref={ref} className="relative">
+3 -9
View File
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react' import { useRef, useState } from 'react'
import { useClickOutside } from '../lib/useClickOutside'
// Regex syntax cheat sheet, scoped to what the Rust `regex` crate actually supports (used server-side // Regex syntax cheat sheet, scoped to what the Rust `regex` crate actually supports (used server-side
// for message-match/field-match regexes and the filter bar's `regex(...)`) — no PCRE-only lookaround // for message-match/field-match regexes and the filter bar's `regex(...)`) — no PCRE-only lookaround
@@ -30,14 +31,7 @@ export function RegexHelpIcon({ label }: { label?: string }) {
const open = pinned || hovering const open = pinned || hovering
const ref = useRef<HTMLDivElement>(null) const ref = useRef<HTMLDivElement>(null)
useEffect(() => { useClickOutside(ref, () => setPinned(false), pinned)
if (!pinned) return
function onClickOutside(e: MouseEvent) {
if (ref.current && !ref.current.contains(e.target as Node)) setPinned(false)
}
document.addEventListener('mousedown', onClickOutside)
return () => document.removeEventListener('mousedown', onClickOutside)
}, [pinned])
return ( return (
<div <div
+14
View File
@@ -0,0 +1,14 @@
import { useEffect, type RefObject } from 'react'
// Shared by popover-style UI (RegexHelpIcon, LogPreview's ColumnPicker) that closes itself when a
// mousedown lands outside its container ref, while `active`.
export function useClickOutside(ref: RefObject<HTMLElement | null>, onOutside: () => void, active: boolean) {
useEffect(() => {
if (!active) return
function onClickOutside(e: MouseEvent) {
if (ref.current && !ref.current.contains(e.target as Node)) onOutside()
}
document.addEventListener('mousedown', onClickOutside)
return () => document.removeEventListener('mousedown', onClickOutside)
}, [active, ref, onOutside])
}