@openpkg-ts/ui 0.1.5 → 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.
- package/dist/docskit/index.d.ts +57 -1
- package/dist/docskit/index.js +205 -52
- package/package.json +5 -7
- package/src/styles/docskit.css +89 -0
- package/src/styles/index.ts +2 -0
- package/src/styles/tokens.css +232 -0
- package/dist/api/index.d.ts +0 -114
- package/dist/api/index.js +0 -435
package/dist/docskit/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 };
|
package/dist/docskit/index.js
CHANGED
|
@@ -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
|
|
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] =
|
|
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] =
|
|
818
|
-
const [copied,
|
|
819
|
-
const [highlighted, setHighlighted] =
|
|
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
|
-
|
|
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,
|
|
1043
|
+
const [copied, copy] = useCopyToClipboard();
|
|
1031
1044
|
const handleCopy = () => {
|
|
1032
|
-
|
|
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,
|
|
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
|
-
const _nestedCount = hasNested ? Object.keys(schema.properties).length : 0;
|
|
1079
|
-
const handleCopy = () => {
|
|
1080
|
-
navigator.clipboard.writeText(name);
|
|
1081
|
-
setCopied(true);
|
|
1082
|
-
setTimeout(() => setCopied(false), 1200);
|
|
1083
|
-
};
|
|
1089
|
+
const _nestedCount = hasNested && schema.properties ? Object.keys(schema.properties).length : 0;
|
|
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:
|
|
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,
|
|
1180
|
+
const [copied, copy] = useCopyToClipboard();
|
|
1175
1181
|
const hasNested = children?.properties && Object.keys(children.properties).length > 0;
|
|
1176
|
-
const _nestedCount = hasNested ? Object.keys(children.properties).length : 0;
|
|
1177
|
-
const handleCopy = () => {
|
|
1178
|
-
navigator.clipboard.writeText(name);
|
|
1179
|
-
setCopied(true);
|
|
1180
|
-
setTimeout(() => setCopied(false), 1200);
|
|
1181
|
-
};
|
|
1182
|
+
const _nestedCount = hasNested && children?.properties ? Object.keys(children.properties).length : 0;
|
|
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:
|
|
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,
|
|
1312
|
+
const [copied, copy] = useCopyToClipboard();
|
|
1313
1313
|
const jsonString = JSON.stringify(data, null, 2);
|
|
1314
1314
|
const handleCopy = () => {
|
|
1315
|
-
|
|
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,
|
|
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
|
|
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] =
|
|
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] =
|
|
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] =
|
|
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] =
|
|
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(() => {
|
|
@@ -2004,6 +1997,8 @@ function ClientCode(props) {
|
|
|
2004
1997
|
}
|
|
2005
1998
|
if (codeblocks.length === 1) {
|
|
2006
1999
|
const tab = highlighted.get(0);
|
|
2000
|
+
if (!tab)
|
|
2001
|
+
return null;
|
|
2007
2002
|
const handlers = getHandlers(tab.options);
|
|
2008
2003
|
const { background: _background, ...highlightedStyle } = tab.highlighted.style;
|
|
2009
2004
|
return /* @__PURE__ */ jsxs19("div", {
|
|
@@ -2107,7 +2102,7 @@ import {
|
|
|
2107
2102
|
Pre as Pre4
|
|
2108
2103
|
} from "codehike/code";
|
|
2109
2104
|
import { ChevronDown as ChevronDown3, ChevronUp } from "lucide-react";
|
|
2110
|
-
import { useEffect as useEffect4, useState as
|
|
2105
|
+
import { useEffect as useEffect4, useState as useState8 } from "react";
|
|
2111
2106
|
import { jsx as jsx34, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2112
2107
|
|
|
2113
2108
|
function StackedChevrons({ isOpen, className }) {
|
|
@@ -2133,8 +2128,8 @@ function ClientDiffCode(props) {
|
|
|
2133
2128
|
className: wrapperClassName,
|
|
2134
2129
|
defaultOpen = true
|
|
2135
2130
|
} = props;
|
|
2136
|
-
const [highlighted, setHighlighted] =
|
|
2137
|
-
const [isOpen, setIsOpen] =
|
|
2131
|
+
const [highlighted, setHighlighted] = useState8(null);
|
|
2132
|
+
const [isOpen, setIsOpen] = useState8(defaultOpen);
|
|
2138
2133
|
const { title, flags } = extractFlags3(codeblock);
|
|
2139
2134
|
const options = flagsToOptions(flags);
|
|
2140
2135
|
const filename = filenameProp || title || "file";
|
|
@@ -2264,7 +2259,7 @@ async function DocsKitInlineCode({
|
|
|
2264
2259
|
});
|
|
2265
2260
|
}
|
|
2266
2261
|
// src/docskit/code.package-install.tsx
|
|
2267
|
-
import { useState as
|
|
2262
|
+
import { useState as useState9 } from "react";
|
|
2268
2263
|
import { jsx as jsx36, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
2269
2264
|
|
|
2270
2265
|
var managerLabels = {
|
|
@@ -2317,7 +2312,7 @@ function PackageInstall({
|
|
|
2317
2312
|
managers = ["npm", "bun", "pnpm", "yarn"],
|
|
2318
2313
|
copyButton = true
|
|
2319
2314
|
}) {
|
|
2320
|
-
const [activeManager, setActiveManager] =
|
|
2315
|
+
const [activeManager, setActiveManager] = useState9(managers[0]);
|
|
2321
2316
|
const command = getInstallCommand(activeManager, pkg, { dev, global: isGlobal });
|
|
2322
2317
|
return /* @__PURE__ */ jsxs21("div", {
|
|
2323
2318
|
className: "group rounded overflow-hidden border border-dk-border flex flex-col my-4 not-prose",
|
|
@@ -2537,8 +2532,163 @@ function WithNotes({ children, ...rest }) {
|
|
|
2537
2532
|
children
|
|
2538
2533
|
});
|
|
2539
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";
|
|
2540
2689
|
export {
|
|
2541
2690
|
wordWrap,
|
|
2691
|
+
typeBadgeVariants,
|
|
2542
2692
|
tooltip,
|
|
2543
2693
|
toCodeGroup,
|
|
2544
2694
|
theme,
|
|
@@ -2555,6 +2705,7 @@ export {
|
|
|
2555
2705
|
addDocsKit,
|
|
2556
2706
|
WithNotes,
|
|
2557
2707
|
WithHover,
|
|
2708
|
+
TypeBadge,
|
|
2558
2709
|
TooltipLink,
|
|
2559
2710
|
TerminalSkeleton,
|
|
2560
2711
|
Terminal,
|
|
@@ -2569,6 +2720,7 @@ export {
|
|
|
2569
2720
|
MultiCode,
|
|
2570
2721
|
LanguageSelector,
|
|
2571
2722
|
InlineCodeSkeleton,
|
|
2723
|
+
ImportSection,
|
|
2572
2724
|
HoverLink,
|
|
2573
2725
|
EndpointHeader,
|
|
2574
2726
|
EndpointBadge,
|
|
@@ -2576,6 +2728,7 @@ export {
|
|
|
2576
2728
|
DocsKitCode,
|
|
2577
2729
|
CopyButton,
|
|
2578
2730
|
CodeTabsSkeleton,
|
|
2731
|
+
CodeTabs,
|
|
2579
2732
|
CodeIcon,
|
|
2580
2733
|
CodeGroup,
|
|
2581
2734
|
CodeBlockSkeleton,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpkg-ts/ui",
|
|
3
|
-
"version": "0.1.
|
|
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
|
+
}
|