diff --git a/.gitignore b/.gitignore index 81ca99ed4..a0c91f387 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ dist .DS_Store *.pem +www-old/ + # debug npm-debug.log* yarn-debug.log* @@ -37,4 +39,4 @@ yarn-error.log* .vercel # vscode plugin -*.vsix \ No newline at end of file +*.vsix diff --git a/apps/www/.gitignore b/apps/www/.gitignore index 55a12ae71..c09047d52 100644 --- a/apps/www/.gitignore +++ b/apps/www/.gitignore @@ -1,28 +1,44 @@ -# deps -/node_modules +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. -# generated content -.contentlayer -.content-collections -.source +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions -# test & build +# testing /coverage + +# next.js /.next/ /out/ + +# production /build -*.tsbuildinfo # misc .DS_Store *.pem -/.pnp -.pnp.js + +# debug npm-debug.log* yarn-debug.log* yarn-error.log* +.pnpm-debug.log* -# others -.env*.local +# env files (can opt-in for committing if needed) +.env* + +# vercel .vercel -next-env.d.ts \ No newline at end of file + +# typescript +*.tsbuildinfo +next-env.d.ts + +# fumadocs source +.source diff --git a/apps/www/README.md b/apps/www/README.md index e1a157820..e215bc4cc 100644 --- a/apps/www/README.md +++ b/apps/www/README.md @@ -1,26 +1,36 @@ -# fuma-base +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). -This is a Next.js application generated with -[Create Fumadocs](https://github.com/fuma-nama/fumadocs). +## Getting Started -Run development server: +First, run the development server: ```bash npm run dev # or +yarn dev +# or pnpm dev # or -yarn dev +bun dev ``` -Open http://localhost:3000 with your browser to see the result. +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. ## Learn More -To learn more about Next.js and Fumadocs, take a look at the following -resources: +To learn more about Next.js, take a look at the following resources: -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js - features and API. +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/apps/www/next.config.mjs b/apps/www/next.config.mjs index 20a35b725..f11ce3d38 100644 --- a/apps/www/next.config.mjs +++ b/apps/www/next.config.mjs @@ -1,7 +1,5 @@ import { createMDX } from 'fumadocs-mdx/next'; -const withMDX = createMDX(); - /** @type {import('next').NextConfig} */ const config = { reactStrictMode: true, @@ -12,11 +10,6 @@ const config = { // !! WARN !! ignoreBuildErrors: true }, - eslint: { - // Warning: This allows production builds to successfully complete even if - // your project has ESLint errors. - ignoreDuringBuilds: true - }, experimental: { optimizePackageImports: ['shiki'] }, @@ -34,4 +27,6 @@ const config = { } }; +const withMDX = createMDX(); + export default withMDX(config); diff --git a/apps/www/package.json b/apps/www/package.json index 316a76861..8b5e195a3 100644 --- a/apps/www/package.json +++ b/apps/www/package.json @@ -1,46 +1,42 @@ { - "name": "www", - "version": "1.0.0", + "name": "www-beta", + "version": "0.1.0", "private": true, "scripts": { "prebuild": "cd ../.. && npm run build:apsara", - "build": "next build", "dev": "next dev", + "build": "next build", "start": "next start", "postinstall": "fumadocs-mdx" }, "dependencies": { + "@radix-ui/react-icons": "^1.3.2", "@raystack/apsara": "workspace:*", + "@types/mdast": "^4.0.4", "class-variance-authority": "^0.7.1", - "dayjs": "^1.11.11", - "fumadocs-core": "^14.7.7", + "fumadocs-core": "16.0.7", "fumadocs-docgen": "^1.3.8", - "fumadocs-mdx": "^11.5.6", + "fumadocs-mdx": "13.0.5", "fumadocs-typescript": "^4.0.6", - "fumadocs-ui": "^14.7.7", - "lucide-react": "^0.477.0", - "next": "14.2.5", + "fumadocs-ui": "16.0.7", + "lucide-react": "^0.548.0", + "next": "16.0.1", "next-themes": "^0.4.4", "prettier": "^2.8.8", - "react": "^18.3.1", - "react-dom": "^18.3.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", "react-live": "^4.1.8", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-mdx": "^3.1.0", - "unist-util-visit": "^5.0.0", - "zod": "^3.24.2" + "unist-util-visit": "^5.0.0" }, "devDependencies": { - "@types/mdast": "^4.0.4", "@types/mdx": "^2.0.13", - "@types/node": "22.13.4", - "@types/prettier": "^3.0.0", - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "eslint": "^8", - "eslint-config-next": "14", - "typescript": "^5.7.3" + "@types/node": "^24.9.2", + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "typescript": "^5.9.3" }, "engines": { "node": ">=22" diff --git a/apps/www/public/assets/logo.png b/apps/www/public/assets/logo.png index 61cad6a69..c4be1ab12 100644 Binary files a/apps/www/public/assets/logo.png and b/apps/www/public/assets/logo.png differ diff --git a/apps/www/public/assets/logo.svg b/apps/www/public/assets/logo.svg deleted file mode 100644 index a678b0b18..000000000 --- a/apps/www/public/assets/logo.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/apps/www/source.config.ts b/apps/www/source.config.ts index d5852b227..868e9cb49 100644 --- a/apps/www/source.config.ts +++ b/apps/www/source.config.ts @@ -1,11 +1,11 @@ import * as path from 'node:path'; import { fileURLToPath } from 'url'; -import { TagSchema } from '@/lib/types'; import { remarkInstall } from 'fumadocs-docgen'; import { defineConfig, defineDocs, - frontmatterSchema + frontmatterSchema, + metaSchema } from 'fumadocs-mdx/config'; import { GeneratorOptions, @@ -27,9 +27,13 @@ const generator = createGenerator(tsconfig); export const docs = defineDocs({ dir: 'src/content/docs', docs: { - schema: frontmatterSchema.extend({ - tag: TagSchema - }) + schema: frontmatterSchema, + postprocess: { + includeProcessedMarkdown: true + } + }, + meta: { + schema: metaSchema } }); diff --git a/apps/www/src/app/(home)/page.tsx b/apps/www/src/app/(home)/page.tsx index 4544dddb8..c4cc58d48 100644 --- a/apps/www/src/app/(home)/page.tsx +++ b/apps/www/src/app/(home)/page.tsx @@ -1,17 +1,15 @@ -import Logo from "@/components/logo"; -import { Card } from "fumadocs-ui/components/card"; -import { Notebook, Paintbrush } from "lucide-react"; -import styles from "./page.module.css"; +import Logo from '@/components/logo'; +import styles from './page.module.css'; export const metadata = { - title: "Apsara", + title: 'Apsara' }; export default function HomePage() { return (
- +

