Skip to content

Citation Popover

Trust component

<loquix-citation-popover> is the small numbered chip you place inside generated prose. Hovering or focusing it opens a popover with the source title, host, and snippet, so a reader can check a claim without leaving the sentence.

loquix-citation-popoverhover and focusURL allowlist
Citations in prose Live component

The refund window is 30 days from delivery and applies to unopened items only .

Hover or tab to a chip to open its popover.

import '@loquix/core/define/define-citation-popover';
<loquix-citation-popover index="1"></loquix-citation-popover>

source is an object, so assign it as a property.

const chip = document.querySelector('loquix-citation-popover');
chip.source = {
title: 'Refund policy',
url: 'https://example.com/policies/refunds',
host: 'example.com',
snippet: 'Customers may request a full refund within 30 days of delivery.',
};
chip.addEventListener('loquix-citation-click', (event) => {
openSourcePanel(event.detail.source);
});
Field Type Required Description
title string yes Source title shown in the popover.
url string yes Target URL. Validated against an http(s): allowlist before rendering.
host string no Display host, such as arxiv.org.
snippet string no Short excerpt shown under the title.
favicon string no Favicon URL, validated against the same allowlist.
id string no Stable identifier for analytics or de-duplication.
Property Attribute Type Default Description
index index number 1 One-based citation number shown in the badge. Matches the numbering in Source List.
source — Source { title: '', url: '' } Source data. Property-only.
Event Detail Description
loquix-citation-click { index, source } Fired when the chip is clicked or activated with the keyboard.

The popover is positioned inside the component and carries a high z-index, but a z-index only ranks an element within its own stacking context. If any ancestor establishes one — a transform, a filter, an opacity below 1, or an isolation: isolate on a layout column — the popover cannot paint above anything outside it, and fixed page chrome such as a sidebar will cover it.

If that happens, the fix is in your layout rather than in the component: remove the isolating property from the ancestor, or raise that ancestor above the chrome it is losing to.

The panel sits a little away from the chip, and the pointer crosses that gap on its way over. Closing is held back briefly so it stays open when you do; Escape and moving focus away close it at once.

The popover is wired through aria-describedby, so a screen reader announces the source as a description of the chip rather than replacing its name. The popover opens on focus as well as hover, and closes on blur or Escape.

Positioning uses Floating UI with autoUpdate(), so the popover follows the chip through scrolling and resizing. The cleanup runs on close and on disconnect, so no listeners are left behind when a message is removed from the transcript.

Part Purpose
chip The clickable chip button.
index Numeric badge.
popover Popover panel.
favicon Favicon container inside the popover.
body Text container inside the popover.
title Source title.
host Host name.
snippet Snippet text.
arrow Trailing external-link icon.
Variable Purpose
--loquix-ai-color Chip foreground and hover background.
--loquix-ai-color-subtle Chip resting background.