Files
cosscom__coss/apps/ui/components/code-block-command.tsx
Pasquale Vitiello e7a3a00c5f refactor: UI/UX general improvements (#617)
* feat: 1:1 font replacement

* feat: add examples app

* style: update font sizes and improve component styles for consistency

* update font

* style: restore default font weights

* refactor: move local fonts to packages

* feat: update font weights and refactor font imports in examples app

* fix CommandDialog not closing on ESC

* refactor: command component improvements

* chore: remove console log from command demo

* refactor: update Command and Menu components to use <kbd> for shortcuts and improve styling

* style: fix formatting in globals.css by removing unnecessary whitespace

* fix: refactor group and toggle-group to prevent flickering menu trigger at the end of a group

* refactor: toggle group and group improvements

* refactor: update toggle component styles for consistency and clarity

* refactor: major styling improvements

* fix: dialogs

* refactor: prefer not-dark:

* fix: scrollarea overscroll

* refactor: integrate ScrollArea component throughout

* style: various improvements

* style: mc

* style: update button sizes and improve mobile footer layout

* style: adjust code component font size and refactor particle card container className

* style: improve mobile footer

* refactor: improve carious components

* style: mc

* chore: implement Cal.ai badge

* feat: implement new event type dialog

* refactor: clean up event types and improve page layout

* feat: implement ai-mode in the cmdk component

* chore: format

* fix: remove outline from CommandDialogPopup

* fix: update separator className to use bg-input instead of bg-border

* fix: cubic issues

* style: update font size in code components for consistency

* style: improve shadows

* fix: update badge and toggle components to use bg-background

* chore: update color references

* chore: fix registry

* chore: sync package component + build registry

* fix(accordion): issue 596

* fix: issue 609

* docs: updates

* chore: improve sync script

* feat: add AI-powered command particle

* feat: improve switch and add menu checkbox switch variant

* style: toggle improvements

* fix: docs container

* style: remove css vars from examples

* chore: format

* feat: add more example pages
2026-01-08 09:35:53 +00:00

129 lines
3.8 KiB
TypeScript

"use client";
import { useCopyToClipboard } from "@coss/ui/hooks/use-copy-to-clipboard";
import {
ComputerTerminal02Icon,
Copy01Icon,
Tick02Icon,
} from "@hugeicons/core-free-icons";
import { HugeiconsIcon } from "@hugeicons/react";
import * as React from "react";
import { useConfig } from "@/hooks/use-config";
import { Button } from "@/registry/default/ui/button";
import { ScrollArea } from "@/registry/default/ui/scroll-area";
import { Tabs, TabsList, TabsPanel, TabsTab } from "@/registry/default/ui/tabs";
import {
Tooltip,
TooltipPopup,
TooltipTrigger,
} from "@/registry/default/ui/tooltip";
export function CodeBlockCommand({
__npm__,
__yarn__,
__pnpm__,
__bun__,
}: React.ComponentProps<"pre"> & {
__npm__?: string;
__yarn__?: string;
__pnpm__?: string;
__bun__?: string;
}) {
const [config, setConfig] = useConfig();
const { isCopied, copyToClipboard } = useCopyToClipboard();
const packageManager = config.packageManager || "pnpm";
const tabs = React.useMemo(() => {
return {
bun: __bun__,
npm: __npm__,
pnpm: __pnpm__,
yarn: __yarn__,
};
}, [__npm__, __pnpm__, __yarn__, __bun__]);
const copyCommand = React.useCallback(() => {
const command = tabs[packageManager];
if (!command) {
return;
}
copyToClipboard(command);
}, [packageManager, tabs, copyToClipboard]);
return (
<div>
<Tabs
className="gap-0"
onValueChange={(value) => {
setConfig({
...config,
packageManager: value as "pnpm" | "npm" | "yarn" | "bun",
});
}}
value={packageManager}
>
<div className="flex items-center gap-2 border-border/64 border-b px-4 py-1 font-mono">
<HugeiconsIcon
className="size-5 text-code-foreground sm:size-4"
icon={ComputerTerminal02Icon}
strokeWidth={2}
/>
<TabsList className="bg-transparent p-0 *:data-[slot=tab-indicator]:rounded-lg *:data-[slot=tab-indicator]:bg-accent *:data-[slot=tab-indicator]:shadow-none">
{Object.entries(tabs).map(([key]) => {
return (
<TabsTab className="rounded-lg" key={key} value={key}>
{key}
</TabsTab>
);
})}
</TabsList>
</div>
<ScrollArea className="**:data-[slot=scroll-area-scrollbar]:data-[orientation=horizontal]:mx-2 **:data-[slot=scroll-area-scrollbar]:data-[orientation=vertical]:my-2">
{Object.entries(tabs).map(([key, value]) => {
return (
<TabsPanel
className="mt-0 w-max px-4 py-3.5"
key={key}
value={key}
>
<pre>
<code
className="relative font-mono text-[.8125rem] leading-none"
data-language="bash"
>
{value}
</code>
</pre>
</TabsPanel>
);
})}
</ScrollArea>
</Tabs>
<Tooltip>
<TooltipTrigger
render={
<Button
className="absolute top-1.5 right-1.5 z-3 size-9 opacity-70 hover:opacity-100 focus-visible:opacity-100 sm:size-8"
data-slot="copy-button"
onClick={copyCommand}
size="icon"
variant="ghost"
>
<span className="sr-only">Copy</span>
{isCopied ? (
<HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />
) : (
<HugeiconsIcon icon={Copy01Icon} strokeWidth={2} />
)}
</Button>
}
/>
<TooltipPopup>{isCopied ? "Copied" : "Copy to Clipboard"}</TooltipPopup>
</Tooltip>
</div>
);
}