chore: Remove unused code from ui-library (#38374)

* Remove unneeded code.

* Remove more unused code.

* Update knip.jsonc for ui-library.

* Remove unneeded imports. Change the registry generation to only generate what's needed.

* Cleanup the rehype middleware (it wasn't used). Clean up the example blocks generation.

* Don't show the "show code" button in all dropzone examples.
This commit is contained in:
Ivan Vasilov
2025-09-02 15:36:41 +02:00
committed by GitHub
parent 0d224c3aae
commit 501918857b
41 changed files with 49 additions and 2208 deletions

View File

@@ -1,527 +1,43 @@
// @ts-nocheck
// This file is autogenerated by scripts/build-registry.ts
// This file is autogenerated by scripts/build-registry.mts
// Do not edit this file directly.
import * as React from "react"
export const Index: Record<string, any> = {
export const Index = {
"default": {
"password-based-auth-nextjs": {
name: "password-based-auth-nextjs",
type: "registry:block",
registryDependencies: ["button","card","input","label"],
component: React.lazy(() => import("@/registry/default/blocks/password-based-auth-nextjs/app/auth/login/page.tsx")),
source: "",
files: ["registry/default/blocks/password-based-auth-nextjs/app/auth/login/page.tsx","registry/default/blocks/password-based-auth-nextjs/app/auth/error/page.tsx","registry/default/blocks/password-based-auth-nextjs/app/protected/page.tsx","registry/default/blocks/password-based-auth-nextjs/app/auth/confirm/route.ts","registry/default/blocks/password-based-auth-nextjs/components/login-form.tsx","registry/default/blocks/password-based-auth-nextjs/middleware.ts","registry/default/blocks/password-based-auth-nextjs/app/auth/sign-up/page.tsx","registry/default/blocks/password-based-auth-nextjs/app/auth/sign-up-success/page.tsx","registry/default/blocks/password-based-auth-nextjs/components/sign-up-form.tsx","registry/default/blocks/password-based-auth-nextjs/app/auth/forgot-password/page.tsx","registry/default/blocks/password-based-auth-nextjs/app/auth/update-password/page.tsx","registry/default/blocks/password-based-auth-nextjs/components/forgot-password-form.tsx","registry/default/blocks/password-based-auth-nextjs/components/update-password-form.tsx","registry/default/blocks/password-based-auth-nextjs/components/logout-button.tsx","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"password-based-auth-react": {
name: "password-based-auth-react",
type: "registry:block",
registryDependencies: ["button","card","input","label"],
component: React.lazy(() => import("@/registry/default/blocks/password-based-auth-react/components/login-form.tsx")),
source: "",
files: ["registry/default/blocks/password-based-auth-react/components/login-form.tsx","registry/default/blocks/password-based-auth-react/components/sign-up-form.tsx","registry/default/blocks/password-based-auth-react/components/forgot-password-form.tsx","registry/default/blocks/password-based-auth-react/components/update-password-form.tsx","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"password-based-auth-react-router": {
name: "password-based-auth-react-router",
type: "registry:block",
registryDependencies: ["button","card","input","label"],
component: React.lazy(() => import("@/registry/default/blocks/password-based-auth-react-router/app/routes/auth.confirm.tsx")),
source: "",
files: ["registry/default/blocks/password-based-auth-react-router/app/routes/auth.confirm.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/auth.error.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/forgot-password.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/login.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/logout.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/protected.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/sign-up.tsx","registry/default/blocks/password-based-auth-react-router/app/routes/update-password.tsx","registry/default/blocks/password-based-auth-react-router/app/routes.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"password-based-auth-tanstack": {
name: "password-based-auth-tanstack",
type: "registry:block",
registryDependencies: ["button","card","input","label"],
component: React.lazy(() => import("@/registry/default/blocks/password-based-auth-tanstack/routes/login.tsx")),
source: "",
files: ["registry/default/blocks/password-based-auth-tanstack/routes/login.tsx","registry/default/blocks/password-based-auth-tanstack/routes/auth/error.tsx","registry/default/blocks/password-based-auth-tanstack/routes/_protected.tsx","registry/default/blocks/password-based-auth-tanstack/routes/_protected/protected.tsx","registry/default/blocks/password-based-auth-tanstack/routes/auth/confirm.ts","registry/default/blocks/password-based-auth-tanstack/components/login-form.tsx","registry/default/blocks/password-based-auth-tanstack/routes/sign-up.tsx","registry/default/blocks/password-based-auth-tanstack/routes/sign-up-success.tsx","registry/default/blocks/password-based-auth-tanstack/components/sign-up-form.tsx","registry/default/blocks/password-based-auth-tanstack/routes/forgot-password.tsx","registry/default/blocks/password-based-auth-tanstack/routes/update-password.tsx","registry/default/blocks/password-based-auth-tanstack/components/forgot-password-form.tsx","registry/default/blocks/password-based-auth-tanstack/components/update-password-form.tsx","registry/default/blocks/password-based-auth-tanstack/lib/supabase/fetch-user-server-fn.ts","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"social-auth-nextjs": {
name: "social-auth-nextjs",
type: "registry:block",
registryDependencies: ["button","card"],
component: React.lazy(() => import("@/registry/default/blocks/social-auth-nextjs/app/auth/login/page.tsx")),
source: "",
files: ["registry/default/blocks/social-auth-nextjs/app/auth/login/page.tsx","registry/default/blocks/social-auth-nextjs/app/auth/error/page.tsx","registry/default/blocks/social-auth-nextjs/app/protected/page.tsx","registry/default/blocks/social-auth-nextjs/app/auth/oauth/route.ts","registry/default/blocks/social-auth-nextjs/components/login-form.tsx","registry/default/blocks/social-auth-nextjs/middleware.ts","registry/default/blocks/social-auth-nextjs/components/logout-button.tsx","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"social-auth-react": {
name: "social-auth-react",
type: "registry:block",
registryDependencies: ["button","card"],
component: React.lazy(() => import("@/registry/default/blocks/social-auth-react/components/login-form.tsx")),
source: "",
files: ["registry/default/blocks/social-auth-react/components/login-form.tsx","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"social-auth-react-router": {
name: "social-auth-react-router",
type: "registry:block",
registryDependencies: ["button","card"],
component: React.lazy(() => import("@/registry/default/blocks/social-auth-react-router/app/routes/auth.error.tsx")),
source: "",
files: ["registry/default/blocks/social-auth-react-router/app/routes/auth.error.tsx","registry/default/blocks/social-auth-react-router/app/routes/auth.oauth.tsx","registry/default/blocks/social-auth-react-router/app/routes/login.tsx","registry/default/blocks/social-auth-react-router/app/routes/logout.tsx","registry/default/blocks/social-auth-react-router/app/routes/protected.tsx","registry/default/blocks/social-auth-react-router/app/routes.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"social-auth-tanstack": {
name: "social-auth-tanstack",
type: "registry:block",
registryDependencies: ["button","card"],
component: React.lazy(() => import("@/registry/default/blocks/social-auth-tanstack/components/login-form.tsx")),
source: "",
files: ["registry/default/blocks/social-auth-tanstack/components/login-form.tsx","registry/default/blocks/social-auth-tanstack/lib/supabase/fetch-user-server-fn.ts","registry/default/blocks/social-auth-tanstack/routes/_protected.tsx","registry/default/blocks/social-auth-tanstack/routes/_protected/protected.tsx","registry/default/blocks/social-auth-tanstack/routes/auth/error.tsx","registry/default/blocks/social-auth-tanstack/routes/auth/oauth.ts","registry/default/blocks/social-auth-tanstack/routes/login.tsx","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"dropzone-nextjs": {
name: "dropzone-nextjs",
type: "registry:component",
registryDependencies: ["button"],
component: React.lazy(() => import("@/registry/default/blocks/dropzone/components/dropzone.tsx")),
source: "",
files: ["registry/default/blocks/dropzone/components/dropzone.tsx","registry/default/blocks/dropzone/hooks/use-supabase-upload.ts","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"dropzone-react": {
name: "dropzone-react",
type: "registry:component",
registryDependencies: ["button"],
component: React.lazy(() => import("@/registry/default/blocks/dropzone/components/dropzone.tsx")),
source: "",
files: ["registry/default/blocks/dropzone/components/dropzone.tsx","registry/default/blocks/dropzone/hooks/use-supabase-upload.ts","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"dropzone-react-router": {
name: "dropzone-react-router",
type: "registry:component",
registryDependencies: ["button"],
component: React.lazy(() => import("@/registry/default/blocks/dropzone/components/dropzone.tsx")),
source: "",
files: ["registry/default/blocks/dropzone/components/dropzone.tsx","registry/default/blocks/dropzone/hooks/use-supabase-upload.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"dropzone-tanstack": {
name: "dropzone-tanstack",
type: "registry:component",
registryDependencies: ["button"],
component: React.lazy(() => import("@/registry/default/blocks/dropzone/components/dropzone.tsx")),
source: "",
files: ["registry/default/blocks/dropzone/components/dropzone.tsx","registry/default/blocks/dropzone/hooks/use-supabase-upload.ts","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-cursor-nextjs": {
name: "realtime-cursor-nextjs",
type: "registry:component",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/blocks/realtime-cursor/components/cursor.tsx")),
source: "",
files: ["registry/default/blocks/realtime-cursor/components/cursor.tsx","registry/default/blocks/realtime-cursor/components/realtime-cursors.tsx","registry/default/blocks/realtime-cursor/hooks/use-realtime-cursors.ts","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-cursor-react": {
name: "realtime-cursor-react",
type: "registry:component",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/blocks/realtime-cursor/components/cursor.tsx")),
source: "",
files: ["registry/default/blocks/realtime-cursor/components/cursor.tsx","registry/default/blocks/realtime-cursor/components/realtime-cursors.tsx","registry/default/blocks/realtime-cursor/hooks/use-realtime-cursors.ts","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-cursor-react-router": {
name: "realtime-cursor-react-router",
type: "registry:component",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/blocks/realtime-cursor/components/cursor.tsx")),
source: "",
files: ["registry/default/blocks/realtime-cursor/components/cursor.tsx","registry/default/blocks/realtime-cursor/components/realtime-cursors.tsx","registry/default/blocks/realtime-cursor/hooks/use-realtime-cursors.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-cursor-tanstack": {
name: "realtime-cursor-tanstack",
type: "registry:component",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/blocks/realtime-cursor/components/cursor.tsx")),
source: "",
files: ["registry/default/blocks/realtime-cursor/components/cursor.tsx","registry/default/blocks/realtime-cursor/components/realtime-cursors.tsx","registry/default/blocks/realtime-cursor/hooks/use-realtime-cursors.ts","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-nextjs": {
name: "current-user-avatar-nextjs",
type: "registry:component",
registryDependencies: ["avatar"],
component: React.lazy(() => import("@/registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx")),
source: "",
files: ["registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-react": {
name: "current-user-avatar-react",
type: "registry:component",
registryDependencies: ["avatar"],
component: React.lazy(() => import("@/registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx")),
source: "",
files: ["registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-react-router": {
name: "current-user-avatar-react-router",
type: "registry:component",
registryDependencies: ["avatar"],
component: React.lazy(() => import("@/registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx")),
source: "",
files: ["registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-tanstack": {
name: "current-user-avatar-tanstack",
type: "registry:component",
registryDependencies: ["avatar"],
component: React.lazy(() => import("@/registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx")),
source: "",
files: ["registry/default/blocks/current-user-avatar/components/current-user-avatar.tsx","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-nextjs": {
name: "realtime-avatar-stack-nextjs",
type: "registry:component",
registryDependencies: ["avatar","tooltip"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx")),
source: "",
files: ["registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/components/realtime-avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/hooks/use-realtime-presence-room.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-react": {
name: "realtime-avatar-stack-react",
type: "registry:component",
registryDependencies: ["avatar","tooltip"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx")),
source: "",
files: ["registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/components/realtime-avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/hooks/use-realtime-presence-room.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-react-router": {
name: "realtime-avatar-stack-react-router",
type: "registry:component",
registryDependencies: ["avatar","tooltip"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx")),
source: "",
files: ["registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/components/realtime-avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/hooks/use-realtime-presence-room.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-tanstack": {
name: "realtime-avatar-stack-tanstack",
type: "registry:component",
registryDependencies: ["avatar","tooltip"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx")),
source: "",
files: ["registry/default/blocks/realtime-avatar-stack/components/avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/components/realtime-avatar-stack.tsx","registry/default/blocks/realtime-avatar-stack/hooks/use-realtime-presence-room.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-name.ts","registry/default/blocks/current-user-avatar/hooks/use-current-user-image.ts","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-chat-nextjs": {
name: "realtime-chat-nextjs",
type: "registry:component",
registryDependencies: ["input","button"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-chat/components/chat-message.tsx")),
source: "",
files: ["registry/default/blocks/realtime-chat/components/chat-message.tsx","registry/default/blocks/realtime-chat/components/realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-chat-scroll.tsx","registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-chat-react": {
name: "realtime-chat-react",
type: "registry:component",
registryDependencies: ["input","button"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-chat/components/chat-message.tsx")),
source: "",
files: ["registry/default/blocks/realtime-chat/components/chat-message.tsx","registry/default/blocks/realtime-chat/components/realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-chat-scroll.tsx","registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-chat-react-router": {
name: "realtime-chat-react-router",
type: "registry:component",
registryDependencies: ["input","button"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-chat/components/chat-message.tsx")),
source: "",
files: ["registry/default/blocks/realtime-chat/components/chat-message.tsx","registry/default/blocks/realtime-chat/components/realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-chat-scroll.tsx","registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-chat-tanstack": {
name: "realtime-chat-tanstack",
type: "registry:component",
registryDependencies: ["input","button"],
component: React.lazy(() => import("@/registry/default/blocks/realtime-chat/components/chat-message.tsx")),
source: "",
files: ["registry/default/blocks/realtime-chat/components/chat-message.tsx","registry/default/blocks/realtime-chat/components/realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-realtime-chat.tsx","registry/default/blocks/realtime-chat/hooks/use-chat-scroll.tsx","registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"infinite-query-hook": {
name: "infinite-query-hook",
type: "registry:block",
registryDependencies: [],
source: "",
files: ["registry/default/blocks/infinite-query-hook/hooks/use-infinite-query.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"supabase-client-nextjs": {
name: "supabase-client-nextjs",
type: "registry:lib",
registryDependencies: [],
source: "",
files: ["registry/default/clients/nextjs/lib/supabase/client.ts","registry/default/clients/nextjs/lib/supabase/middleware.ts","registry/default/clients/nextjs/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"supabase-client-react": {
name: "supabase-client-react",
type: "registry:lib",
registryDependencies: [],
source: "",
files: ["registry/default/clients/react/lib/supabase/client.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"supabase-client-react-router": {
name: "supabase-client-react-router",
type: "registry:lib",
registryDependencies: [],
source: "",
files: ["registry/default/clients/react-router/lib/supabase/client.ts","registry/default/clients/react-router/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"supabase-client-tanstack": {
name: "supabase-client-tanstack",
type: "registry:lib",
registryDependencies: [],
source: "",
files: ["registry/default/clients/tanstack/lib/supabase/client.ts","registry/default/clients/tanstack/lib/supabase/server.ts"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"platform-kit-nextjs": {
name: "platform-kit-nextjs",
type: "registry:block",
registryDependencies: ["alert","badge","button","card","chart","command","dialog","drawer","form","hover-card","input","label","popover","select","skeleton","switch","table","toggle","toggle-group","tooltip"],
component: React.lazy(() => import("@/registry/default/platform/platform-kit-nextjs/components/dynamic-form.tsx")),
source: "",
files: ["registry/default/platform/platform-kit-nextjs/app/api/ai/sql/route.ts","registry/default/platform/platform-kit-nextjs/app/api/supabase-proxy/[...path]/route.ts","registry/default/platform/platform-kit-nextjs/components/dynamic-form.tsx","registry/default/platform/platform-kit-nextjs/components/logo-supabase.tsx","registry/default/platform/platform-kit-nextjs/components/results-table.tsx","registry/default/platform/platform-kit-nextjs/components/sql-editor.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/auth.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/database.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/index.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/logs.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/secrets.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/storage.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/suggestions.tsx","registry/default/platform/platform-kit-nextjs/components/supabase-manager/users.tsx","registry/default/platform/platform-kit-nextjs/components/users-growth-chart.tsx","registry/default/platform/platform-kit-nextjs/hooks/use-auth.ts","registry/default/platform/platform-kit-nextjs/hooks/use-logs.ts","registry/default/platform/platform-kit-nextjs/hooks/use-run-query.ts","registry/default/platform/platform-kit-nextjs/hooks/use-secrets.ts","registry/default/platform/platform-kit-nextjs/hooks/use-storage.ts","registry/default/platform/platform-kit-nextjs/hooks/use-suggestions.ts","registry/default/platform/platform-kit-nextjs/hooks/use-tables.ts","registry/default/platform/platform-kit-nextjs/hooks/use-user-counts.ts","registry/default/platform/platform-kit-nextjs/lib/logs.ts","registry/default/platform/platform-kit-nextjs/lib/management-api-schema.d.ts","registry/default/platform/platform-kit-nextjs/lib/management-api.ts","registry/default/platform/platform-kit-nextjs/lib/pg-meta/sql.ts","registry/default/platform/platform-kit-nextjs/lib/pg-meta/index.ts","registry/default/platform/platform-kit-nextjs/lib/pg-meta/types.ts","registry/default/platform/platform-kit-nextjs/lib/schemas/auth.ts","registry/default/platform/platform-kit-nextjs/lib/schemas/secrets.ts","registry/default/platform/platform-kit-nextjs/contexts/SheetNavigationContext.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"ai-editor-rules": {
name: "ai-editor-rules",
type: "registry:file",
registryDependencies: [],
source: "",
files: ["registry/default/ai-editor-rules/create-db-functions.mdc","registry/default/ai-editor-rules/create-migration.mdc","registry/default/ai-editor-rules/create-rls-policies.mdc","registry/default/ai-editor-rules/postgres-sql-style-guide.mdc","registry/default/ai-editor-rules/writing-supabase-edge-functions.mdc","registry/default/ai-editor-rules/use-realtime.mdc"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"dropzone-demo": {
name: "dropzone-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/dropzone-demo.tsx")),
source: "",
files: ["registry/default/examples/dropzone-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-cursor-demo": {
name: "realtime-cursor-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/realtime-cursor-demo.tsx")),
source: "",
files: ["registry/default/examples/realtime-cursor-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"password-based-auth-demo": {
name: "password-based-auth-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/password-based-auth.tsx")),
source: "",
files: ["registry/default/examples/password-based-auth.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-demo": {
name: "current-user-avatar-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/current-user-avatar-demo.tsx")),
source: "",
files: ["registry/default/examples/current-user-avatar-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"current-user-avatar-preview": {
name: "current-user-avatar-preview",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/current-user-avatar-preview.tsx")),
source: "",
files: ["registry/default/examples/current-user-avatar-preview.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-demo": {
name: "realtime-avatar-stack-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/realtime-avatar-stack-demo.tsx")),
source: "",
files: ["registry/default/examples/realtime-avatar-stack-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"realtime-avatar-stack-preview": {
name: "realtime-avatar-stack-preview",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/realtime-avatar-stack-preview.tsx")),
source: "",
files: ["registry/default/examples/realtime-avatar-stack-preview.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
,
"infinite-query-hook-demo": {
name: "infinite-query-hook-demo",
type: "registry:example",
registryDependencies: [],
component: React.lazy(() => import("@/registry/default/examples/infinite-query-hook-demo.tsx")),
source: "",
files: ["registry/default/examples/infinite-query-hook-demo.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
}
},
}
} as const

View File

@@ -19,11 +19,3 @@ export const BlockItem = ({ name }: BlockItemProps) => {
</div>
)
}
export const BlockItemPreview = ({ title, src }: { title: string; src: string }) => {
return (
<div className="flex items-center justify-center relative border rounded-lg">
<iframe src={src} className="w-full h-[600px] border-0 rounded-md" title={title} />
</div>
)
}

View File

@@ -1,18 +0,0 @@
import * as React from 'react'
const ClassLabel = React.forwardRef<HTMLSpanElement, { children: React.ReactNode }>(
({ children }, ref) => {
return (
<span
ref={ref}
className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground"
>
{children}
</span>
)
}
)
ClassLabel.displayName = 'ClassLabel'
export { ClassLabel }

View File

@@ -1,16 +0,0 @@
'use client'
import { useState } from 'react'
export function ClickCounter() {
const [count, setCount] = useState(0)
return (
<button
onClick={() => setCount(count + 1)}
className="whitespace-nowrap rounded-lg bg-gray-700 px-3 py-1 text-sm font-medium tabular-nums text-gray-100 hover:bg-gray-500 hover:text-white"
>
{count} Clicks
</button>
)
}

View File

@@ -1,53 +0,0 @@
'use client'
import * as React from 'react'
import { cn } from 'ui'
import { Button } from 'ui'
import {
Collapsible_Shadcn_ as Collapsible,
CollapsibleContent_Shadcn_ as CollapsibleContent,
CollapsibleTrigger_Shadcn_ as CollapsibleTrigger,
} from 'ui'
interface CodeBlockProps extends React.HTMLAttributes<HTMLDivElement> {
expandButtonTitle?: string
}
export function CodeBlockWrapper({
expandButtonTitle = 'View Code',
className,
children,
...props
}: CodeBlockProps) {
const [isOpened, setIsOpened] = React.useState(false)
return (
<Collapsible open={isOpened} onOpenChange={setIsOpened}>
<div className={cn('relative overflow-hidden', className)} {...props}>
<CollapsibleContent forceMount className={cn('overflow-hidden', !isOpened && 'max-h-32')}>
<div
className={cn(
'[&_pre]:my-0 [&_pre]:max-h-[650px] [&_pre]:pb-[100px]',
!isOpened ? '[&_pre]:overflow-hidden' : '[&_pre]:overflow-auto]'
)}
>
{children}
</div>
</CollapsibleContent>
<div
className={cn(
'absolute flex items-center justify-center bg-gradient-to-b from-zinc-700/30 to-zinc-950/90 p-2',
isOpened ? 'inset-x-0 bottom-0 h-12' : 'inset-0'
)}
>
<CollapsibleTrigger asChild>
<Button type="secondary" className="h-8 text-xs">
{isOpened ? 'Collapse' : expandButtonTitle}
</Button>
</CollapsibleTrigger>
</div>
</div>
</Collapsible>
)
}

View File

@@ -1,105 +0,0 @@
'use client'
import { Index } from '@/__registry__'
import * as React from 'react'
import { useConfig } from '@/hooks/use-config'
import { cn } from 'ui'
import { styles } from '@/registry/styles'
interface ComponentPreviewProps extends React.HTMLAttributes<HTMLDivElement> {
name: string
extractClassname?: boolean
extractedClassNames?: string
align?: 'center' | 'start' | 'end'
showGrid?: boolean
showDottedGrid?: boolean
wide?: boolean
}
export function CodeFragment({
name,
children,
className,
extractClassname,
extractedClassNames,
align = 'center',
showGrid = false,
showDottedGrid = true,
wide = false,
...props
}: ComponentPreviewProps) {
const [config] = useConfig()
const index = styles.findIndex((style) => style.name === config.style)
const Codes = React.Children.toArray(children) as React.ReactElement[]
const Code = Codes[index]
const [expand, setExpandState] = React.useState(false)
const Preview = React.useMemo(() => {
// console.log('Index', Index)
// console.log('name', name)
// console.log('config.style', config.style)
const Component = Index[config.style][name]?.component
// const Component = Index[name]?.component
if (!Component) {
return (
<p className="text-sm text-muted-foreground">
Code fragment{' '}
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
{name}
</code>{' '}
not found in registry.
</p>
)
}
return <Component />
}, [name, config.style])
const ComponentPreview = React.useMemo(() => {
return (
<>
<div
className={cn('preview flex min-h-[350px] w-full justify-center p-10', {
'items-center': align === 'center',
'items-start': align === 'start',
'items-end': align === 'end',
})}
>
<React.Suspense
fallback={
<div className="flex items-center text-sm text-muted-foreground">Loading...</div>
}
>
{Preview}
</React.Suspense>
</div>
</>
)
}, [Preview, align])
const wideClasses = wide ? '2xl:-ml-12 2xl:-mr-12' : ''
return (
<div className={cn('mt-4 mb-12', wideClasses)}>
<div
className={cn(
'relative rounded-md border-t border-l border-r border-b bg-studio overflow-hidden'
)}
>
{showGrid && (
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
)}
{showDottedGrid && (
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
)}
<div className="z-10 relative">{ComponentPreview}</div>
</div>
</div>
)
}

View File

@@ -1,97 +0,0 @@
'use client'
import * as React from 'react'
import { cn } from 'ui'
import {
// CopyButton,
CopyWithClassNames,
} from '@/components/copy-button'
import {
Tabs_Shadcn_ as Tabs,
TabsContent_Shadcn_ as TabsContent,
TabsList_Shadcn_ as TabsList,
TabsTrigger_Shadcn_ as TabsTrigger,
} from 'ui'
interface ComponentExampleProps extends React.HTMLAttributes<HTMLDivElement> {
extractClassname?: boolean
extractedClassNames?: string
align?: 'center' | 'start' | 'end'
src?: string
}
export function ComponentExample({
children,
className,
extractClassname,
extractedClassNames,
align = 'center',
src: _,
...props
}: ComponentExampleProps) {
const [Example, Code, ...Children] = React.Children.toArray(children) as React.ReactElement[]
const codeString = React.useMemo(() => {
if (typeof Code?.props['data-rehype-pretty-code-fragment'] !== 'undefined') {
const [, Button] = React.Children.toArray(Code.props.children) as React.ReactElement[]
return Button?.props?.value || Button?.props?.__rawString__ || null
}
}, [Code])
return (
<div className={cn('group relative my-4 flex flex-col gap-2', className)} {...props}>
<Tabs defaultValue="preview" className="relative mr-auto w-full">
<div className="flex items-center justify-between pb-3">
<TabsList className="w-full justify-start rounded-none border-b bg-transparent p-0">
<TabsTrigger
value="preview"
className="relative 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"
>
Preview
</TabsTrigger>
<TabsTrigger
value="code"
className="relative 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"
>
Code
</TabsTrigger>
</TabsList>
{
extractedClassNames ? (
<CopyWithClassNames
value={codeString}
classNames={extractedClassNames}
className="absolute right-4 top-20"
/>
) : undefined
// codeString && <CopyButton value={codeString} className="absolute right-4 top-20" />
}
</div>
<TabsContent value="preview" className="rounded-md border">
<div
className={cn('flex min-h-[350px] justify-center p-10', {
'items-center': align === 'center',
'items-start': align === 'start',
'items-end': align === 'end',
})}
>
{Example}
</div>
</TabsContent>
<TabsContent value="code">
<div className="flex flex-col space-y-4">
<div className="w-full rounded-md [&_button]:hidden [&_pre]:my-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
{Code}
</div>
{Children?.length ? (
<div className="rounded-md [&_button]:hidden [&_pre]:my-0 [&_pre]:max-h-[350px] [&_pre]:overflow-auto">
{Children}
</div>
) : null}
</div>
</TabsContent>
</Tabs>
</div>
)
}

View File

@@ -10,7 +10,7 @@ import { styles } from '@/registry/styles'
import { ChevronRight } from 'lucide-react'
interface ComponentPreviewProps extends React.HTMLAttributes<HTMLDivElement> {
name: string
name: keyof (typeof Index)['default']
extractClassname?: boolean
extractedClassNames?: string
align?: 'center' | 'start' | 'end'
@@ -36,8 +36,6 @@ export function ComponentPreview({
const [config] = useConfig()
const index = styles.findIndex((style) => style.name === config.style)
const [expand, setExpandState] = React.useState(false)
const Preview = React.useMemo(() => {
const Component = Index['default'][name]?.component

View File

@@ -1,58 +0,0 @@
import fs from 'fs'
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from 'ui'
// import { parse } from 'react-docgen'
export function ComponentProps(props: any) {
// map through all props types for this component DropdownMenu
// return a table with the prop name, type, default value, and description
// const code = `
// /** My first component */
// export default ({ name }: { name: string }) => <div>{{name}}</div>;
// `
// const documentation = parse(code)
//
// console.log(documentation)
// console.log('from the component props', JSON.parse(props.docs))
const docs = JSON.parse(props.docs)
// console.log(docs.props)
return (
<div className="space-y-2">
<p className="font-medium text-foreground-light">{props.children}</p>
<Table>
<TableHeader>
<TableRow>
<TableHead className="font-mono uppercase text-xs font-normal">Prop Name</TableHead>
<TableHead className="font-mono uppercase text-xs font-normal">Required</TableHead>
<TableHead className="font-mono uppercase text-xs font-normal">Type</TableHead>
<TableHead className="font-mono uppercase text-xs text-right font-normal">
Description
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Object.entries(docs.props).map(([propName, prop], index) => (
<TableRow key={index}>
<TableCell>{propName}</TableCell>
{/*
// @ts-ignore */}
<TableCell>{prop.required ? 'Yes' : 'No'}</TableCell>
{/*
// @ts-ignore */}
<TableCell>{prop.flowType.name}</TableCell>
{/*
// @ts-ignore */}
<TableCell className="text-right">{prop.description}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
)
}

View File

@@ -1,21 +0,0 @@
'use client'
import * as React from 'react'
import { cn } from 'ui'
import { CodeBlockWrapper } from '@/components/code-block-wrapper'
interface ComponentSourceProps extends React.HTMLAttributes<HTMLDivElement> {
src: string
}
export function ComponentSource({ children, className, ...props }: ComponentSourceProps) {
return (
<CodeBlockWrapper
expandButtonTitle="Expand"
className={cn('my-6 overflow-hidden rounded-md', className)}
>
{children}
</CodeBlockWrapper>
)
}

View File

@@ -1,45 +1,16 @@
'use client'
import { Check, Copy } from 'lucide-react'
import * as React from 'react'
// import { NpmCommands } from 'types/unist'
// import { Event, trackEvent } from '@/lib/events'
import { Check, Copy } from 'lucide-react'
import {
Button,
cn,
copyToClipboard,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuTriggerProps,
} from 'ui'
import { Button, cn, copyToClipboard } from 'ui'
interface CopyButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
value: string
src?: string
// event?: Event['name']
}
export async function copyToClipboardWithMeta(
value: string
// event?: Event
) {
copyToClipboard(value)
if (event) {
// trackEvent(event)
}
}
export function CopyButton({
value,
className,
src,
// event,
...props
}: CopyButtonProps) {
export function CopyButton({ value, className, src, ...props }: CopyButtonProps) {
const [hasCopied, setHasCopied] = React.useState(false)
React.useEffect(() => {
@@ -57,17 +28,7 @@ export function CopyButton({
className
)}
onClick={() => {
copyToClipboardWithMeta(
value
// event
// ? {
// name: event,
// properties: {
// code: value,
// },
// }
// : undefined
)
copyToClipboard(value)
setHasCopied(true)
}}
{...props}
@@ -77,109 +38,3 @@ export function CopyButton({
</Button>
)
}
interface CopyWithClassNamesProps extends DropdownMenuTriggerProps {
value: string
classNames: string
className?: string
}
export function CopyWithClassNames({
value,
classNames,
className,
...props
}: CopyWithClassNamesProps) {
const [hasCopied, setHasCopied] = React.useState(false)
React.useEffect(() => {
setTimeout(() => {
setHasCopied(false)
}, 2000)
}, [hasCopied])
const copyToClipboard = React.useCallback((value: string) => {
copyToClipboardWithMeta(value)
setHasCopied(true)
}, [])
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
size="small"
type="outline"
className={cn(
'relative z-10 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50',
className
)}
>
{hasCopied ? <Check className="h-3 w-3" /> : <Copy className="h-3 w-3" />}
<span className="sr-only">Copy</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem onClick={() => copyToClipboard(value)}>Component</DropdownMenuItem>
<DropdownMenuItem onClick={() => copyToClipboard(classNames)}>Classname</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)
}
interface CopyNpmCommandButtonProps extends DropdownMenuTriggerProps {
// commands: Required<NpmCommands>
}
// export function CopyNpmCommandButton({ commands, className, ...props }: CopyNpmCommandButtonProps) {
// const [hasCopied, setHasCopied] = React.useState(false)
// React.useEffect(() => {
// setTimeout(() => {
// setHasCopied(false)
// }, 2000)
// }, [hasCopied])
// // const copyCommand = React.useCallback((value: string, pm: 'npm' | 'pnpm' | 'yarn' | 'bun') => {
// // copyToClipboardWithMeta(value,
// // // {
// // // name: 'copy_npm_command',
// // // properties: {
// // // command: value,
// // // pm,
// // // },
// // })
// // setHasCopied(true)
// // }, [])
// return (
// <DropdownMenu>
// <DropdownMenuTrigger asChild>
// <Button
// // size="icon"
// type="outline"
// className={cn(
// 'relative z-10 h-6 w-6 text-zinc-50 hover:bg-zinc-700 hover:text-zinc-50',
// className
// )}
// >
// {hasCopied ? <CheckIcon className="h-3 w-3" /> : <CopyIcon className="h-3 w-3" />}
// <span className="sr-only">Copy</span>
// </Button>
// </DropdownMenuTrigger>
// <DropdownMenuContent align="end">
// <DropdownMenuItem onClick={() => copyCommand(commands.__npmCommand__, 'npm')}>
// npm
// </DropdownMenuItem>
// <DropdownMenuItem onClick={() => copyCommand(commands.__yarnCommand__, 'yarn')}>
// yarn
// </DropdownMenuItem>
// <DropdownMenuItem onClick={() => copyCommand(commands.__pnpmCommand__, 'pnpm')}>
// pnpm
// </DropdownMenuItem>
// <DropdownMenuItem onClick={() => copyCommand(commands.__bunCommand__, 'bun')}>
// bun
// </DropdownMenuItem>
// </DropdownMenuContent>
// </DropdownMenu>
// )
// }

View File

@@ -1,15 +0,0 @@
import * as React from 'react'
const ExampleLabel = React.forwardRef<HTMLSpanElement, { children: React.ReactNode }>(
({ children }, ref) => {
return (
<span ref={ref} className="text-xs flex gap-3 items-center text-foreground-muted">
{children}
</span>
)
}
)
ExampleLabel.displayName = 'ExampleLabel'
export { ExampleLabel }

View File

@@ -1,66 +0,0 @@
'use client'
import { cva } from 'class-variance-authority'
import { FileIcon, FolderIcon, FolderOpen } from 'lucide-react'
import { useState, type HTMLAttributes, type ReactNode } from 'react'
import { cn, Collapsible_Shadcn_, CollapsibleContent_Shadcn_, CollapsibleTrigger_Shadcn_ } from 'ui'
const itemVariants = cva(
'flex flex-row items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-fd-accent hover:text-fd-accent-foreground [&_svg]:size-4'
)
export function Files({ className, ...props }: HTMLAttributes<HTMLDivElement>): React.ReactElement {
return (
<div className={cn('not-prose rounded-md border bg-fd-card p-2', className)} {...props}>
{props.children}
</div>
)
}
export interface FileProps extends HTMLAttributes<HTMLDivElement> {
name: string
icon?: ReactNode
}
export interface FolderProps extends HTMLAttributes<HTMLDivElement> {
name: string
disabled?: boolean
/**
* Open folder by default
*
* @defaultValue false
*/
defaultOpen?: boolean
}
export function File({
name,
icon = <FileIcon />,
className,
...rest
}: FileProps): React.ReactElement {
return (
<div className={cn(itemVariants({ className }))} {...rest}>
{icon}
{name}
</div>
)
}
export function Folder({ name, defaultOpen = false, ...props }: FolderProps): React.ReactElement {
const [open, setOpen] = useState(defaultOpen)
return (
<Collapsible_Shadcn_ open={open} onOpenChange={setOpen} {...props}>
<CollapsibleTrigger_Shadcn_ className={cn(itemVariants({ className: 'w-full' }))}>
{open ? <FolderOpen /> : <FolderIcon />}
{name}
</CollapsibleTrigger_Shadcn_>
<CollapsibleContent_Shadcn_>
<div className="ms-2 flex flex-col border-l ps-2">{props.children}</div>
</CollapsibleContent_Shadcn_>
</Collapsible_Shadcn_>
)
}

View File

@@ -1,62 +0,0 @@
import { forwardRef } from 'react'
import { cn } from 'ui'
const Grid = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
({ children, ...props }, ref) => {
return (
<div
ref={ref}
{...props}
className={cn(
'grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 border-t border-l my-12',
props.className
)}
>
{children}
</div>
)
}
)
Grid.displayName = 'Grid'
const GridItem = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
({ children, ...props }, ref) => {
return (
<div
ref={ref}
{...props}
className={cn(
`
relative
min-h-32
flex gap-4 flex-col items-center p-4
border-b border-r
bg-surface-75/50
justify-center hover:bg-surface-100
group
cursor-pointer
`,
props.className
)}
>
<div
className="
absolute
w-full h-full box-content
transition
group-hover:border
group-hover:border-foreground-muted
group-data-[state=open]:border
group-data-[state=open]:border-foreground-muted
"
></div>
{children}
</div>
)
}
)
GridItem.displayName = 'GridItem'
export { Grid, GridItem }

View File

@@ -1,20 +0,0 @@
'use client'
import { useTheme } from 'next-themes'
import SVG from 'react-inlinesvg'
import { cn } from 'ui'
const HomepageSvgHandler = ({ name, className }: { name: string; className?: string }) => {
const { resolvedTheme } = useTheme()
return (
<div>
<SVG
className={cn('h-32 w-auto', className)}
src={`${process.env.NEXT_PUBLIC_BASE_PATH ?? ''}/img/design-system-marks/${name}--${resolvedTheme}.svg`}
/>
</div>
)
}
export { HomepageSvgHandler }

View File

@@ -1,69 +0,0 @@
import { Index } from 'icons/__registry__/index'
import { Copy } from 'lucide-react'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuTrigger,
} from 'ui'
import { Grid, GridItem } from './grid'
function Icons() {
return (
<>
<Grid>
{Index.map((icon: any, i: number) => (
<DropdownMenu key={i} modal={false}>
<DropdownMenuTrigger asChild>
<GridItem>
<icon.component
strokeWidth={1.5}
size={21}
className="group-data-[state=open]:scale-125 transition-all"
/>
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground">
{icon.name}
</span>
</GridItem>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-48">
<DropdownMenuGroup>
<DropdownMenuItem
className="flex items-center gap-2"
onSelect={() => navigator.clipboard.writeText(icon.name)}
>
<Copy size={14} strokeWidth={1} />
Copy name
</DropdownMenuItem>
<DropdownMenuItem
className="flex items-center gap-2"
onSelect={() => navigator.clipboard.writeText(icon.jsx)}
>
<Copy size={14} strokeWidth={1} />
Copy JSX
</DropdownMenuItem>
<DropdownMenuItem
className="flex items-center gap-2"
onSelect={() => navigator.clipboard.writeText(icon.import)}
>
<Copy size={14} strokeWidth={1} />
Copy import path
</DropdownMenuItem>
<DropdownMenuItem
className="flex items-center gap-2"
onSelect={() => navigator.clipboard.writeText(icon.svg)}
>
<Copy size={14} strokeWidth={1} />
Copy SVG
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
))}
</Grid>
</>
)
}
export { Icons }

View File

@@ -1,45 +1,23 @@
import { useMDXComponent } from 'next-contentlayer2/hooks'
import Image from 'next/image'
import Link from 'next/link'
import * as React from 'react'
// import { NpmCommands } from 'types/unist'
// import { Event } from '@/lib/events'
import { Callout } from '@/components/callout'
import { CodeBlockWrapper } from '@/components/code-block-wrapper'
import { ComponentExample } from '@/components/component-example'
import { ComponentPreview } from '@/components/component-preview'
import { ComponentSource } from '@/components/component-source'
import { CopyButton } from '@/components/copy-button'
import { cn } from 'ui'
// import { FrameworkDocs } from '@/components/framework-docs'
import { CodeFragment } from '@/components/code-fragment'
import { DualRealtimeChat } from '@/components/dual-realtime-chat'
import { Icons } from '@/components/icons'
import { RegistryBlock } from '@/components/registry-block'
import TanStackBeta from '@/components/tanstack-beta'
import { ThemeSettings } from '@/components/theme-settings'
import { Style } from '@/registry/styles'
import type { Style } from '@/registry/styles'
import {
Accordion_Shadcn_ as Accordion,
AccordionContent_Shadcn_ as AccordionContent,
AccordionItem_Shadcn_ as AccordionItem,
AccordionTrigger_Shadcn_ as AccordionTrigger,
Alert_Shadcn_ as Alert,
AlertDescription_Shadcn_ as AlertDescription,
AlertTitle_Shadcn_ as AlertTitle,
AspectRatio,
Tabs_Shadcn_ as Tabs,
TabsContent_Shadcn_ as TabsContent,
TabsList_Shadcn_ as TabsList,
TabsTrigger_Shadcn_ as TabsTrigger,
cn,
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { BlockItem } from './block-item'
import { BlockPreview } from './block-preview'
import { ComponentProps } from './component-props'
import { SonnerExpandConfig } from './sonner-expand-config'
import { SonnerPositionConfig } from './sonner-expand-position'
import { Callout } from './callout'
import { ComponentPreview } from './component-preview'
import { CopyButton } from './copy-button'
import { DualRealtimeChat } from './dual-realtime-chat'
import { RegistryBlock } from './registry-block'
import { StyleWrapper } from './style-wrapper'
import TanStackBeta from './tanstack-beta'
const components = {
RegistryBlock,
@@ -47,9 +25,6 @@ const components = {
AccordionContent,
AccordionItem,
AccordionTrigger,
Alert,
AlertTitle,
AlertDescription,
h1: ({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) => (
<h1 className={cn('font-heading mt-2 scroll-m-20 text-4xl font-bold', className)} {...props} />
),
@@ -140,17 +115,11 @@ const components = {
{...props}
/>
),
pre: (
{
pre: ({
className,
__rawString__,
// __npmCommand__,
// __yarnCommand__,
// __pnpmCommand__,
// __bunCommand__,
__withMeta__,
__src__,
// __event__,
__style__,
...props
}: React.HTMLAttributes<HTMLPreElement> & {
@@ -158,10 +127,7 @@ const components = {
__rawString__?: string
__withMeta__?: boolean
__src__?: string
// __event__?: Event['name']
}
// & NpmCommands
) => {
}) => {
return (
<StyleWrapper styleName={__style__}>
<pre
@@ -172,25 +138,12 @@ const components = {
{...props}
/>
{__rawString__ && (
// !__npmCommand__ &&
<CopyButton
value={__rawString__}
src={__src__}
// event={__event__}
className={cn('absolute right-4 top-4', __withMeta__ && 'top-16')}
/>
)}
{/* {__npmCommand__ && __yarnCommand__ && __pnpmCommand__ && __bunCommand__ && (
<CopyNpmCommandButton
commands={{
__npmCommand__,
__yarnCommand__,
__pnpmCommand__,
__bunCommand__,
}}
className={cn('absolute right-4 top-4', __withMeta__ && 'top-16')}
/>
)} */}
</StyleWrapper>
)
},
@@ -203,60 +156,9 @@ const components = {
{...props}
/>
),
Image,
Callout,
ComponentPreview,
ComponentExample,
ComponentSource,
ComponentProps,
AspectRatio,
CodeBlockWrapper: ({ ...props }) => <CodeBlockWrapper className="rounded-md border" {...props} />,
Step: ({ className, ...props }: React.ComponentProps<'h3'>) => (
<h3
className={cn(
'font-heading mt-8 scroll-m-20 text-xl font-semibold tracking-tight',
className
)}
{...props}
/>
),
Steps: ({ ...props }) => (
<div className="[&>h3]:step steps mb-12 ml-4 border-l pl-8 [counter-reset:step]" {...props} />
),
Tabs: ({ className, ...props }: React.ComponentProps<typeof Tabs>) => (
<Tabs className={cn('relative mt-6 w-full', className)} {...props} />
),
TabsList: ({ className, ...props }: React.ComponentProps<typeof TabsList>) => (
<TabsList
className={cn('w-full justify-start rounded-none border-b bg-transparent p-0', className)}
{...props}
/>
),
TabsTrigger: ({ className, ...props }: React.ComponentProps<typeof TabsTrigger>) => (
<TabsTrigger
className={cn(
'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',
className
)}
{...props}
/>
),
TabsContent: ({ className, ...props }: React.ComponentProps<typeof TabsContent>) => (
<TabsContent
className={cn(
'relative [&_h3.font-heading]:text-base [&_h3.font-heading]:font-semibold',
className
)}
{...props}
/>
),
TanStackBeta,
// FrameworkDocs: ({ className, ...props }: React.ComponentProps<typeof FrameworkDocs>) => (
// <FrameworkDocs className={cn(className)} {...props} />
// ),
Link: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
<Link className={cn('font-medium underline underline-offset-4', className)} {...props} />
),
LinkedCard: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
<Link
className={cn(
@@ -266,12 +168,6 @@ const components = {
{...props}
/>
),
Icons,
ThemeSettings,
CodeFragment,
Admonition,
SonnerExpandConfig,
SonnerPositionConfig,
BlockItem,
BlockPreview,
DualRealtimeChat,

View File

@@ -1,29 +0,0 @@
'use client'
import { useTheme } from 'next-themes'
import * as React from 'react'
import { Moon, Sun } from 'lucide-react'
import { Button_Shadcn_ } from 'ui'
export function ModeToggle() {
const { setTheme, resolvedTheme } = useTheme()
const [, startTransition] = React.useTransition()
return (
<Button_Shadcn_
className="h-7 w-7"
onClick={() => {
startTransition(() => {
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
})
}}
size="icon"
variant="ghost"
>
<Moon className="dark:hidden" />
<Sun className="hidden dark:block" />
<span className="sr-only">Toggle theme</span>
</Button_Shadcn_>
)
}

View File

@@ -1,11 +0,0 @@
'use client'
import { ThemeProvider } from 'next-themes'
export function Providers({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider attribute="class" defaultTheme="system" disableTransitionOnChange enableSystem>
{children}
</ThemeProvider>
)
}

View File

@@ -1,37 +0,0 @@
import { useConfig } from '@/hooks/use-config'
import { Switch } from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
function SonnerExpandConfig() {
const [config, setConfig] = useConfig()
return (
<div className="px-5 py-5 border rounded-lg my-2 bg-surface-75">
<form>
<FormItemLayout
name="sonnerExpand"
id="sonnerExpand"
isReactForm={false}
label="Use expand prop"
description="You will need to fire a few Sonner toasts first"
layout="flex"
>
<Switch
name="sonnerExpand"
id="sonnerExpand"
size="large"
checked={config.sonnerExpand}
onCheckedChange={(e) =>
setConfig({
...config,
sonnerExpand: e,
})
}
/>
</FormItemLayout>
</form>
</div>
)
}
export { SonnerExpandConfig }

View File

@@ -1,70 +0,0 @@
import { useConfig } from '@/hooks/use-config'
import { ComponentProps } from 'react'
import {
SelectContent_Shadcn_,
SelectGroup_Shadcn_,
SelectItem_Shadcn_,
SelectLabel_Shadcn_,
SelectTrigger_Shadcn_,
SelectValue_Shadcn_,
Select_Shadcn_,
SonnerToaster,
} from 'ui'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
function SonnerPositionConfig() {
const [config, setConfig] = useConfig()
type Position = NonNullable<ComponentProps<typeof SonnerToaster>['position']>
const positions: Position[] = [
'top-left',
'top-right',
'bottom-left',
'bottom-right',
'top-center',
'bottom-center',
]
return (
<div className="px-5 py-5 border rounded-lg my-2 bg-surface-75">
<form>
<FormItemLayout
name="sonnerExpand"
id="sonnerExpand"
isReactForm={false}
label="Use position prop"
description="You will need to fire a few Sonner toasts first"
layout="flex"
>
<Select_Shadcn_
value={config.sonnerPosition}
defaultValue={config.sonnerPosition}
onValueChange={(e: Position) => {
setConfig({
...config,
sonnerPosition: e,
})
}}
>
<SelectTrigger_Shadcn_ className="w-[180px]">
<SelectValue_Shadcn_ placeholder="Select a position" />
</SelectTrigger_Shadcn_>
<SelectContent_Shadcn_>
<SelectGroup_Shadcn_>
<SelectLabel_Shadcn_>Positions available</SelectLabel_Shadcn_>
{positions.map((position) => (
<SelectItem_Shadcn_ key={position} value={position}>
{position}
</SelectItem_Shadcn_>
))}
</SelectGroup_Shadcn_>
</SelectContent_Shadcn_>
</Select_Shadcn_>
</FormItemLayout>
</form>
</div>
)
}
export { SonnerPositionConfig }

View File

@@ -1,15 +0,0 @@
export function TailwindIndicator() {
if (process.env.NODE_ENV === 'production' || process.env.HIDE_TAILWIND_INDICATOR === '1')
return null
return (
<div className="fixed bottom-1 left-1 z-50 flex h-6 w-6 items-center justify-center rounded-full bg-zinc-800 p-3 font-mono text-xs text-white">
<div className="block sm:hidden">xs</div>
<div className="hidden sm:block md:hidden">sm</div>
<div className="hidden md:block lg:hidden">md</div>
<div className="hidden lg:block xl:hidden">lg</div>
<div className="hidden xl:block 2xl:hidden">xl</div>
<div className="hidden 2xl:block">2xl</div>
</div>
)
}

View File

@@ -1,54 +0,0 @@
'use client'
import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
import SVG from 'react-inlinesvg'
import { RadioGroupLargeItem_Shadcn_, RadioGroup_Shadcn_, Theme, singleThemes } from 'ui'
const ThemeSettings = () => {
const [mounted, setMounted] = useState(false)
const { theme, setTheme } = useTheme()
/**
* Avoid Hydration Mismatch
* https://github.com/pacocoursey/next-themes?tab=readme-ov-file#avoid-hydration-mismatch
*/
// useEffect only runs on the client, so now we can safely show the UI
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
function SingleThemeSelection() {
return (
<form className="py-8">
<RadioGroup_Shadcn_
name="theme"
onValueChange={setTheme}
aria-label="Choose a theme"
defaultValue={theme}
value={theme}
className="flex flex-wrap gap-3"
>
{singleThemes.map((theme: Theme) => (
<RadioGroupLargeItem_Shadcn_ key={theme.value} value={theme.value} label={theme.name}>
<SVG src={`${process.env.NEXT_PUBLIC_BASE_PATH}/img/themes/${theme.value}.svg`} />
</RadioGroupLargeItem_Shadcn_>
))}
</RadioGroup_Shadcn_>
</form>
)
}
return (
<>
<SingleThemeSelection />
</>
)
}
export { ThemeSettings }

View File

@@ -3,7 +3,7 @@
import { Moon, Sun } from 'lucide-react'
import { useTheme } from 'next-themes'
import { useEffect, useState } from 'react'
import SVG from 'react-inlinesvg'
import {
Button,
DropdownMenu,
@@ -13,7 +13,6 @@ import {
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
RadioGroupLargeItem_Shadcn_,
RadioGroup_Shadcn_,
Theme,
singleThemes,

View File

@@ -1,17 +0,0 @@
'use client'
import { Search } from 'lucide-react'
import { Input } from 'ui-patterns/DataInputs/Input'
function TopNavigationSearch() {
return (
<Input
size="small"
className="transition w-64 rounded-full hover:bg-surface-200 hover:border-foreground-muted cursor-pointer"
icon={<Search size={14} />}
placeholder="Search UI Library..."
/>
)
}
export { TopNavigationSearch }

View File

@@ -1,37 +0,0 @@
// import { docsConfig } from '@/config/docs'
import Link from 'next/link'
import { CommandMenu } from './command-menu'
import { HomepageSvgHandler } from './homepage-svg-handler'
import { ThemeSwitcherDropdown } from './theme-switcher-dropdown'
function TopNavigation() {
return (
<header className="sticky top-0 z-50 w-full border-t bg-studio/95 backdrop-blur supports-[backdrop-filter]:bg-studio/60">
<div className="absolute border-b border-dashed w-full top-[3.4rem] -z-10"></div>
<nav className="h-14 w-full flex">
<div className="max-w-site border-b w-full flex flex-row items-center gap-6 mx-auto px-6 border-r border-l justify-between">
<div className="flex items-center gap-8">
<Link href="/">
<h1>Supabase UI Library</h1>
</Link>
<HomepageSvgHandler name="design-system-marks" className="h-4 w-auto" />
</div>
{/* {docsConfig.mainNav.map((section) => (
<>
<div className="font-mono uppercase text-xs text-foreground-lighter">
{section.title}
</div>
</>
))} */}
<div className="flex items-center gap-8">
{/* <TopNavigationSearch /> */}
<CommandMenu />
<ThemeSwitcherDropdown />
</div>
</div>
</nav>
</header>
)
}
export default TopNavigation

View File

@@ -6,6 +6,7 @@ description: Displays a control for easier uploading of files directly to Supaba
<ComponentPreview
name="dropzone-demo"
description="An alert with an icon, title and description. The title says 'Heads up!' and the description is 'You can add components to your app using the cli.'."
showCode={false}
/>
## Installation

View File

@@ -6,6 +6,7 @@ description: Displays a control for easier uploading of files directly to Supaba
<ComponentPreview
name="dropzone-demo"
description="An alert with an icon, title and description. The title says 'Heads up!' and the description is 'You can add components to your app using the cli.'."
showCode={false}
/>
## Installation

View File

@@ -6,6 +6,7 @@ description: Displays a control for easier uploading of files directly to Supaba
<ComponentPreview
name="dropzone-demo"
description="An alert with an icon, title and description. The title says 'Heads up!' and the description is 'You can add components to your app using the cli.'."
showCode={false}
/>
## Installation

View File

@@ -6,6 +6,7 @@ description: Displays a control for easier uploading of files directly to Supaba
<ComponentPreview
name="dropzone-demo"
description="An alert with an icon, title and description. The title says 'Heads up!' and the description is 'You can add components to your app using the cli.'."
showCode={false}
/>
## Installation

View File

@@ -1,6 +1,6 @@
import path from 'path'
import { getHighlighter, loadTheme } from '@shikijs/compat'
import { defineDocumentType, defineNestedType, makeSource } from 'contentlayer2/source-files'
import path from 'path'
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
import rehypePrettyCode from 'rehype-pretty-code'
import rehypeSlug from 'rehype-slug'
@@ -8,9 +8,6 @@ import { codeImport } from 'remark-code-import'
import remarkGfm from 'remark-gfm'
import { visit } from 'unist-util-visit'
import { rehypeComponent } from './lib/rehype-component'
import { rehypeNpmCommand } from './lib/rehype-npm-command'
/** @type {import('contentlayer2/source-files').ComputedFields} */
const computedFields = {
slug: {
@@ -112,7 +109,6 @@ export default makeSource({
remarkPlugins: [remarkGfm, codeImport],
rehypePlugins: [
rehypeSlug,
rehypeComponent,
() => (tree) => {
visit(tree, (node) => {
if (node?.type === 'element' && node?.tagName === 'pre') {

View File

@@ -1,19 +0,0 @@
import * as React from 'react'
export function useMediaQuery(query: string) {
const [value, setValue] = React.useState(false)
React.useEffect(() => {
function onChange(event: MediaQueryListEvent) {
setValue(event.matches)
}
const result = matchMedia(query)
result.addEventListener('change', onChange)
setValue(result.matches)
return () => result.removeEventListener('change', onChange)
}, [query])
return value
}

View File

@@ -1,406 +0,0 @@
import fs from 'fs'
import path from 'path'
import { UnistNode, UnistTree } from 'types/unist'
import { u } from 'unist-builder'
import { visit } from 'unist-util-visit'
import { Index } from '../__registry__'
import { styles } from '../registry/styles'
// import { parse } from 'react-docgen'
// import * as reactDocgenTypescript from 'react-docgen-typescript'
// import { Column, IColumnProps } from './sample-component'
import React from 'react' // ComponentType
function inspectComponentProps<T>(component: React.ComponentType<T>): void {
// Assert the component's props type
const defaultProps = (component as React.ComponentType<any>).defaultProps || {}
// console.log('Component props:')
// console.log('----------------')
for (const propName in defaultProps) {
const propType = typeof defaultProps[propName]
console.log(`${propName}: ${propType}`)
}
}
export function rehypeComponent() {
return async (tree: UnistTree) => {
visit(tree, (node: UnistNode) => {
// src prop overrides both name and fileName.
const { value: srcPath, name: componentName } =
(getNodeAttributeByName(node, 'src') as {
name: string
value?: string
type?: string
}) || {}
// console.log(srcPath, componentName)
// inspectComponentProps(Column)
// console.log('NEW NODE: ', node.name)
// if (node.name === 'ComponentProps') {
// // Parse a file for docgen info
// const options = {
// // savePropValueAsString: true,
// }
// // const parser = reactDocgenTypescript.parse('./sample-component.tsx', options)
// // console.log('PARSER', parser)
// const code = `
// /** My first component */
// export default ({ name, title }: {
// /** My first component */
// name: string,
// /** My first component */
// title: string
// }) => <div>{{name}}</div>;
// `
// // console.log('node', node)
// const documentation = parse(code)[0]
// // console.log('documentation', documentation)
// // Add attributes to object
// node.attributes?.push({
// type: 'mdxJsxAttribute',
// name: 'docs',
// value: JSON.stringify(documentation),
// })
// // console.log('node after', node)
// // Add random text as children
// // node.children?.push({
// // type: 'text',
// // value: 'I am random text', // Generate a random UUID as text content
// // })
// // node.data = {
// // ...node.data,
// // name: 'documentation',
// // type: 'mdxJsxAttribute',
// // value: documentation,
// // }
// }
if (node.name === 'ComponentSource') {
// console.log('DO NOT USE THIS COMPONENT')
// This component should not be in use!
// console.log('node', node)
const name = getNodeAttributeByName(node, 'name')?.value as string
const fileName = getNodeAttributeByName(node, 'fileName')?.value as string | undefined
if (!name && !srcPath) {
return null
}
try {
for (const style of styles) {
let src: string
if (srcPath) {
src = srcPath
} else {
const component = Index[style.name][name]
// console.log('got to ELSE STATEMENT')
// console.log('filename', fileName)
// console.log('name', name)
src = fileName
? component.files.find((file: string) => {
return file.endsWith(`${fileName}.tsx`) || file.endsWith(`${fileName}.ts`)
}) || component.files[0]
: component.files[0]
// console.log('got to END of ELSE STATEMENT')
}
// Read the source file.
const filePath = path.join(process.cwd(), src)
let source = fs.readFileSync(filePath, 'utf8')
// Replace imports.
// TODO: Use @swc/core and a visitor to replace this.
// For now a simple regex should do.
// source = source.replaceAll(`@/registry/${style.name}/`, '@/components/') // COMMENT THEE OUT
// source = source.replaceAll('export default', 'export')
// Add code as children so that rehype can take over at build time.
node.children?.push(
u('element', {
tagName: 'pre',
properties: {
__src__: src,
__style__: style.name,
},
attributes: [
{
name: 'styleName',
type: 'mdxJsxAttribute',
value: style.name,
},
],
children: [
u('element', {
tagName: 'code',
properties: {
className: ['language-tsx'],
},
children: [
{
type: 'text',
value: source,
},
],
}),
],
})
)
}
} catch (error) {
console.error(error)
}
}
if (node.name === 'ComponentPreview') {
const name = getNodeAttributeByName(node, 'name')?.value as string
if (!name) {
return null
}
try {
for (const style of styles) {
const component = Index[style.name][name]
// console.log('GOT HERE')
const src = component.files[0]
// Read the source file.
const filePath = path.join(process.cwd(), src)
let source = fs.readFileSync(filePath, 'utf8')
// Replace imports.
// TODO: Use @swc/core and a visitor to replace this.
// For now a simple regex should do.
source = source.replaceAll(`@/registry/${style.name}/`, '@/components/')
source = source.replaceAll('export default', 'export')
// Add code as children so that rehype can take over at build time.
node.children?.push(
u('element', {
tagName: 'pre',
properties: {
__src__: src,
},
children: [
u('element', {
tagName: 'code',
properties: {
className: ['language-tsx'],
},
children: [
{
type: 'text',
value: source,
},
],
}),
],
})
)
}
} catch (error) {
console.error(error)
}
}
if (node.name === 'CodeFragment') {
const name = getNodeAttributeByName(node, 'name')?.value as string
if (!name) {
return null
}
try {
for (const style of styles) {
const component = Index[style.name][name]
// console.log('GOT HERE')
const src = component.files[0]
// Read the source file.
const filePath = path.join(process.cwd(), src)
let source = fs.readFileSync(filePath, 'utf8')
// Replace imports.
// TODO: Use @swc/core and a visitor to replace this.
// For now a simple regex should do.
source = source.replaceAll(`@/registry/${style.name}/`, '@/components/')
source = source.replaceAll('export default', 'export')
// Add code as children so that rehype can take over at build time.
node.children?.push(
u('element', {
tagName: 'pre',
properties: {
__src__: src,
},
children: [
u('element', {
tagName: 'code',
properties: {
className: ['language-tsx'],
},
children: [
{
type: 'text',
value: source,
},
],
}),
],
})
)
}
} catch (error) {
console.error(error)
}
}
// if (node.name === "ComponentExample") {
// const source = getComponentSourceFileContent(node)
// if (!source) {
// return
// }
// // Replace the Example component with a pre element.
// node.children?.push(
// u("element", {
// tagName: "pre",
// properties: {
// __src__: src,
// },
// children: [
// u("element", {
// tagName: "code",
// properties: {
// className: ["language-tsx"],
// },
// children: [
// {
// type: "text",
// value: source,
// },
// ],
// }),
// ],
// })
// )
// const extractClassname = getNodeAttributeByName(
// node,
// "extractClassname"
// )
// if (
// extractClassname &&
// typeof extractClassname.value !== "undefined" &&
// extractClassname.value !== "false"
// ) {
// // Extract className from string
// // TODO: Use @swc/core and a visitor to extract this.
// // For now, a simple regex should do.
// const values = source.match(/className="(.*)"/)
// const className = values ? values[1] : ""
// // Add the className as a jsx prop so we can pass it to the copy button.
// node.attributes?.push({
// name: "extractedClassNames",
// type: "mdxJsxAttribute",
// value: className,
// })
// // Add a pre element with the className only.
// node.children?.push(
// u("element", {
// tagName: "pre",
// properties: {},
// children: [
// u("element", {
// tagName: "code",
// properties: {
// className: ["language-tsx"],
// },
// children: [
// {
// type: "text",
// value: className,
// },
// ],
// }),
// ],
// })
// )
// }
// }
// if (node.name === "ComponentSource") {
// const source = getComponentSourceFileContent(node)
// if (!source) {
// return
// }
// // Replace the Source component with a pre element.
// node.children?.push(
// u("element", {
// tagName: "pre",
// properties: {
// __src__: src,
// },
// children: [
// u("element", {
// tagName: "code",
// properties: {
// className: ["language-tsx"],
// },
// children: [
// {
// type: "text",
// value: source,
// },
// ],
// }),
// ],
// })
// )
// }
})
}
}
function getNodeAttributeByName(node: UnistNode, name: string) {
return node.attributes?.find((attribute) => attribute.name === name)
}
function getComponentSourceFileContent(node: UnistNode) {
const src = getNodeAttributeByName(node, 'src')?.value as string
if (!src) {
return null
}
// Read the source file.
const filePath = path.join(process.cwd(), src)
console.log('filePath', filePath)
const source = fs.readFileSync(filePath, 'utf8')
return source
}

View File

@@ -1,42 +0,0 @@
import { UnistNode, UnistTree } from 'types/unist'
import { visit } from 'unist-util-visit'
export function rehypeNpmCommand() {
return (tree: UnistTree) => {
visit(tree, (node: UnistNode) => {
if (node.type !== 'element' || node?.tagName !== 'pre') {
return
}
// npm install.
if (node.properties?.['__rawString__']?.startsWith('npm install')) {
const npmCommand = node.properties?.['__rawString__']
node.properties['__npmCommand__'] = npmCommand
node.properties['__yarnCommand__'] = npmCommand.replace('npm install', 'yarn add')
node.properties['__pnpmCommand__'] = npmCommand.replace('npm install', 'pnpm add')
node.properties['__bunCommand__'] = npmCommand.replace('npm install', 'bun add')
}
// npx create.
if (node.properties?.['__rawString__']?.startsWith('npx create-')) {
const npmCommand = node.properties?.['__rawString__']
node.properties['__npmCommand__'] = npmCommand
node.properties['__yarnCommand__'] = npmCommand.replace('npx create-', 'yarn create ')
node.properties['__pnpmCommand__'] = npmCommand.replace('npx create-', 'pnpm create ')
node.properties['__bunCommand__'] = npmCommand.replace('npx', 'bunx --bun')
}
// npx.
if (
node.properties?.['__rawString__']?.startsWith('npx') &&
!node.properties?.['__rawString__']?.startsWith('npx create-')
) {
const npmCommand = node.properties?.['__rawString__']
node.properties['__npmCommand__'] = npmCommand
node.properties['__yarnCommand__'] = npmCommand
node.properties['__pnpmCommand__'] = npmCommand.replace('npx', 'pnpm dlx')
node.properties['__bunCommand__'] = npmCommand.replace('npx', 'bunx --bun')
}
})
}
}

View File

@@ -1,27 +0,0 @@
import * as React from 'react'
import { Component } from 'react'
/**
* Column properties.
*/
export interface IColumnProps {
/** prop1 description */
prop1?: string
/** prop2 description */
prop2: number
/**
* prop3 description
*/
prop3: () => void
/** prop4 description */
prop4: 'option1' | 'option2' | 'option3'
}
/**
* Form column.
*/
export class Column extends Component<IColumnProps, {}> {
render() {
return <div>Test</div>
}
}

View File

@@ -2,15 +2,6 @@ import { cn as uiCN } from 'ui'
export const cn = uiCN
export function formatDate(input: string | number): string {
const date = new Date(input)
return date.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
}
export function absoluteUrl(path: string) {
return `${process.env.NEXT_PUBLIC_APP_URL}${path}`
}

View File

@@ -70,7 +70,6 @@
"react-docgen": "^7.0.3",
"react-dom": "catalog:",
"react-hook-form": "^7.45.0",
"react-inlinesvg": "^4.0.4",
"react-markdown": "^10.1.0",
"react-wrap-balancer": "^1.1.0",
"recharts": "^2.8.0",
@@ -111,7 +110,6 @@
"tsconfig": "workspace:*",
"tsx": "^4.19.3",
"typescript": "~5.5.0",
"unist-builder": "3.0.0",
"vite": "catalog:"
}
}

View File

@@ -19,30 +19,24 @@ fs.writeFileSync(registryPath, JSON.stringify(cleanedRegistry, null, 2))
// Create a registry index file for use by ComponentPreview in the app.
const registryIndex = `
// @ts-nocheck
// This file is autogenerated by scripts/build-registry.ts
// This file is autogenerated by scripts/build-registry.mts
// Do not edit this file directly.
import * as React from "react"
export const Index: Record<string, any> = {
export const Index = {
"default": {
${registry.items.map((item) => {
${registry.items
.filter((item) => item.type === 'registry:example')
.map((item) => {
const componentFile = item.files.find((file) => file.path.endsWith('.tsx'))
return `
"${item.name}": {
name: "${item.name}",
type: "${item.type}",
registryDependencies: [${item.registryDependencies.map((dep) => `"${dep}"`).join(',')}],
${componentFile ? `component: React.lazy(() => import("@/${componentFile.path}")),` : ''}
source: "",
files: [${item.files?.map((file) => `"${file.path}"`).join(',')}],
category: "undefined",
subcategory: "undefined",
chunks: []
component: ${componentFile ? `React.lazy(() => import("@/${componentFile.path}"))` : 'null'},
}
`
})}
},
}
} as const
`
fs.writeFileSync(`__registry__/index.tsx`, registryIndex)

View File

@@ -1,31 +0,0 @@
import { Node } from 'unist-builder'
export interface UnistNode extends Node {
type: string
name?: string
tagName?: string
value?: string
properties?: {
__rawString__?: string
__className__?: string
__event__?: string
[key: string]: unknown
} & NpmCommands
attributes?: {
name: string
value: unknown
type?: string
}[]
children?: UnistNode[]
}
export interface UnistTree extends Node {
children: UnistNode[]
}
export interface NpmCommands {
__npmCommand__?: string
__yarnCommand__?: string
__pnpmCommand__?: string
__bunCommand__?: string
}

View File

@@ -11,5 +11,8 @@
"apps/studio/public/**",
// ignore studio components, they're dynamically imported
"apps/studio/components/interfaces/Connect/content/**",
// ignore registry blocks in ui-library
"apps/ui-library/registry/default/**",
"apps/ui-library/contentlayer.config.js",
],
}

6
pnpm-lock.yaml generated
View File

@@ -1387,9 +1387,6 @@ importers:
react-hook-form:
specifier: ^7.45.0
version: 7.47.0(react@18.3.1)
react-inlinesvg:
specifier: ^4.0.4
version: 4.0.4(react@18.3.1)
react-markdown:
specifier: ^10.1.0
version: 10.1.0(@types/react@18.3.3)(react@18.3.1)(supports-color@8.1.1)
@@ -1505,9 +1502,6 @@ importers:
typescript:
specifier: ~5.5.0
version: 5.5.2
unist-builder:
specifier: 3.0.0
version: 3.0.0
vite:
specifier: 'catalog:'
version: 6.3.5(@types/node@22.13.14)(jiti@2.4.2)(sass@1.77.4)(terser@5.39.0)(tsx@4.19.3)(yaml@2.4.5)