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 02c50f7416d..bc1ca8cc089 100644 --- a/.github/workflows/fix-typos.yml +++ b/.github/workflows/fix-typos.yml @@ -10,8 +10,7 @@ concurrency: cancel-in-progress: true permissions: - contents: write - pull-requests: write + contents: read 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/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 index b8b4226b25d..ffb9c43ca95 100644 --- a/.github/workflows/validate-pr.yml +++ b/.github/workflows/validate-pr.yml @@ -1,5 +1,6 @@ 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] diff --git a/.gitignore b/.gitignore index 164a3881bb8..5d4494d1cbd 100644 --- a/.gitignore +++ b/.gitignore @@ -117,7 +117,9 @@ next-env.d.ts .vercel # AI assistant local files -.claude/ +.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/.prettierrc b/.prettierrc deleted file mode 100644 index 58dc1645bf8..00000000000 --- a/.prettierrc +++ /dev/null @@ -1,16 +0,0 @@ -{ - "trailingComma": "es5", - "tabWidth": 2, - "semi": false, - "singleQuote": true, - "printWidth": 100, - "endOfLine": "lf", - "sqlKeywordCase": "lower", - "plugins": ["prettier-plugin-sql-cst"], - "overrides": [ - { - "files": "**/*.json", - "options": { "parser": "json" } - } - ] -} diff --git a/DEVELOPERS.md b/DEVELOPERS.md index d97159286e1..d228ea7b169 100644 --- a/DEVELOPERS.md +++ b/DEVELOPERS.md @@ -35,7 +35,7 @@ To ensure a positive and inclusive environment, please read our [code of conduct You will need to install and configure the following dependencies on your machine to build [Supabase](https://supabase.com): - [Git](https://git-scm.com/) -- [Node.js v22.x or higher](https://nodejs.org) +- [Node.js](https://nodejs.org) version as documented in [.nvmrc](./.nvmrc) - [pnpm](https://pnpm.io/) version 9.x.x or higher - [make](https://www.gnu.org/software/make/) or the equivalent to `build-essentials` for your OS - [Docker](https://docs.docker.com/get-docker/) (to run studio locally) diff --git a/README.md b/README.md index 1e438a1917a..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 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 59e7e54043f..fc94395ea85 100644 --- a/apps/design-system/__registry__/index.tsx +++ b/apps/design-system/__registry__/index.tsx @@ -38,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", @@ -148,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", @@ -170,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", @@ -1259,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", @@ -1303,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", @@ -1358,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", @@ -1369,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", @@ -1765,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", @@ -1842,6 +1908,138 @@ 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", @@ -2040,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", @@ -2271,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: [] @@ -2524,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: [] @@ -2689,149 +2887,6 @@ 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", - 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", - 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", - 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", - 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", - 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", - 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", - 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", - 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", - 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", - chunks: [] - }, "chart-bar-interactive": { name: "chart-bar-interactive", type: "components:block", @@ -2843,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) { + + )} + {doc.links?.api && ( + + )} + + ) : null} + + + ) + } + } + return (
+ {/* */}
) 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 ( -
-
-