fix(ui): unwrap the link hint popover and unify the mono font (#5023)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Amir Raminfar
2026-09-06 02:13:50 +00:00
committed by GitHub
co-authored by Claude Opus 5
parent 81c3e30152
commit 7cd703b6e9
4 changed files with 93 additions and 59 deletions
+1 -15
View File
@@ -63,7 +63,7 @@
{{ key.join(".") }}
</td>
<td class="truncate max-md:hidden">
<code>{{ JSON.stringify(value) }}</code>
<code class="font-mono">{{ JSON.stringify(value) }}</code>
</td>
<td>
<input type="checkbox" class="toggle toggle-primary" :checked="enabled" @change="toggleField(key)" />
@@ -167,17 +167,3 @@ const toggleAllFields = computed({
useSortable(list, fields);
</script>
<style scoped>
@reference "@/main.css";
.font-mono {
font-family:
ui-monospace,
SFMono-Regular,
SF Mono,
Consolas,
Liberation Mono,
monaco,
Menlo,
monospace;
}
</style>
+1 -9
View File
@@ -60,15 +60,7 @@ useIntersectionObserver(
<style scoped>
@reference "@/main.css";
ul {
font-family:
ui-monospace,
SFMono-Regular,
SF Mono,
Consolas,
Liberation Mono,
monaco,
Menlo,
monospace;
font-family: var(--font-mono);
> li {
@apply flex px-2 py-1 break-words last:snap-end odd:bg-gray-400/[0.07] md:px-4;
@@ -23,8 +23,8 @@
</div>
<pre
class="bg-base-300/60 rounded-box overflow-x-auto p-2 font-mono text-[11px] leading-relaxed"
><code>{{ snippet }}</code></pre>
class="bg-base-300/60 rounded-box p-2 text-[11px] leading-relaxed break-all whitespace-pre-wrap"
><code class="font-mono">{{ snippet }}</code></pre>
<template #action>
<button type="button" class="btn btn-xs btn-primary" @click="copySnippet">
+89 -33
View File
@@ -1,36 +1,39 @@
<template>
<div class="dropdown" :class="align === 'end' ? 'dropdown-end' : ''">
<button
tabindex="0"
role="button"
class="icon-btn text-base-content/25 hover:text-primary shrink-0 transition-colors"
:title="title"
:aria-label="title"
>
<slot name="icon"><mdi:lightbulb-on-outline class="size-4" /></slot>
</button>
<div
tabindex="0"
class="dropdown-content rounded-box bg-base-200 border-base-content/20 z-50 mt-1 border p-3 text-xs shadow-sm"
:style="{ width: `${width}px` }"
>
<div class="text-base-content/60 mb-2 text-[11px] tracking-wide uppercase">{{ title }}</div>
<slot></slot>
<div class="mt-2 flex items-center justify-between gap-2">
<div><slot name="action"></slot></div>
<div class="flex items-center gap-2">
<a
v-if="docs"
:href="docs"
target="_blank"
rel="noopener noreferrer"
class="link link-hover text-base-content/60"
>{{ $t("hint.learn-more") }}</a
>
<button type="button" class="link link-hover text-base-content/60" @click="$emit('dismiss')">
{{ $t("hint.dismiss") }}
</button>
</div>
<button
ref="trigger"
type="button"
class="icon-btn text-base-content/25 hover:text-primary shrink-0 transition-colors"
:title="title"
:aria-label="title"
:popovertarget="id"
>
<slot name="icon"><mdi:lightbulb-on-outline class="size-4" /></slot>
</button>
<div
ref="panel"
:id="id"
popover
class="rounded-box bg-base-200 border-base-content/20 fixed inset-auto m-0 max-w-[calc(100vw-1rem)] border p-3 text-xs whitespace-normal shadow-sm"
:style="{ width: `${width}px` }"
@beforetoggle="onBeforeToggle"
@toggle="onToggle"
>
<div class="text-base-content/60 mb-2 text-[11px] tracking-wide uppercase">{{ title }}</div>
<slot></slot>
<div class="mt-2 flex flex-wrap items-center justify-between gap-2">
<div><slot name="action"></slot></div>
<div class="flex items-center gap-2">
<a
v-if="docs"
:href="docs"
target="_blank"
rel="noopener noreferrer"
class="link link-hover text-base-content/60"
>{{ $t("hint.learn-more") }}</a
>
<button type="button" class="link link-hover text-base-content/60" @click="dismiss">
{{ $t("hint.dismiss") }}
</button>
</div>
</div>
</div>
@@ -40,6 +43,11 @@
/**
* A dismissible "did you know" popover hung off a small icon. Use it to teach an opt-in
* feature at the point where its absence is visible, not as a general tooltip.
*
* The panel uses the native popover API so it renders in the top layer. Anything else gets
* clipped by (and widens) an ancestor with `overflow`, like the container table's scroller.
* The top layer does not escape inheritance though, so the panel resets `white-space`, which
* the container table's cells set to `nowrap`.
*/
const {
title,
@@ -54,5 +62,53 @@ const {
align?: "start" | "end";
}>();
defineEmits<{ dismiss: [] }>();
const emit = defineEmits<{ dismiss: [] }>();
const id = `hint-${useId()}`;
const trigger = useTemplateRef("trigger");
const panel = useTemplateRef("panel");
const GAP = 4;
const MARGIN = 8;
// The popover is in the top layer, so it is positioned against the viewport by hand instead
// of by an anchor. CSS anchor positioning would do this, but Firefox does not have it yet.
function position() {
if (!trigger.value || !panel.value) return;
const anchor = trigger.value.getBoundingClientRect();
const { offsetWidth, offsetHeight } = panel.value;
const left = align === "end" ? anchor.right - offsetWidth : anchor.left;
panel.value.style.left = `${Math.min(Math.max(MARGIN, left), Math.max(MARGIN, window.innerWidth - offsetWidth - MARGIN))}px`;
const below = anchor.bottom + GAP;
const flip = offsetHeight > 0 && below + offsetHeight > window.innerHeight - MARGIN && anchor.top > offsetHeight;
panel.value.style.top = `${flip ? anchor.top - offsetHeight - GAP : below}px`;
}
function onBeforeToggle(event: ToggleEvent) {
if (event.newState === "open") position();
}
function onToggle(event: ToggleEvent) {
if (event.newState === "open") {
// Now that it is laid out, its real height is known and it can flip above the trigger.
position();
window.addEventListener("scroll", position, true);
window.addEventListener("resize", position);
} else {
window.removeEventListener("scroll", position, true);
window.removeEventListener("resize", position);
}
}
onScopeDispose(() => {
window.removeEventListener("scroll", position, true);
window.removeEventListener("resize", position);
});
function dismiss() {
panel.value?.hidePopover();
emit("dismiss");
}
</script>