bknd is dead long live userbase
Run Tests / test (pull_request) Successful in 4m57s

This commit is contained in:
2026-09-27 19:34:06 +05:30
parent 05e0086fcd
commit 0bfcb5ad71
529 changed files with 2385 additions and 2924 deletions
+41 -41
View File
@@ -1,4 +1,4 @@
Subject: [PATCH] bknd ui in docs
Subject: [PATCH] userbase ui in docs
---
Index: docs/package.json
IDEA additional info:
@@ -14,7 +14,7 @@ diff --git a/docs/package.json b/docs/package.json
"tailwind-merge": "^3.3.1",
- "twoslash": "^0.3.2"
+ "twoslash": "^0.3.2",
+ "bknd": "file:../app"
+ "userbase": "file:../app"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.11",
@@ -30,7 +30,7 @@ diff --git a/docs/package-lock.json b/docs/package-lock.json
"dependencies": {
"@iconify/react": "^6.0.0",
"@orama/orama": "^3.1.10",
+ "bknd": "file:../app",
+ "userbase": "file:../app",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"fumadocs-core": "^15.6.1",
@@ -39,7 +39,7 @@ diff --git a/docs/package-lock.json b/docs/package-lock.json
}
},
+ "../app": {
+ "name": "bknd",
+ "name": "userbase",
+ "version": "0.18.0-rc.3",
+ "license": "FSL-1.1-MIT",
+ "dependencies": {
@@ -70,7 +70,7 @@ diff --git a/docs/package-lock.json b/docs/package-lock.json
+ "swr": "^2.3.3"
+ },
+ "bin": {
+ "bknd": "dist/cli/index.js"
+ "userbase": "dist/cli/index.js"
+ },
+ "devDependencies": {
+ "@aws-sdk/client-s3": "^3.758.0",
@@ -149,7 +149,7 @@ diff --git a/docs/package-lock.json b/docs/package-lock.json
"dev": true,
"license": "MIT"
},
+ "node_modules/bknd": {
+ "node_modules/userbase": {
+ "resolved": "../app",
+ "link": true
+ },
@@ -187,12 +187,12 @@ new file mode 100644
+tags: ["documentation"]
+---
+import { TypeTable } from 'fumadocs-ui/components/type-table';
+import { Button } from "bknd-ui"
+import { BkndUi } from "@/app/_components/BkndUi";
+import { Button } from "userbase-ui"
+import { UserbaseUi } from "@/app/_components/UserbaseUi";
+
+Describe how to extend the Admin UI.
+
+<BkndUi code={`import { Button } from "bknd/ui"
+<UserbaseUi code={`import { Button } from "userbase/ui"
+
+function ButtonDemo() {
+ return <div className="flex flex-row gap-4">
@@ -230,14 +230,14 @@ new file mode 100644
+ Subtlered
+ </Button>
+ </div>
+</BkndUi>
+</UserbaseUi>
+
+<AutoTypeTable path="../app/src/ui/Admin.tsx" name="BkndAdminProps" />
+<AutoTypeTable path="../app/src/ui/Admin.tsx" name="UserbaseAdminProps" />
+
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="BkndAdminEntityOptions" />
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="BkndAdminEntityFieldOptions" />
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="UserbaseAdminEntityOptions" />
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="UserbaseAdminEntityFieldOptions" />
+
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="BkndAdminAppShellOptions" />
+<AutoTypeTable path="../app/src/ui/options/index.ts" name="UserbaseAdminAppShellOptions" />
\ No newline at end of file
Index: docs/tsconfig.json
IDEA additional info:
@@ -250,38 +250,38 @@ diff --git a/docs/tsconfig.json b/docs/tsconfig.json
@@ -18,6 +18,7 @@
"paths": {
"@/.source": ["./.source/index.ts"],
"@/bknd/*": ["../app/src/"],
+ "bknd-ui": ["../app/dist/ui/index.js"],
"@/userbase/*": ["../app/src/"],
+ "userbase-ui": ["../app/dist/ui/index.js"],
"@/*": ["./*"]
},
Index: docs/app/_components/BkndUi.tsx
Index: docs/app/_components/UserbaseUi.tsx
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/docs/app/_components/BkndUi.tsx b/docs/app/_components/BkndUi.tsx
diff --git a/docs/app/_components/UserbaseUi.tsx b/docs/app/_components/UserbaseUi.tsx
new file mode 100644
--- /dev/null (date 1758280846757)
+++ b/docs/app/_components/BkndUi.tsx (date 1758280846757)
+++ b/docs/app/_components/UserbaseUi.tsx (date 1758280846757)
@@ -0,0 +1,36 @@
+import { readFileSync } from "node:fs";
+import { join } from "node:path";
+import { BkndUiClient } from "./BkndUiClient";
+import { UserbaseUiClient } from "./UserbaseUiClient";
+
+// Server component that reads CSS from disk
+export function BkndUi({ children, code }: { children: React.ReactNode; code?: string }) {
+ let bkndCss = "";
+export function UserbaseUi({ children, code }: { children: React.ReactNode; code?: string }) {
+ let userbaseCss = "";
+
+ try {
+ // Try to read the CSS file from the app directory
+ const cssPath = join(process.cwd(), "node_modules", "bknd", "dist", "ui", "main.css");
+ bkndCss = readFileSync(cssPath, "utf-8");
+ const cssPath = join(process.cwd(), "node_modules", "userbase", "dist", "ui", "main.css");
+ userbaseCss = readFileSync(cssPath, "utf-8");
+ } catch (error) {
+ console.warn("Could not read bknd CSS file:", error);
+ console.warn("Could not read userbase CSS file:", error);
+ // Fallback CSS
+ bkndCss = `
+ .bknd-admin {
+ userbaseCss = `
+ .userbase-admin {
+ --color-primary: #18181b;
+ --color-background: #fafafa;
+ --color-muted: #e4e4e7;
@@ -296,9 +296,9 @@ new file mode 100644
+ }
+
+ return (
+ <BkndUiClient bkndCss={bkndCss} code={code}>
+ <UserbaseUiClient userbaseCss={userbaseCss} code={code}>
+ {children}
+ </BkndUiClient>
+ </UserbaseUiClient>
+ );
+}
Index: docs/next.config.mjs
@@ -311,23 +311,23 @@ diff --git a/docs/next.config.mjs b/docs/next.config.mjs
+++ b/docs/next.config.mjs (date 1758281330764)
@@ -19,6 +19,9 @@
webpack(config) {
config.resolve.alias["@/bknd"] = path.resolve(__dirname, "../app/src");
config.resolve.alias["@/userbase"] = path.resolve(__dirname, "../app/src");
config.resolve.alias["@"] = path.resolve(__dirname);
+
+ // @todo: this doesn't work with turbo
+ config.resolve.alias["bknd-ui"] = path.resolve(__dirname, "../app/dist/ui/index.js");
+ config.resolve.alias["userbase-ui"] = path.resolve(__dirname, "../app/dist/ui/index.js");
return config;
},
eslint: {
Index: docs/app/_components/BkndUiClient.tsx
Index: docs/app/_components/UserbaseUiClient.tsx
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/docs/app/_components/BkndUiClient.tsx b/docs/app/_components/BkndUiClient.tsx
diff --git a/docs/app/_components/UserbaseUiClient.tsx b/docs/app/_components/UserbaseUiClient.tsx
new file mode 100644
--- /dev/null (date 1758281176041)
+++ b/docs/app/_components/BkndUiClient.tsx (date 1758281176041)
+++ b/docs/app/_components/UserbaseUiClient.tsx (date 1758281176041)
@@ -0,0 +1,62 @@
+"use client";
+
@@ -337,13 +337,13 @@ new file mode 100644
+import { DynamicCodeBlock } from "fumadocs-ui/components/dynamic-codeblock";
+import { useTheme } from "next-themes";
+
+interface BkndUiClientProps {
+ bkndCss: string;
+interface UserbaseUiClientProps {
+ userbaseCss: string;
+ children: React.ReactNode;
+ code?: string;
+}
+
+export function BkndUiClient({ bkndCss, children, code }: BkndUiClientProps) {
+export function UserbaseUiClient({ userbaseCss, children, code }: UserbaseUiClientProps) {
+ const { theme } = useTheme();
+ const containerRef = useRef<HTMLDivElement>(null);
+ const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);
@@ -362,26 +362,26 @@ new file mode 100644
+ display: block;
+ isolation: isolate;
+ }
+ ${bkndCss}
+ ${userbaseCss}
+ `;
+
+ shadow.appendChild(style);
+
+ // Create mount point for React content
+ const mount = document.createElement("div");
+ mount.className = `bknd-admin ${theme}`;
+ mount.className = `userbase-admin ${theme}`;
+ shadow.appendChild(mount);
+
+ setShadowRoot(shadow);
+ setMountPoint(mount);
+ }, [shadowRoot, bkndCss]);
+ }, [shadowRoot, userbaseCss]);
+
+ return (
+ <>
+ {/* @ts-ignore */}
+ <Card className="p-0">
+ <div className="flex flex-col justify-center items-center p-4">
+ <div ref={containerRef} className="bknd-ui-shadow-host">
+ <div ref={containerRef} className="userbase-ui-shadow-host">
+ <div>Loading...</div>
+ {shadowRoot && mountPoint && createPortal(children, mountPoint)}
+ </div>