@openpkg-ts/ui 0.1.1

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.
@@ -0,0 +1,114 @@
1
+ interface ParameterSchema {
2
+ /** Type name (e.g., "string", "number", "object") */
3
+ type?: string;
4
+ /** Formatted type string for display */
5
+ typeString?: string;
6
+ /** Description of the parameter/property */
7
+ description?: string;
8
+ /** Nested properties for object types */
9
+ properties?: Record<string, ParameterSchema>;
10
+ /** Required property names */
11
+ required?: string[];
12
+ }
13
+ interface ParameterItemProps {
14
+ /** Parameter name */
15
+ name: string;
16
+ /** Parameter schema */
17
+ schema: ParameterSchema;
18
+ /** Whether this parameter is required */
19
+ required?: boolean;
20
+ /** Description (overrides schema.description) */
21
+ description?: string;
22
+ /** Nesting depth for indentation */
23
+ depth?: number;
24
+ /** Custom className */
25
+ className?: string;
26
+ }
27
+ /**
28
+ * Single parameter with expand capability for nested objects.
29
+ * Features expandable nested params, type annotations, and required/optional badges.
30
+ */
31
+ declare function ParameterItem({ name, schema, required: isRequired, description, depth, className }: ParameterItemProps): React.ReactNode;
32
+ import * as React2 from "react";
33
+ type TypeColor = "string" | "number" | "boolean" | "null" | "undefined" | "object" | "array" | "function" | "union" | "generic" | "default";
34
+ /**
35
+ * Type coloring for syntax display.
36
+ * Follows Stripe-style: consistent colors for primitives vs complex types.
37
+ */
38
+ declare const typeBadgeVariants: (props?: {
39
+ typeColor?: TypeColor | null;
40
+ className?: string;
41
+ }) => string;
42
+ interface TypeBadgeProps extends React2.HTMLAttributes<HTMLSpanElement> {
43
+ /** Type string to display */
44
+ type: string;
45
+ /** Override color detection */
46
+ typeColor?: TypeColor | null;
47
+ }
48
+ /**
49
+ * Inline type display with syntax coloring.
50
+ * Automatically detects type category and applies appropriate color.
51
+ */
52
+ declare const TypeBadge: React2.ForwardRefExoticComponent<TypeBadgeProps & React2.RefAttributes<HTMLSpanElement>>;
53
+ interface ImportSectionProps {
54
+ /** Import statement text */
55
+ importStatement: string;
56
+ /** Custom className */
57
+ className?: string;
58
+ }
59
+ /**
60
+ * Displays a copyable import statement with one-click copy.
61
+ * Monospace styling with copy button.
62
+ */
63
+ declare function ImportSection({ importStatement, className }: ImportSectionProps): React.ReactNode;
64
+ import { ReactNode as ReactNode2 } from "react";
65
+ interface CodeTab {
66
+ /** Tab label */
67
+ label: string;
68
+ /** Tab content (code block) */
69
+ content: ReactNode2;
70
+ /** Raw code for copy button */
71
+ code: string;
72
+ }
73
+ interface CodeTabsProps {
74
+ /** Array of tabs */
75
+ tabs: CodeTab[];
76
+ /** Default selected tab index */
77
+ defaultIndex?: number;
78
+ /** Enable sticky positioning for the header */
79
+ sticky?: boolean;
80
+ /** Custom className */
81
+ className?: string;
82
+ }
83
+ /**
84
+ * Tabbed code block wrapper with copy button per tab.
85
+ * Uses docskit --dk-* CSS variables for consistent theming.
86
+ */
87
+ declare function CodeTabs({ tabs, defaultIndex, sticky, className }: CodeTabsProps): React.ReactNode2;
88
+ import * as React3 from "react";
89
+ type ExportKind = "function" | "type" | "variable" | "class" | "interface" | "enum";
90
+ /**
91
+ * Kind badge variants for export cards.
92
+ */
93
+ declare const kindBadgeVariants: (props?: {
94
+ kind?: ExportKind | null;
95
+ className?: string;
96
+ }) => string;
97
+ interface ExportCardProps extends React3.AnchorHTMLAttributes<HTMLAnchorElement> {
98
+ /** Export name */
99
+ name: string;
100
+ /** Description snippet */
101
+ description?: string;
102
+ /** Link to detail page */
103
+ href: string;
104
+ /** Export kind */
105
+ kind?: ExportKind | null;
106
+ /** Custom link component (for Next.js Link) */
107
+ as?: React3.ElementType;
108
+ }
109
+ /**
110
+ * Card component for displaying exports in an index grid.
111
+ * Features function name styling, description, kind badge, and hover effects.
112
+ */
113
+ declare const ExportCard: React3.ForwardRefExoticComponent<ExportCardProps & React3.RefAttributes<HTMLAnchorElement>>;
114
+ export { typeBadgeVariants, kindBadgeVariants, TypeBadgeProps, TypeBadge, ParameterSchema, ParameterItemProps, ParameterItem, ImportSectionProps, ImportSection, ExportKind, ExportCardProps, ExportCard, CodeTabsProps, CodeTabs, CodeTab };
@@ -0,0 +1,435 @@
1
+ "use client";
2
+ // src/api/ParameterItem.tsx
3
+ import { ChevronRight } from "lucide-react";
4
+ import { useState } from "react";
5
+
6
+ // src/lib/utils.ts
7
+ import { clsx } from "clsx";
8
+ import { twMerge } from "tailwind-merge";
9
+ function cn(...inputs) {
10
+ return twMerge(clsx(inputs));
11
+ }
12
+
13
+ // src/api/ParameterItem.tsx
14
+ import { jsx, jsxs } from "react/jsx-runtime";
15
+
16
+ function getNestedProperties(schema) {
17
+ if (!schema || typeof schema !== "object")
18
+ return null;
19
+ if (schema.type === "object" && schema.properties) {
20
+ return schema.properties;
21
+ }
22
+ return null;
23
+ }
24
+ function getRequiredFields(schema) {
25
+ return schema.required ?? [];
26
+ }
27
+ function countProperties(schema) {
28
+ const props = getNestedProperties(schema);
29
+ return props ? Object.keys(props).length : 0;
30
+ }
31
+ function getTypeDisplay(schema) {
32
+ if (schema.typeString)
33
+ return schema.typeString;
34
+ return schema.type ?? "unknown";
35
+ }
36
+ function NestedPropertyItem({
37
+ name,
38
+ schema,
39
+ required = false,
40
+ depth = 0
41
+ }) {
42
+ const [expanded, setExpanded] = useState(false);
43
+ const type = getTypeDisplay(schema);
44
+ const nestedProps = getNestedProperties(schema);
45
+ const nestedCount = countProperties(schema);
46
+ const hasNested = nestedCount > 0;
47
+ return /* @__PURE__ */ jsxs("div", {
48
+ className: cn("border-t border-border first:border-t-0", depth > 0 && "ml-4"),
49
+ children: [
50
+ /* @__PURE__ */ jsx("div", {
51
+ className: "py-3",
52
+ children: /* @__PURE__ */ jsxs("div", {
53
+ className: "flex items-start gap-2",
54
+ children: [
55
+ hasNested && /* @__PURE__ */ jsx("button", {
56
+ type: "button",
57
+ onClick: () => setExpanded(!expanded),
58
+ className: "mt-0.5 p-0.5 text-muted-foreground hover:text-foreground transition-colors cursor-pointer",
59
+ "aria-label": expanded ? "Collapse" : "Expand",
60
+ children: /* @__PURE__ */ jsx(ChevronRight, {
61
+ size: 14,
62
+ className: cn("transition-transform duration-200", expanded && "rotate-90")
63
+ })
64
+ }),
65
+ !hasNested && /* @__PURE__ */ jsx("div", {
66
+ className: "w-5"
67
+ }),
68
+ /* @__PURE__ */ jsxs("div", {
69
+ className: "flex-1 min-w-0",
70
+ children: [
71
+ /* @__PURE__ */ jsxs("div", {
72
+ className: "flex items-baseline gap-2 flex-wrap",
73
+ children: [
74
+ /* @__PURE__ */ jsxs("span", {
75
+ className: "font-mono text-sm text-foreground",
76
+ children: [
77
+ name,
78
+ !required && /* @__PURE__ */ jsx("span", {
79
+ className: "text-muted-foreground",
80
+ children: "?"
81
+ })
82
+ ]
83
+ }),
84
+ /* @__PURE__ */ jsx("span", {
85
+ className: "font-mono text-sm text-muted-foreground",
86
+ children: hasNested ? "object" : type
87
+ }),
88
+ hasNested && /* @__PURE__ */ jsxs("button", {
89
+ type: "button",
90
+ onClick: () => setExpanded(!expanded),
91
+ className: "text-xs text-primary hover:underline cursor-pointer",
92
+ children: [
93
+ nestedCount,
94
+ " ",
95
+ nestedCount === 1 ? "property" : "properties"
96
+ ]
97
+ })
98
+ ]
99
+ }),
100
+ schema.description && /* @__PURE__ */ jsx("p", {
101
+ className: "text-sm text-muted-foreground mt-1",
102
+ children: schema.description
103
+ })
104
+ ]
105
+ })
106
+ ]
107
+ })
108
+ }),
109
+ hasNested && expanded && nestedProps && /* @__PURE__ */ jsx("div", {
110
+ className: "border-l border-border ml-2",
111
+ children: Object.entries(nestedProps).map(([propName, propSchema]) => /* @__PURE__ */ jsx(NestedPropertyItem, {
112
+ name: propName,
113
+ schema: propSchema,
114
+ required: getRequiredFields(schema).includes(propName),
115
+ depth: depth + 1
116
+ }, propName))
117
+ })
118
+ ]
119
+ });
120
+ }
121
+ function ParameterItem({
122
+ name,
123
+ schema,
124
+ required: isRequired = true,
125
+ description,
126
+ depth = 0,
127
+ className
128
+ }) {
129
+ const [expanded, setExpanded] = useState(false);
130
+ const type = getTypeDisplay(schema);
131
+ const nestedProps = getNestedProperties(schema);
132
+ const nestedCount = countProperties(schema);
133
+ const hasNested = nestedCount > 0;
134
+ const displayDescription = description ?? schema.description;
135
+ return /* @__PURE__ */ jsxs("div", {
136
+ className: cn("border-b border-border last:border-b-0", className),
137
+ children: [
138
+ /* @__PURE__ */ jsx("div", {
139
+ className: "py-3",
140
+ children: /* @__PURE__ */ jsxs("div", {
141
+ className: "flex items-start gap-2",
142
+ children: [
143
+ hasNested && /* @__PURE__ */ jsx("button", {
144
+ type: "button",
145
+ onClick: () => setExpanded(!expanded),
146
+ className: "mt-0.5 p-0.5 text-muted-foreground hover:text-foreground transition-colors cursor-pointer",
147
+ "aria-label": expanded ? "Collapse" : "Expand",
148
+ children: /* @__PURE__ */ jsx(ChevronRight, {
149
+ size: 14,
150
+ className: cn("transition-transform duration-200", expanded && "rotate-90")
151
+ })
152
+ }),
153
+ !hasNested && /* @__PURE__ */ jsx("div", {
154
+ className: "w-5"
155
+ }),
156
+ /* @__PURE__ */ jsxs("div", {
157
+ className: "flex-1 min-w-0",
158
+ children: [
159
+ /* @__PURE__ */ jsxs("div", {
160
+ className: "flex items-baseline gap-2 flex-wrap",
161
+ children: [
162
+ /* @__PURE__ */ jsx("span", {
163
+ className: "font-mono text-sm font-medium text-foreground",
164
+ children: name
165
+ }),
166
+ isRequired && /* @__PURE__ */ jsx("span", {
167
+ className: "text-[10px] font-semibold px-1.5 py-0.5 rounded border border-border bg-muted text-muted-foreground uppercase tracking-wide",
168
+ children: "Required"
169
+ }),
170
+ /* @__PURE__ */ jsx("span", {
171
+ className: "font-mono text-sm text-muted-foreground",
172
+ children: hasNested ? "object" : type
173
+ }),
174
+ hasNested && /* @__PURE__ */ jsxs("button", {
175
+ type: "button",
176
+ onClick: () => setExpanded(!expanded),
177
+ className: "text-xs text-primary hover:underline cursor-pointer",
178
+ children: [
179
+ nestedCount,
180
+ " ",
181
+ nestedCount === 1 ? "property" : "properties"
182
+ ]
183
+ })
184
+ ]
185
+ }),
186
+ displayDescription && /* @__PURE__ */ jsx("p", {
187
+ className: "text-sm text-muted-foreground mt-1",
188
+ children: displayDescription
189
+ })
190
+ ]
191
+ })
192
+ ]
193
+ })
194
+ }),
195
+ hasNested && expanded && nestedProps && /* @__PURE__ */ jsx("div", {
196
+ className: "border-l border-border ml-2 mb-3",
197
+ children: Object.entries(nestedProps).map(([propName, propSchema]) => /* @__PURE__ */ jsx(NestedPropertyItem, {
198
+ name: propName,
199
+ schema: propSchema,
200
+ required: getRequiredFields(schema).includes(propName),
201
+ depth: depth + 1
202
+ }, propName))
203
+ })
204
+ ]
205
+ });
206
+ }
207
+ // src/api/TypeBadge.tsx
208
+ import { cva } from "class-variance-authority";
209
+ import * as React from "react";
210
+ import { jsx as jsx2 } from "react/jsx-runtime";
211
+ var typeBadgeVariants = cva("font-mono text-sm", {
212
+ variants: {
213
+ typeColor: {
214
+ string: "text-emerald-600 dark:text-emerald-400",
215
+ number: "text-blue-600 dark:text-blue-400",
216
+ boolean: "text-amber-600 dark:text-amber-400",
217
+ null: "text-gray-500 dark:text-gray-400",
218
+ undefined: "text-gray-500 dark:text-gray-400",
219
+ object: "text-purple-600 dark:text-purple-400",
220
+ array: "text-cyan-600 dark:text-cyan-400",
221
+ function: "text-fuchsia-600 dark:text-fuchsia-400",
222
+ union: "text-orange-600 dark:text-orange-400",
223
+ generic: "text-rose-600 dark:text-rose-400",
224
+ default: "text-muted-foreground"
225
+ }
226
+ },
227
+ defaultVariants: {
228
+ typeColor: "default"
229
+ }
230
+ });
231
+ function detectTypeColor(type) {
232
+ const normalized = type.toLowerCase().trim();
233
+ if (normalized === "string" || normalized.startsWith('"') || normalized.startsWith("'")) {
234
+ return "string";
235
+ }
236
+ if (normalized === "number" || /^\d+$/.test(normalized)) {
237
+ return "number";
238
+ }
239
+ if (normalized === "boolean" || normalized === "true" || normalized === "false") {
240
+ return "boolean";
241
+ }
242
+ if (normalized === "null") {
243
+ return "null";
244
+ }
245
+ if (normalized === "undefined" || normalized === "void") {
246
+ return "undefined";
247
+ }
248
+ if (normalized === "object" || normalized.startsWith("{")) {
249
+ return "object";
250
+ }
251
+ if (normalized.endsWith("[]") || normalized.startsWith("array")) {
252
+ return "array";
253
+ }
254
+ if (normalized.startsWith("(") || normalized.includes("=>") || normalized.startsWith("function")) {
255
+ return "function";
256
+ }
257
+ if (normalized.includes("|")) {
258
+ return "union";
259
+ }
260
+ if (normalized.includes("<") && normalized.includes(">")) {
261
+ return "generic";
262
+ }
263
+ return "default";
264
+ }
265
+ var TypeBadge = React.forwardRef(({ className, type, typeColor, ...props }, ref) => {
266
+ const color = typeColor ?? detectTypeColor(type);
267
+ return /* @__PURE__ */ jsx2("span", {
268
+ ref,
269
+ className: cn(typeBadgeVariants({ typeColor: color }), className),
270
+ ...props,
271
+ children: type
272
+ });
273
+ });
274
+ TypeBadge.displayName = "TypeBadge";
275
+ // src/api/ImportSection.tsx
276
+ import { Check, Copy } from "lucide-react";
277
+ import { useState as useState2 } from "react";
278
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
279
+
280
+ function ImportSection({ importStatement, className }) {
281
+ const [copied, setCopied] = useState2(false);
282
+ const handleCopy = () => {
283
+ navigator.clipboard.writeText(importStatement);
284
+ setCopied(true);
285
+ setTimeout(() => setCopied(false), 1200);
286
+ };
287
+ return /* @__PURE__ */ jsxs2("div", {
288
+ className: cn("group flex items-center justify-between gap-3", "rounded-lg border border-border bg-muted/30 px-4 py-3", className),
289
+ children: [
290
+ /* @__PURE__ */ jsx3("code", {
291
+ className: "font-mono text-sm text-foreground overflow-x-auto",
292
+ children: importStatement
293
+ }),
294
+ /* @__PURE__ */ jsx3("button", {
295
+ type: "button",
296
+ onClick: handleCopy,
297
+ className: cn("shrink-0 p-1.5 rounded", "text-muted-foreground hover:text-foreground", "opacity-0 group-hover:opacity-100 transition-opacity duration-200", "cursor-pointer"),
298
+ "aria-label": "Copy import statement",
299
+ children: copied ? /* @__PURE__ */ jsx3(Check, {
300
+ size: 16
301
+ }) : /* @__PURE__ */ jsx3(Copy, {
302
+ size: 16
303
+ })
304
+ })
305
+ ]
306
+ });
307
+ }
308
+ // src/api/CodeTabs.tsx
309
+ import { Check as Check2, Copy as Copy2 } from "lucide-react";
310
+ import { useState as useState3 } from "react";
311
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
312
+
313
+ function CodeTabs({
314
+ tabs,
315
+ defaultIndex = 0,
316
+ sticky = false,
317
+ className
318
+ }) {
319
+ const [activeIndex, setActiveIndex] = useState3(defaultIndex);
320
+ const [copied, setCopied] = useState3(false);
321
+ const activeTab = tabs[activeIndex];
322
+ const handleCopy = () => {
323
+ if (!activeTab)
324
+ return;
325
+ navigator.clipboard.writeText(activeTab.code);
326
+ setCopied(true);
327
+ setTimeout(() => setCopied(false), 1200);
328
+ };
329
+ if (!tabs.length)
330
+ return null;
331
+ return /* @__PURE__ */ jsxs3("div", {
332
+ className: cn("group rounded-lg border border-dk-border bg-dk-background overflow-hidden", "selection:bg-dk-selection selection:text-current", className),
333
+ children: [
334
+ /* @__PURE__ */ jsxs3("div", {
335
+ className: cn("flex items-center border-b border-dk-border bg-dk-tabs-background", sticky && "sticky top-0 z-10"),
336
+ children: [
337
+ /* @__PURE__ */ jsx4("div", {
338
+ className: "flex-1 flex items-stretch",
339
+ children: tabs.map((tab, index) => /* @__PURE__ */ jsx4("button", {
340
+ type: "button",
341
+ onClick: () => setActiveIndex(index),
342
+ className: cn("px-4 py-2 text-sm font-mono transition-colors duration-200", "border-r border-dk-border last:border-r-0", index === activeIndex ? "text-dk-tab-active-foreground bg-dk-background/50" : "text-dk-tab-inactive-foreground hover:text-dk-tab-active-foreground"),
343
+ children: tab.label
344
+ }, tab.label))
345
+ }),
346
+ /* @__PURE__ */ jsx4("button", {
347
+ type: "button",
348
+ onClick: handleCopy,
349
+ className: cn("p-2 mx-2", "text-dk-tab-inactive-foreground hover:text-dk-tab-active-foreground", "opacity-0 group-hover:opacity-100 transition-opacity", "cursor-pointer"),
350
+ "aria-label": "Copy code",
351
+ children: copied ? /* @__PURE__ */ jsx4(Check2, {
352
+ size: 16
353
+ }) : /* @__PURE__ */ jsx4(Copy2, {
354
+ size: 16
355
+ })
356
+ })
357
+ ]
358
+ }),
359
+ /* @__PURE__ */ jsx4("div", {
360
+ className: "bg-dk-background",
361
+ children: activeTab?.content
362
+ })
363
+ ]
364
+ });
365
+ }
366
+ // src/api/ExportCard.tsx
367
+ import { cva as cva2 } from "class-variance-authority";
368
+ import * as React2 from "react";
369
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
370
+
371
+ var kindBadgeVariants = cva2("inline-flex items-center justify-center font-mono font-medium rounded shrink-0 h-5 px-1.5 text-xs", {
372
+ variants: {
373
+ kind: {
374
+ function: "bg-fuchsia-500/15 text-fuchsia-600 dark:text-fuchsia-400",
375
+ class: "bg-amber-500/15 text-amber-600 dark:text-amber-400",
376
+ interface: "bg-cyan-500/15 text-cyan-600 dark:text-cyan-400",
377
+ type: "bg-purple-500/15 text-purple-600 dark:text-purple-400",
378
+ enum: "bg-emerald-500/15 text-emerald-600 dark:text-emerald-400",
379
+ variable: "bg-blue-500/15 text-blue-600 dark:text-blue-400"
380
+ }
381
+ },
382
+ defaultVariants: {
383
+ kind: "function"
384
+ }
385
+ });
386
+ var kindLabels = {
387
+ function: "fn",
388
+ class: "cls",
389
+ interface: "int",
390
+ type: "type",
391
+ enum: "enum",
392
+ variable: "var"
393
+ };
394
+ var ExportCard = React2.forwardRef(({ name, description, href, kind = "function", as: Component = "a", className, ...props }, ref) => {
395
+ const isFunction = kind === "function";
396
+ return /* @__PURE__ */ jsxs4(Component, {
397
+ ref,
398
+ href,
399
+ className: cn("group block rounded-lg border border-border bg-card/50 p-4", "transition-all duration-200", "hover:border-border/80 hover:bg-card hover:shadow-md", "hover:-translate-y-0.5", className),
400
+ ...props,
401
+ children: [
402
+ /* @__PURE__ */ jsxs4("div", {
403
+ className: "flex items-center gap-2 mb-2",
404
+ children: [
405
+ /* @__PURE__ */ jsx5("span", {
406
+ className: kindBadgeVariants({ kind }),
407
+ children: kindLabels[kind]
408
+ }),
409
+ /* @__PURE__ */ jsx5("span", {
410
+ className: "font-mono text-base font-medium text-foreground group-hover:text-primary transition-colors",
411
+ children: name
412
+ }),
413
+ isFunction && /* @__PURE__ */ jsx5("span", {
414
+ className: "font-mono text-base text-muted-foreground",
415
+ children: "()"
416
+ })
417
+ ]
418
+ }),
419
+ description && /* @__PURE__ */ jsx5("p", {
420
+ className: "text-sm text-muted-foreground line-clamp-2 leading-relaxed",
421
+ children: description
422
+ })
423
+ ]
424
+ });
425
+ });
426
+ ExportCard.displayName = "ExportCard";
427
+ export {
428
+ typeBadgeVariants,
429
+ kindBadgeVariants,
430
+ TypeBadge,
431
+ ParameterItem,
432
+ ImportSection,
433
+ ExportCard,
434
+ CodeTabs
435
+ };
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ type KindBadgeKind = "function" | "class" | "interface" | "type" | "enum" | "variable" | "namespace" | "module" | "reference" | "external";
3
+ type KindBadgeSize = "sm" | "md";
4
+ declare const kindBadgeVariants: (props?: {
5
+ kind?: KindBadgeKind | null;
6
+ size?: KindBadgeSize | null;
7
+ className?: string;
8
+ }) => string;
9
+ interface KindBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
10
+ kind?: KindBadgeKind | null;
11
+ size?: KindBadgeSize | null;
12
+ label?: string;
13
+ }
14
+ declare const KindBadge: React.ForwardRefExoticComponent<KindBadgeProps & React.RefAttributes<HTMLSpanElement>>;
15
+ type StatusBadgeStatus = "success" | "warning" | "error" | "neutral";
16
+ type StatusBadgeSize = "sm" | "md";
17
+ declare const statusBadgeVariants: (props?: {
18
+ status?: StatusBadgeStatus | null;
19
+ size?: StatusBadgeSize | null;
20
+ className?: string;
21
+ }) => string;
22
+ interface StatusBadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
23
+ status?: StatusBadgeStatus | null;
24
+ size?: StatusBadgeSize | null;
25
+ label?: string;
26
+ icon?: React.ReactNode;
27
+ }
28
+ declare const StatusBadge: React.ForwardRefExoticComponent<StatusBadgeProps & React.RefAttributes<HTMLSpanElement>>;
29
+ export { statusBadgeVariants, kindBadgeVariants, StatusBadgeStatus, StatusBadgeSize, StatusBadgeProps, StatusBadge, KindBadgeSize, KindBadgeProps, KindBadgeKind, KindBadge };
@@ -0,0 +1,94 @@
1
+ // src/badge/badge.tsx
2
+ import { cva } from "class-variance-authority";
3
+ import * as React from "react";
4
+
5
+ // src/lib/utils.ts
6
+ import { clsx } from "clsx";
7
+ import { twMerge } from "tailwind-merge";
8
+ function cn(...inputs) {
9
+ return twMerge(clsx(inputs));
10
+ }
11
+
12
+ // src/badge/badge.tsx
13
+ import { jsx, jsxs } from "react/jsx-runtime";
14
+ var kindBadgeVariants = cva("inline-flex items-center justify-center font-mono font-medium rounded shrink-0", {
15
+ variants: {
16
+ kind: {
17
+ function: "bg-kind-function/15 text-kind-function",
18
+ class: "bg-kind-class/15 text-kind-class",
19
+ interface: "bg-kind-interface/15 text-kind-interface",
20
+ type: "bg-kind-type/15 text-kind-type",
21
+ enum: "bg-kind-enum/15 text-kind-enum",
22
+ variable: "bg-kind-variable/15 text-kind-variable",
23
+ namespace: "bg-kind-namespace/15 text-kind-namespace",
24
+ module: "bg-kind-module/15 text-kind-module",
25
+ reference: "bg-kind-reference/15 text-kind-reference",
26
+ external: "bg-kind-external/15 text-kind-external"
27
+ },
28
+ size: {
29
+ sm: "h-4 px-1 text-[10px]",
30
+ md: "h-5 px-1.5 text-xs"
31
+ }
32
+ },
33
+ defaultVariants: {
34
+ kind: "function",
35
+ size: "md"
36
+ }
37
+ });
38
+ var KindBadge = React.forwardRef(({ className, kind, size, label, ...props }, ref) => {
39
+ const defaultLabels = {
40
+ function: "fn",
41
+ class: "cls",
42
+ interface: "int",
43
+ type: "type",
44
+ enum: "enum",
45
+ variable: "var",
46
+ namespace: "ns",
47
+ module: "mod",
48
+ reference: "ref",
49
+ external: "ext"
50
+ };
51
+ return /* @__PURE__ */ jsx("span", {
52
+ ref,
53
+ className: cn(kindBadgeVariants({ kind, size, className })),
54
+ ...props,
55
+ children: label || defaultLabels[kind || "function"]
56
+ });
57
+ });
58
+ KindBadge.displayName = "KindBadge";
59
+ var statusBadgeVariants = cva("inline-flex items-center justify-center gap-1 font-medium rounded-full", {
60
+ variants: {
61
+ status: {
62
+ success: "bg-success-light text-success",
63
+ warning: "bg-warning-light text-warning",
64
+ error: "bg-destructive-light text-destructive",
65
+ neutral: "bg-muted text-muted-foreground"
66
+ },
67
+ size: {
68
+ sm: "h-5 px-2 text-xs",
69
+ md: "h-6 px-2.5 text-sm"
70
+ }
71
+ },
72
+ defaultVariants: {
73
+ status: "neutral",
74
+ size: "md"
75
+ }
76
+ });
77
+ var StatusBadge = React.forwardRef(({ className, status, size, label, icon, children, ...props }, ref) => {
78
+ return /* @__PURE__ */ jsxs("span", {
79
+ ref,
80
+ className: cn(statusBadgeVariants({ status, size, className })),
81
+ ...props,
82
+ children: [
83
+ icon,
84
+ label || children
85
+ ]
86
+ });
87
+ });
88
+ StatusBadge.displayName = "StatusBadge";
89
+ export {
90
+ statusBadgeVariants,
91
+ kindBadgeVariants,
92
+ StatusBadge,
93
+ KindBadge
94
+ };