BlockDex

Components

Registries

Free blocks

Method

BlockDex

Components

Registries

Free blocks

Method

Open API

BlockDex

Components

Registries

Free blocks

Method

Open API

Components/ns-ui/citation-inline-card

Citation Inline Card

ns-ui/citation-inline-card
FreeComponent

An inline citation pill (hostname + source count, Geist Mono) that opens one bordered card with a title, excerpt and a 1/N stepper, instead of a popover per source.

Live preview

live · rendered by the registry
Rendered by ns-ui on their own page — this is the component running, not a screenshot of it.

Install it

npx shadcn@latest add https://design.helpmarq.com/r/citation-inline-card.json

Source

registry/core/citation-inline-card/component.tsxdesign.helpmarq.com/r/citation-inline-card.json · first 6 KB
1"use client";
2
3import {
4 useEffect,
5 useId,
6 useRef,
7 useState,
8 type KeyboardEvent as ReactKeyboardEvent,
9} from "react";
10import { createPortal } from "react-dom";
11
12// MarginCite — an inline citation primitive. The trigger is one monochrome
13// superscript pill (hostname of the primary source, plus a small source
14// count when there's more than one) sitting right in the text flow. Opening
15// it reveals ONE bordered card — title, excerpt, a "1 / N" stepper — instead
16// of a popover-per-source; three sources behind a claim is one card the
17// reader pages through, not three stacked callouts.
18//
19// The card is rendered through a portal into document.body and positioned
20// with `position: fixed`, coordinates read from the trigger's own
21// getBoundingClientRect on open, on scroll and on resize. That's the fix for
22// the same clipping hazard tooltips and menus hit: a card left as a plain
23// `absolute` child of the trigger gets silently cut off by the first
24// ancestor with overflow-hidden (a common wrapper around body copy). It also
25// flips above the trigger when there isn't room below, and clamps
26// horizontally so it never runs off the viewport edge.
27//
28// Fully keyboard-operable: the trigger is a real button (Enter/Space toggle
29// it natively), focus moves into the open card so Tab reaches Previous,
30// Next and the source link in order, Left/Right arrow keys step the reader
31// through sources without leaving the keyboard, and Escape closes the card
32// and returns focus to the trigger. A visually-hidden status region
33// announces "Source 2 of 3" on every step so paging is legible to assistive
34// tech, not just sighted users watching the "1 / N" readout update.
35//
36// Zero dependencies beyond react-dom's createPortal. No canvas — the card is
37// plain DOM, and every color is a token (--background --foreground --muted
38// --border --accent) so both themes render correctly. Under
39// prefers-reduced-motion the entrance animation is dropped via a CSS media
40// query; the card still opens instantly and is fully operable.
41
42export type CiteSource = {
43 id: string;
44 title: string;
45 excerpt: string;
46 /** full URL; hostname is derived from it for both the pill and the card footer */
47 url: string;
48};
49
50export interface MarginCiteProps {
51 sources: CiteSource[];
52 className?: string;
53}
54
55const GAP = 8; // px between trigger and card
56const CARD_WIDTH = 320;
57const VIEWPORT_MARGIN = 12; // px clamp from viewport edges
58
59function hostnameOf(url: string): string {
60// … truncated

Files it writes

  • registry/core/citation-inline-card/component.tsx

Facts

Registry
ns-ui
Type
registry:ui
Access
Free
Files written
1
Licence
MIT
First indexed
2026-08-02
Last confirmed
yesterday

Go to the source

Docs on ns-ui design.helpmarq.com nikolas-sapa/ns-ui on GitHub Raw registry item This item as JSON

More from ns-ui

All 228 items
Same registry, same kind — the ones you would have found next
ComponentRegistryKindAccessInstallsCommand
Accordion Latchaccordion-latchns-uiComponentsFreeno deps
Approval Inline Diffapproval-inline-diffns-uiComponentsFreeno deps
ASCII Engraving Contourascii-engraving-contourns-uiComponentsFreeno deps
ASCII Globe Spinascii-globe-spinns-uiComponentsFreeno deps
ASCII Torus Donutascii-torus-donutns-uiComponentsFreeno deps
Autosave Ratchetautosave-ratchetns-uiComponentsFreeno deps
Avatar Stack Flockavatar-stack-flockns-uiComponentsFreeno deps
Background ASCII Ditherbackground-ascii-ditherns-uiComponentsFreeno deps
BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex

BlockDex

Built by

Kynth Studio

Index

Components
Registries
Method
Open API

Guides

shadcn component libraries
Best shadcn registries
Free shadcn blocks

Reference

Corpus counts
Crawl health
hello@kynth.studio
Privacy
Terms

BlockDex