@contractspec/lib.design-system 0.0.0-canary-20260114030712 → 0.0.0-canary-20260119224015
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/components/atoms/Cta.d.ts.map +1 -1
- package/dist/components/atoms/Cta.js +0 -2
- package/dist/components/atoms/Cta.js.map +1 -1
- package/dist/components/molecules/CodeBlock/CodeBlock.d.ts +3 -2
- package/dist/components/molecules/CodeBlock/CodeBlock.d.ts.map +1 -1
- package/dist/components/molecules/CodeBlock/CodeBlock.js +6 -2
- package/dist/components/molecules/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/components/molecules/CodeBlock/types.d.ts +2 -0
- package/dist/components/molecules/CommandTabs/CommandTabs.d.ts +1 -0
- package/dist/components/molecules/CommandTabs/CommandTabs.d.ts.map +1 -1
- package/dist/components/molecules/CommandTabs/CommandTabs.js +9 -2
- package/dist/components/molecules/CommandTabs/CommandTabs.js.map +1 -1
- package/dist/components/molecules/CommandTabs/types.d.ts +6 -1
- package/dist/components/molecules/CommandTabs/types.d.ts.map +1 -1
- package/dist/components/molecules/CopyButton/CopyButton.d.ts +2 -2
- package/dist/components/molecules/CopyButton/CopyButton.js +2 -2
- package/dist/components/molecules/CopyButton/CopyButton.js.map +1 -1
- package/dist/components/molecules/InstallCommand/InstallCommand.d.ts +1 -0
- package/dist/components/molecules/InstallCommand/InstallCommand.d.ts.map +1 -1
- package/dist/components/molecules/InstallCommand/InstallCommand.js +2 -1
- package/dist/components/molecules/InstallCommand/InstallCommand.js.map +1 -1
- package/dist/components/molecules/InstallCommand/types.d.ts +7 -1
- package/dist/components/molecules/InstallCommand/types.d.ts.map +1 -1
- package/dist/components/molecules/NavItemCard.js +1 -0
- package/dist/components/molecules/NavItemCard.js.map +1 -1
- package/dist/components/molecules/SkeletonBlock/index.web.d.ts +2 -2
- package/dist/components/molecules/SkeletonCircle/index.web.d.ts +2 -2
- package/dist/components/molecules/SkeletonList/index.web.d.ts +2 -2
- package/dist/components/templates/lists/ListPageTemplate/index.web.d.ts +2 -2
- package/dist/renderers/form-contract.d.ts +2 -2
- package/dist/types/navigation.d.ts +1 -0
- package/dist/types/navigation.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cta.d.ts","names":[],"sources":["../../../src/components/atoms/Cta.tsx"],"sourcesContent":[],"mappings":";;;;;;;;cAsBa,KAAG,KAAA,CAAA,0BAAA,
|
|
1
|
+
{"version":3,"file":"Cta.d.ts","names":[],"sources":["../../../src/components/atoms/Cta.tsx"],"sourcesContent":[],"mappings":";;;;;;;;cAsBa,KAAG,KAAA,CAAA,0BAAA,KAiEf,uCAAA,CAjEe,WAAA;EAHD,QAAM,iBAAA;;;;EAGL,OAAA,CAAA,EAAA,GAAA,GAAA,IAAA;EAAA,SAAA,CAAA,EAAA,GAAA,GAAA,IAAA;;;;;;;;;;;;;aAHD,KAAA,CAAM"}
|
|
@@ -28,8 +28,6 @@ const Cta = React.forwardRef(({ capture, ctaName, as = "button", href, onClick,
|
|
|
28
28
|
const handleClick = (e) => {
|
|
29
29
|
if (ctaName) try {
|
|
30
30
|
if (capture) capture(ctaName);
|
|
31
|
-
const ph = globalThis.posthog;
|
|
32
|
-
if (ph && typeof ph.capture === "function") ph.capture("cta_click", { cta: ctaName });
|
|
33
31
|
} catch {}
|
|
34
32
|
onClick?.(e);
|
|
35
33
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cta.js","names":[],"sources":["../../../src/components/atoms/Cta.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Button, type ButtonProps } from './Button';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ButtonLink } from './ButtonLink';\n\nconst _ctaVariants = cva('', {\n variants: {\n size: { sm: 'sm', md: 'md', lg: 'lg', touch: 'touch' },\n emphasis: { default: 'default', subtle: 'secondary', strong: 'default' },\n },\n defaultVariants: { size: 'touch', emphasis: 'default' },\n});\n\nexport type CtaProps = ButtonProps &\n VariantProps<typeof _ctaVariants> & {\n capture?: (cta: string) => void;\n ctaName?: string;\n as?: 'button' | 'a';\n href?: string;\n children?: React.ReactNode;\n };\n\nexport const Cta = React.forwardRef<\n HTMLButtonElement | HTMLAnchorElement,\n CtaProps\n>(\n (\n {\n capture,\n ctaName,\n as = 'button',\n href,\n onClick,\n size = 'touch',\n emphasis = 'default',\n children,\n ...props\n },\n _ref\n ) => {\n const handleClick: React.MouseEventHandler<\n HTMLButtonElement | HTMLAnchorElement\n > = (e) => {\n if (ctaName) {\n try {\n if (capture) capture(ctaName);\n
|
|
1
|
+
{"version":3,"file":"Cta.js","names":[],"sources":["../../../src/components/atoms/Cta.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Button, type ButtonProps } from './Button';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { ButtonLink } from './ButtonLink';\n\nconst _ctaVariants = cva('', {\n variants: {\n size: { sm: 'sm', md: 'md', lg: 'lg', touch: 'touch' },\n emphasis: { default: 'default', subtle: 'secondary', strong: 'default' },\n },\n defaultVariants: { size: 'touch', emphasis: 'default' },\n});\n\nexport type CtaProps = ButtonProps &\n VariantProps<typeof _ctaVariants> & {\n capture?: (cta: string) => void;\n ctaName?: string;\n as?: 'button' | 'a';\n href?: string;\n children?: React.ReactNode;\n };\n\nexport const Cta = React.forwardRef<\n HTMLButtonElement | HTMLAnchorElement,\n CtaProps\n>(\n (\n {\n capture,\n ctaName,\n as = 'button',\n href,\n onClick,\n size = 'touch',\n emphasis = 'default',\n children,\n ...props\n },\n _ref\n ) => {\n const handleClick: React.MouseEventHandler<\n HTMLButtonElement | HTMLAnchorElement\n > = (e) => {\n if (ctaName) {\n try {\n if (capture) capture(ctaName);\n } catch {\n /* noop */\n }\n }\n onClick?.(e as unknown as React.MouseEvent<HTMLButtonElement>);\n };\n\n const uiSize = size as ButtonProps['size'];\n const uiVariant = (\n emphasis === 'subtle' ? 'secondary' : 'default'\n ) as ButtonProps['variant'];\n\n if (as === 'a') {\n return (\n <ButtonLink\n size={uiSize}\n variant={uiVariant}\n {...props}\n href={href}\n onClick={\n handleClick as unknown as React.MouseEventHandler<HTMLAnchorElement>\n }\n >\n {children}\n </ButtonLink>\n );\n }\n\n return (\n <Button\n size={uiSize}\n variant={uiVariant}\n onClick={\n handleClick as unknown as React.MouseEventHandler<HTMLButtonElement>\n }\n {...props}\n >\n {children}\n </Button>\n );\n }\n);\nCta.displayName = 'Cta';\n"],"mappings":";;;;;;;AAKqB,IAAI,IAAI;CAC3B,UAAU;EACR,MAAM;GAAE,IAAI;GAAM,IAAI;GAAM,IAAI;GAAM,OAAO;GAAS;EACtD,UAAU;GAAE,SAAS;GAAW,QAAQ;GAAa,QAAQ;GAAW;EACzE;CACD,iBAAiB;EAAE,MAAM;EAAS,UAAU;EAAW;CACxD,CAAC;AAWF,MAAa,MAAM,MAAM,YAKrB,EACE,SACA,SACA,KAAK,UACL,MACA,SACA,OAAO,SACP,WAAW,WACX,UACA,GAAG,SAEL,SACG;CACH,MAAM,eAED,MAAM;AACT,MAAI,QACF,KAAI;AACF,OAAI,QAAS,SAAQ,QAAQ;UACvB;AAIV,YAAU,EAAoD;;CAGhE,MAAM,SAAS;CACf,MAAM,YACJ,aAAa,WAAW,cAAc;AAGxC,KAAI,OAAO,IACT,QACE,oBAAC;EACC,MAAM;EACN,SAAS;EACT,GAAI;EACE;EACN,SACE;EAGD;GACU;AAIjB,QACE,oBAAC;EACC,MAAM;EACN,SAAS;EACT,SACE;EAEF,GAAI;EAEH;GACM;EAGd;AACD,IAAI,cAAc"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CodeBlockProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime115 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/molecules/CodeBlock/CodeBlock.d.ts
|
|
5
5
|
declare function CodeBlock({
|
|
@@ -8,9 +8,10 @@ declare function CodeBlock({
|
|
|
8
8
|
filename,
|
|
9
9
|
showLineNumbers,
|
|
10
10
|
showCopyButton,
|
|
11
|
+
onCopy,
|
|
11
12
|
className,
|
|
12
13
|
...props
|
|
13
|
-
}: CodeBlockProps):
|
|
14
|
+
}: CodeBlockProps): react_jsx_runtime115.JSX.Element;
|
|
14
15
|
//#endregion
|
|
15
16
|
export { CodeBlock };
|
|
16
17
|
//# sourceMappingURL=CodeBlock.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.d.ts","names":[],"sources":["../../../../src/components/molecules/CodeBlock/CodeBlock.tsx"],"sourcesContent":[],"mappings":";;;;iBAOgB,SAAA
|
|
1
|
+
{"version":3,"file":"CodeBlock.d.ts","names":[],"sources":["../../../../src/components/molecules/CodeBlock/CodeBlock.tsx"],"sourcesContent":[],"mappings":";;;;iBAOgB,SAAA;;;;;;;;;GASb,iBAAc,oBAAA,CAAA,GAAA,CAAA"}
|
|
@@ -6,8 +6,11 @@ import { useEffect, useState } from "react";
|
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
|
|
8
8
|
//#region src/components/molecules/CodeBlock/CodeBlock.tsx
|
|
9
|
-
function CodeBlock({ code, language = "typescript", filename, showLineNumbers = false, showCopyButton = true, className, ...props }) {
|
|
9
|
+
function CodeBlock({ code, language = "typescript", filename, showLineNumbers = false, showCopyButton = true, onCopy, className, ...props }) {
|
|
10
10
|
const [highlightedHtml, setHighlightedHtml] = useState(null);
|
|
11
|
+
const handleCopy = () => {
|
|
12
|
+
onCopy?.();
|
|
13
|
+
};
|
|
11
14
|
useEffect(() => {
|
|
12
15
|
let mounted = true;
|
|
13
16
|
async function highlight() {
|
|
@@ -37,7 +40,8 @@ function CodeBlock({ code, language = "typescript", filename, showLineNumbers =
|
|
|
37
40
|
className: "relative",
|
|
38
41
|
children: [showCopyButton && /* @__PURE__ */ jsx(CopyButton, {
|
|
39
42
|
value: code,
|
|
40
|
-
className: "absolute top-3 right-3"
|
|
43
|
+
className: "absolute top-3 right-3",
|
|
44
|
+
onCopy: handleCopy
|
|
41
45
|
}), highlightedHtml ? /* @__PURE__ */ jsx("div", {
|
|
42
46
|
className: cn("overflow-x-auto p-4 font-mono text-[13px] leading-6", "[&_pre]:!m-0 [&_pre]:!bg-transparent [&_pre]:!p-0", "[&_code]:!bg-transparent", showLineNumbers && "line-numbers"),
|
|
43
47
|
dangerouslySetInnerHTML: { __html: highlightedHtml }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeBlock.js","names":[],"sources":["../../../../src/components/molecules/CodeBlock/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { useEffect, useState } from 'react';\nimport { CopyButton } from '../CopyButton';\nimport type { CodeBlockProps } from './types';\n\nexport function CodeBlock({\n code,\n language = 'typescript',\n filename,\n showLineNumbers = false,\n showCopyButton = true,\n className,\n ...props\n}: CodeBlockProps) {\n const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null);\n\n useEffect(() => {\n let mounted = true;\n\n async function highlight() {\n try {\n const { codeToHtml } = await import('shiki');\n const html = await codeToHtml(code, {\n lang: language === 'text' ? 'plaintext' : language,\n // theme: 'github-dark-dimmed',\n theme: 'vitesse-dark',\n });\n if (mounted) {\n setHighlightedHtml(html);\n }\n } catch (err) {\n console.error('Failed to highlight code:', err);\n }\n }\n\n highlight();\n\n return () => {\n mounted = false;\n };\n }, [code, language]);\n\n return (\n <div\n className={cn(\n 'relative overflow-hidden rounded-lg border border-zinc-800 bg-zinc-950',\n className\n )}\n {...props}\n >\n {filename && (\n <div className=\"flex items-center justify-between border-b border-zinc-800 bg-zinc-900/50 px-4 py-2 text-xs text-zinc-400\">\n <span>{filename}</span>\n </div>\n )}\n <div className=\"relative\">\n {showCopyButton && (\n <CopyButton
|
|
1
|
+
{"version":3,"file":"CodeBlock.js","names":[],"sources":["../../../../src/components/molecules/CodeBlock/CodeBlock.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { useEffect, useState } from 'react';\nimport { CopyButton } from '../CopyButton';\nimport type { CodeBlockProps } from './types';\n\nexport function CodeBlock({\n code,\n language = 'typescript',\n filename,\n showLineNumbers = false,\n showCopyButton = true,\n onCopy,\n className,\n ...props\n}: CodeBlockProps) {\n const [highlightedHtml, setHighlightedHtml] = useState<string | null>(null);\n\n const handleCopy = () => {\n onCopy?.();\n };\n\n useEffect(() => {\n let mounted = true;\n\n async function highlight() {\n try {\n const { codeToHtml } = await import('shiki');\n const html = await codeToHtml(code, {\n lang: language === 'text' ? 'plaintext' : language,\n // theme: 'github-dark-dimmed',\n theme: 'vitesse-dark',\n });\n if (mounted) {\n setHighlightedHtml(html);\n }\n } catch (err) {\n console.error('Failed to highlight code:', err);\n }\n }\n\n highlight();\n\n return () => {\n mounted = false;\n };\n }, [code, language]);\n\n return (\n <div\n className={cn(\n 'relative overflow-hidden rounded-lg border border-zinc-800 bg-zinc-950',\n className\n )}\n {...props}\n >\n {filename && (\n <div className=\"flex items-center justify-between border-b border-zinc-800 bg-zinc-900/50 px-4 py-2 text-xs text-zinc-400\">\n <span>{filename}</span>\n </div>\n )}\n <div className=\"relative\">\n {showCopyButton && (\n <CopyButton\n value={code}\n className=\"absolute top-3 right-3\"\n onCopy={handleCopy}\n />\n )}\n {highlightedHtml ? (\n <div\n className={cn(\n 'overflow-x-auto p-4 font-mono text-[13px] leading-6',\n '[&_pre]:!m-0 [&_pre]:!bg-transparent [&_pre]:!p-0',\n '[&_code]:!bg-transparent',\n showLineNumbers && 'line-numbers'\n )}\n dangerouslySetInnerHTML={{ __html: highlightedHtml }}\n />\n ) : (\n <pre\n className={cn(\n 'overflow-x-auto p-4 font-mono text-[13px] leading-6 text-zinc-300',\n showLineNumbers && 'line-numbers'\n )}\n >\n <code>{code}</code>\n </pre>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,UAAU,EACxB,MACA,WAAW,cACX,UACA,kBAAkB,OAClB,iBAAiB,MACjB,QACA,WACA,GAAG,SACc;CACjB,MAAM,CAAC,iBAAiB,sBAAsB,SAAwB,KAAK;CAE3E,MAAM,mBAAmB;AACvB,YAAU;;AAGZ,iBAAgB;EACd,IAAI,UAAU;EAEd,eAAe,YAAY;AACzB,OAAI;IACF,MAAM,EAAE,eAAe,MAAM,OAAO;IACpC,MAAM,OAAO,MAAM,WAAW,MAAM;KAClC,MAAM,aAAa,SAAS,cAAc;KAE1C,OAAO;KACR,CAAC;AACF,QAAI,QACF,oBAAmB,KAAK;YAEnB,KAAK;AACZ,YAAQ,MAAM,6BAA6B,IAAI;;;AAInD,aAAW;AAEX,eAAa;AACX,aAAU;;IAEX,CAAC,MAAM,SAAS,CAAC;AAEpB,QACE,qBAAC;EACC,WAAW,GACT,0EACA,UACD;EACD,GAAI;aAEH,YACC,oBAAC;GAAI,WAAU;aACb,oBAAC,oBAAM,WAAgB;IACnB,EAER,qBAAC;GAAI,WAAU;cACZ,kBACC,oBAAC;IACC,OAAO;IACP,WAAU;IACV,QAAQ;KACR,EAEH,kBACC,oBAAC;IACC,WAAW,GACT,uDACA,qDACA,4BACA,mBAAmB,eACpB;IACD,yBAAyB,EAAE,QAAQ,iBAAiB;KACpD,GAEF,oBAAC;IACC,WAAW,GACT,qEACA,mBAAmB,eACpB;cAED,oBAAC,oBAAM,OAAY;KACf;IAEJ;GACF"}
|
|
@@ -13,6 +13,8 @@ interface CodeBlockProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
13
13
|
showLineNumbers?: boolean;
|
|
14
14
|
/** Whether to show the copy button */
|
|
15
15
|
showCopyButton?: boolean;
|
|
16
|
+
/** Optional callback when copy succeeds */
|
|
17
|
+
onCopy?: () => void;
|
|
16
18
|
}
|
|
17
19
|
//#endregion
|
|
18
20
|
export { CodeBlockProps, CodeLanguage };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandTabs.d.ts","names":[],"sources":["../../../../src/components/molecules/CommandTabs/CommandTabs.tsx"],"sourcesContent":[],"mappings":";;;;iBAUgB,WAAA
|
|
1
|
+
{"version":3,"file":"CommandTabs.d.ts","names":[],"sources":["../../../../src/components/molecules/CommandTabs/CommandTabs.tsx"],"sourcesContent":[],"mappings":";;;;iBAUgB,WAAA;;;;;;GAMb,mBAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -8,7 +8,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
|
|
9
9
|
//#region src/components/molecules/CommandTabs/CommandTabs.tsx
|
|
10
10
|
const STORAGE_KEY = "package-manager-preference";
|
|
11
|
-
function CommandTabs({ commands, initialPreference = "bun", className, ...props }) {
|
|
11
|
+
function CommandTabs({ commands, initialPreference = "bun", className, onCopy, ...props }) {
|
|
12
12
|
const context = usePackageManager();
|
|
13
13
|
const [localSelected, setLocalSelected] = useState(() => {
|
|
14
14
|
return initialPreference;
|
|
@@ -34,6 +34,12 @@ function CommandTabs({ commands, initialPreference = "bun", className, ...props
|
|
|
34
34
|
if (!effectiveSelected) return null;
|
|
35
35
|
const currentCommand = commands[effectiveSelected];
|
|
36
36
|
if (!currentCommand) return null;
|
|
37
|
+
const handleCopy = () => {
|
|
38
|
+
onCopy?.({
|
|
39
|
+
command: currentCommand,
|
|
40
|
+
packageManager: effectiveSelected
|
|
41
|
+
});
|
|
42
|
+
};
|
|
37
43
|
return /* @__PURE__ */ jsxs("div", {
|
|
38
44
|
className: cn("relative rounded-lg border border-zinc-800 bg-zinc-950", className),
|
|
39
45
|
...props,
|
|
@@ -54,7 +60,8 @@ function CommandTabs({ commands, initialPreference = "bun", className, ...props
|
|
|
54
60
|
role: "tabpanel",
|
|
55
61
|
children: [/* @__PURE__ */ jsx(CopyButton, {
|
|
56
62
|
value: currentCommand,
|
|
57
|
-
className: "absolute top-3 right-3"
|
|
63
|
+
className: "absolute top-3 right-3",
|
|
64
|
+
onCopy: handleCopy
|
|
58
65
|
}), /* @__PURE__ */ jsx("pre", {
|
|
59
66
|
className: "overflow-x-auto pr-10 font-mono text-[13px] leading-6 text-white",
|
|
60
67
|
children: /* @__PURE__ */ jsx("code", { children: currentCommand })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandTabs.js","names":[],"sources":["../../../../src/components/molecules/CommandTabs/CommandTabs.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { useEffect, useState } from 'react';\nimport { CopyButton } from '../CopyButton';\nimport { usePackageManager } from '../../providers/PackageManagerProvider';\nimport type { CommandTabsProps, PackageManager } from './types';\n\nconst STORAGE_KEY = 'package-manager-preference';\n\nexport function CommandTabs({\n commands,\n initialPreference = 'bun',\n className,\n ...props\n}: CommandTabsProps) {\n const context = usePackageManager();\n\n const [localSelected, setLocalSelected] = useState<PackageManager>(() => {\n return initialPreference;\n });\n\n // Use context if available, otherwise use local state\n const selected = context?.preference ?? localSelected;\n const setSelected = context?.setPreference ?? setLocalSelected;\n\n // Hydrate preference from localStorage (only if not using context)\n useEffect(() => {\n if (context) return; // Context handles its own persistence\n\n try {\n const saved = localStorage.getItem(STORAGE_KEY) as PackageManager | null;\n if (saved && commands[saved]) {\n setLocalSelected(saved);\n }\n } catch {\n // localStorage not available\n }\n }, [commands, context]);\n\n const handleSelect = (pm: PackageManager) => {\n setSelected(pm);\n\n // Only persist locally if not using context\n if (!context) {\n try {\n localStorage.setItem(STORAGE_KEY, pm);\n } catch {\n // localStorage not available\n }\n }\n };\n\n // Get available package managers from commands\n const packageManagers = Object.keys(commands) as PackageManager[];\n\n // Early return if no commands available\n if (packageManagers.length === 0) return null;\n\n // Use selected if available, otherwise fallback to first available\n const effectiveSelected = commands[selected] ? selected : packageManagers[0];\n if (!effectiveSelected) return null;\n const currentCommand = commands[effectiveSelected];\n if (!currentCommand) return null;\n\n return (\n <div\n className={cn(\n 'relative rounded-lg border border-zinc-800 bg-zinc-950',\n className\n )}\n {...props}\n >\n <div\n className=\"flex items-center border-b border-zinc-800 bg-zinc-900/50 px-2 pt-2\"\n role=\"tablist\"\n aria-label=\"Package manager selection\"\n >\n {packageManagers.map((pm) => (\n <button\n key={pm}\n type=\"button\"\n role=\"tab\"\n aria-selected={effectiveSelected === pm}\n onClick={() => handleSelect(pm)}\n className={cn(\n 'rounded-t-md border-t border-r border-l border-transparent px-4 py-2 text-xs font-medium text-zinc-400',\n 'transition-colors hover:text-zinc-100',\n 'focus:ring-2 focus:ring-zinc-600 focus:ring-offset-1 focus:ring-offset-zinc-900 focus:outline-none',\n effectiveSelected === pm &&\n 'border-zinc-800 bg-zinc-950 text-zinc-100'\n )}\n >\n {pm}\n </button>\n ))}\n </div>\n <div className=\"relative p-4\" role=\"tabpanel\">\n <CopyButton
|
|
1
|
+
{"version":3,"file":"CommandTabs.js","names":[],"sources":["../../../../src/components/molecules/CommandTabs/CommandTabs.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { useEffect, useState } from 'react';\nimport { CopyButton } from '../CopyButton';\nimport { usePackageManager } from '../../providers/PackageManagerProvider';\nimport type { CommandTabsProps, PackageManager } from './types';\n\nconst STORAGE_KEY = 'package-manager-preference';\n\nexport function CommandTabs({\n commands,\n initialPreference = 'bun',\n className,\n onCopy,\n ...props\n}: CommandTabsProps) {\n const context = usePackageManager();\n\n const [localSelected, setLocalSelected] = useState<PackageManager>(() => {\n return initialPreference;\n });\n\n // Use context if available, otherwise use local state\n const selected = context?.preference ?? localSelected;\n const setSelected = context?.setPreference ?? setLocalSelected;\n\n // Hydrate preference from localStorage (only if not using context)\n useEffect(() => {\n if (context) return; // Context handles its own persistence\n\n try {\n const saved = localStorage.getItem(STORAGE_KEY) as PackageManager | null;\n if (saved && commands[saved]) {\n setLocalSelected(saved);\n }\n } catch {\n // localStorage not available\n }\n }, [commands, context]);\n\n const handleSelect = (pm: PackageManager) => {\n setSelected(pm);\n\n // Only persist locally if not using context\n if (!context) {\n try {\n localStorage.setItem(STORAGE_KEY, pm);\n } catch {\n // localStorage not available\n }\n }\n };\n\n // Get available package managers from commands\n const packageManagers = Object.keys(commands) as PackageManager[];\n\n // Early return if no commands available\n if (packageManagers.length === 0) return null;\n\n // Use selected if available, otherwise fallback to first available\n const effectiveSelected = commands[selected] ? selected : packageManagers[0];\n if (!effectiveSelected) return null;\n const currentCommand = commands[effectiveSelected];\n if (!currentCommand) return null;\n\n const handleCopy = () => {\n onCopy?.({\n command: currentCommand,\n packageManager: effectiveSelected,\n });\n };\n\n return (\n <div\n className={cn(\n 'relative rounded-lg border border-zinc-800 bg-zinc-950',\n className\n )}\n {...props}\n >\n <div\n className=\"flex items-center border-b border-zinc-800 bg-zinc-900/50 px-2 pt-2\"\n role=\"tablist\"\n aria-label=\"Package manager selection\"\n >\n {packageManagers.map((pm) => (\n <button\n key={pm}\n type=\"button\"\n role=\"tab\"\n aria-selected={effectiveSelected === pm}\n onClick={() => handleSelect(pm)}\n className={cn(\n 'rounded-t-md border-t border-r border-l border-transparent px-4 py-2 text-xs font-medium text-zinc-400',\n 'transition-colors hover:text-zinc-100',\n 'focus:ring-2 focus:ring-zinc-600 focus:ring-offset-1 focus:ring-offset-zinc-900 focus:outline-none',\n effectiveSelected === pm &&\n 'border-zinc-800 bg-zinc-950 text-zinc-100'\n )}\n >\n {pm}\n </button>\n ))}\n </div>\n <div className=\"relative p-4\" role=\"tabpanel\">\n <CopyButton\n value={currentCommand}\n className=\"absolute top-3 right-3\"\n onCopy={handleCopy}\n />\n <pre className=\"overflow-x-auto pr-10 font-mono text-[13px] leading-6 text-white\">\n <code>{currentCommand}</code>\n </pre>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,MAAM,cAAc;AAEpB,SAAgB,YAAY,EAC1B,UACA,oBAAoB,OACpB,WACA,QACA,GAAG,SACgB;CACnB,MAAM,UAAU,mBAAmB;CAEnC,MAAM,CAAC,eAAe,oBAAoB,eAA+B;AACvE,SAAO;GACP;CAGF,MAAM,WAAW,SAAS,cAAc;CACxC,MAAM,cAAc,SAAS,iBAAiB;AAG9C,iBAAgB;AACd,MAAI,QAAS;AAEb,MAAI;GACF,MAAM,QAAQ,aAAa,QAAQ,YAAY;AAC/C,OAAI,SAAS,SAAS,OACpB,kBAAiB,MAAM;UAEnB;IAGP,CAAC,UAAU,QAAQ,CAAC;CAEvB,MAAM,gBAAgB,OAAuB;AAC3C,cAAY,GAAG;AAGf,MAAI,CAAC,QACH,KAAI;AACF,gBAAa,QAAQ,aAAa,GAAG;UAC/B;;CAOZ,MAAM,kBAAkB,OAAO,KAAK,SAAS;AAG7C,KAAI,gBAAgB,WAAW,EAAG,QAAO;CAGzC,MAAM,oBAAoB,SAAS,YAAY,WAAW,gBAAgB;AAC1E,KAAI,CAAC,kBAAmB,QAAO;CAC/B,MAAM,iBAAiB,SAAS;AAChC,KAAI,CAAC,eAAgB,QAAO;CAE5B,MAAM,mBAAmB;AACvB,WAAS;GACP,SAAS;GACT,gBAAgB;GACjB,CAAC;;AAGJ,QACE,qBAAC;EACC,WAAW,GACT,0DACA,UACD;EACD,GAAI;aAEJ,oBAAC;GACC,WAAU;GACV,MAAK;GACL,cAAW;aAEV,gBAAgB,KAAK,OACpB,oBAAC;IAEC,MAAK;IACL,MAAK;IACL,iBAAe,sBAAsB;IACrC,eAAe,aAAa,GAAG;IAC/B,WAAW,GACT,0GACA,yCACA,sGACA,sBAAsB,MACpB,4CACH;cAEA;MAbI,GAcE,CACT;IACE,EACN,qBAAC;GAAI,WAAU;GAAe,MAAK;cACjC,oBAAC;IACC,OAAO;IACP,WAAU;IACV,QAAQ;KACR,EACF,oBAAC;IAAI,WAAU;cACb,oBAAC,oBAAM,iBAAsB;KACzB;IACF;GACF"}
|
|
@@ -2,11 +2,16 @@ import { HTMLAttributes } from "react";
|
|
|
2
2
|
|
|
3
3
|
//#region src/components/molecules/CommandTabs/types.d.ts
|
|
4
4
|
type PackageManager = 'bun' | 'npm' | 'yarn' | 'pnpm';
|
|
5
|
-
interface CommandTabsProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
interface CommandTabsProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onCopy'> {
|
|
6
6
|
/** Commands for each package manager */
|
|
7
7
|
commands: Partial<Record<PackageManager, string>>;
|
|
8
8
|
/** Initial package manager preference (overridden by context if available) */
|
|
9
9
|
initialPreference?: PackageManager;
|
|
10
|
+
/** Optional callback when copy succeeds */
|
|
11
|
+
onCopy?: (data: {
|
|
12
|
+
command: string;
|
|
13
|
+
packageManager: PackageManager;
|
|
14
|
+
}) => void;
|
|
10
15
|
}
|
|
11
16
|
interface PackageManagerContextValue {
|
|
12
17
|
/** Current package manager preference */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/components/molecules/CommandTabs/types.ts"],"sourcesContent":[],"mappings":";;;KAEY,cAAA;UAEK,gBAAA,SAAyB,eAAe;
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/components/molecules/CommandTabs/types.ts"],"sourcesContent":[],"mappings":";;;KAEY,cAAA;UAEK,gBAAA,SAAyB,KACxC,eAAe;EAHL;EAEK,QAAA,EAKL,OALK,CAKG,MALc,CAKP,cALO,EAAA,MAAA,CAAA,CAAA;EACjB;EAAf,iBAAA,CAAA,EAMoB,cANpB;EAIyB;EAAP,MAAA,CAAA,EAAA,CAAA,IAAA,EAAA;IAAR,OAAA,EAAA,MAAA;IAEU,cAAA,EAE+B,cAF/B;EAE+B,CAAA,EAAA,GAAA,IAAA;;AATP,UAY7B,0BAAA,CAZ6B;EAY7B;cAEH;;sBAEQ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CopyButtonProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime116 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/molecules/CopyButton/CopyButton.d.ts
|
|
5
5
|
declare function CopyButton({
|
|
@@ -7,7 +7,7 @@ declare function CopyButton({
|
|
|
7
7
|
onCopy,
|
|
8
8
|
className,
|
|
9
9
|
...props
|
|
10
|
-
}: CopyButtonProps):
|
|
10
|
+
}: CopyButtonProps): react_jsx_runtime116.JSX.Element;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { CopyButton };
|
|
13
13
|
//# sourceMappingURL=CopyButton.d.ts.map
|
|
@@ -20,8 +20,8 @@ function CopyButton({ value, onCopy, className, ...props }) {
|
|
|
20
20
|
await navigator.clipboard.writeText(value);
|
|
21
21
|
setHasCopied(true);
|
|
22
22
|
onCopy?.();
|
|
23
|
-
} catch
|
|
24
|
-
|
|
23
|
+
} catch {
|
|
24
|
+
return;
|
|
25
25
|
}
|
|
26
26
|
}, [value, onCopy]);
|
|
27
27
|
return /* @__PURE__ */ jsxs("button", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopyButton.js","names":[],"sources":["../../../../src/components/molecules/CopyButton/CopyButton.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { Check, Copy } from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\nimport type { CopyButtonProps } from './types';\n\nexport function CopyButton({\n value,\n onCopy,\n className,\n ...props\n}: CopyButtonProps) {\n const [hasCopied, setHasCopied] = useState(false);\n\n useEffect(() => {\n if (!hasCopied) return;\n const timeout = setTimeout(() => {\n setHasCopied(false);\n }, 2000);\n return () => clearTimeout(timeout);\n }, [hasCopied]);\n\n const copyToClipboard = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setHasCopied(true);\n onCopy?.();\n } catch
|
|
1
|
+
{"version":3,"file":"CopyButton.js","names":[],"sources":["../../../../src/components/molecules/CopyButton/CopyButton.tsx"],"sourcesContent":["'use client';\n\nimport { cn } from '../../../lib/utils';\nimport { Check, Copy } from 'lucide-react';\nimport { useCallback, useEffect, useState } from 'react';\nimport type { CopyButtonProps } from './types';\n\nexport function CopyButton({\n value,\n onCopy,\n className,\n ...props\n}: CopyButtonProps) {\n const [hasCopied, setHasCopied] = useState(false);\n\n useEffect(() => {\n if (!hasCopied) return;\n const timeout = setTimeout(() => {\n setHasCopied(false);\n }, 2000);\n return () => clearTimeout(timeout);\n }, [hasCopied]);\n\n const copyToClipboard = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setHasCopied(true);\n onCopy?.();\n } catch {\n return;\n }\n }, [value, onCopy]);\n\n return (\n <button\n type=\"button\"\n className={cn(\n 'relative z-10 inline-flex h-6 w-6 items-center justify-center rounded-md',\n 'border border-zinc-700 bg-zinc-800 text-zinc-400',\n 'transition-all hover:bg-zinc-700 hover:text-zinc-100',\n 'focus:ring-2 focus:ring-zinc-600 focus:ring-offset-2 focus:ring-offset-zinc-900 focus:outline-none',\n className\n )}\n onClick={copyToClipboard}\n aria-label={hasCopied ? 'Copied' : 'Copy to clipboard'}\n {...props}\n >\n <span className=\"sr-only\">{hasCopied ? 'Copied' : 'Copy'}</span>\n {hasCopied ? <Check className=\"h-3 w-3\" /> : <Copy className=\"h-3 w-3\" />}\n </button>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,WAAW,EACzB,OACA,QACA,WACA,GAAG,SACe;CAClB,MAAM,CAAC,WAAW,gBAAgB,SAAS,MAAM;AAEjD,iBAAgB;AACd,MAAI,CAAC,UAAW;EAChB,MAAM,UAAU,iBAAiB;AAC/B,gBAAa,MAAM;KAClB,IAAK;AACR,eAAa,aAAa,QAAQ;IACjC,CAAC,UAAU,CAAC;CAEf,MAAM,kBAAkB,YAAY,YAAY;AAC9C,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,MAAM;AAC1C,gBAAa,KAAK;AAClB,aAAU;UACJ;AACN;;IAED,CAAC,OAAO,OAAO,CAAC;AAEnB,QACE,qBAAC;EACC,MAAK;EACL,WAAW,GACT,4EACA,oDACA,wDACA,sGACA,UACD;EACD,SAAS;EACT,cAAY,YAAY,WAAW;EACnC,GAAI;aAEJ,oBAAC;GAAK,WAAU;aAAW,YAAY,WAAW;IAAc,EAC/D,YAAY,oBAAC,SAAM,WAAU,YAAY,GAAG,oBAAC,QAAK,WAAU,YAAY;GAClE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallCommand.d.ts","names":[],"sources":["../../../../src/components/molecules/InstallCommand/InstallCommand.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAwFA;;;;;;;;;iBAAgB,cAAA;WACL
|
|
1
|
+
{"version":3,"file":"InstallCommand.d.ts","names":[],"sources":["../../../../src/components/molecules/InstallCommand/InstallCommand.tsx"],"sourcesContent":[],"mappings":";;;;;;;;AAwFA;;;;;;;;;iBAAgB,cAAA;WACL;;;;;;GAMR,sBAAmB,oBAAA,CAAA,GAAA,CAAA"}
|
|
@@ -45,7 +45,7 @@ function buildCommand(pm, packageNames, type, dev, global) {
|
|
|
45
45
|
* <InstallCommand package="create-next-app" type="exec" />
|
|
46
46
|
* ```
|
|
47
47
|
*/
|
|
48
|
-
function InstallCommand({ package: packageName, type = "add", dev = false, global = false, ...props }) {
|
|
48
|
+
function InstallCommand({ package: packageName, type = "add", dev = false, global = false, onCopy, ...props }) {
|
|
49
49
|
const packageNames = useMemo(() => Array.isArray(packageName) ? packageName : [packageName], [packageName]);
|
|
50
50
|
return /* @__PURE__ */ jsx(CommandTabs, {
|
|
51
51
|
commands: useMemo(() => ({
|
|
@@ -59,6 +59,7 @@ function InstallCommand({ package: packageName, type = "add", dev = false, globa
|
|
|
59
59
|
dev,
|
|
60
60
|
global
|
|
61
61
|
]),
|
|
62
|
+
onCopy,
|
|
62
63
|
...props
|
|
63
64
|
});
|
|
64
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstallCommand.js","names":[],"sources":["../../../../src/components/molecules/InstallCommand/InstallCommand.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { CommandTabs } from '../CommandTabs';\nimport type { PackageManager } from '../CommandTabs/types';\nimport type { InstallCommandProps, InstallCommandType } from './types';\n\nfunction buildCommand(\n pm: PackageManager,\n packageNames: string[],\n type: InstallCommandType,\n dev: boolean,\n global: boolean\n): string {\n const packages = packageNames.join(' ');\n\n // Handle exec/run commands (npx, bunx, etc.)\n if (type === 'exec') {\n switch (pm) {\n case 'bun':\n return `bunx ${packages}`;\n case 'npm':\n return `npx ${packages}`;\n case 'yarn':\n return `yarn dlx ${packages}`;\n case 'pnpm':\n return `pnpm dlx ${packages}`;\n }\n }\n\n // Handle create commands\n if (type === 'create') {\n switch (pm) {\n case 'bun':\n return `bun create ${packages}`;\n case 'npm':\n return `npm create ${packages}`;\n case 'yarn':\n return `yarn create ${packages}`;\n case 'pnpm':\n return `pnpm create ${packages}`;\n }\n }\n\n // Handle run commands\n if (type === 'run') {\n switch (pm) {\n case 'bun':\n return `bun run ${packages}`;\n case 'npm':\n return `npm run ${packages}`;\n case 'yarn':\n return `yarn ${packages}`;\n case 'pnpm':\n return `pnpm ${packages}`;\n }\n }\n\n // Build flags\n const devFlag = dev ? (pm === 'npm' ? '--save-dev' : '-D') : '';\n const globalFlag = global ? '-g' : '';\n const flags = [devFlag, globalFlag].filter(Boolean).join(' ');\n\n // Handle add/install commands\n switch (pm) {\n case 'bun':\n return `bun add ${packages}${flags ? ` ${flags}` : ''}`;\n case 'npm':\n return `npm install ${packages}${flags ? ` ${flags}` : ''}`;\n case 'yarn':\n return `yarn add ${packages}${flags ? ` ${flags}` : ''}`;\n case 'pnpm':\n return `pnpm add ${packages}${flags ? ` ${flags}` : ''}`;\n }\n}\n\n/**\n * Convenience component for displaying package installation commands.\n * Automatically generates the correct command for each package manager.\n *\n * @example\n * ```tsx\n * <InstallCommand package=\"@contractspec/lib.contracts\" />\n * <InstallCommand package={[\"react\", \"react-dom\"]} />\n * <InstallCommand package=\"typescript\" dev />\n * <InstallCommand package=\"create-next-app\" type=\"exec\" />\n * ```\n */\nexport function InstallCommand({\n package: packageName,\n type = 'add',\n dev = false,\n global = false,\n ...props\n}: InstallCommandProps) {\n const packageNames = useMemo(\n () => (Array.isArray(packageName) ? packageName : [packageName]),\n [packageName]\n );\n\n const commands = useMemo(\n () => ({\n bun: buildCommand('bun', packageNames, type, dev, global),\n npm: buildCommand('npm', packageNames, type, dev, global),\n yarn: buildCommand('yarn', packageNames, type, dev, global),\n pnpm: buildCommand('pnpm', packageNames, type, dev, global),\n }),\n [packageNames, type, dev, global]\n );\n\n return <CommandTabs commands={commands} {...props} />;\n}\n"],"mappings":";;;;;;;AAOA,SAAS,aACP,IACA,cACA,MACA,KACA,QACQ;CACR,MAAM,WAAW,aAAa,KAAK,IAAI;AAGvC,KAAI,SAAS,OACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,QAAQ;EACjB,KAAK,MACH,QAAO,OAAO;EAChB,KAAK,OACH,QAAO,YAAY;EACrB,KAAK,OACH,QAAO,YAAY;;AAKzB,KAAI,SAAS,SACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,cAAc;EACvB,KAAK,MACH,QAAO,cAAc;EACvB,KAAK,OACH,QAAO,eAAe;EACxB,KAAK,OACH,QAAO,eAAe;;AAK5B,KAAI,SAAS,MACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,WAAW;EACpB,KAAK,MACH,QAAO,WAAW;EACpB,KAAK,OACH,QAAO,QAAQ;EACjB,KAAK,OACH,QAAO,QAAQ;;CAOrB,MAAM,QAAQ,CAFE,MAAO,OAAO,QAAQ,eAAe,OAAQ,IAC1C,SAAS,OAAO,GACA,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;AAG7D,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,WAAW,WAAW,QAAQ,IAAI,UAAU;EACrD,KAAK,MACH,QAAO,eAAe,WAAW,QAAQ,IAAI,UAAU;EACzD,KAAK,OACH,QAAO,YAAY,WAAW,QAAQ,IAAI,UAAU;EACtD,KAAK,OACH,QAAO,YAAY,WAAW,QAAQ,IAAI,UAAU;;;;;;;;;;;;;;;AAgB1D,SAAgB,eAAe,EAC7B,SAAS,aACT,OAAO,OACP,MAAM,OACN,SAAS,OACT,GAAG,SACmB;CACtB,MAAM,eAAe,cACZ,MAAM,QAAQ,YAAY,GAAG,cAAc,CAAC,YAAY,EAC/D,CAAC,YAAY,CACd;AAYD,QAAO,oBAAC;EAAY,UAVH,eACR;GACL,KAAK,aAAa,OAAO,cAAc,MAAM,KAAK,OAAO;GACzD,KAAK,aAAa,OAAO,cAAc,MAAM,KAAK,OAAO;GACzD,MAAM,aAAa,QAAQ,cAAc,MAAM,KAAK,OAAO;GAC3D,MAAM,aAAa,QAAQ,cAAc,MAAM,KAAK,OAAO;GAC5D,GACD;GAAC;GAAc;GAAM;GAAK;GAAO,CAClC;
|
|
1
|
+
{"version":3,"file":"InstallCommand.js","names":[],"sources":["../../../../src/components/molecules/InstallCommand/InstallCommand.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo } from 'react';\nimport { CommandTabs } from '../CommandTabs';\nimport type { PackageManager } from '../CommandTabs/types';\nimport type { InstallCommandProps, InstallCommandType } from './types';\n\nfunction buildCommand(\n pm: PackageManager,\n packageNames: string[],\n type: InstallCommandType,\n dev: boolean,\n global: boolean\n): string {\n const packages = packageNames.join(' ');\n\n // Handle exec/run commands (npx, bunx, etc.)\n if (type === 'exec') {\n switch (pm) {\n case 'bun':\n return `bunx ${packages}`;\n case 'npm':\n return `npx ${packages}`;\n case 'yarn':\n return `yarn dlx ${packages}`;\n case 'pnpm':\n return `pnpm dlx ${packages}`;\n }\n }\n\n // Handle create commands\n if (type === 'create') {\n switch (pm) {\n case 'bun':\n return `bun create ${packages}`;\n case 'npm':\n return `npm create ${packages}`;\n case 'yarn':\n return `yarn create ${packages}`;\n case 'pnpm':\n return `pnpm create ${packages}`;\n }\n }\n\n // Handle run commands\n if (type === 'run') {\n switch (pm) {\n case 'bun':\n return `bun run ${packages}`;\n case 'npm':\n return `npm run ${packages}`;\n case 'yarn':\n return `yarn ${packages}`;\n case 'pnpm':\n return `pnpm ${packages}`;\n }\n }\n\n // Build flags\n const devFlag = dev ? (pm === 'npm' ? '--save-dev' : '-D') : '';\n const globalFlag = global ? '-g' : '';\n const flags = [devFlag, globalFlag].filter(Boolean).join(' ');\n\n // Handle add/install commands\n switch (pm) {\n case 'bun':\n return `bun add ${packages}${flags ? ` ${flags}` : ''}`;\n case 'npm':\n return `npm install ${packages}${flags ? ` ${flags}` : ''}`;\n case 'yarn':\n return `yarn add ${packages}${flags ? ` ${flags}` : ''}`;\n case 'pnpm':\n return `pnpm add ${packages}${flags ? ` ${flags}` : ''}`;\n }\n}\n\n/**\n * Convenience component for displaying package installation commands.\n * Automatically generates the correct command for each package manager.\n *\n * @example\n * ```tsx\n * <InstallCommand package=\"@contractspec/lib.contracts\" />\n * <InstallCommand package={[\"react\", \"react-dom\"]} />\n * <InstallCommand package=\"typescript\" dev />\n * <InstallCommand package=\"create-next-app\" type=\"exec\" />\n * ```\n */\nexport function InstallCommand({\n package: packageName,\n type = 'add',\n dev = false,\n global = false,\n onCopy,\n ...props\n}: InstallCommandProps) {\n const packageNames = useMemo(\n () => (Array.isArray(packageName) ? packageName : [packageName]),\n [packageName]\n );\n\n const commands = useMemo(\n () => ({\n bun: buildCommand('bun', packageNames, type, dev, global),\n npm: buildCommand('npm', packageNames, type, dev, global),\n yarn: buildCommand('yarn', packageNames, type, dev, global),\n pnpm: buildCommand('pnpm', packageNames, type, dev, global),\n }),\n [packageNames, type, dev, global]\n );\n\n return <CommandTabs commands={commands} onCopy={onCopy} {...props} />;\n}\n"],"mappings":";;;;;;;AAOA,SAAS,aACP,IACA,cACA,MACA,KACA,QACQ;CACR,MAAM,WAAW,aAAa,KAAK,IAAI;AAGvC,KAAI,SAAS,OACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,QAAQ;EACjB,KAAK,MACH,QAAO,OAAO;EAChB,KAAK,OACH,QAAO,YAAY;EACrB,KAAK,OACH,QAAO,YAAY;;AAKzB,KAAI,SAAS,SACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,cAAc;EACvB,KAAK,MACH,QAAO,cAAc;EACvB,KAAK,OACH,QAAO,eAAe;EACxB,KAAK,OACH,QAAO,eAAe;;AAK5B,KAAI,SAAS,MACX,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,WAAW;EACpB,KAAK,MACH,QAAO,WAAW;EACpB,KAAK,OACH,QAAO,QAAQ;EACjB,KAAK,OACH,QAAO,QAAQ;;CAOrB,MAAM,QAAQ,CAFE,MAAO,OAAO,QAAQ,eAAe,OAAQ,IAC1C,SAAS,OAAO,GACA,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI;AAG7D,SAAQ,IAAR;EACE,KAAK,MACH,QAAO,WAAW,WAAW,QAAQ,IAAI,UAAU;EACrD,KAAK,MACH,QAAO,eAAe,WAAW,QAAQ,IAAI,UAAU;EACzD,KAAK,OACH,QAAO,YAAY,WAAW,QAAQ,IAAI,UAAU;EACtD,KAAK,OACH,QAAO,YAAY,WAAW,QAAQ,IAAI,UAAU;;;;;;;;;;;;;;;AAgB1D,SAAgB,eAAe,EAC7B,SAAS,aACT,OAAO,OACP,MAAM,OACN,SAAS,OACT,QACA,GAAG,SACmB;CACtB,MAAM,eAAe,cACZ,MAAM,QAAQ,YAAY,GAAG,cAAc,CAAC,YAAY,EAC/D,CAAC,YAAY,CACd;AAYD,QAAO,oBAAC;EAAY,UAVH,eACR;GACL,KAAK,aAAa,OAAO,cAAc,MAAM,KAAK,OAAO;GACzD,KAAK,aAAa,OAAO,cAAc,MAAM,KAAK,OAAO;GACzD,MAAM,aAAa,QAAQ,cAAc,MAAM,KAAK,OAAO;GAC3D,MAAM,aAAa,QAAQ,cAAc,MAAM,KAAK,OAAO;GAC5D,GACD;GAAC;GAAc;GAAM;GAAK;GAAO,CAClC;EAE+C;EAAQ,GAAI;GAAS"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { PackageManager } from "../CommandTabs/types.js";
|
|
1
2
|
import { HTMLAttributes } from "react";
|
|
2
3
|
|
|
3
4
|
//#region src/components/molecules/InstallCommand/types.d.ts
|
|
4
5
|
type InstallCommandType = 'add' | 'install' | 'create' | 'run' | 'exec';
|
|
5
|
-
interface InstallCommandProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
6
|
+
interface InstallCommandProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onCopy'> {
|
|
6
7
|
/** The package name(s) to install */
|
|
7
8
|
package: string | string[];
|
|
8
9
|
/** The type of command (defaults to 'add' for package installation) */
|
|
@@ -11,6 +12,11 @@ interface InstallCommandProps extends Omit<HTMLAttributes<HTMLDivElement>, 'chil
|
|
|
11
12
|
dev?: boolean;
|
|
12
13
|
/** Whether this is a global installation (adds -g flag) */
|
|
13
14
|
global?: boolean;
|
|
15
|
+
/** Optional callback when copy succeeds */
|
|
16
|
+
onCopy?: (data: {
|
|
17
|
+
command: string;
|
|
18
|
+
packageManager: PackageManager;
|
|
19
|
+
}) => void;
|
|
14
20
|
}
|
|
15
21
|
//#endregion
|
|
16
22
|
export { InstallCommandProps, InstallCommandType };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/components/molecules/InstallCommand/types.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","names":[],"sources":["../../../../src/components/molecules/InstallCommand/types.ts"],"sourcesContent":[],"mappings":";;;;KAGY,kBAAA;UAEK,mBAAA,SAA4B,KAC3C,eAAe;EAHL;EAEK,OAAA,EAAA,MAAA,GAAA,MAAoB,EAAA;EACpB;EAAf,IAAA,CAAA,EAMO,kBANP;EAMO;EAM4C,GAAA,CAAA,EAAA,OAAA;EAbR;EAAI,MAAA,CAAA,EAAA,OAAA;;;;oBAaI"}
|
|
@@ -12,6 +12,7 @@ function NavItemCard({ item, className }) {
|
|
|
12
12
|
"aria-label": typeof item.label === "string" ? item.label : item.ariaLabel,
|
|
13
13
|
target: item.target,
|
|
14
14
|
rel: item.external ? "noopener noreferrer" : void 0,
|
|
15
|
+
onClick: item.onClick,
|
|
15
16
|
children: /* @__PURE__ */ jsxs("div", {
|
|
16
17
|
className: "flex items-center gap-3",
|
|
17
18
|
children: [item.imageSrc ? /* @__PURE__ */ jsx("img", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NavItemCard.js","names":[],"sources":["../../../src/components/molecules/NavItemCard.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cn } from '@contractspec/lib.ui-kit-web/ui/utils';\nimport type { NavLink } from '../../types/navigation';\n\nexport interface NavItemCardProps {\n item: NavLink;\n className?: string;\n}\n\nexport function NavItemCard({ item, className }: NavItemCardProps) {\n return (\n <a\n href={item.href}\n className={cn(\n 'hover:bg-accent block rounded-md p-2 transition-colors',\n className\n )}\n aria-label={typeof item.label === 'string' ? item.label : item.ariaLabel}\n target={item.target}\n rel={item.external ? 'noopener noreferrer' : undefined}\n >\n <div className=\"flex items-center gap-3\">\n {item.imageSrc ? (\n // keep generic img to avoid coupling to Next.js Image\n <img\n src={item.imageSrc}\n alt={item.imageAlt || ''}\n className=\"h-12 w-12 rounded-xs object-cover\"\n />\n ) : (\n item.icon || null\n )}\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2 text-base font-medium\">\n {item.label}\n {item.badge && (\n <span className=\"text-muted-foreground ml-1 text-xs\">\n {item.badge}\n </span>\n )}\n </div>\n {item.description && (\n <div className=\"text-muted-foreground line-clamp-2 text-sm\">\n {item.description}\n </div>\n )}\n {item.categories && item.categories.length > 0 && (\n <div className=\"mt-1 flex flex-wrap items-center gap-1\">\n {item.categories.map((c, i) => (\n <span\n key={i}\n className=\"bg-muted text-muted-foreground rounded-xs px-1.5 py-0.5 text-[10px]\"\n >\n {c}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n </a>\n );\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,YAAY,EAAE,MAAM,aAA+B;AACjE,QACE,oBAAC;EACC,MAAM,KAAK;EACX,WAAW,GACT,0DACA,UACD;EACD,cAAY,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAK;EAC/D,QAAQ,KAAK;EACb,KAAK,KAAK,WAAW,wBAAwB;
|
|
1
|
+
{"version":3,"file":"NavItemCard.js","names":[],"sources":["../../../src/components/molecules/NavItemCard.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { cn } from '@contractspec/lib.ui-kit-web/ui/utils';\nimport type { NavLink } from '../../types/navigation';\n\nexport interface NavItemCardProps {\n item: NavLink;\n className?: string;\n}\n\nexport function NavItemCard({ item, className }: NavItemCardProps) {\n return (\n <a\n href={item.href}\n className={cn(\n 'hover:bg-accent block rounded-md p-2 transition-colors',\n className\n )}\n aria-label={typeof item.label === 'string' ? item.label : item.ariaLabel}\n target={item.target}\n rel={item.external ? 'noopener noreferrer' : undefined}\n onClick={item.onClick}\n >\n <div className=\"flex items-center gap-3\">\n {item.imageSrc ? (\n // keep generic img to avoid coupling to Next.js Image\n <img\n src={item.imageSrc}\n alt={item.imageAlt || ''}\n className=\"h-12 w-12 rounded-xs object-cover\"\n />\n ) : (\n item.icon || null\n )}\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2 text-base font-medium\">\n {item.label}\n {item.badge && (\n <span className=\"text-muted-foreground ml-1 text-xs\">\n {item.badge}\n </span>\n )}\n </div>\n {item.description && (\n <div className=\"text-muted-foreground line-clamp-2 text-sm\">\n {item.description}\n </div>\n )}\n {item.categories && item.categories.length > 0 && (\n <div className=\"mt-1 flex flex-wrap items-center gap-1\">\n {item.categories.map((c, i) => (\n <span\n key={i}\n className=\"bg-muted text-muted-foreground rounded-xs px-1.5 py-0.5 text-[10px]\"\n >\n {c}\n </span>\n ))}\n </div>\n )}\n </div>\n </div>\n </a>\n );\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,YAAY,EAAE,MAAM,aAA+B;AACjE,QACE,oBAAC;EACC,MAAM,KAAK;EACX,WAAW,GACT,0DACA,UACD;EACD,cAAY,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ,KAAK;EAC/D,QAAQ,KAAK;EACb,KAAK,KAAK,WAAW,wBAAwB;EAC7C,SAAS,KAAK;YAEd,qBAAC;GAAI,WAAU;cACZ,KAAK,WAEJ,oBAAC;IACC,KAAK,KAAK;IACV,KAAK,KAAK,YAAY;IACtB,WAAU;KACV,GAEF,KAAK,QAAQ,MAEf,qBAAC;IAAI,WAAU;;KACb,qBAAC;MAAI,WAAU;iBACZ,KAAK,OACL,KAAK,SACJ,oBAAC;OAAK,WAAU;iBACb,KAAK;QACD;OAEL;KACL,KAAK,eACJ,oBAAC;MAAI,WAAU;gBACZ,KAAK;OACF;KAEP,KAAK,cAAc,KAAK,WAAW,SAAS,KAC3C,oBAAC;MAAI,WAAU;gBACZ,KAAK,WAAW,KAAK,GAAG,MACvB,oBAAC;OAEC,WAAU;iBAET;SAHI,EAIA,CACP;OACE;;KAEJ;IACF;GACJ"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SkeletonBlockProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime110 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/molecules/SkeletonBlock/index.web.d.ts
|
|
5
5
|
declare function SkeletonBlock({
|
|
@@ -7,7 +7,7 @@ declare function SkeletonBlock({
|
|
|
7
7
|
h,
|
|
8
8
|
rounded,
|
|
9
9
|
className
|
|
10
|
-
}: SkeletonBlockProps):
|
|
10
|
+
}: SkeletonBlockProps): react_jsx_runtime110.JSX.Element;
|
|
11
11
|
//#endregion
|
|
12
12
|
export { SkeletonBlock };
|
|
13
13
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { SkeletonCircleProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime111 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/molecules/SkeletonCircle/index.web.d.ts
|
|
5
5
|
declare function SkeletonCircle({
|
|
6
6
|
size,
|
|
7
7
|
sizeClass,
|
|
8
8
|
className
|
|
9
|
-
}: SkeletonCircleProps):
|
|
9
|
+
}: SkeletonCircleProps): react_jsx_runtime111.JSX.Element;
|
|
10
10
|
//#endregion
|
|
11
11
|
export { SkeletonCircle };
|
|
12
12
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { SkeletonListProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime112 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/molecules/SkeletonList/index.web.d.ts
|
|
5
5
|
declare function SkeletonList({
|
|
6
6
|
count,
|
|
7
7
|
className
|
|
8
|
-
}: SkeletonListProps):
|
|
8
|
+
}: SkeletonListProps): react_jsx_runtime112.JSX.Element;
|
|
9
9
|
//#endregion
|
|
10
10
|
export { SkeletonList };
|
|
11
11
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ListPageTemplateProps } from "./types.js";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime109 from "react/jsx-runtime";
|
|
3
3
|
|
|
4
4
|
//#region src/components/templates/lists/ListPageTemplate/index.web.d.ts
|
|
5
5
|
declare function ListPageTemplate<T = unknown>({
|
|
@@ -17,7 +17,7 @@ declare function ListPageTemplate<T = unknown>({
|
|
|
17
17
|
data,
|
|
18
18
|
renderItem,
|
|
19
19
|
emptyProps
|
|
20
|
-
}: ListPageTemplateProps<T>):
|
|
20
|
+
}: ListPageTemplateProps<T>): react_jsx_runtime109.JSX.Element;
|
|
21
21
|
//#endregion
|
|
22
22
|
export { ListPageTemplate };
|
|
23
23
|
//# sourceMappingURL=index.web.d.ts.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as _contractspec_lib_contracts_client_react_form_render0 from "@contractspec/lib.contracts/client/react/form-render";
|
|
2
|
-
import * as
|
|
2
|
+
import * as react_jsx_runtime113 from "react/jsx-runtime";
|
|
3
3
|
import * as _contractspec_lib_schema0 from "@contractspec/lib.schema";
|
|
4
4
|
import * as _contractspec_lib_contracts_forms0 from "@contractspec/lib.contracts/forms";
|
|
5
5
|
|
|
6
6
|
//#region src/renderers/form-contract.d.ts
|
|
7
7
|
declare const formRenderer: {
|
|
8
|
-
render: (spec: _contractspec_lib_contracts_forms0.FormSpec<_contractspec_lib_schema0.AnySchemaModel>, options?: _contractspec_lib_contracts_client_react_form_render0.RenderOptions<unknown> | undefined) =>
|
|
8
|
+
render: (spec: _contractspec_lib_contracts_forms0.FormSpec<_contractspec_lib_schema0.AnySchemaModel>, options?: _contractspec_lib_contracts_client_react_form_render0.RenderOptions<unknown> | undefined) => react_jsx_runtime113.JSX.Element;
|
|
9
9
|
};
|
|
10
10
|
//#endregion
|
|
11
11
|
export { formRenderer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","names":[],"sources":["../../src/types/navigation.ts"],"sourcesContent":[],"mappings":";;;UAEiB,OAAA;SACR,KAAA,CAAM;EADE,IAAA,EAAA,MAAO;EACf,IAAM,CAAA,EAEN,KAAA,CAAM,SAFA;EAEN,KAAM,CAAA,EAAA,MAAA,GAAA,MAAA;EAKC,MAAM,CAAA,EAAA,OAAA,GAAA,QAAA;
|
|
1
|
+
{"version":3,"file":"navigation.d.ts","names":[],"sources":["../../src/types/navigation.ts"],"sourcesContent":[],"mappings":";;;UAEiB,OAAA;SACR,KAAA,CAAM;EADE,IAAA,EAAA,MAAO;EACf,IAAM,CAAA,EAEN,KAAA,CAAM,SAFA;EAEN,KAAM,CAAA,EAAA,MAAA,GAAA,MAAA;EAKC,MAAM,CAAA,EAAA,OAAA,GAAA,QAAA;EAIgB,SAAA,CAAA,EAAA,MAAA;EAAjB,QAAM,CAAA,EAAA,OAAA;EAAU,WAAA,CAAA,EAJrB,KAAA,CAAM,SAIe;EAGpB,QAAA,CAAA,EAAA,MAAU;EAKV,QAAA,CAAA,EAAA,MAAY;EAQZ,UAAA,CAAA,EAAA,MAAa,EAAA;EACrB,OAAM,CAAA,EAAA,CAAA,KAAA,CAAA,EAjBM,KAAA,CAAM,UAiBZ,CAjBuB,iBAiBvB,CAAA,EAAA,GAAA,IAAA;;AAIL,UAlBO,UAAA,CAkBP;EAAO,KAAA,CAAA,EAjBP,KAAA,CAAM,SAiBC;EAIA,KAAA,EApBR,OAoBiB,EAAA;;UAjBT,YAAA;SACR,KAAA,CAAM;;;SAGN,KAAA,CAAM;;;UAIE,aAAA;SACR,KAAA,CAAM;;gBAEC,KAAA,CAAM;;UAEZ;;;UAIO,SAAA;SACR,KAAA,CAAM"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contractspec/lib.design-system",
|
|
3
|
-
"version": "0.0.0-canary-
|
|
3
|
+
"version": "0.0.0-canary-20260119224015",
|
|
4
4
|
"description": "Design tokens and theming primitives",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"contractspec",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"build:types": "tsc --noEmit -p tsconfig.build.json",
|
|
19
19
|
"dev": "bun run build:bundle --watch",
|
|
20
20
|
"registry:build": "bun run scripts/build-registry.ts",
|
|
21
|
-
"test": "bun test
|
|
21
|
+
"test": "bun test",
|
|
22
22
|
"lint": "bun run lint:fix",
|
|
23
23
|
"lint:fix": "eslint src --fix",
|
|
24
24
|
"lint:check": "eslint src"
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"sideEffects": false,
|
|
29
29
|
"tree-shake": true,
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@contractspec/lib.ai-agent": "0.0.0-canary-
|
|
32
|
-
"@contractspec/lib.contracts": "0.0.0-canary-
|
|
33
|
-
"@contractspec/lib.ui-kit": "
|
|
34
|
-
"@contractspec/lib.ui-kit-web": "
|
|
31
|
+
"@contractspec/lib.ai-agent": "0.0.0-canary-20260119224015",
|
|
32
|
+
"@contractspec/lib.contracts": "0.0.0-canary-20260119224015",
|
|
33
|
+
"@contractspec/lib.ui-kit": "1.48.0",
|
|
34
|
+
"@contractspec/lib.ui-kit-web": "1.48.0",
|
|
35
35
|
"@hookform/resolvers": "5.2.2",
|
|
36
36
|
"class-variance-authority": "^0.7.1",
|
|
37
37
|
"clsx": "^2.1.1",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"zod": "^4.3.5"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@contractspec/tool.tsdown": "
|
|
50
|
-
"@contractspec/tool.typescript": "
|
|
49
|
+
"@contractspec/tool.tsdown": "1.48.0",
|
|
50
|
+
"@contractspec/tool.typescript": "1.48.0",
|
|
51
51
|
"@types/node": "^25.0.6",
|
|
52
52
|
"@types/react-dom": "^19.0.14",
|
|
53
53
|
"postcss": "^8.5",
|