magicui

Форк
0
/
component-preview.tsx 
102 строки · 3.6 Кб
1
"use client";
2
import ComponentWrapper from "@/components/component-wrapper";
3
import { Icons } from "@/components/icons";
4
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
5
import { cn } from "@/lib/utils";
6
import { registry } from "@/registry/index";
7
import { RotateCcw } from "lucide-react";
8
import * as React from "react";
9
import { Button } from "./ui/button";
10

11
interface ComponentPreviewProps extends React.HTMLAttributes<HTMLDivElement> {
12
  name: string;
13
  align?: "center" | "start" | "end";
14
}
15

16
export function ComponentPreview({
17
  name,
18
  children,
19
  className,
20
  align = "center",
21
  ...props
22
}: ComponentPreviewProps) {
23
  const [key, setKey] = React.useState(0); // State to trigger re-render of preview
24
  const Codes = React.Children.toArray(children) as React.ReactElement[];
25
  const Code = Codes[0]; // first child
26

27
  const Preview = React.useMemo(() => {
28
    const Component = registry[name]?.component;
29

30
    if (!Component) {
31
      console.error(`Component with name "${name}" not found in registry.`);
32
      return (
33
        <p className="text-sm text-muted-foreground">
34
          Component{" "}
35
          <code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
36
            {name}
37
          </code>{" "}
38
          not found in registry.
39
        </p>
40
      );
41
    }
42

43
    return <Component />;
44
  }, [name, key]);
45

46
  return (
47
    <div
48
      className={cn(
49
        "relative my-4 flex flex-col space-y-2 lg:max-w-[120ch]",
50
        className,
51
      )}
52
      {...props}
53
    >
54
      <Tabs defaultValue="preview" className="relative mr-auto w-full">
55
        <div className="flex items-center justify-between pb-3">
56
          <TabsList className="w-full justify-start rounded-none border-b bg-transparent p-0">
57
            <TabsTrigger
58
              value="preview"
59
              className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
60
            >
61
              Preview
62
            </TabsTrigger>
63
            <TabsTrigger
64
              value="code"
65
              className="relative h-9 rounded-none border-b-2 border-b-transparent bg-transparent px-4 pb-3 pt-2 font-semibold text-muted-foreground shadow-none transition-none data-[state=active]:border-b-primary data-[state=active]:text-foreground data-[state=active]:shadow-none"
66
            >
67
              Code
68
            </TabsTrigger>
69
          </TabsList>
70
        </div>
71
        <TabsContent value="preview" className="relative rounded-md" key={key}>
72
          <ComponentWrapper>
73
            <Button
74
              onClick={() => setKey((prev) => prev + 1)}
75
              className="absolute right-0 top-0 z-50 ml-4 flex items-center rounded-lg px-3 py-1"
76
              variant="ghost"
77
            >
78
              <RotateCcw size={16} />
79
            </Button>
80
            <React.Suspense
81
              fallback={
82
                <div className="flex items-center text-sm text-muted-foreground">
83
                  <Icons.spinner className="mr-2 h-4 w-4 animate-spin" />
84
                  Loading...
85
                </div>
86
              }
87
            >
88
              {Preview}
89
            </React.Suspense>
90
          </ComponentWrapper>
91
        </TabsContent>
92
        <TabsContent value="code">
93
          <div className="flex flex-col space-y-4">
94
            <div className="w-full rounded-md [&_pre]:my-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
95
              {Code}
96
            </div>
97
          </div>
98
        </TabsContent>
99
      </Tabs>
100
    </div>
101
  );
102
}
103

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.