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.
Preview
Section titled “Preview”The refund window is 30 days from delivery
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);});The source object
Section titled “The source object”| 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. |
Properties
Section titled “Properties”| 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. |
Events
Section titled “Events”| Event | Detail | Description |
|---|---|---|
loquix-citation-click |
{ index, source } |
Fired when the chip is clicked or activated with the keyboard. |
Stacking
Section titled “Stacking”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.
Accessibility
Section titled “Accessibility”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.
CSS parts
Section titled “CSS parts”| 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. |
CSS custom properties
Section titled “CSS custom properties”| Variable | Purpose |
|---|---|
--loquix-ai-color |
Chip foreground and hover background. |
--loquix-ai-color-subtle |
Chip resting background. |