@openpkg-ts/ui 0.1.6 → 0.1.7

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.
@@ -408,4 +408,60 @@ declare function TooltipLink(props: {
408
408
  }): React.JSX.Element;
409
409
  import { AnnotationHandler as AnnotationHandler14 } from "codehike/code";
410
410
  declare const wordWrap2: AnnotationHandler14;
411
- export { wordWrap2 as wordWrap, tooltip, toCodeGroup, theme, mark, link, lineNumbers2 as lineNumbers, hover, flagsToOptions, expandable, endpointBadgeVariants, diff, collapse, callout, addDocsKit, WithNotes, WithHover, TooltipLink, TerminalSkeleton, Terminal, TabsTrigger, TabsList, TabsContent, Tabs, SingleCode, ResponseBlockProps, ResponseBlock, ParameterListProps, ParameterList, PackageInstall, MultiCode, LanguageSelectorProps, LanguageSelector, Language, InlineCodeSkeleton, HttpMethod, HoverLink, EndpointHeaderProps, EndpointHeader, EndpointBadgeProps, EndpointBadge, DocsKitInlineCode, DocsKitCode, DiffStats, CopyButton, CodeTabsSkeleton, CodeInfo, CodeIcon, CodeGroup, CodeExample, CodeBlockSkeleton, Code, ClientTerminal, ClientInlineCode, ClientDocsKitCode, ClientDiffCodeProps, ClientDiffCode, ClientCode, APISectionProps, APISection, APIReferencePageProps, APIReferencePage, APIParameterSchema, APIParameterItemProps, APIParameterItem, APICodePanelProps, APICodePanel };
411
+ import { ReactNode as ReactNode2 } from "react";
412
+ interface CodeTab {
413
+ /** Tab label */
414
+ label: string;
415
+ /** Tab content (code block) */
416
+ content: ReactNode2;
417
+ /** Raw code for copy button */
418
+ code: string;
419
+ }
420
+ interface CodeTabsProps {
421
+ /** Array of tabs */
422
+ tabs: CodeTab[];
423
+ /** Default selected tab index */
424
+ defaultIndex?: number;
425
+ /** Enable sticky positioning for the header */
426
+ sticky?: boolean;
427
+ /** Custom className */
428
+ className?: string;
429
+ }
430
+ /**
431
+ * Tabbed code block wrapper with copy button per tab.
432
+ * Uses docskit --dk-* CSS variables for consistent theming.
433
+ */
434
+ declare function CodeTabs({ tabs, defaultIndex, sticky, className }: CodeTabsProps): React.ReactNode2;
435
+ interface ImportSectionProps {
436
+ /** Import statement text */
437
+ importStatement: string;
438
+ /** Custom className */
439
+ className?: string;
440
+ }
441
+ /**
442
+ * Displays a copyable import statement with one-click copy.
443
+ * Monospace styling with copy button.
444
+ */
445
+ declare function ImportSection({ importStatement, className }: ImportSectionProps): React.ReactNode;
446
+ import * as React14 from "react";
447
+ type TypeColor = "string" | "number" | "boolean" | "null" | "undefined" | "object" | "array" | "function" | "union" | "generic" | "default";
448
+ /**
449
+ * Type coloring for syntax display.
450
+ * Follows Stripe-style: consistent colors for primitives vs complex types.
451
+ */
452
+ declare const typeBadgeVariants: (props?: {
453
+ typeColor?: TypeColor | null;
454
+ className?: string;
455
+ }) => string;
456
+ interface TypeBadgeProps extends React14.HTMLAttributes<HTMLSpanElement> {
457
+ /** Type string to display */
458
+ type: string;
459
+ /** Override color detection */
460
+ typeColor?: TypeColor | null;
461
+ }
462
+ /**
463
+ * Inline type display with syntax coloring.
464
+ * Automatically detects type category and applies appropriate color.
465
+ */
466
+ declare const TypeBadge: React14.ForwardRefExoticComponent<TypeBadgeProps & React14.RefAttributes<HTMLSpanElement>>;
467
+ export { wordWrap2 as wordWrap, typeBadgeVariants, tooltip, toCodeGroup, theme, mark, link, lineNumbers2 as lineNumbers, hover, flagsToOptions, expandable, endpointBadgeVariants, diff, collapse, callout, addDocsKit, WithNotes, WithHover, TypeColor, TypeBadgeProps, TypeBadge, TooltipLink, TerminalSkeleton, Terminal, TabsTrigger, TabsList, TabsContent, Tabs, SingleCode, ResponseBlockProps, ResponseBlock, ParameterListProps, ParameterList, PackageInstall, MultiCode, LanguageSelectorProps, LanguageSelector, Language, InlineCodeSkeleton, ImportSectionProps, ImportSection, HttpMethod, HoverLink, EndpointHeaderProps, EndpointHeader, EndpointBadgeProps, EndpointBadge, DocsKitInlineCode, DocsKitCode, DiffStats, CopyButton, CodeTabsSkeleton, CodeTabsProps, CodeTabs, CodeTab, CodeInfo, CodeIcon, CodeGroup, CodeExample, CodeBlockSkeleton, Code, ClientTerminal, ClientInlineCode, ClientDocsKitCode, ClientDiffCodeProps, ClientDiffCode, ClientCode, APISectionProps, APISection, APIReferencePageProps, APIReferencePage, APIParameterSchema, APIParameterItemProps, APIParameterItem, APICodePanelProps, APICodePanel };
@@ -2,7 +2,7 @@
2
2
  // src/docskit/api/api-code-panel.tsx
