mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
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:
1 parent
0a024516ad
commit
031b227165
96 files changed
+363
-574
No files matched your search
@@ -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,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -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 && (
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
+9
-20
@@ -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
|
||||
|
||||
+3
-3
@@ -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`,
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+1
-4
@@ -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>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
)
|
||||
|
||||
+4
-3
@@ -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"
|
||||
|
||||
+8
-6
@@ -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"
|
||||
|
||||
+3
-3
@@ -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>
|
||||
)}
|
||||
|
||||
|
||||
+1
-3
@@ -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_>
|
||||
|
||||
+1
-1
@@ -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>
|
||||
)}
|
||||
|
||||
+1
-1
@@ -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>
|
||||
|
||||
+13
-6
@@ -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_>
|
||||
|
||||
+1
-1
@@ -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">
|
||||
|
||||
+1
-1
@@ -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}
|
||||
|
||||
+8
-12
@@ -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}
|
||||
|
||||
+2
-2
@@ -47,9 +47,9 @@ export const EventMessage = ({
|
||||
? 'warning'
|
||||
: 'default'
|
||||
}
|
||||
className="ml-2 text-xs"
|
||||
className="ml-2"
|
||||
>
|
||||
{severity.toUpperCase()}
|
||||
{severity}
|
||||
</Badge>
|
||||
)}
|
||||
</span>
|
||||
|
||||
+1
-5
@@ -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',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)}
|
||||
>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 }
|
||||
Reference in new issue
Block a user