+
{t("attention")}
diff --git a/registry.json b/registry.json
index 594c402..b72ad67 100644
--- a/registry.json
+++ b/registry.json
@@ -5,7 +5,7 @@
"items": [
{
"name": "button",
- "type": "registry:block",
+ "type": "registry:component",
"title": "Button",
"description": "MateChat Button",
"files": [
@@ -17,7 +17,7 @@
},
{
"name": "sender",
- "type": "registry:block",
+ "type": "registry:component",
"title": "Sender",
"description": "MateChat Sender",
"files": [
@@ -27,9 +27,25 @@
}
]
},
+ {
+ "name": "suggestion",
+ "type": "registry:component",
+ "title": "Suggestion",
+ "description": "MateChat Suggestion",
+ "files": [
+ {
+ "path": "src/suggestion.tsx",
+ "type": "registry:component"
+ },
+ {
+ "path": "src/list.tsx",
+ "type": "registry:component"
+ }
+ ]
+ },
{
"name": "prompt",
- "type": "registry:block",
+ "type": "registry:component",
"title": "Prompt",
"description": "MateChat Prompt",
"files": [
@@ -39,6 +55,18 @@
}
]
},
+ {
+ "name": "file-upload",
+ "type": "registry:component",
+ "title": "File Upload",
+ "description": "MateChat File Upload",
+ "files": [
+ {
+ "path": "src/file-upload.tsx",
+ "type": "registry:component"
+ }
+ ]
+ },
{
"name": "bubble",
"type": "registry:block",
@@ -46,16 +74,16 @@
"description": "MateChat Bubble",
"files": [
{
- "path": "src/bubble/index.tsx",
+ "path": "src/bubble.tsx",
"type": "registry:component"
},
{
- "path": "src/bubble/markdown.tsx",
+ "path": "src/markdown.tsx",
"type": "registry:component"
},
{
- "path": "src/bubble/hooks.tsx",
- "type": "registry:component"
+ "path": "src/hooks/use-theme.ts",
+ "type": "registry:hook"
}
],
"dependencies": [
diff --git a/scripts/strip-tailwind-registry.ts b/scripts/strip-tailwind-registry.ts
new file mode 100644
index 0000000..c0b043b
--- /dev/null
+++ b/scripts/strip-tailwind-registry.ts
@@ -0,0 +1,35 @@
+import { readdirSync, readFileSync, writeFileSync } from "node:fs";
+import { join } from "node:path";
+
+const registryDir = process.argv[2];
+if (!registryDir) {
+ console.error(
+ "Usage: tsx scripts/strip-tailwind-registry.ts ",
+ );
+ process.exit(1);
+}
+
+const tailwindImportRE = /^import\s+["']\.\.?\/tailwind\.css["'];?\s*\n?/m;
+
+let cleaned = 0;
+for (const file of readdirSync(registryDir)) {
+ if (!file.endsWith(".json") || file === "registry.json") continue;
+ const filePath = join(registryDir, file);
+ const raw = readFileSync(filePath, "utf-8");
+ const data = JSON.parse(raw);
+
+ if (!data.files) continue;
+
+ for (const f of data.files) {
+ if (!f.content) continue;
+ const original = f.content;
+ f.content = f.content.replace(tailwindImportRE, "");
+ if (f.content !== original) {
+ cleaned++;
+ }
+ }
+
+ writeFileSync(filePath, JSON.stringify(data, null, 2), "utf-8");
+}
+
+console.log(`Cleaned ${cleaned} tailwind.css imports across ${registryDir}`);
diff --git a/src/bubble/index.tsx b/src/bubble.tsx
similarity index 98%
rename from src/bubble/index.tsx
rename to src/bubble.tsx
index 4b94f26..4fb91ec 100644
--- a/src/bubble/index.tsx
+++ b/src/bubble.tsx
@@ -1,7 +1,5 @@
-import { cva, type VariantProps } from "class-variance-authority";
-import "../tailwind.css";
-
import type { UIMessage } from "ai";
+import { cva, type VariantProps } from "class-variance-authority";
import clsx from "clsx";
import type React from "react";
import { memo, useCallback, useEffect, useRef } from "react";
@@ -9,10 +7,12 @@ import Markdown from "react-markdown";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import { twMerge } from "tailwind-merge";
-import { BlockQuote, CodeBlock, Heading, Link } from "./markdown";
+import { BlockQuote, CodeBlock, Heading, Link } from "@/markdown";
+
+import "./tailwind.css";
const bubbleVariants = cva(
- "flex flex-col gap-1 justify-center rounded-lg dark:text-gray-200 text-gray-800 max-w-full whitespace-pre-wrap break-words",
+ "flex flex-col gap-1 justify-center rounded-lg dark:text-gray-200 text-gray-800 max-w-full whitespace-pre-wrap wrap-break-word",
{
variants: {
size: {
diff --git a/src/button.tsx b/src/button.tsx
index f7f0f58..963ebe2 100644
--- a/src/button.tsx
+++ b/src/button.tsx
@@ -1,10 +1,10 @@
-import "./tailwind.css";
-
import { cva, type VariantProps } from "class-variance-authority";
import clsx from "clsx";
import type * as React from "react";
import { twMerge } from "tailwind-merge";
+import "./tailwind.css";
+
const buttonVariants = cva(
"cursor-pointer inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors text-white dark:text-white/80",
{
diff --git a/src/file-upload.tsx b/src/file-upload.tsx
index 9015282..5d01e56 100644
--- a/src/file-upload.tsx
+++ b/src/file-upload.tsx
@@ -2,7 +2,7 @@ import clsx from "clsx";
import type React from "react";
import { useCallback, useRef } from "react";
import { twMerge } from "tailwind-merge";
-import Appendix from "./icons/appendix.svg";
+import Appendix from "@/icons/appendix.svg";
export interface FileUploadProps extends React.ComponentProps<"button"> {
onFilesSelect?: (files: File[]) => void;
diff --git a/src/bubble/hooks.tsx b/src/hooks/use-theme.ts
similarity index 95%
rename from src/bubble/hooks.tsx
rename to src/hooks/use-theme.ts
index ef4ab07..dc2c9fb 100644
--- a/src/bubble/hooks.tsx
+++ b/src/hooks/use-theme.ts
@@ -20,7 +20,5 @@ export const useTheme = () => {
};
}, []);
- console.log(isDark);
-
return { isDark };
};
diff --git a/src/index.ts b/src/index.ts
index d0939ad..d874275 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,8 +1,9 @@
export type { UseChatOptions } from "@ai-sdk/react";
export { useChat } from "@ai-sdk/react";
-export * from "./bubble";
-export * from "./button";
-export * from "./file-upload";
-export * from "./list";
-export * from "./prompt";
-export * from "./sender";
+export * from "@/bubble";
+export * from "@/button";
+export * from "@/file-upload";
+export * from "@/list";
+export * from "@/prompt";
+export * from "@/sender";
+export * from "@/suggestion";
diff --git a/src/bubble/markdown.tsx b/src/markdown.tsx
similarity index 98%
rename from src/bubble/markdown.tsx
rename to src/markdown.tsx
index 168e01b..345122b 100644
--- a/src/bubble/markdown.tsx
+++ b/src/markdown.tsx
@@ -5,7 +5,7 @@ import {
oneLight,
vscDarkPlus,
} from "react-syntax-highlighter/dist/esm/styles/prism";
-import { useTheme } from "./hooks";
+import { useTheme } from "@/hooks/use-theme";
export interface HeadingProps extends React.ComponentProps<"h1"> {
level: 1 | 2 | 3 | 4 | 5 | 6;
diff --git a/src/prompt.tsx b/src/prompt.tsx
index a24b53f..3136f38 100644
--- a/src/prompt.tsx
+++ b/src/prompt.tsx
@@ -1,10 +1,10 @@
-import "./tailwind.css";
-
import { cva, type VariantProps } from "class-variance-authority";
import clsx from "clsx";
import type * as React from "react";
import { twMerge } from "tailwind-merge";
+import "./tailwind.css";
+
const promptsVariants = cva("flex", {
variants: {
size: {
diff --git a/src/sender.tsx b/src/sender.tsx
index 832f446..033dd51 100644
--- a/src/sender.tsx
+++ b/src/sender.tsx
@@ -1,10 +1,8 @@
-import "./tailwind.css";
-
import clsx from "clsx";
import { useCallback, useEffect, useRef, useState } from "react";
import { twMerge } from "tailwind-merge";
-import type { TriggerConfig } from "./suggestion";
-import Suggestion from "./suggestion";
+
+import "./tailwind.css";
export interface InputCountProps extends React.ComponentProps<"span"> {
count: number;
@@ -60,7 +58,11 @@ export interface SenderProps extends React.ComponentProps<"div"> {
onMessageChange?: (message: string) => void;
onSend?: () => void;
toolbar?: React.ReactNode;
- triggerConfigs?: TriggerConfig[];
+ suggestion?: (context: {
+ message: string;
+ textareaRef: React.RefObject;
+ onInject: (text: string, position: number) => void;
+ }) => React.ReactNode;
}
export function Sender({
@@ -71,7 +73,7 @@ export function Sender({
sendMessage,
onSend,
toolbar,
- triggerConfigs,
+ suggestion,
...props
}: SenderProps) {
const textareaRef = useRef(null);
@@ -150,12 +152,11 @@ export function Sender({
)}
{...props}
>
-
+ {suggestion?.({
+ message,
+ textareaRef,
+ onInject: handleTextInject,
+ })}