3
3
  import { highlight, Pre } from "codehike/code";
4
4
  import { Check, Copy, ExternalLink } from "lucide-react";
5
- import { useEffect as useEffect2, useState as useState3 } from "react";
5
+ import { useEffect as useEffect2, useState as useState4 } from "react";
6
6
 
7
7
  // src/lib/utils.ts
8
8
  import { clsx } from "clsx";
@@ -11,6 +11,22 @@ function cn(...inputs) {
11
11
  return twMerge(clsx(inputs));
12
12
  }
13
13
 
14
+ // src/hooks/use-copy-to-clipboard.ts
15
+ import { useCallback, useRef, useState } from "react";
16
+ var COPY_FEEDBACK_MS = 1200;
17
+ function useCopyToClipboard(timeout = COPY_FEEDBACK_MS) {
18
+ const [copied, setCopied] = useState(false);
19
+ const timerRef = useRef();
20
+ const copy = useCallback((text) => {
21
+ navigator.clipboard.writeText(text).then(() => {
22
+ setCopied(true);
23
+ clearTimeout(timerRef.current);
24
+ timerRef.current = setTimeout(() => setCopied(false), timeout);
25
+ });
26
+ }, [timeout]);
27
+ return [copied, copy];
28
+ }
29
+
14
30
  // src/docskit/code.config.ts
15
31
  var theme = "github-from-css";