The design system
for the next big thing @@ -21,22 +19,6 @@ export default function HomePage() { built using Radix UI.

-
- } - href="/docs" - className={styles.card} - /> - } - href="/playground" - className={styles.card} - /> -
); } diff --git a/apps/www/src/app/api/search/route.ts b/apps/www/src/app/api/search/route.ts deleted file mode 100644 index 570732244..000000000 --- a/apps/www/src/app/api/search/route.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { docs } from "@/lib/source"; -import { createFromSource } from "fumadocs-core/search/server"; - -export const { GET } = createFromSource(docs); diff --git a/apps/www/src/app/docs/[[...slug]]/page.module.css b/apps/www/src/app/docs/[[...slug]]/page.module.css index eabd8b9c3..80292dc70 100644 --- a/apps/www/src/app/docs/[[...slug]]/page.module.css +++ b/apps/www/src/app/docs/[[...slug]]/page.module.css @@ -1,16 +1,8 @@ -.title { - display: flex; - gap: 12px; - align-items: center; -} -.actions { - display: flex; - align-items: center; +.content { + max-width: 806px; + padding: var(--rs-space-15) var(--rs-space-7); } -.container { - display: flex; - gap: 12px; - align-items: center; - justify-content: space-between; +.prose { + gap: var(--rs-space-12); } diff --git a/apps/www/src/app/docs/[[...slug]]/page.tsx b/apps/www/src/app/docs/[[...slug]]/page.tsx index df2256354..520f9535c 100644 --- a/apps/www/src/app/docs/[[...slug]]/page.tsx +++ b/apps/www/src/app/docs/[[...slug]]/page.tsx @@ -1,22 +1,16 @@ -import { LLMCopyButton, ViewOptions } from '@/components/ai/page-actions'; import Demo from '@/components/demo'; -import Tag from '@/components/tag'; +import DocsNavbar from '@/components/docs/navbar'; +// import { TypeTable } from 'fumadocs-ui/components/type-table'; +import { TypeTable } from '@/components/typetable'; import { docs } from '@/lib/source'; +import { Flex, Headline, Text } from '@raystack/apsara'; import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; -import { TypeTable } from 'fumadocs-ui/components/type-table'; -import defaultMdxComponents from 'fumadocs-ui/mdx'; -import { - DocsBody, - DocsDescription, - DocsPage, - DocsTitle -} from 'fumadocs-ui/page'; +import defaultMdxComponents, { createRelativeLink } from 'fumadocs-ui/mdx'; +import type { Metadata } from 'next'; import { notFound } from 'next/navigation'; import styles from './page.module.css'; -export default async function Page(props: { - params: Promise<{ slug?: string[] }>; -}) { +export default async function Page(props: PageProps<'/docs/[[...slug]]'>) { const params = await props.params; const page = docs.getPage(params.slug); if (!page) notFound(); @@ -24,38 +18,31 @@ export default async function Page(props: { const MDX = page.data.body; return ( - - -
-
- {page.data.title} - -
-
- - -
-
-
- {page.data.description} - - - -
+ + + {page.data.title} + {page.data.description} + + + + + ); } @@ -63,9 +50,9 @@ export async function generateStaticParams() { return docs.generateParams(); } -export async function generateMetadata(props: { - params: Promise<{ slug?: string[] }>; -}) { +export async function generateMetadata( + props: PageProps<'/docs/[[...slug]]'> +): Promise { const params = await props.params; const page = docs.getPage(params.slug); if (!page) notFound(); diff --git a/apps/www/src/app/docs/layout.module.css b/apps/www/src/app/docs/layout.module.css new file mode 100644 index 000000000..946033346 --- /dev/null +++ b/apps/www/src/app/docs/layout.module.css @@ -0,0 +1,13 @@ +.container { + display: flex; + flex-direction: row; + position: relative; +} +.sidebar { + height: 100vh; + position: sticky; + top: 0; +} +.content { + flex: 1; +} diff --git a/apps/www/src/app/docs/layout.tsx b/apps/www/src/app/docs/layout.tsx index 9f4e4da23..86e9b46a1 100644 --- a/apps/www/src/app/docs/layout.tsx +++ b/apps/www/src/app/docs/layout.tsx @@ -1,24 +1,14 @@ -import type { ReactNode } from "react"; -import { DocsLayout } from "fumadocs-ui/layouts/docs"; -import { docs } from "@/lib/source"; -import ThemeSwitcher from "@/components/theme-switcher"; -import { SidebarItem } from "@/components/docs/sidebar-item"; +import DocsSidebar from '@/components/docs/sidebar'; +import { docs } from '@/lib/source'; +import { Flex } from '@raystack/apsara'; +import type { ReactNode } from 'react'; +import styles from './layout.module.css'; export default function Layout({ children }: { children: ReactNode }) { return ( - }} - disableThemeSwitch={true} - sidebar={{ - collapsible: false, - footer: , - hideSearch: true, - components: { - Item: SidebarItem, - }, - }}> - {children} - + + +
{children}
+
); } diff --git a/apps/www/src/app/examples/page.tsx b/apps/www/src/app/examples/page.tsx deleted file mode 100644 index c5d95758b..000000000 --- a/apps/www/src/app/examples/page.tsx +++ /dev/null @@ -1,1969 +0,0 @@ -'use client'; -import { - Amount, - Avatar, - AvatarGroup, - Button, - Callout, - DatePicker, - Dialog, - DropdownMenu, - EmptyState, - Flex, - IconButton, - Indicator, - InputField, - Popover, - RangePicker, - Search, - Select, - Sheet, - Sidebar, - Spinner, - Text, - TextArea, - Tooltip -} from '@raystack/apsara'; -import { - BellIcon, - FilterIcon, - OrganizationIcon, - SidebarIcon -} from '@raystack/apsara/icons'; -import dayjs from 'dayjs'; -import React, { useState } from 'react'; - -const Page = () => { - const [dialogOpen, setDialogOpen] = useState(false); - const [nestedDialogOpen, setNestedDialogOpen] = useState(false); - const [dialogSheetOpen, setDialogSheetOpen] = useState(false); - const [search1, setSearch1] = useState(''); - const [search2, setSearch2] = useState(''); - const [search3, setSearch3] = useState(''); - const [search4, setSearch4] = useState(''); - const [selectValue, setSelectValue] = useState(''); - const [selectValue1, setSelectValue1] = useState(''); - const [selectValue2, setSelectValue2] = useState(''); - const [inputValue, setInputValue] = useState(''); - const [rangeValue, setRangeValue] = useState({ - from: dayjs('2027-11-15').toDate(), - to: dayjs('2027-12-10').toDate() - }); - - // Sample options data with icons - const selectOptions = [ - { value: 'dashboard', label: 'Dashboard', icon: }, - { value: 'analytics', label: 'Analytics', icon: }, - { value: 'settings', label: 'Settings', icon: }, - { value: 'profile', label: 'Profile', icon: } - ]; - - const filterOptions = [ - { value: 'Option 1', label: 'Option 1', icon: }, - { value: 'Option 2', label: 'Option 2', icon: }, - { value: 'Option 3', label: 'Option 3', icon: } - ]; - - return ( - <> - - - - - console.log('Logo clicked')} - aria-label='Logo' - > - - - - Raystack - - - - - - }> - Dashboard - - - - Analytics - - - }> - Reports - - Activities - - - - Settings - - Notifications - - - - - Help & Support - - Preferences - - - - - - Main - - {`const button = (x>=2 && y!=3) - const getLoaderOnlyClass = (size) => - size === 'small' - ? styles['loader-only-button-small'] - : styles['loader-only-button-normal']; - - const test = 10 >= 8 : true : false; - - - <= < > >= == === != !== - - => ==> && || !! ?? - <-- --> *** **** - - /* comment */ /* ---------- __ */`} - - - ) => - setSearch1(e.target.value) - } - onClear={() => setSearch1('')} - /> - console.log(value)} - calendarProps={{ - captionLayout: 'dropdown', - startMonth: dayjs().add(3, 'month').toDate(), - endMonth: dayjs().add(4, 'year').toDate(), - disabled: { - before: dayjs().add(3, 'month').toDate(), - after: dayjs().add(3, 'year').toDate() - }, - mode: 'single', - required: true, - selected: new Date() - }} - inputFieldProps={{ - size: 'small' - }} - /> - - setRangeValue(range)} - calendarProps={{ - captionLayout: 'dropdown', - mode: 'range', - required: true, - selected: { - from: dayjs('2027-11-15').toDate(), - to: dayjs('2027-12-10').toDate() - }, - numberOfMonths: 2, - fromYear: 2024, - toYear: 2027, - startMonth: dayjs('2024-01-01').toDate(), - endMonth: dayjs('2027-12-01').toDate(), - defaultMonth: dayjs('2027-11-01').toDate() - }} - inputFieldsProps={{ - startDate: { - size: 'small' - }, - endDate: { - size: 'small' - } - }} - /> - - - Some important message in the footer - - } - /> - - - - - Skeleton Examples - - - - - - - - - - - - - {/* Button Examples */} - - Button Examples - All Combinations - - - {/* Solid Variant */} - - Solid Variant - - {/* Normal Size */} - - Normal Size: - - - - - - - - - - - - - - - - - - - - - - - - {/* Small Size */} - - Small Size: - - - - - - - - - - - - - - - - - - - - - - - - - {/* Outline Variant */} - - Outline Variant - - {/* Normal Size */} - - Normal Size: - - - - - - - - - - - - - - - - - - - - - - - - {/* Small Size */} - - Small Size: - - - - - - - - - - - - - - - - - - - - - - - - - {/* Ghost Variant */} - - Ghost Variant - - {/* Normal Size */} - - Normal Size: - - - - - - - - - - - - - - - - - - - - - - - - {/* Small Size */} - - Small Size: - - - - - - - - - - - - - - - - - - - - - - - - - {/* Text Variant */} - - Text Variant - - {/* Normal Size */} - - Normal Size: - - - - - - - - - - - - - - - - - - - - - - - - {/* Small Size */} - - Small Size: - - - - - - - - - - - - - - - - - - - - - - - - - - Spinner Examples - - - - - - - - - - - - - - - Button Loading States Examples - - - - {/* Solid Variant */} - - Solid Variant (Inverted Spinner) - - - - - - - - {/* Outline Variant */} - - - Outline Variant (Matching Color Spinner) - - - - - - - - - {/* Ghost Variant */} - - - Ghost Variant (Matching Color Spinner for colored) - - - - - - - - - {/* Text Variant */} - - - Text Variant (Matching Color Spinner for colored) - - - - - - - - - - {/* Size Variants */} - - Size Variants - - - - - - - - - {/* Loading with and without text */} - - Loading With/Without Text - - - - - - - - - {/* Disabled Loading State */} - - Disabled Loading State - - - - - - - - - - ) => - setSearch2(e.target.value) - } - onClear={() => setSearch2('')} - /> - - ) => - setSearch3(e.target.value) - } - onClear={() => setSearch3('')} - /> - - ) => - setSearch4(e.target.value) - } - onClear={() => setSearch4('')} - /> - - - {/* Select component examples */} - - Select Examples - - - } - heading='KYC required for image orders' - subHeading='Please contact your organization owner to complete the KYC process for the image orders. You can also contact support@raystack.io for assistance.' - primaryAction={ - - } - variant='empty1' - /> - -