diff --git a/.claude/scripts/install_pkgs.sh b/.claude/scripts/install_pkgs.sh new file mode 100755 index 00000000000..b407f3ce31a --- /dev/null +++ b/.claude/scripts/install_pkgs.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +if [ "$CLAUDE_CODE_REMOTE" != "true" ]; then + exit 0 +fi + +pnpm install diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 00000000000..502fd54dc4b --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "SessionStart": [ + { + "matcher": "startup", + "hooks": [ + { + "type": "command", + "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/scripts/install_pkgs.sh" + } + ] + } + ] + } +} diff --git a/.cursor/rules/docs-graphql.mdc b/.cursor/rules/docs-graphql.mdc deleted file mode 100644 index d8bcbc5d932..00000000000 --- a/.cursor/rules/docs-graphql.mdc +++ /dev/null @@ -1,267 +0,0 @@ ---- -description: Docs GraphQL Architecture -globs: apps/docs/resources/**/*.ts -alwaysApply: false ---- - -# Docs GraphQL Architecture - -## Overview - -The `/apps/docs/resources` folder contains the GraphQL endpoint architecture for the docs GraphQL endpoint at `/api/graphql`. It follows a modular pattern where each top-level query is organized into its own folder with consistent file structure. - -## Architecture Pattern - -Each GraphQL query follows this structure: - -``` -resources/ -├── queryObject/ -│ ├── queryObjectModel.ts # Data models and business logic -│ ├── queryObjectSchema.ts # GraphQL type definitions -│ ├── queryObjectResolver.ts # Query resolver and arguments -│ ├── queryObjectTypes.ts # TypeScript interfaces (optional) -│ └── queryObjectSync.ts # Functions for syncing repo content to the database (optional) -├── utils/ -│ ├── connections.ts # GraphQL connection/pagination utilities -│ └── fields.ts # GraphQL field selection utilities -├── rootSchema.ts # Main GraphQL schema with all queries -└── rootSync.ts # Root sync script for syncing to database -``` - -## Example queries - -1. **searchDocs** (`globalSearch/`) - Vector-based search across all docs content -2. **error** (`error/`) - Error code lookup for Supabase services -3. **schema** - GraphQL schema introspection - -## Key Files - -### `rootSchema.ts` -- Main GraphQL schema definition -- Imports all resolvers and combines them into the root query -- Defines the `RootQueryType` with all top-level fields - -### `utils/connections.ts` -- Provides `createCollectionType()` for paginated collections -- `GraphQLCollectionBuilder` for building collection responses -- Standard pagination arguments and edge/node patterns - -### `utils/fields.ts` -- `graphQLFields()` utility to analyze requested fields in resolvers -- Used for optimizing data fetching based on what fields are actually requested - -## Creating a New Top-Level Query - -To add a new GraphQL query, follow these steps: - -### 1. Create Query Folder Structure -```bash -mkdir resources/newQuery -touch resources/newQuery/newQueryModel.ts -touch resources/newQuery/newQuerySchema.ts -touch resources/newQuery/newQueryResolver.ts -``` - -### 2. Define GraphQL Schema (`newQuerySchema.ts`) -```typescript -import { GraphQLObjectType, GraphQLString } from 'graphql' - -export const GRAPHQL_FIELD_NEW_QUERY = 'newQuery' as const - -export const GraphQLObjectTypeNewQuery = new GraphQLObjectType({ - name: 'NewQuery', - description: 'Description of what this query returns', - fields: { - id: { - type: GraphQLString, - description: 'Unique identifier', - }, - // Add other fields... - }, -}) -``` - -### 3. Create Data Model (`newQueryModel.ts`) - -> [!NOTE] -> The data model should be agnostic to GraphQL. It may import argument types -> from `~/__generated__/graphql`, but otherwise all functions and classes -> should be unaware of whether they are called for GraphQL resolution. - -> [!TIP] -> The types in `~/__generated__/graphql` for a new endpoint will not exist -> until the code generation is run in the next step. - -```typescript -import { type RootQueryTypeNewQueryArgs } from '~/__generated__/graphql' -import { convertPostgrestToApiError, type ApiErrorGeneric } from '~/app/api/utils' -import { Result } from '~/features/helpers.fn' -import { supabase } from '~/lib/supabase' - -export class NewQueryModel { - constructor(public readonly data: { - id: string - // other properties... - }) {} - - static async loadData( - args: RootQueryTypeNewQueryArgs, - requestedFields: Array - ): Promise> { - // Implement data fetching logic - const result = new Result( - await supabase() - .from('your_table') - .select('*') - // Add filters based on args - ) - .map((data) => data.map((item) => new NewQueryModel(item))) - .mapError(convertPostgrestToApiError) - - return result - } -} -``` - -### 4. Create Resolver (`newQueryResolver.ts`) -```typescript -import { GraphQLError, GraphQLNonNull, GraphQLString, type GraphQLResolveInfo } from 'graphql' -import { type RootQueryTypeNewQueryArgs } from '~/__generated__/graphql' -import { convertUnknownToApiError } from '~/app/api/utils' -import { Result } from '~/features/helpers.fn' -import { graphQLFields } from '../utils/fields' -import { NewQueryModel } from './newQueryModel' -import { GRAPHQL_FIELD_NEW_QUERY, GraphQLObjectTypeNewQuery } from './newQuerySchema' - -async function resolveNewQuery( - _parent: unknown, - args: RootQueryTypeNewQueryArgs, - _context: unknown, - info: GraphQLResolveInfo -): Promise { - return ( - await Result.tryCatchFlat( - resolveNewQueryImpl, - convertUnknownToApiError, - args, - info - ) - ).match( - (data) => data, - (error) => { - console.error(`Error resolving ${GRAPHQL_FIELD_NEW_QUERY}:`, error) - return new GraphQLError(error.isPrivate() ? 'Internal Server Error' : error.message) - } - ) -} - -async function resolveNewQueryImpl( - args: RootQueryTypeNewQueryArgs, - info: GraphQLResolveInfo -): Promise> { - const fieldsInfo = graphQLFields(info) - const requestedFields = Object.keys(fieldsInfo) - return await NewQueryModel.loadData(args, requestedFields) -} - -export const newQueryRoot = { - [GRAPHQL_FIELD_NEW_QUERY]: { - description: 'Description of what this query does', - args: { - id: { - type: new GraphQLNonNull(GraphQLString), - description: 'Required argument description', - }, - // Add other arguments... - }, - type: GraphQLObjectTypeNewQuery, // or createCollectionType() for lists - resolve: resolveNewQuery, - }, -} -``` - -### 5. Register in Root Schema -In `rootSchema.ts`, add your resolver: - -```typescript -// Import your resolver -import { newQueryRoot } from './newQuery/newQueryResolver' - -// Add to the query fields -export const rootGraphQLSchema = new GraphQLSchema({ - query: new GraphQLObjectType({ - name: 'RootQueryType', - fields: { - ...introspectRoot, - ...searchRoot, - ...errorRoot, - ...newQueryRoot, // Add this line - }, - }), - types: [ - GraphQLObjectTypeGuide, - GraphQLObjectTypeReferenceCLICommand, - GraphQLObjectTypeReferenceSDKFunction, - GraphQLObjectTypeTroubleshooting, - ], -}) -``` - -### 6. Update TypeScript Types -Run the GraphQL codegen to update TypeScript types: -```bash -pnpm run -F docs codegen:graphql -``` - -## Best Practices - -1. **Error Handling**: Error handling always uses the Result class, defined in apps/docs/features/helpers.fn.ts -2. **Field Optimization**: Use `graphQLFields()` to only fetch requested data -3. **Collections**: Use `createCollectionType()` for paginated lists -4. **Naming**: Use `GRAPHQL_FIELD_*` constants for field names -5. **Documentation**: Add GraphQL descriptions to all fields and types -6. **Database**: Use `supabase()` client for database operations with `convertPostgrestToApiError` - -## Testing - -Tests are located in apps/docs/app/api/graphql/tests. Each top-level query -should have its own test file, located at .test.ts. - -### Test data - -Test data uses a local database, seeded with the file at supabase/seed.sql. Add -any data required for running your new query. - -### Integration tests - -Integration tests import the POST function defined in -apps/docs/api/graphql/route.ts, then make a request to this function. - -For example: - -```ts -import { POST } from '../route' - -it('test name', async () => { - const query = ` - query { - ... - } - ` - const request = new Request('http://localhost/api/graphql', { - method: 'POST', - body: JSON.stringify({ query }), - }) - - const result = await POST(request) -}) -``` - -Include at least the following tests: - -1. A test that requests all fields (including nested fields) on the new query - object, and asserts that there are no errors, and the requested fields are - properly returned. -2. A test that triggers and error, and asserts that a GraphQL error is properly - returned. diff --git a/.cursor/rules/docs-test-requirements.mdc b/.cursor/rules/docs-test-requirements.mdc deleted file mode 100644 index f76ca2ba7cf..00000000000 --- a/.cursor/rules/docs-test-requirements.mdc +++ /dev/null @@ -1,71 +0,0 @@ ---- -description: Docs Testing Procedure -globs: apps/docs/**/*.test.ts -alwaysApply: false ---- - -# Docs Test Requirements - -Rules for running tests in the docs application, ensuring proper Supabase setup and test execution. - - -name: docs_test_requirements -description: Standards for running tests in the docs application with proper Supabase setup -filters: - # Match test files in the docs app - - type: file_extension - pattern: "\\.(test|spec)\\.(ts|tsx)$" - - type: path - pattern: "^apps/docs/.*" - # Match test execution events - - type: event - pattern: "test_execution" - -actions: - - type: suggest - message: | - Before running tests in the docs app: - - 1. Check Supabase status: - ```bash - pnpm supabase status - ``` - - 2. If Supabase is not running: - ```bash - pnpm supabase start - ``` - - 3. Reset the database to ensure clean state: - ```bash - pnpm supabase db reset --local - ``` - - 4. Run the tests: - ```bash - pnpm run -F docs test:local:unwatch - ``` - - Important notes: - - Always ensure Supabase is running before tests - - Database must be reset to ensure clean state - - Use test:local:unwatch to run tests without watch mode - - Tests are located in apps/docs/**/*.{test,spec}.{ts,tsx} - -examples: - - input: | - # Bad: Running tests without proper setup - pnpm run -F docs test - pnpm run -F docs test:local - - # Good: Proper test execution sequence - pnpm supabase status - pnpm supabase start # if not running - pnpm supabase db reset --local - pnpm run -F docs test:local:unwatch - output: "Correctly executed docs tests with proper Supabase setup" - -metadata: - priority: high - version: 1.0 - diff --git a/.cursor/rules/docs-embeddings-generation.md b/.cursor/rules/docs/docs-embeddings-generation/RULE.md similarity index 79% rename from .cursor/rules/docs-embeddings-generation.md rename to .cursor/rules/docs/docs-embeddings-generation/RULE.md index 22ce5fd4359..6eab6f71510 100644 --- a/.cursor/rules/docs-embeddings-generation.md +++ b/.cursor/rules/docs/docs-embeddings-generation/RULE.md @@ -1,3 +1,10 @@ +--- +description: "Docs: embeddings generation pipeline (apps/docs/scripts/search)" +globs: + - apps/docs/scripts/search/**/*.ts +alwaysApply: false +--- + # Documentation Embeddings Generation System ## Overview @@ -12,31 +19,34 @@ The documentation embeddings generation system processes various documentation s ## Architecture ### Main Entry Point -- `generate-embeddings.ts` - Main script that orchestrates the entire process + +- `apps/docs/scripts/search/generate-embeddings.ts` - Main script that orchestrates the entire process - Supports `--refresh` flag to force regeneration of all content ### Content Sources (`sources/` directory) #### Base Classes + - `BaseLoader` - Abstract class for loading content from different sources - `BaseSource` - Abstract class for processing and formatting content #### Source Types -1. **Markdown Sources** (`markdown.ts`) + +1. **Markdown Sources** (`apps/docs/scripts/search/sources/markdown.ts`) - Processes `.mdx` files from guides and documentation - Extracts frontmatter metadata and content sections -2. **Reference Documentation** (`reference-doc.ts`) +2. **Reference Documentation** (`apps/docs/scripts/search/sources/reference-doc.ts`) - **OpenAPI References** - Management API documentation from OpenAPI specs - **Client Library References** - JavaScript, Dart, Python, C#, Swift, Kotlin SDKs - **CLI References** - Command-line interface documentation - Processes YAML/JSON specs and matches with common sections -3. **GitHub Discussions** (`github-discussion.ts`) +3. **GitHub Discussions** (`apps/docs/scripts/search/sources/github-discussion.ts`) - Fetches troubleshooting discussions from GitHub using GraphQL API - Uses GitHub App authentication for access -4. **Partner Integrations** (`partner-integrations.ts`) +4. **Partner Integrations** (`apps/docs/scripts/search/sources/partner-integrations.ts`) - Fetches approved partner integration documentation from Supabase database - Technology integrations only (excludes agencies) @@ -56,4 +66,3 @@ The documentation embeddings generation system processes various documentation s - **`page`** table: Stores page metadata, content, checksum, version - **`page_section`** table: Stores individual sections with embeddings, token counts - diff --git a/.cursor/rules/docs/docs-graphql/RULE.md b/.cursor/rules/docs/docs-graphql/RULE.md new file mode 100644 index 00000000000..8b16f176dc4 --- /dev/null +++ b/.cursor/rules/docs/docs-graphql/RULE.md @@ -0,0 +1,132 @@ +--- +description: "Docs: GraphQL architecture for apps/docs/resources" +globs: + - apps/docs/resources/**/*.ts +alwaysApply: false +--- + +# Docs GraphQL Architecture + +## Overview + +The `apps/docs/resources` folder contains the GraphQL endpoint architecture for the docs GraphQL endpoint at `/api/graphql`. It follows a modular pattern where each top-level query is organized into its own folder with consistent file structure. + +## Architecture Pattern + +Each GraphQL query follows this structure: + +``` +resources/ +├── queryObject/ +│ ├── queryObjectModel.ts # Data models and business logic +│ ├── queryObjectSchema.ts # GraphQL type definitions +│ ├── queryObjectResolver.ts # Query resolver and arguments +│ ├── queryObjectTypes.ts # TypeScript interfaces (optional) +│ └── queryObjectSync.ts # Functions for syncing repo content to the database (optional) +├── utils/ +│ ├── connections.ts # GraphQL connection/pagination utilities +│ └── fields.ts # GraphQL field selection utilities +├── rootSchema.ts # Main GraphQL schema with all queries +└── rootSync.ts # Root sync script for syncing to database +``` + +## Example queries + +1. **searchDocs** (`globalSearch/`) - Vector-based search across all docs content +2. **error** (`error/`) - Error code lookup for Supabase services +3. **schema** - GraphQL schema introspection + +## Key Files + +### `rootSchema.ts` + +- Main GraphQL schema definition +- Imports all resolvers and combines them into the root query +- Defines the `RootQueryType` with all top-level fields + +### `utils/connections.ts` + +- Provides `createCollectionType()` for paginated collections +- `GraphQLCollectionBuilder` for building collection responses +- Standard pagination arguments and edge/node patterns + +### `utils/fields.ts` + +- `graphQLFields()` utility to analyze requested fields in resolvers +- Used for optimizing data fetching based on what fields are actually requested + +## Creating a New Top-Level Query + +To add a new GraphQL query, follow these steps: + +### 1. Create Query Folder Structure + +```bash +mkdir resources/newQuery +touch resources/newQuery/newQueryModel.ts +touch resources/newQuery/newQuerySchema.ts +touch resources/newQuery/newQueryResolver.ts +``` + +### 2. Define GraphQL Schema (`newQuerySchema.ts`) + +```typescript +import { GraphQLObjectType, GraphQLString } from 'graphql' + +export const GRAPHQL_FIELD_NEW_QUERY = 'newQuery' as const + +export const GraphQLObjectTypeNewQuery = new GraphQLObjectType({ + name: 'NewQuery', + description: 'Description of what this query returns', + fields: { + id: { + type: GraphQLString, + description: 'Unique identifier', + }, + // Add other fields... + }, +}) +``` + +### 3. Create Data Model (`newQueryModel.ts`) + +> [!NOTE] +> The data model should be agnostic to GraphQL. It may import argument types +> from `~/__generated__/graphql`, but otherwise all functions and classes +> should be unaware of whether they are called for GraphQL resolution. + +> [!TIP] +> The types in `~/__generated__/graphql` for a new endpoint will not exist +> until the code generation is run in the next step. + +```typescript +import { type RootQueryTypeNewQueryArgs } from '~/__generated__/graphql' +import { convertPostgrestToApiError, type ApiErrorGeneric } from '~/app/api/utils' +import { Result } from '~/features/helpers.fn' +import { supabase } from '~/lib/supabase' + +export class NewQueryModel { + constructor( + public readonly data: { + id: string + // other properties... + } + ) {} + + static async loadData( + args: RootQueryTypeNewQueryArgs, + requestedFields: Array + ): Promise> { + // Implement data fetching logic + const result = new Result( + await supabase() + .from('your_table') + .select('*') + // Add filters based on args + ) + .map((data) => data.map((item) => new NewQueryModel(item))) + .mapError(convertPostgrestToApiError) + return result + } +} +``` diff --git a/.cursor/rules/docs/docs-test-requirements/RULE.md b/.cursor/rules/docs/docs-test-requirements/RULE.md new file mode 100644 index 00000000000..15cbda674e8 --- /dev/null +++ b/.cursor/rules/docs/docs-test-requirements/RULE.md @@ -0,0 +1,25 @@ +--- +description: "Docs: how to run tests locally (Supabase setup + correct commands)" +globs: + - apps/docs/**/*.{test,spec}.{ts,tsx} +alwaysApply: false +--- + +# Docs test requirements + +Before running tests for `apps/docs`, ensure local Supabase is available and the DB is in a known state. + +## Recommended sequence + +```bash +pnpm supabase status +pnpm supabase start # if not running +pnpm supabase db reset --local +pnpm run -F docs test:local:unwatch +``` + +## Notes + +- Always reset the local DB before running docs tests to avoid state leakage. +- Prefer `test:local:unwatch` for non-watch CI-like runs. + diff --git a/.cursor/rules/studio-ui.mdc b/.cursor/rules/studio-ui.mdc deleted file mode 100644 index 391978294b4..00000000000 --- a/.cursor/rules/studio-ui.mdc +++ /dev/null @@ -1,262 +0,0 @@ ---- -description: How to generate pages and interfaces in Studio, a web interface for managing Supabase projects -globs: -alwaysApply: true ---- - -## Project Structure - -- Next.js app using pages router -- Pages go in @apps/studio/pages - - Project related pages go in @apps/studio/pages/projects/[ref] - - Organization related pages go in @apps/studio/pages/org/[slug] -- Studio specific components go in @apps/studio/components - - Studio specific generic UI components go in @apps/studio/components/ui - - Studio specific components related to individual pages go in @apps/studio/components/interfaces e.g. @apps/studio/components/interfaces/Auth -- Generic helper functions go in @apps/studio/lib -- Generic hooks go in @apps/studio/hooks - -## Component system - -Our primitive component system is in @packages/ui and is based off shadcn/ui components. These components can be shared across all @apps e.g. studio and docs. Do not introduce new ui components unless asked to. - -- UI components are imported from this package across apps e.g. import { Button, Badge } from 'ui' -- Some components have a _Shadcn_ namespace appended to component name e.g. import { Input*Shadcn* } from 'ui' -- We should be using _Shadcn_ components where possible -- Before composing interfaces, read @packages/ui/index.tsx file for a full list of available components - -## Styling - -We use Tailwind for styling. - -- You should never use tailwind classes for colours and instead use classes we've defined ourselves - - Backgrounds // most of the time you will not need to define a background - - 'bg' used for main app surface background - - 'bg-muted' for elevating content // you can use Card instead - - 'bg-warning' for highlighting information that needs to be acted on - - 'bg-destructive' for highlighting issues - - Text - - 'text-foreground' for primary text like headings - - 'text-foreground-light' for body text - - 'text-foreground-lighter' for subtle text - - 'text-warning' for calling out information that needs action - - 'text-destructive' for calling out when something went wrong -- When needing to apply typography styles, read @apps/studio/styles/typography.scss and use one of the available classes instead of hard coding classes e.g. use "heading-default" instead of "text-sm font-medium" -- When applying focus styles for keyboard navigation, read @apps/studio/styles/focus.scss for any appropriate classes for consistency with other focus styles - -## Page structure - -When creating a new page follow these steps: - -- Create the page in @apps/studio/pages -- Use the PageLayout component that has the following props - - ```jsx - export interface NavigationItem { - id?: string - label: string - href?: string - icon?: ReactNode - onClick?: () => void - badge?: string - active?: boolean - } - - interface PageLayoutProps { - children?: ReactNode - title?: string | ReactNode - subtitle?: string | ReactNode - icon?: ReactNode - breadcrumbs?: Array<{ - label?: string - href?: string - element?: ReactNode - }> - primaryActions?: ReactNode - secondaryActions?: ReactNode - navigationItems?: NavigationItem[] - className?: string - size?: 'default' | 'full' | 'large' | 'small' - isCompact?: boolean - } - ``` - -- If a page has page related actions, add them to primary and secondary action props e.g. Users page has "Create new user" action -- If a page is within an existing section (e.g. Auth), you should use the related layout component e.g. AuthLayout -- Create a new component in @apps/studio/components/interfaces for the contents of the page -- Use ScaffoldContainer if the page should be center aligned in a container -- Use ScaffoldSection, ScaffoldSectionTitle, ScaffoldSectionDescription if the page has multiple sections - -### Page example - -```jsx -import { MyPageComponent } from 'components/interfaces/MyPage/MyPageComponent' -import AuthLayout from './AuthLayout' -import DefaultLayout from 'components/layouts/DefaultLayout' -import { ScaffoldContainer } from 'components/layouts/Scaffold' -import type { NextPageWithLayout } from 'types' - -const MyPage: NextPageWithLayout = () => { - return ( - - - - ) -} - -MyPage.getLayout = (page) => ( - - {page} - -) - -export default MyPage - -export const MyPageComponent = () => ( - -
- My page section - A brief description of the purpose of the page -
- // Content goes here -
-) -``` - -## Forms - -- Build forms with `react-hook-form` + `zod`. -- Use our `_Shadcn_` form primitives from `ui` and prefer `FormItemLayout` with layout="flex-row-reverse" for most controls (see `apps/studio/components/interfaces/Settings/Integrations/GithubIntegration/GitHubIntegrationConnectionForm.tsx`). -- Keep imports from `ui` with `_Shadcn_` suffixes. -- Forms should generally be wrapped in a Card unless specified -- If the submit button is outside the form, add a new variable named formId outside the component, and set it as property id on the form element and formId on the button. - -### Example (single field) - -```tsx -import { zodResolver } from '@hookform/resolvers/zod' -import { useForm } from 'react-hook-form' -import * as z from 'zod' - -import { Button, Form_Shadcn_, FormField_Shadcn_, FormControl_Shadcn_, Input_Shadcn_ } from 'ui' -import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' - -const profileSchema = z.object({ - username: z.string().min(2, 'Username must be at least 2 characters'), -}) - -const formId = `profile-form` - -export function ProfileForm() { - const form = useForm>({ - resolver: zodResolver(profileSchema), - defaultValues: { username: '' }, - mode: 'onSubmit', - reValidateMode: 'onBlur', - }) - - function onSubmit(values: z.infer) { - // handle values - } - - return ( - -
- - - ( - - - - - - )} - /> - - - - - -
-
- ) -} -``` - -## Cards - -- Use cards when needing to group related pieces of information -- Cards can have sections with CardContent -- Use CardFooter for actions -- Only use CardHeader and CardTitle if the card content has not been described by the surrounding content e.g. Page title or ScaffoldSectionTitle -- Use CardHeader and CardTitle when you are using multiple Cards to group related pieces of content e.g. Primary branch, Persistent branches, Preview branches - -## Sheets - -- Use a sheet when needing to reveal more complicated forms or information relating to an object and context switching away to a new page would be disruptive e.g. we list auth providers, clicking an auth provider opens a sheet with information about that provider and a form to enable, user can close sheet to go back to providers list - -## React Query - -- When doing a mutation, always use the mutate function. Always use onSuccess and onError with a toast.success and toast.error. -- Use mutateAsync only if the mutation is part of multiple async actions. Wrap the mutateAsync call with try/catch block and add toast.success and toast.error. - -## Tables - -- Use the generic ui table components for most tables -- Tables are generally contained witin a card -- If a table has associated actions, they should go above on right hand side -- If a table has associated search or filters, they should go above on left hand side -- If a table is the main content of a page, and it does not have search or filters, you can add table actions to primary and secondary actions of PageLayout -- If a table is the main content of a page section, and it does not have search or filters, you can add table actions to the right of ScaffoldSectionTitle -- For simple lists of objects you can use ResourceList with ResourceListItem instead - -### Table example - -```jsx -import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from 'ui' - -; - A list of your recent invoices. - - - Invoice - Status - Method - Amount - - - - - INV001 - Paid - Credit Card - $250.00 - - -
-``` - -## Alerts - -- Use Admonition component to alert users of important actions or restrictions in place -- Place the Admonition either at the top of the contents of the page (below page title) or at the top of the related ScaffoldSection , below ScaffoldTitle -- Use sparingly - -### Alert example - -```jsx - -``` diff --git a/.cursor/rules/studio-useStaticEffectEvent.mdc b/.cursor/rules/studio-useStaticEffectEvent.mdc new file mode 100644 index 00000000000..07e82b5e4fa --- /dev/null +++ b/.cursor/rules/studio-useStaticEffectEvent.mdc @@ -0,0 +1,161 @@ +--- +description: Guidelines for using the useStaticEffectEvent hook in Studio - a polyfill for React's useEffectEvent pattern +alwaysApply: false +--- + +# useStaticEffectEvent Hook + +The `useStaticEffectEvent` hook (located at `apps/studio/hooks/useStaticEffectEvent.ts`) is a userland implementation of React's `useEffectEvent` pattern. It solves the stale closure problem by providing a stable callback reference that always accesses the latest props and state values. + +## What Problem Does It Solve? + +When using `useEffect`, you often need to access props or state inside your Effect, but you don't want changes to those values to re-run the Effect. Without `useStaticEffectEvent`, you'd face two bad options: + +1. **Add them to dependencies** - causes unnecessary Effect re-runs (teardown/reconnect cycles) +2. **Omit from dependencies** - causes stale closure bugs where your callback uses outdated values + +```tsx +// Problem: This Effect re-runs every time `theme` changes, even though +// we only want to reconnect when `roomId` changes +useEffect(() => { + const connection = createConnection(roomId) + connection.on('connected', () => { + showNotification('Connected!', theme) // `theme` causes unwanted re-runs + }) + return () => connection.disconnect() +}, [roomId, theme]) // Adding theme causes unnecessary reconnections +``` + +## When to Use useStaticEffectEvent + +Use `useStaticEffectEvent` when you need to: + +1. **Read latest state/props inside an Effect without re-triggering it** +2. **Create stable callbacks that always use current values** +3. **Avoid stale closure bugs in event handlers used within Effects** + +### Pattern 1: Syncing data without re-running on every change + +```tsx +// ✅ Good - sync data when status changes, but always read latest state +const syncApiPrivileges = useStaticEffectEvent(() => { + if (hasLoadedInitialData.current) return + if (!apiAccessStatus.isSuccess) return + if (!privilegesForTable) return + + hasLoadedInitialData.current = true + setPrivileges(privilegesForTable.privileges) +}) + +useEffect(() => { + syncApiPrivileges() +}, [apiAccessStatus.status, syncApiPrivileges]) +``` + +### Pattern 2: Stable callbacks for async operations + +```tsx +// ✅ Good - wrap complex async logic that reads many values +const exportInternal = useStaticEffectEvent( + async ({ bypassConfirmation }: { bypassConfirmation: boolean }): Promise => { + if (!params.enabled) return + const { projectRef, connectionString, entity, totalRows } = params + // ... complex async logic using latest params + } +) + +// This callback is stable and can be safely used in useCallback +const exportInDesiredFormat = useCallback( + () => exportInternal({ bypassConfirmation: false }), + [exportInternal] +) +``` + +### Pattern 3: Infinite scroll / pagination triggers + +```tsx +// ✅ Good - always read latest pagination state when scrolling triggers fetch +const fetchNext = useStaticEffectEvent(() => { + if (lastItem && lastItem.index >= items.length - 1 && hasNextPage && !isFetchingNextPage) { + fetchNextPage() + } +}) + +useEffect(fetchNext, [lastItem, fetchNext]) +``` + +## When NOT to Use useStaticEffectEvent + +### Don't use it to avoid specifying legitimate dependencies + +```tsx +// ❌ Bad - hiding the fact that this should re-run when roomId changes +const connect = useStaticEffectEvent(() => { + const connection = createConnection(roomId) + connection.connect() +}) + +useEffect(() => { + connect() // BUG: Won't reconnect when roomId changes! +}, [connect]) + +// ✅ Good - roomId is a legitimate dependency +useEffect(() => { + const connection = createConnection(roomId) + connection.connect() + return () => connection.disconnect() +}, [roomId]) +``` + +### Don't use it for simple event handlers outside Effects + +```tsx +// ❌ Unnecessary - not used inside an Effect +const handleClick = useStaticEffectEvent(() => { + console.log(count) +}) + +// ✅ Good - regular function or useCallback is fine +const handleClick = () => { + console.log(count) +} +``` + +## How It Works + +The hook uses a ref to store the latest callback and returns a stable wrapper function: + +```tsx +export const useStaticEffectEvent = (callback: Callback) => { + const callbackRef = useRef(callback) + + // Update the ref on every render with the latest callback + useLayoutEffect(() => { + callbackRef.current = callback + }) + + // Return a stable function that calls the latest callback + const eventFn = useCallback((...args: any) => { + return callbackRef.current(...args) + }, []) + + return eventFn as unknown as Callback +} +``` + +## Relationship to React's useEffectEvent + +This hook is a polyfill for React's experimental `useEffectEvent` (now stable in React 19.2). The core concept is identical: + +- Extract non-reactive logic into a stable function +- Always access the latest props/state without adding them as Effect dependencies +- Should only be called from within Effects + +When React's `useEffectEvent` becomes widely available, this hook can be replaced with the official API. + +## Rules + +1. **Only call the returned function inside Effects** (useEffect, useLayoutEffect) +2. **Don't pass the function to other components or hooks** as a callback prop +3. **Use for non-reactive logic only** - logic that reads values but shouldn't trigger re-runs +4. **Include it in dependency arrays** when used in useEffect (the function is stable, so it won't cause re-runs) diff --git a/.cursor/rules/studio/RULE.md b/.cursor/rules/studio/RULE.md new file mode 100644 index 00000000000..60e3c155802 --- /dev/null +++ b/.cursor/rules/studio/RULE.md @@ -0,0 +1,33 @@ +--- +description: 'Studio: index rule for architecture, style, and UI composition patterns' +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio + +Use the nested rules in this folder for focused guidance while working in `apps/studio/`. + +## Architecture and style + +- `studio/project-structure` +- `studio/component-system` +- `studio/styling` +- `studio/best-practices` + +## UI composition (Design System patterns) + +- `studio/layout` +- `studio/forms` +- `studio/tables` +- `studio/charts` +- `studio/empty-states` +- `studio/navigation` + +## Common UI building blocks + +- `studio/sheets` +- `studio/cards` +- `studio/alerts` +- `studio/react-query` diff --git a/.cursor/rules/studio/alerts/RULE.md b/.cursor/rules/studio/alerts/RULE.md new file mode 100644 index 00000000000..feb55b0564b --- /dev/null +++ b/.cursor/rules/studio/alerts/RULE.md @@ -0,0 +1,13 @@ +--- +description: "Studio: alert/admonition usage and placement" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio alerts + +- Use `Admonition` to call out important actions, restrictions, or critical context. +- Place at the top of a page’s content (below the page title) or at the top of the relevant section (below the section title). +- Use sparingly. + diff --git a/.cursor/rules/studio/best-practices/RULE.md b/.cursor/rules/studio/best-practices/RULE.md new file mode 100644 index 00000000000..357265450a8 --- /dev/null +++ b/.cursor/rules/studio/best-practices/RULE.md @@ -0,0 +1,433 @@ +--- +description: "Studio: React and TypeScript best practices for maintainable Studio code" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio Best Practices + +## Boolean Handling + +### Assign complex conditions to descriptive variables + +When you have multiple conditions in a single expression, extract them into well-named boolean variables. This improves readability and makes the code self-documenting. + +```tsx +// ❌ Bad - complex inline condition +{ + !isSchemaLocked && isTableLike(selectedTable) && canUpdateColumns && !isLoading && ( + + ) +} + +// ✅ Good - extract to descriptive variables +const isTableEntity = isTableLike(selectedTable) +const canShowAddButton = !isSchemaLocked && isTableEntity && canUpdateColumns && !isLoading + +{ + canShowAddButton && +} +``` + +### Use consistent naming conventions for booleans + +- Use `is` prefix for state/identity: `isLoading`, `isPaused`, `isNewRecord`, `isError` +- Use `has` prefix for possession: `hasPermission`, `hasShownModal`, `hasData` +- Use `can` prefix for capability/permission: `canUpdateColumns`, `canDelete`, `canEdit` +- Use `should` prefix for conditional behavior: `shouldFetch`, `shouldRender`, `shouldValidate` + +```tsx +// ✅ Good examples from codebase +const isNewRecord = column === undefined +const isPaused = project?.status === PROJECT_STATUS.INACTIVE +const isMatureProject = dayjs(project?.inserted_at).isBefore(dayjs().subtract(10, 'day')) +const { can: canUpdateColumns } = useAsyncCheckPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'columns' +) +``` + +### Derive boolean state instead of storing it + +When a boolean can be computed from existing state, derive it rather than storing it separately. + +```tsx +// ❌ Bad - storing derived state +const [isFormValid, setIsFormValid] = useState(false) + +useEffect(() => { + setIsFormValid(name.length > 0 && email.includes('@')) +}, [name, email]) + +// ✅ Good - derive from existing state +const isFormValid = name.length > 0 && email.includes('@') +``` + +## Component Structure + +### Break down large components + +Components should ideally be under 200-300 lines. If a component grows larger, consider splitting it. + +**Signs a component should be split:** + +- Multiple distinct UI sections +- Complex conditional rendering logic +- Multiple useState hooks for unrelated state +- Difficult to understand at a glance + +```tsx +// ❌ Bad - monolithic component with everything inline +const UserDashboard = () => { + // 50 lines of hooks and state + // 100 lines of handlers + // 300 lines of JSX with nested conditions +} + +// ✅ Good - split into focused sub-components +const UserDashboard = () => { + return ( +
+ + + + +
+ ) +} +``` + +### Co-locate related components + +Place sub-components in the same directory as the parent component. Use an index file for cleaner imports. + +``` +components/interfaces/Auth/Users/ +├── UserPanel.tsx +├── UserOverview.tsx +├── UserLogs.tsx +├── Users.constants.ts +└── index.ts +``` + +### Extract repeated JSX patterns + +If you find yourself copying similar JSX blocks, extract them into a component. + +```tsx +// ❌ Bad - repeated pattern + + Overview + + + Logs + + +// ✅ Good - extract to component +const PanelTab = ({ value, children }: { value: string; children: ReactNode }) => ( + + {children} + +) +``` + +## Loading and Error States + +### Use consistent loading/error/success pattern + +Follow a consistent pattern for handling async states: + +```tsx +const { data, error, isLoading, isError, isSuccess } = useQuery() + +// Handle loading state first +if (isLoading) { + return +} + +// Handle error state +if (isError) { + return +} + +// Handle empty state if needed +if (isSuccess && data.length === 0) { + return +} + +// Render success state +return +``` + +### Use early returns for guard clauses + +Prefer early returns over deeply nested conditionals: + +```tsx +// ❌ Bad - deeply nested +const Component = () => { + if (data) { + if (!isError) { + if (hasPermission) { + return + } + } + } + return null +} + +// ✅ Good - early returns +const Component = () => { + if (!data) return null + if (isError) return + if (!hasPermission) return + + return +} +``` + +## State Management + +### Keep state as local as possible + +Start with local state and lift up only when needed. + +```tsx +// ✅ Good - state lives where it's used +const SearchableList = () => { + const [filterString, setFilterString] = useState('') + + const filteredItems = items.filter((item) => item.name.includes(filterString)) + + return ( +
+ setFilterString(e.target.value)} /> + +
+ ) +} +``` + +### Group related state with objects or reducers + +When you have multiple related pieces of state, consider grouping them: + +```tsx +// ❌ Bad - multiple related useState calls +const [name, setName] = useState('') +const [email, setEmail] = useState('') +const [phone, setPhone] = useState('') + +// ✅ Good - grouped state for forms (use react-hook-form) +const form = useForm({ + defaultValues: { name: '', email: '', phone: '' }, +}) +``` + +## Custom Hooks + +### Extract complex logic into custom hooks + +When logic becomes reusable or complex, extract it: + +```tsx +// ✅ Good - extracted to custom hook +export function useAsyncCheckPermissions(action: string, resource: string) { + const { permissions, isLoading, isSuccess } = useGetProjectPermissions() + + const can = useMemo(() => { + if (!IS_PLATFORM) return true + if (!isSuccess || !permissions) return false + return doPermissionsCheck(permissions, action, resource) + }, [isSuccess, permissions, action, resource]) + + return { isLoading, isSuccess, can } +} + +// Usage +const { can: canUpdateColumns } = useAsyncCheckPermissions( + PermissionAction.TENANT_SQL_ADMIN_WRITE, + 'columns' +) +``` + +### Return objects from hooks for better extensibility + +```tsx +// ❌ Bad - returning array (hard to extend) +const useToggle = () => { + const [value, setValue] = useState(false) + return [value, () => setValue((v) => !v)] +} + +// ✅ Good - returning object (easy to extend) +const useToggle = (initial = false) => { + const [value, setValue] = useState(initial) + return { + value, + toggle: () => setValue((v) => !v), + setTrue: () => setValue(true), + setFalse: () => setValue(false), + } +} +``` + +## Event Handlers + +### Name handlers consistently + +Use `on` prefix for prop callbacks and `handle` prefix for internal handlers: + +```tsx +interface Props { + onClose: () => void // Callback prop + onSave: (data: Data) => void +} + +const Component = ({ onClose, onSave }: Props) => { + const handleSubmit = () => { + // Internal handler + // process data + onSave(data) + } + + const handleCancel = () => { + // cleanup + onClose() + } +} +``` + +### Avoid inline arrow functions for expensive operations + +```tsx +// ❌ Bad - creates new function every render + handleItemClick(item)} /> + +// ✅ Good - stable reference with useCallback +const handleItemClick = useCallback( + (item: Item) => { + // handle click + }, + [dependencies] +) + + +``` + +## Conditional Rendering + +### Use appropriate patterns for different scenarios + +```tsx +// Simple show/hide - use && +{ + isVisible && +} + +// Binary choice - use ternary +{ + isLoading ? : +} + +// Multiple conditions - use early returns or extracted component +const StatusDisplay = ({ status }: { status: Status }) => { + if (status === 'loading') return + if (status === 'error') return + if (status === 'empty') return + return +} +``` + +### Avoid nested ternaries + +```tsx +// ❌ Bad - nested ternary +{ + isLoading ? : isError ? : +} + +// ✅ Good - separate conditions or early returns +if (isLoading) return +if (isError) return +return +``` + +## Performance + +### Use useMemo for expensive computations + +```tsx +// ✅ Good - memoize expensive filtering +const filteredItems = useMemo( + () => items.filter((item) => item.name.toLowerCase().includes(searchQuery.toLowerCase())), + [items, searchQuery] +) +``` + +### Avoid premature optimization + +Don't wrap everything in useMemo/useCallback. Only optimize when: + +- You have measured a performance problem +- The computation is genuinely expensive +- The value is passed to memoized children + +## TypeScript + +### Define prop interfaces explicitly + +```tsx +interface UserCardProps { + user: User + onEdit: (user: User) => void + onDelete: (userId: string) => void + isEditable?: boolean +} + +export const UserCard = ({ user, onEdit, onDelete, isEditable = true }: UserCardProps) => { + // ... +} +``` + +### Use discriminated unions for complex state + +```tsx +type AsyncState = + | { status: 'idle' } + | { status: 'loading' } + | { status: 'success'; data: T } + | { status: 'error'; error: Error } +``` + +### Avoid type casting, prefer validation with zod + +Never use type casting (e.g., `as any`, `as Type`). Instead, validate values at runtime using zod schemas. This ensures type safety and catches runtime errors. + +```tsx +// ❌ Bad - type casting bypasses type checking +const user = apiResponse as User +const data = unknownValue as string + +// ✅ Good - validate with zod schema +const userSchema = z.object({ + id: z.string(), + name: z.string(), + email: z.string().email(), +}) + +const user = userSchema.parse(apiResponse) +const data = z.string().parse(unknownValue) + +// ✅ Good - safe parsing with error handling +const result = userSchema.safeParse(apiResponse) +if (result.success) { + const user = result.data +} else { + // handle validation errors +} +``` diff --git a/.cursor/rules/studio/cards/RULE.md b/.cursor/rules/studio/cards/RULE.md new file mode 100644 index 00000000000..efcb36733b1 --- /dev/null +++ b/.cursor/rules/studio/cards/RULE.md @@ -0,0 +1,14 @@ +--- +description: "Studio: Card usage for grouping related content and actions" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio cards + +- Use cards to group related pieces of information. +- Use `CardContent` for sections and `CardFooter` for actions. +- Only use `CardHeader`/`CardTitle` when the card content is not already described by surrounding content (page title, section title, etc). +- Prefer headers/titles when multiple cards represent distinct groups (e.g. multiple settings groups). + diff --git a/.cursor/rules/studio/charts/RULE.md b/.cursor/rules/studio/charts/RULE.md new file mode 100644 index 00000000000..558580db3e8 --- /dev/null +++ b/.cursor/rules/studio/charts/RULE.md @@ -0,0 +1,26 @@ +--- +description: "Studio: composable chart patterns built on Recharts and our chart presentational components" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio charts + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/charts.mdx` +- Demos: + - `apps/design-system/__registry__/default/block/chart-composed-demo.tsx` + - `apps/design-system/__registry__/default/block/chart-composed-basic.tsx` + - `apps/design-system/__registry__/default/block/chart-composed-states.tsx` + - `apps/design-system/__registry__/default/block/chart-composed-metrics.tsx` + - `apps/design-system/__registry__/default/block/chart-composed-actions.tsx` + - `apps/design-system/__registry__/default/block/chart-composed-table.tsx` + +## Best practices + +- Prefer provided chart building blocks over passing raw Recharts components to `ChartContent`. +- Use `useChart` context flags for consistent loading/disabled handling. +- Keep chart composition straightforward; avoid over-abstraction. + diff --git a/.cursor/rules/studio/component-system/RULE.md b/.cursor/rules/studio/component-system/RULE.md new file mode 100644 index 00000000000..b6433123d0d --- /dev/null +++ b/.cursor/rules/studio/component-system/RULE.md @@ -0,0 +1,16 @@ +--- +description: 'Studio: UI component system (packages/ui + shadcn primitives)' +globs: + - apps/studio/**/*.{ts,tsx} + - packages/ui/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio component system + +Our primitive component system lives in `packages/ui` and is based on shadcn/ui patterns. + +- Prefer using components exported from `ui` (e.g. `import { Button } from 'ui'`). +- Prefer `_Shadcn_`-suffixed components for form components e.g. `Input_Shadcn_`. +- Avoid introducing new primitives unless explicitly requested. +- Browse available exports in `packages/ui/index.tsx` before composing new UI. diff --git a/.cursor/rules/studio/empty-states/RULE.md b/.cursor/rules/studio/empty-states/RULE.md new file mode 100644 index 00000000000..266213fe9a9 --- /dev/null +++ b/.cursor/rules/studio/empty-states/RULE.md @@ -0,0 +1,25 @@ +--- +description: 'Studio: empty state patterns (presentational vs informational vs zero-results vs missing route)' +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio empty states + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/empty-states.mdx` +- Demos: + - `apps/design-system/registry/default/example/empty-state-presentational-icon.tsx` + - `apps/design-system/registry/default/example/empty-state-initial-state-informational.tsx` + - `apps/design-system/registry/default/example/empty-state-zero-items-table.tsx` + - `apps/design-system/registry/default/example/data-grid-empty-state.tsx` + - `apps/design-system/registry/default/example/empty-state-missing-route.tsx` + +## Quick guidance + +- Initial states: use presentational empty states when onboarding/value prop + a clear next action helps. +- Data-heavy lists: prefer informational empty states that match the list/table layout. +- Zero results: keep the UI consistent with the data state to avoid jarring transitions. +- Missing routes: prefer a centered `Admonition` pattern. diff --git a/.cursor/rules/studio/forms/RULE.md b/.cursor/rules/studio/forms/RULE.md new file mode 100644 index 00000000000..b9b729111b5 --- /dev/null +++ b/.cursor/rules/studio/forms/RULE.md @@ -0,0 +1,35 @@ +--- +description: "Studio: form patterns (page layouts + side panels) and react-hook-form conventions" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio forms + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/forms.mdx` +- Demos: + - `apps/design-system/registry/default/example/form-patterns-pagelayout.tsx` + - `apps/design-system/registry/default/example/form-patterns-sidepanel.tsx` + +## Requirements + +- Build forms with `react-hook-form` + `zod`. +- Use `FormItemLayout` instead of manually composing `FormItem`/`FormLabel`/`FormMessage`/`FormDescription`. +- Wrap inputs with `FormControl_Shadcn_`. +- Use `_Shadcn_` imports from `ui` for form primitives where available. + +## Layout selection + +- Page layouts: `FormItemLayout layout="flex-row-reverse"` inside `Card` (`CardContent` per field; `CardFooter` for actions). +- Side panels (wide): `FormItemLayout layout="horizontal"` inside `SheetSection`. +- Side panels (narrow, `size="sm"` or below): `FormItemLayout layout="vertical"`. + +## Actions and state + +- Handle dirty state (`form.formState.isDirty`) to show Cancel and to disable Save. +- Show loading on submit buttons via `loading`. +- When submit button is outside the `
`, set a stable `formId` and use the button’s `form` prop. + diff --git a/.cursor/rules/studio/layout/RULE.md b/.cursor/rules/studio/layout/RULE.md new file mode 100644 index 00000000000..b39f082b740 --- /dev/null +++ b/.cursor/rules/studio/layout/RULE.md @@ -0,0 +1,28 @@ +--- +description: 'Studio: page layout patterns (PageContainer/PageHeader/PageSection) and sizing guidance. Use to learn how to create or update existing pages in Studio.' +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio layout + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/layout.mdx` +- Demos: + - `apps/design-system/registry/default/example/page-layout-settings.tsx` + - `apps/design-system/registry/default/example/page-layout-list.tsx` + - `apps/design-system/registry/default/example/page-layout-list-simple.tsx` + - `apps/design-system/registry/default/example/page-layout-detail.tsx` + +## Guidelines + +- Build pages using `PageContainer`, `PageHeader`, and `PageSection` for consistent spacing and max-widths. +- Choose `size` based on content: + - Settings/config: `size="default"` + - List/table-heavy: `size="large"` + - Full-screen experiences: `size="full"` +- For list pages: + - If filters/search exist, align table actions with filters (avoid `PageHeaderAside`/`PageSectionAside` for those actions). + - If no filters/search, actions can go in `PageHeaderAside` or `PageSectionAside` depending on context. diff --git a/.cursor/rules/studio/navigation/RULE.md b/.cursor/rules/studio/navigation/RULE.md new file mode 100644 index 00000000000..eb37afda3fb --- /dev/null +++ b/.cursor/rules/studio/navigation/RULE.md @@ -0,0 +1,19 @@ +--- +description: "Studio: navigation patterns (page-level NavMenu + URL-driven navigation)" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio navigation + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/navigation.mdx` + +## NavMenu + +- Use `NavMenu` for a horizontal list of related views within a consistent page layout. +- Activating an item should trigger a URL change (no local-only tab state). +- See: `apps/design-system/content/docs/components/nav-menu.mdx` + diff --git a/.cursor/rules/studio/project-structure/RULE.md b/.cursor/rules/studio/project-structure/RULE.md new file mode 100644 index 00000000000..d87139dd5a3 --- /dev/null +++ b/.cursor/rules/studio/project-structure/RULE.md @@ -0,0 +1,19 @@ +--- +description: "Studio: project structure and where code lives" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio project structure + +- Studio is a Next.js app using the pages router. +- Pages live in `apps/studio/pages`. + - Project pages: `apps/studio/pages/projects/[ref]` + - Org pages: `apps/studio/pages/org/[slug]` +- Studio components live in `apps/studio/components`. + - Studio UI helpers: `apps/studio/components/ui` + - Interface/page components: `apps/studio/components/interfaces` (e.g. `apps/studio/components/interfaces/Auth`) +- Shared hooks: `apps/studio/hooks` +- Shared helpers: `apps/studio/lib` + diff --git a/.cursor/rules/studio/queries/RULE.md b/.cursor/rules/studio/queries/RULE.md new file mode 100644 index 00000000000..0e394b01d28 --- /dev/null +++ b/.cursor/rules/studio/queries/RULE.md @@ -0,0 +1,113 @@ +--- +description: 'Studio: data fetching conventions for queries/mutations (React Query hooks)' +globs: + - apps/studio/data/**/*.{ts,tsx} + - apps/studio/pages/**/*.{ts,tsx} + - apps/studio/components/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio queries & mutations (React Query) + +Follow the `apps/studio/data/` patterns used by edge functions: + +- Query hook: `apps/studio/data/edge-functions/edge-functions-query.ts` +- Mutation hook: `apps/studio/data/edge-functions/edge-functions-update-mutation.ts` +- Keys: `apps/studio/data/edge-functions/keys.ts` +- Page usage: `apps/studio/pages/project/[ref]/functions/index.tsx` + +## Organize query keys + +- Define a `keys.ts` per domain and export `*Keys` helpers (use array keys with `as const`). +- Do not inline query keys in components. + +Example: + +```ts +export const edgeFunctionsKeys = { + list: (projectRef: string | undefined) => ['projects', projectRef, 'edge-functions'] as const, + detail: (projectRef: string | undefined, slug: string | undefined) => + ['projects', projectRef, 'edge-function', slug, 'detail'] as const, +} +``` + +## Write a query hook + +- Export `Variables`, `Data`, and `Error` types from the file. +- Implement a `getX(variables, signal?)` function that: + - throws if required variables are missing + - passes the `signal` through to the fetcher for cancellation + - calls `handleError(error)` and returns `data` +- Wrap it in `useXQuery()` using `useQuery`, `UseCustomQueryOptions`, and a domain key helper. +- Gate with `enabled` so the query doesn’t run until required variables exist (and platform-only queries should include `IS_PLATFORM`). + +Template: + +```ts +export type XVariables = { projectRef?: string } +export type XError = ResponseError + +export async function getX({ projectRef }: XVariables, signal?: AbortSignal) { + if (!projectRef) throw new Error('projectRef is required') + const { data, error } = await get('/v1/projects/{ref}/x', { + params: { path: { ref: projectRef } }, + signal, + }) + if (error) handleError(error) + return data +} + +export type XData = Awaited> + +export const useXQuery = ( + { projectRef }: XVariables, + { enabled = true, ...options }: UseCustomQueryOptions = {} +) => + useQuery({ + queryKey: xKeys.list(projectRef), + queryFn: ({ signal }) => getX({ projectRef }, signal), + enabled: IS_PLATFORM && enabled && typeof projectRef !== 'undefined', + ...options, + }) +``` + +## Write a mutation hook + +- Export a `Variables` type that includes `projectRef`, identifiers (e.g. `slug`), and `payload`. +- Implement an `updateX(vars)` function that validates required variables and uses `handleError`. +- Prefer a `useXMutation()` wrapper that: + - accepts `UseCustomMutationOptions` (omit `mutationFn`) + - invalidates the relevant `list()` + `detail()` keys in `onSuccess` and `await`s them via `Promise.all` + - defaults to a `toast.error(...)` when `onError` isn’t provided + +Template: + +```ts +export const useXUpdateMutation = ({ onSuccess, onError, ...options } = {}) => { + const queryClient = useQueryClient() + return useMutation({ + mutationFn: updateX, + async onSuccess(data, variables, context) { + await Promise.all([ + queryClient.invalidateQueries({ + queryKey: xKeys.detail(variables.projectRef, variables.slug), + }), + queryClient.invalidateQueries({ queryKey: xKeys.list(variables.projectRef) }), + ]) + await onSuccess?.(data, variables, context) + }, + async onError(error, variables, context) { + if (onError === undefined) toast.error(`Failed to update: ${error.message}`) + else onError(error, variables, context) + }, + ...options, + }) +} +``` + +## Component usage + +- Prefer React Query’s v5 flags: + - `isPending` for initial load (often aliased to `isLoading`) + - `isFetching` for background refetches +- Render states explicitly (pending → error → success), like `apps/studio/pages/project/[ref]/functions/index.tsx`. diff --git a/.cursor/rules/studio/sheets/RULE.md b/.cursor/rules/studio/sheets/RULE.md new file mode 100644 index 00000000000..f55b3958ec5 --- /dev/null +++ b/.cursor/rules/studio/sheets/RULE.md @@ -0,0 +1,23 @@ +--- +description: "Studio: side panels (Sheet) for context-preserving workflows" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio sheets + +Use a `Sheet` when switching to a new page would be disruptive and the user should keep context (e.g. selecting an item from a list to edit details). + +## Structure + +- Prefer `SheetContent` with `size="lg"` for forms that need horizontal layout. +- Use `SheetHeader`, `SheetTitle`, `SheetSection`, and `SheetFooter` for consistent structure. +- Place submit/cancel actions in `SheetFooter`. + +## Forms in sheets + +- Prefer `FormItemLayout`: + - `layout="horizontal"` for wider sheets + - `layout="vertical"` for narrow sheets (`size="sm"` or below) +- See `@studio/forms` for the canonical patterns and demos. diff --git a/.cursor/rules/studio/styling/RULE.md b/.cursor/rules/studio/styling/RULE.md new file mode 100644 index 00000000000..f1679fbc264 --- /dev/null +++ b/.cursor/rules/studio/styling/RULE.md @@ -0,0 +1,16 @@ +--- +description: "Studio: styling rules (Tailwind + semantic tokens + typography/focus utilities)" +globs: + - apps/studio/**/*.{ts,tsx,scss} +alwaysApply: false +--- + +# Studio styling + +- Use Tailwind. +- Do not hardcode Tailwind color tokens; use our semantic classes: + - backgrounds: `bg`, `bg-muted`, `bg-warning`, `bg-destructive` + - text: `text-foreground`, `text-foreground-light`, `text-foreground-lighter`, `text-warning`, `text-destructive` +- Use existing typography utilities from `apps/studio/styles/typography.scss` instead of recreating styles. +- Use existing focus utilities from `apps/studio/styles/focus.scss` for consistent keyboard focus styling. + diff --git a/.cursor/rules/studio/tables/RULE.md b/.cursor/rules/studio/tables/RULE.md new file mode 100644 index 00000000000..c610fe84268 --- /dev/null +++ b/.cursor/rules/studio/tables/RULE.md @@ -0,0 +1,29 @@ +--- +description: "Studio: table patterns (Table vs Data Table vs Data Grid) and placement of actions/filters" +globs: + - apps/studio/**/*.{ts,tsx} +alwaysApply: false +--- + +# Studio tables + +Use the Design System UI pattern docs as the source of truth: + +- Documentation: `apps/design-system/content/docs/ui-patterns/tables.mdx` +- Demos: + - `apps/design-system/registry/default/example/table-demo.tsx` + - `apps/design-system/registry/default/example/data-table-demo.tsx` + - `apps/design-system/registry/default/example/data-grid-demo.tsx` + +## Choose the right pattern + +- `Table`: simple, static, semantic table display. +- Data Table: TanStack-powered pattern for sorting/filtering/pagination; composed per use case. +- Data Grid: only when you need virtualization, column resizing, or complex cell editing. + +## Actions and filters placement + +- Actions: above the table, aligned right. +- Search/filters: above the table, aligned left. +- If the table is the primary page content and has no filters/search, actions can live in the page’s primary/secondary actions area. + diff --git a/.cursor/rules/testing/e2e-studio/RULE.md b/.cursor/rules/testing/e2e-studio/RULE.md new file mode 100644 index 00000000000..354cd86ac20 --- /dev/null +++ b/.cursor/rules/testing/e2e-studio/RULE.md @@ -0,0 +1,324 @@ +--- +description: "Testing: Playwright E2E best practices for Studio tests (avoid flake + race conditions)" +globs: + - e2e/studio/**/*.ts + - e2e/studio/**/*.spec.ts +alwaysApply: false +--- + +# E2E Testing Best Practices + +## Getting Context + +Before writing or modifying tests, use the Playwright MCP to understand: + +- Available page elements and their roles/locators +- Current page state and network activity +- Existing test patterns in the codebase + +Avoid extensive code reading - let Playwright's inspection tools guide your understanding of the UI. + +## Avoiding Race Conditions + +### Set up API waiters BEFORE triggering actions + +The most common source of flaky tests is race conditions between UI actions and API calls. Always create response waiters before clicking buttons or navigating. + +```ts +// ❌ Bad - race condition: response might complete before waiter is set up +await page.getByRole('button', { name: 'Save' }).click() +await waitForApiResponse(page, 'pg-meta', ref, 'query?key=table-create') + +// ✅ Good - waiter is ready before action +const apiPromise = waitForApiResponse(page, 'pg-meta', ref, 'query?key=table-create') +await page.getByRole('button', { name: 'Save' }).click() +await apiPromise +``` + +### Use `createApiResponseWaiter` for pre-navigation waits + +When you need to wait for a response that happens during navigation: + +```ts +// ✅ Good - waiter created before navigation +const loadPromise = waitForTableToLoad(page, ref) +await page.goto(toUrl(`/project/${ref}/editor?schema=public`)) +await loadPromise +``` + +### Wait for multiple related API calls with Promise.all + +When an action triggers multiple API calls, wait for all of them: + +```ts +// ✅ Good - wait for all related API calls +const createTablePromise = waitForApiResponseWithTimeout(page, (response) => + response.url().includes('query?key=table-create') +) +const tablesPromise = waitForApiResponseWithTimeout(page, (response) => + response.url().includes('tables?include_columns=true') +) +const entitiesPromise = waitForApiResponseWithTimeout(page, (response) => + response.url().includes('query?key=entity-types-') +) + +await page.getByRole('button', { name: 'Save' }).click() +await Promise.all([createTablePromise, tablesPromise, entitiesPromise]) +``` + +## Waiting Strategies + +### Prefer Playwright's built-in auto-waiting + +Playwright automatically waits for elements to be actionable. Use this instead of manual timeouts: + +```ts +// ❌ Bad - arbitrary timeout +await page.waitForTimeout(2000) +await page.getByRole('button', { name: 'Submit' }).click() + +// ✅ Good - auto-waits for element to be visible and enabled +await page.getByRole('button', { name: 'Submit' }).click() +``` + +### Use `expect.poll` for dynamic assertions + +When waiting for state to change: + +```ts +// ✅ Good - polls until condition is met +await expect + .poll(async () => { + return await page.getByLabel(`View ${tableName}`).count() + }) + .toBe(0) +``` + +### Use `waitForSelector` with state for element lifecycle + +```ts +// ✅ Good - wait for panel to close +await page.waitForSelector('[data-testid="side-panel"]', { state: 'detached' }) +``` + +### Avoid `networkidle` - use specific API waits instead + +```ts +// ❌ Bad - unreliable and slow +await page.waitForLoadState('networkidle') + +// ✅ Good - wait for specific API response +await waitForApiResponse(page, 'pg-meta', ref, 'tables') +``` + +### Use timeouts sparingly and only for non-API waits + +```ts +// ✅ Acceptable - waiting for client-side debounce +await page.getByRole('textbox').fill('search term') +await page.waitForTimeout(300) // Allow debounce to complete + +// ✅ Acceptable - waiting for clipboard API +await page.evaluate(() => navigator.clipboard.readText()) +await page.waitForTimeout(500) +``` + +## Test Structure + +### Use the custom test utility + +Always import from the custom test utility for consistent fixtures: + +```ts +import { test } from '../utils/test.js' +``` + +### Use `withFileOnceSetup` for expensive setup + +When setup is expensive (cleanup, seeding), run it once per file: + +```ts +test.beforeAll(async ({ browser, ref }) => { + await withFileOnceSetup(import.meta.url, async () => { + const ctx = await browser.newContext() + const page = await ctx.newPage() + + // Expensive setup logic (e.g., cleanup old test data) + await deleteTestTables(page, ref) + }) +}) + +test.afterAll(async () => { + await releaseFileOnceCleanup(import.meta.url) +}) +``` + +### Dismiss toasts before interacting with UI + +Toasts can overlay buttons and block interactions: + +```ts +const dismissToastsIfAny = async (page: Page) => { + const closeButtons = page.getByRole('button', { name: 'Close toast' }) + const count = await closeButtons.count() + for (let i = 0; i < count; i++) { + await closeButtons.nth(i).click() + } +} + +// ✅ Good - dismiss toasts before clicking +await dismissToastsIfAny(page) +await page.getByRole('button', { name: 'New table' }).click() +``` + +## Assertions + +### Always include descriptive messages + +```ts +// ❌ Bad - no context on failure +await expect(page.getByRole('button', { name: 'Save' })).toBeVisible() + +// ✅ Good - clear message on failure +await expect( + page.getByRole('button', { name: 'Save' }), + 'Save button should be visible after form is filled' +).toBeVisible() +``` + +### Use appropriate timeouts for slow operations + +```ts +// ✅ Good - explicit timeout for slow operations +await expect( + page.getByText(`Table ${tableName} is good to go!`), + 'Success toast should be visible after table creation' +).toBeVisible({ timeout: 50000 }) +``` + +## Locators + +### Prefer role-based locators + +```ts +// ✅ Good - semantic and resilient +page.getByRole('button', { name: 'Save' }) +page.getByRole('textbox', { name: 'Username' }) +page.getByRole('menuitem', { name: 'Delete' }) + +// ❌ Avoid - brittle CSS selectors +page.locator('.btn-primary') +page.locator('#submit-button') +``` + +### Use test IDs for complex elements + +```ts +// ✅ Good - stable identifier for complex elements +page.getByTestId('table-editor-side-panel') +page.getByTestId('action-bar-save-row') +``` + +### Use `filter` for finding elements in context + +```ts +// ✅ Good - find button within specific row +const bucketRow = page.getByRole('row').filter({ hasText: bucketName }) +await bucketRow.getByRole('button').click() +``` + +## Helper Functions + +### Extract reusable operations into helpers + +Create helper functions for common operations: + +```ts +// e2e/studio/utils/storage-helpers.ts +export const createBucket = async ( + page: Page, + ref: string, + bucketName: string, + isPublic: boolean = false +) => { + await navigateToStorageFiles(page, ref) + + // Check if already exists + const bucketRow = page.getByRole('row').filter({ hasText: bucketName }) + if ((await bucketRow.count()) > 0) return + + await dismissToastsIfAny(page) + + // Create bucket with proper waits + const apiPromise = waitForApiResponse(page, 'storage', ref, 'bucket', { method: 'POST' }) + await page.getByRole('button', { name: 'New bucket' }).click() + await page.getByRole('textbox', { name: 'Bucket name' }).fill(bucketName) + await page.getByRole('button', { name: 'Create' }).click() + await apiPromise + + await expect( + page.getByRole('row').filter({ hasText: bucketName }), + `Bucket ${bucketName} should be visible` + ).toBeVisible() +} +``` + +### Use the existing wait utilities + +```ts +import { + createApiResponseWaiter, + waitForApiResponse, + waitForGridDataToLoad, + waitForTableToLoad, +} from '../utils/wait-for-response.js' +``` + +## API Mocking + +### Mock APIs for isolated testing + +```ts +// ✅ Good - mock API response +await page.route('*/**/logs.all*', async (route) => { + await route.fulfill({ body: JSON.stringify(mockAPILogs) }) +}) +``` + +### Use soft waits for optional API calls + +```ts +// ✅ Good - don't fail if API doesn't respond +await waitForApiResponse(page, 'pg-meta', ref, 'optional-endpoint', { + soft: true, + fallbackWaitMs: 1000, +}) +``` + +## Cleanup + +### Clean up test data in beforeAll/beforeEach + +```ts +test.beforeEach(async ({ page, ref }) => { + await deleteAllBuckets(page, ref) +}) +``` + +### Handle existing state gracefully + +```ts +// ✅ Good - check before trying to delete +const bucketRow = page.getByRole('row').filter({ hasText: bucketName }) +if ((await bucketRow.count()) === 0) return +// proceed with deletion +``` + +### Reset local storage when needed + +```ts +import { resetLocalStorage } from '../utils/reset-local-storage.js' + +// Clean up after tests that modify local storage +await resetLocalStorage(page, ref) +``` diff --git a/.cursor/rules/testing/unit-integration/RULE.md b/.cursor/rules/testing/unit-integration/RULE.md new file mode 100644 index 00000000000..7248ee737a4 --- /dev/null +++ b/.cursor/rules/testing/unit-integration/RULE.md @@ -0,0 +1,10 @@ +--- +description: "Testing: unit/integration conventions for Studio test files" +globs: + - apps/studio/**/*.test.ts + - apps/studio/**/*.test.tsx +alwaysApply: false +--- + +Follow the guidelines in `apps/studio/tests/README.md` when writing tests for Studio. + diff --git a/.cursor/rules/unit-integration-testing.mdc b/.cursor/rules/unit-integration-testing.mdc deleted file mode 100644 index e3a659a7c53..00000000000 --- a/.cursor/rules/unit-integration-testing.mdc +++ /dev/null @@ -1,6 +0,0 @@ ---- -description: -globs: apps/studio/**/*.test.ts,apps/studio/**/*.test.tsx -alwaysApply: false ---- -Make sure to follow the guidelines in this file to write tests: [README.md](mdc:apps/studio/tests/README.md) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f8828ca5959..5747ca47b96 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,3 +18,5 @@ /apps/studio/components/interfaces/Billing/Payment @supabase/security /apps/studio/components/interfaces/Organization/Documents/ @supabase/security /apps/studio/pages/new/index.tsx @supabase/security + +/apps/studio/data/sql/queries/ @supabase/postgres @avallete \ No newline at end of file diff --git a/.github/workflows/authorize-vercel-deploys.yml b/.github/workflows/authorize-vercel-deploys.yml new file mode 100644 index 00000000000..6a72b23d7a6 --- /dev/null +++ b/.github/workflows/authorize-vercel-deploys.yml @@ -0,0 +1,50 @@ +name: Authorize Vercel Deploys + +# This workflow is triggered by the validate-pr workflow. When it's triggered, it will run the +# authorize-vercel-deploys.yml in master branch. If you want to change it, you'll have to merge it into master. +on: + # only run this workflow when the validate-pr workflow completes (successfully or not) + workflow_run: + workflows: ['Validate pull request'] + types: [completed] + +# Cancel old builds on new commit for same workflow + branch/PR. +concurrency: + group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + authorize-vercel-deploys: + runs-on: blacksmith-4vcpu-ubuntu-2404 + + steps: + # Checkout the master branch from the supabase repo and run that script to authorize Vercel deploys + - name: Check out repo + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + ref: master + # fetch only the root files and scripts folder + sparse-checkout: | + scripts + - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + name: Install pnpm + with: + run_install: false + - name: Setup node + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: '.nvmrc' + cache: 'pnpm' + - name: Download dependencies + run: | + pnpm install --frozen-lockfile + - name: Authorize Vercel Deploys + run: |- + pnpm run authorize-vercel-deploys + env: + VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }} + # The SHA of the commit that triggered the validate-pr workflow + HEAD_COMMIT_SHA: ${{ github.event.workflow_run.head_sha }} diff --git a/.github/workflows/autofix_linters.yml b/.github/workflows/autofix_linters.yml index 860525080d2..2ae0159afa5 100644 --- a/.github/workflows/autofix_linters.yml +++ b/.github/workflows/autofix_linters.yml @@ -10,9 +10,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true -permissions: - contents: read - jobs: autofix: runs-on: blacksmith-2vcpu-ubuntu-2404 @@ -23,10 +20,18 @@ jobs: - name: Calculate number of commits run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}" + - name: Generate token + id: app-token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + permission-contents: write + - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 with: ref: ${{ github.head_ref }} - token: ${{ secrets.PAT_AUTOFIX }} + token: ${{ steps.app-token.outputs.token }} fetch-depth: ${{ env.PR_FETCH_DEPTH }} sparse-checkout: | packages diff --git a/.github/workflows/braintrust-evals.yml b/.github/workflows/braintrust-evals.yml new file mode 100644 index 00000000000..915d2e3bb38 --- /dev/null +++ b/.github/workflows/braintrust-evals.yml @@ -0,0 +1,60 @@ +name: Run Braintrust evals + +on: + push: + branches: [master] + pull_request: + types: [opened, synchronize, labeled] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +permissions: + pull-requests: write + contents: read + +jobs: + eval: + name: Run evals + if: github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-evals')) + runs-on: ubuntu-latest + timeout-minutes: 20 + + env: + BRAINTRUST_PROJECT_ID: ${{ secrets.BRAINTRUST_PROJECT_ID }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + + steps: + - name: Checkout + uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + with: + fetch-depth: 0 + # For PR events, checkout the actual branch so Braintrust can report the correct branch name instead of detached HEAD. + # github.head_ref is the PR source branch, github.ref_name is the fallback for push events (e.g., master). + ref: ${{ github.head_ref || github.ref_name }} + + - name: Install pnpm + uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + with: + run_install: false + + - name: Use Node.js + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 + with: + node-version-file: ".nvmrc" + cache: "pnpm" + + - name: Install Dependencies + run: pnpm install --frozen-lockfile + + - name: Setup Evals + run: cd apps/studio && pnpm evals:setup + + - name: Run Evals + uses: braintrustdata/eval-action@v1 + with: + api_key: ${{ secrets.BRAINTRUST_API_KEY }} + runtime: node + package_manager: pnpm + root: apps/studio diff --git a/.github/workflows/docs-js-libs-update.yml b/.github/workflows/docs-js-libs-update.yml index 8f0de19feca..398ebf0b5fb 100644 --- a/.github/workflows/docs-js-libs-update.yml +++ b/.github/workflows/docs-js-libs-update.yml @@ -54,14 +54,21 @@ jobs: echo "Generating new typespec snapshot for review..." npx vitest run --update ./features/docs/Reference.typeSpec.test.ts + - name: Generate token + id: app-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + - name: Create pull request uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 with: - token: ${{ secrets.GITHUB_TOKEN }} - commit-message: 'docs: update js client libraries (${{ github.event.inputs.version }})' - title: 'docs: update js client libraries (${{ github.event.inputs.version }})' + token: ${{ steps.app-token.outputs.token }} + commit-message: 'docs: update js sdk docs (${{ github.event.inputs.version }})' + title: 'docs: update js sdk docs (${{ github.event.inputs.version }})' body: | - Updates JS client libraries documentation following stable release. + Updates JS sdk documentation following stable release. Ran `make` in apps/docs/spec to regenerate tsdoc files. **Details:** @@ -69,6 +76,6 @@ jobs: - **Source:** `${{ github.event.inputs.source }}` - **Changes:** Regenerated tsdoc files from latest spec files - 🤖 Auto-generated from supabase-js-libs stable release. - branch: 'gha/update-js-libs-docs-${{ github.run_number }}' + 🤖 Auto-generated from @supabase/supabase-js stable release. + branch: 'gha/update-js-sdk-docs-${{ github.run_number }}' base: 'master' diff --git a/.github/workflows/docs-mgmt-api-update.yml b/.github/workflows/docs-mgmt-api-update.yml index ad119b68993..26eb74756e6 100644 --- a/.github/workflows/docs-mgmt-api-update.yml +++ b/.github/workflows/docs-mgmt-api-update.yml @@ -39,10 +39,17 @@ jobs: working-directory: apps/docs/spec run: make download.api.v1 dereference.api.v1 generate.sections.api.v1 format + - name: Generate token + id: app-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + - name: Create pull request uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ steps.app-token.outputs.token }} commit-message: 'feat: update mgmt api docs' title: 'feat: update mgmt api docs' body: 'This PR updates mgmt api docs automatically.' diff --git a/.github/workflows/docs-sync-troubleshooting.yml b/.github/workflows/docs-sync-troubleshooting.yml index 88eb091e21a..c3794079eca 100644 --- a/.github/workflows/docs-sync-troubleshooting.yml +++ b/.github/workflows/docs-sync-troubleshooting.yml @@ -54,3 +54,4 @@ jobs: author: 'github-docs-sync-bot ' branch: 'bot/docs-sync-troubleshooting' branch-suffix: 'random' + labels: 'documentation' diff --git a/.github/workflows/fix-typos.yml b/.github/workflows/fix-typos.yml index a7af81d334d..bc1ca8cc089 100644 --- a/.github/workflows/fix-typos.yml +++ b/.github/workflows/fix-typos.yml @@ -11,7 +11,6 @@ concurrency: permissions: contents: read - pull-requests: write jobs: build: @@ -21,6 +20,16 @@ jobs: with: ref: master - uses: sobolevn/misspell-fixer-action@06ff0b508d4f4c0ba70d15f9a628232c0aade536 # v0.1.0 + + - name: Generate token + id: app-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ steps.app-token.outputs.token }} diff --git a/.github/workflows/publish_image.yml b/.github/workflows/publish_image.yml index 40c142134ab..9865b284630 100644 --- a/.github/workflows/publish_image.yml +++ b/.github/workflows/publish_image.yml @@ -124,6 +124,12 @@ jobs: docker buildx imagetools create -t supabase/studio:latest \ supabase/studio@${{ needs.release_x86.outputs.image_digest }} \ supabase/studio@${{ needs.release_arm.outputs.image_digest }} + echo "Published Registry Images" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "| Image | Link |" >> $GITHUB_STEP_SUMMARY + echo "|-------|------|" >> $GITHUB_STEP_SUMMARY + echo "| \`supabase/studio:${{ needs.settings.outputs.image_version }}\` | [View on Docker Hub](https://hub.docker.com/r/supabase/studio/tags?name=${{ needs.settings.outputs.image_version }}) |" >> $GITHUB_STEP_SUMMARY + echo "| \`supabase/studio:latest\` | [View on Docker Hub](https://hub.docker.com/r/supabase/studio/tags?name=latest) |" >> $GITHUB_STEP_SUMMARY publish: needs: diff --git a/.github/workflows/studio-e2e-test.yml b/.github/workflows/studio-e2e-test.yml index 68fa270e72c..e7f0cbb39b7 100644 --- a/.github/workflows/studio-e2e-test.yml +++ b/.github/workflows/studio-e2e-test.yml @@ -2,18 +2,7 @@ name: Selfhosted Studio E2E Tests on: push: branches: [master] - paths: - - 'packages/pg-meta/**/*' - - 'apps/studio/**' - - 'e2e/studio/**' - - 'pnpm-lock.yaml' pull_request: - paths: - - 'packages/pg-meta/**/*' - - 'apps/studio/**' - - 'e2e/studio/**' - - 'pnpm-lock.yaml' - - '.github/workflows/studio-e2e-test.yml' # Cancel old builds on new commit for same workflow + branch/PR concurrency: @@ -28,33 +17,51 @@ jobs: test: timeout-minutes: 60 runs-on: blacksmith-4vcpu-ubuntu-2404 - # Require approval only for pull requests from forks - environment: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork && 'Studio E2E Tests' || '' }} + + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} steps: - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0 + - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + id: filter + with: + filters: | + studio: + - 'packages/pg-meta/**' + - 'apps/studio/**' + - 'apps/ui-library/**' + - 'apps/design-system/**' + - 'e2e/studio/**' + - 'pnpm-lock.yaml' + - '.github/workflows/studio-e2e-test.yml' - uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0 + if: steps.filter.outputs.studio == 'true' name: Install pnpm with: run_install: false - name: Use Node.js + if: steps.filter.outputs.studio == 'true' uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version-file: '.nvmrc' cache: 'pnpm' - name: Install dependencies + if: steps.filter.outputs.studio == 'true' run: pnpm install --frozen-lockfile - name: Install Playwright Browsers + if: steps.filter.outputs.studio == 'true' run: pnpm -C e2e/studio exec playwright install chromium --with-deps --only-shell - name: 🚀 Run Playwright tests against Vercel Preview + if: steps.filter.outputs.studio == 'true' id: playwright run: pnpm e2e - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 - if: always() + if: always() && steps.filter.outputs.studio == 'true' with: name: playwright-artifacts path: | @@ -64,13 +71,13 @@ jobs: - name: Comment Playwright test results on PR uses: daun/playwright-report-comment@be9e270edd5ad86038604d3caa84a819a6ff6fed # v3.10.0 - if: always() && github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork + if: always() && steps.filter.outputs.studio == 'true' && github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork with: report-file: e2e/studio/test-results/test-results.json comment-title: '🎭 Playwright Test Results' - name: Fail job if tests failed - if: steps.playwright.outcome != 'success' || steps.summarize.outputs.flaky_count > 0 + if: steps.filter.outputs.studio == 'true' && (steps.playwright.outcome != 'success' || steps.summarize.outputs.flaky_count > 0) run: | echo "E2E tests failed" >&2 exit 1 diff --git a/.github/workflows/studio-lint-ratchet-decrease.yml b/.github/workflows/studio-lint-ratchet-decrease.yml index 27d3f968e03..4598a0cf7fb 100644 --- a/.github/workflows/studio-lint-ratchet-decrease.yml +++ b/.github/workflows/studio-lint-ratchet-decrease.yml @@ -35,9 +35,16 @@ jobs: - name: Install deps run: pnpm install --frozen-lockfile + - name: Generate token + id: app-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + - name: Decrease ESLint ratchet baselines and open PR env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ steps.app-token.outputs.token }} DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} run: | set -eo pipefail diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index dbb9a2fedc1..cd3b1d5d5f6 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -16,8 +16,9 @@ permissions: jobs: typecheck: - # Uses larger hosted runner as it significantly decreases build times - runs-on: blacksmith-4vcpu-ubuntu-2404 + runs-on: blacksmith-2vcpu-ubuntu-2404 + env: + NODE_OPTIONS: --max-old-space-size=4096 steps: - name: Checkout @@ -38,7 +39,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Run TypeScript type check - run: pnpm exec turbo run typecheck + run: pnpm run typecheck - name: Run Lint - run: pnpm exec turbo run lint + run: pnpm run lint diff --git a/.github/workflows/update-js-libs.yml b/.github/workflows/update-js-libs.yml index 2c371be9380..ef6a611e712 100644 --- a/.github/workflows/update-js-libs.yml +++ b/.github/workflows/update-js-libs.yml @@ -56,11 +56,18 @@ jobs: - name: Install dependencies run: pnpm install --no-frozen-lockfile - + + - name: Generate token + id: app-token + uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1 + with: + app-id: ${{ secrets.GH_AUTOFIX_APP_ID }} + private-key: ${{ secrets.GH_AUTOFIX_PRIVATE_KEY }} + - name: Create pull request uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0 with: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ steps.app-token.outputs.token }} commit-message: 'feat: update @supabase/*-js libraries to v${{ github.event.inputs.version }}' title: 'feat: update @supabase/*-js libraries to v${{ github.event.inputs.version }}' body: | diff --git a/.github/workflows/validate-pr.yml b/.github/workflows/validate-pr.yml new file mode 100644 index 00000000000..ffb9c43ca95 --- /dev/null +++ b/.github/workflows/validate-pr.yml @@ -0,0 +1,21 @@ +name: Validate pull request + +# This workflow will trigger the authorize-vercel-deploys workflow when it's finished. +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize, ready_for_review] + +jobs: + validate-pr: + runs-on: ubuntu-latest + steps: + - name: Tagged with 'do not merge' + if: contains( github.event.pull_request.labels.*.name, 'do-not-merge') + run: | + echo "PR blocked: [tag: do not merge]" + exit 1 + + - name: All good + if: ${{ success() }} + run: | + echo "All good" diff --git a/.gitignore b/.gitignore index 25662fb0017..5d4494d1cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,9 @@ next-env.d.ts .vercel # AI assistant local files -.serena/ +.claude/* +!.claude/settings.json +!.claude/scripts/ CLAUDE.md #include template .env file for docker-compose @@ -149,4 +151,4 @@ gcloud.json # Sentry CLI config **/.sentryclirc -keys.json \ No newline at end of file +keys.json diff --git a/DEVELOPERS.md b/DEVELOPERS.md index ef6e298c9ae..d97159286e1 100644 --- a/DEVELOPERS.md +++ b/DEVELOPERS.md @@ -192,7 +192,7 @@ We support "federating" docs, meaning doc content can come directly from externa Federated docs work using Next.js's build pipeline. We use `getStaticProps()` to fetch remote documentation (ie. markdown) at build time which is processed and passed to the respective page within the docs. -See the [Vecs Python source code](https://github.com/supabase/supabase/blob/master/apps/docs/pages/guides/ai/python/%5Bslug%5D.tsx) to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs. +See the [Vecs Python source code](https://github.com/supabase/supabase/tree/master/apps/docs/app/guides/ai/python/%5Bslug%5D to see how we do this for [`supabase/vecs`](https://github.com/supabase/vecs). Use this as a starting point for federating other docs. Some things to consider: diff --git a/README.md b/README.md index ee13ffbc323..08120545543 100644 --- a/README.md +++ b/README.md @@ -96,11 +96,11 @@ Our approach for client libraries is modular. Each sub-library is a standalone i JavaScript (TypeScript) supabase-js - postgrest-js - gotrue-js - realtime-js - storage-js - functions-js + postgrest-js + auth-js + realtime-js + storage-js + functions-js Flutter @@ -189,11 +189,11 @@ Our approach for client libraries is modular. Each sub-library is a standalone i Godot Engine (GDScript) supabase-gdscript - postgrest-gdscript - gotrue-gdscript - realtime-gdscript - storage-gdscript - functions-gdscript + - + - + - + - + - diff --git a/apps/cms/package.json b/apps/cms/package.json index 5a688013ef2..7be1e1b4c31 100644 --- a/apps/cms/package.json +++ b/apps/cms/package.json @@ -17,14 +17,14 @@ "payload": "cross-env NODE_OPTIONS=--no-deprecation payload", "start": "cross-env NODE_OPTIONS=--no-deprecation next start", "vercel-build": "pnpm migrate && pnpm build", - "typecheck_IGNORED": "tsc --noEmit" + "typecheck": "tsc --noEmit" }, "dependencies": { "@payloadcms/admin-bar": "^3.52.0", "@payloadcms/db-postgres": "^3.52.0", "@payloadcms/live-preview-react": "^3.52.0", "@payloadcms/next": "3.52.0", - "@payloadcms/payload-cloud": "3.52.0", + "@payloadcms/payload-cloud": "3.60.0", "@payloadcms/plugin-form-builder": "3.52.0", "@payloadcms/plugin-nested-docs": "3.52.0", "@payloadcms/plugin-seo": "3.52.0", diff --git a/apps/cms/src/blocks/Banner/Component.tsx b/apps/cms/src/blocks/Banner/Component.tsx index 6abb8ad09a6..c395d687801 100644 --- a/apps/cms/src/blocks/Banner/Component.tsx +++ b/apps/cms/src/blocks/Banner/Component.tsx @@ -1,4 +1,4 @@ -import type { BannerBlock as BannerBlockProps } from 'src/payload-types' +import type { BannerBlock as BannerBlockProps } from '@/payload-types' import { cn } from '@/utilities/ui' import React from 'react' diff --git a/apps/cms/src/blocks/Quote/Component.tsx b/apps/cms/src/blocks/Quote/Component.tsx index 90717fa1e6d..1689a82a535 100644 --- a/apps/cms/src/blocks/Quote/Component.tsx +++ b/apps/cms/src/blocks/Quote/Component.tsx @@ -1,4 +1,4 @@ -import type { QuoteBlock as QuoteBlockProps } from 'src/payload-types' +import type { QuoteBlock as QuoteBlockProps } from '@/payload-types' import React from 'react' diff --git a/apps/cms/src/blocks/YouTube/Component.tsx b/apps/cms/src/blocks/YouTube/Component.tsx index 0704f2f7757..2d903a2a6ca 100644 --- a/apps/cms/src/blocks/YouTube/Component.tsx +++ b/apps/cms/src/blocks/YouTube/Component.tsx @@ -1,4 +1,4 @@ -import type { YouTubeBlock as YouTubeBlockProps } from 'src/payload-types' +import type { YouTubeBlock as YouTubeBlockProps } from '@/payload-types' import { cn } from '@/utilities/ui' import React from 'react' diff --git a/apps/cms/src/utilities/getDocument.ts b/apps/cms/src/utilities/getDocument.ts index 31e79ed4ead..f63a9c8db66 100644 --- a/apps/cms/src/utilities/getDocument.ts +++ b/apps/cms/src/utilities/getDocument.ts @@ -1,4 +1,4 @@ -import type { Config } from 'src/payload-types' +import type { Config } from '@/payload-types' import configPromise from '@payload-config' import { getPayload } from 'payload' diff --git a/apps/cms/src/utilities/getGlobals.ts b/apps/cms/src/utilities/getGlobals.ts index 39d6830b195..aaae4c15f0b 100644 --- a/apps/cms/src/utilities/getGlobals.ts +++ b/apps/cms/src/utilities/getGlobals.ts @@ -1,4 +1,4 @@ -import type { Config } from 'src/payload-types' +import type { Config } from '@/payload-types' import configPromise from '@payload-config' import { getPayload } from 'payload' diff --git a/apps/cms/tsconfig.json b/apps/cms/tsconfig.json index 5a66dbfae8e..b9a9542387c 100644 --- a/apps/cms/tsconfig.json +++ b/apps/cms/tsconfig.json @@ -3,7 +3,6 @@ "strict": true, "noUncheckedIndexedAccess": true, "noImplicitOverride": true, - "baseUrl": ".", "esModuleInterop": true, "target": "ES2022", "lib": ["DOM", "DOM.Iterable", "ES2022"], diff --git a/apps/design-system/README.md b/apps/design-system/README.md index f7d0347f0b5..06296fb3f4b 100644 --- a/apps/design-system/README.md +++ b/apps/design-system/README.md @@ -60,9 +60,9 @@ With that out of the way, there are several parts of this design system that nee - `config/docs.ts`: list of components in the sidebar - `content/docs`: the actual component documentation - `registry/examples.ts`: list of example components -- `registry/default/example`: the actual example components -- `registry/charts.ts`: chart components -- `registry/fragments.ts`: fragment components +- `registry/fragments.ts`: list of fragment components +- `registry/charts.ts`: list of chart components +- `registry/default/example/*`: the actual example components You will probably need to rebuild the design system’s registry after making new additions. You can do that via: diff --git a/apps/design-system/__registry__/default/block/chart-area-axes.tsx b/apps/design-system/__registry__/default/block/chart-area-axes.tsx deleted file mode 100644 index 26713267cbd..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-axes.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An area chart with axes' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Axes - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-default.tsx b/apps/design-system/__registry__/default/block/chart-area-default.tsx deleted file mode 100644 index 0ccfe016d7c..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-default.tsx +++ /dev/null @@ -1,77 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A simple area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-gradient.tsx b/apps/design-system/__registry__/default/block/chart-area-gradient.tsx deleted file mode 100644 index d6e7ad9b621..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-gradient.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An area chart with gradient fill' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Gradient - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - - - - - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-icons.tsx b/apps/design-system/__registry__/default/block/chart-area-icons.tsx deleted file mode 100644 index bc9d0195253..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-icons.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingDown, TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'An area chart with icons' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: TrendingDown, - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - icon: TrendingUp, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Icons - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - } /> - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-interactive.tsx b/apps/design-system/__registry__/default/block/chart-area-interactive.tsx deleted file mode 100644 index df2579fe8f8..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-interactive.tsx +++ /dev/null @@ -1,238 +0,0 @@ -'use client' - -import * as React from 'react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' -import { - Select_Shadcn_, - SelectContent_Shadcn_, - SelectItem_Shadcn_, - SelectTrigger_Shadcn_, - SelectValue_Shadcn_, -} from 'ui' - -export const description = 'An interactive area chart' - -const chartData = [ - { date: '2024-04-01', desktop: 222, mobile: 150 }, - { date: '2024-04-02', desktop: 97, mobile: 180 }, - { date: '2024-04-03', desktop: 167, mobile: 120 }, - { date: '2024-04-04', desktop: 242, mobile: 260 }, - { date: '2024-04-05', desktop: 373, mobile: 290 }, - { date: '2024-04-06', desktop: 301, mobile: 340 }, - { date: '2024-04-07', desktop: 245, mobile: 180 }, - { date: '2024-04-08', desktop: 409, mobile: 320 }, - { date: '2024-04-09', desktop: 59, mobile: 110 }, - { date: '2024-04-10', desktop: 261, mobile: 190 }, - { date: '2024-04-11', desktop: 327, mobile: 350 }, - { date: '2024-04-12', desktop: 292, mobile: 210 }, - { date: '2024-04-13', desktop: 342, mobile: 380 }, - { date: '2024-04-14', desktop: 137, mobile: 220 }, - { date: '2024-04-15', desktop: 120, mobile: 170 }, - { date: '2024-04-16', desktop: 138, mobile: 190 }, - { date: '2024-04-17', desktop: 446, mobile: 360 }, - { date: '2024-04-18', desktop: 364, mobile: 410 }, - { date: '2024-04-19', desktop: 243, mobile: 180 }, - { date: '2024-04-20', desktop: 89, mobile: 150 }, - { date: '2024-04-21', desktop: 137, mobile: 200 }, - { date: '2024-04-22', desktop: 224, mobile: 170 }, - { date: '2024-04-23', desktop: 138, mobile: 230 }, - { date: '2024-04-24', desktop: 387, mobile: 290 }, - { date: '2024-04-25', desktop: 215, mobile: 250 }, - { date: '2024-04-26', desktop: 75, mobile: 130 }, - { date: '2024-04-27', desktop: 383, mobile: 420 }, - { date: '2024-04-28', desktop: 122, mobile: 180 }, - { date: '2024-04-29', desktop: 315, mobile: 240 }, - { date: '2024-04-30', desktop: 454, mobile: 380 }, - { date: '2024-05-01', desktop: 165, mobile: 220 }, - { date: '2024-05-02', desktop: 293, mobile: 310 }, - { date: '2024-05-03', desktop: 247, mobile: 190 }, - { date: '2024-05-04', desktop: 385, mobile: 420 }, - { date: '2024-05-05', desktop: 481, mobile: 390 }, - { date: '2024-05-06', desktop: 498, mobile: 520 }, - { date: '2024-05-07', desktop: 388, mobile: 300 }, - { date: '2024-05-08', desktop: 149, mobile: 210 }, - { date: '2024-05-09', desktop: 227, mobile: 180 }, - { date: '2024-05-10', desktop: 293, mobile: 330 }, - { date: '2024-05-11', desktop: 335, mobile: 270 }, - { date: '2024-05-12', desktop: 197, mobile: 240 }, - { date: '2024-05-13', desktop: 197, mobile: 160 }, - { date: '2024-05-14', desktop: 448, mobile: 490 }, - { date: '2024-05-15', desktop: 473, mobile: 380 }, - { date: '2024-05-16', desktop: 338, mobile: 400 }, - { date: '2024-05-17', desktop: 499, mobile: 420 }, - { date: '2024-05-18', desktop: 315, mobile: 350 }, - { date: '2024-05-19', desktop: 235, mobile: 180 }, - { date: '2024-05-20', desktop: 177, mobile: 230 }, - { date: '2024-05-21', desktop: 82, mobile: 140 }, - { date: '2024-05-22', desktop: 81, mobile: 120 }, - { date: '2024-05-23', desktop: 252, mobile: 290 }, - { date: '2024-05-24', desktop: 294, mobile: 220 }, - { date: '2024-05-25', desktop: 201, mobile: 250 }, - { date: '2024-05-26', desktop: 213, mobile: 170 }, - { date: '2024-05-27', desktop: 420, mobile: 460 }, - { date: '2024-05-28', desktop: 233, mobile: 190 }, - { date: '2024-05-29', desktop: 78, mobile: 130 }, - { date: '2024-05-30', desktop: 340, mobile: 280 }, - { date: '2024-05-31', desktop: 178, mobile: 230 }, - { date: '2024-06-01', desktop: 178, mobile: 200 }, - { date: '2024-06-02', desktop: 470, mobile: 410 }, - { date: '2024-06-03', desktop: 103, mobile: 160 }, - { date: '2024-06-04', desktop: 439, mobile: 380 }, - { date: '2024-06-05', desktop: 88, mobile: 140 }, - { date: '2024-06-06', desktop: 294, mobile: 250 }, - { date: '2024-06-07', desktop: 323, mobile: 370 }, - { date: '2024-06-08', desktop: 385, mobile: 320 }, - { date: '2024-06-09', desktop: 438, mobile: 480 }, - { date: '2024-06-10', desktop: 155, mobile: 200 }, - { date: '2024-06-11', desktop: 92, mobile: 150 }, - { date: '2024-06-12', desktop: 492, mobile: 420 }, - { date: '2024-06-13', desktop: 81, mobile: 130 }, - { date: '2024-06-14', desktop: 426, mobile: 380 }, - { date: '2024-06-15', desktop: 307, mobile: 350 }, - { date: '2024-06-16', desktop: 371, mobile: 310 }, - { date: '2024-06-17', desktop: 475, mobile: 520 }, - { date: '2024-06-18', desktop: 107, mobile: 170 }, - { date: '2024-06-19', desktop: 341, mobile: 290 }, - { date: '2024-06-20', desktop: 408, mobile: 450 }, - { date: '2024-06-21', desktop: 169, mobile: 210 }, - { date: '2024-06-22', desktop: 317, mobile: 270 }, - { date: '2024-06-23', desktop: 480, mobile: 530 }, - { date: '2024-06-24', desktop: 132, mobile: 180 }, - { date: '2024-06-25', desktop: 141, mobile: 190 }, - { date: '2024-06-26', desktop: 434, mobile: 380 }, - { date: '2024-06-27', desktop: 448, mobile: 490 }, - { date: '2024-06-28', desktop: 149, mobile: 200 }, - { date: '2024-06-29', desktop: 103, mobile: 160 }, - { date: '2024-06-30', desktop: 446, mobile: 400 }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const [timeRange, setTimeRange] = React.useState('90d') - - const filteredData = chartData.filter((item) => { - const date = new Date(item.date) - const now = new Date() - let daysToSubtract = 90 - if (timeRange === '30d') { - daysToSubtract = 30 - } else if (timeRange === '7d') { - daysToSubtract = 7 - } - now.setDate(now.getDate() - daysToSubtract) - return date >= now - }) - - return ( - - -
- Area Chart - Interactive - Showing total visitors for the last 3 months -
- - - - - - - Last 3 months - - - Last 30 days - - - Last 7 days - - - -
- - - - - - - - - - - - - - - { - const date = new Date(value) - return date.toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - /> - { - return new Date(value).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - indicator="dot" - /> - } - /> - - - } /> - - - -
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-legend.tsx b/apps/design-system/__registry__/default/block/chart-area-legend.tsx deleted file mode 100644 index a58cfa9fbd9..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-legend.tsx +++ /dev/null @@ -1,98 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'An area chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Legend - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - } /> - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-linear.tsx b/apps/design-system/__registry__/default/block/chart-area-linear.tsx deleted file mode 100644 index 8381711c7aa..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-linear.tsx +++ /dev/null @@ -1,80 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A linear area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Linear - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } - /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-stacked-expand.tsx b/apps/design-system/__registry__/default/block/chart-area-stacked-expand.tsx deleted file mode 100644 index eca0b1118f7..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-stacked-expand.tsx +++ /dev/null @@ -1,104 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A stacked area chart with expand stacking' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80, other: 45 }, - { month: 'February', desktop: 305, mobile: 200, other: 100 }, - { month: 'March', desktop: 237, mobile: 120, other: 150 }, - { month: 'April', desktop: 73, mobile: 190, other: 50 }, - { month: 'May', desktop: 209, mobile: 130, other: 100 }, - { month: 'June', desktop: 214, mobile: 140, other: 160 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-3))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Stacked Expanded - Showing total visitors for the last 6months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-stacked.tsx b/apps/design-system/__registry__/default/block/chart-area-stacked.tsx deleted file mode 100644 index 22c0f58558b..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-stacked.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A stacked area chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Stacked - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-area-step.tsx b/apps/design-system/__registry__/default/block/chart-area-step.tsx deleted file mode 100644 index 5ac732aeaf4..00000000000 --- a/apps/design-system/__registry__/default/block/chart-area-step.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client' - -import { Activity, TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A step area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: Activity, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Step - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-active.tsx b/apps/design-system/__registry__/default/block/chart-bar-active.tsx deleted file mode 100644 index b1ab1d95e1a..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-active.tsx +++ /dev/null @@ -1,94 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with an active bar' - -const chartData = [ - { browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 275, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Active - January - June 2024 - - - - - - chartConfig[value as keyof typeof chartConfig]?.label} - /> - } /> - { - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-default.tsx b/apps/design-system/__registry__/default/block/chart-bar-default.tsx deleted file mode 100644 index 1c0596e3b57..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-default.tsx +++ /dev/null @@ -1,60 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-horizontal.tsx b/apps/design-system/__registry__/default/block/chart-bar-horizontal.tsx deleted file mode 100644 index 2305d0a4e1c..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-horizontal.tsx +++ /dev/null @@ -1,68 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A horizontal bar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Horizontal - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-label-custom.tsx b/apps/design-system/__registry__/default/block/chart-bar-label-custom.tsx deleted file mode 100644 index 7867342bc6d..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-label-custom.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with a custom label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, - label: { - color: 'hsl(var(--background))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Custom Label - January - June 2024 - - - - - - value.slice(0, 3)} - hide - /> - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-label.tsx b/apps/design-system/__registry__/default/block/chart-bar-label.tsx deleted file mode 100644 index 3bbdcc7a7ea..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-label.tsx +++ /dev/null @@ -1,68 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, LabelList, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with a label' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Label - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-mixed.tsx b/apps/design-system/__registry__/default/block/chart-bar-mixed.tsx deleted file mode 100644 index 1790507f73f..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-mixed.tsx +++ /dev/null @@ -1,86 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A mixed bar chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Mixed - January - June 2024 - - - - - chartConfig[value as keyof typeof chartConfig]?.label} - /> - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-multiple.tsx b/apps/design-system/__registry__/default/block/chart-bar-multiple.tsx deleted file mode 100644 index ffb9c61679a..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-multiple.tsx +++ /dev/null @@ -1,65 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A multiple bar chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Multiple - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-negative.tsx b/apps/design-system/__registry__/default/block/chart-bar-negative.tsx deleted file mode 100644 index 43f87ef0762..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-negative.tsx +++ /dev/null @@ -1,63 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, Cell, LabelList } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with negative values' - -const chartData = [ - { month: 'January', visitors: 186 }, - { month: 'February', visitors: 205 }, - { month: 'March', visitors: -207 }, - { month: 'April', visitors: 173 }, - { month: 'May', visitors: -209 }, - { month: 'June', visitors: 214 }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Negative - January - June 2024 - - - - - - } - /> - - - {chartData.map((item) => ( - 0 ? 'hsl(var(--chart-1))' : 'hsl(var(--chart-2))'} - /> - ))} - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-bar-stacked.tsx b/apps/design-system/__registry__/default/block/chart-bar-stacked.tsx deleted file mode 100644 index 34a7439e982..00000000000 --- a/apps/design-system/__registry__/default/block/chart-bar-stacked.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A stacked bar chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Stacked + Legend - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-composed-actions.tsx b/apps/design-system/__registry__/default/block/chart-composed-actions.tsx new file mode 100644 index 00000000000..f6eac7312b2 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-actions.tsx @@ -0,0 +1,106 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartLine, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink, LineChart } from 'lucide-react' +import { useState, useEffect } from 'react' + +export default function ChartComposedActions() { + const [isLoading, setIsLoading] = useState(true) + const [chartType, setChartType] = useState<'bar' | 'line'>('bar') + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Opening in Logs Explorer...') + }, + icon: , + }, + { + label: 'Toggle Chart Type', + onClick: () => { + setChartType(chartType === 'bar' ? 'line' : 'bar') + }, + icon: chartType === 'bar' ? : , + }, + ] + + const data = Array.from({ length: 46 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + requests: Math.floor(Math.random() * 100), + } + }).reverse() + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Total Requests + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ {chartType === 'bar' ? ( + `${value}k`, + width: 80, + }} + isFullHeight={true} + /> + ) : ( + `${value}k`, + width: 80, + }} + isFullHeight={true} + /> + )} +
+
+
+
+
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-composed-basic.tsx b/apps/design-system/__registry__/default/block/chart-composed-basic.tsx new file mode 100644 index 00000000000..d9457c3d308 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-basic.tsx @@ -0,0 +1,142 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartLine, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' + +export default function ComposedChartBasic() { + const [isLoading, setIsLoading] = useState(true) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + const data = Array.from({ length: 40 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 3) // Each point 3 minutes apart + + const progress = i / 40 + const standard_score = Math.floor(55 + progress * 55 + (Math.random() - 0.5) * 12) + const performance = Math.floor(35 + progress * 35 + (Math.random() - 0.5) * 10) + const efficiency = Math.floor(25 + progress * 25 + (Math.random() - 0.5) * 12) + + return { + timestamp: date.toISOString(), + standard_score: Math.max(0, Math.min(100, standard_score)), + performance: Math.max(0, Math.min(100, performance)), + efficiency: Math.max(0, Math.min(100, efficiency)), + } + }).reverse() + + const chartConfig = { + standard_score: { + label: 'Standard Score', + color: 'hsl(var(--brand-default))', + }, + performance: { + label: 'Performance', + color: 'hsl(var(--chart-2))', + }, + efficiency: { + label: 'Efficiency', + color: 'hsl(var(--chart-5))', + }, + } + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Standard Bar Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+
+
+ + + + + Standard Line Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+
+
+
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-composed-demo.tsx b/apps/design-system/__registry__/default/block/chart-composed-demo.tsx new file mode 100644 index 00000000000..c734900d395 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-demo.tsx @@ -0,0 +1,73 @@ +'use client' + +import { + Chart, + ChartCard, + ChartContent, + ChartHeader, + ChartEmptyState, + ChartLoadingState, + ChartMetric, +} from 'ui-patterns/Chart' +import { BarChart2 } from 'lucide-react' +import { LogsBarChart } from 'ui-patterns/LogsBarChart' +import { useState, useEffect } from 'react' + +export default function ComposedChartDemo() { + const [isLoading, setIsLoading] = useState(true) + + const data = Array.from({ length: 60 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + ok_count: Math.floor(Math.random() * 100), // Random value 0-99 + error_count: Math.floor(Math.random() * 50), // Random value 0-50 + warning_count: Math.floor(Math.random() * 50), // Random value 0-50 + } + }).reverse() + + const totalUsersValue = 4663 + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + +
+ + +
+
+ } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ +
+
+
+
+
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx b/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx new file mode 100644 index 00000000000..0c876d7e589 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-metrics.tsx @@ -0,0 +1,100 @@ +'use client' + +import { + Chart, + ChartCard, + ChartHeader, + ChartActions, + ChartContent, + ChartMetric, + ChartSparkline, +} from 'ui-patterns/Chart' +import { ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' +import { Skeleton } from 'ui' + +export default function ChartComposedMetrics() { + const [data, setData] = useState>([]) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + useEffect(() => { + const now = new Date() + setData( + Array.from({ length: 12 }, (_, i) => ({ + value: Math.floor(4000 + i * 100 + (Math.random() * 2000 - 800)), + timestamp: new Date(now.getTime() - (11 - i) * 60 * 60 * 1000).toISOString(), + })) + ) + }, []) + + const averageValue = data.reduce((acc, curr) => acc + curr.value, 0) / data.length + + const diff = data[data.length - 1]?.value - data[0]?.value || 0 + const diffPercentage = (diff / averageValue) * 100 + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + } + > + + + + + + + + + + + } + > + + + + +
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-composed-states.tsx b/apps/design-system/__registry__/default/block/chart-composed-states.tsx new file mode 100644 index 00000000000..4e5aa5d8bd5 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-states.tsx @@ -0,0 +1,92 @@ +'use client' + +import { BarChart2, ExternalLink } from 'lucide-react' +import { + Chart, + ChartCard, + ChartHeader, + ChartTitle, + ChartActions, + ChartContent, + ChartEmptyState, + ChartLoadingState, + ChartDisabledState, +} from 'ui-patterns/Chart' +import { Badge } from 'ui' + +export default function ChartComposedStates() { + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + const disabledActions = [ + { + label: 'Upgrade to Pro', + href: '#', + }, + ] + + return ( +
+ + + + Response Errors + + + }>My chart here... + + + + + + + Response Errors + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > + My chart here... + + + + + + + + Response Errors + + + } + disabledState={ + Pro} + label="API Processing Time" + description="This chart is available on the Pro plan and above" + actions={disabledActions} + /> + } + > + My chart here... + + + +
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-composed-table.tsx b/apps/design-system/__registry__/default/block/chart-composed-table.tsx new file mode 100644 index 00000000000..303114447e9 --- /dev/null +++ b/apps/design-system/__registry__/default/block/chart-composed-table.tsx @@ -0,0 +1,106 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartFooter, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' +import { Table, TableHead, TableBody, TableRow, TableCell, TableHeader } from 'ui' +import { format } from 'date-fns' + +export default function ChartComposedTable() { + const [isLoading, setIsLoading] = useState(true) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Opening in Logs Explorer...') + }, + icon: , + }, + ] + + const data = Array.from({ length: 46 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + standard_score: Math.floor(Math.random() * 100), + } + }).reverse() + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Standard Bar Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+ + + + + Timestamp + Standard Score + + + + {data.slice(0, 3).map((item) => ( + + + {format(new Date(item.timestamp), 'MMM d, yyyy h:mm a')} + + {item.standard_score} + + ))} + +
+
+
+
+
+ ) +} diff --git a/apps/design-system/__registry__/default/block/chart-line-default.tsx b/apps/design-system/__registry__/default/block/chart-line-default.tsx deleted file mode 100644 index 408dc1d6f9f..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-default.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-dots-colors.tsx b/apps/design-system/__registry__/default/block/chart-line-dots-colors.tsx deleted file mode 100644 index c8a55a0c44b..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-dots-colors.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Dot, Line, LineChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with dots and colors' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - color: 'hsl(var(--chart-2))', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Dots Colors - January - June 2024 - - - - - - } - /> - { - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-dots-custom.tsx b/apps/design-system/__registry__/default/block/chart-line-dots-custom.tsx deleted file mode 100644 index 87c69309319..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-dots-custom.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { GitCommitVertical, TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with custom dots' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Custom Dots - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - { - const r = 24 - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-dots.tsx b/apps/design-system/__registry__/default/block/chart-line-dots.tsx deleted file mode 100644 index cc211f2c2b4..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-dots.tsx +++ /dev/null @@ -1,82 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with dots' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Dots - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-interactive.tsx b/apps/design-system/__registry__/default/block/chart-line-interactive.tsx deleted file mode 100644 index 5f9c92b9792..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-interactive.tsx +++ /dev/null @@ -1,208 +0,0 @@ -'use client' - -import * as React from 'react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An interactive line chart' - -const chartData = [ - { date: '2024-04-01', desktop: 222, mobile: 150 }, - { date: '2024-04-02', desktop: 97, mobile: 180 }, - { date: '2024-04-03', desktop: 167, mobile: 120 }, - { date: '2024-04-04', desktop: 242, mobile: 260 }, - { date: '2024-04-05', desktop: 373, mobile: 290 }, - { date: '2024-04-06', desktop: 301, mobile: 340 }, - { date: '2024-04-07', desktop: 245, mobile: 180 }, - { date: '2024-04-08', desktop: 409, mobile: 320 }, - { date: '2024-04-09', desktop: 59, mobile: 110 }, - { date: '2024-04-10', desktop: 261, mobile: 190 }, - { date: '2024-04-11', desktop: 327, mobile: 350 }, - { date: '2024-04-12', desktop: 292, mobile: 210 }, - { date: '2024-04-13', desktop: 342, mobile: 380 }, - { date: '2024-04-14', desktop: 137, mobile: 220 }, - { date: '2024-04-15', desktop: 120, mobile: 170 }, - { date: '2024-04-16', desktop: 138, mobile: 190 }, - { date: '2024-04-17', desktop: 446, mobile: 360 }, - { date: '2024-04-18', desktop: 364, mobile: 410 }, - { date: '2024-04-19', desktop: 243, mobile: 180 }, - { date: '2024-04-20', desktop: 89, mobile: 150 }, - { date: '2024-04-21', desktop: 137, mobile: 200 }, - { date: '2024-04-22', desktop: 224, mobile: 170 }, - { date: '2024-04-23', desktop: 138, mobile: 230 }, - { date: '2024-04-24', desktop: 387, mobile: 290 }, - { date: '2024-04-25', desktop: 215, mobile: 250 }, - { date: '2024-04-26', desktop: 75, mobile: 130 }, - { date: '2024-04-27', desktop: 383, mobile: 420 }, - { date: '2024-04-28', desktop: 122, mobile: 180 }, - { date: '2024-04-29', desktop: 315, mobile: 240 }, - { date: '2024-04-30', desktop: 454, mobile: 380 }, - { date: '2024-05-01', desktop: 165, mobile: 220 }, - { date: '2024-05-02', desktop: 293, mobile: 310 }, - { date: '2024-05-03', desktop: 247, mobile: 190 }, - { date: '2024-05-04', desktop: 385, mobile: 420 }, - { date: '2024-05-05', desktop: 481, mobile: 390 }, - { date: '2024-05-06', desktop: 498, mobile: 520 }, - { date: '2024-05-07', desktop: 388, mobile: 300 }, - { date: '2024-05-08', desktop: 149, mobile: 210 }, - { date: '2024-05-09', desktop: 227, mobile: 180 }, - { date: '2024-05-10', desktop: 293, mobile: 330 }, - { date: '2024-05-11', desktop: 335, mobile: 270 }, - { date: '2024-05-12', desktop: 197, mobile: 240 }, - { date: '2024-05-13', desktop: 197, mobile: 160 }, - { date: '2024-05-14', desktop: 448, mobile: 490 }, - { date: '2024-05-15', desktop: 473, mobile: 380 }, - { date: '2024-05-16', desktop: 338, mobile: 400 }, - { date: '2024-05-17', desktop: 499, mobile: 420 }, - { date: '2024-05-18', desktop: 315, mobile: 350 }, - { date: '2024-05-19', desktop: 235, mobile: 180 }, - { date: '2024-05-20', desktop: 177, mobile: 230 }, - { date: '2024-05-21', desktop: 82, mobile: 140 }, - { date: '2024-05-22', desktop: 81, mobile: 120 }, - { date: '2024-05-23', desktop: 252, mobile: 290 }, - { date: '2024-05-24', desktop: 294, mobile: 220 }, - { date: '2024-05-25', desktop: 201, mobile: 250 }, - { date: '2024-05-26', desktop: 213, mobile: 170 }, - { date: '2024-05-27', desktop: 420, mobile: 460 }, - { date: '2024-05-28', desktop: 233, mobile: 190 }, - { date: '2024-05-29', desktop: 78, mobile: 130 }, - { date: '2024-05-30', desktop: 340, mobile: 280 }, - { date: '2024-05-31', desktop: 178, mobile: 230 }, - { date: '2024-06-01', desktop: 178, mobile: 200 }, - { date: '2024-06-02', desktop: 470, mobile: 410 }, - { date: '2024-06-03', desktop: 103, mobile: 160 }, - { date: '2024-06-04', desktop: 439, mobile: 380 }, - { date: '2024-06-05', desktop: 88, mobile: 140 }, - { date: '2024-06-06', desktop: 294, mobile: 250 }, - { date: '2024-06-07', desktop: 323, mobile: 370 }, - { date: '2024-06-08', desktop: 385, mobile: 320 }, - { date: '2024-06-09', desktop: 438, mobile: 480 }, - { date: '2024-06-10', desktop: 155, mobile: 200 }, - { date: '2024-06-11', desktop: 92, mobile: 150 }, - { date: '2024-06-12', desktop: 492, mobile: 420 }, - { date: '2024-06-13', desktop: 81, mobile: 130 }, - { date: '2024-06-14', desktop: 426, mobile: 380 }, - { date: '2024-06-15', desktop: 307, mobile: 350 }, - { date: '2024-06-16', desktop: 371, mobile: 310 }, - { date: '2024-06-17', desktop: 475, mobile: 520 }, - { date: '2024-06-18', desktop: 107, mobile: 170 }, - { date: '2024-06-19', desktop: 341, mobile: 290 }, - { date: '2024-06-20', desktop: 408, mobile: 450 }, - { date: '2024-06-21', desktop: 169, mobile: 210 }, - { date: '2024-06-22', desktop: 317, mobile: 270 }, - { date: '2024-06-23', desktop: 480, mobile: 530 }, - { date: '2024-06-24', desktop: 132, mobile: 180 }, - { date: '2024-06-25', desktop: 141, mobile: 190 }, - { date: '2024-06-26', desktop: 434, mobile: 380 }, - { date: '2024-06-27', desktop: 448, mobile: 490 }, - { date: '2024-06-28', desktop: 149, mobile: 200 }, - { date: '2024-06-29', desktop: 103, mobile: 160 }, - { date: '2024-06-30', desktop: 446, mobile: 400 }, -] - -const chartConfig = { - views: { - label: 'Page Views', - }, - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const [activeChart, setActiveChart] = React.useState('desktop') - - const total = React.useMemo( - () => ({ - desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0), - mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0), - }), - [] - ) - - return ( - - -
- Line Chart - Interactive - Showing total visitors for the last 3 months -
-
- {['desktop', 'mobile'].map((key) => { - const chart = key as keyof typeof chartConfig - return ( - - ) - })} -
-
- - - - - { - const date = new Date(value) - return date.toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - /> - { - return new Date(value).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }) - }} - /> - } - /> - - - - -
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-label-custom.tsx b/apps/design-system/__registry__/default/block/chart-line-label-custom.tsx deleted file mode 100644 index 3d84fec03a3..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-label-custom.tsx +++ /dev/null @@ -1,103 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, LabelList, Line, LineChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with a custom label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - color: 'hsl(var(--chart-2))', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Custom Label - January - June 2024 - - - - - - } - /> - - chartConfig[value]?.label} - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-label.tsx b/apps/design-system/__registry__/default/block/chart-line-label.tsx deleted file mode 100644 index 2c187e95961..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-label.tsx +++ /dev/null @@ -1,85 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, LabelList, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with a label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Label - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-linear.tsx b/apps/design-system/__registry__/default/block/chart-line-linear.tsx deleted file mode 100644 index 9219a3c9de4..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-linear.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A linear line chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Linear - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-multiple.tsx b/apps/design-system/__registry__/default/block/chart-line-multiple.tsx deleted file mode 100644 index f09714a2737..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-multiple.tsx +++ /dev/null @@ -1,88 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A multiple line chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Multiple - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-line-step.tsx b/apps/design-system/__registry__/default/block/chart-line-step.tsx deleted file mode 100644 index 0ab71e07d09..00000000000 --- a/apps/design-system/__registry__/default/block/chart-line-step.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with step' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Step - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-donut-active.tsx b/apps/design-system/__registry__/default/block/chart-pie-donut-active.tsx deleted file mode 100644 index 2490b50f65f..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-donut-active.tsx +++ /dev/null @@ -1,81 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart, Sector } from 'recharts' -import { PieSectorDataItem } from 'recharts/types/polar/Pie' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart with an active sector' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Donut Active - January - June 2024 - - - - - } /> - ( - - )} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-donut-text.tsx b/apps/design-system/__registry__/default/block/chart-pie-donut-text.tsx deleted file mode 100644 index cba1eee8492..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-donut-text.tsx +++ /dev/null @@ -1,111 +0,0 @@ -'use client' - -import * as React from 'react' -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart with text' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 287, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 190, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - const totalVisitors = React.useMemo(() => { - return chartData.reduce((acc, curr) => acc + curr.visitors, 0) - }, []) - - return ( - - - Pie Chart - Donut with Text - January - June 2024 - - - - - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-donut.tsx b/apps/design-system/__registry__/default/block/chart-pie-donut.tsx deleted file mode 100644 index 328fbd4b48a..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-donut.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Donut - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-interactive.tsx b/apps/design-system/__registry__/default/block/chart-pie-interactive.tsx deleted file mode 100644 index be05cbf8e41..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-interactive.tsx +++ /dev/null @@ -1,170 +0,0 @@ -'use client' - -import * as React from 'react' -import { Label, Pie, PieChart, Sector } from 'recharts' -import { PieSectorDataItem } from 'recharts/types/polar/Pie' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartStyle, ChartTooltip, ChartTooltipContent } from 'ui' -import { - Select_Shadcn_, - SelectContent_Shadcn_, - SelectItem_Shadcn_, - SelectTrigger_Shadcn_, - SelectValue_Shadcn_, -} from 'ui' - -export const description = 'An interactive pie chart' - -const desktopData = [ - { month: 'january', desktop: 186, fill: 'var(--color-january)' }, - { month: 'february', desktop: 305, fill: 'var(--color-february)' }, - { month: 'march', desktop: 237, fill: 'var(--color-march)' }, - { month: 'april', desktop: 173, fill: 'var(--color-april)' }, - { month: 'may', desktop: 209, fill: 'var(--color-may)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - }, - mobile: { - label: 'Mobile', - }, - january: { - label: 'January', - color: 'hsl(var(--chart-1))', - }, - february: { - label: 'February', - color: 'hsl(var(--chart-2))', - }, - march: { - label: 'March', - color: 'hsl(var(--chart-3))', - }, - april: { - label: 'April', - color: 'hsl(var(--chart-4))', - }, - may: { - label: 'May', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - const id = 'pie-interactive' - const [activeMonth, setActiveMonth] = React.useState(desktopData[0].month) - - const activeIndex = React.useMemo( - () => desktopData.findIndex((item) => item.month === activeMonth), - [activeMonth] - ) - const months = React.useMemo(() => desktopData.map((item) => item.month), []) - - return ( - - - -
- Pie Chart - Interactive - January - June 2024 -
- - - - - - {months.map((key) => { - const config = chartConfig[key as keyof typeof chartConfig] - - if (!config) { - return null - } - - return ( - -
- - {config?.label} -
-
- ) - })} -
-
-
- - - - } /> - ( - - - - - )} - > - - - - -
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-label-custom.tsx b/apps/design-system/__registry__/default/block/chart-pie-label-custom.tsx deleted file mode 100644 index 5fcae35aabe..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-label-custom.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a custom label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Custom Label - January - June 2024 - - - - - } /> - { - return ( - - {`${ - chartConfig[payload.browser as keyof typeof chartConfig]?.label - } (${payload.visitors})`} - - ) - }} - nameKey="browser" - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-label-list.tsx b/apps/design-system/__registry__/default/block/chart-pie-label-list.tsx deleted file mode 100644 index 814371c307e..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-label-list.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { LabelList, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a label list' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Label List - January - June 2024 - - - - - } /> - - chartConfig[value]?.label} - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-label.tsx b/apps/design-system/__registry__/default/block/chart-pie-label.tsx deleted file mode 100644 index 408bd68fb95..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-label.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Label - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-legend.tsx b/apps/design-system/__registry__/default/block/chart-pie-legend.tsx deleted file mode 100644 index c72830caf17..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-legend.tsx +++ /dev/null @@ -1,64 +0,0 @@ -'use client' - -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartLegend, ChartLegendContent } from 'ui' - -export const description = 'A pie chart with a legend' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Legend - January - June 2024 - - - - - - } - className="-translate-y-2 flex-wrap gap-2 [&>*]:basis-1/4 [&>*]:justify-center" - /> - - - - - ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-separator-none.tsx b/apps/design-system/__registry__/default/block/chart-pie-separator-none.tsx deleted file mode 100644 index ed00866c3b8..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-separator-none.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with no separator' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Separator None - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-simple.tsx b/apps/design-system/__registry__/default/block/chart-pie-simple.tsx deleted file mode 100644 index a16fb87ca56..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-simple.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A simple pie chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-pie-stacked.tsx b/apps/design-system/__registry__/default/block/chart-pie-stacked.tsx deleted file mode 100644 index a2ab16ba711..00000000000 --- a/apps/design-system/__registry__/default/block/chart-pie-stacked.tsx +++ /dev/null @@ -1,97 +0,0 @@ -'use client' - -import * as React from 'react' -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with stacked sections' - -const desktopData = [ - { month: 'january', desktop: 186, fill: 'var(--color-january)' }, - { month: 'february', desktop: 305, fill: 'var(--color-february)' }, - { month: 'march', desktop: 237, fill: 'var(--color-march)' }, - { month: 'april', desktop: 173, fill: 'var(--color-april)' }, - { month: 'may', desktop: 209, fill: 'var(--color-may)' }, -] - -const mobileData = [ - { month: 'january', mobile: 80, fill: 'var(--color-january)' }, - { month: 'february', mobile: 200, fill: 'var(--color-february)' }, - { month: 'march', mobile: 120, fill: 'var(--color-march)' }, - { month: 'april', mobile: 190, fill: 'var(--color-april)' }, - { month: 'may', mobile: 130, fill: 'var(--color-may)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - }, - mobile: { - label: 'Mobile', - }, - january: { - label: 'January', - color: 'hsl(var(--chart-1))', - }, - february: { - label: 'February', - color: 'hsl(var(--chart-2))', - }, - march: { - label: 'March', - color: 'hsl(var(--chart-3))', - }, - april: { - label: 'April', - color: 'hsl(var(--chart-4))', - }, - may: { - label: 'May', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Stacked - January - June 2024 - - - - - { - return chartConfig[payload?.[0].dataKey as keyof typeof chartConfig].label - }} - /> - } - /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-default.tsx b/apps/design-system/__registry__/default/block/chart-radar-default.tsx deleted file mode 100644 index dc3d4e6d553..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-default.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-dots.tsx b/apps/design-system/__registry__/default/block/chart-radar-dots.tsx deleted file mode 100644 index bedf14de29b..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-dots.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with dots' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Dots - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-circle-fill.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-circle-fill.tsx deleted file mode 100644 index d17d1536225..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-circle-fill.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle fill' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 285 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 264 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle Filled - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-circle-no-lines.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-circle-no-lines.tsx deleted file mode 100644 index 3e602ac5745..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-circle-no-lines.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle fill' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle - No lines - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-circle.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-circle.tsx deleted file mode 100644 index 0cc0277a0c4..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-circle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-custom.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-custom.tsx deleted file mode 100644 index 31614acc9a3..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-custom.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a custom grid' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Custom - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-fill.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-fill.tsx deleted file mode 100644 index 7745a10fb13..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-fill.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid filled' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 285 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 264 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Filled - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-grid-none.tsx b/apps/design-system/__registry__/default/block/chart-radar-grid-none.tsx deleted file mode 100644 index a75ac15da18..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-grid-none.tsx +++ /dev/null @@ -1,61 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with no grid' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid None - Showing total visitors for the last 6 months - - - - - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-icons.tsx b/apps/design-system/__registry__/default/block/chart-radar-icons.tsx deleted file mode 100644 index b2a83ad3934..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-icons.tsx +++ /dev/null @@ -1,75 +0,0 @@ -'use client' - -import { ArrowDownFromLine, ArrowUpFromLine, TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A radar chart with icons' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: ArrowDownFromLine, - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - icon: ArrowUpFromLine, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Icons - Showing total visitors for the last 6 months - - - - - } /> - - - - - } /> - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-label-custom.tsx b/apps/design-system/__registry__/default/block/chart-radar-label-custom.tsx deleted file mode 100644 index 51edad28517..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-label-custom.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a custom label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Custom Label - Showing total visitors for the last 6 months - - - - - } /> - { - const data = chartData[index] - - return ( - - {data.desktop} - / - {data.mobile} - - {data.month} - - - ) - }} - /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-legend.tsx b/apps/design-system/__registry__/default/block/chart-radar-legend.tsx deleted file mode 100644 index 1500cc422a3..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-legend.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A radar chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Legend - Showing total visitors for the last 6 months - - - - - } /> - - - - - } /> - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-lines-only.tsx b/apps/design-system/__registry__/default/block/chart-radar-lines-only.tsx deleted file mode 100644 index acb880c81c3..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-lines-only.tsx +++ /dev/null @@ -1,71 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with lines only' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 160 }, - { month: 'February', desktop: 185, mobile: 170 }, - { month: 'March', desktop: 207, mobile: 180 }, - { month: 'April', desktop: 173, mobile: 160 }, - { month: 'May', desktop: 160, mobile: 190 }, - { month: 'June', desktop: 174, mobile: 204 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Lines Only - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-multiple.tsx b/apps/design-system/__registry__/default/block/chart-radar-multiple.tsx deleted file mode 100644 index 5cc44043950..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-multiple.tsx +++ /dev/null @@ -1,59 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with multiple data' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Multiple - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radar-radius.tsx b/apps/design-system/__registry__/default/block/chart-radar-radius.tsx deleted file mode 100644 index f6616c4ac00..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radar-radius.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a radius axis' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Radius Axis - Showing total visitors for the last 6 months - - - - - } - /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-grid.tsx b/apps/design-system/__registry__/default/block/chart-radial-grid.tsx deleted file mode 100644 index fea6deab0c2..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-grid.tsx +++ /dev/null @@ -1,74 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarGrid, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with a grid' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Grid - January - June 2024 - - - - - } - /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-label.tsx b/apps/design-system/__registry__/default/block/chart-radial-label.tsx deleted file mode 100644 index 073e8b4ed47..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-label.tsx +++ /dev/null @@ -1,86 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { LabelList, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with a label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Label - January - June 2024 - - - - - } - /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-shape.tsx b/apps/design-system/__registry__/default/block/chart-radial-shape.tsx deleted file mode 100644 index 120a2df88d4..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-shape.tsx +++ /dev/null @@ -1,85 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer } from 'ui' - -export const description = 'A radial chart with a custom shape' - -const chartData = [{ browser: 'safari', visitors: 1260, fill: 'var(--color-safari)' }] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Shape - January - June 2024 - - - - - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-simple.tsx b/apps/design-system/__registry__/default/block/chart-radial-simple.tsx deleted file mode 100644 index 6c7590b2573..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-simple.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - January - June 2024 - - - - - } - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-stacked.tsx b/apps/design-system/__registry__/default/block/chart-radial-stacked.tsx deleted file mode 100644 index e38791f9bae..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-stacked.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with stacked sections' - -const chartData = [{ month: 'january', desktop: 1260, mobile: 570 }] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const totalVisitors = chartData[0].desktop + chartData[0].mobile - - return ( - - - Radial Chart - Stacked - January - June 2024 - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/default/block/chart-radial-text.tsx b/apps/design-system/__registry__/default/block/chart-radial-text.tsx deleted file mode 100644 index 8dd238c505b..00000000000 --- a/apps/design-system/__registry__/default/block/chart-radial-text.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer } from 'ui' - -export const description = 'A radial chart with text' - -const chartData = [{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Text - January - June 2024 - - - - - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/__registry__/index.tsx b/apps/design-system/__registry__/index.tsx index 553c807886f..fc94395ea85 100644 --- a/apps/design-system/__registry__/index.tsx +++ b/apps/design-system/__registry__/index.tsx @@ -16,6 +16,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "EmptyStatePresentational": { + name: "EmptyStatePresentational", + type: "components:fragment", + registryDependencies: undefined, + component: React.lazy(() => import("@/../../packages/ui-patterns/src/EmptyStatePresentational")), + source: "", + files: ["registry/default//EmptyStatePresentational/index.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "TextConfirmModal": { name: "TextConfirmModal", type: "components:fragment", @@ -27,17 +38,6 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "ConfirmDialog": { - name: "ConfirmDialog", - type: "components:fragment", - registryDependencies: undefined, - component: React.lazy(() => import("@/../../packages/ui-patterns/src/Dialogs/ConfirmDialog")), - source: "", - files: ["registry/default//Dialogs/ConfirmDialog.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, "PageContainer": { name: "PageContainer", type: "components:fragment", @@ -93,6 +93,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "admonition-button": { + name: "admonition-button", + type: "components:example", + registryDependencies: ["admonition"], + component: React.lazy(() => import("@/registry/default/example/admonition-button")), + source: "", + files: ["registry/default/example/admonition-button.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "admonition-warning": { name: "admonition-warning", type: "components:example", @@ -126,17 +137,6 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "alert-destructive": { - name: "alert-destructive", - type: "components:example", - registryDependencies: ["alert"], - component: React.lazy(() => import("@/registry/default/example/alert-destructive")), - source: "", - files: ["registry/default/example/alert-destructive.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, "alert-dialog-demo": { name: "alert-dialog-demo", type: "components:example", @@ -148,6 +148,39 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "alert-dialog-close-only": { + name: "alert-dialog-close-only", + type: "components:example", + registryDependencies: ["alert-dialog","button"], + component: React.lazy(() => import("@/registry/default/example/alert-dialog-close-only")), + source: "", + files: ["registry/default/example/alert-dialog-close-only.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "alert-dialog-destructive": { + name: "alert-dialog-destructive", + type: "components:example", + registryDependencies: ["alert-dialog","button"], + component: React.lazy(() => import("@/registry/default/example/alert-dialog-destructive")), + source: "", + files: ["registry/default/example/alert-dialog-destructive.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "alert-dialog-warning": { + name: "alert-dialog-warning", + type: "components:example", + registryDependencies: ["alert-dialog","button"], + component: React.lazy(() => import("@/registry/default/example/alert-dialog-warning")), + source: "", + files: ["registry/default/example/alert-dialog-warning.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "aspect-ratio-demo": { name: "aspect-ratio-demo", type: "components:example", @@ -181,24 +214,13 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "badge-destructive": { - name: "badge-destructive", + "badge-state": { + name: "badge-state", type: "components:example", registryDependencies: ["badge"], - component: React.lazy(() => import("@/registry/default/example/badge-destructive")), + component: React.lazy(() => import("@/registry/default/example/badge-state")), source: "", - files: ["registry/default/example/badge-destructive.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "badge-outline": { - name: "badge-outline", - type: "components:example", - registryDependencies: ["badge"], - component: React.lazy(() => import("@/registry/default/example/badge-outline")), - source: "", - files: ["registry/default/example/badge-outline.tsx"], + files: ["registry/default/example/badge-state.tsx"], category: "undefined", subcategory: "undefined", chunks: [] @@ -1248,6 +1270,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "sheet-nonmodal": { + name: "sheet-nonmodal", + type: "components:example", + registryDependencies: ["sheet"], + component: React.lazy(() => import("@/registry/default/example/sheet-nonmodal")), + source: "", + files: ["registry/default/example/sheet-nonmodal.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "sheet-side": { name: "sheet-side", type: "components:example", @@ -1292,6 +1325,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "slider-minMax-range": { + name: "slider-minMax-range", + type: "components:example", + registryDependencies: ["slider"], + component: React.lazy(() => import("@/registry/default/example/slider-minMax-range")), + source: "", + files: ["registry/default/example/slider-minMax-range.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "sonner-demo": { name: "sonner-demo", type: "components:example", @@ -1347,6 +1391,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "table-cross-link": { + name: "table-cross-link", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-cross-link")), + source: "", + files: ["registry/default/example/table-cross-link.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "table-demo": { name: "table-demo", type: "components:example", @@ -1358,6 +1413,61 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "table-actions": { + name: "table-actions", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-actions")), + source: "", + files: ["registry/default/example/table-actions.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "table-icons": { + name: "table-icons", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-icons")), + source: "", + files: ["registry/default/example/table-icons.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "table-row-link": { + name: "table-row-link", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-row-link")), + source: "", + files: ["registry/default/example/table-row-link.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "table-row-link-actions": { + name: "table-row-link-actions", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-row-link-actions")), + source: "", + files: ["registry/default/example/table-row-link-actions.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "table-sort": { + name: "table-sort", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/table-sort")), + source: "", + files: ["registry/default/example/table-sort.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "tabs-demo": { name: "tabs-demo", type: "components:example", @@ -1754,39 +1864,6 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "text-confirm-dialog-with-info-alert": { - name: "text-confirm-dialog-with-info-alert", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/text-confirm-dialog-with-info-alert")), - source: "", - files: ["registry/default/example/text-confirm-dialog-with-info-alert.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "text-confirm-dialog-with-warning-alert": { - name: "text-confirm-dialog-with-warning-alert", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/text-confirm-dialog-with-warning-alert")), - source: "", - files: ["registry/default/example/text-confirm-dialog-with-warning-alert.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "text-confirm-dialog-with-destructive-alert": { - name: "text-confirm-dialog-with-destructive-alert", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/text-confirm-dialog-with-destructive-alert")), - source: "", - files: ["registry/default/example/text-confirm-dialog-with-destructive-alert.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, "text-confirm-dialog-with-size": { name: "text-confirm-dialog-with-size", type: "components:example", @@ -1831,6 +1908,160 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "field-choice-card": { + name: "field-choice-card", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-choice-card")), + source: "", + files: ["registry/default/example/field-choice-card.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-checkbox": { + name: "field-checkbox", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-checkbox")), + source: "", + files: ["registry/default/example/field-checkbox.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-demo": { + name: "field-demo", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-demo")), + source: "", + files: ["registry/default/example/field-demo.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-fieldset": { + name: "field-fieldset", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-fieldset")), + source: "", + files: ["registry/default/example/field-fieldset.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-input": { + name: "field-input", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-input")), + source: "", + files: ["registry/default/example/field-input.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-group": { + name: "field-group", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-group")), + source: "", + files: ["registry/default/example/field-group.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-radio": { + name: "field-radio", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-radio")), + source: "", + files: ["registry/default/example/field-radio.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-responsive": { + name: "field-responsive", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-responsive")), + source: "", + files: ["registry/default/example/field-responsive.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-select": { + name: "field-select", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-select")), + source: "", + files: ["registry/default/example/field-select.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-slider": { + name: "field-slider", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-slider")), + source: "", + files: ["registry/default/example/field-slider.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-switch": { + name: "field-switch", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-switch")), + source: "", + files: ["registry/default/example/field-switch.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "field-textarea": { + name: "field-textarea", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/field-textarea")), + source: "", + files: ["registry/default/example/field-textarea.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "form-patterns-pagelayout": { + name: "form-patterns-pagelayout", + type: "components:example", + registryDependencies: ["form","card","input","button","select","switch","checkbox","textarea","radio-group","calendar","popover","multi-select"], + component: React.lazy(() => import("@/registry/default/example/form-patterns-pagelayout")), + source: "", + files: ["registry/default/example/form-patterns-pagelayout.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "form-patterns-sidepanel": { + name: "form-patterns-sidepanel", + type: "components:example", + registryDependencies: ["form","sheet","input","button","select","switch","checkbox","textarea","radio-group","calendar","popover","multi-select"], + component: React.lazy(() => import("@/registry/default/example/form-patterns-sidepanel")), + source: "", + files: ["registry/default/example/form-patterns-sidepanel.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "form-item-layout-with-select": { name: "form-item-layout-with-select", type: "components:example", @@ -2007,6 +2238,17 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, + "page-section-title-only": { + name: "page-section-title-only", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/page-section-title-only")), + source: "", + files: ["registry/default/example/page-section-title-only.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, "page-section-with-aside": { name: "page-section-with-aside", type: "components:example", @@ -2238,46 +2480,13 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "modal-demo": { - name: "modal-demo", + "confirmation-modal-demo": { + name: "confirmation-modal-demo", type: "components:example", registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/modal-demo")), + component: React.lazy(() => import("@/registry/default/example/confirmation-modal-demo")), source: "", - files: ["registry/default/example/modal-demo.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "modal-aligned-footer": { - name: "modal-aligned-footer", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/modal-aligned-footer")), - source: "", - files: ["registry/default/example/modal-aligned-footer.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "modal-custom-footer": { - name: "modal-custom-footer", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/modal-custom-footer")), - source: "", - files: ["registry/default/example/modal-custom-footer.tsx"], - category: "undefined", - subcategory: "undefined", - chunks: [] - }, - "modal-hide-footer": { - name: "modal-hide-footer", - type: "components:example", - registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/modal-hide-footer")), - source: "", - files: ["registry/default/example/modal-hide-footer.tsx"], + files: ["registry/default/example/confirmation-modal-demo.tsx"], category: "undefined", subcategory: "undefined", chunks: [] @@ -2447,13 +2656,35 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "empty-state-initial-state-presentational": { - name: "empty-state-initial-state-presentational", + "empty-state-presentational-demo": { + name: "empty-state-presentational-demo", type: "components:example", registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/empty-state-initial-state-presentational")), + component: React.lazy(() => import("@/registry/default/example/empty-state-presentational-demo")), source: "", - files: ["registry/default/example/empty-state-initial-state-presentational.tsx"], + files: ["registry/default/example/empty-state-presentational-demo.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "empty-state-presentational-buttons": { + name: "empty-state-presentational-buttons", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/empty-state-presentational-buttons")), + source: "", + files: ["registry/default/example/empty-state-presentational-buttons.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "empty-state-presentational-icon": { + name: "empty-state-presentational-icon", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/empty-state-presentational-icon")), + source: "", + files: ["registry/default/example/empty-state-presentational-icon.tsx"], category: "undefined", subcategory: "undefined", chunks: [] @@ -2469,13 +2700,35 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "empty-state-zero-items-data-grid": { - name: "empty-state-zero-items-data-grid", + "data-grid-demo": { + name: "data-grid-demo", type: "components:example", registryDependencies: undefined, - component: React.lazy(() => import("@/registry/default/example/empty-state-zero-items-data-grid")), + component: React.lazy(() => import("@/registry/default/example/data-grid-demo")), source: "", - files: ["registry/default/example/empty-state-zero-items-data-grid.tsx"], + files: ["registry/default/example/data-grid-demo.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "data-grid-empty-state": { + name: "data-grid-empty-state", + type: "components:example", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/example/data-grid-empty-state")), + source: "", + files: ["registry/default/example/data-grid-empty-state.tsx"], + category: "undefined", + subcategory: "undefined", + chunks: [] + }, + "data-table-demo": { + name: "data-table-demo", + type: "components:example", + registryDependencies: ["table"], + component: React.lazy(() => import("@/registry/default/example/data-table-demo")), + source: "", + files: ["registry/default/example/data-table-demo.tsx"], category: "undefined", subcategory: "undefined", chunks: [] @@ -2524,147 +2777,114 @@ export const Index: Record = { subcategory: "undefined", chunks: [] }, - "chart-area-axes": { - name: "chart-area-axes", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-axes")), - source: "__registry__/default/block/chart-area-axes.tsx", - files: ["registry/default/block/chart-area-axes.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-demo": { + name: "mermaid-demo", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-demo")), + source: "", + files: ["registry/default/example/mermaid-demo.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-default": { - name: "chart-area-default", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-default")), - source: "__registry__/default/block/chart-area-default.tsx", - files: ["registry/default/block/chart-area-default.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-flowchart": { + name: "mermaid-flowchart", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-flowchart")), + source: "", + files: ["registry/default/example/mermaid-flowchart.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-gradient": { - name: "chart-area-gradient", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-gradient")), - source: "__registry__/default/block/chart-area-gradient.tsx", - files: ["registry/default/block/chart-area-gradient.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-er-diagram": { + name: "mermaid-er-diagram", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-er-diagram")), + source: "", + files: ["registry/default/example/mermaid-er-diagram.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-icons": { - name: "chart-area-icons", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-icons")), - source: "__registry__/default/block/chart-area-icons.tsx", - files: ["registry/default/block/chart-area-icons.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-sequence-async": { + name: "mermaid-sequence-async", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-async")), + source: "", + files: ["registry/default/example/mermaid-sequence-async.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-interactive": { - name: "chart-area-interactive", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-interactive")), - source: "__registry__/default/block/chart-area-interactive.tsx", - files: ["registry/default/block/chart-area-interactive.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-sequence-sync": { + name: "mermaid-sequence-sync", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-sync")), + source: "", + files: ["registry/default/example/mermaid-sequence-sync.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-legend": { - name: "chart-area-legend", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-legend")), - source: "__registry__/default/block/chart-area-legend.tsx", - files: ["registry/default/block/chart-area-legend.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-oauth-flow": { + name: "mermaid-oauth-flow", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-oauth-flow")), + source: "", + files: ["registry/default/example/mermaid-oauth-flow.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-linear": { - name: "chart-area-linear", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-linear")), - source: "__registry__/default/block/chart-area-linear.tsx", - files: ["registry/default/block/chart-area-linear.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-flowchart-subgraph": { + name: "mermaid-flowchart-subgraph", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-flowchart-subgraph")), + source: "", + files: ["registry/default/example/mermaid-flowchart-subgraph.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-stacked-expand": { - name: "chart-area-stacked-expand", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-stacked-expand")), - source: "__registry__/default/block/chart-area-stacked-expand.tsx", - files: ["registry/default/block/chart-area-stacked-expand.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-sequence-api": { + name: "mermaid-sequence-api", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-sequence-api")), + source: "", + files: ["registry/default/example/mermaid-sequence-api.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-stacked": { - name: "chart-area-stacked", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-stacked")), - source: "__registry__/default/block/chart-area-stacked.tsx", - files: ["registry/default/block/chart-area-stacked.tsx"], - category: "Charts", - subcategory: "Area", + "mermaid-er-simple": { + name: "mermaid-er-simple", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-er-simple")), + source: "", + files: ["registry/default/example/mermaid-er-simple.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, - "chart-area-step": { - name: "chart-area-step", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-area-step")), - source: "__registry__/default/block/chart-area-step.tsx", - files: ["registry/default/block/chart-area-step.tsx"], - category: "Charts", - subcategory: "Area", - chunks: [] - }, - "chart-bar-active": { - name: "chart-bar-active", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-active")), - source: "__registry__/default/block/chart-bar-active.tsx", - files: ["registry/default/block/chart-bar-active.tsx"], - category: "Charts", - subcategory: "Bar", - chunks: [] - }, - "chart-bar-default": { - name: "chart-bar-default", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-default")), - source: "__registry__/default/block/chart-bar-default.tsx", - files: ["registry/default/block/chart-bar-default.tsx"], - category: "Charts", - subcategory: "Bar", - chunks: [] - }, - "chart-bar-horizontal": { - name: "chart-bar-horizontal", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-horizontal")), - source: "__registry__/default/block/chart-bar-horizontal.tsx", - files: ["registry/default/block/chart-bar-horizontal.tsx"], - category: "Charts", - subcategory: "Bar", + "mermaid-basic": { + name: "mermaid-basic", + type: "components:example", + registryDependencies: ["mermaid"], + component: React.lazy(() => import("@/registry/default/example/mermaid-basic")), + source: "", + files: ["registry/default/example/mermaid-basic.tsx"], + category: "undefined", + subcategory: "undefined", chunks: [] }, "chart-bar-interactive": { @@ -2678,521 +2898,158 @@ export const Index: Record = { subcategory: "Bar", chunks: [] }, - "chart-bar-label-custom": { - name: "chart-bar-label-custom", + "chart-composed-demo": { + name: "chart-composed-demo", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-label-custom")), - source: "__registry__/default/block/chart-bar-label-custom.tsx", - files: ["registry/default/block/chart-bar-label-custom.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-demo")), + source: "__registry__/default/block/chart-composed-demo.tsx", + files: ["registry/default/block/chart-composed-demo.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-bar-label": { - name: "chart-bar-label", + "chart-composed-basic": { + name: "chart-composed-basic", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-label")), - source: "__registry__/default/block/chart-bar-label.tsx", - files: ["registry/default/block/chart-bar-label.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-basic")), + source: "__registry__/default/block/chart-composed-basic.tsx", + files: ["registry/default/block/chart-composed-basic.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-bar-mixed": { - name: "chart-bar-mixed", + "chart-composed-states": { + name: "chart-composed-states", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-mixed")), - source: "__registry__/default/block/chart-bar-mixed.tsx", - files: ["registry/default/block/chart-bar-mixed.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-states")), + source: "__registry__/default/block/chart-composed-states.tsx", + files: ["registry/default/block/chart-composed-states.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-bar-multiple": { - name: "chart-bar-multiple", + "chart-composed-table": { + name: "chart-composed-table", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-multiple")), - source: "__registry__/default/block/chart-bar-multiple.tsx", - files: ["registry/default/block/chart-bar-multiple.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-table")), + source: "__registry__/default/block/chart-composed-table.tsx", + files: ["registry/default/block/chart-composed-table.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-bar-negative": { - name: "chart-bar-negative", + "chart-composed-metrics": { + name: "chart-composed-metrics", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-negative")), - source: "__registry__/default/block/chart-bar-negative.tsx", - files: ["registry/default/block/chart-bar-negative.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-metrics")), + source: "__registry__/default/block/chart-composed-metrics.tsx", + files: ["registry/default/block/chart-composed-metrics.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-bar-stacked": { - name: "chart-bar-stacked", + "chart-composed-actions": { + name: "chart-composed-actions", type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-bar-stacked")), - source: "__registry__/default/block/chart-bar-stacked.tsx", - files: ["registry/default/block/chart-bar-stacked.tsx"], + registryDependencies: ["chart"], + component: React.lazy(() => import("@/registry/default/block/chart-composed-actions")), + source: "__registry__/default/block/chart-composed-actions.tsx", + files: ["registry/default/block/chart-composed-actions.tsx"], category: "Charts", - subcategory: "Bar", + subcategory: "Composed", chunks: [] }, - "chart-line-default": { - name: "chart-line-default", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-default")), - source: "__registry__/default/block/chart-line-default.tsx", - files: ["registry/default/block/chart-line-default.tsx"], - category: "Charts", - subcategory: "Line", + "copy-button-verbs": { + name: "copy-button-verbs", + type: "components:example", + registryDependencies: ["button"], + component: React.lazy(() => import("@/registry/default/example/copy-button-verbs")), + source: "", + files: ["registry/default/example/copy-button-verbs.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-dots-colors": { - name: "chart-line-dots-colors", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-dots-colors")), - source: "__registry__/default/block/chart-line-dots-colors.tsx", - files: ["registry/default/block/chart-line-dots-colors.tsx"], - category: "Charts", - subcategory: "Line", + "copy-form-labels": { + name: "copy-form-labels", + type: "components:example", + registryDependencies: ["form"], + component: React.lazy(() => import("@/registry/default/example/copy-form-labels")), + source: "", + files: ["registry/default/example/copy-form-labels.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-dots-custom": { - name: "chart-line-dots-custom", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-dots-custom")), - source: "__registry__/default/block/chart-line-dots-custom.tsx", - files: ["registry/default/block/chart-line-dots-custom.tsx"], - category: "Charts", - subcategory: "Line", + "copy-error-messages": { + name: "copy-error-messages", + type: "components:example", + registryDependencies: ["form"], + component: React.lazy(() => import("@/registry/default/example/copy-error-messages")), + source: "", + files: ["registry/default/example/copy-error-messages.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-dots": { - name: "chart-line-dots", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-dots")), - source: "__registry__/default/block/chart-line-dots.tsx", - files: ["registry/default/block/chart-line-dots.tsx"], - category: "Charts", - subcategory: "Line", + "copy-success-messages": { + name: "copy-success-messages", + type: "components:example", + registryDependencies: ["form"], + component: React.lazy(() => import("@/registry/default/example/copy-success-messages")), + source: "", + files: ["registry/default/example/copy-success-messages.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-interactive": { - name: "chart-line-interactive", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-interactive")), - source: "__registry__/default/block/chart-line-interactive.tsx", - files: ["registry/default/block/chart-line-interactive.tsx"], - category: "Charts", - subcategory: "Line", + "copy-tooltips": { + name: "copy-tooltips", + type: "components:example", + registryDependencies: ["tooltip"], + component: React.lazy(() => import("@/registry/default/example/copy-tooltips")), + source: "", + files: ["registry/default/example/copy-tooltips.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-label-custom": { - name: "chart-line-label-custom", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-label-custom")), - source: "__registry__/default/block/chart-line-label-custom.tsx", - files: ["registry/default/block/chart-line-label-custom.tsx"], - category: "Charts", - subcategory: "Line", + "copy-loading-states": { + name: "copy-loading-states", + type: "components:example", + registryDependencies: ["loading-state"], + component: React.lazy(() => import("@/registry/default/example/copy-loading-states")), + source: "", + files: ["registry/default/example/copy-loading-states.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-label": { - name: "chart-line-label", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-label")), - source: "__registry__/default/block/chart-line-label.tsx", - files: ["registry/default/block/chart-line-label.tsx"], - category: "Charts", - subcategory: "Line", + "copy-empty-states": { + name: "copy-empty-states", + type: "components:example", + registryDependencies: ["empty-state"], + component: React.lazy(() => import("@/registry/default/example/copy-empty-states")), + source: "", + files: ["registry/default/example/copy-empty-states.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, - "chart-line-linear": { - name: "chart-line-linear", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-linear")), - source: "__registry__/default/block/chart-line-linear.tsx", - files: ["registry/default/block/chart-line-linear.tsx"], - category: "Charts", - subcategory: "Line", - chunks: [] - }, - "chart-line-multiple": { - name: "chart-line-multiple", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-multiple")), - source: "__registry__/default/block/chart-line-multiple.tsx", - files: ["registry/default/block/chart-line-multiple.tsx"], - category: "Charts", - subcategory: "Line", - chunks: [] - }, - "chart-line-step": { - name: "chart-line-step", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-line-step")), - source: "__registry__/default/block/chart-line-step.tsx", - files: ["registry/default/block/chart-line-step.tsx"], - category: "Charts", - subcategory: "Line", - chunks: [] - }, - "chart-pie-donut-active": { - name: "chart-pie-donut-active", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-donut-active")), - source: "__registry__/default/block/chart-pie-donut-active.tsx", - files: ["registry/default/block/chart-pie-donut-active.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-donut-text": { - name: "chart-pie-donut-text", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-donut-text")), - source: "__registry__/default/block/chart-pie-donut-text.tsx", - files: ["registry/default/block/chart-pie-donut-text.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-donut": { - name: "chart-pie-donut", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-donut")), - source: "__registry__/default/block/chart-pie-donut.tsx", - files: ["registry/default/block/chart-pie-donut.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-interactive": { - name: "chart-pie-interactive", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-interactive")), - source: "__registry__/default/block/chart-pie-interactive.tsx", - files: ["registry/default/block/chart-pie-interactive.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-label-custom": { - name: "chart-pie-label-custom", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-label-custom")), - source: "__registry__/default/block/chart-pie-label-custom.tsx", - files: ["registry/default/block/chart-pie-label-custom.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-label-list": { - name: "chart-pie-label-list", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-label-list")), - source: "__registry__/default/block/chart-pie-label-list.tsx", - files: ["registry/default/block/chart-pie-label-list.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-label": { - name: "chart-pie-label", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-label")), - source: "__registry__/default/block/chart-pie-label.tsx", - files: ["registry/default/block/chart-pie-label.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-legend": { - name: "chart-pie-legend", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-legend")), - source: "__registry__/default/block/chart-pie-legend.tsx", - files: ["registry/default/block/chart-pie-legend.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-separator-none": { - name: "chart-pie-separator-none", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-separator-none")), - source: "__registry__/default/block/chart-pie-separator-none.tsx", - files: ["registry/default/block/chart-pie-separator-none.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-simple": { - name: "chart-pie-simple", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-simple")), - source: "__registry__/default/block/chart-pie-simple.tsx", - files: ["registry/default/block/chart-pie-simple.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-pie-stacked": { - name: "chart-pie-stacked", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-pie-stacked")), - source: "__registry__/default/block/chart-pie-stacked.tsx", - files: ["registry/default/block/chart-pie-stacked.tsx"], - category: "Charts", - subcategory: "Pie", - chunks: [] - }, - "chart-radar-default": { - name: "chart-radar-default", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-default")), - source: "__registry__/default/block/chart-radar-default.tsx", - files: ["registry/default/block/chart-radar-default.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-dots": { - name: "chart-radar-dots", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-dots")), - source: "__registry__/default/block/chart-radar-dots.tsx", - files: ["registry/default/block/chart-radar-dots.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-circle-fill": { - name: "chart-radar-grid-circle-fill", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle-fill")), - source: "__registry__/default/block/chart-radar-grid-circle-fill.tsx", - files: ["registry/default/block/chart-radar-grid-circle-fill.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-circle-no-lines": { - name: "chart-radar-grid-circle-no-lines", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle-no-lines")), - source: "__registry__/default/block/chart-radar-grid-circle-no-lines.tsx", - files: ["registry/default/block/chart-radar-grid-circle-no-lines.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-circle": { - name: "chart-radar-grid-circle", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-circle")), - source: "__registry__/default/block/chart-radar-grid-circle.tsx", - files: ["registry/default/block/chart-radar-grid-circle.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-custom": { - name: "chart-radar-grid-custom", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-custom")), - source: "__registry__/default/block/chart-radar-grid-custom.tsx", - files: ["registry/default/block/chart-radar-grid-custom.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-fill": { - name: "chart-radar-grid-fill", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-fill")), - source: "__registry__/default/block/chart-radar-grid-fill.tsx", - files: ["registry/default/block/chart-radar-grid-fill.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-grid-none": { - name: "chart-radar-grid-none", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-grid-none")), - source: "__registry__/default/block/chart-radar-grid-none.tsx", - files: ["registry/default/block/chart-radar-grid-none.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-icons": { - name: "chart-radar-icons", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-icons")), - source: "__registry__/default/block/chart-radar-icons.tsx", - files: ["registry/default/block/chart-radar-icons.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-label-custom": { - name: "chart-radar-label-custom", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-label-custom")), - source: "__registry__/default/block/chart-radar-label-custom.tsx", - files: ["registry/default/block/chart-radar-label-custom.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-legend": { - name: "chart-radar-legend", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-legend")), - source: "__registry__/default/block/chart-radar-legend.tsx", - files: ["registry/default/block/chart-radar-legend.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-lines-only": { - name: "chart-radar-lines-only", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-lines-only")), - source: "__registry__/default/block/chart-radar-lines-only.tsx", - files: ["registry/default/block/chart-radar-lines-only.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-multiple": { - name: "chart-radar-multiple", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-multiple")), - source: "__registry__/default/block/chart-radar-multiple.tsx", - files: ["registry/default/block/chart-radar-multiple.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radar-radius": { - name: "chart-radar-radius", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radar-radius")), - source: "__registry__/default/block/chart-radar-radius.tsx", - files: ["registry/default/block/chart-radar-radius.tsx"], - category: "Charts", - subcategory: "Radar", - chunks: [] - }, - "chart-radial-grid": { - name: "chart-radial-grid", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-grid")), - source: "__registry__/default/block/chart-radial-grid.tsx", - files: ["registry/default/block/chart-radial-grid.tsx"], - category: "Charts", - subcategory: "Radial", - chunks: [] - }, - "chart-radial-label": { - name: "chart-radial-label", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-label")), - source: "__registry__/default/block/chart-radial-label.tsx", - files: ["registry/default/block/chart-radial-label.tsx"], - category: "Charts", - subcategory: "Radial", - chunks: [] - }, - "chart-radial-shape": { - name: "chart-radial-shape", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-shape")), - source: "__registry__/default/block/chart-radial-shape.tsx", - files: ["registry/default/block/chart-radial-shape.tsx"], - category: "Charts", - subcategory: "Radial", - chunks: [] - }, - "chart-radial-simple": { - name: "chart-radial-simple", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-simple")), - source: "__registry__/default/block/chart-radial-simple.tsx", - files: ["registry/default/block/chart-radial-simple.tsx"], - category: "Charts", - subcategory: "Radial", - chunks: [] - }, - "chart-radial-stacked": { - name: "chart-radial-stacked", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-stacked")), - source: "__registry__/default/block/chart-radial-stacked.tsx", - files: ["registry/default/block/chart-radial-stacked.tsx"], - category: "Charts", - subcategory: "Radial", - chunks: [] - }, - "chart-radial-text": { - name: "chart-radial-text", - type: "components:block", - registryDependencies: ["card","chart"], - component: React.lazy(() => import("@/registry/default/block/chart-radial-text")), - source: "__registry__/default/block/chart-radial-text.tsx", - files: ["registry/default/block/chart-radial-text.tsx"], - category: "Charts", - subcategory: "Radial", + "copy-confirmations": { + name: "copy-confirmations", + type: "components:example", + registryDependencies: ["confirmation"], + component: React.lazy(() => import("@/registry/default/example/copy-confirmations")), + source: "", + files: ["registry/default/example/copy-confirmations.tsx"], + category: "Getting Started", + subcategory: "Copywriting", chunks: [] }, }, diff --git a/apps/design-system/app/(app)/docs/[[...slug]]/page.tsx b/apps/design-system/app/(app)/docs/[[...slug]]/page.tsx index b6b883b9323..9454a245b8a 100644 --- a/apps/design-system/app/(app)/docs/[[...slug]]/page.tsx +++ b/apps/design-system/app/(app)/docs/[[...slug]]/page.tsx @@ -4,7 +4,7 @@ import { SourcePanel } from '@/components/source-panel' import { DashboardTableOfContents } from '@/components/toc' import { siteConfig } from '@/config/site' import { getTableOfContents } from '@/lib/toc' -import { absoluteUrl, cn } from '@/lib/utils' +import { absoluteUrl } from '@/lib/utils' import '@/styles/code-block-variables.css' import '@/styles/mdx.css' import { allDocs } from 'contentlayer/generated' @@ -83,15 +83,15 @@ export default async function DocPage(props: DocPageProps) { const toc = await getTableOfContents(doc.body.raw) return ( -
-
+
+
Docs
{doc.title}
-

{doc.title}

+

{doc.title}

{doc.description && (

{doc.description} @@ -107,15 +107,15 @@ export default async function DocPage(props: DocPageProps) {

{doc.toc && (
-
+
-
+
)} -
+ ) } diff --git a/apps/design-system/app/(app)/layout.tsx b/apps/design-system/app/(app)/layout.tsx index 49b81a77a8f..775f444ff4f 100644 --- a/apps/design-system/app/(app)/layout.tsx +++ b/apps/design-system/app/(app)/layout.tsx @@ -1,34 +1,28 @@ -import SideNavigation from '@/components/side-navigation' +import { SideNavigation } from '@/components/side-navigation' import { SiteFooter } from '@/components/site-footer' -// import ThemeSettings from '@/components/theme-settings' -import TopNavigation from '@/components/top-navigation' +import { TopNavigation } from '@/components/top-navigation' +import { MobileSidebarSheet } from '@/components/mobile-sidebar-sheet' import { ScrollArea } from 'ui' interface AppLayoutProps { children: React.ReactNode } -export default function AppLayout({ children }: AppLayoutProps) { +export default async function AppLayout({ children }: AppLayoutProps) { return ( <> - {/* main container */} -
- {/* main content */} -
- {/* {children} */} -
-
- - {children} -
-
-
-
+ +
+
+ + {children} +
+
) diff --git a/apps/design-system/app/(app)/page.tsx b/apps/design-system/app/(app)/page.tsx index 38bfce96e77..377ca6bdd09 100644 --- a/apps/design-system/app/(app)/page.tsx +++ b/apps/design-system/app/(app)/page.tsx @@ -1,114 +1,96 @@ import { HomepageSvgHandler } from '@/components/homepage-svg-handler' +import { Auth, Database, Realtime } from 'icons/src/icons' +import { Paintbrush } from 'lucide-react' import Link from 'next/link' export default function Home() { return ( -
-
-
- {/*
- -
*/} -
-

Supabase Design System

-

- Design resources for building consistent user experiences -

-
+
+
+
+

Supabase Design System

+

+ Design resources for building consistent user experiences +

- {/* Homepage items */} - -
- -
- -
-

Atom components

-

Building blocks of User interfaces

-
-
- - -
- -
-

Fragment components

-

Components assembled from Atoms

-
-
- - -
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
+
+ +
+
+

Colors

-

Building blocks of User interfaces

+

Custom color palette for Supabase

- -
- -
-

Theming

-

Components assembled from Atoms

+ +
+
+ + +
-
- - - -
-

Icons

-

Components assembled from Atoms

+

Custom icons for Supabase

+
+
+ + + +
+
+ +
+
+

Theming

+

Simple extensible theming system

+
+
+ + +
+
+ +
+
+

UI patterns

+

+ Design guidelines for common interface patterns +

+
+
+ + + +
+
+ +
+
+

Fragment components

+

Components assembled from atoms

+
+
+ + + +
+
+ +
+
+

Atom components

+

Building blocks of user interfaces

-
+ ) } diff --git a/apps/design-system/app/Providers.tsx b/apps/design-system/app/Providers.tsx index 87bac1f1e2f..d2ace2cd703 100644 --- a/apps/design-system/app/Providers.tsx +++ b/apps/design-system/app/Providers.tsx @@ -5,12 +5,15 @@ import { ThemeProvider as NextThemesProvider } from 'next-themes' import { ThemeProviderProps } from 'next-themes/dist/types' import { TooltipProvider } from 'ui' +import { MobileSidebarProvider } from '@/context/mobile-sidebar-context' export function ThemeProvider({ children, ...props }: ThemeProviderProps) { return ( - {children} + + {children} + ) diff --git a/apps/design-system/components/command-menu.tsx b/apps/design-system/components/command-menu.tsx index 1673e8f2ed0..5a2f558b385 100644 --- a/apps/design-system/components/command-menu.tsx +++ b/apps/design-system/components/command-menu.tsx @@ -1,6 +1,6 @@ 'use client' -import { CircleIcon, LaptopIcon, MoonIcon, SunIcon } from 'lucide-react' +import { CircleIcon, LaptopIcon, MoonIcon, SunIcon, Search } from 'lucide-react' import { useTheme } from 'next-themes' import { useRouter } from 'next/navigation' import * as React from 'react' @@ -17,6 +17,7 @@ import { CommandList_Shadcn_, CommandSeparator_Shadcn_, DialogProps, + DialogTitle, } from 'ui' export function CommandMenu({ ...props }: DialogProps) { @@ -55,8 +56,7 @@ export function CommandMenu({ ...props }: DialogProps) { + @@ -233,13 +227,64 @@ const SourcePanel = forwardRef & className="rounded-full" icon={} > - + API Reference + + + )} + + ) : null} + + + ) + } + } - // className={cn(badgeVariants({ variant: 'default' }), 'gap-1')} - > + const RechartsPanel = () => { + if (doc.source?.recharts) { + return ( +
+ + + + +
+ This component uses Recharts + {doc.links ? ( +
+ {doc.links?.doc && ( + + )} + {doc.links?.api && ( + @@ -258,6 +303,7 @@ const SourcePanel = forwardRef & + {/* */}
) diff --git a/apps/design-system/components/theme-switcher-dropdown.tsx b/apps/design-system/components/theme-switcher-dropdown.tsx index 4796194c07d..c2df0f267f1 100644 --- a/apps/design-system/components/theme-switcher-dropdown.tsx +++ b/apps/design-system/components/theme-switcher-dropdown.tsx @@ -3,7 +3,6 @@ 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,8 +12,6 @@ import { DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, - RadioGroupLargeItem_Shadcn_, - RadioGroup_Shadcn_, Theme, singleThemes, } from 'ui' @@ -36,22 +33,7 @@ const ThemeSwitcherDropdown = () => { return null } - function SingleThemeSelection() { - return ( - - - - ) - } - - const iconClasses = 'text-foreground-light group-data-[state=open]:text-foreground' + const iconClasses = 'text-foreground-lighter group-data-[state=open]:text-foreground' return ( <> @@ -68,7 +50,7 @@ const ThemeSwitcherDropdown = () => { ) } - > + /> Theme diff --git a/apps/design-system/components/top-navigation.tsx b/apps/design-system/components/top-navigation.tsx index 4aec103a965..5e9c85dff48 100644 --- a/apps/design-system/components/top-navigation.tsx +++ b/apps/design-system/components/top-navigation.tsx @@ -1,30 +1,37 @@ -// import { docsConfig } from '@/config/docs' +'use client' + import Link from 'next/link' +import { Menu } from 'lucide-react' +import { Button } from 'ui' import { CommandMenu } from './command-menu' import { HomepageSvgHandler } from './homepage-svg-handler' import { ThemeSwitcherDropdown } from './theme-switcher-dropdown' +import { useMobileSidebar } from '@/hooks/use-mobile-sidebar' + +export const TopNavigation = () => { + const { toggle } = useMobileSidebar() -function TopNavigation() { return ( -
-
-
- ) -} -``` - -See [Reusable Components](#reusable-components) section for a more advanced pagination component. - - - -## Sorting - -Let's make the email column sortable. - - - -### Update `` - -```tsx showLineNumbers title="app/payments/data-table.tsx" showLineNumbers {3,6,10,18,25-28} -"use client" - -import * as React from "react" -import { - ColumnDef, - SortingState, - flexRender, - getCoreRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table" - -export function DataTable({ - columns, - data, -}: DataTableProps) { - const [sorting, setSorting] = React.useState([]) - - const table = useReactTable({ - data, - columns, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - onSortingChange: setSorting, - getSortedRowModel: getSortedRowModel(), - state: { - sorting, - }, - }) - - return ( -
-
- { ... }
-
-
- ) -} -``` - -### Make header cell sortable - -We can now update the `email` header cell to add sorting controls. - -```tsx showLineNumbers title="app/payments/columns.tsx" {4,9-19} -'use client' - -import { ColumnDef } from '@tanstack/react-table' -import { ArrowUpDown, MoreHorizontal } from 'lucide-react' - -export const columns: ColumnDef[] = [ - { - accessorKey: 'email', - header: ({ column }) => { - return ( - - ) - }, - }, -] -``` - -This will automatically sort the table (asc and desc) when the user toggles on the header cell. - -
- -## Filtering - -Let's add a search input to filter emails in our table. - - - -### Update `` - -```tsx showLineNumbers title="app/payments/data-table.tsx" {6,10,17,24-26,35-36,39,45-54} -"use client" - -import * as React from "react" -import { - ColumnDef, - ColumnFiltersState, - SortingState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table" - -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" - -export function DataTable({ - columns, - data, -}: DataTableProps) { - const [sorting, setSorting] = React.useState([]) - const [columnFilters, setColumnFilters] = React.useState( - [] - ) - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - onColumnFiltersChange: setColumnFilters, - getFilteredRowModel: getFilteredRowModel(), - state: { - sorting, - columnFilters, - }, - }) - - return ( -
-
- - table.getColumn("email")?.setFilterValue(event.target.value) - } - className="max-w-sm" - /> -
-
- { ... }
-
-
- ) -} -``` - -Filtering is now enabled for the `email` column. You can add filters to other columns as well. See the [filtering docs](https://tanstack.com/table/v8/docs/guide/filters) for more information on customizing filters. - -
- -## Visibility - -Adding column visibility is fairly simple using `@tanstack/react-table` visibility API. - - - -### Update `` - -```tsx showLineNumbers title="app/payments/data-table.tsx" {8,18-23,33-34,45,49,64-91} -"use client" - -import * as React from "react" -import { - ColumnDef, - ColumnFiltersState, - SortingState, - VisibilityState, - flexRender, - getCoreRowModel, - getFilteredRowModel, - getPaginationRowModel, - getSortedRowModel, - useReactTable, -} from "@tanstack/react-table" - -import { Button } from "@/components/ui/button" -import { - DropdownMenu, - DropdownMenuCheckboxItem, - DropdownMenuContent, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" - -export function DataTable({ - columns, - data, -}: DataTableProps) { - const [sorting, setSorting] = React.useState([]) - const [columnFilters, setColumnFilters] = React.useState( - [] - ) - const [columnVisibility, setColumnVisibility] = - React.useState({}) - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - onColumnVisibilityChange: setColumnVisibility, - state: { - sorting, - columnFilters, - columnVisibility, - }, - }) - - return ( -
-
- - table.getColumn("email")?.setFilterValue(event.target.value) - } - className="max-w-sm" - /> - - - - - - {table - .getAllColumns() - .filter( - (column) => column.getCanHide() - ) - .map((column) => { - return ( - - column.toggleVisibility(!!value) - } - > - {column.id} - - ) - })} - - -
-
- { ... }
-
-
- ) -} -``` - -This adds a dropdown menu that you can use to toggle column visibility. - -
- -## Row Selection - -Next, we're going to add row selection to our table. - - - -### Update column definitions - -```tsx showLineNumbers title="app/payments/columns.tsx" {6,9-27} -'use client' - -import { ColumnDef } from '@tanstack/react-table' - -import { Badge } from '@/components/ui/badge' -import { Checkbox } from '@/components/ui/checkbox' - -export const columns: ColumnDef[] = [ - { - id: 'select', - header: ({ table }) => ( - table.toggleAllPageRowsSelected(!!value)} - aria-label="Select all" - /> - ), - cell: ({ row }) => ( - row.toggleSelected(!!value)} - aria-label="Select row" - /> - ), - enableSorting: false, - enableHiding: false, - }, -] -``` - -### Update `` - -```tsx showLineNumbers title="app/payments/data-table.tsx" {11,23,28} -export function DataTable({ columns, data }: DataTableProps) { - const [sorting, setSorting] = React.useState([]) - const [columnFilters, setColumnFilters] = React.useState([]) - const [columnVisibility, setColumnVisibility] = React.useState({}) - const [rowSelection, setRowSelection] = React.useState({}) - - const table = useReactTable({ - data, - columns, - onSortingChange: setSorting, - onColumnFiltersChange: setColumnFilters, - getCoreRowModel: getCoreRowModel(), - getPaginationRowModel: getPaginationRowModel(), - getSortedRowModel: getSortedRowModel(), - getFilteredRowModel: getFilteredRowModel(), - onColumnVisibilityChange: setColumnVisibility, - onRowSelectionChange: setRowSelection, - state: { - sorting, - columnFilters, - columnVisibility, - rowSelection, - }, - }) - - return ( -
-
- - - - ) -} -``` - -This adds a checkbox to each row and a checkbox in the header to select all rows. - -### Show selected rows - -You can show the number of selected rows using the `table.getFilteredSelectedRowModel()` API. - -```tsx -
- {table.getFilteredSelectedRowModel().rows.length} of {table.getFilteredRowModel().rows.length}{' '} - row(s) selected. -
-``` - - - -## Reusable Components - -Here are some components you can use to build your data tables. This is from the [Tasks](/examples/tasks) demo. - -### Column header - -Make any column header sortable and hideable. - - - -```tsx {5} -export const columns = [ - { - accessorKey: 'email', - header: ({ column }) => , - }, -] -``` - -### Pagination - -Add pagination controls to your table including page size and selection count. - - - -```tsx - -``` - -### Column toggle - -A component to toggle column visibility. - - - -```tsx - -``` diff --git a/apps/design-system/content/docs/components/dialog.mdx b/apps/design-system/content/docs/components/dialog.mdx index b8f9ae549d6..108d9852e05 100644 --- a/apps/design-system/content/docs/components/dialog.mdx +++ b/apps/design-system/content/docs/components/dialog.mdx @@ -1,7 +1,6 @@ --- title: Dialog -description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert. -featured: true +description: A general-purpose modal for non-critical flows, forms, and custom interactions. component: true links: doc: https://www.radix-ui.com/docs/primitives/components/dialog @@ -11,6 +10,20 @@ source: shadcn: true --- +Dialog is a flexible, general-purpose modal used for bespoke interactions such as forms, pickers, multi-step flows, or displaying non-urgent information. Unlike confirmation-focused dialogs, it is designed to be safely dismissible and does not force an explicit decision. + +Dialog can be closed by clicking outside the modal or pressing the Escape key, making it suitable for workflows where cancellation is expected and low-risk. + +Use Dialog when you need full control over layout, content, and behavior, and the interaction does not involve a critical or destructive action. + +For confirmations or warnings, try to use an existing component: + +- Use [Alert Dialog](../components/alert-dialog) for critical confirmations that require an explicit decision +- Use [Confirmation Modal](../fragments/confirmation-modal) when additional context is needed for a confirmation +- Use [Text Confirm Dialog](../fragments/text-confirm-dialog) for highly destructive actions that require typed intent + +See [Modality](../ui-patterns/modality) for guidance on choosing the appropriate dialog pattern. + ## Usage @@ -31,23 +44,31 @@ import { Open - Are you absolutely sure? + Project settings - This action cannot be undone. This will permanently delete your account and remove your data - from our servers. + Update configuration options for this project. Changes can be discarded at any time. + {/* Custom content goes here */} ``` +## Guidelines + +- **Use for non-critical interactions:** Dialog is appropriate when dismissal has no serious consequences. +- **Design for cancellation**: Assume users may close the dialog without completing the action. +- **Keep focus contained**: Dialog content should remain scoped to a single task or flow. +- **Avoid destructive confirmations**: If the dialog’s primary purpose is to confirm a risky action, use a confirmation-focused pattern instead. +- **Compose freely**: Dialog is intentionally unopinionated. Build custom layouts, forms, or step-based flows as needed. + ## Examples ### Custom close button -### Centered behaviour +### Centered behavior You can control whether the dialog is centered by passing `centered={false}` to the `DialogContent` component. @@ -69,30 +90,27 @@ You can control whether the dialog is centered by passing `centered={false}` to To activate the `Dialog` component from within a `Context Menu` or `Dropdown Menu`, you must encase the `Context Menu` or `Dropdown Menu` component in the `Dialog` component. For more information, refer to the linked issue [here](https://github.com/radix-ui/primitives/issues/1836). -```tsx {14-25} +```tsx {7-11, 14-23} - Dialog not centered + Show Menu Open Download - Delete + Show Dialog - Are you absolutely sure? - - This action cannot be undone. Are you sure you want to permanently delete this file from our - servers? - + Edit profile + Make changes to your profile here. - + diff --git a/apps/design-system/content/docs/components/dropdown-menu.mdx b/apps/design-system/content/docs/components/dropdown-menu.mdx index daccc38aa88..e7fed432cd7 100644 --- a/apps/design-system/content/docs/components/dropdown-menu.mdx +++ b/apps/design-system/content/docs/components/dropdown-menu.mdx @@ -15,12 +15,6 @@ source: ## Installation -So I guess I can write anything i want in here. - -## Props - -{/* */} - diff --git a/apps/design-system/content/docs/components/field.mdx b/apps/design-system/content/docs/components/field.mdx new file mode 100644 index 00000000000..aa5e30a6542 --- /dev/null +++ b/apps/design-system/content/docs/components/field.mdx @@ -0,0 +1,333 @@ +--- +title: Field +description: Combine labels, controls, and help text to compose accessible form fields and grouped inputs. +component: true +source: + shadcn: true +--- + + + +## Installation + + + + + CLI + Manual + + + +```bash +npx shadcn@latest add field +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx showLineNumbers +import { + Field, + FieldContent, + FieldDescription, + FieldError, + FieldGroup, + FieldLabel, + FieldLegend, + FieldSeparator, + FieldSet, + FieldTitle, +} from '@/components/ui/field' +``` + +```tsx showLineNumbers +
+ Profile + This appears on invoices and emails. + + + Full name + + This appears on invoices and emails. + + + Username + + Choose another username. + + + + Subscribe to the newsletter + + +
+``` + +## Anatomy + +The `Field` family is designed for composing accessible forms. A typical field is structured as follows: + +```tsx showLineNumbers + + Label + {/* Input, Select, Switch, etc. */} + Optional helper text. + Validation message. + +``` + +- `Field` is the core wrapper for a single field. +- `FieldContent` is a flex column that groups label and description. Not required if you have no description. +- Wrap related fields with `FieldGroup`, and use `FieldSet` with `FieldLegend` for semantic grouping. + +## Form + +See the [Form](/docs/forms) documentation for building forms with the `Field` component and [React Hook Form](/docs/forms/react-hook-form) or [Tanstack Form](/docs/forms/tanstack-form). + +## Examples + +### Input + + + +### Textarea + + + +### Select + + + +### Slider + + + +### Fieldset + + + +### Checkbox + + + +### Radio + + + +### Switch + + + +### Choice Card + +Wrap `Field` components inside `FieldLabel` to create selectable field groups. This works with `RadioItem`, `Checkbox` and `Switch` components. + + + +### Field Group + +Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them. + + + +## Responsive Layout + +- **Vertical fields:** Default orientation stacks label, control, and helper text—ideal for mobile-first layouts. +- **Horizontal fields:** Set `orientation="horizontal"` on `Field` to align the label and control side-by-side. Pair with `FieldContent` to keep descriptions aligned. +- **Responsive fields:** Set `orientation="responsive"` for automatic column layouts inside container-aware parents. Apply `@container/field-group` classes on `FieldGroup` to switch orientations at specific breakpoints. + + + +## Validation and Errors + +- Add `data-invalid` to `Field` to switch the entire block into an error state. +- Add `aria-invalid` on the input itself for assistive technologies. +- Render `FieldError` immediately after the control or inside `FieldContent` to keep error messages aligned with the field. + +```tsx showLineNumbers /data-invalid/ /aria-invalid/ + + Email + + Enter a valid email address. + +``` + +## Accessibility + +- `FieldSet` and `FieldLegend` keep related controls grouped for keyboard and assistive tech users. +- `Field` outputs `role="group"` so nested controls inherit labeling from `FieldLabel` and `FieldLegend` when combined. +- Apply `FieldSeparator` sparingly to ensure screen readers encounter clear section boundaries. + +## API Reference + +### FieldSet + +Container that renders a semantic `fieldset` with spacing presets. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx +
+ Delivery + {/* Fields */} +
+``` + +### FieldLegend + +Legend element for a `FieldSet`. Switch to the `label` variant to align with label sizing. + +| Prop | Type | Default | +| ----------- | --------------------- | ---------- | +| `variant` | `"legend" \| "label"` | `"legend"` | +| `className` | `string` | | + +```tsx +Notification Preferences +``` + +The `FieldLegend` has two variants: `legend` and `label`. The `label` variant applies label sizing and alignment. Handy if you have nested `FieldSet`. + +### FieldGroup + +Layout wrapper that stacks `Field` components and enables container queries for responsive orientations. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx + + {/* ... */} + {/* ... */} + +``` + +### Field + +The core wrapper for a single field. Provides orientation control, invalid state styling, and spacing. + +| Prop | Type | Default | +| -------------- | -------------------------------------------- | ------------ | +| `orientation` | `"vertical" \| "horizontal" \| "responsive"` | `"vertical"` | +| `className` | `string` | | +| `data-invalid` | `boolean` | | + +```tsx + + Remember me + + +``` + +### FieldContent + +Flex column that groups control and descriptions when the label sits beside the control. Not required if you have no description. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx + + + + Notifications + Email, SMS, and push options. + + +``` + +### FieldLabel + +Label styled for both direct inputs and nested `Field` children. + +| Prop | Type | Default | +| ----------- | --------- | ------- | +| `className` | `string` | | +| `asChild` | `boolean` | `false` | + +```tsx +Email +``` + +### FieldTitle + +Renders a title with label styling inside `FieldContent`. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx + + Enable Touch ID + Unlock your device faster. + +``` + +### FieldDescription + +Helper text slot that automatically balances long lines in horizontal layouts. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx +We never share your email with anyone. +``` + +### FieldSeparator + +Visual divider to separate sections inside a `FieldGroup`. Accepts optional inline content. + +| Prop | Type | Default | +| ----------- | -------- | ------- | +| `className` | `string` | | + +```tsx +Or continue with +``` + +### FieldError + +Accessible error container that accepts children or an `errors` array (e.g., from `react-hook-form`). + +| Prop | Type | Default | +| ----------- | ------------------------------------------ | ------- | +| `errors` | `Array<{ message?: string } \| undefined>` | | +| `className` | `string` | | + +```tsx + +``` + +When the `errors` array contains multiple messages, the component renders a list automatically. + +`FieldError` also accepts issues produced by any validator that implements [Standard Schema](https://standardschema.dev/), including Zod, Valibot, and ArkType. Pass the `issues` array from the schema result directly to render a unified error list across libraries. diff --git a/apps/design-system/content/docs/components/fragment-components.mdx b/apps/design-system/content/docs/components/fragment-components.mdx deleted file mode 100644 index 1a924430a1f..00000000000 --- a/apps/design-system/content/docs/components/fragment-components.mdx +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Fragment components -description: '' ---- diff --git a/apps/design-system/content/docs/components/introduction.mdx b/apps/design-system/content/docs/components/introduction.mdx new file mode 100644 index 00000000000..8022af4294d --- /dev/null +++ b/apps/design-system/content/docs/components/introduction.mdx @@ -0,0 +1,10 @@ +--- +title: Atom components +description: Fundamental building blocks of user interfaces, based on shadcn/ui components. +--- + +Atom components are the fundamental building blocks of our design system. These are primitive, single-purpose components that serve as the foundation for building more complex interfaces. Unlike fragment components (pre-built composite components) or UI patterns (guidelines for structuring sections), atom components are the smallest reusable units that can be composed together. + +These components are based on [shadcn/ui](https://ui.shadcn.com) and live in the `ui` package, making them shareable across all Supabase applications. They provide consistent styling, accessibility, and behavior for common interface elements like buttons, inputs, cards, dialogs, and form controls. + +Atom components are imported from the `ui` package and can be used directly or combined to create fragment components and implement UI patterns. They form the base layer of our component architecture, ensuring visual and functional consistency across the entire design system. diff --git a/apps/design-system/content/docs/components/mermaid.mdx b/apps/design-system/content/docs/components/mermaid.mdx new file mode 100644 index 00000000000..0d12331145d --- /dev/null +++ b/apps/design-system/content/docs/components/mermaid.mdx @@ -0,0 +1,121 @@ +--- +title: Mermaid +description: Render diagrams from text using Mermaid syntax. +component: true +--- + + + +## Usage + +### In MDX (Blog Posts) + +The simplest way to add diagrams in blog posts is with a fenced code block using the `mermaid` language tag: + +````mdx +```mermaid +flowchart LR + A[User Request] --> B{Authenticated?} + B -->|Yes| C[Process Request] + B -->|No| D[Return 401] +``` +```` + +This is automatically rendered as a diagram. No imports needed. + +### As a Component + +For more control, import and use the component directly: + +```tsx +import { Mermaid } from 'ui' + +export function MyDiagram() { + return ( + B{Authenticated?} + B -->|Yes| C[Process Request] + B -->|No| D[Return 401] +`} + /> + ) +} +``` + +Use the component when you need to pass props like `className`, conditionally render, or integrate with React logic. + +## Flowcharts + +Use `flowchart` or `graph` to create flowcharts with nodes and edges. Supports decision diamonds, different node shapes, and directional layouts (TD, LR, etc). +[View Mermaid flowchart docs](https://mermaid.js.org/syntax/flowchart.html) + +A basic request flow showing conditional branching with a decision node (`{}`), demonstrating how to visualize auth checks and data flow. + + + +### With Subgraphs + +Group related nodes into labeled subgraphs to show system boundaries. Useful for depicting frontend/backend separation or microservice architecture. + + + +### Supabase Architecture + +Shows how client requests flow through the API Gateway to core services (Auth, PostgREST, Realtime) which all connect to PostgreSQL. + + + +### OAuth Authorization Flow + +Illustrates the OAuth 2.0 authorization code flow, showing the handoff between a third-party app, your authorization endpoint, and Supabase Auth for token exchange. + + + +## ER Diagrams + +Use `erDiagram` to create entity-relationship diagrams showing database schemas. Great for documenting table relationships and foreign keys. +[View Mermaid ER diagram docs](https://mermaid.js.org/syntax/entityRelationshipDiagram.html) + +A simple e-commerce schema showing cardinality between customers, orders, products, and line items using crow's foot notation. + + + +### With Attributes + +Include column definitions with types and constraints (PK, FK) to create more detailed schema documentation. + + + +## Sequence Diagrams + +Use `sequenceDiagram` to show interactions between participants over time. Ideal for documenting API flows, authentication handshakes, or any request/response patterns. +[View Mermaid sequence diagram docs](https://mermaid.js.org/syntax/sequenceDiagram.html) + +A typical authenticated API request showing JWT validation, database insert, and response flow between Client, API, Auth, and DB participants. + + + +### Async Streaming (FDW) + +Shows how Foreign Data Wrappers can stream data asynchronously using bounded channels, with parallel execution indicated by the `par` block. + + + +### Sync Blocking (FDW) + +Contrasts with async by showing traditional blocking FDW behavior where all rows are fetched and buffered before processing. + + + +## Props + +| Prop | Type | Description | +| ----------- | -------- | ------------------------------------ | +| `chart` | `string` | The Mermaid diagram definition | +| `className` | `string` | Optional CSS class for the container | + +## Learn More + +See the [Mermaid documentation](https://mermaid.js.org/intro/) for full syntax reference and additional diagram types. diff --git a/apps/design-system/content/docs/components/sheet.mdx b/apps/design-system/content/docs/components/sheet.mdx index 96220e63eb5..75edbb53860 100644 --- a/apps/design-system/content/docs/components/sheet.mdx +++ b/apps/design-system/content/docs/components/sheet.mdx @@ -12,6 +12,22 @@ source: +1. **Use for side panels** + + - Forms with multiple fields + - Settings panels + - Detailed editors + +2. **Consider screen size** + + - Sheets work well on desktop + - On mobile, consider full-screen or bottom sheet variants + +3. **Structure content clearly** + - Use `SheetHeader` and `SheetTitle` for context + - Use `SheetSection` to group related fields + - Use `SheetFooter` for actions + ## Installation @@ -80,11 +96,21 @@ import { ## Examples -### Side +### Nonmodal -Use the `side` property to `` to indicate the edge of the screen where the component will appear. The values can be `top`, `right`, `bottom` or `left`. +This sheet is nonmodal, meaning it does not block the underlying content. It’s useful when +you want to display content that complements the main content of the screen. - + + +To have the underlying content resize to fit the sheet (so nothing is overlapping) use the Sidebar component +or build a custom panel. You can refer to the following Studio components for guidance: + +- `AIAssistant` +- `EditorPanel` +- `AdvisorPanel` + +See [`LayoutSidebarProvider`](https://github.com/supabase/supabase/blob/master/apps/studio/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider.tsx) for more. ### Size @@ -104,3 +130,11 @@ You can adjust the size of the sheet using CSS classes: ``` + +### Side + +Use the `side` property to `` to indicate the edge of the screen where the component will appear. The values can be `top`, `right`, `bottom` or `left`. + + + +That said, stick to the default `right` unless you have a strong reason not to. diff --git a/apps/design-system/content/docs/components/slider.mdx b/apps/design-system/content/docs/components/slider.mdx index e2f1120559c..6f22de237df 100644 --- a/apps/design-system/content/docs/components/slider.mdx +++ b/apps/design-system/content/docs/components/slider.mdx @@ -59,3 +59,9 @@ import { Slider } from '@/components/ui/slider' ```tsx ``` + +## Examples + +### Min and Max Range + + diff --git a/apps/design-system/content/docs/components/table.mdx b/apps/design-system/content/docs/components/table.mdx index ab2cc6bf5dc..2de803e5266 100644 --- a/apps/design-system/content/docs/components/table.mdx +++ b/apps/design-system/content/docs/components/table.mdx @@ -1,57 +1,222 @@ --- title: Table -description: A responsive table component for basic data. +description: A responsive table component for presenting data inline. component: true +source: + shadcn: true --- -Table presents basic tabular data presentation within a [Card](/docs/components/card). +Table is an opinionated `
` element for basic tabular data presentation. It is usually presented within a [Card](../components/card). -Columns will naturally take the width of their content. Width specification is therefore not required unless you require columns to span a specific width. An example use-case may be when placing multiple Table instances on the one page, where columns on each table should optically align. - -`TableHead` includes a `whitespace-nowrap` utility class to prevent its text from wrapping. `TableCell` must have any custom width specified, as there are legitimate use cases for both wrapping (or truncated) text. - ## Usage ```tsx import { + Card, Table, TableBody, - TableCaption, TableCell, + TableFooter, TableHead, TableHeader, TableRow, -} from '@/components/ui/table' +} from 'ui' ``` ```tsx + +
+ + + Column 1 + Column 2 + Column 3 + + + + + Value 1 + Value 2 + Value 3 + + + + + Total + Value + + +
+ +``` + +## Layout + +Columns will naturally take the width of their content unless otherwise specified. Specific column widths may be useful for controlling layout shift or for aligning multiple Table instances vertically. + +Table Head includes a `whitespace-nowrap` utility class to prevent its text from wrapping. Table Cell must have any custom width specified, as there are legitimate use cases for both wrapping (or truncated) text. + +The Table component is wrapped in a `ShadowScrollArea` by default, which provides horizontal scrolling on smaller screens when the table content exceeds the viewport width. + +## Structure + +Table is comprised of the following [Shadcn primitives](https://ui.shadcn.com/docs/components/table) which map directly to their HTML counterparts: + +| Component | HTML element | +| ------------- | ------------------------------------------------------------------------------------------- | +| Table | [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/table) | +| Table Body | [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/tbody) | +| Table Caption | [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/tfoot) | +| Table Head | [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/thead) | +| Table Row | [``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/tr) | + +Table and its child components follow their HTML element counterparts for semantics, accessibility, and best practices. + +### Table Caption + +Table Caption describes a table’s purpose or content. Think of it like the label of a diagram. It should only contain a single text node. + +Just like its `
`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/caption) | +| Table Cell | [`
`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/td) | +| Table Footer | [`
`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/th) | +| Table Header | [`
` counterpart, Table Caption should be the first child of a Table element (before a Table Body) irrespective of its final visual positioning. + +### Table Footer + +Table Footer is a semantic grouping for the final rows of a table, typically used for column summaries, totals, or footnotes that relate to the data in the body of the table. + +Table Footer typically contains the same child elements as a Table Body, such as Table Row and Table Cell, and is a sibling of Table Body. + +## Examples + +### Empty state + +When displaying an empty state within a table, dim the Table Head text to indicate that no data is present. Use consistent zero results presentation across your application to maintain a cohesive user experience. + + + +To prevent the empty state row from being highlighted on hover, apply the `[&>td]:hover:bg-inherit` class to the Table Row containing the empty state message. + +```tsx showLineNumbers {1} + + +

No results found

+

+ Your search for “test” did not return any results +

+
+
+``` + +See [Empty States](../ui-patterns/empty-states) for more information. + +### Sortable columns + +Use `TableHeadSort` inside Table Head to enable column sorting. This component provides visual indicators for sort state (ascending, descending, or unsorted) and handles click interactions. + +```tsx +import { TableHeadSort } from 'ui' +``` + +| Prop | Type | Description | +| -------------- | -------------------------- | ------------------------------------------------------------------ | +| `column` | `string` | Unique identifier for the column | +| `currentSort` | `string` | Current sort state in format `"column:order"` (e.g., `"name:asc"`) | +| `onSortChange` | `(column: string) => void` | Callback fired when column header is clicked | +| `children` | `ReactNode` | The label text for the column header | +| `className` | `string` | Optional additional CSS classes | + +```tsx showLineNumbers {2} + + + Name + + +``` + +The component displays: + +- An up arrow when the column is sorted ascending +- A down arrow when the column is sorted descending +- A chevrons icon when the column is not currently sorted (visible on hover) + + + +### Row icons + +When adding icon columns to your table, use [Accessibility](../accessibility) markup by including a screen reader-only label in the corresponding Table Head using the `sr-only` class. This ensures that assistive technologies can properly identify the column's purpose. Remove these icon cells when loading or displaying zero results to maintain a clean and consistent table structure. + + + +```tsx showLineNumbers {4, 5, 13, 14} - A list of your recent invoices. - Invoice - Status - Method - Amount + + Icon + + Name + Email - INV001 - Paid - Credit Card - $250.00 + + + + Value + Value
``` -## Data Table +### Actions -You can use the `` component to build more complex data tables. Combine it with [@tanstack/react-table](https://tanstack.com/table/v8) to create tables with sorting, filtering and pagination. +Action should be placed in the last column of each Table Row to maintain a logical reading flow. Users scan table data from left to right, so positioning actions on the right ensures they encounter the primary information first before reaching interactive controls. -See the [Data Table](/docs/components/data-table) documentation for more information. +#### Multiple actions -You can also see an example of a data table in the [Tasks](/examples/tasks) demo. +When multiple actions are available for a row, display one primary action as a button and place additional options in an overflow menu. This keeps the table clean and scannable while providing access to all necessary actions without overwhelming the user. + + + +#### Cross-links + +You may need to link to related resources from within table cells. In these cases, use the `text-link-table-cell` CSS class to provide a visual hint that the text is interactive while maintaining its appearance as tertiary content. + + + +Avoid making the entire row interactive when using cross-links. Multiple interactive areas within a single row increases the chance of mis-taps and creates ambiguity about which action will be triggered. Keep cross-links as discrete, scannable elements within their respective cells, and maintain a dedicated action column for primary row-level actions. + +#### Row-level navigation + +The entire Table Row may be tappable. This pattern is most effective when navigation is the sole or primary action for each row, as it provides a large, easy-to-target interaction area. + +Avoid adding other actions when using row-level navigation, as multiple interactive areas within a single row create competing affordances and increase interaction complexity. + + + +When implementing row-level navigation, pay close attention to [Accessibility](/accessibility#focus-management) requirements. The row must be keyboard accessible with proper focus management. Also consider these affordances: + +- Handle `Enter` and `Space` key presses for activation +- Provide visual focus indicators using classes like `inset-focus` +- Support modifier keys (`Ctrl`/`Cmd`, middle-click) for opening links in new tabs + - Consider using the shared `createNavigationHandler` function to handle modifier keys +- Avoid bubbling up action events from _within_ the row + +#### Row navigation with actions + +If you must combine row-level navigation with additional actions, nest all secondary actions in an overflow menu and maintain a [ChevronRight](https://lucide.dev/icons/chevron-right) visual indicator to signal that the row is navigable. This pattern preserves the primary navigation affordance while keeping secondary actions accessible but unobtrusive. + + + +This hybrid approach requires careful attention to event handling. Ensure that taps on action buttons stop event propagation to prevent triggering row navigation, and maintain clear visual separation between the navigable row area and the action controls. + +## Related + +Use the Table component for simple, static tabular data presentation with a fixed number of rows. Consider using [Data Table](../ui-patterns/tables#data-table) for more complex cases as it provides built-in sorting, filtering, and pagination capabilities. + +Refer to [Tables](../ui-patterns/tables) for broader guidance and best practices on presenting tabular data. diff --git a/apps/design-system/content/docs/copywriting.mdx b/apps/design-system/content/docs/copywriting.mdx new file mode 100644 index 00000000000..751cf4e0497 --- /dev/null +++ b/apps/design-system/content/docs/copywriting.mdx @@ -0,0 +1,240 @@ +--- +title: Copywriting +description: A concise guide for writing UI copy in Supabase. +--- + +Write UI copy that helps developers complete tasks quickly. Be direct, action-oriented, and respectful of developer time. + +## Voice and tone + +Supabase UI copy is: + +- **Direct**: Say what something does, not what it "enables" you to do. +- **Action-oriented**: Focus on what happens, not what we built. +- **Technical without jargon**: Use precise terms but explain when necessary. +- **Pragmatic**: Acknowledge tradeoffs and limitations when relevant. + +## Buttons and actions + +### Use verbs, not nouns + + + +### Be specific about outcomes + +| Bad | Good | +| ----------- | ---------------- | +| "Remove" | "Delete project" | +| "Change" | "Revoke access" | +| "Configure" | "Enable RLS" | + +### Match button text to the action + +| Action | Bad | Good | +| ----------------- | --------- | -------------- | +| Primary action: | "Submit" | "Create table" | +| Secondary action: | "Go back" | "Cancel" | + +## Form labels and descriptions + +### Labels describe the field, not the feature + + + +| Action | Bad | Good | +| ------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------- | +| Label: | "Name your table" | "Table name" | +| Description: | "This field allows you to specify a name for your table using letters, numbers, and underscores" | "Letters, numbers, and underscores only" | + +### Descriptions explain constraints, not concepts + +| Bad | Good | +| --------------------------------------------------------------- | ---------------------------------- | +| "This ensures your table name is unique" | "Must be unique within the schema" | +| "You can enter up to 255 characters here" | "Maximum 255 characters" | +| "This field is required when using Row Level Security policies" | "Required for RLS policies" | + +### Use present tense + +| Bad | Good | +| -------------------------------------- | --------------------------------- | +| "Will store connection pool settings" | "Stores connection pool settings" | +| "This will limit query execution time" | "Limits query execution time" | + +## Error messages + +### State what went wrong, then how to fix it + + + +| Bad | Good | +| ----------------------------------------- | ----------------------------------------------------- | +| "An error occurred" | "Table name already exists. Choose a different name." | +| "Something went wrong. Please try again." | "Invalid API key. Check your project settings." | + +### Be specific about the problem + +| Bad | Good | +| ------------------ | --------------------------------------------- | +| "Invalid input" | "Password must be at least 8 characters" | +| "Connection error" | "Connection failed: timeout after 30 seconds" | + +### Avoid blame or apology + +| Bad | Good | +| ---------------------------- | ------------------------------------------------ | +| "Sorry, we couldn't connect" | "Unable to connect to database" | +| "Oops! Something went wrong" | "Table creation failed: column name is reserved" | + +## Success messages + +### Confirm what happened + + + +| Bad | Good | +| --------------------- | ---------------------------- | +| "Success!" | "Table created successfully" | +| "Done" | "API key revoked" | +| "Operation completed" | "Changes saved" | + +### Keep it brief + +| Bad | Good | +| ------------------------------------------------------------- | ------------------- | +| "Your backup has been successfully restored to your database" | "Backup restored" | +| "The migration has been applied successfully to your project" | "Migration applied" | + +## Tooltips and help text + +### Explain why, not what + + + +| Bad | Good | +| ------------------------- | ------------------------------------------------ | +| "This is a toggle switch" | "Enables real-time subscriptions for this table" | +| "Click to delete" | "Prevents accidental deletions" | + +### One sentence maximum + +| Bad | Good | +| ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------ | +| "Row Level Security restricts access based on user policies. When enabled, users can only access rows that match their policy conditions." | "Restricts access based on user policies" | +| "This setting controls the maximum number of concurrent connections that can be established to your database at any given time." | "Maximum number of concurrent connections" | + +## Navigation and headings + +### Use sentence case + +| Bad | Good | +| ----------------------- | ----------------------- | +| "Set Up Authentication" | "Set up authentication" | +| "Database Settings" | "Database settings" | +| "Create New Project" | "Create new project" | + +### Headings describe the page, not the feature + +| Bad | Good | +| ------------------------------ | -------------------- | +| "Manage your API keys" | "API keys" | +| "Configure connection pooling" | "Connection pooling" | +| "Edit your tables" | "Table editor" | + +## Empty states + +### Explain what's missing, then how to add it + + + +| Bad | Good | +| --------------------------------- | ---------------------------------------------------------- | +| "You don't have any tables" | "No tables yet. Create your first table to get started." | +| "There are no API keys available" | "No API keys. Generate a key to connect your application." | + +### Include the action + +| Bad | Good | +| ------------------------ | ------------------------------------------------- | +| "No buckets found" | "No buckets yet. [Create bucket] button" | +| "No functions available" | "No functions deployed. [Deploy function] button" | + +## Loading states + +### Describe what's happening + + + +| Bad | Good | +| ---------------- | ----------------------- | +| "Please wait..." | "Creating table..." | +| "Loading..." | "Loading schema..." | +| "Processing..." | "Applying migration..." | + +### Match the action verb + +| Action | Bad | Good | +| --------------------------- | ---------------- | --------------------- | +| "Delete project" → Loading: | "Processing..." | "Deleting project..." | +| "Save changes" → Loading: | "Please wait..." | "Saving changes..." | + +## Confirmations and dialogs + +### State consequences clearly + + + +| Bad | Good | +| ------------------------------------- | ----------------------------------------------------------------------------------------- | +| "Are you sure?" | "Delete this project? This action cannot be undone and will permanently delete all data." | +| "This action is permanent. Continue?" | "Revoke this API key? Applications using this key will stop working immediately." | + +### Use active voice + +| Bad | Good | +| ------------------------------------------------------------ | --------------------------------------------------- | +| "All data will be removed if this project is deleted" | "Deleting this project will remove all data" | +| "Existing connections will be broken if this key is revoked" | "Revoking this key will break existing connections" | + +## Words to avoid + +### Marketing language + +| Bad | Good | +| ---------------------------- | -------------------- | +| "Easily create tables" | "Create tables" | +| "Simply configure settings" | "Configure settings" | +| "Powerful database features" | "Database features" | + +### Vague verbs + +| Bad | Good | +| ---------------- | -------------------------------- | +| "Manage tables" | "Create, edit, or delete tables" | +| "Handle errors" | "View and resolve errors" | +| "Work with data" | "Query and update data" | + +## Capitalization + +- **Sentence case** for all UI text (buttons, labels, headings) +- **Product names:** Database, Auth, Storage, Edge Functions, Realtime, Vector +- **Postgres**, not PostgreSQL +- **Supabase** (capitalize except in code) + +## Formatting + +- **Bold for emphasis** only when necessary +- **Inline code** for technical terms: `RLS`, `API key`, `supabase init` +- **No italics** for emphasis +- **No exclamation marks** unless critical (e.g., destructive actions) + +## Quick checklist + +Before publishing UI copy, ask: + +- Does it use an action verb? +- Is it specific about what happens? +- Can a developer complete the task without reading more? +- Does it avoid marketing language? +- Is it in sentence case? +- Is it one sentence or less (for labels, buttons, tooltips)? diff --git a/apps/design-system/content/docs/fragments/admonition.mdx b/apps/design-system/content/docs/fragments/admonition.mdx index 5df52e91ceb..0143008fcd9 100644 --- a/apps/design-system/content/docs/fragments/admonition.mdx +++ b/apps/design-system/content/docs/fragments/admonition.mdx @@ -2,11 +2,10 @@ title: Admonition description: Displays a callout for user attention. fragment: true -links: - doc: https://www.radix-ui.com/docs/primitives/components/alert - api: https://www.radix-ui.com/docs/primitives/components/alert#api-reference --- +Admonition provides focus for situations that require a callout. + +Use Admonition instead of [Alert](../components/alert) unless you specifically need the primitives. If in doubt, stick with Admonition. + ## Usage ```tsx @@ -28,8 +29,26 @@ import { Admonition } from 'ui-patterns/admonition' /> ``` +### Buttons + +Style the color of the button based upon the _context_ of the Admonition, not its inherited `type`. For example, the below `warning` Admonition has an encouraged action, so its button has `type="default"`. The `destructive` Admonition has a button that is destructive, so the button has `type="danger"`. + + + +Only ever use the `primary` (green) button `type` on a `default` Admonition. Even then—given that Admonition is an isolated callout—the `primary` button `type` should rarely be used. + ## Examples +### With actions + + + ### Warning +There are several components that wrap the `warning` Admonition type with reusable text or functionality. These include: + +- AlertError +- NoPermission + +AlertError for example rolls up consistent error handling and support contact methods. + ### Destructive + +## Usage + +```tsx +'use client' + +import { useState } from 'react' +import { Button } from 'ui' +import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' +``` + +```tsx +export default function ConfirmationModalDemo() { + const [visible, setVisible] = useState(false) + + return ( + <> + + + { + setVisible(false) + }} + onCancel={() => { + setVisible(false) + }} + > + This will resume the project and restart any paused processes. + + + ) +} +``` + +## Guidelines + +- **Use for moderate complexity:** Suitable when the confirmation requires more than a single sentence but does not need typed intent. +- **Avoid critical destruction:** Do not use for irreversible or high-risk actions that could benefit from stronger safeguards. +- **Keep content focused:** Include only the context needed to make the decision. If the dialog becomes a full flow, use a custom [Dialog](../components/dialog) instead. +- **Provide clear actions:** Ensure confirm and cancel labels clearly describe the outcome of each choice. + +## Props + +- `visible`: Controls open state +- `title`: Dialog title +- `description`: Optional description +- `variant`: 'default' | 'destructive' | 'warning' +- `loading`: Loading state +- `onConfirm`: Confirm handler +- `onCancel`: Cancel handler +- `alert`: Optional callout (see [Admonition](../fragments/admonition)) +- `children`: Additional content diff --git a/apps/design-system/content/docs/fragments/empty-state-presentational.mdx b/apps/design-system/content/docs/fragments/empty-state-presentational.mdx new file mode 100644 index 00000000000..361be6250cb --- /dev/null +++ b/apps/design-system/content/docs/fragments/empty-state-presentational.mdx @@ -0,0 +1,35 @@ +--- +title: Empty State Presentational +description: An empty state for encouraging action. +component: true +fragment: true +--- + + + +Expects a title, description, and optional action buttons or other children. + +## Props + +### Text + +All text should be written using active language. The title should prompt the user to take an action, and the description should clearly explain the value of doing so. + +### Icon + +Supports both Lucide icons and [custom icons](../icons) via the `icons` package. If neither are passed, Empty State Presentational falls back to Lucide’s `SquarePlus`. + + + +See also [Empty States](../ui-patterns/empty-states). + +## Examples + +It’s okay to repeat buttons inside of Empty State Presentational that are also available outside of it. The alternative is to conditionally determine button placement whilst polling for list length (to determine whether to show an empty state or not). This is problematic for two reasons: + +1. Rendering after client-side polling often leads to confusing layout shift. This layout shift becomes exacerbated when buttons are stacked against other objects. +2. Consistent entry points outside of Empty State Presentational also teach a pattern that will continue to exist post initial object creation. + +When repeating buttons, set the `type` to `default` so the original `primary`, button remains the only `primary` action on display. + + diff --git a/apps/design-system/content/docs/fragments/filter-bar.mdx b/apps/design-system/content/docs/fragments/filter-bar.mdx index fed27c7219d..34cbf1ac0e3 100644 --- a/apps/design-system/content/docs/fragments/filter-bar.mdx +++ b/apps/design-system/content/docs/fragments/filter-bar.mdx @@ -85,130 +85,44 @@ interface FilterCondition { ### Component Props -| Prop | Type | Description | -| -------------------- | ------------------------------ | ---------------------------------------- | -| filterProperties | FilterProperty[] | Array of properties that can be filtered | -| filters | FilterGroup | Current filter state | -| onFilterChange | (filters: FilterGroup) => void | Callback when filters change | -| freeformText | string | Current free-form search text | -| onFreeformTextChange | (text: string) => void | Callback when free-form text changes | -| aiApiUrl | string? | Optional URL for AI-powered filtering | +| Prop | Type | Description | +| -------------------- | ------------------------------ | ----------------------------------------------- | +| filterProperties | FilterProperty[] | Array of properties that can be filtered | +| filters | FilterGroup | Current filter state | +| onFilterChange | (filters: FilterGroup) => void | Callback when filters change | +| freeformText | string | Current free-form search text | +| onFreeformTextChange | (text: string) => void | Callback when free-form text changes | +| actions | FilterBarAction[]? | Optional custom actions to show in the menu | +| isLoading | boolean? | If true, dims the bar while work is in progress | -## AI Integration +## Custom actions (e.g. AI) -The Filter Bar component supports AI-powered filtering through an optional API endpoint. When `aiApiUrl` is provided, the component will send natural language queries to be converted into structured filters. - -### API Endpoint - -The AI API endpoint should accept POST requests with the following structure: - -```typescript -// Request body -interface AIFilterRequest { - prompt: string // Natural language query - filterProperties: FilterProperty[] // Available filter properties -} - -// Response body -interface AIFilterResponse { - logicalOperator: 'AND' | 'OR' - conditions: (FilterCondition | FilterGroup)[] -} -``` - -### Example API Implementation - -```typescript -import { generateObject } from 'ai' -import { openai } from '@ai-sdk/openai' -import { z } from 'zod' - -// Define schemas for validation -const FilterProperty = z.object({ - label: z.string(), - name: z.string(), - type: z.enum(['string', 'number', 'date', 'boolean']), - options: z.array(z.string()).optional(), - operators: z.array(z.string()).optional(), -}) - -const FilterCondition = z.object({ - propertyName: z.string(), - value: z.union([z.string(), z.number(), z.boolean(), z.null()]), - operator: z.string(), -}) - -type FilterGroupType = { - logicalOperator: 'AND' | 'OR' - conditions: Array | FilterGroupType> -} - -const FilterGroup: z.ZodType = z.lazy(() => - z.object({ - logicalOperator: z.enum(['AND', 'OR']), - conditions: z.array(z.union([FilterCondition, FilterGroup])), - }) -) - -export async function POST(req: Request) { - const { prompt, filterProperties } = await req.json() - const filterPropertiesString = JSON.stringify(filterProperties) - - try { - const { object } = await generateObject({ - model: openai('gpt-4-mini'), - schema: FilterGroup, - prompt: `Generate a filter group based on the following prompt: "${prompt}". - Use only these filter properties: ${filterPropertiesString}. - Each property has its own set of valid operators defined in the operators field. - Return a filter group with a logical operator ('AND'/'OR') and an array of conditions. - Each condition can be either a filter condition or another filter group. - Filter conditions should have the structure: { propertyName: string, value: string | number | boolean | null, operator: string }. - Ensure that the generated filters use only the provided property names and their corresponding operators.`, - }) - - // Validate that all propertyNames exist in filterProperties - const validatePropertyNames = (group: FilterGroupType): boolean => { - return group.conditions.every((condition) => { - if ('logicalOperator' in condition) { - return validatePropertyNames(condition as FilterGroupType) - } - const property = filterProperties.find( - (p: z.infer) => p.name === condition.propertyName - ) - if (!property) return false - // Validate operator is valid for this property - return property.operators?.includes(condition.operator) ?? false - }) - } - - if (!validatePropertyNames(object)) { - throw new Error('Invalid property names or operators in generated filter') - } - - // Zod will throw an error if the object doesn't match the schema - const validatedFilters = FilterGroup.parse(object) - return Response.json(validatedFilters) - } catch (error: any) { - console.error('Error in AI filtering:', error) - return Response.json({ error: error.message || 'AI filtering failed' }, { status: 500 }) - } -} -``` - -### Usage with AI +You can append custom actions to the property menu. Each action receives the current free-form input value and the active group's path so you can plug in AI, saved queries, etc. ```tsx -export function FilterDemoWithAI() { - const [filters, setFilters] = useState(initialFilters) +const actions = [ + { + value: 'ai-filter', + label: 'Filter by AI', + onSelect: async (inputValue, { path }) => { + const response = await fetch('/api/filter-ai', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ prompt: inputValue, path }), + }) + const group = (await response.json()) as FilterGroup + // Replace your filter state at the provided path with the returned group + setFilters((prev) => updateGroupAtPath(prev, path, group)) + }, + }, +] - return ( - - ) -} + ``` diff --git a/apps/design-system/content/docs/fragments/introduction.mdx b/apps/design-system/content/docs/fragments/introduction.mdx new file mode 100644 index 00000000000..39bac50ecfd --- /dev/null +++ b/apps/design-system/content/docs/fragments/introduction.mdx @@ -0,0 +1,10 @@ +--- +title: Fragment components +description: Reusable composite components assembled from atom components to solve common interface needs. +--- + +Fragment components are pre-built composite components that combine multiple atom components to create reusable interface elements. Unlike atom components (basic building blocks like buttons and inputs) or UI patterns (guidelines for structuring entire sections), fragment components are ready-to-use solutions for specific interface needs. + +These components help maintain consistency across Supabase products by providing standardized implementations for common interface patterns like data visualization, dialogs, empty states, forms, layout, and navigation. + +Fragment components are imported from the `ui-patterns` package and can be used directly in your application. They encapsulate common combinations of atom components, reducing boilerplate and ensuring consistent behavior across similar features. diff --git a/apps/design-system/content/docs/fragments/modal.mdx b/apps/design-system/content/docs/fragments/modal.mdx deleted file mode 100644 index 2bbd59837cf..00000000000 --- a/apps/design-system/content/docs/fragments/modal.mdx +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Modal -description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert. -fragment: true -links: - doc: https://www.radix-ui.com/docs/primitives/components/dialog - api: https://www.radix-ui.com/docs/primitives/components/dialog#api-reference ---- - - - -## Examples - -### Aligned footer - - - -### Hide footer - - - -### Custom footer - - diff --git a/apps/design-system/content/docs/fragments/page-header.mdx b/apps/design-system/content/docs/fragments/page-header.mdx index 741efbbc0e1..2af086da1ee 100644 --- a/apps/design-system/content/docs/fragments/page-header.mdx +++ b/apps/design-system/content/docs/fragments/page-header.mdx @@ -21,4 +21,4 @@ fragment: true - `PageHeaderTitle` - Primary page heading (h1) - `PageHeaderDescription` - Supporting text below title - `PageHeaderAside` - Container for action buttons (should be inside PageHeaderMeta, has `shrink-0`) -- `PageHeaderFooter` - Container for tab navigation (NavMenu, should be last child) +- `PageHeaderNavigationTabs` - Container for tab navigation (NavMenu, should be last child) diff --git a/apps/design-system/content/docs/fragments/page-section.mdx b/apps/design-system/content/docs/fragments/page-section.mdx index bc70b83723a..997276759a0 100644 --- a/apps/design-system/content/docs/fragments/page-section.mdx +++ b/apps/design-system/content/docs/fragments/page-section.mdx @@ -14,11 +14,11 @@ fragment: true ## Sub-components - `PageSection` - Root container with orientation variants (`horizontal` or `vertical`) -- `PageSectionMeta` - Meta wrapper for summary and aside (groups summary and aside together) -- `PageSectionSummary` - Container for section title and description (should be inside PageSectionMeta, has `flex-1`) +- `PageSectionMeta` - Meta wrapper for `PageSectionSummary` and optional `PageSectionAside` +- `PageSectionSummary` - Container for section title and description (should be inside `PageSectionMeta`, has `flex-1`) - `PageSectionTitle` - Section heading (h2) - `PageSectionDescription` - Supporting text below section title -- `PageSectionAside` - Container for section-level actions (should be inside PageSectionMeta, has `shrink-0`) +- `PageSectionAside` - Container for section-level actions (should be inside `PageSectionMeta`, has `shrink-0`) - `PageSectionContent` - Container for the main section content ## Orientation Variants @@ -45,3 +45,12 @@ fragment: true peekCode wide /> + +### Without Aside + + diff --git a/apps/design-system/content/docs/fragments/text-confirm-dialog.mdx b/apps/design-system/content/docs/fragments/text-confirm-dialog.mdx index f9127a0ebe7..4b812ead978 100644 --- a/apps/design-system/content/docs/fragments/text-confirm-dialog.mdx +++ b/apps/design-system/content/docs/fragments/text-confirm-dialog.mdx @@ -1,57 +1,73 @@ --- title: Text Confirm Dialog -description: A modal dialog that interrupts the user with important content and expects a response. +description: A modal dialog that adds a deliberate confirmation step for highly destructive actions. component: true --- - +Text Confirm Dialog adds a deliberate “speed bump” before a highly destructive action by requiring the user to type an exact confirmation string before the confirm action is enabled. It wraps the Shadcn [Dialog](../components/dialog) component and is intended for actions that must not be triggered accidentally. + +Use Text Confirm Dialog for irreversible operations such as deleting buckets, projects, or other critical resources where an explicit signal of user intent is required beyond a button click. + +For non-destructive or less critical confirmations, use [Alert Dialog](../components/alert-dialog) or [Confirmation Modal](../fragments/confirmation-modal) instead. See [Modality](../ui-patterns/modality) for guidance on choosing the appropriate dialog pattern. + + + +## Usage + +```tsx +'use client' + +import { useState } from 'react' +import { Button } from 'ui' +import TextConfirmModal from 'ui-patterns/Dialogs/TextConfirmModal' +``` + +```tsx +export default function TextConfirmDialogDemo() { + const [visible, setVisible] = useState(false) + const bucketName = 'profile-pictures' + + return ( + <> + + + setVisible(false)} + onCancel={() => setVisible(false)} + > + {/* Optional body content */} + + + ) +} +``` + +## Props + +- `confirmString`: The exact string the user must type to enable the confirm action +- `confirmPlaceholder`: Placeholder text shown in the confirmation input +- `variant`: Visual intent of the dialog (`default`, `destructive`, or `warning`) +- Other standard modal props inherited from the underlying [Dialog](../components/dialog) component ## Examples -### With Info Alert +### Cancel button - + -### With warning Alert +### Children - + -### With destructive Alert +### Size - - -### With cancel button - - - -### With children - - - -### With size - - + diff --git a/apps/design-system/content/docs/icons.mdx b/apps/design-system/content/docs/icons.mdx index 5e020a680d4..e0d0925e237 100644 --- a/apps/design-system/content/docs/icons.mdx +++ b/apps/design-system/content/docs/icons.mdx @@ -49,27 +49,30 @@ function app() { ### Adding new custom icons -To add a new custom icon to the Supabase icon library: +Follow these steps to add a new custom icon to the Supabase icon library. 1. **Create SVG file**: Add your SVG file to `packages/icons/src/raw-icons/` with a kebab-case name (e.g., `my-new-icon.svg`). Make sure it has follows these exact requirements: - Exported at 24x24px with `viewBox="0 0 24 24"` - Uses `stroke="currentColor"` for strokes (no hardcoded colors) + - Uses `stroke-width="1.5"` unless there is a good reason to deviate - Uses `fill="none"` for fills (no hardcoded colors) - Icon content is optically centered and around 18x18px within the 24x24 frame - Any unnecessary elements like ``, ``, and `` wrappers have been removed - SVG structure is as simple as possible with just `` elements -Just leave attributes like `stroke-width` as they are. The conversion to camel-case (for React compatibility) is handled by the below build process. +Leave attributes like `stroke-width` as they are. The conversion to camel-case for React compatibility (e.g. `strokeWidth`) is handled by the below build process. 2. **Build the component**: Run `npm run build:icons` from inside the `packages/icons` directory 3. **Use the icon**: Import and use like any other icon: - ```jsx - import { MyNewIcon } from 'icons' - ; - ``` +```tsx +import { MyNewIcon } from 'icons' +; +``` + +The icon name is automatically made available in camel-case, determined by the kebab-case input SVG. For example, `my-new-icon.svg` will become available as `MyNewIcon`. ### SVG design guidelines diff --git a/apps/design-system/content/docs/index.mdx b/apps/design-system/content/docs/index.mdx index 7e392c1b574..2d9559606e4 100644 --- a/apps/design-system/content/docs/index.mdx +++ b/apps/design-system/content/docs/index.mdx @@ -3,10 +3,11 @@ title: Introduction description: Components and patterns that you can copy and paste into Supabase apps. Accessible. Customizable. Open Source. --- +Welcome to the Supabase Design System! + ## FAQ - Why copy/paste and not packaged as a dependency? @@ -20,5 +21,28 @@ One of the drawback of packaging the components in an npm package is that the st + + + Which libraries do you use? + + + We use the following libraries as a basis. Anywhere we use additional libraries, we document them in the individual component pages. + + - [tailwindcss](https://tailwindcss.com) + - [shadcn/ui](https://ui.shadcn.com) + - [lucide-react](https://lucide.dev) + - [react-hook-form](https://react-hook-form.com) + You can find the full list of dependencies in the [package.json](https://github.com/supabase/design-system/blob/main/package.json) file. + + + + + + I was looking for Supabase UI Library + + + If you are looking for the Supabase UI, you can find it [here](https://supabase.com/ui). + + diff --git a/apps/design-system/content/docs/typography.mdx b/apps/design-system/content/docs/typography.mdx new file mode 100644 index 00000000000..d6c36ca61c3 --- /dev/null +++ b/apps/design-system/content/docs/typography.mdx @@ -0,0 +1,15 @@ +--- +title: Typography +description: An overview of all available typography CSS variables. +--- + +Some reusable patterns work better as CSS variables, or “shorthands”, than as components. Typography is one of these cases, since its usage and context vary widely. + +The shorthands below are composed of core [Tailwind utility classes](../docs/tailwind-classes). You can view the full list of shorthands in [`typography.scss`](https://github.com/supabase/supabase/blob/master/apps/studio/styles/typography.scss). + +## Shorthands + +| Value | Usage | +| ------------------ | ---------------------------------------------------------------------------- | +| `text-code-inline` | Apply to a `code` element for inline code or similar custom inline content | +| `text-brand-link` | Supabase green text that meets contrast requirements in light and dark modes | diff --git a/apps/design-system/content/docs/ui-patterns/accessibility.mdx b/apps/design-system/content/docs/ui-patterns/accessibility.mdx deleted file mode 100644 index 267d8089138..00000000000 --- a/apps/design-system/content/docs/ui-patterns/accessibility.mdx +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Accessibility -description: Make Supabase work for everyone. ---- - -Accessibility is about making an interface work for as many people as possible across as many circumstances as possible. All of us lean on affordances that accessible experiences provide: - -- Keyboard navigation -- Legible and resizable elements -- Large tap targets -- Clear and simple language - -## Checklist - -About to push some code? At a minimum, check your work against this list: - -- Are interactive page elements [keyboard-focusable](#focus-management)? -- Are all elements announcable by a [screen reader](#screen-reader-support)? -- Are textual elements legible and scalable? -- Can I use this on a smaller and/or older device? - -## Focus management - -All interactive page elements should be reachable by keyboard. They should also provide visual feedback upon selection via a `focus-visible` state. We use consistent focus styles such as `inset-focus` so users recognize this state instantly. - -```jsx - -

{name}

- -
-``` - -Consider also affordances like `ctrl` and `meta` key support for opening in a new tab. Anything that you can do with a mouse input should be replicable by keyboard. - -## Screen reader support - -Textual elements are supported out-of-the-box by screen readers. Imagery of course should be described by `alt` tags. - -Less obvious however are scaffolding elements that only makes sense visually, when paired with other content. For example: a table column for actions may not have a visual _Actions_ label because its purpose is obvious to a sighted person. For everyone else’s sake, this column should be titled with `sr-only` text: - -```jsx - - Actions - -``` diff --git a/apps/design-system/content/docs/ui-patterns/charts.mdx b/apps/design-system/content/docs/ui-patterns/charts.mdx new file mode 100644 index 00000000000..ef2b6cf8ad9 --- /dev/null +++ b/apps/design-system/content/docs/ui-patterns/charts.mdx @@ -0,0 +1,281 @@ +--- +title: Charts +description: Composable charts for Reports, Dashboards and other visualizations. +links: + doc: https://recharts.github.io/en-US/ +source: + recharts: true +--- + + + +## About + +Charts are an integral part of Observability at Supabase. Charts aim to be composable and reusable for frictionless setup. + +Our charts use a combination of our own presentational components and [Recharts](https://recharts.github.io/en-US/) for extensibility. + +## Best Practices + +1. **Use provided chart types first**: Always try to use the default provided charts first, otherwise passing Recharts compoennts to `` is possible but not recommended to avoid complexity. + +2. **Use the `useChart` context to show loading and disabled states**: The `useChart` context provides boolean flags for child components to show `isLoading` and `isDisabled` states. + +3. **Keep it simple**: Try to avoid abstracting the chart content too much. These components should cover most of your presentational needs. + +## Examples + +### Basic Chart Types + + + +### Chart States + + + +### Charts as Standalone Metrics + + + +### Charts with Actions + + + +### Chart with Table + + + +You can pass through our [Table](/docs/components/table) component to the `ChartFooter` and expect it to be styled correctly. There is no additional need to style the table, `ChartFooter` will handle the styling for you. + +## API + +### Chart + +The root container component that provides chart context to all child components. + +| Prop | Type | Default | Description | +| ------------ | -------------------------------------- | ------- | ------------------------------------------------------------------ | +| `children` | `React.ReactNode` | - | Chart child components | +| `isLoading` | `boolean` | `false` | Shows loading state in child components via the `useChart` context | +| `isDisabled` | `boolean` | `false` | Disables chart interactions via the `useChart` context | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartCard + +A card wrapper for the chart. Can be used as a Card component or as a slot. + +| Prop | Type | Default | Description | +| ----------- | -------------------------------------- | ------- | ----------------------------------------------------------------------------- | +| `children` | `React.ReactNode` | - | Chart content | +| `asChild` | `boolean` | - | Render as child component (uses Slot) - ideal for removing the `Card` wrapper | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartHeader + +Container for chart header content like title and actions. + +| Prop | Type | Default | Description | +| ----------- | -------------------------------------- | ---------- | ------------------------------------------------------------------- | +| `children` | `React.ReactNode` | - | Header content (typically ChartTitle, ChartActions, or ChartMetric) | +| `align` | `'start' \| 'center'` | `'center'` | Alignment of header content | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartTitle + +Displays the chart title with optional tooltip. + +| Prop | Type | Default | Description | +| ----------- | -------------------------------------- | ------- | ------------------------------------- | +| `children` | `React.ReactNode` | - | Title text | +| `tooltip` | `string` | - | Tooltip text shown on help icon hover | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartActions + +Renders action buttons or links in the chart header. + +| Prop | Type | Default | Description | +| ----------- | -------------------------------------- | ------- | ---------------------------------------------------------- | +| `actions` | `ChartAction[]` | - | Array of action objects (see ChartAction type below) | +| `children` | `React.ReactNode` | - | Custom action content (takes precedence over actions prop) | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +#### ChartAction Type + +| Property | Type | Description | +| ----------- | -------------------- | ----------------------------------------------- | +| `label` | `string` | Accessible label for the action | +| `icon` | `React.ReactNode` | Icon component to display | +| `onClick` | `() => void` | Click handler for button actions | +| `href` | `string` | URL for link actions | +| `type` | `'button' \| 'link'` | Action type (auto-detected if href is provided) | +| `className` | `string` | Additional CSS classes | + +### ChartMetric + +Displays a metric value with optional status indicator. + +| Prop | Type | Default | Description | +| ----------- | ---------------------------------------------------- | --------- | --------------------------------------------------- | +| `label` | `string` | - | Metric label text | +| `value` | `string \| number \| null \| undefined` | - | Metric value to display | +| `diffValue` | `string \| number \| null \| undefined` | - | Differential value to display (shown as +/- change) | +| `status` | `'positive' \| 'negative' \| 'warning' \| 'default'` | - | Status indicator color | +| `align` | `'start' \| 'end'` | `'start'` | Alignment of the metric | +| `tooltip` | `string` | - | Tooltip text shown on help icon hover | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartContent + +Container for the main chart visualization. Handles loading and empty states. + +| Prop | Type | Default | Description | +| ----------------- | -------------------------------------- | ------- | -------------------------------------- | +| `children` | `React.ReactNode` | - | Chart visualization content | +| `isEmpty` | `boolean` | `false` | Whether to show empty state | +| `emptyState` | `React.ReactNode` | - | Custom empty state component | +| `loadingState` | `React.ReactNode` | - | Custom loading state component | +| `disabledState` | `React.ReactNode` | - | Custom disabled state component | +| `disabledActions` | `ChartAction[]` | - | Actions to show when chart is disabled | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartEmptyState + +Pre-built empty state component for charts. + +| Prop | Type | Default | Description | +| ------------- | -------------------------------------- | ------- | ------------------------ | +| `title` | `string` | - | Empty state title | +| `description` | `string` | - | Empty state description | +| `icon` | `React.ReactNode` | - | Optional icon to display | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartLoadingState + +Pre-built loading state component. Takes no props. + +### ChartFooter + +Container for footer content below the chart. + +| Prop | Type | Default | Description | +| ----------- | -------------------------------------- | ------- | ---------------------- | +| `children` | `React.ReactNode` | - | Footer content | +| `className` | `string` | - | Additional CSS classes | +| `...props` | `React.HTMLAttributes` | - | All standard div props | + +### ChartConfig + +Type definition for chart configuration used with Recharts components. + +```tsx +type ChartConfig = { + [key: string]: { + label?: React.ReactNode + icon?: React.ComponentType + } & ( + | { color?: string; theme?: never } + | { color?: never; theme: Record<'light' | 'dark', string> } + ) +} +``` + +| Property | Type | Description | +| -------- | ----------------------------------- | -------------------------------------------------------- | +| `label` | `React.ReactNode` | Label for the data series | +| `icon` | `React.ComponentType` | Icon component for the data series | +| `color` | `string` | Single color value (mutually exclusive with theme) | +| `theme` | `Record<'light' \| 'dark', string>` | Theme-aware color values (mutually exclusive with color) | + +### ChartLine + +Line chart component for displaying time-series data. + +| Prop | Type | Default | Description | +| ------------------- | --------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- | +| `data` | `ChartLineTick[]` | - | Array of data points with timestamp | +| `dataKey` | `string` | - | Key in data object to plot | +| `config` | `ChartConfig?` | - | Chart configuration for styling | +| `onLineClick` | `(datum: ChartLineTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for line points | +| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | +| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | +| `className` | `string` | - | Additional CSS classes | +| `color` | `string` | `'hsl(var(--brand-default))'` | Line color | +| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Line color on hover | +| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | +| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | +| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | +| `syncId` | `string` | - | ID to sync multiple charts | +| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | +| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | +| `showGrid` | `boolean` | `false` | Whether to show grid lines | +| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | +| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | +| `strokeWidth` | `number` | `1.5` | Line stroke width | + +#### ChartLineTick Type + +| Property | Type | Description | +| --------------- | ------------------ | ---------------------------- | +| `timestamp` | `string` | Timestamp for the data point | +| `[key: string]` | `string \| number` | Additional data fields | + +#### ChartHighlight Type + +| Property | Type | Description | +| ----------------- | ------------------------------------------------------------- | ------------------------------------ | +| `handleMouseDown` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse down handler | +| `handleMouseMove` | `(e: { activeLabel?: string; coordinates?: string }) => void` | Mouse move handler | +| `handleMouseUp` | `(e: { chartX?: number; chartY?: number }) => void` | Mouse up handler | +| `coordinates` | `{ left?: string; right?: string }` | Highlight area coordinates | +| `clearHighlight` | `() => void?` | Optional function to clear highlight | + +#### ChartHighlightAction Type + +| Property | Type | Description | +| ------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------- | +| `id` | `string` | Unique identifier for the action | +| `label` | `string \| ((ctx: { start: string; end: string; clear: () => void }) => string)` | Action label or function that returns label | +| `icon` | `ReactNode?` | Optional icon component | +| `isDisabled` | `(ctx: { start: string; end: string; clear: () => void }) => boolean?` | Optional function to determine if action is disabled | +| `onSelect` | `(ctx: { start: string; end: string; clear: () => void }) => void` | Action selection handler | + +### ChartBar + +Bar chart component for displaying time-series data. + +| Prop | Type | Default | Description | +| ------------------- | -------------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------- | +| `data` | `ChartBarTick[]` | - | Array of data points with timestamp | +| `dataKey` | `string` | - | Key in data object to plot | +| `config` | `ChartConfig?` | - | Chart configuration for styling | +| `onBarClick` | `(datum: ChartBarTick, tooltipData?: CategoricalChartState) => void` | - | Click handler for bars | +| `DateTimeFormat` | `string` | `'MMM D, YYYY, hh:mma'` | Date format for tooltips and labels | +| `isFullHeight` | `boolean` | `false` | Whether chart should take full height | +| `className` | `string` | - | Additional CSS classes | +| `color` | `string` | `'hsl(var(--brand-default))'` | Bar color | +| `hoverColor` | `string` | `'hsl(var(--brand-500))'` | Bar color on hover | +| `chartHighlight` | `ChartHighlight` | - | Highlight selection configuration | +| `updateDateRange` | `(from: string, to: string) => void` | - | Callback when date range is updated via highlight | +| `highlightActions` | `ChartHighlightAction[]` | - | Actions to show when area is highlighted | +| `syncId` | `string` | - | ID to sync multiple charts | +| `showHighlightArea` | `boolean` | `true` | Whether to show highlight area | +| `cursor` | `string` | - | Cursor style (defaults to 'crosshair' if chartHighlight provided) | +| `showGrid` | `boolean` | `false` | Whether to show grid lines | +| `showYAxis` | `boolean` | `false` | Whether to show Y-axis | +| `YAxisProps` | `object` | - | Additional Y-axis props (tick, tickFormatter, width, etc.) | + +#### ChartBarTick Type + +| Property | Type | Description | +| --------------- | ------------------ | ---------------------------- | +| `timestamp` | `string` | Timestamp for the data point | +| `[key: string]` | `string \| number` | Additional data fields | diff --git a/apps/design-system/content/docs/ui-patterns/empty-states.mdx b/apps/design-system/content/docs/ui-patterns/empty-states.mdx index 53a3a8d96be..f4dc21628e5 100644 --- a/apps/design-system/content/docs/ui-patterns/empty-states.mdx +++ b/apps/design-system/content/docs/ui-patterns/empty-states.mdx @@ -3,50 +3,30 @@ title: Empty states description: Convey the absence of data and provide clear instruction for what to do about it. --- -Empty states convey the fact that there is nothing to list, perform, or display on the current page. **Ideally**, they also provide a clear action for the user to take. +Empty states convey the fact that there is nothing to list, perform, or display on the current page. Ideally, they also provide a clear action for the user to take. -## Missing route +## Best practices -Users may accidentally navigate to a non-existent dynamic route, such as a non-existent bucket in [Storage](https://supabase.com/dashboard/project/_/storage) or a non-existent table in the [Table Editor](https://supabase.com/dashboard/project/_/editor). In these cases, follow the pattern of a centered [Admonition](../fragments/admonition) as shown below. - - - -## No data +### No data There are two ways an empty state may be displayed in cases where there is no data: -- **Zero results**: no data after a search or filter - **Initial state**: no data to begin with +- **Zero results**: no data after a search or filter -### Zero results +#### Initial state -Data-heavy presentations without results should have an empty state that broadly matches the state when there is data. This makes the transition between the two states more seamless. +Perhaps the user has not yet created any data. The presentation of this empty state depends on the context of the list and the type of data it contains. Be mindful of the journey to rendering an empty state and any possible layout shift along the way. -#### Table +##### Presentational -A [Table](../components/table) instance with zero results should display a single row. Dulling the TableHead text color and removing the TableCell hover state can further reinforce the lack of usable data. +The user may be learning about a feature for the first time, and could benefit from lightweight feature education or onboarding. Use the dedicated [Empty State Presentational](../fragments/empty-state-presentational) component in this case, putting emphasis on an action the user can take. - + -#### DataGrid +Remember to use active language in presentational empty states. For example: “Create a vector bucket” instead of “No vector buckets found”. The latter is more appropriate in table-based presentations, as described below. -[DataGrid](../components/data-table) typically spans the full height and width of a container. A classic example is [Users](https://supabase.com/dashboard/project/_/auth/users), which (as it sounds) displays a list of the project’s registered users. Any instance with zero results should display a more prominent empty with a clear title, description, and supporting illustration. - - - -Other DataGrid instances include [Cron Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) and [Queues](https://supabase.com/dashboard/project/_/integrations/queues). - -### Initial state - -Perhaps the user has not yet created any data. The presentation of this empty state depends on the context of the list and the type of data it contains. - -#### Presentational - -The user may be learning about a feature for the first time, and this experience benefits from user education or onboarding. In cases like these, the empty state should put more focus on the feature’s value proposition and an action the user can take. - - - -#### Informational +##### Informational Or perhaps the list type is data-heavy or does not benefit from additional information. In these cases, the empty state should provide show the initial state in the same presentation as the list when there is data, much like the [zero results](#zero-results) scenario. @@ -54,10 +34,37 @@ Or perhaps the list type is data-heavy or does not benefit from additional infor Keep in mind that empty states will likely appear after a visual loading state. Consider layout shift and button placement during and after the transition. +#### Zero results + +Data-heavy presentations without results should have an empty state that broadly matches the state when there is data. This makes the transition between the two states more seamless. + +##### Table + +A [Table](../components/table) instance with zero results should display a single row. Dulling the TableHead text color and removing the TableCell hover state can further reinforce the lack of usable data. + + + +Studio contains two pre-built components to handle these cases consistently: + +- No Filter Results +- No Search Results + +##### Data Grid + +[Data Grid](../ui-patterns/tables#data-grid) and [Data Table](../ui-patterns/tables#data-table) component patterns typically span the full height and width of a container. A classic example is [Users](https://supabase.com/dashboard/project/_/auth/users), which (as it sounds) displays a list of the project’s registered users. Any instance with zero results should display a more prominent empty with a clear title, description, and supporting illustration. + + + +Other Data Grid instances include [Cron Jobs](https://supabase.com/dashboard/project/_/integrations/cron/jobs) and [Queues](https://supabase.com/dashboard/project/_/integrations/queues). + +### Missing route + +Users may accidentally navigate to a non-existent dynamic route, such as a non-existent bucket in [Storage](https://supabase.com/dashboard/project/_/storage) or a non-existent table in the [Table Editor](https://supabase.com/dashboard/project/_/editor). In these cases, follow the pattern of a centered [Admonition](../fragments/admonition) as shown below. + + + ## Components -There is not yet a shared empty state UI component. The context and needs for each placement differ enough to warrant custom components for each placement. +For presentational empty states (initial states with value propositions and actions), use the [Empty State Presentational](../fragments/empty-state-presentational) component from `ui-patterns`. This component provides a consistent structure with support for icons, titles, descriptions, and action buttons. -## External references - -- [_Empty States_ on GitHub Primer](https://primer.style/product/ui-patterns/empty-states/) +For other empty state scenarios (zero results, missing routes, etc), custom components may still be appropriate as the context and needs for each placement can differ significantly. diff --git a/apps/design-system/content/docs/ui-patterns/forms.mdx b/apps/design-system/content/docs/ui-patterns/forms.mdx new file mode 100644 index 00000000000..eb71580c536 --- /dev/null +++ b/apps/design-system/content/docs/ui-patterns/forms.mdx @@ -0,0 +1,50 @@ +--- +title: Forms +description: Common form patterns used in Studio settings pages and side panels. +--- + +Forms in Supabase Studio should follow consistent patterns to ensure a cohesive user experience across settings pages and side panels. This guide covers the most common form patterns and field types. + +## Page Layout + +Forms in page layouts typically use `PageSection` components with `Card` containers. Fields use `FormItemLayout` with `layout="flex-row-reverse"` for horizontal alignment. + + + +## Side Panel + +Forms in side panels (Sheets) use `FormItemLayout` with `layout="horizontal"` on wider panels and `layout="vertical"` on panels with a size of `sm` or below. The form is typically wrapped in a `Sheet` component. + + + +## Best Practices + +1. **Always use FormItemLayout**: Use `FormItemLayout` instead of manually composing `FormItem`, `FormLabel`, `FormMessage`, and `FormDescription`. + +2. **Layout selection**: + + - Use `layout="flex-row-reverse"` for page layouts (horizontal alignment) + - Use `layout="horizontal"` for side panels with more width + - Use `layout="vertical"` for side panels with limited width + +3. **Wrap inputs in FormControl*Shadcn***: Always wrap form inputs with `FormControl_Shadcn_` to ensure proper form integration. + +4. **Use Cards for grouping**: Wrap form sections in `Card` components with `CardContent` and `CardFooter` for actions. + +5. **Handle dirty state**: Show cancel buttons and disable save buttons based on `form.formState.isDirty`. + +6. **Error handling**: Always use mutations with `onSuccess` and `onError` callbacks that show toast notifications. + +7. **Loading states**: Show loading states on submit buttons using the `loading` prop. + +8. **Form IDs**: When submit buttons are outside the form, use a form ID and reference it with the `form` prop on the button. diff --git a/apps/design-system/content/docs/ui-patterns/introduction.mdx b/apps/design-system/content/docs/ui-patterns/introduction.mdx new file mode 100644 index 00000000000..b89667e7750 --- /dev/null +++ b/apps/design-system/content/docs/ui-patterns/introduction.mdx @@ -0,0 +1,16 @@ +--- +title: UI patterns +description: Higher-level guidance on how to compose components together to solve common interface problems. +--- + +UI patterns are reusable design solutions that combine multiple components from our design system to address common interface challenges. Unlike atom components (basic building blocks like buttons and inputs) or fragment components (pre-built composite components), UI patterns provide guidelines and best practices for structuring entire interface sections. + +These patterns help ensure consistency across Supabase products by establishing standard approaches for: + +- **[Charts](/docs/ui-patterns/charts)**: Visualizing data consistently using standardized chart types and styling. +- **[Empty States](/docs/ui-patterns/empty-states)**: Communicating the absence of data and guiding users toward meaningful actions. +- **[Forms](/docs/ui-patterns/forms)**: Building cohesive form experiences in both page layouts and side panels. +- **[Layout](/docs/ui-patterns/layout)**: Creating consistent page structures with proper spacing, max-widths, and content organization. +- **[Navigation](/docs/ui-patterns/navigation)**: Organizing complex hierarchical navigation systems across multiple products and contexts. + +UI patterns may incorporate external libraries (such as `react-markdown`, `reactflow`, `recharts`, etc) or compose various components from the `ui` package. They serve as blueprints for solving recurring design problems, ensuring that similar features across the application follow the same structural and interaction patterns. diff --git a/apps/design-system/content/docs/ui-patterns/layout.mdx b/apps/design-system/content/docs/ui-patterns/layout.mdx index e69716e597e..4ee7a5bb1cb 100644 --- a/apps/design-system/content/docs/ui-patterns/layout.mdx +++ b/apps/design-system/content/docs/ui-patterns/layout.mdx @@ -75,6 +75,6 @@ Detail pages display dense or lengthy content split into multiple sections. The ## Components -- **[PageContainer](/docs/fragments/page-container)** - Container component providing consistent max-width and padding based on size variants -- **[PageHeader](/docs/fragments/page-header)** - Compound component for building page headers with breadcrumbs, icons, titles, descriptions, actions, and navigation -- **[PageSection](/docs/fragments/page-section)** - Compound component for organizing page content into distinct sections with title, description, and action areas +- **[Page Container](../fragments/page-container)**: Container component providing consistent max-width and padding based on size variants +- **[Page Header](../fragments/page-header)**: Compound component for building page headers with breadcrumbs, icons, titles, descriptions, actions, and navigation +- **[Page Section](../fragments/page-section)**: Compound component for organizing page content into distinct sections with title, description, and action areas diff --git a/apps/design-system/content/docs/ui-patterns/modality.mdx b/apps/design-system/content/docs/ui-patterns/modality.mdx new file mode 100644 index 00000000000..3da04913adf --- /dev/null +++ b/apps/design-system/content/docs/ui-patterns/modality.mdx @@ -0,0 +1,76 @@ +--- +title: Modality +description: Present ephemeral information and demand action. +--- + +Modal elements interrupt the user’s current task to ask for input, a decision, or focused attention. They appear at the top of the visual stack and (by default) render everything beneath them inactive. + +Given their highly interruptive nature, modal elements should be used sparingly. Common use cases include: + +- Requiring confirmation from the user +- Requiring an ephemeral form submission from the user before an action can be completed +- Alerting or slowing the user down before a destructive action + +We have two main ways of handling modality: + +- [Dialogs](#dialogs) +- [Sheets](#sheets) + +As a general rule: use dialogs for short, focused tasks and use sheets for longer forms or more detailed views. + +## Dialogs + +Dialogs are centered overlays used for short, focused tasks. All dialogs should follow these best practices: + +- **Reiterative:** Dialog header and confirmation button text and should match the action and flow on from the entry point. +- **Simple:** No layered elements like subtitles or admonitions unless necessary. Put all the focus on the actions to get out of the dialog. +- **Accessible:** Always provide clear labels and descriptions via semantic HTML and the correct ARIA attributes. Ensure keyboard navigation works correctly. + +### Components + +There are quite a few dialog components, each suited to a different task or context: + +- [Alert Dialog](../components/alert-dialog) contains a single, short paragraph and an explicit action. +- [Text Confirm Dialog](../fragments/text-confirm-dialog) requires a textual response before the action is enabled. +- [Confirmation Modal](../fragments/confirmation-modal) provides more flexible dialog body contents. +- [Dialog](../components/dialog) is a generalized component for bespoke purposes. + +#### Alert Dialog + +[Alert Dialog](../components/alert-dialog) is used to confirm or acknowledge a critical action with a single, short paragraph and a clear decision. + + + +#### Text Confirm Dialog + +[Text Confirm Dialog](../fragments/text-confirm-dialog) adds a deliberate speed bump for highly destructive actions by requiring the user to type an exact confirmation string before proceeding. + + + +#### Confirmation Modal + +[Confirmation Modal](../fragments/confirmation-modal) is a convenience wrapper for less-critical confirmations that require more than a single paragraph, such as additional context, callouts, or simple form elements. + + + +#### Dialog + +[Dialog](../components/dialog) is a general-purpose modal for bespoke flows such as forms, pickers, or non-critical interactions where dismissal is acceptable. + + + +## Sheets + +Sheets are dialogs presented as side panels. Use them for content that is larger than a few fields, or when a centered dialog would feel cramped. + +- **Use for**: multi-field forms, editors, settings panels, and detailed views. +- **Prefer the default**: sheets slide in from the right unless you have a strong reason to use another side. +- **Group content**: use header/sections/footer so the user can scan and act quickly. + +### Components + +#### Sheet + +[Sheet](../components/sheet) is modal by default, blocking interaction with the underlying page. + + diff --git a/apps/design-system/content/docs/ui-patterns/tables.mdx b/apps/design-system/content/docs/ui-patterns/tables.mdx new file mode 100644 index 00000000000..84f4df000f5 --- /dev/null +++ b/apps/design-system/content/docs/ui-patterns/tables.mdx @@ -0,0 +1,83 @@ +--- +title: Tables +description: Display structured data in a scannable, organized way. +--- + +Tables are a fundamental pattern for displaying structured data in rows and columns. They provide a scannable, organized way to present collections of related information, making it easy for users to compare values, identify patterns, and take action on specific items. + +The choice of table pattern depends on several factors: the complexity of the data, the level of interactivity required, the amount of data being displayed, and the context within the page layout. + +## Components + +There are three main table patterns, each suited to different use cases: + +- [Table](../components/table) is a low-level, presentational table component. +- [Data Table](#data-table) builds on [Table](../components/table) and [TanStack Table](https://tanstack.com/table) to provide a feature-rich data browsing experience (sorting, filtering, pagination, etc.). +- [Data Grid](#data-grid) is a separate grid implementation used for highly interactive, spreadsheet-like surfaces and very large datasets. + +Use Table when: + +- You need simple, static display +- No filtering or complex behavior is needed + +Use Data Table when: + +- You need sorting, pagination, filtering, search, or row actions +- You want TanStack-powered behavior with table semantics + +Use Data Grid when: + +- You need virtualization today +- You need column resizing +- You need spreadsheet-like editing + +Data Table and Data Grid are both _pattern components_: they are composed from primitives and built per use case. They are not available as standalone components. + +### Table + +[Table](../components/table) is designed for simple, static tabular data presentation. It is a presentational wrapper around the HTML `
` element. Use it when: + +- Displaying a fixed, known number of rows +- The data is primarily read-only +- Sort, filter, or search actions are not required or can be basic + + + +### Data Table + +Data Table is a pattern component and is not exposed as a Design System component. It is built on top of [Table](../components/table) and [TanStack Table](https://tanstack.com/table). + +Data Table extends Table with column definitions and row models (via TanStack) for complex sorting, filtering, and row actions. Use it when: + +- Displaying large datasets that require pagination +- Users need to perform complex sort, filter, or search actions through the data +- Row selection is required + +Data Table does not yet support virtualization, resizable columns, or advanced editors. These capabilities are planned as part of [consolidation with Data Grid](#future). + + + +As you can see from the above example, Data Table’s composition is heavily dependent on use case. We do not yet have a shared Design System component for this reason. + +Follow [Shadcn’s Data Table documentation](https://ui.shadcn.com/docs/components/data-table) for a complete guide on building upon the Data Table pattern for each specific use case. These patterns map closely to the approaches we follow internally. + +### Data Grid + +Data Grid is a pattern component and is not exposed as a Design System component. It is based on [React Data Grid](https://comcast.github.io/react-data-grid/#/CommonFeatures) and originally adopted for areas including Studio’s Table Editor, Query Performance, and other high-interaction surfaces. + +Use it only when you need virtualization, column resizing, or complex cell editing. Otherwise [Data Table](#data-table) is simpler and more flexible. + + + +## Future + +Data Table and Data Grid overlap significantly. We’re looking at consolidating these into one data table component, which will likely be improvements to Data Table given the numerous advantages of TanStack Table and difficulties extending React Data Grid. + +The likely direction is a single Data Table component built on TanStack Table, with + +- Virtualization +- Resizable columns +- Plug-in cell editors +- Shared filtering/sorting utilities +- Shared UI patterns (horizontal and vertical filter bars, date pickers, side panels) +- Accessible, semantic HTML table markup diff --git a/apps/design-system/contentlayer.config.js b/apps/design-system/contentlayer.config.js index edc30b91b1d..f57e01f20db 100644 --- a/apps/design-system/contentlayer.config.js +++ b/apps/design-system/contentlayer.config.js @@ -53,6 +53,9 @@ const NestedProperties = defineNestedType(() => ({ reactAccessibleTreeview: { type: 'boolean', }, + recharts: { + type: 'boolean', + }, }, })) @@ -107,6 +110,7 @@ export const Doc = defineDocumentType(() => ({ export default makeSource({ contentDirPath: './content', + disableImportAliasWarning: true, documentTypes: [Doc], mdx: { remarkPlugins: [remarkGfm, codeImport], diff --git a/apps/design-system/context/mobile-sidebar-context.tsx b/apps/design-system/context/mobile-sidebar-context.tsx new file mode 100644 index 00000000000..d746a355b36 --- /dev/null +++ b/apps/design-system/context/mobile-sidebar-context.tsx @@ -0,0 +1,34 @@ +'use client' + +import React, { ReactNode, useState, useCallback } from 'react' +import { MobileSidebarContext, MobileSidebarContextType } from '@/hooks/use-mobile-sidebar' + +interface MobileSidebarProviderProps { + children: ReactNode +} + +/** + * Provider component for mobile sidebar state + * Wraps children with context that provides mobile sidebar state and controls + */ +export function MobileSidebarProvider({ children }: MobileSidebarProviderProps) { + const [open, setOpen] = useState(false) + + // Use useCallback for stable function references + const handleSetOpen = useCallback((value: boolean) => { + setOpen(value) + }, []) + + const toggle = useCallback(() => { + setOpen((prev) => !prev) + }, []) + + // Memoize the context value to prevent unnecessary re-renders + const value: MobileSidebarContextType = { + open, + setOpen: handleSetOpen, + toggle, + } + + return {children} +} diff --git a/apps/design-system/eslint.config.cjs b/apps/design-system/eslint.config.cjs index fec3ac9b3ab..4f1bc5e2275 100644 --- a/apps/design-system/eslint.config.cjs +++ b/apps/design-system/eslint.config.cjs @@ -1,4 +1,12 @@ const { defineConfig } = require('eslint/config') const supabaseConfig = require('eslint-config-supabase/next') -module.exports = defineConfig([supabaseConfig]) +module.exports = defineConfig([ + supabaseConfig, + { + files: ['registry/**/*.tsx', '__registry__/**/*.tsx', 'app/**/*.tsx'], + rules: { + 'no-restricted-exports': 'off', + }, + }, +]) diff --git a/apps/design-system/hooks/use-mobile-sidebar.ts b/apps/design-system/hooks/use-mobile-sidebar.ts new file mode 100644 index 00000000000..dc6294823cb --- /dev/null +++ b/apps/design-system/hooks/use-mobile-sidebar.ts @@ -0,0 +1,24 @@ +'use client' + +import { createContext, useContext } from 'react' + +export interface MobileSidebarContextType { + open: boolean + setOpen: (open: boolean) => void + toggle: () => void +} + +export const MobileSidebarContext = createContext(null) + +export function useMobileSidebar(): MobileSidebarContextType { + const context = useContext(MobileSidebarContext) + + if (context === null) { + throw new Error( + 'useMobileSidebar must be used within a MobileSidebarProvider. ' + + 'Ensure your component is wrapped with MobileSidebarProvider.' + ) + } + + return context +} diff --git a/apps/design-system/lib/rehype-component.ts b/apps/design-system/lib/rehype-component.ts index adc038328ea..9efbc93cc93 100644 --- a/apps/design-system/lib/rehype-component.ts +++ b/apps/design-system/lib/rehype-component.ts @@ -1,16 +1,12 @@ import fs from 'fs' import path from 'path' -import { UnistNode, UnistTree } from 'types/unist' +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 @@ -38,61 +34,6 @@ export function rehypeComponent() { 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 - // }) =>
{{name}}
; - // ` - // // 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! diff --git a/apps/design-system/lib/rehype-npm-command.ts b/apps/design-system/lib/rehype-npm-command.ts index aaa3792922f..7b50e4ee696 100644 --- a/apps/design-system/lib/rehype-npm-command.ts +++ b/apps/design-system/lib/rehype-npm-command.ts @@ -1,4 +1,4 @@ -import { UnistNode, UnistTree } from 'types/unist' +import { UnistNode, UnistTree } from '@/types/unist' import { visit } from 'unist-util-visit' export function rehypeNpmCommand() { diff --git a/apps/design-system/package.json b/apps/design-system/package.json index b79fa890b5f..aa0c8da1057 100644 --- a/apps/design-system/package.json +++ b/apps/design-system/package.json @@ -18,9 +18,10 @@ }, "dependencies": { "@hookform/resolvers": "^3.1.1", + "@tanstack/react-table": "^8.21.3", "contentlayer2": "0.4.6", - "dayjs": "1.11.13", "date-fns": "^2.30.0", + "dayjs": "1.11.13", "eslint-config-supabase": "workspace:*", "icons": "workspace:*", "jotai": "^2.8.0", @@ -32,7 +33,6 @@ "react": "catalog:", "react-data-grid": "7.0.0-beta.41", "react-day-picker": "^9.11.1", - "react-docgen": "^7.0.3", "react-dom": "catalog:", "react-hook-form": "^7.45.0", "react-inlinesvg": "^4.0.4", diff --git a/apps/design-system/public/img/design-system-marks/atoms--classic-dark.svg b/apps/design-system/public/img/design-system-marks/atoms--classic-dark.svg new file mode 100644 index 00000000000..fc893c54795 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/atoms--classic-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/atoms--dark.svg b/apps/design-system/public/img/design-system-marks/atoms--dark.svg new file mode 100644 index 00000000000..07fb5880c21 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/atoms--dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/design-system/public/img/design-system-marks/atoms--light.svg b/apps/design-system/public/img/design-system-marks/atoms--light.svg new file mode 100644 index 00000000000..19079cdd792 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/atoms--light.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/colours--classic-dark.svg b/apps/design-system/public/img/design-system-marks/colours--classic-dark.svg new file mode 100644 index 00000000000..40c1a337921 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/colours--classic-dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/colours--dark.svg b/apps/design-system/public/img/design-system-marks/colours--dark.svg new file mode 100644 index 00000000000..40c1a337921 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/colours--dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/colours--light.svg b/apps/design-system/public/img/design-system-marks/colours--light.svg new file mode 100644 index 00000000000..e0b69022678 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/colours--light.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/fragments--classic-dark.svg b/apps/design-system/public/img/design-system-marks/fragments--classic-dark.svg new file mode 100644 index 00000000000..8428d72d4a2 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/fragments--classic-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/fragments--dark.svg b/apps/design-system/public/img/design-system-marks/fragments--dark.svg new file mode 100644 index 00000000000..7444f87a553 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/fragments--dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/fragments--light.svg b/apps/design-system/public/img/design-system-marks/fragments--light.svg new file mode 100644 index 00000000000..7444f87a553 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/fragments--light.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/logo--classic-dark.svg b/apps/design-system/public/img/design-system-marks/logo--classic-dark.svg new file mode 100644 index 00000000000..41259ccc0ea --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/logo--classic-dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/logo--dark.svg b/apps/design-system/public/img/design-system-marks/logo--dark.svg new file mode 100644 index 00000000000..7193f0ac5d9 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/logo--dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/logo--light.svg b/apps/design-system/public/img/design-system-marks/logo--light.svg new file mode 100644 index 00000000000..9fc83e3aa75 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/logo--light.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/ui-patterns--classic-dark.svg b/apps/design-system/public/img/design-system-marks/ui-patterns--classic-dark.svg new file mode 100644 index 00000000000..286fe636014 --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/ui-patterns--classic-dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/ui-patterns--dark.svg b/apps/design-system/public/img/design-system-marks/ui-patterns--dark.svg new file mode 100644 index 00000000000..958e9e9b78b --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/ui-patterns--dark.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/public/img/design-system-marks/ui-patterns--light.svg b/apps/design-system/public/img/design-system-marks/ui-patterns--light.svg new file mode 100644 index 00000000000..958e9e9b78b --- /dev/null +++ b/apps/design-system/public/img/design-system-marks/ui-patterns--light.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/design-system/registry/charts.ts b/apps/design-system/registry/charts.ts index be6ab4c2b48..9a42e5095a0 100644 --- a/apps/design-system/registry/charts.ts +++ b/apps/design-system/registry/charts.ts @@ -1,113 +1,6 @@ import { Registry } from './schema' export const charts: Registry = [ - // Area Charts - { - name: 'chart-area-axes', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-axes.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-default', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-default.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-gradient', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-gradient.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-icons', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-icons.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-interactive', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-interactive.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-legend', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-legend.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-linear', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-linear.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-stacked-expand', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-stacked-expand.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-stacked', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-stacked.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - { - name: 'chart-area-step', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-area-step.tsx'], - category: 'Charts', - subcategory: 'Area', - }, - - // Bar Charts - { - name: 'chart-bar-active', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-active.tsx'], - category: 'Charts', - subcategory: 'Bar', - }, - { - name: 'chart-bar-default', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-default.tsx'], - category: 'Charts', - subcategory: 'Bar', - }, - { - name: 'chart-bar-horizontal', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-horizontal.tsx'], - category: 'Charts', - subcategory: 'Bar', - }, { name: 'chart-bar-interactive', type: 'components:block', @@ -117,387 +10,51 @@ export const charts: Registry = [ subcategory: 'Bar', }, { - name: 'chart-bar-label-custom', + name: 'chart-composed-demo', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-label-custom.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-demo.tsx'], category: 'Charts', - subcategory: 'Bar', + subcategory: 'Composed', }, { - name: 'chart-bar-label', + name: 'chart-composed-basic', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-label.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-basic.tsx'], category: 'Charts', - subcategory: 'Bar', + subcategory: 'Composed', }, { - name: 'chart-bar-mixed', + name: 'chart-composed-states', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-mixed.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-states.tsx'], category: 'Charts', - subcategory: 'Bar', + subcategory: 'Composed', }, { - name: 'chart-bar-multiple', + name: 'chart-composed-table', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-multiple.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-table.tsx'], category: 'Charts', - subcategory: 'Bar', + subcategory: 'Composed', }, { - name: 'chart-bar-negative', + name: 'chart-composed-metrics', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-negative.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-metrics.tsx'], category: 'Charts', - subcategory: 'Bar', + subcategory: 'Composed', }, { - name: 'chart-bar-stacked', + name: 'chart-composed-actions', type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-bar-stacked.tsx'], + registryDependencies: ['chart'], + files: ['block/chart-composed-actions.tsx'], category: 'Charts', - subcategory: 'Bar', - }, - - // Line Charts - { - name: 'chart-line-default', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-default.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-dots-colors', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-dots-colors.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-dots-custom', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-dots-custom.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-dots', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-dots.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-interactive', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-interactive.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-label-custom', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-label-custom.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-label', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-label.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-linear', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-linear.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-multiple', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-multiple.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - { - name: 'chart-line-step', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-line-step.tsx'], - category: 'Charts', - subcategory: 'Line', - }, - - // Pie Charts - { - name: 'chart-pie-donut-active', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-donut-active.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-donut-text', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-donut-text.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-donut', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-donut.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-interactive', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-interactive.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-label-custom', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-label-custom.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-label-list', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-label-list.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-label', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-label.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-legend', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-legend.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-separator-none', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-separator-none.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-simple', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-simple.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - { - name: 'chart-pie-stacked', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-pie-stacked.tsx'], - category: 'Charts', - subcategory: 'Pie', - }, - - // Radar Charts - { - name: 'chart-radar-default', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-default.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-dots', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-dots.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-circle-fill', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-circle-fill.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-circle-no-lines', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-circle-no-lines.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-circle', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-circle.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-custom', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-custom.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-fill', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-fill.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-grid-none', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-grid-none.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-icons', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-icons.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-label-custom', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-label-custom.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-legend', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-legend.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-lines-only', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-lines-only.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-multiple', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-multiple.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - { - name: 'chart-radar-radius', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radar-radius.tsx'], - category: 'Charts', - subcategory: 'Radar', - }, - - // Radial Charts - { - name: 'chart-radial-grid', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-grid.tsx'], - category: 'Charts', - subcategory: 'Radial', - }, - { - name: 'chart-radial-label', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-label.tsx'], - category: 'Charts', - subcategory: 'Radial', - }, - { - name: 'chart-radial-shape', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-shape.tsx'], - category: 'Charts', - subcategory: 'Radial', - }, - { - name: 'chart-radial-simple', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-simple.tsx'], - category: 'Charts', - subcategory: 'Radial', - }, - { - name: 'chart-radial-stacked', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-stacked.tsx'], - category: 'Charts', - subcategory: 'Radial', - }, - { - name: 'chart-radial-text', - type: 'components:block', - registryDependencies: ['card', 'chart'], - files: ['block/chart-radial-text.tsx'], - category: 'Charts', - subcategory: 'Radial', + subcategory: 'Composed', }, ] diff --git a/apps/design-system/registry/copy-writing.ts b/apps/design-system/registry/copy-writing.ts new file mode 100644 index 00000000000..33afc906d80 --- /dev/null +++ b/apps/design-system/registry/copy-writing.ts @@ -0,0 +1,68 @@ +import { Registry } from './schema' + +export const copyWriting: Registry = [ + { + name: 'copy-button-verbs', + type: 'components:example', + files: ['example/copy-button-verbs.tsx'], + registryDependencies: ['button'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-form-labels', + type: 'components:example', + files: ['example/copy-form-labels.tsx'], + registryDependencies: ['form'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-error-messages', + type: 'components:example', + files: ['example/copy-error-messages.tsx'], + registryDependencies: ['form'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-success-messages', + type: 'components:example', + files: ['example/copy-success-messages.tsx'], + registryDependencies: ['form'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-tooltips', + type: 'components:example', + files: ['example/copy-tooltips.tsx'], + registryDependencies: ['tooltip'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-loading-states', + type: 'components:example', + files: ['example/copy-loading-states.tsx'], + registryDependencies: ['loading-state'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-empty-states', + type: 'components:example', + files: ['example/copy-empty-states.tsx'], + registryDependencies: ['empty-state'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, + { + name: 'copy-confirmations', + type: 'components:example', + files: ['example/copy-confirmations.tsx'], + registryDependencies: ['confirmation'], + category: 'Getting Started', + subcategory: 'Copywriting', + }, +] diff --git a/apps/design-system/registry/default/block/chart-area-axes.tsx b/apps/design-system/registry/default/block/chart-area-axes.tsx deleted file mode 100644 index 26713267cbd..00000000000 --- a/apps/design-system/registry/default/block/chart-area-axes.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An area chart with axes' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Axes - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-default.tsx b/apps/design-system/registry/default/block/chart-area-default.tsx deleted file mode 100644 index 0ccfe016d7c..00000000000 --- a/apps/design-system/registry/default/block/chart-area-default.tsx +++ /dev/null @@ -1,77 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A simple area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-gradient.tsx b/apps/design-system/registry/default/block/chart-area-gradient.tsx deleted file mode 100644 index d6e7ad9b621..00000000000 --- a/apps/design-system/registry/default/block/chart-area-gradient.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An area chart with gradient fill' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Gradient - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - - - - - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-icons.tsx b/apps/design-system/registry/default/block/chart-area-icons.tsx deleted file mode 100644 index bc9d0195253..00000000000 --- a/apps/design-system/registry/default/block/chart-area-icons.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingDown, TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'An area chart with icons' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: TrendingDown, - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - icon: TrendingUp, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Icons - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - } /> - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-interactive.tsx b/apps/design-system/registry/default/block/chart-area-interactive.tsx deleted file mode 100644 index df2579fe8f8..00000000000 --- a/apps/design-system/registry/default/block/chart-area-interactive.tsx +++ /dev/null @@ -1,238 +0,0 @@ -'use client' - -import * as React from 'react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' -import { - Select_Shadcn_, - SelectContent_Shadcn_, - SelectItem_Shadcn_, - SelectTrigger_Shadcn_, - SelectValue_Shadcn_, -} from 'ui' - -export const description = 'An interactive area chart' - -const chartData = [ - { date: '2024-04-01', desktop: 222, mobile: 150 }, - { date: '2024-04-02', desktop: 97, mobile: 180 }, - { date: '2024-04-03', desktop: 167, mobile: 120 }, - { date: '2024-04-04', desktop: 242, mobile: 260 }, - { date: '2024-04-05', desktop: 373, mobile: 290 }, - { date: '2024-04-06', desktop: 301, mobile: 340 }, - { date: '2024-04-07', desktop: 245, mobile: 180 }, - { date: '2024-04-08', desktop: 409, mobile: 320 }, - { date: '2024-04-09', desktop: 59, mobile: 110 }, - { date: '2024-04-10', desktop: 261, mobile: 190 }, - { date: '2024-04-11', desktop: 327, mobile: 350 }, - { date: '2024-04-12', desktop: 292, mobile: 210 }, - { date: '2024-04-13', desktop: 342, mobile: 380 }, - { date: '2024-04-14', desktop: 137, mobile: 220 }, - { date: '2024-04-15', desktop: 120, mobile: 170 }, - { date: '2024-04-16', desktop: 138, mobile: 190 }, - { date: '2024-04-17', desktop: 446, mobile: 360 }, - { date: '2024-04-18', desktop: 364, mobile: 410 }, - { date: '2024-04-19', desktop: 243, mobile: 180 }, - { date: '2024-04-20', desktop: 89, mobile: 150 }, - { date: '2024-04-21', desktop: 137, mobile: 200 }, - { date: '2024-04-22', desktop: 224, mobile: 170 }, - { date: '2024-04-23', desktop: 138, mobile: 230 }, - { date: '2024-04-24', desktop: 387, mobile: 290 }, - { date: '2024-04-25', desktop: 215, mobile: 250 }, - { date: '2024-04-26', desktop: 75, mobile: 130 }, - { date: '2024-04-27', desktop: 383, mobile: 420 }, - { date: '2024-04-28', desktop: 122, mobile: 180 }, - { date: '2024-04-29', desktop: 315, mobile: 240 }, - { date: '2024-04-30', desktop: 454, mobile: 380 }, - { date: '2024-05-01', desktop: 165, mobile: 220 }, - { date: '2024-05-02', desktop: 293, mobile: 310 }, - { date: '2024-05-03', desktop: 247, mobile: 190 }, - { date: '2024-05-04', desktop: 385, mobile: 420 }, - { date: '2024-05-05', desktop: 481, mobile: 390 }, - { date: '2024-05-06', desktop: 498, mobile: 520 }, - { date: '2024-05-07', desktop: 388, mobile: 300 }, - { date: '2024-05-08', desktop: 149, mobile: 210 }, - { date: '2024-05-09', desktop: 227, mobile: 180 }, - { date: '2024-05-10', desktop: 293, mobile: 330 }, - { date: '2024-05-11', desktop: 335, mobile: 270 }, - { date: '2024-05-12', desktop: 197, mobile: 240 }, - { date: '2024-05-13', desktop: 197, mobile: 160 }, - { date: '2024-05-14', desktop: 448, mobile: 490 }, - { date: '2024-05-15', desktop: 473, mobile: 380 }, - { date: '2024-05-16', desktop: 338, mobile: 400 }, - { date: '2024-05-17', desktop: 499, mobile: 420 }, - { date: '2024-05-18', desktop: 315, mobile: 350 }, - { date: '2024-05-19', desktop: 235, mobile: 180 }, - { date: '2024-05-20', desktop: 177, mobile: 230 }, - { date: '2024-05-21', desktop: 82, mobile: 140 }, - { date: '2024-05-22', desktop: 81, mobile: 120 }, - { date: '2024-05-23', desktop: 252, mobile: 290 }, - { date: '2024-05-24', desktop: 294, mobile: 220 }, - { date: '2024-05-25', desktop: 201, mobile: 250 }, - { date: '2024-05-26', desktop: 213, mobile: 170 }, - { date: '2024-05-27', desktop: 420, mobile: 460 }, - { date: '2024-05-28', desktop: 233, mobile: 190 }, - { date: '2024-05-29', desktop: 78, mobile: 130 }, - { date: '2024-05-30', desktop: 340, mobile: 280 }, - { date: '2024-05-31', desktop: 178, mobile: 230 }, - { date: '2024-06-01', desktop: 178, mobile: 200 }, - { date: '2024-06-02', desktop: 470, mobile: 410 }, - { date: '2024-06-03', desktop: 103, mobile: 160 }, - { date: '2024-06-04', desktop: 439, mobile: 380 }, - { date: '2024-06-05', desktop: 88, mobile: 140 }, - { date: '2024-06-06', desktop: 294, mobile: 250 }, - { date: '2024-06-07', desktop: 323, mobile: 370 }, - { date: '2024-06-08', desktop: 385, mobile: 320 }, - { date: '2024-06-09', desktop: 438, mobile: 480 }, - { date: '2024-06-10', desktop: 155, mobile: 200 }, - { date: '2024-06-11', desktop: 92, mobile: 150 }, - { date: '2024-06-12', desktop: 492, mobile: 420 }, - { date: '2024-06-13', desktop: 81, mobile: 130 }, - { date: '2024-06-14', desktop: 426, mobile: 380 }, - { date: '2024-06-15', desktop: 307, mobile: 350 }, - { date: '2024-06-16', desktop: 371, mobile: 310 }, - { date: '2024-06-17', desktop: 475, mobile: 520 }, - { date: '2024-06-18', desktop: 107, mobile: 170 }, - { date: '2024-06-19', desktop: 341, mobile: 290 }, - { date: '2024-06-20', desktop: 408, mobile: 450 }, - { date: '2024-06-21', desktop: 169, mobile: 210 }, - { date: '2024-06-22', desktop: 317, mobile: 270 }, - { date: '2024-06-23', desktop: 480, mobile: 530 }, - { date: '2024-06-24', desktop: 132, mobile: 180 }, - { date: '2024-06-25', desktop: 141, mobile: 190 }, - { date: '2024-06-26', desktop: 434, mobile: 380 }, - { date: '2024-06-27', desktop: 448, mobile: 490 }, - { date: '2024-06-28', desktop: 149, mobile: 200 }, - { date: '2024-06-29', desktop: 103, mobile: 160 }, - { date: '2024-06-30', desktop: 446, mobile: 400 }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const [timeRange, setTimeRange] = React.useState('90d') - - const filteredData = chartData.filter((item) => { - const date = new Date(item.date) - const now = new Date() - let daysToSubtract = 90 - if (timeRange === '30d') { - daysToSubtract = 30 - } else if (timeRange === '7d') { - daysToSubtract = 7 - } - now.setDate(now.getDate() - daysToSubtract) - return date >= now - }) - - return ( - - -
- Area Chart - Interactive - Showing total visitors for the last 3 months -
- - - - - - - Last 3 months - - - Last 30 days - - - Last 7 days - - - -
- - - - - - - - - - - - - - - { - const date = new Date(value) - return date.toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - /> - { - return new Date(value).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - indicator="dot" - /> - } - /> - - - } /> - - - -
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-legend.tsx b/apps/design-system/registry/default/block/chart-area-legend.tsx deleted file mode 100644 index a58cfa9fbd9..00000000000 --- a/apps/design-system/registry/default/block/chart-area-legend.tsx +++ /dev/null @@ -1,98 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'An area chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Legend - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - } /> - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-linear.tsx b/apps/design-system/registry/default/block/chart-area-linear.tsx deleted file mode 100644 index 8381711c7aa..00000000000 --- a/apps/design-system/registry/default/block/chart-area-linear.tsx +++ /dev/null @@ -1,80 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A linear area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Linear - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } - /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-stacked-expand.tsx b/apps/design-system/registry/default/block/chart-area-stacked-expand.tsx deleted file mode 100644 index eca0b1118f7..00000000000 --- a/apps/design-system/registry/default/block/chart-area-stacked-expand.tsx +++ /dev/null @@ -1,104 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A stacked area chart with expand stacking' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80, other: 45 }, - { month: 'February', desktop: 305, mobile: 200, other: 100 }, - { month: 'March', desktop: 237, mobile: 120, other: 150 }, - { month: 'April', desktop: 73, mobile: 190, other: 50 }, - { month: 'May', desktop: 209, mobile: 130, other: 100 }, - { month: 'June', desktop: 214, mobile: 140, other: 160 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-3))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Stacked Expanded - Showing total visitors for the last 6months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-stacked.tsx b/apps/design-system/registry/default/block/chart-area-stacked.tsx deleted file mode 100644 index 22c0f58558b..00000000000 --- a/apps/design-system/registry/default/block/chart-area-stacked.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A stacked area chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Stacked - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-area-step.tsx b/apps/design-system/registry/default/block/chart-area-step.tsx deleted file mode 100644 index 5ac732aeaf4..00000000000 --- a/apps/design-system/registry/default/block/chart-area-step.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client' - -import { Activity, TrendingUp } from 'lucide-react' -import { Area, AreaChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A step area chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: Activity, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Area Chart - Step - Showing total visitors for the last 6 months - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
-
-
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-active.tsx b/apps/design-system/registry/default/block/chart-bar-active.tsx deleted file mode 100644 index b1ab1d95e1a..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-active.tsx +++ /dev/null @@ -1,94 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, Rectangle, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with an active bar' - -const chartData = [ - { browser: 'chrome', visitors: 187, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 275, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Active - January - June 2024 - - - - - - chartConfig[value as keyof typeof chartConfig]?.label} - /> - } /> - { - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-default.tsx b/apps/design-system/registry/default/block/chart-bar-default.tsx deleted file mode 100644 index 1c0596e3b57..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-default.tsx +++ /dev/null @@ -1,60 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-horizontal.tsx b/apps/design-system/registry/default/block/chart-bar-horizontal.tsx deleted file mode 100644 index 2305d0a4e1c..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-horizontal.tsx +++ /dev/null @@ -1,68 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A horizontal bar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Horizontal - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-label-custom.tsx b/apps/design-system/registry/default/block/chart-bar-label-custom.tsx deleted file mode 100644 index 7867342bc6d..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-label-custom.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with a custom label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, - label: { - color: 'hsl(var(--background))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Custom Label - January - June 2024 - - - - - - value.slice(0, 3)} - hide - /> - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-label.tsx b/apps/design-system/registry/default/block/chart-bar-label.tsx deleted file mode 100644 index 3bbdcc7a7ea..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-label.tsx +++ /dev/null @@ -1,68 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, LabelList, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with a label' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Label - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-mixed.tsx b/apps/design-system/registry/default/block/chart-bar-mixed.tsx deleted file mode 100644 index 1790507f73f..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-mixed.tsx +++ /dev/null @@ -1,86 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, XAxis, YAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A mixed bar chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Mixed - January - June 2024 - - - - - chartConfig[value as keyof typeof chartConfig]?.label} - /> - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-multiple.tsx b/apps/design-system/registry/default/block/chart-bar-multiple.tsx deleted file mode 100644 index ffb9c61679a..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-multiple.tsx +++ /dev/null @@ -1,65 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A multiple bar chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Multiple - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-negative.tsx b/apps/design-system/registry/default/block/chart-bar-negative.tsx deleted file mode 100644 index 43f87ef0762..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-negative.tsx +++ /dev/null @@ -1,63 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, Cell, LabelList } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A bar chart with negative values' - -const chartData = [ - { month: 'January', visitors: 186 }, - { month: 'February', visitors: 205 }, - { month: 'March', visitors: -207 }, - { month: 'April', visitors: 173 }, - { month: 'May', visitors: -209 }, - { month: 'June', visitors: 214 }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Negative - January - June 2024 - - - - - - } - /> - - - {chartData.map((item) => ( - 0 ? 'hsl(var(--chart-1))' : 'hsl(var(--chart-2))'} - /> - ))} - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-bar-stacked.tsx b/apps/design-system/registry/default/block/chart-bar-stacked.tsx deleted file mode 100644 index 34a7439e982..00000000000 --- a/apps/design-system/registry/default/block/chart-bar-stacked.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A stacked bar chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Bar Chart - Stacked + Legend - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-composed-actions.tsx b/apps/design-system/registry/default/block/chart-composed-actions.tsx new file mode 100644 index 00000000000..f6eac7312b2 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-actions.tsx @@ -0,0 +1,106 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartLine, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink, LineChart } from 'lucide-react' +import { useState, useEffect } from 'react' + +export default function ChartComposedActions() { + const [isLoading, setIsLoading] = useState(true) + const [chartType, setChartType] = useState<'bar' | 'line'>('bar') + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Opening in Logs Explorer...') + }, + icon: , + }, + { + label: 'Toggle Chart Type', + onClick: () => { + setChartType(chartType === 'bar' ? 'line' : 'bar') + }, + icon: chartType === 'bar' ? : , + }, + ] + + const data = Array.from({ length: 46 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + requests: Math.floor(Math.random() * 100), + } + }).reverse() + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Total Requests + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ {chartType === 'bar' ? ( + `${value}k`, + width: 80, + }} + isFullHeight={true} + /> + ) : ( + `${value}k`, + width: 80, + }} + isFullHeight={true} + /> + )} +
+
+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/block/chart-composed-basic.tsx b/apps/design-system/registry/default/block/chart-composed-basic.tsx new file mode 100644 index 00000000000..d9457c3d308 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-basic.tsx @@ -0,0 +1,142 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartLine, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' + +export default function ComposedChartBasic() { + const [isLoading, setIsLoading] = useState(true) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + const data = Array.from({ length: 40 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 3) // Each point 3 minutes apart + + const progress = i / 40 + const standard_score = Math.floor(55 + progress * 55 + (Math.random() - 0.5) * 12) + const performance = Math.floor(35 + progress * 35 + (Math.random() - 0.5) * 10) + const efficiency = Math.floor(25 + progress * 25 + (Math.random() - 0.5) * 12) + + return { + timestamp: date.toISOString(), + standard_score: Math.max(0, Math.min(100, standard_score)), + performance: Math.max(0, Math.min(100, performance)), + efficiency: Math.max(0, Math.min(100, efficiency)), + } + }).reverse() + + const chartConfig = { + standard_score: { + label: 'Standard Score', + color: 'hsl(var(--brand-default))', + }, + performance: { + label: 'Performance', + color: 'hsl(var(--chart-2))', + }, + efficiency: { + label: 'Efficiency', + color: 'hsl(var(--chart-5))', + }, + } + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Standard Bar Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+
+
+ + + + + Standard Line Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/block/chart-composed-demo.tsx b/apps/design-system/registry/default/block/chart-composed-demo.tsx new file mode 100644 index 00000000000..c734900d395 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-demo.tsx @@ -0,0 +1,73 @@ +'use client' + +import { + Chart, + ChartCard, + ChartContent, + ChartHeader, + ChartEmptyState, + ChartLoadingState, + ChartMetric, +} from 'ui-patterns/Chart' +import { BarChart2 } from 'lucide-react' +import { LogsBarChart } from 'ui-patterns/LogsBarChart' +import { useState, useEffect } from 'react' + +export default function ComposedChartDemo() { + const [isLoading, setIsLoading] = useState(true) + + const data = Array.from({ length: 60 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + ok_count: Math.floor(Math.random() * 100), // Random value 0-99 + error_count: Math.floor(Math.random() * 50), // Random value 0-50 + warning_count: Math.floor(Math.random() * 50), // Random value 0-50 + } + }).reverse() + + const totalUsersValue = 4663 + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + +
+ + +
+
+ } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ +
+
+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/block/chart-composed-metrics.tsx b/apps/design-system/registry/default/block/chart-composed-metrics.tsx new file mode 100644 index 00000000000..0c876d7e589 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-metrics.tsx @@ -0,0 +1,100 @@ +'use client' + +import { + Chart, + ChartCard, + ChartHeader, + ChartActions, + ChartContent, + ChartMetric, + ChartSparkline, +} from 'ui-patterns/Chart' +import { ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' +import { Skeleton } from 'ui' + +export default function ChartComposedMetrics() { + const [data, setData] = useState>([]) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + useEffect(() => { + const now = new Date() + setData( + Array.from({ length: 12 }, (_, i) => ({ + value: Math.floor(4000 + i * 100 + (Math.random() * 2000 - 800)), + timestamp: new Date(now.getTime() - (11 - i) * 60 * 60 * 1000).toISOString(), + })) + ) + }, []) + + const averageValue = data.reduce((acc, curr) => acc + curr.value, 0) / data.length + + const diff = data[data.length - 1]?.value - data[0]?.value || 0 + const diffPercentage = (diff / averageValue) * 100 + + return ( +
+ + + + + + + + + + + + + + + + + + + + + + + } + > + + + + + + + + + + + } + > + + + + +
+ ) +} diff --git a/apps/design-system/registry/default/block/chart-composed-states.tsx b/apps/design-system/registry/default/block/chart-composed-states.tsx new file mode 100644 index 00000000000..4e5aa5d8bd5 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-states.tsx @@ -0,0 +1,92 @@ +'use client' + +import { BarChart2, ExternalLink } from 'lucide-react' +import { + Chart, + ChartCard, + ChartHeader, + ChartTitle, + ChartActions, + ChartContent, + ChartEmptyState, + ChartLoadingState, + ChartDisabledState, +} from 'ui-patterns/Chart' +import { Badge } from 'ui' + +export default function ChartComposedStates() { + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Ta da! You clicked me! 🎉') + }, + icon: , + }, + ] + + const disabledActions = [ + { + label: 'Upgrade to Pro', + href: '#', + }, + ] + + return ( +
+ + + + Response Errors + + + }>My chart here... + + + + + + + Response Errors + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > + My chart here... + + + + + + + + Response Errors + + + } + disabledState={ + Pro} + label="API Processing Time" + description="This chart is available on the Pro plan and above" + actions={disabledActions} + /> + } + > + My chart here... + + + +
+ ) +} diff --git a/apps/design-system/registry/default/block/chart-composed-table.tsx b/apps/design-system/registry/default/block/chart-composed-table.tsx new file mode 100644 index 00000000000..303114447e9 --- /dev/null +++ b/apps/design-system/registry/default/block/chart-composed-table.tsx @@ -0,0 +1,106 @@ +'use client' + +import { + Chart, + ChartActions, + ChartCard, + ChartContent, + ChartHeader, + ChartTitle, + ChartEmptyState, + ChartLoadingState, + ChartBar, + ChartFooter, +} from 'ui-patterns/Chart' +import { BarChart2, ExternalLink } from 'lucide-react' +import { useState, useEffect } from 'react' +import { Table, TableHead, TableBody, TableRow, TableCell, TableHeader } from 'ui' +import { format } from 'date-fns' + +export default function ChartComposedTable() { + const [isLoading, setIsLoading] = useState(true) + + const actions = [ + { + label: 'Open in Logs Explorer', + onClick: () => { + alert('Opening in Logs Explorer...') + }, + icon: , + }, + ] + + const data = Array.from({ length: 46 }, (_, i) => { + const date = new Date() + date.setMinutes(date.getMinutes() - i * 5) // Each point 5 minutes apart + + return { + timestamp: date.toISOString(), + standard_score: Math.floor(Math.random() * 100), + } + }).reverse() + + useEffect(() => { + setTimeout(() => { + setIsLoading(false) + }, 1000) + }, []) + + return ( +
+ + + + Standard Bar Chart + + + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > +
+ `${value}k`, + width: 80, + }} + isFullHeight={true} + /> +
+
+ +
+ + + Timestamp + Standard Score + + + + {data.slice(0, 3).map((item) => ( + + + {format(new Date(item.timestamp), 'MMM d, yyyy h:mm a')} + + {item.standard_score} + + ))} + +
+ + + + + ) +} diff --git a/apps/design-system/registry/default/block/chart-line-default.tsx b/apps/design-system/registry/default/block/chart-line-default.tsx deleted file mode 100644 index 408dc1d6f9f..00000000000 --- a/apps/design-system/registry/default/block/chart-line-default.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-dots-colors.tsx b/apps/design-system/registry/default/block/chart-line-dots-colors.tsx deleted file mode 100644 index c8a55a0c44b..00000000000 --- a/apps/design-system/registry/default/block/chart-line-dots-colors.tsx +++ /dev/null @@ -1,100 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Dot, Line, LineChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with dots and colors' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - color: 'hsl(var(--chart-2))', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Dots Colors - January - June 2024 - - - - - - } - /> - { - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-dots-custom.tsx b/apps/design-system/registry/default/block/chart-line-dots-custom.tsx deleted file mode 100644 index 87c69309319..00000000000 --- a/apps/design-system/registry/default/block/chart-line-dots-custom.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { GitCommitVertical, TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with custom dots' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Custom Dots - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - { - const r = 24 - return ( - - ) - }} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-dots.tsx b/apps/design-system/registry/default/block/chart-line-dots.tsx deleted file mode 100644 index cc211f2c2b4..00000000000 --- a/apps/design-system/registry/default/block/chart-line-dots.tsx +++ /dev/null @@ -1,82 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with dots' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Dots - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-interactive.tsx b/apps/design-system/registry/default/block/chart-line-interactive.tsx deleted file mode 100644 index 5f9c92b9792..00000000000 --- a/apps/design-system/registry/default/block/chart-line-interactive.tsx +++ /dev/null @@ -1,208 +0,0 @@ -'use client' - -import * as React from 'react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'An interactive line chart' - -const chartData = [ - { date: '2024-04-01', desktop: 222, mobile: 150 }, - { date: '2024-04-02', desktop: 97, mobile: 180 }, - { date: '2024-04-03', desktop: 167, mobile: 120 }, - { date: '2024-04-04', desktop: 242, mobile: 260 }, - { date: '2024-04-05', desktop: 373, mobile: 290 }, - { date: '2024-04-06', desktop: 301, mobile: 340 }, - { date: '2024-04-07', desktop: 245, mobile: 180 }, - { date: '2024-04-08', desktop: 409, mobile: 320 }, - { date: '2024-04-09', desktop: 59, mobile: 110 }, - { date: '2024-04-10', desktop: 261, mobile: 190 }, - { date: '2024-04-11', desktop: 327, mobile: 350 }, - { date: '2024-04-12', desktop: 292, mobile: 210 }, - { date: '2024-04-13', desktop: 342, mobile: 380 }, - { date: '2024-04-14', desktop: 137, mobile: 220 }, - { date: '2024-04-15', desktop: 120, mobile: 170 }, - { date: '2024-04-16', desktop: 138, mobile: 190 }, - { date: '2024-04-17', desktop: 446, mobile: 360 }, - { date: '2024-04-18', desktop: 364, mobile: 410 }, - { date: '2024-04-19', desktop: 243, mobile: 180 }, - { date: '2024-04-20', desktop: 89, mobile: 150 }, - { date: '2024-04-21', desktop: 137, mobile: 200 }, - { date: '2024-04-22', desktop: 224, mobile: 170 }, - { date: '2024-04-23', desktop: 138, mobile: 230 }, - { date: '2024-04-24', desktop: 387, mobile: 290 }, - { date: '2024-04-25', desktop: 215, mobile: 250 }, - { date: '2024-04-26', desktop: 75, mobile: 130 }, - { date: '2024-04-27', desktop: 383, mobile: 420 }, - { date: '2024-04-28', desktop: 122, mobile: 180 }, - { date: '2024-04-29', desktop: 315, mobile: 240 }, - { date: '2024-04-30', desktop: 454, mobile: 380 }, - { date: '2024-05-01', desktop: 165, mobile: 220 }, - { date: '2024-05-02', desktop: 293, mobile: 310 }, - { date: '2024-05-03', desktop: 247, mobile: 190 }, - { date: '2024-05-04', desktop: 385, mobile: 420 }, - { date: '2024-05-05', desktop: 481, mobile: 390 }, - { date: '2024-05-06', desktop: 498, mobile: 520 }, - { date: '2024-05-07', desktop: 388, mobile: 300 }, - { date: '2024-05-08', desktop: 149, mobile: 210 }, - { date: '2024-05-09', desktop: 227, mobile: 180 }, - { date: '2024-05-10', desktop: 293, mobile: 330 }, - { date: '2024-05-11', desktop: 335, mobile: 270 }, - { date: '2024-05-12', desktop: 197, mobile: 240 }, - { date: '2024-05-13', desktop: 197, mobile: 160 }, - { date: '2024-05-14', desktop: 448, mobile: 490 }, - { date: '2024-05-15', desktop: 473, mobile: 380 }, - { date: '2024-05-16', desktop: 338, mobile: 400 }, - { date: '2024-05-17', desktop: 499, mobile: 420 }, - { date: '2024-05-18', desktop: 315, mobile: 350 }, - { date: '2024-05-19', desktop: 235, mobile: 180 }, - { date: '2024-05-20', desktop: 177, mobile: 230 }, - { date: '2024-05-21', desktop: 82, mobile: 140 }, - { date: '2024-05-22', desktop: 81, mobile: 120 }, - { date: '2024-05-23', desktop: 252, mobile: 290 }, - { date: '2024-05-24', desktop: 294, mobile: 220 }, - { date: '2024-05-25', desktop: 201, mobile: 250 }, - { date: '2024-05-26', desktop: 213, mobile: 170 }, - { date: '2024-05-27', desktop: 420, mobile: 460 }, - { date: '2024-05-28', desktop: 233, mobile: 190 }, - { date: '2024-05-29', desktop: 78, mobile: 130 }, - { date: '2024-05-30', desktop: 340, mobile: 280 }, - { date: '2024-05-31', desktop: 178, mobile: 230 }, - { date: '2024-06-01', desktop: 178, mobile: 200 }, - { date: '2024-06-02', desktop: 470, mobile: 410 }, - { date: '2024-06-03', desktop: 103, mobile: 160 }, - { date: '2024-06-04', desktop: 439, mobile: 380 }, - { date: '2024-06-05', desktop: 88, mobile: 140 }, - { date: '2024-06-06', desktop: 294, mobile: 250 }, - { date: '2024-06-07', desktop: 323, mobile: 370 }, - { date: '2024-06-08', desktop: 385, mobile: 320 }, - { date: '2024-06-09', desktop: 438, mobile: 480 }, - { date: '2024-06-10', desktop: 155, mobile: 200 }, - { date: '2024-06-11', desktop: 92, mobile: 150 }, - { date: '2024-06-12', desktop: 492, mobile: 420 }, - { date: '2024-06-13', desktop: 81, mobile: 130 }, - { date: '2024-06-14', desktop: 426, mobile: 380 }, - { date: '2024-06-15', desktop: 307, mobile: 350 }, - { date: '2024-06-16', desktop: 371, mobile: 310 }, - { date: '2024-06-17', desktop: 475, mobile: 520 }, - { date: '2024-06-18', desktop: 107, mobile: 170 }, - { date: '2024-06-19', desktop: 341, mobile: 290 }, - { date: '2024-06-20', desktop: 408, mobile: 450 }, - { date: '2024-06-21', desktop: 169, mobile: 210 }, - { date: '2024-06-22', desktop: 317, mobile: 270 }, - { date: '2024-06-23', desktop: 480, mobile: 530 }, - { date: '2024-06-24', desktop: 132, mobile: 180 }, - { date: '2024-06-25', desktop: 141, mobile: 190 }, - { date: '2024-06-26', desktop: 434, mobile: 380 }, - { date: '2024-06-27', desktop: 448, mobile: 490 }, - { date: '2024-06-28', desktop: 149, mobile: 200 }, - { date: '2024-06-29', desktop: 103, mobile: 160 }, - { date: '2024-06-30', desktop: 446, mobile: 400 }, -] - -const chartConfig = { - views: { - label: 'Page Views', - }, - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const [activeChart, setActiveChart] = React.useState('desktop') - - const total = React.useMemo( - () => ({ - desktop: chartData.reduce((acc, curr) => acc + curr.desktop, 0), - mobile: chartData.reduce((acc, curr) => acc + curr.mobile, 0), - }), - [] - ) - - return ( - - -
- Line Chart - Interactive - Showing total visitors for the last 3 months -
-
- {['desktop', 'mobile'].map((key) => { - const chart = key as keyof typeof chartConfig - return ( - - ) - })} -
-
- - - - - { - const date = new Date(value) - return date.toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - }) - }} - /> - { - return new Date(value).toLocaleDateString('en-US', { - month: 'short', - day: 'numeric', - year: 'numeric', - }) - }} - /> - } - /> - - - - -
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-label-custom.tsx b/apps/design-system/registry/default/block/chart-line-label-custom.tsx deleted file mode 100644 index 3d84fec03a3..00000000000 --- a/apps/design-system/registry/default/block/chart-line-label-custom.tsx +++ /dev/null @@ -1,103 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, LabelList, Line, LineChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with a custom label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - color: 'hsl(var(--chart-2))', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Custom Label - January - June 2024 - - - - - - } - /> - - chartConfig[value]?.label} - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-label.tsx b/apps/design-system/registry/default/block/chart-line-label.tsx deleted file mode 100644 index 2c187e95961..00000000000 --- a/apps/design-system/registry/default/block/chart-line-label.tsx +++ /dev/null @@ -1,85 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, LabelList, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with a label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Label - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-linear.tsx b/apps/design-system/registry/default/block/chart-line-linear.tsx deleted file mode 100644 index 9219a3c9de4..00000000000 --- a/apps/design-system/registry/default/block/chart-line-linear.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A linear line chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Linear - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-multiple.tsx b/apps/design-system/registry/default/block/chart-line-multiple.tsx deleted file mode 100644 index f09714a2737..00000000000 --- a/apps/design-system/registry/default/block/chart-line-multiple.tsx +++ /dev/null @@ -1,88 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A multiple line chart' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Multiple - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - - -
-
-
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-line-step.tsx b/apps/design-system/registry/default/block/chart-line-step.tsx deleted file mode 100644 index 0ab71e07d09..00000000000 --- a/apps/design-system/registry/default/block/chart-line-step.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { CartesianGrid, Line, LineChart, XAxis } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A line chart with step' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 73 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Line Chart - Step - January - June 2024 - - - - - - value.slice(0, 3)} - /> - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-donut-active.tsx b/apps/design-system/registry/default/block/chart-pie-donut-active.tsx deleted file mode 100644 index 2490b50f65f..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-donut-active.tsx +++ /dev/null @@ -1,81 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart, Sector } from 'recharts' -import { PieSectorDataItem } from 'recharts/types/polar/Pie' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart with an active sector' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Donut Active - January - June 2024 - - - - - } /> - ( - - )} - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-donut-text.tsx b/apps/design-system/registry/default/block/chart-pie-donut-text.tsx deleted file mode 100644 index cba1eee8492..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-donut-text.tsx +++ /dev/null @@ -1,111 +0,0 @@ -'use client' - -import * as React from 'react' -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart with text' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 287, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 190, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - const totalVisitors = React.useMemo(() => { - return chartData.reduce((acc, curr) => acc + curr.visitors, 0) - }, []) - - return ( - - - Pie Chart - Donut with Text - January - June 2024 - - - - - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-donut.tsx b/apps/design-system/registry/default/block/chart-pie-donut.tsx deleted file mode 100644 index 328fbd4b48a..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-donut.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A donut chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Donut - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-interactive.tsx b/apps/design-system/registry/default/block/chart-pie-interactive.tsx deleted file mode 100644 index be05cbf8e41..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-interactive.tsx +++ /dev/null @@ -1,170 +0,0 @@ -'use client' - -import * as React from 'react' -import { Label, Pie, PieChart, Sector } from 'recharts' -import { PieSectorDataItem } from 'recharts/types/polar/Pie' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartStyle, ChartTooltip, ChartTooltipContent } from 'ui' -import { - Select_Shadcn_, - SelectContent_Shadcn_, - SelectItem_Shadcn_, - SelectTrigger_Shadcn_, - SelectValue_Shadcn_, -} from 'ui' - -export const description = 'An interactive pie chart' - -const desktopData = [ - { month: 'january', desktop: 186, fill: 'var(--color-january)' }, - { month: 'february', desktop: 305, fill: 'var(--color-february)' }, - { month: 'march', desktop: 237, fill: 'var(--color-march)' }, - { month: 'april', desktop: 173, fill: 'var(--color-april)' }, - { month: 'may', desktop: 209, fill: 'var(--color-may)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - }, - mobile: { - label: 'Mobile', - }, - january: { - label: 'January', - color: 'hsl(var(--chart-1))', - }, - february: { - label: 'February', - color: 'hsl(var(--chart-2))', - }, - march: { - label: 'March', - color: 'hsl(var(--chart-3))', - }, - april: { - label: 'April', - color: 'hsl(var(--chart-4))', - }, - may: { - label: 'May', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - const id = 'pie-interactive' - const [activeMonth, setActiveMonth] = React.useState(desktopData[0].month) - - const activeIndex = React.useMemo( - () => desktopData.findIndex((item) => item.month === activeMonth), - [activeMonth] - ) - const months = React.useMemo(() => desktopData.map((item) => item.month), []) - - return ( - - - -
- Pie Chart - Interactive - January - June 2024 -
- - - - - - {months.map((key) => { - const config = chartConfig[key as keyof typeof chartConfig] - - if (!config) { - return null - } - - return ( - -
- - {config?.label} -
-
- ) - })} -
-
-
- - - - } /> - ( - - - - - )} - > - - - - -
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-label-custom.tsx b/apps/design-system/registry/default/block/chart-pie-label-custom.tsx deleted file mode 100644 index 5fcae35aabe..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-label-custom.tsx +++ /dev/null @@ -1,92 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a custom label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Custom Label - January - June 2024 - - - - - } /> - { - return ( - - {`${ - chartConfig[payload.browser as keyof typeof chartConfig]?.label - } (${payload.visitors})`} - - ) - }} - nameKey="browser" - /> - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-label-list.tsx b/apps/design-system/registry/default/block/chart-pie-label-list.tsx deleted file mode 100644 index 814371c307e..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-label-list.tsx +++ /dev/null @@ -1,78 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { LabelList, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a label list' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Label List - January - June 2024 - - - - - } /> - - chartConfig[value]?.label} - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-label.tsx b/apps/design-system/registry/default/block/chart-pie-label.tsx deleted file mode 100644 index 408bd68fb95..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-label.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with a label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Label - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-legend.tsx b/apps/design-system/registry/default/block/chart-pie-legend.tsx deleted file mode 100644 index c72830caf17..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-legend.tsx +++ /dev/null @@ -1,64 +0,0 @@ -'use client' - -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartLegend, ChartLegendContent } from 'ui' - -export const description = 'A pie chart with a legend' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Legend - January - June 2024 - - - - - - } - className="-translate-y-2 flex-wrap gap-2 [&>*]:basis-1/4 [&>*]:justify-center" - /> - - - - - ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-separator-none.tsx b/apps/design-system/registry/default/block/chart-pie-separator-none.tsx deleted file mode 100644 index ed00866c3b8..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-separator-none.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with no separator' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Separator None - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-simple.tsx b/apps/design-system/registry/default/block/chart-pie-simple.tsx deleted file mode 100644 index a16fb87ca56..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-simple.tsx +++ /dev/null @@ -1,70 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A simple pie chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - January - June 2024 - - - - - } /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-pie-stacked.tsx b/apps/design-system/registry/default/block/chart-pie-stacked.tsx deleted file mode 100644 index a2ab16ba711..00000000000 --- a/apps/design-system/registry/default/block/chart-pie-stacked.tsx +++ /dev/null @@ -1,97 +0,0 @@ -'use client' - -import * as React from 'react' -import { TrendingUp } from 'lucide-react' -import { Label, Pie, PieChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A pie chart with stacked sections' - -const desktopData = [ - { month: 'january', desktop: 186, fill: 'var(--color-january)' }, - { month: 'february', desktop: 305, fill: 'var(--color-february)' }, - { month: 'march', desktop: 237, fill: 'var(--color-march)' }, - { month: 'april', desktop: 173, fill: 'var(--color-april)' }, - { month: 'may', desktop: 209, fill: 'var(--color-may)' }, -] - -const mobileData = [ - { month: 'january', mobile: 80, fill: 'var(--color-january)' }, - { month: 'february', mobile: 200, fill: 'var(--color-february)' }, - { month: 'march', mobile: 120, fill: 'var(--color-march)' }, - { month: 'april', mobile: 190, fill: 'var(--color-april)' }, - { month: 'may', mobile: 130, fill: 'var(--color-may)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - desktop: { - label: 'Desktop', - }, - mobile: { - label: 'Mobile', - }, - january: { - label: 'January', - color: 'hsl(var(--chart-1))', - }, - february: { - label: 'February', - color: 'hsl(var(--chart-2))', - }, - march: { - label: 'March', - color: 'hsl(var(--chart-3))', - }, - april: { - label: 'April', - color: 'hsl(var(--chart-4))', - }, - may: { - label: 'May', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Pie Chart - Stacked - January - June 2024 - - - - - { - return chartConfig[payload?.[0].dataKey as keyof typeof chartConfig].label - }} - /> - } - /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-default.tsx b/apps/design-system/registry/default/block/chart-radar-default.tsx deleted file mode 100644 index dc3d4e6d553..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-default.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-dots.tsx b/apps/design-system/registry/default/block/chart-radar-dots.tsx deleted file mode 100644 index bedf14de29b..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-dots.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with dots' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Dots - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-circle-fill.tsx b/apps/design-system/registry/default/block/chart-radar-grid-circle-fill.tsx deleted file mode 100644 index d17d1536225..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-circle-fill.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle fill' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 285 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 264 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle Filled - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-circle-no-lines.tsx b/apps/design-system/registry/default/block/chart-radar-grid-circle-no-lines.tsx deleted file mode 100644 index 3e602ac5745..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-circle-no-lines.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle fill' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle - No lines - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-circle.tsx b/apps/design-system/registry/default/block/chart-radar-grid-circle.tsx deleted file mode 100644 index 0cc0277a0c4..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-circle.tsx +++ /dev/null @@ -1,62 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid and circle' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Circle - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-custom.tsx b/apps/design-system/registry/default/block/chart-radar-grid-custom.tsx deleted file mode 100644 index 31614acc9a3..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-custom.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a custom grid' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Custom - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-fill.tsx b/apps/design-system/registry/default/block/chart-radar-grid-fill.tsx deleted file mode 100644 index 7745a10fb13..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-fill.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a grid filled' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 285 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 203 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 264 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid Filled - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-grid-none.tsx b/apps/design-system/registry/default/block/chart-radar-grid-none.tsx deleted file mode 100644 index a75ac15da18..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-grid-none.tsx +++ /dev/null @@ -1,61 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with no grid' - -const chartData = [ - { month: 'January', desktop: 186 }, - { month: 'February', desktop: 305 }, - { month: 'March', desktop: 237 }, - { month: 'April', desktop: 273 }, - { month: 'May', desktop: 209 }, - { month: 'June', desktop: 214 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Grid None - Showing total visitors for the last 6 months - - - - - } /> - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-icons.tsx b/apps/design-system/registry/default/block/chart-radar-icons.tsx deleted file mode 100644 index b2a83ad3934..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-icons.tsx +++ /dev/null @@ -1,75 +0,0 @@ -'use client' - -import { ArrowDownFromLine, ArrowUpFromLine, TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A radar chart with icons' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - icon: ArrowDownFromLine, - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - icon: ArrowUpFromLine, - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Icons - Showing total visitors for the last 6 months - - - - - } /> - - - - - } /> - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-label-custom.tsx b/apps/design-system/registry/default/block/chart-radar-label-custom.tsx deleted file mode 100644 index 51edad28517..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-label-custom.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a custom label' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Custom Label - Showing total visitors for the last 6 months - - - - - } /> - { - const data = chartData[index] - - return ( - - {data.desktop} - / - {data.mobile} - - {data.month} - - - ) - }} - /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-legend.tsx b/apps/design-system/registry/default/block/chart-radar-legend.tsx deleted file mode 100644 index 1500cc422a3..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-legend.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { - ChartConfig, - ChartContainer, - ChartLegend, - ChartLegendContent, - ChartTooltip, - ChartTooltipContent, -} from 'ui' - -export const description = 'A radar chart with a legend' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Legend - Showing total visitors for the last 6 months - - - - - } /> - - - - - } /> - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-lines-only.tsx b/apps/design-system/registry/default/block/chart-radar-lines-only.tsx deleted file mode 100644 index acb880c81c3..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-lines-only.tsx +++ /dev/null @@ -1,71 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with lines only' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 160 }, - { month: 'February', desktop: 185, mobile: 170 }, - { month: 'March', desktop: 207, mobile: 180 }, - { month: 'April', desktop: 173, mobile: 160 }, - { month: 'May', desktop: 160, mobile: 190 }, - { month: 'June', desktop: 174, mobile: 204 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Lines Only - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-multiple.tsx b/apps/design-system/registry/default/block/chart-radar-multiple.tsx deleted file mode 100644 index 5cc44043950..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-multiple.tsx +++ /dev/null @@ -1,59 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with multiple data' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Multiple - Showing total visitors for the last 6 months - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radar-radius.tsx b/apps/design-system/registry/default/block/chart-radar-radius.tsx deleted file mode 100644 index f6616c4ac00..00000000000 --- a/apps/design-system/registry/default/block/chart-radar-radius.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarAngleAxis, PolarGrid, PolarRadiusAxis, Radar, RadarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radar chart with a radius axis' - -const chartData = [ - { month: 'January', desktop: 186, mobile: 80 }, - { month: 'February', desktop: 305, mobile: 200 }, - { month: 'March', desktop: 237, mobile: 120 }, - { month: 'April', desktop: 73, mobile: 190 }, - { month: 'May', desktop: 209, mobile: 130 }, - { month: 'June', desktop: 214, mobile: 140 }, -] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radar Chart - Radius Axis - Showing total visitors for the last 6 months - - - - - } - /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- January - June 2024 -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-grid.tsx b/apps/design-system/registry/default/block/chart-radial-grid.tsx deleted file mode 100644 index fea6deab0c2..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-grid.tsx +++ /dev/null @@ -1,74 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { PolarGrid, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with a grid' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Grid - January - June 2024 - - - - - } - /> - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-label.tsx b/apps/design-system/registry/default/block/chart-radial-label.tsx deleted file mode 100644 index 073e8b4ed47..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-label.tsx +++ /dev/null @@ -1,86 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { LabelList, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with a label' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Label - January - June 2024 - - - - - } - /> - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-shape.tsx b/apps/design-system/registry/default/block/chart-radial-shape.tsx deleted file mode 100644 index 120a2df88d4..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-shape.tsx +++ /dev/null @@ -1,85 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer } from 'ui' - -export const description = 'A radial chart with a custom shape' - -const chartData = [{ browser: 'safari', visitors: 1260, fill: 'var(--color-safari)' }] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Shape - January - June 2024 - - - - - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-simple.tsx b/apps/design-system/registry/default/block/chart-radial-simple.tsx deleted file mode 100644 index 6c7590b2573..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-simple.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart' - -const chartData = [ - { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, - { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, - { browser: 'firefox', visitors: 187, fill: 'var(--color-firefox)' }, - { browser: 'edge', visitors: 173, fill: 'var(--color-edge)' }, - { browser: 'other', visitors: 90, fill: 'var(--color-other)' }, -] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - chrome: { - label: 'Chrome', - color: 'hsl(var(--chart-1))', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, - firefox: { - label: 'Firefox', - color: 'hsl(var(--chart-3))', - }, - edge: { - label: 'Edge', - color: 'hsl(var(--chart-4))', - }, - other: { - label: 'Other', - color: 'hsl(var(--chart-5))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - January - June 2024 - - - - - } - /> - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-stacked.tsx b/apps/design-system/registry/default/block/chart-radial-stacked.tsx deleted file mode 100644 index e38791f9bae..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-stacked.tsx +++ /dev/null @@ -1,90 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from 'ui' - -export const description = 'A radial chart with stacked sections' - -const chartData = [{ month: 'january', desktop: 1260, mobile: 570 }] - -const chartConfig = { - desktop: { - label: 'Desktop', - color: 'hsl(var(--chart-1))', - }, - mobile: { - label: 'Mobile', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - const totalVisitors = chartData[0].desktop + chartData[0].mobile - - return ( - - - Radial Chart - Stacked - January - June 2024 - - - - - } /> - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/block/chart-radial-text.tsx b/apps/design-system/registry/default/block/chart-radial-text.tsx deleted file mode 100644 index 8dd238c505b..00000000000 --- a/apps/design-system/registry/default/block/chart-radial-text.tsx +++ /dev/null @@ -1,91 +0,0 @@ -'use client' - -import { TrendingUp } from 'lucide-react' -import { Label, PolarGrid, PolarRadiusAxis, RadialBar, RadialBarChart } from 'recharts' - -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from 'ui' -import { ChartConfig, ChartContainer } from 'ui' - -export const description = 'A radial chart with text' - -const chartData = [{ browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }] - -const chartConfig = { - visitors: { - label: 'Visitors', - }, - safari: { - label: 'Safari', - color: 'hsl(var(--chart-2))', - }, -} satisfies ChartConfig - -export default function Component() { - return ( - - - Radial Chart - Text - January - June 2024 - - - - - - - - - - - - -
- Trending up by 5.2% this month -
-
- Showing total visitors for the last 6 months -
-
-
- ) -} diff --git a/apps/design-system/registry/default/example/admonition-button.tsx b/apps/design-system/registry/default/example/admonition-button.tsx new file mode 100644 index 00000000000..b6251de2bef --- /dev/null +++ b/apps/design-system/registry/default/example/admonition-button.tsx @@ -0,0 +1,24 @@ +import { Button } from 'ui' +import { Admonition } from 'ui-patterns/admonition' + +export default function AdmonitionDemo() { + return ( +
+ Set up SMTP} + /> + Delete organization} + /> +
+ ) +} diff --git a/apps/design-system/registry/default/example/admonition-demo.tsx b/apps/design-system/registry/default/example/admonition-demo.tsx index 77c15eea02c..75040b9fc63 100644 --- a/apps/design-system/registry/default/example/admonition-demo.tsx +++ b/apps/design-system/registry/default/example/admonition-demo.tsx @@ -1,11 +1,15 @@ +import { Button } from 'ui' import { Admonition } from 'ui-patterns/admonition' export default function AdmonitionDemo() { return ( OAuth Server Settings} /> ) } diff --git a/apps/design-system/registry/default/example/alert-demo.tsx b/apps/design-system/registry/default/example/alert-demo.tsx index 311b4bc8d62..cbb9ce1b70e 100644 --- a/apps/design-system/registry/default/example/alert-demo.tsx +++ b/apps/design-system/registry/default/example/alert-demo.tsx @@ -1,14 +1,13 @@ import { Terminal } from 'lucide-react' - import { Alert_Shadcn_, AlertDescription_Shadcn_, AlertTitle_Shadcn_ } from 'ui' export default function AlertDemo() { return ( - + Heads up! - You can add components to your app using the cli. + You can also add components to your app using the CLI. ) diff --git a/apps/design-system/registry/default/example/alert-destructive.tsx b/apps/design-system/registry/default/example/alert-destructive.tsx deleted file mode 100644 index 67c3b747149..00000000000 --- a/apps/design-system/registry/default/example/alert-destructive.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { AlertCircle } from 'lucide-react' - -import { Alert_Shadcn_, AlertDescription_Shadcn_, AlertTitle_Shadcn_ } from 'ui' - -export default function AlertDestructive() { - return ( - - - Error - - Your session has expired. Please log in again. - - - ) -} diff --git a/apps/design-system/registry/default/example/alert-dialog-close-only.tsx b/apps/design-system/registry/default/example/alert-dialog-close-only.tsx new file mode 100644 index 00000000000..204d3e3b970 --- /dev/null +++ b/apps/design-system/registry/default/example/alert-dialog-close-only.tsx @@ -0,0 +1,33 @@ +import { + AlertDialog, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, + Button, +} from 'ui' + +export default function AlertDialogCloseOnly() { + return ( + + + + + + + Application submitted + + Thank you for your submission! Please check your email for a confirmation link to + complete your application. + + + + Close + + + + ) +} diff --git a/apps/design-system/registry/default/example/alert-dialog-demo.tsx b/apps/design-system/registry/default/example/alert-dialog-demo.tsx index 38f358327a4..447be8975eb 100644 --- a/apps/design-system/registry/default/example/alert-dialog-demo.tsx +++ b/apps/design-system/registry/default/example/alert-dialog-demo.tsx @@ -8,26 +8,27 @@ import { AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, + Button, } from 'ui' -import { Button } from 'ui' export default function AlertDialogDemo() { return ( - + - Are you absolutely sure? + Create new API keys - This action cannot be undone. This will permanently delete your account and remove your - data from our servers. + This will create a default publishable key and a default secret key both named{' '} + default. These keys are required to connect + your application to your Supabase project. Cancel - Continue + Create keys diff --git a/apps/design-system/registry/default/example/alert-dialog-destructive.tsx b/apps/design-system/registry/default/example/alert-dialog-destructive.tsx new file mode 100644 index 00000000000..6edea2532a1 --- /dev/null +++ b/apps/design-system/registry/default/example/alert-dialog-destructive.tsx @@ -0,0 +1,37 @@ +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, + Button, +} from 'ui' + +export default function AlertDialogDestructive() { + return ( + + + + + + + + Delete hello-world + + + This action cannot be undone. Ensure that you have a backup in case you want to restore + this edge function. + + + + Cancel + Delete + + + + ) +} diff --git a/apps/design-system/registry/default/example/alert-dialog-warning.tsx b/apps/design-system/registry/default/example/alert-dialog-warning.tsx new file mode 100644 index 00000000000..8b95feaa82a --- /dev/null +++ b/apps/design-system/registry/default/example/alert-dialog-warning.tsx @@ -0,0 +1,35 @@ +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, + Button, +} from 'ui' + +export default function AlertDialogWarning() { + return ( + + + + + + + Update branch + + This branch has 3 modified edge functions that will be overwritten when updating with + the latest functions from the production branch. This action cannot be undone. + + + + Cancel + Update + + + + ) +} diff --git a/apps/design-system/registry/default/example/badge-demo.tsx b/apps/design-system/registry/default/example/badge-demo.tsx index d34f2ce7052..13528c3c7ca 100644 --- a/apps/design-system/registry/default/example/badge-demo.tsx +++ b/apps/design-system/registry/default/example/badge-demo.tsx @@ -1,5 +1,5 @@ import { Badge } from 'ui' export default function BadgeDemo() { - return Badge + return Default } diff --git a/apps/design-system/registry/default/example/badge-destructive.tsx b/apps/design-system/registry/default/example/badge-destructive.tsx deleted file mode 100644 index a1d3b2ce590..00000000000 --- a/apps/design-system/registry/default/example/badge-destructive.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Badge } from 'ui' - -export default function BadgeDestructive() { - return Destructive -} diff --git a/apps/design-system/registry/default/example/badge-outline.tsx b/apps/design-system/registry/default/example/badge-outline.tsx deleted file mode 100644 index 780711720d4..00000000000 --- a/apps/design-system/registry/default/example/badge-outline.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { Badge } from 'ui' - -export default function BadgeOutline() { - return Outline -} diff --git a/apps/design-system/registry/default/example/badge-state.tsx b/apps/design-system/registry/default/example/badge-state.tsx new file mode 100644 index 00000000000..2fe91c5ba6c --- /dev/null +++ b/apps/design-system/registry/default/example/badge-state.tsx @@ -0,0 +1,12 @@ +import { Badge } from 'ui' + +export default function BadgeState() { + return ( +
+ Default + Warning + Success + Destructive +
+ ) +} diff --git a/apps/design-system/registry/default/example/confirmation-modal-demo.tsx b/apps/design-system/registry/default/example/confirmation-modal-demo.tsx new file mode 100644 index 00000000000..dc1d91e32d1 --- /dev/null +++ b/apps/design-system/registry/default/example/confirmation-modal-demo.tsx @@ -0,0 +1,75 @@ +import { useState } from 'react' +import { useForm } from 'react-hook-form' +import { + Button, + Form_Shadcn_, + FormControl_Shadcn_, + FormField_Shadcn_, + Select_Shadcn_, + SelectContent_Shadcn_, + SelectItem_Shadcn_, + SelectTrigger_Shadcn_, + SelectValue_Shadcn_, +} from 'ui' +import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' +import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' + +export default function ConfirmationModalDemo() { + const [visible, setVisible] = useState(false) + const form = useForm({ + defaultValues: { + postgresVersion: '17.6.1.054', + }, + }) + + return ( + <> + + setVisible(false)} + onConfirm={() => {}} + loading={false} + confirmLabel="Resume" + confirmLabelLoading="Resuming" + cancelLabel="Cancel" + > + {/* Dialog contents */} +
+ {/* Text content */} +

+ Your project’s data will be restored to when it was initially paused. +

+ {/* Dropdown for Postgres version */} +
+ + ( + + + + + + + + 17.6.1.054 + 17.6.1.055 + + + + + )} + /> + +
+
+
+ + ) +} diff --git a/apps/design-system/registry/default/example/copy-button-verbs.tsx b/apps/design-system/registry/default/example/copy-button-verbs.tsx new file mode 100644 index 00000000000..3cf3c071531 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-button-verbs.tsx @@ -0,0 +1,22 @@ +'use client' + +import { Button } from 'ui' + +export default function CopyButtonVerbs() { + return ( +
+
+ Bad Example + + + +
+
+ Good Example + + + +
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-confirmations.tsx b/apps/design-system/registry/default/example/copy-confirmations.tsx new file mode 100644 index 00000000000..ce9406cbfc9 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-confirmations.tsx @@ -0,0 +1,54 @@ +'use client' + +import { Button } from 'ui' +import { AlertTriangle } from 'lucide-react' + +export default function CopyConfirmations() { + return ( +
+
+ Bad Example +
+
+
+

Are you sure?

+

+ All data will be removed if this project is deleted +

+
+
+
+ + +
+
+
+
+ Good Example +
+
+
+

Delete this project?

+

+ This action cannot be undone and will permanently delete all data. Deleting this + project will remove all data. +

+
+
+
+ + +
+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-empty-states.tsx b/apps/design-system/registry/default/example/copy-empty-states.tsx new file mode 100644 index 00000000000..1315f8e42b6 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-empty-states.tsx @@ -0,0 +1,34 @@ +'use client' + +import { Button } from 'ui' +import { EmptyStatePresentational } from 'ui-patterns' +import { Key } from 'lucide-react' + +export default function CopyEmptyStates() { + return ( +
+
+ Bad Example +
+ +
+
+
+ Good Example +
+ + + +
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-error-messages.tsx b/apps/design-system/registry/default/example/copy-error-messages.tsx new file mode 100644 index 00000000000..7a19c25ca31 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-error-messages.tsx @@ -0,0 +1,24 @@ +'use client' + +import { CircleAlert } from 'lucide-react' + +export default function CopyErrorMessages() { + return ( +
+
+ Bad Example +
+ +

Something went wrong. Please try again.

+
+
+
+ Good Example +
+ +

Invalid API key. Check your project settings.

+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-form-labels.tsx b/apps/design-system/registry/default/example/copy-form-labels.tsx new file mode 100644 index 00000000000..099afe5b906 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-form-labels.tsx @@ -0,0 +1,29 @@ +'use client' + +import { Input_Shadcn_, Label_Shadcn_ } from 'ui' + +export default function CopyFormLabels() { + return ( +
+
+ Bad Example +
+ Name your table + +

+ This field allows you to specify a name for your table using letters, numbers, and + underscores +

+
+
+
+ Good Example +
+ Table name + +

Letters, numbers, and underscores only

+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-loading-states.tsx b/apps/design-system/registry/default/example/copy-loading-states.tsx new file mode 100644 index 00000000000..db1259dc196 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-loading-states.tsx @@ -0,0 +1,38 @@ +'use client' + +import { Button } from 'ui' + +export default function CopyLoadingStates() { + return ( +
+
+ Bad Example +
+ + + +
+
+
+ Good Example +
+ + + +
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-success-messages.tsx b/apps/design-system/registry/default/example/copy-success-messages.tsx new file mode 100644 index 00000000000..d5589fede23 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-success-messages.tsx @@ -0,0 +1,24 @@ +'use client' + +import { CheckCircle } from 'lucide-react' + +export default function CopySuccessMessages() { + return ( +
+
+ Bad Example +
+ +

Success!

+
+
+
+ Good Example +
+ +

Table created successfully

+
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/copy-tooltips.tsx b/apps/design-system/registry/default/example/copy-tooltips.tsx new file mode 100644 index 00000000000..594c5622533 --- /dev/null +++ b/apps/design-system/registry/default/example/copy-tooltips.tsx @@ -0,0 +1,51 @@ +'use client' + +import { Button, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from 'ui' +import { Info } from 'lucide-react' + +export default function CopyTooltips() { + return ( +
+
+ Bad Example +
+ + + +
+
+
+ Good Example +
+ + + +
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/data-grid-demo.tsx b/apps/design-system/registry/default/example/data-grid-demo.tsx new file mode 100644 index 00000000000..b2a1906e287 --- /dev/null +++ b/apps/design-system/registry/default/example/data-grid-demo.tsx @@ -0,0 +1,166 @@ +import { useState } from 'react' +import DataGrid, { Column, useRowSelection } from 'react-data-grid' +import 'react-data-grid/lib/styles.css' +import { Checkbox_Shadcn_, cn } from 'ui' + +type User = { + id: string + name: string + email: string + phone: string +} + +/** + * Render a data grid demo with selectable rows and sample user data. + * + * Renders a DataGrid configured with a checkbox column for per-row selection, columns for display name, + * email, and phone, and ten hard-coded sample users. Selection state is managed internally and applied + * to row styling. + * + * @returns A React element that renders the configured DataGrid with row selection and sample rows. + */ +export default function DataGridDemo() { + const [selectedRows, setSelectedRows] = useState>(new Set()) + + const columns: Column[] = [ + { + key: 'checkbox', + name: '', + width: 50, + resizable: false, + headerCellClass: 'border-default border-r border-b', + renderCell: ({ row }) => { + // eslint-disable-next-line react-hooks/rules-of-hooks + const [isRowSelected, onRowSelectionChange] = useRowSelection() + + return ( +
+ { + e.stopPropagation() + onRowSelectionChange({ + row, + type: 'ROW', + checked: !isRowSelected, + isShiftClick: e.shiftKey, + }) + }} + /> +
+ ) + }, + }, + { + key: 'name', + name: 'Display name', + minWidth: 200, + resizable: true, + headerCellClass: 'border-default border-r border-b', + }, + { + key: 'email', + name: 'Email', + minWidth: 250, + resizable: true, + headerCellClass: 'border-default border-r border-b', + }, + { + key: 'phone', + name: 'Phone', + minWidth: 150, + resizable: true, + headerCellClass: 'border-default border-b', + }, + ] + + const rows: User[] = [ + { + id: '1', + name: 'Wallace', + email: 'wallace@example.com', + phone: '+44 1234 567890', + }, + { + id: '2', + name: 'Gromit', + email: 'gromit@example.com', + phone: '+44 1234 567891', + }, + { + id: '3', + name: 'Wendolene Ramsbottom', + email: 'wendolene@example.com', + phone: '+44 1234 567892', + }, + { + id: '4', + name: 'Feathers McGraw', + email: 'feathers@example.com', + phone: '+44 1234 567893', + }, + { + id: '5', + name: 'Preston', + email: 'preston@example.com', + phone: '+44 1234 567894', + }, + { + id: '6', + name: 'Piella Bakewell', + email: 'piella@example.com', + phone: '+44 1234 567895', + }, + { + id: '7', + name: 'Victor Quartermaine', + email: 'victor@example.com', + phone: '+44 1234 567896', + }, + { + id: '8', + name: 'Lady Tottington', + email: 'lady@example.com', + phone: '+44 1234 567897', + }, + { + id: '9', + name: 'Shaun', + email: 'shaun@example.com', + phone: '+44 1234 567898', + }, + { + id: '10', + name: 'Hutch', + email: 'hutch@example.com', + phone: '+44 1234 567899', + }, + ] + + return ( +
+ row.id} + rowClass={(row, idx) => { + const isSelected = selectedRows.has(row.id) + const isLastRow = idx === rows.length - 1 + return cn( + 'bg-surface-75', + isSelected && 'bg-surface-200', + '[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none', + '[&>.rdg-cell]:border-secondary [&>.rdg-cell:not(:last-child)]:border-r', + !isLastRow && '[&>.rdg-cell]:border-b', + '[&>.rdg-cell:nth-child(2)>div]:ml-8' + ) + }} + selectedRows={selectedRows} + onSelectedRowsChange={setSelectedRows} + /> +
+ ) +} diff --git a/apps/design-system/registry/default/example/empty-state-zero-items-data-grid.tsx b/apps/design-system/registry/default/example/data-grid-empty-state.tsx similarity index 81% rename from apps/design-system/registry/default/example/empty-state-zero-items-data-grid.tsx rename to apps/design-system/registry/default/example/data-grid-empty-state.tsx index c6fb5657eb8..048385d5d12 100644 --- a/apps/design-system/registry/default/example/empty-state-zero-items-data-grid.tsx +++ b/apps/design-system/registry/default/example/data-grid-empty-state.tsx @@ -3,7 +3,14 @@ import DataGrid, { Column } from 'react-data-grid' import 'react-data-grid/lib/styles.css' import { cn } from 'ui' -export default function EmptyStateZeroItemsDataGrid() { +/** + * Renders a DataGrid configured to display an empty "no users" state. + * + * The grid includes three columns (Display name, Email, Phone) and no rows, and supplies a centered overlay with an icon and explanatory text when there are no rows. + * + * @returns A React element containing the configured DataGrid with an empty-state fallback UI. + */ +export default function DataGridEmptyState() { const columns: Column<{ id: string; name: string; email: string }>[] = [ { key: 'name', name: 'Display name', minWidth: 200, resizable: true }, { key: 'email', name: 'Email', minWidth: 250, resizable: true }, diff --git a/apps/design-system/registry/default/example/data-table-demo.tsx b/apps/design-system/registry/default/example/data-table-demo.tsx new file mode 100644 index 00000000000..926ecd3db7e --- /dev/null +++ b/apps/design-system/registry/default/example/data-table-demo.tsx @@ -0,0 +1,349 @@ +'use client' + +import { + ColumnDef, + ColumnFiltersState, + flexRender, + getCoreRowModel, + getFilteredRowModel, + getPaginationRowModel, + getSortedRowModel, + SortingState, + useReactTable, + VisibilityState, +} from '@tanstack/react-table' +import { ChevronDown, MoreVertical } from 'lucide-react' +import * as React from 'react' + +import { + Button, + Card, + Checkbox_Shadcn_, + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, + Input, + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableHeadSort, + TableRow, +} from 'ui' + +const data: Payment[] = [ + { + id: 'm5gr84i9', + amount: 316, + status: 'success', + email: 'wallace@example.com', + }, + { + id: '3u1reuv4', + amount: 242, + status: 'success', + email: 'wendolene@example.com', + }, + { + id: 'derv1ws0', + amount: 837, + status: 'processing', + email: 'piella@example.com', + }, + { + id: '5kma53ae', + amount: 874, + status: 'success', + email: 'victor@example.com', + }, + { + id: 'bhqecj4p', + amount: 721, + status: 'failed', + email: 'feathers@example.com', + }, +] + +export type Payment = { + id: string + amount: number + status: 'pending' | 'processing' | 'success' | 'failed' + email: string +} + +export const columns: ColumnDef[] = [ + { + id: 'select', + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + }, + { + accessorKey: 'status', + header: 'Status', + enableSorting: true, + cell: ({ row }) =>
{row.getValue('status')}
, + }, + { + accessorKey: 'email', + header: 'Email', + enableSorting: true, + cell: ({ row }) =>
{row.getValue('email')}
, + }, + { + accessorKey: 'amount', + header: () =>
Amount
, + enableSorting: true, + cell: ({ row }) => { + const amount = parseFloat(row.getValue('amount')) + + // Format the amount as a dollar amount + const formatted = new Intl.NumberFormat('en-US', { + style: 'currency', + currency: 'USD', + }).format(amount) + + return
{formatted}
+ }, + }, + { + id: 'actions', + enableHiding: false, + header: () => Actions, + cell: ({ row }) => { + const payment = row.original + + return ( + + + + + + {table + .getAllColumns() + .filter((column) => column.getCanHide()) + .map((column) => { + return ( + column.toggleVisibility(!!value)} + > + {column.id} + + ) + })} + + + + {/* Table */} + + + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + const columnId = header.column.id + const canSort = header.column.getCanSort() + + return ( + + {header.isPlaceholder ? null : canSort ? ( + + {flexRender(header.column.columnDef.header, header.getContext())} + + ) : ( + flexRender(header.column.columnDef.header, header.getContext()) + )} + + ) + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + ) : ( + + +

No results found

+

+ Your search did not return any results +

+
+
+ )} +
+
+
+ {/* Count and pagination controls */} +
+
+ {table.getFilteredSelectedRowModel().rows.length} of{' '} + {table.getFilteredRowModel().rows.length} row(s) selected +
+
+ + +
+
+ + ) +} diff --git a/apps/design-system/registry/default/example/dialog-centered-off.tsx b/apps/design-system/registry/default/example/dialog-centered-off.tsx index 54713321a25..fd32ad1d7a4 100644 --- a/apps/design-system/registry/default/example/dialog-centered-off.tsx +++ b/apps/design-system/registry/default/example/dialog-centered-off.tsx @@ -1,29 +1,31 @@ -import { Button, DialogSection, DialogSectionSeparator } from 'ui' import { + Button, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, + DialogSection, + DialogSectionSeparator, DialogTitle, DialogTrigger, + Input_Shadcn_, + Label_Shadcn_, } from 'ui' -import { Input_Shadcn_ } from 'ui' -import { Label_Shadcn_ } from 'ui' export default function DialogDemo() { return ( - + - + This dialog is not centered. This dialog is not centered. - +
Name @@ -37,7 +39,7 @@ export default function DialogDemo() {
- +
diff --git a/apps/design-system/registry/default/example/dialog-close-button.tsx b/apps/design-system/registry/default/example/dialog-close-button.tsx index 4c45847ef7b..1194933899b 100644 --- a/apps/design-system/registry/default/example/dialog-close-button.tsx +++ b/apps/design-system/registry/default/example/dialog-close-button.tsx @@ -1,18 +1,20 @@ import { Copy } from 'lucide-react' -import { Button, DialogSection, DialogSectionSeparator } from 'ui' import { + Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, + DialogSection, + DialogSectionSeparator, DialogTitle, DialogTrigger, + Input_Shadcn_, + Label_Shadcn_, } from 'ui' -import { Input_Shadcn_ } from 'ui' -import { Label_Shadcn_ } from 'ui' export default function DialogCloseButton() { return ( @@ -21,12 +23,12 @@ export default function DialogCloseButton() { - + Share link Anyone who has this link will be able to view this. - +
@@ -44,7 +46,7 @@ export default function DialogCloseButton() {
- + + - + Edit profile - - Make changes to your profile here. Click save when you're done. - + Make changes to your profile here. - +
- - Name - - + Name +
- - Username - - + Username +
- - + +
diff --git a/apps/design-system/registry/default/example/drawer-dialog.tsx b/apps/design-system/registry/default/example/drawer-dialog.tsx index a89ce2117b8..599cd5bd8b0 100644 --- a/apps/design-system/registry/default/example/drawer-dialog.tsx +++ b/apps/design-system/registry/default/example/drawer-dialog.tsx @@ -2,18 +2,16 @@ import * as React from 'react' -import { cn } from '@/lib/utils' import { useMediaQuery } from '@/hooks/use-media-query' -import { Button } from 'ui' +import { cn } from '@/lib/utils' import { + Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger, -} from 'ui' -import { Drawer, DrawerClose, DrawerContent, @@ -22,9 +20,9 @@ import { DrawerHeader, DrawerTitle, DrawerTrigger, + Input_Shadcn_, + Label_Shadcn_, } from 'ui' -import { Input_Shadcn_ } from 'ui' -import { Label_Shadcn_ } from 'ui' export default function DrawerDialogDemo() { const [open, setOpen] = React.useState(false) @@ -34,7 +32,7 @@ export default function DrawerDialogDemo() { return ( - + @@ -52,7 +50,7 @@ export default function DrawerDialogDemo() { return ( - + diff --git a/apps/design-system/registry/default/example/empty-state-initial-state-presentational.tsx b/apps/design-system/registry/default/example/empty-state-initial-state-presentational.tsx deleted file mode 100644 index 81ace8d4713..00000000000 --- a/apps/design-system/registry/default/example/empty-state-initial-state-presentational.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { BucketAdd } from 'icons' -import { Plus } from 'lucide-react' -import { Button } from 'ui' - -export default function EmptyStateInitialStatePresentational() { - return ( - - ) -} diff --git a/apps/design-system/registry/default/example/empty-state-missing-route.tsx b/apps/design-system/registry/default/example/empty-state-missing-route.tsx index 0c0f9b63ea4..004dd0e1cbc 100644 --- a/apps/design-system/registry/default/example/empty-state-missing-route.tsx +++ b/apps/design-system/registry/default/example/empty-state-missing-route.tsx @@ -17,7 +17,7 @@ export default function EmptyStateMissingRoute() { { - e.preventDefault() + e.preventDefault() // Just for demo purposes }} > Head back diff --git a/apps/design-system/registry/default/example/empty-state-presentational-buttons.tsx b/apps/design-system/registry/default/example/empty-state-presentational-buttons.tsx new file mode 100644 index 00000000000..45eef4ae0a7 --- /dev/null +++ b/apps/design-system/registry/default/example/empty-state-presentational-buttons.tsx @@ -0,0 +1,41 @@ +import { Plus } from 'lucide-react' +import { Button } from 'ui' +import { EmptyStatePresentational } from 'ui-patterns' + +import { + PageSection, + PageSectionAside, + PageSectionContent, + PageSectionMeta, + PageSectionSummary, + PageSectionTitle, +} from 'ui-patterns/PageSection' + +export default function EmptyStatePresentationalIcon() { + return ( +
+ + + + Providers + + + + + + + + + + + +
+ ) +} diff --git a/apps/design-system/registry/default/example/empty-state-presentational-demo.tsx b/apps/design-system/registry/default/example/empty-state-presentational-demo.tsx new file mode 100644 index 00000000000..7b79318535a --- /dev/null +++ b/apps/design-system/registry/default/example/empty-state-presentational-demo.tsx @@ -0,0 +1,16 @@ +import { Plus } from 'lucide-react' +import { Button } from 'ui' +import { EmptyStatePresentational } from 'ui-patterns' + +export default function EmptyStatePresentationalIcon() { + return ( + + + + ) +} diff --git a/apps/design-system/registry/default/example/empty-state-presentational-icon.tsx b/apps/design-system/registry/default/example/empty-state-presentational-icon.tsx new file mode 100644 index 00000000000..2da35261df0 --- /dev/null +++ b/apps/design-system/registry/default/example/empty-state-presentational-icon.tsx @@ -0,0 +1,18 @@ +import { BucketPlus } from 'icons' +import { Plus } from 'lucide-react' +import { Button } from 'ui' +import { EmptyStatePresentational } from 'ui-patterns' + +export default function EmptyStatePresentationalIcon() { + return ( + + + + ) +} diff --git a/apps/design-system/registry/default/example/empty-state-zero-items-table.tsx b/apps/design-system/registry/default/example/empty-state-zero-items-table.tsx index f2a5e37dfc1..385c9ed8172 100644 --- a/apps/design-system/registry/default/example/empty-state-zero-items-table.tsx +++ b/apps/design-system/registry/default/example/empty-state-zero-items-table.tsx @@ -6,9 +6,9 @@ export default function EmptyStateZeroItemsTable() { - Table name - Date created - + Name + Created + Updated diff --git a/apps/design-system/registry/default/example/field-checkbox.tsx b/apps/design-system/registry/default/example/field-checkbox.tsx new file mode 100644 index 00000000000..67d21658b65 --- /dev/null +++ b/apps/design-system/registry/default/example/field-checkbox.tsx @@ -0,0 +1,67 @@ +import { Checkbox_Shadcn_ as Checkbox } from 'ui' +import { + Field, + FieldContent, + FieldDescription, + FieldGroup, + FieldLabel, + FieldLegend, + FieldSeparator, + FieldSet, +} from 'ui/src/components/shadcn/ui/field' + +export default function FieldCheckbox() { + return ( +
+ +
+ Show these items on the desktop + Select the items you want to show on the desktop. + + + + + Hard disks + + + + + + External disks + + + + + + CDs, DVDs, and iPods + + + + + + Connected servers + + + +
+ + + + + + Sync Desktop & Documents folders + + + Your Desktop & Documents folders are being synced with iCloud Drive. You can access + them from other devices. + + + +
+
+ ) +} diff --git a/apps/design-system/registry/default/example/field-choice-card.tsx b/apps/design-system/registry/default/example/field-choice-card.tsx new file mode 100644 index 00000000000..c4b0d6dd8c5 --- /dev/null +++ b/apps/design-system/registry/default/example/field-choice-card.tsx @@ -0,0 +1,47 @@ +import { + FieldSet, + FieldLabel, + FieldDescription, + Field, + FieldContent, + FieldGroup, + FieldTitle, +} from 'ui/src/components/shadcn/ui/field' +import { RadioGroup, RadioGroupItem } from 'ui/src/components/shadcn/ui/radio-group' + +export default function FieldChoiceCard() { + return ( +
+ +
+ Compute Environment + Select the compute environment for your cluster. + + + + + Kubernetes + + Run GPU workloads on a K8s configured cluster. + + + + + + + + + Virtual Machine + + Access a VM configured cluster to run GPU workloads. + + + + + + +
+
+
+ ) +} diff --git a/apps/design-system/registry/default/example/field-demo.tsx b/apps/design-system/registry/default/example/field-demo.tsx new file mode 100644 index 00000000000..c97bfbc677b --- /dev/null +++ b/apps/design-system/registry/default/example/field-demo.tsx @@ -0,0 +1,124 @@ +import { Input, Checkbox_Shadcn_ as Checkbox, Textarea, Button } from 'ui' +import { + FieldSet, + FieldLegend, + FieldDescription, + Field, + FieldLabel, + FieldGroup, + FieldSeparator, +} from 'ui/src/components/shadcn/ui/field' +import { + Select, + SelectTrigger, + SelectValue, + SelectContent, + SelectItem, +} from 'ui/src/components/shadcn/ui/select' + +export default function FieldDemo() { + return ( +
+
+ +
+ Payment Method + All transactions are secure and encrypted + + + Name on Card + + + + Card Number + + Enter your 16-digit card number + +
+ + Month + + + + Year + + + + CVV + + +
+
+
+ +
+ Billing Address + + The billing address associated with your payment method + + + + + + Same as shipping address + + + +
+
+ + + Comments +