@cntyclub/ui-react 0.1.1 → 0.3.0

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.
@@ -0,0 +1,45 @@
1
+ "use client";
2
+
3
+ import { cva, type VariantProps } from "class-variance-authority";
4
+ import type * as React from "react";
5
+
6
+ import { cn } from "../../lib/utils/css";
7
+ import { Button, type ButtonProps } from "./button";
8
+
9
+ const fabVariants = cva(
10
+ "fixed z-50 rounded-full shadow-lg transition-transform duration-150 hover:scale-105 active:scale-95 before:rounded-full",
11
+ {
12
+ defaultVariants: {
13
+ position: "bottom-right",
14
+ },
15
+ variants: {
16
+ position: {
17
+ "bottom-right": "right-4 bottom-4 sm:right-6 sm:bottom-6",
18
+ "bottom-left": "bottom-4 left-4 sm:bottom-6 sm:left-6",
19
+ "top-right": "top-4 right-4 sm:top-6 sm:right-6",
20
+ "top-left": "top-4 left-4 sm:top-6 sm:left-6",
21
+ },
22
+ },
23
+ },
24
+ );
25
+
26
+ export interface FabProps extends ButtonProps {
27
+ position?: VariantProps<typeof fabVariants>["position"];
28
+ }
29
+
30
+ /**
31
+ * Floating action button — a fixed, round icon button used to summon overlays
32
+ * such as chat widgets. Composes `Button`, so all button variants/sizes apply.
33
+ */
34
+ function Fab({ className, position, size = "icon-xl", ...props }: FabProps) {
35
+ return (
36
+ <Button
37
+ className={cn(fabVariants({ className, position }))}
38
+ data-slot="fab"
39
+ size={size}
40
+ {...props}
41
+ />
42
+ );
43
+ }
44
+
45
+ export { Fab, fabVariants };
@@ -0,0 +1,107 @@
1
+ "use client";
2
+
3
+ import type * as React from "react";
4
+ import ReactMarkdown from "react-markdown";
5
+ import remarkGfm from "remark-gfm";
6
+
7
+ import { cn } from "../../lib/utils/css";
8
+
9
+ export interface MarkdownProps {
10
+ /** The markdown source to render. */
11
+ children: string;
12
+ className?: string;
13
+ }
14
+
15
+ /**
16
+ * Markdown renderer for assistant/chat content (GitHub-flavored markdown).
17
+ * Raw HTML in the source is NOT rendered — output is limited to markdown
18
+ * elements, which keeps untrusted model output safe to display.
19
+ */
20
+ function Markdown({ children, className }: MarkdownProps) {
21
+ return (
22
+ <div
23
+ className={cn(
24
+ "space-y-2 break-words text-foreground text-sm leading-relaxed",
25
+ className,
26
+ )}
27
+ data-slot="markdown"
28
+ >
29
+ <ReactMarkdown
30
+ components={{
31
+ a: ({ node: _node, ...props }) => (
32
+ <a
33
+ className="font-medium text-primary underline underline-offset-2 hover:opacity-80"
34
+ rel="noreferrer noopener"
35
+ target="_blank"
36
+ {...props}
37
+ />
38
+ ),
39
+ blockquote: ({ node: _node, ...props }) => (
40
+ <blockquote
41
+ className="border-border border-l-2 pl-3 text-muted-foreground italic"
42
+ {...props}
43
+ />
44
+ ),
45
+ code: ({ node: _node, className: codeClassName, ...props }) => {
46
+ const isBlock = /language-/.test(codeClassName ?? "");
47
+ return (
48
+ <code
49
+ className={cn(
50
+ "rounded bg-muted font-mono text-[0.85em]",
51
+ isBlock ? "block overflow-x-auto p-3" : "px-1 py-0.5",
52
+ codeClassName,
53
+ )}
54
+ {...props}
55
+ />
56
+ );
57
+ },
58
+ h1: ({ node: _node, ...props }) => (
59
+ <h1 className="font-semibold text-base" {...props} />
60
+ ),
61
+ h2: ({ node: _node, ...props }) => (
62
+ <h2 className="font-semibold text-base" {...props} />
63
+ ),
64
+ h3: ({ node: _node, ...props }) => (
65
+ <h3 className="font-semibold text-sm" {...props} />
66
+ ),
67
+ hr: ({ node: _node, ...props }) => (
68
+ <hr className="border-border" {...props} />
69
+ ),
70
+ li: ({ node: _node, ...props }) => <li className="my-0.5" {...props} />,
71
+ ol: ({ node: _node, ...props }) => (
72
+ <ol className="list-decimal space-y-1 pl-5" {...props} />
73
+ ),
74
+ pre: ({ node: _node, ...props }) => (
75
+ <pre
76
+ className="overflow-x-auto rounded-lg bg-muted p-0 text-[0.85em]"
77
+ {...props}
78
+ />
79
+ ),
80
+ table: ({ node: _node, ...props }) => (
81
+ <div className="overflow-x-auto rounded-lg border border-border">
82
+ <table className="w-full text-left text-sm" {...props} />
83
+ </div>
84
+ ),
85
+ td: ({ node: _node, ...props }) => (
86
+ <td className="border-border border-t px-3 py-1.5 align-top" {...props} />
87
+ ),
88
+ th: ({ node: _node, ...props }) => (
89
+ <th
90
+ className="bg-muted px-3 py-1.5 font-medium text-muted-foreground"
91
+ {...props}
92
+ />
93
+ ),
94
+ ul: ({ node: _node, ...props }) => (
95
+ <ul className="list-disc space-y-1 pl-5" {...props} />
96
+ ),
97
+ }}
98
+ remarkPlugins={[remarkGfm]}
99
+ skipHtml
100
+ >
101
+ {children}
102
+ </ReactMarkdown>
103
+ </div>
104
+ );
105
+ }
106
+
107
+ export { Markdown };
package/src/index.ts CHANGED
@@ -19,16 +19,19 @@ export * from "./components/ui/calendar";
19
19
  export * from "./components/ui/card";
20
20
  export * from "./components/ui/carousel";
21
21
  export * from "./components/ui/chart";
22
+ export * from "./components/ui/chat";
22
23
  export * from "./components/ui/checkbox";
23
24
  export * from "./components/ui/checkbox-group";
24
25
  export * from "./components/ui/collapsible";
25
26
  export * from "./components/ui/combobox";
26
27
  export * from "./components/ui/command";
27
28
  export * from "./components/ui/credit-card";
29
+ export * from "./components/ui/data-table-paged";
28
30
  export * from "./components/ui/drawer";
29
31
  export * from "./components/ui/context-menu";
30
32
  export * from "./components/ui/dialog";
31
33
  export * from "./components/ui/empty";
34
+ export * from "./components/ui/fab";
32
35
  export * from "./components/ui/featured-icon";
33
36
  export * from "./components/ui/field";
34
37
  export * from "./components/ui/fieldset";
@@ -43,6 +46,7 @@ export * from "./components/ui/input-otp";
43
46
  export * from "./components/ui/item";
44
47
  export * from "./components/ui/kbd";
45
48
  export * from "./components/ui/label";
49
+ export * from "./components/ui/markdown";
46
50
  export * from "./components/ui/menu";
47
51
  export * from "./components/ui/menubar";
48
52
  export * from "./components/ui/meter";