studio(chore): badge component defrag (#40118)

* component clean up

* optically center

* docs and type size

* code badge variant

* sensible defaults

* fix product menu flex

* badge sweep

* new project badges

* logs

* compute badge

* studio badge sweep

* www sweep

* docs sweep

* clean up

* fixes

* cleanup

* fixes

* better docs

* fixes

* misc fixes

* consistency

* Minor fixes for issues i found

* simplify mt-0

* mt simplification

* remaining optical alignment

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Danny WhiteandJoshen Lim authored and GitHub committed 2025-12-02 11:15:50 +11:00
1 parent 0a024516ad
commit 031b227165
96 files changed
+363 -574

No files matched your search

+4 -15
View File
@@ -192,24 +192,13 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"badge-destructive": {
name: "badge-destructive",
"badge-state": {
name: "badge-state",
type: "components:example",
registryDependencies: ["badge"],
component: React.lazy(() => import("@/registry/default/example/badge-destructive")),
component: React.lazy(() => import("@/registry/default/example/badge-state")),
source: "",
files: ["registry/default/example/badge-destructive.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"badge-outline": {
name: "badge-outline",
type: "components:example",
registryDependencies: ["badge"],
component: React.lazy(() => import("@/registry/default/example/badge-outline")),
source: "",
files: ["registry/default/example/badge-outline.tsx"],
files: ["registry/default/example/badge-state.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
+3 -15
View File
@@ -3,9 +3,9 @@ import Link from 'next/link'
import { forwardRef } from 'react'
import { ExternalLink } from 'lucide-react'
import Image from 'next/image'
import { Button } from 'ui'
import { cn } from 'ui/src/lib/utils/cn'
import Image from 'next/image'
const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> & { doc: Doc }>(
({ doc, children, ...props }, ref) => {
@@ -133,13 +133,7 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
className="rounded-full"
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
>
<Link
href={doc.links.api}
target="_blank"
rel="noreferrer"
// className={cn(badgeVariants({ variant: 'default' }), 'gap-1')}
>
<Link href={doc.links.api} target="_blank" rel="noreferrer">
API Reference
</Link>
</Button>
@@ -233,13 +227,7 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
className="rounded-full"
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
>
<Link
href={doc.links.api}
target="_blank"
rel="noreferrer"
// className={cn(badgeVariants({ variant: 'default' }), 'gap-1')}
>
<Link href={doc.links.api} target="_blank" rel="noreferrer">
API Reference
</Link>
</Button>
@@ -1,44 +1,12 @@
---
title: Badge
description: Displays a badge or a component that looks like a badge.
description: Add contextual metadata to another item.
component: true
source:
shadcn: true
---
<ComponentPreview name="badge-demo" peekCode wide />
Badge displays contextual information such as surrounding state or product category. Its purpose should be be self-evident based on surrounding context.
## Installation
<Tabs defaultValue="cli">
<TabsList>
<TabsTrigger value="cli">CLI</TabsTrigger>
<TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">
```bash
npx shadcn-ui@latest add badge
```
</TabsContent>
<TabsContent value="manual">
<Steps>
<Step>Copy and paste the following code into your project.</Step>
<ComponentSource name="badge" />
<Step>Update the import paths to match your project setup.</Step>
</Steps>
</TabsContent>
</Tabs>
<ComponentPreview name="badge-demo" peekCode />
## Usage
@@ -47,41 +15,23 @@ import { Badge } from '@/components/ui/badge'
```
```tsx
<Badge variant="outline">Badge</Badge>
<Badge variant="default">Default</Badge>
```
### Link
Avoid altering the Badge style, such as text case or roundedness. Consistent implementation makes Badge immediately recognizable throughout Supabase for denoting state or category. Use or create another component for other use cases, such as compute size and status.
You can use the `badgeVariants` helper to create a link that looks like a badge.
Keep Badge text to one or two words as it is designed to support other elements, not as a primary communication aid.
```tsx
import { badgeVariants } from '@/components/ui/badge'
```
```tsx
<Link className={badgeVariants({ variant: 'outline' })}>Badge</Link>
```
Badge is designed to stand out, so should be used sparingly.
## Examples
### Default
### States
<ComponentPreview name="badge-demo" peekCode wide />
---
<ComponentPreview name="badge-state" peekCode />
### Secondary
<ComponentPreview name="badge-secondary" />
A content-only variant similar to the `text` variant of [Button](../components/button#types).
---
### Outline
<ComponentPreview name="badge-outline" />
---
### Destructive
<ComponentPreview name="badge-destructive" />
<ComponentPreview name="badge-secondary" peekCode />
@@ -1,5 +1,5 @@
import { Badge } from 'ui'
export default function BadgeDemo() {
return <Badge>Badge</Badge>
return <Badge>Default</Badge>
}
@@ -1,5 +0,0 @@
import { Badge } from 'ui'
export default function BadgeDestructive() {
return <Badge variant="destructive">Destructive</Badge>
}
@@ -1,5 +0,0 @@
import { Badge } from 'ui'
export default function BadgeOutline() {
return <Badge variant="outline">Outline</Badge>
}
@@ -0,0 +1,12 @@
import { Badge } from 'ui'
export default function BadgeState() {
return (
<div className="flex flex-row gap-2">
<Badge variant="default">Default</Badge>
<Badge variant="warning">Warning</Badge>
<Badge variant="success">Success</Badge>
<Badge variant="destructive">Destructive</Badge>
</div>
)
}
@@ -32,9 +32,7 @@ export default function ModalVerticalCustomFooter() {
customFooter={
<div className="flex items-center gap-3">
<div>
<Badge variant="destructive" dot size="small">
Proceed with caution
</Badge>
<Badge variant="destructive">Proceed with caution</Badge>
</div>
<Button type="secondary">Cancel</Button>
<Button type="danger">Delete</Button>
+2 -8
View File
@@ -62,16 +62,10 @@ export const examples: Registry = [
files: ['example/badge-demo.tsx'],
},
{
name: 'badge-destructive',
name: 'badge-state',
type: 'components:example',
registryDependencies: ['badge'],
files: ['example/badge-destructive.tsx'],
},
{
name: 'badge-outline',
type: 'components:example',
registryDependencies: ['badge'],
files: ['example/badge-outline.tsx'],
files: ['example/badge-state.tsx'],
},
{
name: 'badge-secondary',
@@ -179,7 +179,7 @@ export const MenuItem = React.forwardRef<
<>
{icon && <MenuIconPicker icon={icon} className="text-foreground-lighter" />}
<span className="flex-1">{title}</span>
{community && <Badge size="small">Community</Badge>}
{community && <Badge>Community</Badge>}
</>
)}
</Link>
+7 -11
View File
@@ -1,6 +1,8 @@
import { XCircle } from 'lucide-react'
import { FC, PropsWithChildren, useState } from 'react'
import { Badge } from 'ui'
interface IOptions {
name?: string
}
@@ -56,17 +58,11 @@ const Option: FC<IOption> = (props) => {
</span>
{!props.isEnum && (
<>
<span>
{props.isOptional ? (
<div className="text-[10px] px-3 tracking-wide font-mono text-foreground-lighter">
Optional
</div>
) : (
<div className="text-[10px] border border-amber-700 bg-amber-300 text-amber-900 px-2 tracking-wide font-mono py-0.25 rounded-full">
REQUIRED
</div>
)}
</span>
{props.isOptional ? (
<Badge variant="default">Optional</Badge>
) : (
<Badge variant="warning">Required</Badge>
)}
<span className="text-foreground-muted text-xs">{props.type ?? 'no type'}</span>
</>
)}
+7 -11
View File
@@ -1,5 +1,7 @@
import { ReactMarkdown } from 'react-markdown/lib/react-markdown'
import { Badge } from 'ui'
type IParamProps = any
/**
@@ -12,17 +14,11 @@ const Param = ({ name, isOptional, type, description, children, isPrimitive }: I
{!isPrimitive && (
<span className="text-sm text-foreground font-mono font-medium">{name ?? 'no-name'}</span>
)}
<span>
{isOptional ? (
<div className="text-[10px] px-3 tracking-wide font-mono text-foreground-lighter">
Optional
</div>
) : (
<div className="text-[10px] border border-amber-700 bg-amber-300 text-amber-900 px-2 tracking-wide font-mono py-0.25 rounded-full">
REQUIRED
</div>
)}
</span>
{isOptional ? (
<Badge variant="default">Optional</Badge>
) : (
<Badge variant="warning">Required</Badge>
)}
<span className="text-foreground-muted text-xs">{type ?? 'no type'}</span>
</div>
{description && (
+1 -1
View File
@@ -71,7 +71,7 @@ const RevVersionDropdown = ({
<span className={`${currentVersion === version ? 'font-bold' : ''}`}>
Version {version}.0
</span>
{index === 0 && <Badge size="small">Latest</Badge>}
{index === 0 && <Badge>Latest</Badge>}
</DropdownMenuItem>
))}
</DropdownMenuContent>
+19 -15
View File
@@ -1,13 +1,17 @@
import { Fragment } from 'react'
import ReactMarkdown from 'react-markdown'
import { Tabs_Shadcn_, TabsContent_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_, cn } from 'ui'
import {
Badge,
cn,
Tabs_Shadcn_,
TabsContent_Shadcn_,
TabsList_Shadcn_,
TabsTrigger_Shadcn_,
} from 'ui'
import { isFeatureEnabled } from 'common'
import ApiSchema from '~/components/ApiSchema'
import { clientSdkIds, REFERENCES } from '~/content/navigation.references'
import { MDXRemoteRefs, getRefMarkdown } from '~/features/docs/Reference.mdx'
import type { MethodTypes } from '~/features/docs/Reference.typeSpec'
import { formatMethodSignature } from '~/features/docs/Reference.typeSpec'
import {
getApiEndpointById,
getCliSpec,
@@ -16,20 +20,22 @@ import {
getSelfHostedApiEndpointById,
getTypeSpec,
} from '~/features/docs/Reference.generated.singleton'
import { type IApiEndPoint } from './Reference.api.utils'
import { getRefMarkdown, MDXRemoteRefs } from '~/features/docs/Reference.mdx'
import type { MethodTypes } from '~/features/docs/Reference.typeSpec'
import { formatMethodSignature } from '~/features/docs/Reference.typeSpec'
import {
ApiOperationRequestBodyDetails,
ApiSchemaParamDetails,
CollapsibleDetails,
FnParameterDetails,
RefSubLayout,
RequiredBadge,
ReturnTypeDetails,
StickyHeader,
} from '~/features/docs/Reference.ui'
import type { AbbrevApiReferenceSection } from '~/features/docs/Reference.utils'
import { normalizeMarkdown } from '~/features/docs/Reference.utils'
import { CodeBlock } from '~/features/ui/CodeBlock/CodeBlock'
import { type IApiEndPoint } from './Reference.api.utils'
import { RefInternalLink } from './Reference.navigation.client'
import { ApiOperationBodySchemeSelector } from './Reference.ui.client'
@@ -211,7 +217,11 @@ async function CliCommandSection({ link, section }: CliCommandSectionProps) {
<span className="font-mono text-sm font-medium text-foreground">
{flag.name}
</span>
<RequiredBadge isOptional={!flag.required} />
{flag.required ? (
<Badge variant="warning">Required</Badge>
) : (
<Badge variant="default">Optional</Badge>
)}
</div>
{flag.description && (
<ReactMarkdown className="prose break-words text-sm">
@@ -304,15 +314,9 @@ async function ApiEndpointSection({ link, section, servicePath }: ApiEndpointSec
<>
{endpointDetails.summary}
{endpointDetails.deprecated && (
<span
className="
uppercase
whitespace-nowrap align-middle inline-block -translate-y-0.5
border border-amber-700 bg-amber-300 text-amber-900
rounded-full font-mono font-medium text-xs px-2 py-0.5 ml-2"
>
<Badge variant="warning" className="ml-2">
deprecated
</span>
</Badge>
)}
</>
}
+17 -25
View File
@@ -3,7 +3,13 @@ import { ChevronRight, XCircle } from 'lucide-react'
import type { HTMLAttributes, PropsWithChildren } from 'react'
import ReactMarkdown from 'react-markdown'
import { cn, Collapsible_Shadcn_, CollapsibleContent_Shadcn_, CollapsibleTrigger_Shadcn_ } from 'ui'
import {
Badge,
cn,
Collapsible_Shadcn_,
CollapsibleContent_Shadcn_,
CollapsibleTrigger_Shadcn_,
} from 'ui'
import ApiSchema from '~/components/ApiSchema'
import { MDXRemoteBase } from '~/features/docs/MdxBase'
@@ -214,11 +220,11 @@ function ParamOrTypeDetails({ paramOrType }: { paramOrType: object }) {
? '[Anonymous]'
: (paramOrType.name as string)}
</span>
<RequiredBadge
isOptional={
'isOptional' in paramOrType ? (paramOrType.isOptional as boolean | 'NA') : false
}
/>
{'isOptional' in paramOrType && paramOrType.isOptional === true ? (
<Badge variant="default">Optional</Badge>
) : 'isOptional' in paramOrType && paramOrType.isOptional === false ? (
<Badge variant="warning">Required</Badge>
) : null}
{/* @ts-ignore */}
{paramOrType?.comment?.tags?.some((tag) => tag.tag === 'deprecated') && (
<span className="text-xs text-warning">Deprecated</span>
@@ -327,24 +333,6 @@ function TypeSubDetails({
)
}
export function RequiredBadge({ isOptional }: { isOptional: boolean | 'NA' }) {
return isOptional === true ? (
<span className="font-mono text-[10px] text-foreground-lighter tracking-wide">Optional</span>
) : isOptional === false ? (
<span
className={cn(
'inline-block',
'px-2 py-0.25 rounded-full',
'-translate-y-[0.125rem]', // retranslate to undo visual misalignment from the y-padding
'border border-amber-700 bg-amber-300',
'font-mono text-[10px] text-amber-900 uppercase tracking-wide'
)}
>
Required
</span>
) : undefined
}
export function ApiSchemaParamDetails({ param }: { param: IApiEndPoint['parameters'][number] }) {
return (
<li className="border-t last-of-type:border-b py-5 flex flex-col gap-3">
@@ -352,7 +340,11 @@ export function ApiSchemaParamDetails({ param }: { param: IApiEndPoint['paramete
<span className="font-mono text-sm font-medium text-foreground break-all">
{param.name}
</span>
<RequiredBadge isOptional={!param.required} />
{param.required ? (
<Badge variant="warning">Required</Badge>
) : (
<Badge variant="default">Optional</Badge>
)}
{param.schema?.deprecated && <span className="text-xs text-warning">Deprecated</span>}
{param.schema && (
<span className="text-xs text-foreground-muted">
@@ -103,7 +103,7 @@ const FeaturePreviewModal = () => {
<div className="flex items-center justify-between">
<div className="flex items-center gap-x-2">
<p>{selectedFeature?.name}</p>
{selectedFeature?.isNew && <Badge color="green">New</Badge>}
{selectedFeature?.isNew && <Badge variant="success">New</Badge>}
</div>
<div className="flex items-center gap-x-2">
{selectedFeature?.discussionsUrl !== undefined && (
@@ -114,7 +114,7 @@ export const HookCard = ({ hook, onSelect }: HookCardProps) => {
</div>
<div className="flex-1">
{hook.enabled ? (
<Badge className="space-x-1" variant="brand">
<Badge className="space-x-1" variant="success">
<div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
<Check className="h-2 w-2 text-background-overlay " strokeWidth={6} />
</div>
@@ -133,11 +133,9 @@ export const PolicyDetailsV2 = ({
name="table"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-6 flex flex-col gap-y-1">
<FormLabel_Shadcn_ className="flex items-center gap-x-4">
<p className="text-foreground-light text-sm">Table</p>
<p className="text-foreground-light text-sm">
<code className="text-code-inline">on</code> clause
</p>
<FormLabel_Shadcn_>
Table
<code className="text-code-inline">on</code> clause
</FormLabel_Shadcn_>
{authContext === 'database' && (
<FormControl_Shadcn_>
@@ -222,11 +220,8 @@ export const PolicyDetailsV2 = ({
name="behavior"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-6 flex flex-col gap-y-1">
<FormLabel_Shadcn_ className="flex items-center gap-x-4">
<p className="text-foreground-light text-sm">Policy Behavior</p>
<p className="text-foreground-light text-sm">
<code className="text-code-inline">as</code> clause
</p>
<FormLabel_Shadcn_>
Policy Behavior <code className="text-code-inline">as</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<Select_Shadcn_
@@ -264,11 +259,8 @@ export const PolicyDetailsV2 = ({
name="command"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-12 flex flex-col gap-y-1">
<FormLabel_Shadcn_ className="flex items-center gap-x-4">
<p className="text-foreground-light text-sm">Policy Command</p>
<p className="text-foreground-light text-sm">
<code className="text-code-inline">for</code> clause
</p>
<FormLabel_Shadcn_>
Policy Command <code className="text-code-inline">for</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<RadioGroup_Shadcn_
@@ -305,11 +297,8 @@ export const PolicyDetailsV2 = ({
name="roles"
render={({ field }) => (
<FormItem_Shadcn_ className="col-span-12 flex flex-col gap-y-1">
<FormLabel_Shadcn_ className="flex items-center gap-x-4">
<p className="text-foreground-light text-sm">Target Roles</p>
<p className="text-foreground-light text-sm">
<code className="text-code-inline">to</code> clause
</p>
<FormLabel_Shadcn_>
Target Roles <code className="text-code-inline">to</code> clause
</FormLabel_Shadcn_>
<FormControl_Shadcn_>
<MultiSelectV2
@@ -88,7 +88,7 @@ export const PolicyTemplates = ({
hideChevron
fixedHeight={false}
icon={
<div className="min-w-16">
<div className="min-w-16 flex items-start">
<Badge
className={cn(
'!rounded font-mono',
@@ -98,9 +98,9 @@ export const PolicyTemplates = ({
)}
variant={
template.command === 'ALL'
? 'outline'
? 'default'
: template.command === 'SELECT'
? 'brand'
? 'success'
: template.command === 'UPDATE'
? 'default'
: template.command === 'DELETE'
@@ -208,14 +208,14 @@ export const IntegrationCard = ({
</div>
<div className="flex-1">
{true ? (
<Badge className="space-x-1" size="large" variant="brand">
<Badge className="space-x-1" variant="success">
<div className="h-3.5 w-3.5 bg-brand rounded-full flex justify-center items-center">
<Check className="h-2 w-2 text-background-overlay" strokeWidth={6} />
</div>
<span>Enabled</span>
</Badge>
) : (
<Badge variant="warning" size="large">
<Badge variant="warning">
<span>Disabled</span>
</Badge>
)}
@@ -15,7 +15,7 @@ const invoiceStatusMapping: Record<
> = {
[InvoiceStatus.PAID]: {
label: 'Paid',
badgeVariant: 'brand',
badgeVariant: 'success',
},
[InvoiceStatus.VOID]: {
label: 'Forgiven',
@@ -53,11 +53,7 @@ const InvoiceStatusBadge = ({
return (
<Tooltip>
<TooltipTrigger>
<Badge
size="small"
className="capitalize"
variant={statusMapping?.badgeVariant || 'default'}
>
<Badge variant={statusMapping?.badgeVariant || 'default'}>
{statusMapping?.label || status}
</Badge>
</TooltipTrigger>
@@ -68,7 +68,7 @@ const CreditCard = ({
<div className="flex items-center gap-2">
{isExpiringSoon && <Badge variant="warning">Expiring soon</Badge>}
{isExpired && <Badge variant="destructive">Expired</Badge>}
{isActive && <Badge variant="brand">Active</Badge>}
{isActive && <Badge variant="success">Active</Badge>}
{canUpdatePaymentMethods && (
<DropdownMenu>
@@ -360,11 +360,7 @@ export const CreateBranchModal = () => {
<div className="flex flex-col gap-1">
<div className="flex items-center gap-2">
<Label>Sync with a GitHub branch</Label>
{!gitlessBranching && (
<Badge variant="warning" size="small">
Required
</Badge>
)}
{!gitlessBranching && <Badge variant="warning">Required</Badge>}
</div>
<p className="text-sm text-foreground-lighter">
Keep this preview branch in sync with a chosen GitHub branch
@@ -386,11 +382,7 @@ export const CreateBranchModal = () => {
label={
<>
<Label className="mr-2">Include data</Label>
{!hasPitrEnabled && (
<Badge variant="warning" size="small">
Requires PITR
</Badge>
)}
{!hasPitrEnabled && <Badge variant="warning">Requires PITR</Badge>}
</>
}
layout="flex-row-reverse"
@@ -299,11 +299,7 @@ export const EditBranchModal = ({ branch, visible, onClose }: EditBranchModalPro
<div className="flex flex-col gap-1">
<div className="flex items-center gap-2">
<Label>Sync with a GitHub branch</Label>
{!gitlessBranching && (
<Badge variant="warning" size="small">
Required
</Badge>
)}
{!gitlessBranching && <Badge variant="warning">Required</Badge>}
</div>
<p className="text-sm text-foreground-light">
{gitlessBranching
@@ -1,4 +1,5 @@
import { BookOpen, ChevronDown, ExternalLink } from 'lucide-react'
import Link from 'next/link'
import { parseAsString, useQueryState } from 'nuqs'
import { HTMLAttributes, ReactNode, useEffect, useMemo, useState } from 'react'
@@ -493,11 +494,9 @@ export const DatabaseConnectionString = () => {
}
className="text-foreground !bg-dash-sidebar justify-between"
>
<div className="text-xs flex items-center py-2 px-1">
<div className="text-xs flex items-center gap-x-2 py-2 px-1">
<span>Using the Shared Pooler</span>
<Badge variant={'brand'} size={'small'} className="ml-2">
IPv4 compatible
</Badge>
<Badge variant="success">IPv4 compatible</Badge>
</div>
</Button>
</CollapsibleTrigger_Shadcn_>
@@ -1,5 +1,4 @@
import { AnimatePresence, motion } from 'framer-motion'
import { Badge } from 'ui'
interface FormFooterChangeBadgeProps {
formState: {
@@ -22,20 +21,19 @@ export const FormFooterChangeBadge = ({ formState }: FormFooterChangeBadgeProps)
transition: { duration: 0.3 },
}}
>
<Badge variant={'default'}>
<p className="text-sm text-foreground-lighter">
<motion.span
key={Object.keys(formState.dirtyFields).length}
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
transition={{ duration: 0.1 }}
className="text-sm"
>
{Object.keys(formState.dirtyFields).length === 1
? '1 change to review'
: `${Object.keys(formState.dirtyFields).length} changes to review`}
</motion.span>
</Badge>
</p>
</motion.div>
</motion.div>
)}
@@ -29,11 +29,8 @@ function DatabaseBackupsNav({ active }: Props) {
enabled: databaseRestoreToNewProject && cloud_provider !== 'FLY',
id: 'rtnp',
label: (
<div className="flex items-center gap-1">
Restore to new project{' '}
<Badge size="small" className="!text-[10px] px-1.5 py-0">
Beta
</Badge>
<div className="flex items-center gap-2">
Restore to new project <Badge variant="warning">Beta</Badge>
</div>
),
href: `/project/${ref}/database/backups/restore-to-new-project`,
@@ -21,7 +21,7 @@ export const getStatusConfig = (state: TableState['state']) => {
}
case 'copying_table':
return {
badge: <Badge variant="brand">Copying</Badge>,
badge: <Badge variant="success">Copying</Badge>,
description: "Table's existing rows are being copied before live streaming begins.",
tooltip: "Table's existing rows are being copied before live streaming begins.",
color: 'text-brand-600',
@@ -188,7 +188,7 @@ export const RolesList = () => {
<div>
<div className="bg-surface-100 border border-default px-4 md:px-6 py-3 rounded-t flex items-center space-x-4">
<p className="text-sm text-foreground-light">Roles managed by Supabase</p>
<Badge variant="brand">Protected</Badge>
<Badge variant="success">Protected</Badge>
</div>
{isLoading
@@ -110,16 +110,11 @@ export function StorageTypeField({ form, disableInput }: StorageTypeFieldProps)
className={cn(disableIo2 && '!pointer-events-auto')}
>
<div className="flex flex-col gap-0 items-start">
<div className="flex gap-3 items-center">
<div className="flex gap-2 items-center">
<span className="text-sm text-foreground">{item.name}</span>{' '}
<div>
<Badge
variant={'outline'}
className="font-mono bg-alternative bg-opacity-100"
>
{item.type}
</Badge>
</div>
<Badge variant="default" className="font-mono">
{item.type}
</Badge>
</div>
<p className="text-foreground-light">{item.description}</p>
</div>
@@ -11,7 +11,7 @@ import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { GB } from 'lib/constants'
import { formatBytes } from 'lib/helpers'
import { useMemo } from 'react'
import { badgeVariants, cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { Badge, cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
import { DiskStorageSchemaType } from '../DiskManagement.schema'
import { AUTOSCALING_THRESHOLD } from './DiskManagement.constants'
@@ -93,7 +93,7 @@ export const DiskSpaceBar = ({ form }: DiskSpaceBarProps) => {
<div className="relative">
<div
className={cn(
'h-[35px] relative border rounded-sm w-full transition',
'h-[35px] relative border rounded-sm w-full transition overflow-visible',
showNewSize ? 'bg-selection border border-brand' : 'bg-surface-300'
)}
>
@@ -155,15 +155,15 @@ export const DiskSpaceBar = ({ form }: DiskSpaceBarProps) => {
</AnimatePresence>
<AnimatePresence>
{showNewSize && (
<motion.span
<motion.div
initial={{ opacity: 0, x: 4 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 4 }}
transition={{ duration: 0.12, delay: 0.12 }}
className={cn(badgeVariants({ variant: 'success' }), 'absolute right-1 top-[5px]')}
className="absolute right-2 top-0 flex items-center h-full"
>
New disk size
</motion.span>
<Badge variant="success">New disk size</Badge>
</motion.div>
)}
</AnimatePresence>
</div>
@@ -76,10 +76,7 @@ export const EdgeFunctionSecrets = () => {
const headers = [
<TableHead key="secret-name">Name</TableHead>,
<TableHead key="secret-value" className="flex items-center gap-x-2">
Digest{' '}
<Badge color="scale" className="font-mono">
SHA256
</Badge>
Digest <Badge variant="default">SHA256</Badge>
</TableHead>,
<TableHead key="secret-updated-at">Updated at</TableHead>,
<TableHead key="actions" />,
@@ -39,7 +39,7 @@ export const ClientLibrary = ({
className="block md:hidden"
/>
<h5 className="flex items-center gap-2 text-base text-foreground">
{language} {!officialSupport && <Badge variant="brand">Community</Badge>}
{language} {!officialSupport && <Badge variant="success">Community</Badge>}
</h5>
</div>
<div className="flex gap-2">
@@ -130,11 +130,7 @@ export const ProjectCardStatus = ({
projectStatus === 'isHealthy'
) {
if (renderMode === 'badge') {
return (
<Badge variant="success" className="rounded-md">
Active
</Badge>
)
return <Badge variant="success">Active</Badge>
}
return null
}
@@ -72,14 +72,8 @@ export const IntegrationCard = ({
<h3>{name}</h3>
<p className="text-foreground-light text-sm">{description}</p>
<div className="flex items-center gap-x-1 mt-4">
{status && (
<Badge variant="warning" className="capitalize">
{status}
</Badge>
)}
<Badge>
<span>Official</span>
</Badge>
{status && <Badge variant="warning">{status}</Badge>}
<Badge>Official</Badge>
</div>
</div>
</CardContent>
@@ -98,8 +92,8 @@ export const IntegrationCard = ({
</div>
{isInstalled && (
<div className="flex items-center gap-x-1">
<BadgeCheck size={14} className="text-brand" />
<span className=" text-brand text-xs">Installed</span>
<BadgeCheck size={14} className="text-brand-link" />
<span className="text-brand-link text-xs">Installed</span>
</div>
)}
</div>
@@ -108,14 +102,8 @@ export const IntegrationCard = ({
<p className="text-foreground-light text-xs flex-1">{description}</p>
<div className="flex items-center gap-x-1 mt-4">
{status && (
<Badge variant="warning" className="capitalize">
{status}
</Badge>
)}
<Badge>
<span>Official</span>
</Badge>
{status && <Badge variant="warning">{status}</Badge>}
<Badge>Official</Badge>
</div>
</div>
</CardContent>
@@ -208,7 +208,7 @@ export const CreateQueueSheet = ({ visible, onClose }: CreateQueueSheetProps) =>
{definition.label}
</p>
{definition.value === 'partitioned' && (
<Badge variant="warning">Coming soon</Badge>
<Badge>Coming soon</Badge>
)}
</div>
<p className="text-foreground-lighter text-left">
@@ -270,7 +270,7 @@ export const CreateQueueSheet = ({ visible, onClose }: CreateQueueSheetProps) =>
label={
<div className="flex items-center gap-x-2">
<p>Enable Row Level Security (RLS)</p>
<Badge color="scale">Recommended</Badge>
<Badge variant="success">Recommended</Badge>
</div>
}
description="Restrict access to your queue by enabling RLS and writing Postgres policies to control access for each role."
@@ -70,7 +70,7 @@ const messagesCols = [
return (
<div className="flex items-center">
<Badge variant={isAvailable ? 'brand' : 'warning'}>
<Badge variant={isAvailable ? 'success' : 'warning'}>
{isAvailable ? 'Available ' : `Available at ${dayjs(row.vt).format(DATE_FORMAT)}`}
</Badge>
</div>
@@ -176,7 +176,7 @@ export const CreateKeyDialog = ({
<SelectContent_Shadcn_>
<SelectItem_Shadcn_ value="ES256">
<span>ES256 (ECC)</span>
<Badge variant="brand" className="ml-2">
<Badge variant="success" className="ml-2">
Recommended
</Badge>
</SelectItem_Shadcn_>
@@ -343,7 +343,7 @@ export const LintEntity = ({ metadata }: { metadata: Lint['metadata'] }) => {
export const LintCategoryBadge = ({ category }: { category: string }) => {
return (
<Badge variant={category === 'SECURITY' ? 'destructive' : 'warning'} className="capitalize">
<Badge variant={category === 'SECURITY' ? 'destructive' : 'warning'}>
{category.toLowerCase()}
</Badge>
)
@@ -382,14 +382,15 @@ export const PublishAppSidePanel = ({
<Modal
hideFooter
showCloseButton={false}
className="!max-w-[600px]"
visible={showPreview}
onCancel={() => setShowPreview(false)}
>
<Modal.Content>
<div className="flex items-center justify-between">
<p>Authorize API access for {values.name}</p>
<Badge variant="brand">Preview</Badge>
<div className="flex items-center gap-x-2 justify-between">
<p className="truncate">Authorize API access for {values.name}</p>
<Badge variant="success">Preview</Badge>
</div>
</Modal.Content>
<Modal.Separator />
@@ -75,7 +75,7 @@ export const MemberRow = ({ member }: MemberRowProps) => {
/>
<div className="flex item-center gap-x-2">
<p className="text-foreground-light truncate">{member.primary_email}</p>
{member.gotrue_id === profile?.gotrue_id && <Badge color="scale">You</Badge>}
{member.gotrue_id === profile?.gotrue_id && <Badge>You</Badge>}
</div>
{(member.metadata as any)?.origin && (
@@ -58,13 +58,11 @@ export const AdvancedConfiguration = ({
label={
<>
Postgres
<Badge color="scale" className="ml-2">
Default
</Badge>
<Badge>Default</Badge>
</>
}
description="Recommended for production workloads"
className="[&>div>div>p]:text-left [&>div>div>p]:text-xs"
className="[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2"
/>
</FormControl_Shadcn_>
</FormItem_Shadcn_>
@@ -76,14 +74,12 @@ export const AdvancedConfiguration = ({
label={
<>
Postgres with OrioleDB
<Badge color="warning" className="ml-2">
Alpha
</Badge>
<Badge variant="warning">Alpha</Badge>
</>
}
description="Not recommended for production workloads"
className={cn(
'[&>div>div>p]:text-left [&>div>div>p]:text-xs',
'[&>div>div>p]:text-left [&>div>div>p]:text-xs [&>div>div>label]:flex [&>div>div>label]:items-center [&>div>div>label]:gap-x-2',
form.getValues('useOrioleDb') ? '!rounded-b-none' : ''
)}
/>
@@ -7,7 +7,6 @@ import { getCloudProviderArchitecture } from 'lib/cloudprovider-utils'
import { DOCS_URL } from 'lib/constants'
import { CloudProvider } from 'shared-data'
import {
Badge,
FormField_Shadcn_,
Select_Shadcn_,
SelectContent_Shadcn_,
@@ -16,6 +15,7 @@ import {
SelectTrigger_Shadcn_,
SelectValue_Shadcn_,
} from 'ui'
import { ComputeBadge } from 'ui-patterns'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { sizes } from './ProjectCreation.constants'
import { CreateProjectForm } from './ProjectCreation.schema'
@@ -75,15 +75,11 @@ export const ComputeSizeSelector = ({ form }: ComputeSizeSelectorProps) => {
.map((option) => {
return (
<SelectItem_Shadcn_ key={option} value={option}>
<div className="flex flex-row gap-2">
<div className="text-center w-[80px]">
<Badge
variant={option === 'micro' ? 'default' : 'brand'}
className="rounded-md w-16 text-center flex justify-center font-mono uppercase"
>
{instanceSizeSpecs[option].label}
</Badge>
<div className="flex flex-row gap-4 items-center">
<div className="w-14 flex items-center">
<ComputeBadge infraComputeSize={option} />
</div>
<div className="text-sm">
<span className="text-foreground">
{instanceSizeSpecs[option].ram} RAM /{' '}
@@ -61,13 +61,11 @@ export const OrganizationSelector = ({ form }: OrganizationSelectorProps) => {
<SelectContent_Shadcn_>
<SelectGroup_Shadcn_>
{organizations?.map((x) => (
<SelectItem_Shadcn_
key={x.id}
value={x.slug}
className="flex justify-between"
>
<span className="mr-2">{x.name}</span>
<Badge>{x.plan.name}</Badge>
<SelectItem_Shadcn_ key={x.id} value={x.slug}>
<div className="flex justify-between items-center gap-2 w-full">
<span>{x.name}</span>
<Badge className="mt-[1px]">{x.plan.name}</Badge>
</div>
</SelectItem_Shadcn_>
))}
</SelectGroup_Shadcn_>
@@ -129,18 +129,17 @@ export const PostgresVersionSelector = ({
>
<div className="flex flex-row items-center justify-between w-full">
<span className="text-foreground">{postgresVersion}</span>
<div>
{value.release_channel !== 'ga' && (
<Badge variant="warning" className="mr-1 capitalize">
{value.release_channel}
</Badge>
)}
{value.postgres_engine.includes('oriole') && (
<Badge variant="default" className="mr-1">
OrioleDB
</Badge>
)}
</div>
{value.release_channel !== 'ga' ||
(value.postgres_engine.includes('oriole') && (
<div className="flex flex-row gap-x-2">
{value.release_channel !== 'ga' && (
<Badge variant="warning">{value.release_channel}</Badge>
)}
{value.postgres_engine.includes('oriole') && (
<Badge variant="default">OrioleDB</Badge>
)}
</div>
))}
</div>
</SelectItem_Shadcn_>
)
@@ -124,11 +124,9 @@ export const ProjectCreationFooter = ({
<TableRow>
<TableCell className="w-[170px] flex gap-2">
<span className="truncate">
{form.getValues('projectName') ?? 'New project'}
{form.getValues('projectName') || 'New project'}
</span>
<Badge size={'small'} variant={'default'}>
NEW
</Badge>
<Badge variant="success">New</Badge>
</TableCell>
<TableCell className="text-center">{instanceLabel(instanceSize)}</TableCell>
<TableCell className="text-right">
@@ -106,18 +106,16 @@ export const SecurityOptions = ({
value="false"
// @ts-ignore
label={
<>
Use public schema for Data API
<Badge color="scale" className="ml-2">
Default
</Badge>
</>
<div className="flex items-center gap-2">
<span>Use public schema for Data API</span>
<Badge>Default</Badge>
</div>
}
// @ts-ignore
description={
<>
Query all tables in the{' '}
<code className="text-code-inline">public</code> schema
<code className="text-code-inline !text-[11px]">public</code> schema
</>
}
className="[&>div>div>p]:text-left [&>div>div>p]:text-xs"
@@ -133,7 +131,7 @@ export const SecurityOptions = ({
description={
<>
Query allowlisted tables in a dedicated{' '}
<code className="text-code-inline">api</code> schema
<code className="text-code-inline !text-[11px]">api</code> schema
</>
}
className="[&>div>div>p]:text-left [&>div>div>p]:text-xs"
@@ -1,4 +1,9 @@
import { debounce } from 'lodash'
import { Check, Code, Loader } from 'lucide-react'
import { useEffect, useState } from 'react'
import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import {
AlertDescription_Shadcn_,
AlertTitle_Shadcn_,
@@ -16,11 +21,6 @@ import {
ScrollArea,
} from 'ui'
import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { debounce } from 'lodash'
import { Check, Code, Loader } from 'lucide-react'
interface TableSelectorProps {
className?: string
size?: 'tiny' | 'small'
@@ -125,7 +125,9 @@ const TableSelector = ({
<>
<CommandGroup_Shadcn_ forceMount>
<ScrollArea className={(entities || []).length > 7 ? 'h-[210px]' : ''}>
<CommandEmpty_Shadcn_>No tables found</CommandEmpty_Shadcn_>
{entities.length === 0 && (
<CommandEmpty_Shadcn_>No tables found</CommandEmpty_Shadcn_>
)}
{!searchInput && (
<CommandItem_Shadcn_
key="all-tables"
@@ -1,6 +1,6 @@
import { PlusCircle } from 'lucide-react'
import Link from 'next/link'
import { Dispatch, SetStateAction, useState, useEffect } from 'react'
import { Dispatch, SetStateAction, useEffect, useState } from 'react'
import { useParams } from 'common'
import { useSendEventMutation } from 'data/telemetry/send-event-mutation'
@@ -62,13 +62,13 @@ export const RealtimeFilterPopover = ({ config, onChangeConfig }: RealtimeFilter
<Button
icon={<PlusCircle size="16" />}
type={isFiltered ? 'primary' : 'dashed'}
className={cn('rounded-full px-1.5 text-xs', isFiltered ? '!py-0.5' : '!py-1')}
className={cn('rounded-full px-1 text-xs h-[26px]')}
size="small"
>
{isFiltered ? (
<>
<span className="mr-1">Filtered by </span>
<Badge variant="brand">table: {config.table}</Badge>
<Badge variant="success">table: {config.table}</Badge>
</>
) : (
<span className="mr-1">Filter messages</span>
@@ -213,15 +213,13 @@ export const ChartConfig = ({
<TooltipContent side="bottom">Dismiss</TooltipContent>
</Tooltip>
<div className="flex items-center gap-x-2">
<Badge variant="success" className="text-xs rounded px-1">
NEW
</Badge>
<Badge variant="success">New</Badge>
<p className="text-xs">Add this chart to custom reports</p>
</div>
<p className="text-xs text-foreground-light mt-1">
<p className="text-xs text-foreground-light !mt-1">
SQL snippets can now be added and saved to your custom reports. Try it out now!
</p>
<Button asChild size="tiny" type="default" className="mt-2">
<Button asChild size="tiny" type="default" className="mt-1">
<Link href={`/project/${ref}/reports`}>Head to Reports</Link>
</Button>
</Admonition>
@@ -232,10 +232,7 @@ export const Addons = () => {
<ShimmeringLoader className="w-32" />
) : (
<div className="flex py-3">
<ComputeBadge
infraComputeSize={selectedProject?.infra_compute_size}
size={'large'}
/>
<ComputeBadge infraComputeSize={selectedProject?.infra_compute_size} />
</div>
)}
@@ -262,9 +262,7 @@ export const ProjectUpgradeAlert = () => {
<div className="flex items-center gap-3">
<span className="text-foreground">{postgresVersion}</span>
{value.release_channel !== 'ga' && (
<Badge variant="warning" className="mr-1 capitalize">
{value.release_channel}
</Badge>
<Badge variant="warning">{value.release_channel}</Badge>
)}
</div>
</SelectItem_Shadcn_>
@@ -295,7 +295,7 @@ export const ReplicaNode = ({ data }: NodeProps<ReplicaNodeData>) => {
) : status === REPLICA_STATUS.RESIZING ? (
<Badge>Resizing</Badge>
) : status === REPLICA_STATUS.ACTIVE_HEALTHY ? (
<Badge variant="brand">Healthy</Badge>
<Badge variant="success">Healthy</Badge>
) : (
<Badge variant="warning">Unhealthy</Badge>
)}
@@ -276,7 +276,7 @@ const MapView = ({
`(ID: ${formatDatabaseID(database.identifier)})`
}`}
{database.status === REPLICA_STATUS.ACTIVE_HEALTHY ? (
<Badge variant="brand">Healthy</Badge>
<Badge variant="success">Healthy</Badge>
) : database.status === REPLICA_STATUS.COMING_UP ? (
<Badge>Coming up</Badge>
) : database.status === REPLICA_STATUS.RESTARTING ? (
@@ -149,7 +149,7 @@ const InfrastructureInfo = () => {
isVisibleReleaseChannel && (
<Tooltip>
<TooltipTrigger>
<Badge variant="warning" className="mr-1 capitalize">
<Badge variant="warning" className="mr-1">
{isVisibleReleaseChannel}
</Badge>
</TooltipTrigger>
@@ -174,7 +174,7 @@ const InfrastructureInfo = () => {
isOnLatestVersion && (
<Tooltip>
<TooltipTrigger>
<Badge variant="brand" className="mr-1">
<Badge variant="success" className="mr-1">
Latest
</Badge>
</TooltipTrigger>
@@ -90,7 +90,7 @@ export const UnsupportedExtensionsWarning = ({
<li className="py-3 last:pb-0 flex flex-row justify-between gap-2" key={obj}>
<div className="flex flex-row gap-2 items-center flex-1 min-w-0">
<p className="overflow-hidden text-ellipsis whitespace-nowrap min-w-0">{obj}</p>
<Badge variant="warning" size="small" className="flex-shrink-0">
<Badge variant="warning" className="flex-shrink-0">
Deprecated
</Badge>
</div>
@@ -8,7 +8,7 @@ import { Label } from '@ui/components/shadcn/ui/label'
import { RadioGroup, RadioGroupItem } from '@ui/components/shadcn/ui/radio-group'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { TimeSplitInput } from 'components/ui/DatePicker/TimeSplitInput'
import { useCurrentOrgPlan } from 'hooks/misc/useCurrentOrgPlan'
import { useCheckEntitlements } from 'hooks/misc/useCheckEntitlements'
import {
Button,
ButtonProps,
@@ -21,7 +21,6 @@ import {
} from 'ui'
import { LOGS_LARGE_DATE_RANGE_DAYS_THRESHOLD } from './Logs.constants'
import type { DatetimeHelper } from './Logs.types'
import { useCheckEntitlements } from 'hooks/misc/useCheckEntitlements'
export type DatePickerValue = {
to: string
@@ -290,15 +289,7 @@ export const LogsDatePicker = ({
aria-disabled={helper.disabled}
></RadioGroupItem>
{helper.text}
{showHelperBadge(helper) ? (
<Badge
size="small"
variant="outline"
className="h-5 text-[10px] text-foreground-light capitalize"
>
{helper.availableIn?.[0] || ''}
</Badge>
) : null}
{showHelperBadge(helper) ? <Badge>{helper.availableIn?.[0] || ''}</Badge> : null}
</Label>
))}
</RadioGroup>
@@ -16,7 +16,7 @@ export function LastSignInWrapper({
<div className="flex items-center relative">
{lastSignIn === type && (
<Badge
variant="brand"
variant="success"
className="absolute -right-4 -top-3 rounded-full px-2 py-0.5 shadow z-10 bg-brand-400 bg-opacity-100 text-foreground pointer-events-none"
>
Last used
@@ -45,11 +45,7 @@ export const StorageMenuV2 = () => {
<Menu.Item rounded active={isSelected}>
<div className="flex items-center justify-between">
<p className="truncate">{config.displayName}</p>
{isAlphaEnabled && (
<Badge variant="default" size="small">
New
</Badge>
)}
{isAlphaEnabled && <Badge variant="success">New</Badge>}
</div>
</Menu.Item>
</Link>
@@ -1,5 +1,5 @@
import { noop } from 'lodash'
import { Badge, Button, Checkbox, Modal } from 'ui'
import { Button, Checkbox, cn, Modal } from 'ui'
import { PolicyName } from 'components/interfaces/Auth/Policies/PolicyEditor/PolicyName'
import { PolicyRoles } from 'components/interfaces/Auth/Policies/PolicyEditor/PolicyRoles'
@@ -47,7 +47,7 @@ const PolicyAllowedOperations = ({ allowedOperations = [], onToggleOperation = (
.
</p>
</div>
<div className="md:w-2/3">
<div className="md:w-2/3 flex flex-col gap-3">
<div className="flex flex-wrap items-center gap-x-8 gap-y-4">
<Checkbox
label="SELECT"
@@ -72,11 +72,18 @@ const PolicyAllowedOperations = ({ allowedOperations = [], onToggleOperation = (
</div>
<div className="flex w-5/6 flex-wrap">
{Object.keys(STORAGE_CLIENT_LIBRARY_MAPPINGS).map((method) => (
<div key={method} className="mr-2 mt-2 font-mono">
<Badge variant={allowedClientLibraryMethods.includes(method) ? 'brand' : 'default'}>
<ul key={method} className="mr-2 mt-2 list-none">
<li
className={cn(
'text-xs font-mono leading-[1.1] px-2 py-1 rounded-full border font-normal whitespace-nowrap transition-colors duration-200',
allowedClientLibraryMethods.includes(method)
? 'bg-brand bg-opacity-10 text-brand-600 border-brand-500'
: 'bg-surface-75 text-foreground-lighter border-muted'
)}
>
{method}
</Badge>
</div>
</li>
</ul>
))}
</div>
</div>
@@ -55,11 +55,7 @@ export function OrganizationSelector({ form, orgSlug }: OrganizationSelectorProp
) : (
(organizations ?? []).find((o) => o.slug === field.value)?.name
)}
{subscriptionPlanId && (
<Badge variant="outline" className="capitalize">
{subscriptionPlanId}
</Badge>
)}
{subscriptionPlanId && <Badge variant="default">{subscriptionPlanId}</Badge>}
</div>
</SelectValue_Shadcn_>
</SelectTrigger_Shadcn_>
@@ -171,7 +171,7 @@ const Column = ({
</div>
) : (
<div className="flex items-center gap-x-2 truncate">
<Badge variant={status === 'ADD' ? 'brand' : 'warning'}>
<Badge variant={status === 'ADD' ? 'success' : 'warning'}>
{status}
</Badge>
<p className="truncate">
@@ -49,7 +49,7 @@ export const ForeignKeyRow = ({
{status !== undefined && (
<Badge
variant={
status === 'ADD' ? 'brand' : status === 'UPDATE' ? 'warning' : 'destructive'
status === 'ADD' ? 'success' : status === 'UPDATE' ? 'warning' : 'destructive'
}
>
{status}
@@ -1,14 +1,14 @@
import { ChevronDown, ChevronUp, X } from 'lucide-react'
import { useCallback, useMemo, useEffect } from 'react'
import { useDataTable } from 'components/ui/DataTable/providers/DataTableProvider'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { DataTableColumnStatusCode } from 'components/ui/DataTable/DataTableColumn/DataTableColumnStatusCode'
import { Kbd } from 'components/ui/DataTable/primitives/Kbd'
import { useDataTable } from 'components/ui/DataTable/providers/DataTableProvider'
import { ChevronDown, ChevronUp, X } from 'lucide-react'
import { useCallback, useEffect, useMemo } from 'react'
import { Badge, Button, Separator } from 'ui'
import { LogTypeIcon } from '../../components/LogTypeIcon'
import { ColumnSchema } from '../../UnifiedLogs.schema'
import { getStatusLevel } from '../../UnifiedLogs.utils'
import { TruncatedTextWithPopover } from './shared/TruncatedTextWithPopover'
import { Badge, Button, Separator } from 'ui'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { Kbd } from 'components/ui/DataTable/primitives/Kbd'
import { ColumnSchema } from '../../UnifiedLogs.schema'
interface ServiceFlowHeaderProps {
selectedRow: ColumnSchema
@@ -101,11 +101,7 @@ export const ServiceFlowHeader = ({ selectedRow, enrichedData }: ServiceFlowHead
<div className="flex items-center justify-between px-4 py-3">
<div className="flex items-center gap-3 min-w-0 flex-1 mr-6">
{logType && <LogTypeIcon type={logType} size={16} className="text-foreground/70" />}
{method && (
<Badge variant="default" className="font-mono text-xs rounded px-1">
{method}
</Badge>
)}
{method && <Badge variant="default">{method}</Badge>}
{displayPath.isTruncatable ? (
<TruncatedTextWithPopover
text={displayPath.text}
@@ -47,9 +47,9 @@ export const EventMessage = ({
? 'warning'
: 'default'
}
className="ml-2 text-xs"
className="ml-2"
>
{severity.toUpperCase()}
{severity}
</Badge>
)}
</span>
@@ -78,11 +78,7 @@ export const FieldWithSeeMore = ({
}
if (showValueAsBadge && primaryValue && primaryValue !== 'N/A') {
return (
<Badge variant="secondary" size="small">
{primaryValue}
</Badge>
)
return <Badge variant="secondary">{primaryValue}</Badge>
}
return (
@@ -1,11 +1,11 @@
import { useIsAdvisorRulesEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { ProductMenu } from 'components/ui/ProductMenu'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
import { Badge, Button } from 'ui'
import { FeaturePreviewSidebarPanel } from '../../ui/FeaturePreviewSidebarPanel'
import { generateAdvisorsMenu } from './AdvisorsMenu.utils'
import { useIsAdvisorRulesEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
interface AdvisorsSidebarMenuProps {
page?: string
@@ -25,8 +25,8 @@ export function AdvisorsSidebarMenu({ page }: AdvisorsSidebarMenuProps) {
<FeaturePreviewSidebarPanel
className="mx-4 mt-4"
title="Moving to the toolbar"
description="Advisors are now available in the top toolbar for quicker access across the dashboard"
illustration={<Badge variant="brand">New Location</Badge>}
description="Advisors are now available in the top toolbar for quicker access across the dashboard."
illustration={<Badge variant="success">New</Badge>}
actions={
<Button size="tiny" type="default" onClick={handleOpenAdvisor}>
Try it now
@@ -126,20 +126,28 @@ export const BranchDropdown = () => {
{isSuccess && (
<>
<Link href={`/project/${ref}`} className="flex items-center gap-2 flex-shrink-0 text-sm">
<span className="text-foreground max-w-32 lg:max-w-none truncate">
<Link href={`/project/${ref}`} className="flex items-center gap-2 flex-shrink-0 ">
<span className="text-sm text-foreground max-w-32 lg:max-w-none truncate">
{isBranchingEnabled ? selectedBranch?.name : 'main'}
</span>
{isBranchingEnabled ? (
selectedBranch?.is_default ? (
<Badge variant="warning">Production</Badge>
<Badge variant="warning" className="mt-[1px]">
Production
</Badge>
) : selectedBranch?.persistent ? (
<Badge variant="brand">Persistent</Badge>
<Badge variant="success" className="mt-[1px]">
Persistent
</Badge>
) : (
<Badge variant="brand">Preview</Badge>
<Badge variant="success" className="mt-[1px]">
Preview
</Badge>
)
) : (
<Badge variant="warning">Production</Badge>
<Badge variant="warning" className="mt-[1px]">
Production
</Badge>
)}
</Link>
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={false}>
@@ -95,7 +95,7 @@ export const generateAuthMenu = (
name: 'OAuth Server',
key: 'oauth-server',
url: `/project/${ref}/auth/oauth-server`,
label: 'BETA',
label: 'Beta',
},
]
: []),
@@ -157,7 +157,7 @@ export const generateAuthMenu = (
key: 'hooks',
url: `/project/${ref}/auth/hooks`,
items: [],
label: 'BETA',
label: 'Beta',
},
{
name: 'Audit Logs',
@@ -251,9 +251,9 @@ export function LogsSidebarMenuV2() {
{unifiedLogsFlagEnabled && (
<FeaturePreviewSidebarPanel
className="mx-4 mt-4"
title="New Logs Interface"
description="Unified view across all services with improved filtering and real-time updates"
illustration={<Badge variant="brand">Feature Preview</Badge>}
title="Introducing unified logs"
description="A unified view across all services with improved filtering and real-time updates."
illustration={<Badge variant="success">New</Badge>}
actions={
<>
<Button
@@ -65,7 +65,7 @@ const BuildingState = () => {
<div className="w-full flex flex-col gap-4">
<div className="w-full flex flex-col md:flex-row items-start md:items-center gap-3">
<h1 className="text-3xl">{project?.name}</h1>
<Badge variant="default" className="bg-surface-100 bg-opacity-100">
<Badge>
<div className="flex items-center gap-2">
<Loader2 className="animate-spin" size={12} />
<span>
@@ -51,7 +51,7 @@ const ConnectingState = ({ project }: ConnectingStateProps) => {
<div className="flex flex-col space-y-4 lg:flex-row lg:items-center lg:space-y-0 lg:space-x-6">
<h1 className="text-3xl">{project.name}</h1>
<div>
<Badge variant="brand">
<Badge variant="success">
<div className="flex items-center gap-2">
<Loader className="animate-spin" size={12} />
<span>Connecting to project</span>
@@ -151,9 +151,7 @@ export const LayoutHeader = ({
{exceedingLimits && (
<div className="ml-2">
<Link href={`/org/${selectedOrganization?.slug}/usage`}>
<Badge variant="destructive" className="whitespace-nowrap">
Exceeding usage limits
</Badge>
<Badge variant="destructive">Exceeding usage limits</Badge>
</Link>
</div>
)}
@@ -51,7 +51,7 @@ export const LocalVersionPopover = () => {
return (
<Popover_Shadcn_>
<PopoverTrigger_Shadcn_ className="flex items-center">
<Badge variant={isBeta ? 'warning' : hasUpdate ? 'brand' : 'default'}>
<Badge variant={isBeta ? 'warning' : hasUpdate ? 'success' : 'default'}>
{isBeta ? 'Beta' : hasUpdate ? 'Update available' : 'Latest'}
</Badge>
</PopoverTrigger_Shadcn_>
@@ -114,7 +114,7 @@ export const generateSettingsMenu = (
url: isProjectBuilding ? buildingUrl : `/project/${ref}/integrations/vault/overview`,
items: [],
rightIcon: <ArrowUpRight strokeWidth={1} className="h-4 w-4" />,
label: 'BETA',
label: 'Beta',
},
],
},
+1 -1
View File
@@ -30,7 +30,7 @@ export const AlphaNotice = ({ entity, feedbackUrl }: AlphaNoticeProps) => {
<div className="relative z-10 flex flex-col md:flex-row md:items-center gap-y-2 md:gap-x-8 justify-between px-2 py-1">
<div className="flex flex-col gap-y-0.5">
<div className="flex flex-col gap-y-2 items-start">
<Badge variant="success" className="-ml-0.5 uppercase">
<Badge variant="success" className="-ml-0.5">
New
</Badge>
<p className="text-sm font-medium">Introducing {entity.toLocaleLowerCase()}</p>
@@ -33,12 +33,15 @@ const ProductMenuItem = ({
<Menu.Item icon={icon} rounded active={isActive} onClick={onClick}>
<div className="flex w-full items-center justify-between gap-1">
<div
className="flex items-center gap-1 min-w-0 flex-1"
title={hoverText ? hoverText : typeof name === 'string' ? name : ''}
className={'flex space-between items-center gap-2 truncate w-full ' + textClassName}
>
<span className="truncate flex-1">{name}</span>
<span className="truncate flex-1 min-w-0">{name}</span>
{label !== undefined && (
<Badge variant={label.toLowerCase() === 'new' ? 'default' : 'warning'} size="small">
<Badge
variant={label.toLowerCase() === 'new' ? 'success' : 'warning'}
className="flex-shrink-0"
>
{label}
</Badge>
)}
+1 -1
View File
@@ -64,7 +64,7 @@ const Security: NextPageWithLayout = () => {
</div>
{data ? (
<Badge variant={data.totp.length === 0 ? 'default' : 'brand'}>
<Badge variant={data.totp.length === 0 ? 'default' : 'success'}>
{data.totp.length} app{data.totp.length === 1 ? '' : 's'} configured
</Badge>
) : null}
@@ -70,7 +70,7 @@ const BucketPage: NextPageWithLayout = () => {
<div className="flex items-center gap-2 min-w-0 flex-1">
<span className="truncate">{bucketId}</span>
{bucket?.public && (
<Badge variant="warning" size="small" className="flex-shrink-0">
<Badge variant="warning" className="flex-shrink-0">
Public
</Badge>
)}
@@ -109,8 +109,8 @@ const NavigationItem: React.FC<NavigationItemProps> = ({ item, onClick, ...props
/>
{item.title}
{item.new && (
<Badge variant="brand" className="capitalize">
NEW
<Badge variant="success" className="capitalize">
New
</Badge>
)}
</Link>
+3 -21
View File
@@ -132,13 +132,7 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
className="rounded-full"
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
>
<Link
href={doc.links.api}
target="_blank"
rel="noreferrer"
// className={cn(badgeVariants({ variant: 'default' }), 'gap-1')}
>
<Link href={doc.links.api} target="_blank" rel="noreferrer">
API Reference
</Link>
</Button>
@@ -215,13 +209,7 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
className="rounded-full"
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
>
<Link
href={doc.links.doc}
target="_blank"
rel="noreferrer"
// className={cn(buttonVariants({ variant: 'default' }), 'gap-1')}
>
<Link href={doc.links.doc} target="_blank" rel="noreferrer">
Docs
</Link>
</Button>
@@ -232,13 +220,7 @@ const SourcePanel = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement> &
className="rounded-full"
icon={<ExternalLink className="text-foreground-muted" strokeWidth={1} />}
>
<Link
href={doc.links.api}
target="_blank"
rel="noreferrer"
// className={cn(badgeVariants({ variant: 'default' }), 'gap-1')}
>
<Link href={doc.links.api} target="_blank" rel="noreferrer">
API Reference
</Link>
</Button>
+1 -1
View File
@@ -56,7 +56,7 @@ const AnnouncementBadge = ({
)}
>
{badge && (
<Badge variant="brand" size="large" className="py-1 announcement-badge">
<Badge variant="success" className="py-1 announcement-badge">
{badge}
</Badge>
)}
@@ -144,7 +144,7 @@ const CoverImage = ({ url }: { url?: string }) => {
return (
<div className="w-full bg-surface-100 aspect-square border rounded-lg hidden md:grid place-items-center relative">
<Logo />
<Badge variant="brand" className="absolute bottom-4 right-4">
<Badge variant="success" className="absolute bottom-4 right-4">
Upcoming
</Badge>
</div>
@@ -153,7 +153,7 @@ const CoverImage = ({ url }: { url?: string }) => {
return (
<div className="w-full bg-surface-100 hidden md:block aspect-square border rounded-lg overflow-hidden relative">
<img src={url} alt="Event Cover" className="object-cover object-center w-full" />
<Badge variant="brand" className="absolute bottom-4 right-4">
<Badge variant="success" className="absolute bottom-4 right-4">
Upcoming
</Badge>
</div>
@@ -38,7 +38,7 @@ export function EventGalleryFilters() {
return (
<Badge
key={category.value}
variant={isActive ? 'brand' : 'outline'}
variant={isActive ? 'success' : 'default'}
className="cursor-pointer"
onClick={() => toggleCategory(category.value)}
>
+1 -1
View File
@@ -149,7 +149,7 @@ const Footer = (props: Props) => {
{link.text}
{!link.url && !Component && (
<div className="ml-2 inline text-xs xl:ml-0 xl:block 2xl:ml-2 2xl:inline">
<Badge size="small">Coming soon</Badge>
<Badge>Coming soon</Badge>
</div>
)}
</div>
+1 -3
View File
@@ -24,9 +24,7 @@ const NewFeatureCard = (props: CardProps) => (
<div className="relative z-10 flex flex-col gap-4 p-4 md:p-8 h-full">
<div className="flex items-center gap-2">
<h4 className="text-lg text-foreground">{props.title}</h4>
{props.badge && (
<Badge className="border-strong !bg-alternative-200 text-foreground">{props.badge}</Badge>
)}
{props.badge && <Badge variant="success">{props.badge}</Badge>}
</div>
<div className="flex flex-col w-full xl:w-2/3 flex-grow mb-4 sm:mb-10 lg:mb-8 2xl:xl:mb-32">
<ul className="flex flex-col text-foreground-lighter text-sm gap-1">
@@ -1,8 +1,8 @@
import React, { FC, useEffect, useState } from 'react'
import dayjs from 'dayjs'
import { AnimatePresence, motion } from 'framer-motion'
import { Badge, cn } from 'ui'
import { FC, useEffect, useState } from 'react'
import { useInterval } from 'react-use'
import { Badge, cn } from 'ui'
interface Props {
isActive?: boolean
@@ -87,9 +87,7 @@ const RealtimeLogs: FC<Props> = ({ isActive, isInView, className }) => {
>
<span className="shrink-0">{dayjs(log.timestamp).format('D MMM HH:mm:ss')}</span>
<span className="">
<Badge color={log.status === 200 ? 'slate' : 'amber'} className="rounded">
{log.status}
</Badge>
<Badge variant={log.status === 200 ? 'default' : 'warning'}>{log.status}</Badge>
</span>
<span className="w-10 truncate">{log.method}</span>
<span className="truncate">{log.id}</span>
+16 -18
View File
@@ -1,9 +1,9 @@
import React, { useRef, useState } from 'react'
import Link from 'next/link'
import { useTheme } from 'next-themes'
import { Check } from 'lucide-react'
import { AnimatePresence, motion, useInView } from 'framer-motion'
import { Badge, cn } from 'ui'
import { Check } from 'lucide-react'
import { useTheme } from 'next-themes'
import Link from 'next/link'
import React, { useRef, useState } from 'react'
import { cn } from 'ui'
import BrowserFrame from './BrowserFrame'
export type Tab = {
@@ -96,19 +96,17 @@ interface TabProps {
}
const Tab = ({ label, isActive, onClick }: TabProps) => (
<button onClick={onClick} aria-selected={isActive} role="tab">
<Badge
size="large"
className={cn(
// `text-left py-1.5 px-3 lg:py-2 lg:px-8 border rounded-md bg-alternative hover:border-foreground text-lg opacity-80 transition-all`,
'py-1.5 px-3 lg:py-2 lg:px-8',
'hover:border-foreground-lighter hover:text-foreground',
`opacity-80`,
isActive ? 'opacity-100 !border-foreground' : ''
)}
>
{label}
</Badge>
<button
onClick={onClick}
aria-selected={isActive}
role="tab"
className={cn(
'py-1.5 px-3 lg:py-2 lg:px-8 border rounded-full bg-alternative hover:border-foreground text-sm opacity-80 transition-all',
'hover:border-foreground-lighter hover:text-foreground',
isActive ? 'opacity-100 !border-foreground' : ''
)}
>
{label}
</button>
)
+3 -3
View File
@@ -1,7 +1,7 @@
import React, { FC, useMemo, useEffect, useState } from 'react'
import { cn, Badge, AnimatedCounter } from 'ui'
import { motion } from 'framer-motion'
import { FC, useEffect, useMemo, useState } from 'react'
import { useMedia } from 'react-use'
import { AnimatedCounter, Badge, cn } from 'ui'
import { companyStats } from '~/data/company-stats'
@@ -102,7 +102,7 @@ const GraphLabel: FC<{ className?: string }> = ({ className }) => {
companyStats.developersRegistered.text
)}
</span>
<Badge variant="success" size="small" className="h-[24px] px-2">
<Badge variant="success">
{shouldShowAnimated ? (
<AnimatedCounter
value={companyStats.developersRegisteredChange.number}
+3 -1
View File
@@ -107,7 +107,9 @@ const AWSReInvent2025: NextPage = () => {
<Clock className="w-4 h-4" />
<span className="font-mono">{event.time}</span>
</div>
{event.type === 'keynote' && <Badge variant="brand">Keynote</Badge>}
{event.type === 'keynote' && (
<Badge variant="success">Keynote</Badge>
)}
{event.type === 'networking' && (
<Badge variant="default">Networking</Badge>
)}
+1 -2
View File
@@ -1,5 +1,4 @@
import { GlobeAltIcon } from '@heroicons/react/outline'
import { Check } from 'lucide-react'
import { GetServerSideProps } from 'next'
import { NextSeo } from 'next-seo'
import Image from 'next/image'
@@ -471,7 +470,7 @@ const JobItem = ({ job }: { job: JobItemProps }) => {
<div className="flex items-center gap-4">
<Badge>
<GlobeAltIcon className="w-3 h-3" />
<span className="ml-1">{job.location}</span>
<span>{job.location}</span>
</Badge>
<span className="hidden md:block">{job.employment}</span>
</div>
+3 -3
View File
@@ -11,11 +11,11 @@ import { Swiper, SwiperSlide } from 'swiper/react'
import { Badge, Button, Image, Tabs } from 'ui'
// data
import MainProducts from '~/data/MainProducts'
import ApiExamplesData from 'data/products/database/api-examples'
import ExtensionsExamplesData from 'data/products/database/extensions-examples'
import SqlViewCarouselData from 'data/products/database/sql-view-carousel.json'
import TableViewCarouselData from 'data/products/database/table-view-carousel.json'
import MainProducts from '~/data/MainProducts'
import HighlightsCards from '~/data/products/database/highlight-cards'
import { ArrowUpRight, X } from 'lucide-react'
@@ -268,9 +268,9 @@ function Database() {
]}
footer={[
<div className="grid grid-cols-12" key={0}>
<div className="col-span-12 mt-0 flex flex-col 2xl:flex-row lg:col-span-6 xl:col-span-12 xl:mb-8 gap-1">
<div className="col-span-12 mt-0 flex flex-col 2xl:flex-row lg:col-span-6 xl:col-span-12 xl:mb-8 gap-1 xl:gap-2 xl:items-center">
<p className="text-foreground-light m-0">Available libraries:</p>
<div className="flex gap-1">
<div className="flex gap-1 xl:mb-0.5">
<Link href="/docs/reference/javascript/introduction" target="_blank">
<Badge>Javascript</Badge>
</Link>
+4 -8
View File
@@ -5,14 +5,14 @@ import Link from 'next/link'
import ReactMarkdown from 'react-markdown'
import { Badge, Button, cn, Image } from 'ui'
import DefaultLayout from '~/components/Layouts/Default'
import ShareArticleActions from '~/components/Blog/ShareArticleActions'
import SectionContainer from '~/components/Layouts/SectionContainer'
import CTABanner from '~/components/CTABanner'
import DefaultLayout from '~/components/Layouts/Default'
import SectionContainer from '~/components/Layouts/SectionContainer'
import PrevNextFeatureNav from '~/components/PrevNextFeatureNav'
import { features } from '~/data/features'
import type { FeatureType } from '~/data/features'
import { features } from '~/data/features'
interface FeaturePageProps {
feature: FeatureType
@@ -105,10 +105,7 @@ const FeaturePage: React.FC<FeaturePageProps> = ({ feature, prevFeature, nextFea
<div className="relative h-full flex flex-col items-start gap-2 w-full max-w-2xl mx-auto">
<div className="flex flex-wrap items-center space-x-1 mb-2">
<Link href="/features" passHref>
<Badge
className="p-0 h-[22px] w-[22px] rounded-full flex items-center justify-center text-foreground-lighter hover:text-foreground hover:border-foreground-lighter"
size="small"
>
<Badge className="p-0 h-[22px] w-[22px] rounded-full flex items-center justify-center text-foreground-lighter hover:text-foreground hover:border-foreground-lighter">
<ChevronLeft className="w-3.5 h-3.5" />
</Badge>
</Link>
@@ -122,7 +119,6 @@ const FeaturePage: React.FC<FeaturePageProps> = ({ feature, prevFeature, nextFea
<Badge
key={product}
className="capitalize hover:border-foreground-lighter hover:text-foreground"
size="small"
>
{product}
</Badge>
+26 -14
View File
@@ -1,7 +1,10 @@
import { components } from 'api-types'
import { Badge, cn } from 'ui'
import type { HTMLAttributes } from 'react'
interface ComputeBadgeProps extends React.ComponentProps<typeof Badge> {
import { components } from 'api-types'
import { cn } from 'ui'
interface ComputeBadgeProps extends HTMLAttributes<HTMLDivElement> {
infraComputeSize:
| components['schemas']['ProjectDetailResponse']['infra_compute_size']
| '>16XL'
@@ -13,22 +16,31 @@ export function ComputeBadge({ infraComputeSize, className, ...props }: ComputeB
infraComputeSize?.toLocaleLowerCase() === 'micro' ||
infraComputeSize?.toLocaleLowerCase() === 'nano'
return (
<Badge
className={cn(
'rounded-md text-center flex justify-center font-mono uppercase',
'group-data-[state=open]:bg-opacity-20 group-data-[state=open]:ring-2 group-data-[state=open]:ring-opacity-20',
'transition-all',
smallCompute
? 'group-data-[state=open]:ring-foreground-muted bg-opacity-50 group-data-[state=open]:bg-opacity-75'
: 'group-data-[state=open]:ring-brand',
const hasComputeSize = !!infraComputeSize
return (
<div
className={cn(
// Base styles
'inline-flex items-center justify-center rounded-md text-center font-mono uppercase',
'whitespace-nowrap font-medium tracking-[0.06em] text-[11px] leading-[1.1] px-[5.5px] py-[3px]',
'transition-all',
// Variant styles
!hasComputeSize
? 'bg-surface-75 text-foreground-light border border-strong'
: smallCompute
? 'bg-surface-75 text-foreground-light border border-strong bg-opacity-50'
: 'bg-brand bg-opacity-10 text-brand-600 border border-brand-500',
// Hover card interaction styles
'group-data-[state=open]:bg-opacity-20 group-data-[state=open]:ring-2 group-data-[state=open]:ring-opacity-20',
smallCompute
? 'group-data-[state=open]:ring-foreground-muted group-data-[state=open]:bg-opacity-75'
: 'group-data-[state=open]:ring-brand',
className
)}
variant={!infraComputeSize ? 'default' : smallCompute ? 'default' : 'brand'}
{...props}
>
{infraComputeSize}
</Badge>
</div>
)
}
@@ -23,7 +23,6 @@ import {
SheetHeader,
SheetSection,
SheetTitle,
SidePanel,
Switch,
} from 'ui'
import { z } from 'zod'
@@ -292,9 +291,9 @@ export const Page = () => {
render={({ field }) => (
<FormItemLayout
afterLabel={
<Badge variant={'destructive'} className="flex gap-1">
<FileWarning size={14} strokeWidth={1.5} className="text-destructive-500" />
Danger zone!
<Badge variant="destructive" className="flex gap-1">
<FileWarning size={12} strokeWidth={1.5} className="text-destructive-500" />
Danger
</Badge>
}
label="Use consistent settings"
+21 -40
View File
@@ -3,56 +3,37 @@ import * as React from 'react'
import { cn } from '../../../lib/utils/cn'
const badgeVariants = cva('inline-flex items-center rounded-full font-normal whitespace-nowrap', {
variants: {
variant: {
default: 'bg-surface-75 text-foreground-light border border-strong',
warning: 'bg-warning bg-opacity-10 text-warning border border-warning-500',
success: 'bg-brand bg-opacity-10 text-brand-600 border border-brand-500',
destructive:
'bg-destructive bg-opacity-10 text-destructive-600 border border-destructive-500',
brand: 'bg-brand bg-opacity-10 text-brand-600 border border-brand-500',
secondary:
'bg-secondary bg-opacity-10 hover:bg-secondary/80 border-transparent text-secondary-foreground',
outline: 'bg-transparent text border border-foreground-muted',
const badgeVariants = cva(
'inline-flex items-center gap-1 justify-center rounded-full font-normal whitespace-nowrap tracking-[0.07em] uppercase font-medium text-[9px] leading-none px-[5.5px] py-[3px]',
{
variants: {
variant: {
default: 'bg-surface-75 text-foreground-light border border-strong',
warning: 'bg-warning bg-opacity-10 text-warning border border-warning-500',
success: 'bg-brand bg-opacity-10 text-brand-600 border border-brand-500',
destructive:
'bg-destructive bg-opacity-10 text-destructive-600 border border-destructive-500',
// Secondary is invisible
secondary:
'bg-secondary bg-opacity-50 hover:bg-secondary/80 border-transparent text-secondary-foreground',
},
},
size: {
tiny: 'px-1.5 py-[3px] text-[10px] leading-none tracking-wide uppercase',
small: 'px-2 py-0.5 text-xs',
large: 'px-3 py-0.5 text-sm',
defaultVariants: {
variant: 'default',
},
dot: {
true: '-ml-0.5 mr-1.5 h-2 w-2',
},
},
defaultVariants: {
variant: 'default',
size: 'small',
},
})
}
)
export interface BadgeProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof badgeVariants> {}
function Badge({
className,
variant = 'default',
size = 'small',
dot = false,
children,
...props
}: BadgeProps) {
function Badge({ className, variant = 'default', children, ...props }: BadgeProps) {
return (
<div className={cn(badgeVariants({ variant, size }), className)} {...props}>
{dot && (
<svg className={badgeVariants({ dot })} fill="currentColor" viewBox="0 0 8 8">
<circle cx="4" cy="4" r="3" />
</svg>
)}
<div className={cn(badgeVariants({ variant }), className)} {...props}>
{children}
</div>
)
}
export { Badge, badgeVariants }
export { Badge }