@hex-core/components 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_tsup-dts-rollup.d.ts +575 -18
- package/dist/accordion.js.map +1 -1
- package/dist/alert-dialog.js.map +1 -1
- package/dist/alert.js.map +1 -1
- package/dist/arc.js.map +1 -1
- package/dist/attachment.js.map +1 -1
- package/dist/audio-player.js.map +1 -1
- package/dist/audio-waveform.js.map +1 -1
- package/dist/auth-forgot-password.js.map +1 -1
- package/dist/auth-reset-password.js.map +1 -1
- package/dist/auth-sign-in-split.js.map +1 -1
- package/dist/auth-sign-up-card.js.map +1 -1
- package/dist/auth-verify-email.js.map +1 -1
- package/dist/auth-verify-otp.js.map +1 -1
- package/dist/avatar.js.map +1 -1
- package/dist/badge.js.map +1 -1
- package/dist/branch.d.ts +2 -0
- package/dist/branch.js +136 -0
- package/dist/branch.js.map +1 -0
- package/dist/breadcrumb.js.map +1 -1
- package/dist/button.js.map +1 -1
- package/dist/calendar.js.map +1 -1
- package/dist/canvas.js.map +1 -1
- package/dist/card.js.map +1 -1
- package/dist/chain-of-thought.d.ts +3 -0
- package/dist/chain-of-thought.js +119 -0
- package/dist/chain-of-thought.js.map +1 -0
- package/dist/checkbox.js.map +1 -1
- package/dist/chord.js.map +1 -1
- package/dist/citation.js.map +1 -1
- package/dist/cloze.js.map +1 -1
- package/dist/cluster.js.map +1 -1
- package/dist/code-block-copy.js.map +1 -1
- package/dist/code-block.js.map +1 -1
- package/dist/color-picker.js.map +1 -1
- package/dist/combobox.js.map +1 -1
- package/dist/command.js.map +1 -1
- package/dist/compare-table.js.map +1 -1
- package/dist/composer.js.map +1 -1
- package/dist/container.js.map +1 -1
- package/dist/context-menu.js.map +1 -1
- package/dist/conversation.d.ts +3 -0
- package/dist/conversation.js +358 -0
- package/dist/conversation.js.map +1 -0
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.js.map +1 -1
- package/dist/deck.js.map +1 -1
- package/dist/dendrogram.js.map +1 -1
- package/dist/diagram.js.map +1 -1
- package/dist/dialog.js.map +1 -1
- package/dist/drawer.js.map +1 -1
- package/dist/dropdown-menu.js.map +1 -1
- package/dist/dropzone.js.map +1 -1
- package/dist/empty.js.map +1 -1
- package/dist/error-state.js.map +1 -1
- package/dist/file-tree.js.map +1 -1
- package/dist/flashcard.js.map +1 -1
- package/dist/flowchart.js.map +1 -1
- package/dist/form.js.map +1 -1
- package/dist/funnel.js.map +1 -1
- package/dist/gantt.js.map +1 -1
- package/dist/grid.js.map +1 -1
- package/dist/hover-card.js.map +1 -1
- package/dist/image-occlusion.js.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.js +1011 -13
- package/dist/index.js.map +1 -1
- package/dist/inline-citation.d.ts +2 -0
- package/dist/inline-citation.js +108 -0
- package/dist/inline-citation.js.map +1 -0
- package/dist/input-otp.js.map +1 -1
- package/dist/input.js.map +1 -1
- package/dist/label.js.map +1 -1
- package/dist/loading-indicator.js.map +1 -1
- package/dist/loading.js.map +1 -1
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +784 -4
- package/dist/markdown.js.map +1 -1
- package/dist/matrix.js.map +1 -1
- package/dist/menubar.js.map +1 -1
- package/dist/message-actions.js.map +1 -1
- package/dist/message-list.js.map +1 -1
- package/dist/message.js.map +1 -1
- package/dist/mind-map.js.map +1 -1
- package/dist/multi-combobox.js.map +1 -1
- package/dist/navigation-menu.js.map +1 -1
- package/dist/org-chart.js.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/plan.d.ts +3 -0
- package/dist/plan.js +183 -0
- package/dist/plan.js.map +1 -0
- package/dist/popover.js.map +1 -1
- package/dist/progress.js.map +1 -1
- package/dist/pyramid.js.map +1 -1
- package/dist/quiz.js.map +1 -1
- package/dist/radio-group.js.map +1 -1
- package/dist/reasoning.js.map +1 -1
- package/dist/resizable.js.map +1 -1
- package/dist/sankey.js.map +1 -1
- package/dist/schemas.d.ts +8 -0
- package/dist/schemas.js +774 -17
- package/dist/schemas.js.map +1 -1
- package/dist/scroll-area.js.map +1 -1
- package/dist/select.js.map +1 -1
- package/dist/separator.js.map +1 -1
- package/dist/sequence.js.map +1 -1
- package/dist/sheet.js.map +1 -1
- package/dist/shimmer.d.ts +2 -0
- package/dist/shimmer.js +39 -0
- package/dist/shimmer.js.map +1 -0
- package/dist/sidebar.js.map +1 -1
- package/dist/skeleton.js.map +1 -1
- package/dist/slider.js.map +1 -1
- package/dist/sources.d.ts +3 -0
- package/dist/sources.js +164 -0
- package/dist/sources.js.map +1 -0
- package/dist/spaced-repetition.js.map +1 -1
- package/dist/spacer.js.map +1 -1
- package/dist/speech-recognition.js.map +1 -1
- package/dist/stack.js.map +1 -1
- package/dist/stepper.js.map +1 -1
- package/dist/suggestion.js.map +1 -1
- package/dist/sunburst.js.map +1 -1
- package/dist/switch.js.map +1 -1
- package/dist/table.js.map +1 -1
- package/dist/tabs.js.map +1 -1
- package/dist/tag.js.map +1 -1
- package/dist/task.d.ts +3 -0
- package/dist/task.js +189 -0
- package/dist/task.js.map +1 -0
- package/dist/terminal.js +11 -0
- package/dist/terminal.js.map +1 -1
- package/dist/textarea.js.map +1 -1
- package/dist/time-axis.js.map +1 -1
- package/dist/time-picker.js.map +1 -1
- package/dist/timeline.js.map +1 -1
- package/dist/toggle-group.js.map +1 -1
- package/dist/toggle.js.map +1 -1
- package/dist/tool-call.js +5 -6
- package/dist/tool-call.js.map +1 -1
- package/dist/toolbar.js.map +1 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/tree-map.js.map +1 -1
- package/dist/tree.js.map +1 -1
- package/dist/venn.js.map +1 -1
- package/package.json +8 -3
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as HoverCardPrimitive from '@radix-ui/react-hover-card';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var SAFE_URL_SCHEMES = ["http:", "https:", "mailto:"];
|
|
11
|
+
function safeUrl(raw) {
|
|
12
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
13
|
+
let parsed;
|
|
14
|
+
try {
|
|
15
|
+
parsed = new URL(raw);
|
|
16
|
+
} catch {
|
|
17
|
+
return raw.includes(":") ? void 0 : raw;
|
|
18
|
+
}
|
|
19
|
+
return SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : void 0;
|
|
20
|
+
}
|
|
21
|
+
function InlineCitation({
|
|
22
|
+
index,
|
|
23
|
+
title,
|
|
24
|
+
url: rawUrl,
|
|
25
|
+
excerpt,
|
|
26
|
+
openDelay = 200,
|
|
27
|
+
className
|
|
28
|
+
}) {
|
|
29
|
+
const url = safeUrl(rawUrl);
|
|
30
|
+
const triggerClasses = cn(
|
|
31
|
+
"inline-flex select-none items-center justify-center rounded-sm bg-primary/10 px-1 py-0.5 text-[0.7em] font-mono font-semibold text-primary leading-none",
|
|
32
|
+
"transition-all duration-[var(--duration-normal,200ms)] ease-out",
|
|
33
|
+
"hover:bg-primary/15",
|
|
34
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
|
|
35
|
+
className
|
|
36
|
+
);
|
|
37
|
+
const trigger = url ? /* @__PURE__ */ jsxs(
|
|
38
|
+
"a",
|
|
39
|
+
{
|
|
40
|
+
href: url,
|
|
41
|
+
target: "_blank",
|
|
42
|
+
rel: "noreferrer noopener external",
|
|
43
|
+
className: triggerClasses,
|
|
44
|
+
"aria-label": `Source ${index}: ${title}`,
|
|
45
|
+
children: [
|
|
46
|
+
"[",
|
|
47
|
+
index,
|
|
48
|
+
"]"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
) : (
|
|
52
|
+
// No URL → still focusable so keyboard users can open the popover.
|
|
53
|
+
// Real <button type="button"> over a styled span so the trigger
|
|
54
|
+
// honors space/enter activation natively.
|
|
55
|
+
/* @__PURE__ */ jsxs(
|
|
56
|
+
"button",
|
|
57
|
+
{
|
|
58
|
+
type: "button",
|
|
59
|
+
className: triggerClasses,
|
|
60
|
+
"aria-label": `Source ${index}: ${title}`,
|
|
61
|
+
children: [
|
|
62
|
+
"[",
|
|
63
|
+
index,
|
|
64
|
+
"]"
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
return /* @__PURE__ */ jsxs(HoverCardPrimitive.Root, { openDelay, children: [
|
|
70
|
+
/* @__PURE__ */ jsx(HoverCardPrimitive.Trigger, { asChild: true, children: /* @__PURE__ */ jsx("sup", { className: "inline-block leading-none", children: trigger }) }),
|
|
71
|
+
/* @__PURE__ */ jsx(HoverCardPrimitive.Portal, { children: /* @__PURE__ */ jsx(
|
|
72
|
+
HoverCardPrimitive.Content,
|
|
73
|
+
{
|
|
74
|
+
side: "top",
|
|
75
|
+
align: "center",
|
|
76
|
+
sideOffset: 4,
|
|
77
|
+
className: cn(
|
|
78
|
+
"z-50 max-w-xs rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md",
|
|
79
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
80
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
81
|
+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
|
82
|
+
),
|
|
83
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
84
|
+
/* @__PURE__ */ jsxs("span", { className: "font-mono text-[10px] text-muted-foreground", children: [
|
|
85
|
+
"[",
|
|
86
|
+
index,
|
|
87
|
+
"]"
|
|
88
|
+
] }),
|
|
89
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium leading-snug text-foreground", children: title }),
|
|
90
|
+
excerpt ? /* @__PURE__ */ jsx("span", { className: "text-xs leading-relaxed text-muted-foreground", children: excerpt }) : null,
|
|
91
|
+
url ? /* @__PURE__ */ jsx("span", { className: "truncate text-xs text-primary underline-offset-2 hover:underline", children: inferDisplayUrl(url) }) : null
|
|
92
|
+
] })
|
|
93
|
+
}
|
|
94
|
+
) })
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
function inferDisplayUrl(href) {
|
|
98
|
+
try {
|
|
99
|
+
const url = new URL(href);
|
|
100
|
+
return url.hostname.replace(/^www\./, "") + url.pathname;
|
|
101
|
+
} catch {
|
|
102
|
+
return href;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { InlineCitation };
|
|
107
|
+
//# sourceMappingURL=inline-citation.js.map
|
|
108
|
+
//# sourceMappingURL=inline-citation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/ai/inline-citation/inline-citation.tsx"],"names":[],"mappings":";;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;AAEA,IAAM,gBAAA,GAAmB,CAAC,OAAA,EAAS,QAAA,EAAU,SAAS,CAAA;AAkB/C,SAAS,QAAQ,GAAA,EAA6C;AACpE,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,KAAQ,EAAA,EAAI,OAAO,MAAA;AAI5C,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACH,IAAA,MAAA,GAAS,IAAI,IAAI,GAAG,CAAA;AAAA,EACrB,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,GAAI,MAAA,GAAY,GAAA;AAAA,EACxC;AACA,EAAA,OAAO,gBAAA,CAAiB,KAAK,CAAC,MAAA,KAAW,WAAW,MAAA,CAAO,QAAQ,IAAI,GAAA,GAAM,MAAA;AAC9E;ACDA,SAAS,cAAA,CAAe;AAAA,EACvB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAA,EAAK,MAAA;AAAA,EACL,OAAA;AAAA,EACA,SAAA,GAAY,GAAA;AAAA,EACZ;AACD,CAAA,EAAwB;AAIvB,EAAA,MAAM,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC1B,EAAA,MAAM,cAAA,GAAiB,EAAA;AAAA,IACtB,yJAAA;AAAA,IACA,iEAAA;AAAA,IACA,qBAAA;AAAA,IACA,qGAAA;AAAA,IACA;AAAA,GACD;AAEA,EAAA,MAAM,UAAU,GAAA,mBACf,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACA,IAAA,EAAM,GAAA;AAAA,MACN,MAAA,EAAO,QAAA;AAAA,MACP,GAAA,EAAI,8BAAA;AAAA,MACJ,SAAA,EAAW,cAAA;AAAA,MACX,YAAA,EAAY,CAAA,OAAA,EAAU,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA;AAAA,MACrC,QAAA,EAAA;AAAA,QAAA,GAAA;AAAA,QACE,KAAA;AAAA,QAAM;AAAA;AAAA;AAAA,GACT;AAAA;AAAA;AAAA;AAAA,oBAKA,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW,cAAA;AAAA,QACX,YAAA,EAAY,CAAA,OAAA,EAAU,KAAK,CAAA,EAAA,EAAK,KAAK,CAAA,CAAA;AAAA,QACrC,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,UACE,KAAA;AAAA,UAAM;AAAA;AAAA;AAAA;AACT,GAAA;AAGD,EAAA,uBACC,IAAA,CAAoB,kBAAA,CAAA,IAAA,EAAnB,EAAwB,SAAA,EACxB,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAoB,kBAAA,CAAA,OAAA,EAAnB,EAA2B,OAAA,EAAO,IAAA,EAClC,8BAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EAA6B,QAAA,EAAA,OAAA,EAAQ,CAAA,EACrD,CAAA;AAAA,oBACA,GAAA,CAAoB,2BAAnB,EACA,QAAA,kBAAA,GAAA;AAAA,MAAoB,kBAAA,CAAA,OAAA;AAAA,MAAnB;AAAA,QACA,IAAA,EAAK,KAAA;AAAA,QACL,KAAA,EAAM,QAAA;AAAA,QACN,UAAA,EAAY,CAAA;AAAA,QACZ,SAAA,EAAW,EAAA;AAAA,UACV,gGAAA;AAAA,UACA,8DAAA;AAAA,UACA,4DAAA;AAAA,UACA;AAAA,SACD;AAAA,QAEA,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACd,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,MAAA,EAAA,EAAK,WAAU,6CAAA,EAA8C,QAAA,EAAA;AAAA,YAAA,GAAA;AAAA,YAAE,KAAA;AAAA,YAAM;AAAA,WAAA,EAAC,CAAA;AAAA,0BACvE,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kDAAA,EAAoD,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,UACzE,0BACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+CAAA,EAAiD,mBAAQ,CAAA,GACtE,IAAA;AAAA,UACH,GAAA,uBACC,MAAA,EAAA,EAAK,SAAA,EAAU,oEACd,QAAA,EAAA,eAAA,CAAgB,GAAG,GACrB,CAAA,GACG;AAAA,SAAA,EACL;AAAA;AAAA,KACD,EACD;AAAA,GAAA,EACD,CAAA;AAEF;AAEA,SAAS,gBAAgB,IAAA,EAAsB;AAC9C,EAAA,IAAI;AACH,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,IAAI,CAAA;AACxB,IAAA,OAAO,IAAI,QAAA,CAAS,OAAA,CAAQ,QAAA,EAAU,EAAE,IAAI,GAAA,CAAI,QAAA;AAAA,EACjD,CAAA,CAAA,MAAQ;AACP,IAAA,OAAO,IAAA;AAAA,EACR;AACD","file":"inline-citation.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as HoverCardPrimitive from \"@radix-ui/react-hover-card\";\nimport * as React from \"react\";\nimport { cn, safeUrl } from \"../../lib/utils.js\";\n\n/**\n * Inline footnote-style reference with a hover-preview popover.\n *\n * Pairs with `<Sources>` for the bottom-of-card list. Block-level\n * `<Citation>` chips are too large to embed mid-sentence; this primitive\n * fills the inline-text gap with a `<sup>[N]</sup>` and an\n * Anthropic-style hover preview showing the source title + URL.\n *\n * The Markdown component routes `[N](url)` shapes through this slot —\n * authors don't write the JSX directly in the streaming path.\n *\n * @example\n * The frontier models all publish reasoning evals\n * <InlineCitation index={1} title=\"Anthropic — Claude Sonnet 4.5\"\n * url=\"https://anthropic.com/claude\" />.\n */\nexport interface InlineCitationProps {\n\t/** Footnote number (1-based). Renders inside the visible `<sup>`. */\n\tindex: number;\n\t/** Source title shown in the hover preview. */\n\ttitle: string;\n\t/** Optional URL — when set, the trigger becomes a focusable anchor. */\n\turl?: string;\n\t/** Optional excerpt or context shown under the title in the preview. */\n\texcerpt?: string;\n\t/** Open delay in ms (matches Radix default ~700). */\n\topenDelay?: number;\n\tclassName?: string;\n}\n\n/**\n * Render an inline citation reference with hover preview.\n * @param props - Index, title, optional url + excerpt.\n * @returns A `<sup>` with a Radix HoverCard popover.\n */\nfunction InlineCitation({\n\tindex,\n\ttitle,\n\turl: rawUrl,\n\texcerpt,\n\topenDelay = 200,\n\tclassName,\n}: InlineCitationProps) {\n\t// Gate the URL against `javascript:` / `data:` / `vbscript:` schemes\n\t// before it reaches an `<a href>`. Markdown-path callers already pass\n\t// rehype-sanitized hrefs, but direct-JSX consumers can hand us anything.\n\tconst url = safeUrl(rawUrl);\n\tconst triggerClasses = cn(\n\t\t\"inline-flex select-none items-center justify-center rounded-sm bg-primary/10 px-1 py-0.5 text-[0.7em] font-mono font-semibold text-primary leading-none\",\n\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\"hover:bg-primary/15\",\n\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1\",\n\t\tclassName,\n\t);\n\n\tconst trigger = url ? (\n\t\t<a\n\t\t\thref={url}\n\t\t\ttarget=\"_blank\"\n\t\t\trel=\"noreferrer noopener external\"\n\t\t\tclassName={triggerClasses}\n\t\t\taria-label={`Source ${index}: ${title}`}\n\t\t>\n\t\t\t[{index}]\n\t\t</a>\n\t) : (\n\t\t// No URL → still focusable so keyboard users can open the popover.\n\t\t// Real <button type=\"button\"> over a styled span so the trigger\n\t\t// honors space/enter activation natively.\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclassName={triggerClasses}\n\t\t\taria-label={`Source ${index}: ${title}`}\n\t\t>\n\t\t\t[{index}]\n\t\t</button>\n\t);\n\n\treturn (\n\t\t<HoverCardPrimitive.Root openDelay={openDelay}>\n\t\t\t<HoverCardPrimitive.Trigger asChild>\n\t\t\t\t<sup className=\"inline-block leading-none\">{trigger}</sup>\n\t\t\t</HoverCardPrimitive.Trigger>\n\t\t\t<HoverCardPrimitive.Portal>\n\t\t\t\t<HoverCardPrimitive.Content\n\t\t\t\t\tside=\"top\"\n\t\t\t\t\talign=\"center\"\n\t\t\t\t\tsideOffset={4}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\"z-50 max-w-xs rounded-md border border-border bg-popover p-3 text-popover-foreground shadow-md\",\n\t\t\t\t\t\t\"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n\t\t\t\t\t\t\"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n\t\t\t\t\t\t\"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<div className=\"flex flex-col gap-1\">\n\t\t\t\t\t\t<span className=\"font-mono text-[10px] text-muted-foreground\">[{index}]</span>\n\t\t\t\t\t\t<span className=\"text-sm font-medium leading-snug text-foreground\">{title}</span>\n\t\t\t\t\t\t{excerpt ? (\n\t\t\t\t\t\t\t<span className=\"text-xs leading-relaxed text-muted-foreground\">{excerpt}</span>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t{url ? (\n\t\t\t\t\t\t\t<span className=\"truncate text-xs text-primary underline-offset-2 hover:underline\">\n\t\t\t\t\t\t\t\t{inferDisplayUrl(url)}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t</HoverCardPrimitive.Content>\n\t\t\t</HoverCardPrimitive.Portal>\n\t\t</HoverCardPrimitive.Root>\n\t);\n}\n\nfunction inferDisplayUrl(href: string): string {\n\ttry {\n\t\tconst url = new URL(href);\n\t\treturn url.hostname.replace(/^www\\./, \"\") + url.pathname;\n\t} catch {\n\t\treturn href;\n\t}\n}\n\nexport { InlineCitation };\n"]}
|
package/dist/input-otp.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/components/input-otp/input-otp.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACAA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,SAAA,EAAW,oBAAoB,GAAG,KAAA,IAAS,GAAA,qBAC9C,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,kBAAA,EAAoB,EAAA;AAAA,QACnB,yEAAA;AAAA,QACA;AAAA,OACD;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,6BAAA,EAA+B,SAAS,CAAA;AAAA,MACrD,GAAG;AAAA;AAAA;AAEL;AACD,QAAA,CAAS,WAAA,GAAc,UAAA;AAGvB,IAAM,gBAAsB,KAAA,CAAA,UAAA,CAG1B,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,EAAG,GAAA,yBAC1B,KAAA,EAAA,EAAI,GAAA,EAAU,WAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA,EAAI,GAAG,OAAO,CACzE;AACD,aAAA,CAAc,WAAA,GAAc,eAAA;AAQ5B,IAAM,YAAA,GAAqB,KAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,KAAA,EAAO,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACxC,IAAA,MAAM,eAAA,GAAwB,iBAAW,eAAe,CAAA;AACxD,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,KAAA,CAAM,KAAK,CAAA;AACxC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,IAAA;AAC3B,IAAA,MAAM,YAAA,GAAe,MAAM,YAAA,IAAgB,KAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,KAAA;AAEnC,IAAA,uBACC,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACV,0NAAA;AAAA,UACA,2CAAA;AAAA,UACA,qDAAA;AAAA,UACA,QAAA,IAAY,4DAAA;AAAA,UACZ;AAAA,SACD;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,IAAA;AAAA,UACA,YAAA,wBACC,KAAA,EAAA,EAAI,SAAA,EAAU,yEACd,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAqD,CAAA,EACrE;AAAA;AAAA;AAAA,KAEF;AAAA,EAEF;AACD;AACA,YAAA,CAAa,WAAA,GAAc,cAAA;AAG3B,IAAM,iBAAA,GAA0B,KAAA,CAAA,UAAA,CAG9B,CAAC,EAAE,GAAG,KAAA,EAAM,EAAG,GAAA,qBAChB,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAU,IAAA,EAAK,WAAA,EAAa,GAAG,KAAA,EACnC,QAAA,kBAAA,GAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACA,KAAA,EAAM,4BAAA;AAAA,IACN,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,cAAA;AAAA,IACL,SAAA,EAAU,+BAAA;AAAA,IACV,aAAA,EAAY,MAAA;AAAA,IAEZ,8BAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI;AAAA;AAC/B,CAAA,EACD,CACA;AACD,iBAAA,CAAkB,WAAA,GAAc,mBAAA","file":"input-otp.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Props for the root InputOTP component (mirrors input-otp's OTPInput). */\ntype InputOTPProps = React.ComponentPropsWithoutRef<typeof OTPInput>;\n\n/** Root OTP input. Wraps input-otp's OTPInput and exposes slot context to children. */\nconst InputOTP = React.forwardRef<React.ComponentRef<typeof OTPInput>, InputOTPProps>(\n\t({ className, containerClassName, ...props }, ref) => (\n\t<OTPInput\n\t\tref={ref}\n\t\tcontainerClassName={cn(\n\t\t\t\"flex items-center gap-[var(--gap-sm,0.5rem)] has-[:disabled]:opacity-50\",\n\t\t\tcontainerClassName,\n\t\t)}\n\t\tclassName={cn(\"disabled:cursor-not-allowed\", className)}\n\t\t{...props}\n\t/>\n));\nInputOTP.displayName = \"InputOTP\";\n\n/** Groups slots together; place between runs of slots to add visual dividers. */\nconst InputOTPGroup = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ className, ...props }, ref) => (\n\t<div ref={ref} className={cn(\"flex items-center\", className)} {...props} />\n));\nInputOTPGroup.displayName = \"InputOTPGroup\";\n\ninterface InputOTPSlotProps extends React.ComponentPropsWithoutRef<\"div\"> {\n\t/** Index of the slot in the underlying OTP value. */\n\tindex: number;\n}\n\n/** A single character slot. Reads its state from OTPInputContext. */\nconst InputOTPSlot = React.forwardRef<HTMLDivElement, InputOTPSlotProps>(\n\t({ index, className, ...props }, ref) => {\n\t\tconst inputOTPContext = React.useContext(OTPInputContext);\n\t\tconst slot = inputOTPContext.slots[index];\n\t\tconst char = slot?.char ?? null;\n\t\tconst hasFakeCaret = slot?.hasFakeCaret ?? false;\n\t\tconst isActive = slot?.isActive ?? false;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] items-center justify-center border-y border-r border-input text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"first:rounded-l-md first:border-l last:rounded-r-md\",\n\t\t\t\t\tisActive && \"z-10 ring-2 ring-ring ring-offset-2 ring-offset-background\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{char}\n\t\t\t\t{hasFakeCaret && (\n\t\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"h-4 w-px animate-pulse bg-foreground duration-1000\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nInputOTPSlot.displayName = \"InputOTPSlot\";\n\n/** Visual separator between slot groups (a bullet by default). */\nconst InputOTPSeparator = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ ...props }, ref) => (\n\t<div ref={ref} role=\"separator\" {...props}>\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"currentColor\"\n\t\t\tclassName=\"h-2 w-2 text-muted-foreground\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"6\" />\n\t\t</svg>\n\t</div>\n));\nInputOTPSeparator.displayName = \"InputOTPSeparator\";\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\nexport type { InputOTPProps };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/components/input-otp/input-otp.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACAA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACtB,CAAC,EAAE,SAAA,EAAW,oBAAoB,GAAG,KAAA,IAAS,GAAA,qBAC9C,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,kBAAA,EAAoB,EAAA;AAAA,QACnB,yEAAA;AAAA,QACA;AAAA,OACD;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,6BAAA,EAA+B,SAAS,CAAA;AAAA,MACrD,GAAG;AAAA;AAAA;AAEL;AACD,QAAA,CAAS,WAAA,GAAc,UAAA;AAGvB,IAAM,gBAAsB,KAAA,CAAA,UAAA,CAG1B,CAAC,EAAE,SAAA,EAAW,GAAG,OAAM,EAAG,GAAA,yBAC1B,KAAA,EAAA,EAAI,GAAA,EAAU,WAAW,EAAA,CAAG,mBAAA,EAAqB,SAAS,CAAA,EAAI,GAAG,OAAO,CACzE;AACD,aAAA,CAAc,WAAA,GAAc,eAAA;AAQ5B,IAAM,YAAA,GAAqB,KAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,KAAA,EAAO,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACxC,IAAA,MAAM,eAAA,GAAwB,iBAAW,eAAe,CAAA;AACxD,IAAA,MAAM,IAAA,GAAO,eAAA,CAAgB,KAAA,CAAM,KAAK,CAAA;AACxC,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,IAAQ,IAAA;AAC3B,IAAA,MAAM,YAAA,GAAe,MAAM,YAAA,IAAgB,KAAA;AAC3C,IAAA,MAAM,QAAA,GAAW,MAAM,QAAA,IAAY,KAAA;AAEnC,IAAA,uBACC,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACV,0NAAA;AAAA,UACA,2CAAA;AAAA,UACA,qDAAA;AAAA,UACA,QAAA,IAAY,4DAAA;AAAA,UACZ;AAAA,SACD;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,IAAA;AAAA,UACA,YAAA,wBACC,KAAA,EAAA,EAAI,SAAA,EAAU,yEACd,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EAAqD,CAAA,EACrE;AAAA;AAAA;AAAA,KAEF;AAAA,EAEF;AACD;AACA,YAAA,CAAa,WAAA,GAAc,cAAA;AAG3B,IAAM,iBAAA,GAA0B,KAAA,CAAA,UAAA,CAG9B,CAAC,EAAE,GAAG,KAAA,EAAM,EAAG,GAAA,qBAChB,GAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAU,IAAA,EAAK,WAAA,EAAa,GAAG,KAAA,EACnC,QAAA,kBAAA,GAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACA,KAAA,EAAM,4BAAA;AAAA,IACN,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,cAAA;AAAA,IACL,SAAA,EAAU,+BAAA;AAAA,IACV,aAAA,EAAY,MAAA;AAAA,IAEZ,8BAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI;AAAA;AAC/B,CAAA,EACD,CACA;AACD,iBAAA,CAAkB,WAAA,GAAc,mBAAA","file":"input-otp.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport { OTPInput, OTPInputContext } from \"input-otp\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/** Props for the root InputOTP component (mirrors input-otp's OTPInput). */\ntype InputOTPProps = React.ComponentPropsWithoutRef<typeof OTPInput>;\n\n/** Root OTP input. Wraps input-otp's OTPInput and exposes slot context to children. */\nconst InputOTP = React.forwardRef<React.ComponentRef<typeof OTPInput>, InputOTPProps>(\n\t({ className, containerClassName, ...props }, ref) => (\n\t<OTPInput\n\t\tref={ref}\n\t\tcontainerClassName={cn(\n\t\t\t\"flex items-center gap-[var(--gap-sm,0.5rem)] has-[:disabled]:opacity-50\",\n\t\t\tcontainerClassName,\n\t\t)}\n\t\tclassName={cn(\"disabled:cursor-not-allowed\", className)}\n\t\t{...props}\n\t/>\n));\nInputOTP.displayName = \"InputOTP\";\n\n/** Groups slots together; place between runs of slots to add visual dividers. */\nconst InputOTPGroup = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ className, ...props }, ref) => (\n\t<div ref={ref} className={cn(\"flex items-center\", className)} {...props} />\n));\nInputOTPGroup.displayName = \"InputOTPGroup\";\n\ninterface InputOTPSlotProps extends React.ComponentPropsWithoutRef<\"div\"> {\n\t/** Index of the slot in the underlying OTP value. */\n\tindex: number;\n}\n\n/** A single character slot. Reads its state from OTPInputContext. */\nconst InputOTPSlot = React.forwardRef<HTMLDivElement, InputOTPSlotProps>(\n\t({ index, className, ...props }, ref) => {\n\t\tconst inputOTPContext = React.useContext(OTPInputContext);\n\t\tconst slot = inputOTPContext.slots[index];\n\t\tconst char = slot?.char ?? null;\n\t\tconst hasFakeCaret = slot?.hasFakeCaret ?? false;\n\t\tconst isActive = slot?.isActive ?? false;\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex h-[var(--control-height-md,2.5rem)] w-[var(--control-height-md,2.5rem)] items-center justify-center border-y border-r border-input text-sm transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t\"inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"first:rounded-l-md first:border-l last:rounded-r-md\",\n\t\t\t\t\tisActive && \"z-10 ring-2 ring-ring ring-offset-2 ring-offset-background\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{char}\n\t\t\t\t{hasFakeCaret && (\n\t\t\t\t\t<div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n\t\t\t\t\t\t<div className=\"h-4 w-px animate-pulse bg-foreground duration-1000\" />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t);\n\t},\n);\nInputOTPSlot.displayName = \"InputOTPSlot\";\n\n/** Visual separator between slot groups (a bullet by default). */\nconst InputOTPSeparator = React.forwardRef<\n\tReact.ComponentRef<\"div\">,\n\tReact.ComponentPropsWithoutRef<\"div\">\n>(({ ...props }, ref) => (\n\t<div ref={ref} role=\"separator\" {...props}>\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"currentColor\"\n\t\t\tclassName=\"h-2 w-2 text-muted-foreground\"\n\t\t\taria-hidden=\"true\"\n\t\t>\n\t\t\t<circle cx=\"12\" cy=\"12\" r=\"6\" />\n\t\t</svg>\n\t</div>\n));\nInputOTPSeparator.displayName = \"InputOTPSeparator\";\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\nexport type { InputOTPProps };\n"]}
|
package/dist/input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/input/input.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACLA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACvC,IAAA,uBACC,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACV,6JAAA;AAAA,UACA,iEAAA;AAAA;AAAA;AAAA,UAGA,qDAAA;AAAA,UACA,sFAAA;AAAA,UACA,mCAAA;AAAA,UACA,qGAAA;AAAA,UACA,sDAAA;AAAA,UACA,sCAAA;AAAA,UACA,iDAAA;AAAA,UACA;AAAA,SACD;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACL;AAAA,EAEF;AACD;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"input.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n\t({ className, type, ...props }, ref) => {\n\t\treturn (\n\t\t\t<input\n\t\t\t\ttype={type}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex h-[var(--control-height-md,2.5rem)] w-full rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm\",\n\t\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t// inset-ring gives a self-borne edge so the input field is visible on flat\n\t\t\t\t\t// surfaces (token border alone is too low-contrast on bg-background=white).\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground\",\n\t\t\t\t\t\"placeholder:text-muted-foreground\",\n\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\"focus-visible:shadow-md focus-visible:border-ring/50\",\n\t\t\t\t\t\"hover:border-ring/30 hover:shadow-md\",\n\t\t\t\t\t\"disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/input/input.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACLA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,MAAM,GAAG,KAAA,IAAS,GAAA,KAAQ;AACvC,IAAA,uBACC,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACA,IAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACV,6JAAA;AAAA,UACA,iEAAA;AAAA;AAAA;AAAA,UAGA,qDAAA;AAAA,UACA,sFAAA;AAAA,UACA,mCAAA;AAAA,UACA,qGAAA;AAAA,UACA,sDAAA;AAAA,UACA,sCAAA;AAAA,UACA,iDAAA;AAAA,UACA;AAAA,SACD;AAAA,QACA,GAAA;AAAA,QACC,GAAG;AAAA;AAAA,KACL;AAAA,EAEF;AACD;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"input.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nexport type InputProps = React.InputHTMLAttributes<HTMLInputElement>;\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n\t({ className, type, ...props }, ref) => {\n\t\treturn (\n\t\t\t<input\n\t\t\t\ttype={type}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"flex h-[var(--control-height-md,2.5rem)] w-full rounded-md border border-input bg-background px-[var(--space-3,0.75rem)] py-[var(--space-2,0.5rem)] text-sm\",\n\t\t\t\t\t\"transition-all duration-[var(--duration-normal,200ms)] ease-out\",\n\t\t\t\t\t// inset-ring gives a self-borne edge so the input field is visible on flat\n\t\t\t\t\t// surfaces (token border alone is too low-contrast on bg-background=white).\n\t\t\t\t\t\"shadow-sm inset-ring-1 inset-ring-foreground/[0.06]\",\n\t\t\t\t\t\"file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground\",\n\t\t\t\t\t\"placeholder:text-muted-foreground\",\n\t\t\t\t\t\"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n\t\t\t\t\t\"focus-visible:shadow-md focus-visible:border-ring/50\",\n\t\t\t\t\t\"hover:border-ring/30 hover:shadow-md\",\n\t\t\t\t\t\"disabled:cursor-not-allowed disabled:opacity-50\",\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\tref={ref}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t);\n\t},\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n"]}
|
package/dist/label.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/label/label.tsx"],"names":[],"mappings":";;;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACrB;AACD,CAAA;AAMA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,wBACzB,GAAA,CAAgB,cAAA,CAAA,IAAA,EAAf,EAAoB,GAAA,EAAU,WAAW,EAAA,CAAG,aAAA,IAAiB,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO;AAEvF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"label.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst labelVariants = cva(\n\t\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nexport interface LabelProps\n\textends React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>,\n\t\tVariantProps<typeof labelVariants> {}\n\nconst Label = React.forwardRef<React.ComponentRef<typeof LabelPrimitive.Root>, LabelProps>(\n\t({ className, ...props }, ref) => (\n\t\t<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n\t),\n);\nLabel.displayName = \"Label\";\n\nexport { Label };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/label/label.tsx"],"names":[],"mappings":";;;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACHA,IAAM,aAAA,GAAgB,GAAA;AAAA,EACrB;AACD,CAAA;AAMA,IAAM,KAAA,GAAc,KAAA,CAAA,UAAA;AAAA,EACnB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,EAAM,EAAG,wBACzB,GAAA,CAAgB,cAAA,CAAA,IAAA,EAAf,EAAoB,GAAA,EAAU,WAAW,EAAA,CAAG,aAAA,IAAiB,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO;AAEvF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"label.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","\"use client\";\n\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\nimport { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst labelVariants = cva(\n\t\"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n);\n\nexport interface LabelProps\n\textends React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>,\n\t\tVariantProps<typeof labelVariants> {}\n\nconst Label = React.forwardRef<React.ComponentRef<typeof LabelPrimitive.Root>, LabelProps>(\n\t({ className, ...props }, ref) => (\n\t\t<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />\n\t),\n);\nLabel.displayName = \"Label\";\n\nexport { Label };\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/ai/loading-indicator/loading-indicator.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACNA,IAAM,wBAAA,GAA2B,IAAI,sDAAA,EAAwD;AAAA,EAC5F,QAAA,EAAU;AAAA,IACT,IAAA,EAAM;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,EAAA,EAAI;AAAA;AACL,GACD;AAAA,EACA,eAAA,EAAiB,EAAE,IAAA,EAAM,IAAA;AAC1B,CAAC;AAwBD,SAAS,gBAAA,CAAiB;AAAA,EACzB,OAAA,GAAU,MAAA;AAAA,EACV,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACJ,CAAA,EAA0B;AACzB,EAAA,MAAM,YAAY,KAAA,IAAS,SAAA;AAC3B,EAAA,uBACC,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,WAAW,EAAA,CAAG,wBAAA,CAAyB,EAAE,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MAC1D,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,OAAA,KAAY,MAAA,mBAAS,GAAA,CAAC,IAAA,EAAA,EAAK,CAAA,GAAK,IAAA;AAAA,QAChC,OAAA,KAAY,OAAA,mBAAU,GAAA,CAAC,KAAA,EAAA,EAAM,CAAA,GAAK,IAAA;AAAA,QAClC,OAAA,KAAY,KAAA,mBAAQ,GAAA,CAAC,GAAA,EAAA,EAAI,CAAA,GAAK,IAAA;AAAA,QAC9B,wBACA,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAQ,iBAAM,CAAA,GAC7B,IAAA;AAAA,wBACJ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA,GACtC;AAEF;AAEA,SAAS,IAAA,GAAO;AACf,EAAA,uBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EACf,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,4EAAA,EAA6E,CAAA;AAAA,oBAC7F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6EAAA,EAA8E,CAAA;AAAA,oBAC9F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EAAqD;AAAA,GAAA,EACtE,CAAA;AAEF;AAEA,SAAS,KAAA,GAAQ;AAChB,EAAA,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+CAAA,EAAgD,CAAA;AACxE;AAEA,SAAS,GAAA,GAAM;AACd,EAAA,uBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACf,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,yEAAA,EAA0E,CAAA;AAAA,oBAC1F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yEAAA,EAA0E,CAAA;AAAA,oBAC1F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD;AAAA,GAAA,EACnE,CAAA;AAEF","file":"loading-indicator.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst loadingIndicatorVariants = cva(\"inline-flex items-center gap-2 text-muted-foreground\", {\n\tvariants: {\n\t\tsize: {\n\t\t\tsm: \"text-xs\",\n\t\t\tmd: \"text-sm\",\n\t\t},\n\t},\n\tdefaultVariants: { size: \"md\" },\n});\n\n/**\n * Streaming/typing feedback for an in-flight LLM turn. Three motion variants\n * — `dots` (bouncing trio), `pulse` (single throbbing circle), `bar`\n * (horizontal sweep). Pure CSS, no JS — RSC-safe.\n *\n * @example\n * {isLoading && <LoadingIndicator label=\"Thinking…\" />}\n */\nexport interface LoadingIndicatorProps\n\textends React.HTMLAttributes<HTMLDivElement>,\n\t\tVariantProps<typeof loadingIndicatorVariants> {\n\t/** Animation style. Default `dots`. */\n\tvariant?: \"dots\" | \"pulse\" | \"bar\";\n\t/** Optional adjacent label, e.g. \"Thinking…\" or \"Searching docs…\". */\n\tlabel?: string;\n}\n\n/**\n * Renders an animated loading indicator with optional label.\n * @param props - variant + label\n * @returns A status div with role=\"status\"\n */\nfunction LoadingIndicator({\n\tvariant = \"dots\",\n\tsize,\n\tlabel,\n\tclassName,\n\t...props\n}: LoadingIndicatorProps) {\n\tconst ariaLabel = label ?? \"Loading\";\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\tclassName={cn(loadingIndicatorVariants({ size }), className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{variant === \"dots\" ? <Dots /> : null}\n\t\t\t{variant === \"pulse\" ? <Pulse /> : null}\n\t\t\t{variant === \"bar\" ? <Bar /> : null}\n\t\t\t{label ? (\n\t\t\t\t<span aria-hidden=\"true\">{label}</span>\n\t\t\t) : null}\n\t\t\t<span className=\"sr-only\">{ariaLabel}</span>\n\t\t</div>\n\t);\n}\n\nfunction Dots() {\n\treturn (\n\t\t<span className=\"flex items-center gap-1\">\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.3s]\" />\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.15s]\" />\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current\" />\n\t\t</span>\n\t);\n}\n\nfunction Pulse() {\n\treturn <span className=\"h-2 w-2 animate-pulse rounded-full bg-current\" />;\n}\n\nfunction Bar() {\n\treturn (\n\t\t<span className=\"inline-flex items-center gap-1\">\n\t\t\t<span className=\"h-0.5 w-2 animate-pulse rounded-full bg-current [animation-delay:-0.4s]\" />\n\t\t\t<span className=\"h-0.5 w-3 animate-pulse rounded-full bg-current [animation-delay:-0.2s]\" />\n\t\t\t<span className=\"h-0.5 w-4 animate-pulse rounded-full bg-current\" />\n\t\t</span>\n\t);\n}\n\nexport { LoadingIndicator, loadingIndicatorVariants };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/ai/loading-indicator/loading-indicator.tsx"],"names":[],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACNA,IAAM,wBAAA,GAA2B,IAAI,sDAAA,EAAwD;AAAA,EAC5F,QAAA,EAAU;AAAA,IACT,IAAA,EAAM;AAAA,MACL,EAAA,EAAI,SAAA;AAAA,MACJ,EAAA,EAAI;AAAA;AACL,GACD;AAAA,EACA,eAAA,EAAiB,EAAE,IAAA,EAAM,IAAA;AAC1B,CAAC;AAwBD,SAAS,gBAAA,CAAiB;AAAA,EACzB,OAAA,GAAU,MAAA;AAAA,EACV,IAAA;AAAA,EACA,KAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACJ,CAAA,EAA0B;AACzB,EAAA,MAAM,YAAY,KAAA,IAAS,SAAA;AAC3B,EAAA,uBACC,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,WAAW,EAAA,CAAG,wBAAA,CAAyB,EAAE,IAAA,EAAM,GAAG,SAAS,CAAA;AAAA,MAC1D,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,OAAA,KAAY,MAAA,mBAAS,GAAA,CAAC,IAAA,EAAA,EAAK,CAAA,GAAK,IAAA;AAAA,QAChC,OAAA,KAAY,OAAA,mBAAU,GAAA,CAAC,KAAA,EAAA,EAAM,CAAA,GAAK,IAAA;AAAA,QAClC,OAAA,KAAY,KAAA,mBAAQ,GAAA,CAAC,GAAA,EAAA,EAAI,CAAA,GAAK,IAAA;AAAA,QAC9B,wBACA,GAAA,CAAC,MAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAQ,iBAAM,CAAA,GAC7B,IAAA;AAAA,wBACJ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA,GACtC;AAEF;AAEA,SAAS,IAAA,GAAO;AACf,EAAA,uBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAA,EACf,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,4EAAA,EAA6E,CAAA;AAAA,oBAC7F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6EAAA,EAA8E,CAAA;AAAA,oBAC9F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oDAAA,EAAqD;AAAA,GAAA,EACtE,CAAA;AAEF;AAEA,SAAS,KAAA,GAAQ;AAChB,EAAA,uBAAO,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,+CAAA,EAAgD,CAAA;AACxE;AAEA,SAAS,GAAA,GAAM;AACd,EAAA,uBACC,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,gCAAA,EACf,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,yEAAA,EAA0E,CAAA;AAAA,oBAC1F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yEAAA,EAA0E,CAAA;AAAA,oBAC1F,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,iDAAA,EAAkD;AAAA,GAAA,EACnE,CAAA;AAEF","file":"loading-indicator.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\nconst loadingIndicatorVariants = cva(\"inline-flex items-center gap-2 text-muted-foreground\", {\n\tvariants: {\n\t\tsize: {\n\t\t\tsm: \"text-xs\",\n\t\t\tmd: \"text-sm\",\n\t\t},\n\t},\n\tdefaultVariants: { size: \"md\" },\n});\n\n/**\n * Streaming/typing feedback for an in-flight LLM turn. Three motion variants\n * — `dots` (bouncing trio), `pulse` (single throbbing circle), `bar`\n * (horizontal sweep). Pure CSS, no JS — RSC-safe.\n *\n * @example\n * {isLoading && <LoadingIndicator label=\"Thinking…\" />}\n */\nexport interface LoadingIndicatorProps\n\textends React.HTMLAttributes<HTMLDivElement>,\n\t\tVariantProps<typeof loadingIndicatorVariants> {\n\t/** Animation style. Default `dots`. */\n\tvariant?: \"dots\" | \"pulse\" | \"bar\";\n\t/** Optional adjacent label, e.g. \"Thinking…\" or \"Searching docs…\". */\n\tlabel?: string;\n}\n\n/**\n * Renders an animated loading indicator with optional label.\n * @param props - variant + label\n * @returns A status div with role=\"status\"\n */\nfunction LoadingIndicator({\n\tvariant = \"dots\",\n\tsize,\n\tlabel,\n\tclassName,\n\t...props\n}: LoadingIndicatorProps) {\n\tconst ariaLabel = label ?? \"Loading\";\n\treturn (\n\t\t<div\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\tclassName={cn(loadingIndicatorVariants({ size }), className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{variant === \"dots\" ? <Dots /> : null}\n\t\t\t{variant === \"pulse\" ? <Pulse /> : null}\n\t\t\t{variant === \"bar\" ? <Bar /> : null}\n\t\t\t{label ? (\n\t\t\t\t<span aria-hidden=\"true\">{label}</span>\n\t\t\t) : null}\n\t\t\t<span className=\"sr-only\">{ariaLabel}</span>\n\t\t</div>\n\t);\n}\n\nfunction Dots() {\n\treturn (\n\t\t<span className=\"flex items-center gap-1\">\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.3s]\" />\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current [animation-delay:-0.15s]\" />\n\t\t\t<span className=\"h-1.5 w-1.5 animate-bounce rounded-full bg-current\" />\n\t\t</span>\n\t);\n}\n\nfunction Pulse() {\n\treturn <span className=\"h-2 w-2 animate-pulse rounded-full bg-current\" />;\n}\n\nfunction Bar() {\n\treturn (\n\t\t<span className=\"inline-flex items-center gap-1\">\n\t\t\t<span className=\"h-0.5 w-2 animate-pulse rounded-full bg-current [animation-delay:-0.4s]\" />\n\t\t\t<span className=\"h-0.5 w-3 animate-pulse rounded-full bg-current [animation-delay:-0.2s]\" />\n\t\t\t<span className=\"h-0.5 w-4 animate-pulse rounded-full bg-current\" />\n\t\t</span>\n\t);\n}\n\nexport { LoadingIndicator, loadingIndicatorVariants };\n"]}
|
package/dist/loading.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/skeleton/skeleton.tsx","../src/primitives/loading/loading.tsx"],"names":["jsx"],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACFA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAAyC;AAChF,EAAA,uBACC,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,mEAAA,EAAqE,SAAS,CAAA;AAAA,MAC3F,GAAG;AAAA;AAAA,GACL;AAEF;ACVA,IAAM,eAAA,GAAkB,IAAI,aAAA,EAAe;AAAA,EAC1C,QAAA,EAAU;AAAA,IACT,OAAA,EAAS;AAAA,MACR,IAAA,EAAM,uCAAA;AAAA,MACN,IAAA,EAAM,sGAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACR,GACD;AAAA,EACA,eAAA,EAAiB,EAAE,OAAA,EAAS,MAAA;AAC7B,CAAC;AAsCD,SAAS,OAAA,CAAQ;AAAA,EAChB,SAAA;AAAA,EACA,OAAA,GAAU,MAAA;AAAA,EACV,IAAA,GAAO,CAAA;AAAA,EACP,KAAA,GAAQ,eAAA;AAAA,EACR,GAAA;AAAA,EACA,GAAG;AACJ,CAAA,EAAiB;AAChB,EAAA,uBACC,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,WAAW,EAAA,CAAG,eAAA,CAAgB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,MACpD,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAChC,MAAM,IAAA,CAAK,EAAE,QAAQ,IAAA,EAAK,EAAG,CAAC,CAAA,EAAG,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAKjCA,GAAAA,CAAC,UAAA,EAAA,EAAmB,OAAA,EAAS,OAAA,IAAW,UAAvB,CAA+B;AAAA,SAChD;AAAA;AAAA;AAAA,GACF;AAEF;AAOA,SAAS,UAAA,CAAW,EAAE,OAAA,EAAQ,EAA2C;AACxE,EAAA,IAAI,YAAY,MAAA,EAAQ;AACvB,IAAA,uBACC,IAAA,CAAA,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,sBAChCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBACjCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY;AAAA,KAAA,EACjC,CAAA;AAAA,EAEF;AACA,EAAA,IAAI,YAAY,OAAA,EAAS;AACxB,IAAA,uBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EACd,QAAA,EAAA;AAAA,sBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,iCAAA,EAAkC,CAAA;AAAA,sBACtD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kDAAA,EACd,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,wBAChCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY;AAAA,OAAA,EACjC;AAAA,KAAA,EACD,CAAA;AAAA,EAEF;AAEA,EAAA,uBAAOA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,YAAA,EAAa,CAAA;AACzC","file":"loading.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * A placeholder shimmer element shown while content is loading.\n * Pair with explicit width/height via className.\n * @returns A div with pulsing muted background\n */\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"animate-pulse rounded-md border border-foreground/[0.06] bg-muted\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport { Skeleton };\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\nimport { Skeleton } from \"../skeleton/skeleton.js\";\n\nconst loadingVariants = cva(\"flex w-full\", {\n\tvariants: {\n\t\tvariant: {\n\t\t\tlist: \"flex-col gap-[var(--space-3,0.75rem)]\",\n\t\t\tcard: \"flex-col gap-[var(--space-2,0.5rem)] rounded-md border border-border bg-card p-[var(--space-4,1rem)]\",\n\t\t\tstack: \"flex-col gap-[var(--space-4,1rem)]\",\n\t\t},\n\t},\n\tdefaultVariants: { variant: \"list\" },\n});\n\nexport interface LoadingProps\n\textends Omit<React.HTMLAttributes<HTMLDivElement>, \"role\">,\n\t\tVariantProps<typeof loadingVariants> {\n\t/** Forwarded ref onto the status region. */\n\tref?: React.Ref<HTMLDivElement>;\n\t/**\n\t * Number of placeholder rows to render. Each row may contain multiple\n\t * Skeleton elements depending on `variant` — `list` emits 1 Skeleton\n\t * per row; `card` emits 3 (heading + 2 body lines); `stack` emits 3\n\t * (avatar + 2 text lines). Default 3.\n\t */\n\trows?: number;\n\t/** Optional sr-only label that screen readers announce. Default \"Loading…\". */\n\tlabel?: string;\n}\n\n/**\n * A composed loading-placeholder pattern for lists, cards, and stacks.\n * Renders N {@link Skeleton} rows pre-arranged for the chosen layout —\n * Skeleton is the atom (one shaped pulse), Loading is the molecule\n * (the canonical pattern most surfaces want).\n *\n * Distinct from {@link Empty} (request returned, no items) and\n * {@link ErrorState} (request failed). If you need a single shaped\n * pulse for a specific element (an avatar circle, a heading line),\n * reach for `Skeleton` directly. If the wait has a measurable\n * percent-done, reach for `Progress` instead.\n *\n * @example\n * ```tsx\n * <Loading rows={5} variant=\"list\" />\n * ```\n *\n * @returns A `role=\"status\"` region with `aria-live=\"polite\"` and the\n * announced label (default \"Loading…\") rendered sr-only.\n */\nfunction Loading({\n\tclassName,\n\tvariant = \"list\",\n\trows = 3,\n\tlabel = \"Loading…\",\n\tref,\n\t...props\n}: LoadingProps) {\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\tclassName={cn(loadingVariants({ variant }), className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"sr-only\">{label}</span>\n\t\t\t{Array.from({ length: rows }, (_, i) => (\n\t\t\t\t// `variant` can be `null` per CVA's VariantProps shape — the\n\t\t\t\t// destructured default only catches undefined. The fallback\n\t\t\t\t// here narrows to the LoadingRow's \"list\" | \"card\" | \"stack\"\n\t\t\t\t// signature.\n\t\t\t\t<LoadingRow key={i} variant={variant ?? \"list\"} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n/**\n * One placeholder row inside `Loading`. Layout-specific shape per variant.\n *\n * @param variant - Layout family the row belongs to (`list` / `card` / `stack`).\n */\nfunction LoadingRow({ variant }: { variant: \"list\" | \"card\" | \"stack\" }) {\n\tif (variant === \"card\") {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<Skeleton className=\"h-4 w-3/4\" />\n\t\t\t\t<Skeleton className=\"h-3 w-full\" />\n\t\t\t\t<Skeleton className=\"h-3 w-5/6\" />\n\t\t\t</>\n\t\t);\n\t}\n\tif (variant === \"stack\") {\n\t\treturn (\n\t\t\t<div className=\"flex items-center gap-[var(--space-3,0.75rem)]\">\n\t\t\t\t<Skeleton className=\"h-10 w-10 shrink-0 rounded-full\" />\n\t\t\t\t<div className=\"flex flex-1 flex-col gap-[var(--space-2,0.5rem)]\">\n\t\t\t\t\t<Skeleton className=\"h-4 w-1/3\" />\n\t\t\t\t\t<Skeleton className=\"h-3 w-2/3\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\t// list (default)\n\treturn <Skeleton className=\"h-4 w-full\" />;\n}\n\nexport { Loading, loadingVariants };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/utils.ts","../src/primitives/skeleton/skeleton.tsx","../src/primitives/loading/loading.tsx"],"names":["jsx"],"mappings":";;;;;;AAQO,SAAS,MAAM,MAAA,EAAsB;AAC3C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC5B;ACFA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAAyC;AAChF,EAAA,uBACC,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,SAAA,EAAW,EAAA,CAAG,mEAAA,EAAqE,SAAS,CAAA;AAAA,MAC3F,GAAG;AAAA;AAAA,GACL;AAEF;ACVA,IAAM,eAAA,GAAkB,IAAI,aAAA,EAAe;AAAA,EAC1C,QAAA,EAAU;AAAA,IACT,OAAA,EAAS;AAAA,MACR,IAAA,EAAM,uCAAA;AAAA,MACN,IAAA,EAAM,sGAAA;AAAA,MACN,KAAA,EAAO;AAAA;AACR,GACD;AAAA,EACA,eAAA,EAAiB,EAAE,OAAA,EAAS,MAAA;AAC7B,CAAC;AAsCD,SAAS,OAAA,CAAQ;AAAA,EAChB,SAAA;AAAA,EACA,OAAA,GAAU,MAAA;AAAA,EACV,IAAA,GAAO,CAAA;AAAA,EACP,KAAA,GAAQ,eAAA;AAAA,EACR,GAAA;AAAA,EACA,GAAG;AACJ,CAAA,EAAiB;AAChB,EAAA,uBACC,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACA,GAAA;AAAA,MACA,IAAA,EAAK,QAAA;AAAA,MACL,WAAA,EAAU,QAAA;AAAA,MACV,WAAW,EAAA,CAAG,eAAA,CAAgB,EAAE,OAAA,EAAS,GAAG,SAAS,CAAA;AAAA,MACpD,GAAG,KAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,QAChC,MAAM,IAAA,CAAK,EAAE,QAAQ,IAAA,EAAK,EAAG,CAAC,CAAA,EAAG,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAKjCA,GAAAA,CAAC,UAAA,EAAA,EAAmB,OAAA,EAAS,OAAA,IAAW,UAAvB,CAA+B;AAAA,SAChD;AAAA;AAAA;AAAA,GACF;AAEF;AAOA,SAAS,UAAA,CAAW,EAAE,OAAA,EAAQ,EAA2C;AACxE,EAAA,IAAI,YAAY,MAAA,EAAQ;AACvB,IAAA,uBACC,IAAA,CAAA,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,sBAChCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBACjCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY;AAAA,KAAA,EACjC,CAAA;AAAA,EAEF;AACA,EAAA,IAAI,YAAY,OAAA,EAAS;AACxB,IAAA,uBACC,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gDAAA,EACd,QAAA,EAAA;AAAA,sBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,iCAAA,EAAkC,CAAA;AAAA,sBACtD,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kDAAA,EACd,QAAA,EAAA;AAAA,wBAAAA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,wBAChCA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,WAAA,EAAY;AAAA,OAAA,EACjC;AAAA,KAAA,EACD,CAAA;AAAA,EAEF;AAEA,EAAA,uBAAOA,GAAAA,CAAC,QAAA,EAAA,EAAS,SAAA,EAAU,YAAA,EAAa,CAAA;AACzC","file":"loading.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\n/**\n * Merge class names with Tailwind CSS conflict resolution.\n * @param inputs - Class values (strings, arrays, objects) to merge\n * @returns A single merged class string with Tailwind conflicts resolved\n */\nexport function cn(...inputs: ClassValue[]) {\n\treturn twMerge(clsx(inputs));\n}\n\nconst SAFE_URL_SCHEMES = [\"http:\", \"https:\", \"mailto:\"] as const;\n\n/**\n * Allowlist a URL for use as an `<a href>` against untrusted input.\n *\n * Returns the raw string when it's `http(s):` / `mailto:` / a relative\n * URL (no scheme); returns `undefined` otherwise. Defends against\n * `javascript:` / `data:` / `vbscript:` injection from streamed model\n * output or third-party JSON payloads that flow into citation chips.\n *\n * Inside a Markdown render path, `rehype-sanitize` already strips\n * `javascript:` from inline-link hrefs — but it does NOT introspect\n * JSON nested inside attribute values (e.g. `<sources data='[…]'/>`),\n * so the components that consume that data must guard themselves.\n *\n * @param raw - The candidate URL, or `undefined` when none was supplied.\n * @returns The URL when safe to render, otherwise `undefined`.\n */\nexport function safeUrl(raw: string | undefined): string | undefined {\n\tif (raw === undefined || raw === \"\") return undefined;\n\t// Relative URLs have no scheme — `new URL(relative)` throws without a base,\n\t// so a thrown URL means either malformed input OR a relative path. Treat\n\t// \"throws + does not contain a colon\" as a relative path (safe).\n\tlet parsed: URL;\n\ttry {\n\t\tparsed = new URL(raw);\n\t} catch {\n\t\treturn raw.includes(\":\") ? undefined : raw;\n\t}\n\treturn SAFE_URL_SCHEMES.some((scheme) => scheme === parsed.protocol) ? raw : undefined;\n}\n","import * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\n\n/**\n * A placeholder shimmer element shown while content is loading.\n * Pair with explicit width/height via className.\n * @returns A div with pulsing muted background\n */\nfunction Skeleton({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"animate-pulse rounded-md border border-foreground/[0.06] bg-muted\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport { Skeleton };\n","import { type VariantProps, cva } from \"class-variance-authority\";\nimport * as React from \"react\";\nimport { cn } from \"../../lib/utils.js\";\nimport { Skeleton } from \"../skeleton/skeleton.js\";\n\nconst loadingVariants = cva(\"flex w-full\", {\n\tvariants: {\n\t\tvariant: {\n\t\t\tlist: \"flex-col gap-[var(--space-3,0.75rem)]\",\n\t\t\tcard: \"flex-col gap-[var(--space-2,0.5rem)] rounded-md border border-border bg-card p-[var(--space-4,1rem)]\",\n\t\t\tstack: \"flex-col gap-[var(--space-4,1rem)]\",\n\t\t},\n\t},\n\tdefaultVariants: { variant: \"list\" },\n});\n\nexport interface LoadingProps\n\textends Omit<React.HTMLAttributes<HTMLDivElement>, \"role\">,\n\t\tVariantProps<typeof loadingVariants> {\n\t/** Forwarded ref onto the status region. */\n\tref?: React.Ref<HTMLDivElement>;\n\t/**\n\t * Number of placeholder rows to render. Each row may contain multiple\n\t * Skeleton elements depending on `variant` — `list` emits 1 Skeleton\n\t * per row; `card` emits 3 (heading + 2 body lines); `stack` emits 3\n\t * (avatar + 2 text lines). Default 3.\n\t */\n\trows?: number;\n\t/** Optional sr-only label that screen readers announce. Default \"Loading…\". */\n\tlabel?: string;\n}\n\n/**\n * A composed loading-placeholder pattern for lists, cards, and stacks.\n * Renders N {@link Skeleton} rows pre-arranged for the chosen layout —\n * Skeleton is the atom (one shaped pulse), Loading is the molecule\n * (the canonical pattern most surfaces want).\n *\n * Distinct from {@link Empty} (request returned, no items) and\n * {@link ErrorState} (request failed). If you need a single shaped\n * pulse for a specific element (an avatar circle, a heading line),\n * reach for `Skeleton` directly. If the wait has a measurable\n * percent-done, reach for `Progress` instead.\n *\n * @example\n * ```tsx\n * <Loading rows={5} variant=\"list\" />\n * ```\n *\n * @returns A `role=\"status\"` region with `aria-live=\"polite\"` and the\n * announced label (default \"Loading…\") rendered sr-only.\n */\nfunction Loading({\n\tclassName,\n\tvariant = \"list\",\n\trows = 3,\n\tlabel = \"Loading…\",\n\tref,\n\t...props\n}: LoadingProps) {\n\treturn (\n\t\t<div\n\t\t\tref={ref}\n\t\t\trole=\"status\"\n\t\t\taria-live=\"polite\"\n\t\t\tclassName={cn(loadingVariants({ variant }), className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<span className=\"sr-only\">{label}</span>\n\t\t\t{Array.from({ length: rows }, (_, i) => (\n\t\t\t\t// `variant` can be `null` per CVA's VariantProps shape — the\n\t\t\t\t// destructured default only catches undefined. The fallback\n\t\t\t\t// here narrows to the LoadingRow's \"list\" | \"card\" | \"stack\"\n\t\t\t\t// signature.\n\t\t\t\t<LoadingRow key={i} variant={variant ?? \"list\"} />\n\t\t\t))}\n\t\t</div>\n\t);\n}\n\n/**\n * One placeholder row inside `Loading`. Layout-specific shape per variant.\n *\n * @param variant - Layout family the row belongs to (`list` / `card` / `stack`).\n */\nfunction LoadingRow({ variant }: { variant: \"list\" | \"card\" | \"stack\" }) {\n\tif (variant === \"card\") {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<Skeleton className=\"h-4 w-3/4\" />\n\t\t\t\t<Skeleton className=\"h-3 w-full\" />\n\t\t\t\t<Skeleton className=\"h-3 w-5/6\" />\n\t\t\t</>\n\t\t);\n\t}\n\tif (variant === \"stack\") {\n\t\treturn (\n\t\t\t<div className=\"flex items-center gap-[var(--space-3,0.75rem)]\">\n\t\t\t\t<Skeleton className=\"h-10 w-10 shrink-0 rounded-full\" />\n\t\t\t\t<div className=\"flex flex-1 flex-col gap-[var(--space-2,0.5rem)]\">\n\t\t\t\t\t<Skeleton className=\"h-4 w-1/3\" />\n\t\t\t\t\t<Skeleton className=\"h-3 w-2/3\" />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t);\n\t}\n\t// list (default)\n\treturn <Skeleton className=\"h-4 w-full\" />;\n}\n\nexport { Loading, loadingVariants };\n"]}
|
package/dist/markdown.d.ts
CHANGED