16
32
  function flagsToOptions(flags = "") {
@@ -294,7 +310,7 @@ var expandable = {
294
310
  import {
295
311
  InnerLine as InnerLine5
296
312
  } from "codehike/code";
297
- import { createContext, useContext, useState } from "react";
313
+ import { createContext, useContext, useState as useState2 } from "react";
298
314
  import { jsx as jsx9 } from "react/jsx-runtime";
299
315
 
300
316
  var HoverContext = createContext({
@@ -303,7 +319,7 @@ var HoverContext = createContext({
303
319
  removeHoveredName: () => {}
304
320
  });
305
321
  function HoverProvider({ children }) {
306
- const [hoveredNames, setHoveredNames] = useState([]);
322
+ const [hoveredNames, setHoveredNames] = useState2([]);
307
323
  const addHoveredName = (name) => {
308
324
  setHoveredNames((prev) => [...prev, name]);
309
325
  };
@@ -814,9 +830,9 @@ function APICodePanel({
814
830
  title,
815
831
  className
816
832
  }) {
817
- const [selectedLang, setSelectedLang] = useState3(examples[0]?.languageId ?? languages[0]?.id);
818
- const [copied, setCopied] = useState3(false);
819
- const [highlighted, setHighlighted] = useState3(null);
833
+ const [selectedLang, setSelectedLang] = useState4(examples[0]?.languageId ?? languages[0]?.id);
834
+ const [copied, copy] = useCopyToClipboard();
835
+ const [highlighted, setHighlighted] = useState4(null);
820
836
  const currentExample = examples.find((e) => e.languageId === selectedLang);
821
837
  const code = currentExample?.code ?? "";
822
838
  const lang = currentExample?.highlightLang ?? currentExample?.languageId ?? "txt";
@@ -836,9 +852,7 @@ function APICodePanel({
836
852
  };
837
853
  }, [code, lang]);
838
854
  const handleCopy = () => {
839
- navigator.clipboard.writeText(code);
840
- setCopied(true);
841
- setTimeout(() => setCopied(false), 1200);
855
+ copy(code);
842
856
  };
843
857
  const handlers = getHandlers({ copyButton: false });
844
858
  return /* @__PURE__ */ jsxs10("div", {
@@ -1023,15 +1037,12 @@ EndpointBadge.displayName = "EndpointBadge";
1023
1037
  // src/docskit/api/endpoint-header.tsx
1024
1038
  import { Check as Check2, Copy as Copy2 } from "lucide-react";
1025
1039
  import * as React4 from "react";
1026
- import { useState as useState4 } from "react";
1027
1040
  import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
1028
1041
 
1029
1042
  var EndpointHeader = React4.forwardRef(({ className, method, path, copyable = true, ...props }, ref) => {
1030
- const [copied, setCopied] = useState4(false);
1043
+ const [copied, copy] = useCopyToClipboard();
1031
1044
  const handleCopy = () => {
1032
- navigator.clipboard.writeText(path);
1033
- setCopied(true);
1034
- setTimeout(() => setCopied(false), 1200);
1045
+ copy(path);
1035
1046
  };
1036
1047
  return /* @__PURE__ */ jsxs13("div", {
1037
1048
  ref,
@@ -1072,15 +1083,10 @@ function NestedProperty({
1072
1083
  depth = 0
1073
1084
  }) {
1074
1085
  const [expanded, setExpanded] = useState5(false);
1075
- const [copied, setCopied] = useState5(false);
1086
+ const [copied, copy] = useCopyToClipboard();
1076
1087
  const type = schema.typeString ?? schema.type ?? "unknown";
1077
1088
  const hasNested = schema.properties && Object.keys(schema.properties).length > 0;
1078
1089
  const _nestedCount = hasNested && schema.properties ? Object.keys(schema.properties).length : 0;
1079
- const handleCopy = () => {
1080
- navigator.clipboard.writeText(name);
1081
- setCopied(true);
1082
- setTimeout(() => setCopied(false), 1200);
1083
- };
1084
1090
  return /* @__PURE__ */ jsxs14("div", {
1085
1091
  className: cn("border-t border-border first:border-t-0", depth > 0 && "ml-4"),
1086
1092
  children: [
@@ -1129,7 +1135,7 @@ function NestedProperty({
1129
1135
  }),
1130
1136
  /* @__PURE__ */ jsx25("button", {
1131
1137
  type: "button",
1132
- onClick: handleCopy,
1138
+ onClick: () => copy(name),
1133
1139
  className: "p-1 rounded text-muted-foreground hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer",
1134
1140
  "aria-label": "Copy name",
1135
1141
  children: copied ? /* @__PURE__ */ jsx25(Check3, {
@@ -1171,14 +1177,9 @@ function APIParameterItem({
1171
1177
  className
1172
1178
  }) {
1173
1179
  const [expanded, setExpanded] = useState5(false);
1174
- const [copied, setCopied] = useState5(false);
1180
+ const [copied, copy] = useCopyToClipboard();
1175
1181
  const hasNested = children?.properties && Object.keys(children.properties).length > 0;
1176
1182
  const _nestedCount = hasNested && children?.properties ? Object.keys(children.properties).length : 0;
1177
- const handleCopy = () => {
1178
- navigator.clipboard.writeText(name);
1179
- setCopied(true);
1180
- setTimeout(() => setCopied(false), 1200);
1181
- };
1182
1183
  return /* @__PURE__ */ jsxs14("div", {
1183
1184
  className: cn("border-b border-border last:border-b-0", className),
1184
1185
  children: [
@@ -1225,7 +1226,7 @@ function APIParameterItem({
1225
1226
  }),
1226
1227
  /* @__PURE__ */ jsx25("button", {
1227
1228
  type: "button",
1228
- onClick: handleCopy,
1229
+ onClick: () => copy(name),
1229
1230
  className: "p-1 rounded text-muted-foreground hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity cursor-pointer",
1230
1231
  "aria-label": "Copy name",
1231
1232
  children: copied ? /* @__PURE__ */ jsx25(Check3, {
@@ -1305,16 +1306,13 @@ function ParameterList({
1305
1306
  // src/docskit/api/response-block.tsx
1306
1307
  import { Check as Check4, Copy as Copy4 } from "lucide-react";
1307
1308
  import * as React6 from "react";
1308
- import { useState as useState7 } from "react";
1309
1309
  import { jsx as jsx27, jsxs as jsxs16, Fragment as Fragment4 } from "react/jsx-runtime";
1310
1310
 
1311
1311
  function ResponseBlock({ data, title, className }) {
1312
- const [copied, setCopied] = useState7(false);
1312
+ const [copied, copy] = useCopyToClipboard();
1313
1313
  const jsonString = JSON.stringify(data, null, 2);
1314
1314
  const handleCopy = () => {
1315
- navigator.clipboard.writeText(jsonString);
1316
- setCopied(true);
1317
- setTimeout(() => setCopied(false), 1200);
1315
+ copy(jsonString);
1318
1316
  };
1319
1317
  return /* @__PURE__ */ jsxs16("div", {
1320
1318
  className: cn("group rounded-lg border border-border overflow-hidden bg-muted/30", className),
@@ -1496,7 +1494,6 @@ import { highlight as highlight2, Pre as Pre2 } from "codehike/code";
1496
1494
 
1497
1495
  // src/docskit/code.copy.tsx
1498
1496
  import { Check as Check5, Copy as Copy5 } from "lucide-react";
1499
- import { useState as useState8 } from "react";
1500
1497
  import { jsx as jsx28 } from "react/jsx-runtime";
1501
1498
 
1502
1499
  function CopyButton({
@@ -1504,7 +1501,7 @@ function CopyButton({
1504
1501
  className,
1505
1502
  variant = "floating"
1506
1503
  }) {
1507
- const [copied, setCopied] = useState8(false);
1504
+ const [copied, copy] = useCopyToClipboard();
1508
1505
  return /* @__PURE__ */ jsx28("button", {
1509
1506
  type: "button",
1510
1507
  className: cn("cursor-pointer transition-opacity duration-200", variant === "floating" && [
@@ -1512,11 +1509,7 @@ function CopyButton({
1512
1509
  "rounded border border-dk-border bg-dk-background",
1513
1510
  "opacity-0 group-hover:opacity-100"
1514
1511
  ], variant === "inline" && "rounded", className),
1515
- onClick: () => {
1516
- navigator.clipboard.writeText(text);
1517
- setCopied(true);
1518
- setTimeout(() => setCopied(false), 1200);
1519
- },
1512
+ onClick: () => copy(text),
1520
1513
  "aria-label": "Copy to clipboard",
1521
1514
  children: copied ? /* @__PURE__ */ jsx28(Check5, {
1522
1515
  size: 16,
@@ -1786,12 +1779,12 @@ import {
1786
1779
  Inline,
1787
1780
  Pre as Pre3
1788
1781
  } from "codehike/code";
1789
- import { useEffect as useEffect3, useState as useState9 } from "react";
1782
+ import { useEffect as useEffect3, useState as useState7 } from "react";
1790
1783
  import { jsx as jsx33, jsxs as jsxs19 } from "react/jsx-runtime";
1791
1784
 
1792
1785
  function ClientDocsKitCode(props) {
1793
1786
  const { codeblock, handlers: extraHandlers, className: wrapperClassName } = props;
1794
- const [highlighted, setHighlighted] = useState9(null);
1787
+ const [highlighted, setHighlighted] = useState7(null);
1795
1788
  const { title, flags } = extractFlags2(codeblock);
1796
1789
  const options = flagsToOptions(flags);
1797
1790
  useEffect3(() => {
@@ -1860,7 +1853,7 @@ function ClientDocsKitCode(props) {
1860
1853
  }
1861
1854
  function ClientTerminal(props) {
1862
1855
  const { codeblock, handlers: extraHandlers } = props;
1863
- const [highlighted, setHighlighted] = useState9(null);
1856
+ const [highlighted, setHighlighted] = useState7(null);
1864
1857
  const { flags } = extractFlagsSimple(codeblock);
1865
1858
  const options = flagsToOptions(flags);
1866
1859
  useEffect3(() => {
@@ -1930,7 +1923,7 @@ function ClientTerminal(props) {
1930
1923
  });
1931
1924
  }
1932
1925
  function ClientInlineCode({ codeblock }) {
1933
- const [highlighted, setHighlighted] = useState9(null);
1926
+ const [highlighted, setHighlighted] = useState7(null);
1934
1927
  useEffect3(() => {
1935
1928
  let cancelled = false;
1936
1929
  highlight3(codeblock, theme).then((result) => {
@@ -1965,7 +1958,7 @@ function extractFlagsSimple(codeblock) {
1965
1958
  }
1966
1959
  function ClientCode(props) {
1967
1960
  const { codeblocks, flags: groupFlags, storage } = props;
1968
- const [highlighted, setHighlighted] = useState9(null);
1961
+ const [highlighted, setHighlighted] = useState7(null);
1969
1962
  const groupOptions = flagsToOptions(groupFlags?.startsWith("-") ? groupFlags.slice(1) : groupFlags);
1970
1963
  const _codeBlocksKey = codeblocks.map((b) => `${b.value}|${b.lang}|${b.meta}`).join("::");
1971
1964
  useEffect3(() => {
@@ -2109,7 +2102,7 @@ import {
2109
2102
  Pre as Pre4
2110
2103
  } from "codehike/code";
2111
2104
  import { ChevronDown as ChevronDown3, ChevronUp } from "lucide-react";
2112
- import { useEffect as useEffect4, useState as useState10 } from "react";
2105
+ import { useEffect as useEffect4, useState as useState8 } from "react";
2113
2106
  import { jsx as jsx34, jsxs as jsxs20 } from "react/jsx-runtime";
2114
2107
 
2115
2108
  function StackedChevrons({ isOpen, className }) {
@@ -2135,8 +2128,8 @@ function ClientDiffCode(props) {
2135
2128
  className: wrapperClassName,
2136
2129
  defaultOpen = true
2137
2130
  } = props;
2138
- const [highlighted, setHighlighted] = useState10(null);
2139
- const [isOpen, setIsOpen] = useState10(defaultOpen);
2131
+ const [highlighted, setHighlighted] = useState8(null);
2132
+ const [isOpen, setIsOpen] = useState8(defaultOpen);
2140
2133
  const { title, flags } = extractFlags3(codeblock);
2141
2134
  const options = flagsToOptions(flags);
2142
2135
  const filename = filenameProp || title || "file";
@@ -2266,7 +2259,7 @@ async function DocsKitInlineCode({
2266
2259
  });
2267
2260
  }
2268
2261
  // src/docskit/code.package-install.tsx
2269
- import { useState as useState11 } from "react";
2262
+ import { useState as useState9 } from "react";
2270
2263
  import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
2271
2264
 
2272
2265
  var managerLabels = {
@@ -2319,7 +2312,7 @@ function PackageInstall({
2319
2312
  managers = ["npm", "bun", "pnpm", "yarn"],
2320
2313
  copyButton = true
2321
2314
  }) {
2322
- const [activeManager, setActiveManager] = useState11(managers[0]);
2315
+ const [activeManager, setActiveManager] = useState9(managers[0]);
2323
2316
  const command = getInstallCommand(activeManager, pkg, { dev, global: isGlobal });
2324
2317
  return /* @__PURE__ */ jsxs21("div", {
2325
2318
  className: "group rounded overflow-hidden border border-dk-border flex flex-col my-4 not-prose",
@@ -2539,8 +2532,163 @@ function WithNotes({ children, ...rest }) {
2539
2532
  children
2540
2533
  });
2541
2534
  }
2535
+ // src/docskit/code.tabs-legacy.tsx
2536
+ import { Check as Check6, Copy as Copy6 } from "lucide-react";
2537
+ import { useState as useState10 } from "react";
2538
+ import { jsx as jsx40, jsxs as jsxs23 } from "react/jsx-runtime";
2539
+
2540
+ function CodeTabs({
2541
+ tabs,
2542
+ defaultIndex = 0,
2543
+ sticky = false,
2544
+ className
2545
+ }) {
2546
+ const [activeIndex, setActiveIndex] = useState10(defaultIndex);
2547
+ const [copied, copy] = useCopyToClipboard();
2548
+ const activeTab = tabs[activeIndex];
2549
+ const handleCopy = () => {
2550
+ if (!activeTab)
2551
+ return;
2552
+ copy(activeTab.code);
2553
+ };
2554
+ if (!tabs.length)
2555
+ return null;
2556
+ return /* @__PURE__ */ jsxs23("div", {
2557
+ className: cn("group rounded-lg border border-dk-border bg-dk-background overflow-hidden", "selection:bg-dk-selection selection:text-current", className),
2558
+ children: [
2559
+ /* @__PURE__ */ jsxs23("div", {
2560
+ className: cn("flex items-center border-b border-dk-border bg-dk-tabs-background", sticky && "sticky top-0 z-10"),
2561
+ children: [
2562
+ /* @__PURE__ */ jsx40("div", {
2563
+ className: "flex-1 flex items-stretch",
2564
+ children: tabs.map((tab, index) => /* @__PURE__ */ jsx40("button", {
2565
+ type: "button",
2566
+ onClick: () => setActiveIndex(index),
2567
+ 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"),
2568
+ children: tab.label
2569
+ }, tab.label))
2570
+ }),
2571
+ /* @__PURE__ */ jsx40("button", {
2572
+ type: "button",
2573
+ onClick: handleCopy,
2574
+ 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"),
2575
+ "aria-label": "Copy code",
2576
+ children: copied ? /* @__PURE__ */ jsx40(Check6, {
2577
+ size: 16
2578
+ }) : /* @__PURE__ */ jsx40(Copy6, {
2579
+ size: 16
2580
+ })
2581
+ })
2582
+ ]
2583
+ }),
2584
+ /* @__PURE__ */ jsx40("div", {
2585
+ className: "bg-dk-background",
2586
+ children: activeTab?.content
2587
+ })
2588
+ ]
2589
+ });
2590
+ }
2591
+ // src/docskit/import-section.tsx
2592
+ import { Check as Check7, Copy as Copy7 } from "lucide-react";
2593
+ import { jsx as jsx41, jsxs as jsxs24 } from "react/jsx-runtime";
2594
+
2595
+ function ImportSection({ importStatement, className }) {
2596
+ const [copied, copy] = useCopyToClipboard();
2597
+ const handleCopy = () => {
2598
+ copy(importStatement);
2599
+ };
2600
+ return /* @__PURE__ */ jsxs24("div", {
2601
+ className: cn("group flex items-center justify-between gap-3", "rounded-lg border border-border bg-muted/30 px-4 py-3", className),
2602
+ children: [
2603
+ /* @__PURE__ */ jsx41("code", {
2604
+ className: "font-mono text-sm text-foreground overflow-x-auto",
2605
+ children: importStatement
2606
+ }),
2607
+ /* @__PURE__ */ jsx41("button", {
2608
+ type: "button",
2609
+ onClick: handleCopy,
2610
+ 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"),
2611
+ "aria-label": "Copy import statement",
2612
+ children: copied ? /* @__PURE__ */ jsx41(Check7, {
2613
+ size: 16
2614
+ }) : /* @__PURE__ */ jsx41(Copy7, {
2615
+ size: 16
2616
+ })
2617
+ })
2618
+ ]
2619
+ });
2620
+ }
2621
+ // src/docskit/type-badge.tsx
2622
+ import { cva as cva2 } from "class-variance-authority";
2623
+ import * as React9 from "react";
2624
+ import { jsx as jsx42 } from "react/jsx-runtime";
2625
+ var typeBadgeVariants = cva2("font-mono text-sm", {
2626
+ variants: {
2627
+ typeColor: {
2628
+ string: "text-emerald-600 dark:text-emerald-400",
2629
+ number: "text-blue-600 dark:text-blue-400",
2630
+ boolean: "text-amber-600 dark:text-amber-400",
2631
+ null: "text-gray-500 dark:text-gray-400",
2632
+ undefined: "text-gray-500 dark:text-gray-400",
2633
+ object: "text-purple-600 dark:text-purple-400",
2634
+ array: "text-cyan-600 dark:text-cyan-400",
2635
+ function: "text-fuchsia-600 dark:text-fuchsia-400",
2636
+ union: "text-orange-600 dark:text-orange-400",
2637
+ generic: "text-rose-600 dark:text-rose-400",
2638
+ default: "text-muted-foreground"
2639
+ }
2640
+ },
2641
+ defaultVariants: {
2642
+ typeColor: "default"
2643
+ }
2644
+ });
2645
+ function detectTypeColor(type) {
2646
+ const normalized = type.toLowerCase().trim();
2647
+ if (normalized === "string" || normalized.startsWith('"') || normalized.startsWith("'")) {
2648
+ return "string";
2649
+ }
2650
+ if (normalized === "number" || /^\d+$/.test(normalized)) {
2651
+ return "number";
2652
+ }
2653
+ if (normalized === "boolean" || normalized === "true" || normalized === "false") {
2654
+ return "boolean";
2655
+ }
2656
+ if (normalized === "null") {
2657
+ return "null";
2658
+ }
2659
+ if (normalized === "undefined" || normalized === "void") {
2660
+ return "undefined";
2661
+ }
2662
+ if (normalized === "object" || normalized.startsWith("{")) {
2663
+ return "object";
2664
+ }
2665
+ if (normalized.endsWith("[]") || normalized.startsWith("array")) {
2666
+ return "array";
2667
+ }
2668
+ if (normalized.startsWith("(") || normalized.includes("=>") || normalized.startsWith("function")) {
2669
+ return "function";
2670
+ }
2671
+ if (normalized.includes("|")) {
2672
+ return "union";
2673
+ }
2674
+ if (normalized.includes("<") && normalized.includes(">")) {
2675
+ return "generic";
2676
+ }
2677
+ return "default";
2678
+ }
2679
+ var TypeBadge = React9.forwardRef(({ className, type, typeColor, ...props }, ref) => {
2680
+ const color2 = typeColor ?? detectTypeColor(type);
2681
+ return /* @__PURE__ */ jsx42("span", {
2682
+ ref,
2683
+ className: cn(typeBadgeVariants({ typeColor: color2 }), className),
2684
+ ...props,
2685
+ children: type
2686
+ });
2687
+ });
2688
+ TypeBadge.displayName = "TypeBadge";
2542
2689
  export {
2543
2690
  wordWrap,
2691
+ typeBadgeVariants,
2544
2692
  tooltip,
2545
2693
  toCodeGroup,
2546
2694
  theme,
@@ -2557,6 +2705,7 @@ export {
2557
2705
  addDocsKit,
2558
2706
  WithNotes,
2559
2707
  WithHover,
2708
+ TypeBadge,
2560
2709
  TooltipLink,
2561
2710
  TerminalSkeleton,
2562
2711
  Terminal,
@@ -2571,6 +2720,7 @@ export {
2571
2720
  MultiCode,
2572
2721
  LanguageSelector,
2573
2722
  InlineCodeSkeleton,
2723
+ ImportSection,
2574
2724
  HoverLink,
2575
2725
  EndpointHeader,
2576
2726
  EndpointBadge,
@@ -2578,6 +2728,7 @@ export {
2578
2728
  DocsKitCode,
2579
2729
  CopyButton,
2580
2730
  CodeTabsSkeleton,
2731
+ CodeTabs,
2581
2732
  CodeIcon,
2582
2733
  CodeGroup,
2583
2734
  CodeBlockSkeleton,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/ui",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "UI primitives and components for OpenPkg documentation",
5
5
  "homepage": "https://github.com/ryanwaits/openpkg-ts#readme",
6
6
  "repository": {
@@ -11,13 +11,10 @@
11
11
  "type": "module",
12
12
  "sideEffects": false,
13
13
  "files": [
14
- "dist"
14
+ "dist",
15
+ "src/styles"
15
16
  ],
16
17
  "exports": {
17
- "./api": {
18
- "types": "./dist/api/index.d.ts",
19
- "import": "./dist/api/index.js"
20
- },
21
18
  "./badge": {
22
19
  "types": "./dist/badge/index.d.ts",
23
20
  "import": "./dist/badge/index.js"
@@ -30,7 +27,8 @@
30
27
  "types": "./dist/lib/utils.d.ts",
31
28
  "import": "./dist/lib/utils.js"
32
29
  },
33
- "./styles/tokens.css": "./src/styles/tokens.css"
30
+ "./styles/tokens.css": "./src/styles/tokens.css",
31
+ "./styles/docskit.css": "./src/styles/docskit.css"
34
32
  },
35
33
  "scripts": {
36
34
  "build": "bunup",
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Docskit code block styling for Tailwind v4 consumers.
3
+ * Includes CodeHike theme variables, dk-* Tailwind color mappings,
4
+ * and selection utility.
5
+ *
6
+ * Usage: @import '@openpkg-ts/ui/styles/docskit.css';
7
+ */
8
+
9
+ /* CodeHike github-from-css theme (dark) */
10
+ :root {
11
+ --ch-0: dark;
12
+ --ch-1: #8b949e;
13
+ --ch-2: #79c0ff;
14
+ --ch-3: #ffa657;
15
+ --ch-4: #c9d1d9;
16
+ --ch-5: #d2a8ff;
17
+ --ch-6: #7ee787;
18
+ --ch-7: #ff7b72;
19
+ --ch-8: #a5d6ff;
20
+ --ch-9: #ffa198;
21
+ --ch-10: #f0f6fc;
22
+ --ch-11: #490202;
23
+ --ch-12: #04260f;
24
+ --ch-13: #5a1e02;
25
+ --ch-14: #161b22;
26
+ --ch-15: #8b949e;
27
+ --ch-16: #0d1117;
28
+ --ch-17: #6e76811a;
29
+ --ch-18: #ffffff0b;
30
+ --ch-19: #3794ff;
31
+ --ch-20: #264f78;
32
+ --ch-21: #1f6feb;
33
+ --ch-22: #010409;
34
+ --ch-23: #30363d;
35
+ --ch-24: #6e7681;
36
+ --ch-25: #6e768166;
37
+ --ch-26: #0d1117e6;
38
+ }
39
+
40
+ /* CodeHike github-from-css theme (light) */
41
+ [data-theme="light"] {
42
+ --ch-0: light;
43
+ --ch-1: #6e7781;
44
+ --ch-2: #0550ae;
45
+ --ch-3: #953800;
46
+ --ch-4: #24292f;
47
+ --ch-5: #8250df;
48
+ --ch-6: #116329;
49
+ --ch-7: #cf222e;
50
+ --ch-8: #0a3069;
51
+ --ch-9: #82071e;
52
+ --ch-10: #f6f8fa;
53
+ --ch-11: #ffebe9;
54
+ --ch-12: #dafbe1;
55
+ --ch-13: #ffd8b5;
56
+ --ch-14: #eaeef2;
57
+ --ch-15: #57606a;
58
+ --ch-16: #ffffff;
59
+ --ch-17: #eaeef280;
60
+ --ch-18: #fdff0033;
61
+ --ch-19: #1a85ff;
62
+ --ch-20: #add6ff;
63
+ --ch-21: #0969da;
64
+ --ch-22: #f6f8fa;
65
+ --ch-23: #d0d7de;
66
+ --ch-24: #8c959f;
67
+ --ch-25: #afb8c133;
68
+ --ch-26: #ffffffe6;
69
+ }
70
+
71
+ /* dk-* Tailwind v4 color theme (maps to --ch-* vars) */
72
+ @theme {
73
+ --color-dk-background: var(--ch-16);
74
+ --color-dk-border: var(--ch-23);
75
+ --color-dk-tabs-background: var(--ch-22);
76
+ --color-dk-tab-inactive-foreground: var(--ch-15);
77
+ --color-dk-tab-active-foreground: var(--ch-4);
78
+ --color-dk-selection: var(--ch-20);
79
+ --color-dk-line-number: var(--ch-24);
80
+ --color-dk-active-border: var(--ch-3);
81
+ }
82
+
83
+ /* Selection utility — Tailwind can't auto-generate this */
84
+ @layer utilities {
85
+ .selection\:bg-dk-selection::selection,
86
+ .selection\:bg-dk-selection *::selection {
87
+ background-color: var(--ch-20);
88
+ }
89
+ }
@@ -0,0 +1,2 @@
1
+ // Export styles path for consumers
2
+ export const tokensPath = '@openpkg-ts/ui/styles/tokens.css';