From 87b83bfe7cfff206330d94fed7de66689776ae94 Mon Sep 17 00:00:00 2001 From: Muhammed Sanjid Date: Thu, 26 Mar 2026 21:08:11 +0530 Subject: [PATCH 1/6] feat: added new components and other fixes --- apps/cli/src/index.ts | 3 +- apps/cli/src/utils/files.ts | 239 ++ apps/platform/app/(docs)/[...slug]/page.tsx | 33 +- .../app/(docs)/animated-components/page.tsx | 28 + apps/platform/app/(docs)/components/page.tsx | 17 +- apps/platform/app/(docs)/layout.tsx | 38 +- apps/platform/bun.lock | 2750 +++++++++++++++++ .../components/buttons/spotlight.tsx | 91 + apps/platform/components/app-sidebar.tsx | 10 +- apps/platform/components/core/docs-toc.tsx | 208 +- apps/platform/components/core/navbar.tsx | 6 +- .../components/mdx/component-preview.tsx | 2 +- .../components/mdx/installation-cmd.tsx | 1 + apps/platform/components/nav-main.tsx | 7 +- .../components/showcase/code-block.tsx | 110 +- .../components/showcase/component-docs.tsx | 107 +- .../showcase/component-installation.tsx | 25 +- .../showcase/component-live-preview.tsx | 382 +++ .../components/showcase/docs-primitives.tsx | 69 +- .../showcase/spotlight-button-demo.tsx | 53 + apps/platform/content/components/button.mdx | 140 - apps/platform/content/components/text.mdx | 115 - .../content/docs/components/avatar.mdx | 118 + .../content/docs/components/badge.mdx | 104 + .../content/docs/components/button.mdx | 90 +- .../content/docs/components/input.mdx | 126 + .../content/docs/components/meta.json | 2 +- .../docs/components/spotlight-button.mdx | 125 + .../platform/content/docs/components/text.mdx | 67 +- apps/platform/eslint.config.mjs | 2 + apps/platform/lib/custom-showcase.ts | 39 + apps/platform/lib/docs-navigation.ts | 46 +- apps/platform/lib/registry-catalog.ts | 18 +- apps/platform/lib/registry-data.json | 32 + apps/platform/mdx-components.tsx | 162 +- apps/platform/package.json | 36 +- apps/platform/source.config.ts | 7 +- apps/showcase/.tailwind-debug.css | 857 +++++ apps/showcase/app.json | 6 +- apps/showcase/app/(components)/[slug].tsx | 806 +++++ apps/showcase/app/(tabs)/explore.tsx | 248 +- apps/showcase/app/(tabs)/index.tsx | 128 +- apps/showcase/app/_layout.tsx | 9 + apps/showcase/babel.config.js | 5 +- .../components/animated/spotlight-button.tsx | 276 ++ apps/showcase/components/ui/icon-symbol.tsx | 31 +- apps/showcase/global.css | 76 +- apps/showcase/lib/ui-interop.ts | 10 + apps/showcase/metro.config.js | 19 +- apps/showcase/package.json | 1 + apps/showcase/tailwind-debug.css | 857 +++++ apps/showcase/tailwind.config.js | 38 +- apps/showcase/tsconfig.json | 3 +- packages/registry/package.json | 9 +- packages/registry/registry.json | 154 +- .../registry/src/components/ui/avatar.tsx | 70 + packages/registry/src/components/ui/badge.tsx | 95 + .../registry/src/components/ui/button.tsx | 261 +- packages/registry/src/components/ui/card.tsx | 49 + packages/registry/src/components/ui/input.tsx | 51 + packages/registry/src/components/ui/label.tsx | 21 + .../registry/src/components/ui/separator.tsx | 30 + packages/registry/src/components/ui/text.tsx | 192 +- .../registry/src/components/ui/textarea.tsx | 53 + pnpm-lock.yaml | 2192 ++++++------- 65 files changed, 9802 insertions(+), 2153 deletions(-) create mode 100644 apps/platform/app/(docs)/animated-components/page.tsx create mode 100644 apps/platform/bun.lock create mode 100644 apps/platform/components/animate-ui/components/buttons/spotlight.tsx create mode 100644 apps/platform/components/showcase/component-live-preview.tsx create mode 100644 apps/platform/components/showcase/spotlight-button-demo.tsx delete mode 100644 apps/platform/content/components/button.mdx delete mode 100644 apps/platform/content/components/text.mdx create mode 100644 apps/platform/content/docs/components/avatar.mdx create mode 100644 apps/platform/content/docs/components/badge.mdx create mode 100644 apps/platform/content/docs/components/input.mdx create mode 100644 apps/platform/content/docs/components/spotlight-button.mdx create mode 100644 apps/platform/lib/custom-showcase.ts create mode 100644 apps/showcase/.tailwind-debug.css create mode 100644 apps/showcase/app/(components)/[slug].tsx create mode 100644 apps/showcase/components/animated/spotlight-button.tsx create mode 100644 apps/showcase/lib/ui-interop.ts create mode 100644 apps/showcase/tailwind-debug.css create mode 100644 packages/registry/src/components/ui/avatar.tsx create mode 100644 packages/registry/src/components/ui/badge.tsx create mode 100644 packages/registry/src/components/ui/card.tsx create mode 100644 packages/registry/src/components/ui/input.tsx create mode 100644 packages/registry/src/components/ui/label.tsx create mode 100644 packages/registry/src/components/ui/separator.tsx create mode 100644 packages/registry/src/components/ui/textarea.tsx diff --git a/apps/cli/src/index.ts b/apps/cli/src/index.ts index e049bda..d364e18 100644 --- a/apps/cli/src/index.ts +++ b/apps/cli/src/index.ts @@ -6,7 +6,7 @@ import ora from 'ora'; import { DEFAULT_CONFIG, getConfig, setConfig, type WatermelonConfig } from './utils/config.js'; import { collectComponents, downloadRegistryFile } from './utils/registry.js'; import { getMissingDependencies, installDependencies } from './utils/dependencies.js'; -import { ensureComponentsDirectory, ensureUtilsFile, installFiles } from './utils/files.js'; +import { ensureComponentsDirectory, ensureCssFile, ensureUtilsFile, installFiles } from './utils/files.js'; const program = new Command(); @@ -85,6 +85,7 @@ program await setConfig(cwd, config); await ensureComponentsDirectory(cwd, config); await ensureUtilsFile(cwd, config); + await ensureCssFile(cwd, config); const requiredDeps = [ 'clsx', diff --git a/apps/cli/src/utils/files.ts b/apps/cli/src/utils/files.ts index cf05454..f95222e 100644 --- a/apps/cli/src/utils/files.ts +++ b/apps/cli/src/utils/files.ts @@ -89,6 +89,245 @@ export async function ensureComponentsDirectory(cwd: string, config: WatermelonC await fs.ensureDir(path.join(cwd, componentsPath, 'ui')); } +export async function ensureCssFile(cwd: string, config: WatermelonConfig): Promise { + const cssContent = `@import "tailwindcss"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-sans); + --font-mono: var(--font-geist-mono); + --shadow-3d: inset 0 5px 6px var(--color-border); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --radius-sm: calc(var(--radius) * 0.6); + --radius-md: calc(var(--radius) * 0.8); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) * 1.4); + --radius-2xl: calc(var(--radius) * 1.8); + --radius-3xl: calc(var(--radius) * 2.2); + --radius-4xl: calc(var(--radius) * 2.6); +} + +:root { + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.809 0.105 251.813); + --chart-2: oklch(0.623 0.214 259.815); + --chart-3: oklch(0.546 0.245 262.881); + --chart-4: oklch(0.488 0.243 264.376); + --chart-5: oklch(0.424 0.199 265.638); + --radius: 0.625rem; + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.145 0 0); + --sidebar-primary: oklch(0.205 0 0); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.97 0 0); + --sidebar-accent-foreground: oklch(0.205 0 0); + --sidebar-border: oklch(0.922 0 0); + --sidebar-ring: oklch(0.708 0 0); +} + +.dark { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.809 0.105 251.813); + --chart-2: oklch(0.623 0.214 259.815); + --chart-3: oklch(0.546 0.245 262.881); + --chart-4: oklch(0.488 0.243 264.376); + --chart-5: oklch(0.424 0.199 265.638); + --sidebar: oklch(0.205 0 0); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.488 0.243 264.376); + --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-accent: oklch(0.269 0 0); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } + html { + @apply font-sans; + } + +@keyframes show-top-mask { + to { + --top-mask-height: var(--mask-height); + } + } + +@keyframes hide-bottom-mask { + to { + --bottom-mask-height: 0px; + } + } + +@keyframes show-left-mask { + to { + --left-mask-width: var(--mask-width); + } + } + +@keyframes hide-right-mask { + to { + --right-mask-width: 0px; + } + } +} + +@property --top-mask-height { + syntax: ""; + inherits: true; + initial-value: 0px; +} + +@property --bottom-mask-height { + syntax: ""; + inherits: true; + initial-value: 64px; +} + +@property --left-mask-width { + syntax: ""; + inherits: true; + initial-value: 0px; +} + +@property --right-mask-width { + syntax: ""; + inherits: true; + initial-value: 64px; +} + +@utility scroll-fade-effect-y { + --mask-height: 64px; + --mask-offset-top: 0px; + --mask-offset-bottom: 0px; + --scroll-buffer: 2rem; + mask-image: linear-gradient(to top, transparent, black 90%), linear-gradient(to bottom, transparent 0%, black 100%), linear-gradient(black, black); + mask-size: 100% var(--top-mask-height), 100% var(--bottom-mask-height), 100% 100%; + mask-repeat: no-repeat, no-repeat, no-repeat; + mask-position: 0 var(--mask-offset-top), 0 calc(100% - var(--mask-offset-bottom)), 0 0; + mask-composite: exclude; + animation-name: show-top-mask, hide-bottom-mask; + animation-timeline: scroll(self), scroll(self); + animation-range: 0 var(--scroll-buffer), calc(100% - var(--scroll-buffer)) 100%; + animation-fill-mode: both; +} + +@utility scroll-fade-effect-x { + --mask-width: 64px; + --mask-offset-left: 0px; + --mask-offset-right: 0px; + --scroll-buffer: 2rem; + mask-image: linear-gradient(to left, transparent, black 90%), linear-gradient(to right, transparent 0%, black 100%), linear-gradient(black, black); + mask-size: var(--left-mask-width) 100%, var(--right-mask-width) 100%, 100% 100%; + mask-repeat: no-repeat, no-repeat, no-repeat; + mask-position: var(--mask-offset-left) 0, calc(100% - var(--mask-offset-right)) 0, 0 0; + mask-composite: exclude; + animation-name: show-left-mask, hide-right-mask; + animation-timeline: scroll(self inline), scroll(self inline); + animation-range: 0 var(--scroll-buffer), calc(100% - var(--scroll-buffer)) 100%; + animation-fill-mode: both; +} + +/* Hide scrollbar globally */ +.scrollbar-hide { + -ms-overflow-style: none; + scrollbar-width: none; +} + +.scrollbar-hide::-webkit-scrollbar { + display: none; +} + +/* Apply to all scrollable elements */ +* { + scrollbar-width: none; + -ms-overflow-style: none; +} + +*::-webkit-scrollbar { + display: none; +} +`; + + const fullPath = path.join(cwd, config.tailwind.css); + + if (!(await fs.pathExists(fullPath))) { + await fs.ensureDir(path.dirname(fullPath)); + await fs.writeFile(fullPath, cssContent, 'utf-8'); + } +} + function resolveTargetRoot(cwd: string, installPath?: string): string { if (!installPath) { return cwd; diff --git a/apps/platform/app/(docs)/[...slug]/page.tsx b/apps/platform/app/(docs)/[...slug]/page.tsx index fd936b4..84c5877 100644 --- a/apps/platform/app/(docs)/[...slug]/page.tsx +++ b/apps/platform/app/(docs)/[...slug]/page.tsx @@ -6,7 +6,12 @@ import { DocsBody, DocsDescription, DocsTitle } from "fumadocs-ui/page"; import MotionDiv from "@/components/core/motion-div"; import { PageHeader } from "@/components/core/typography"; import { Button } from "@/components/ui/button"; -import { DocsPager, OnThisPage, PreviewCard } from "@/components/showcase/docs-primitives"; +import { + DocsPager, + OnThisPage, + PreviewCard, +} from "@/components/showcase/docs-primitives"; +import { ComponentLivePreview } from "@/components/showcase/component-live-preview"; import { ComponentPreview } from "@/components/mdx/component-preview"; import { ComponentInstallation } from "@/components/showcase/component-installation"; import { @@ -14,10 +19,7 @@ import { PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; -import { - getComponentLinks, - getComponentPager, -} from "@/lib/docs-navigation"; +import { getComponentLinks, getComponentPager } from "@/lib/docs-navigation"; import { docsSource } from "@/lib/docs-source"; import { getRegistryCatalog } from "@/lib/registry-catalog"; import { customMDXComponents } from "@/mdx-components"; @@ -90,7 +92,7 @@ export default async function DocsPage({ subTitle={page.data.description ?? ""} /> - + @@ -103,7 +105,9 @@ export default async function DocsPage({ const component = catalog .flatMap((category) => category.items) .find((item) => item.slug === componentSlug); - const componentDoc = componentDocs.find((item) => item.slug === componentSlug); + const componentDoc = componentDocs.find( + (item) => item.slug === componentSlug, + ); if (!component || !componentSlug || !componentDoc) { notFound(); @@ -122,10 +126,10 @@ export default async function DocsPage({
-

+

{page.data.category}

- + {page.data.title} @@ -172,9 +176,11 @@ export default async function DocsPage({ ) : null} + video={undefined} + poster={undefined} + > + +
- + diff --git a/apps/platform/app/(docs)/animated-components/page.tsx b/apps/platform/app/(docs)/animated-components/page.tsx new file mode 100644 index 0000000..b5f663b --- /dev/null +++ b/apps/platform/app/(docs)/animated-components/page.tsx @@ -0,0 +1,28 @@ +import type { TOCItemType } from "fumadocs-core/toc"; +import { ComponentsIndexView } from "@/components/showcase/component-docs"; +import { getRegistryCatalog } from "@/lib/registry-catalog"; +import { OnThisPage } from "@/components/showcase/docs-primitives"; + +export default async function AnimatedComponentsPage() { + const categories = await getRegistryCatalog(); + const toc: TOCItemType[] = [ + { url: "#component-overview", title: "Overview", depth: 2 }, + { url: "#animated-components", title: "Animated Components", depth: 2 }, + ]; + + const animatedCategories = categories.filter( + (c) => c.title === "Animated Components", + ); + + return ( + <> + + + + ); +} diff --git a/apps/platform/app/(docs)/components/page.tsx b/apps/platform/app/(docs)/components/page.tsx index 39da432..3d20c00 100644 --- a/apps/platform/app/(docs)/components/page.tsx +++ b/apps/platform/app/(docs)/components/page.tsx @@ -7,17 +7,22 @@ export default async function ComponentsPage() { const categories = await getRegistryCatalog(); const toc: TOCItemType[] = [ { url: "#component-overview", title: "Overview", depth: 2 }, - ...categories.map((category) => ({ - url: `#${category.slug}`, - title: category.title, - depth: 2, - })), + { url: "#components", title: "Components", depth: 2 }, ]; + const standardCategories = categories.filter( + (c) => c.title !== "Animated Components", + ); + return ( <> - + ); } diff --git a/apps/platform/app/(docs)/layout.tsx b/apps/platform/app/(docs)/layout.tsx index 3c5f9c5..dd138b3 100644 --- a/apps/platform/app/(docs)/layout.tsx +++ b/apps/platform/app/(docs)/layout.tsx @@ -5,12 +5,14 @@ import { Navbar } from "@/components/core/navbar"; import { TOCProvider } from "@/components/core/toc-context"; import { DocsTOC } from "@/components/core/docs-toc"; import { + getAnimatedComponentEntries, + getComponentEntries, getCommandLinks, - getComponentGroups, getGuideLinks, } from "@/lib/docs-navigation"; import { HugeiconsIcon } from "@hugeicons/react"; import { + Atom02Icon, BookOpen02Icon, ComputerTerminalIcon, } from "@hugeicons/core-free-icons"; @@ -32,14 +34,15 @@ export default function ComponentsLayout({ })), }, ]; - const componentGroups = getComponentGroups().map((group) => ({ - title: group.title, - url: "#", + const componentGroups = getComponentEntries().map((item) => ({ + title: item.title, + url: item.url, icon: , - items: group.items.map((item) => ({ - title: item.title, - url: item.url, - })), + })); + const animatedComponentGroups = getAnimatedComponentEntries().map((item) => ({ + title: item.title, + url: item.url, + icon: , })); const commandLinks = getCommandLinks(); @@ -49,17 +52,20 @@ export default function ComponentsLayout({ - -
+ +
-
-
- +
+
+
+ +
+
{children}
-
{children}
-
-
+ +