mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 09:25:06 +03:00
design system: text color contrast (#38343)
* Refactor Drawer component and add date-fns dependency Refactored the Drawer component for improved slot-based structure, updated styles, and added 'use client' directive. Added 'date-fns' as a dependency in design-system, updated tsconfig paths for icons, and marked ToggleGroup as a client component. * nit: add env for svg path * fix: instructions * accent color docs and basic tidy * copy value feature * improve color contrast * increase contrast on text-warning in light mode * update changelog * replace outdated text-warning utility classes * remove redundant warning-600 * minor design-system docs updates * docs updates * remove unused brand-button class * update docs * fix: restore brand default * update docs brand text color * low hanging branded text fruit * Nit refactor and clean up * re-add Kemal’s README instructions for hot reload --------- Co-authored-by: Jonathan Summers-Muir <MildTomato@users.noreply.github.com> Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
45 files changed
+148
-237
No files matched your search
@@ -1,46 +1,31 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
# Supabase Design System
|
||||
|
||||
Design resources for building consistent user experiences at Supabase.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
First, make a copy of _.env.local.example_ and name it _env.local_. Then run the development server as described below.
|
||||
|
||||
From within this _design-system_ directory, run:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
# or
|
||||
bun dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
Or from the root directory run:
|
||||
|
||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
||||
```bash
|
||||
pnpm dev:design-system
|
||||
```
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
Open [http://localhost:3003](http://localhost:3003) with your browser to see the result.
|
||||
|
||||
### Watching for MDX changes
|
||||
|
||||
If you would like to watch for changes to MDX files with hot reload, you can run the following command in a separate Terminal shell:
|
||||
If you would like to watch for changes to MDX files with hot reload, you can run the following command in a separate terminal shell:
|
||||
|
||||
```
|
||||
pnpm content:dev
|
||||
```
|
||||
|
||||
This runs Contentlayer concurrently and watches for any changes.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
@@ -8,7 +8,7 @@ const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Supabase Design System',
|
||||
description: 'Generated by create next app',
|
||||
description: 'Design resources for building consistent user experiences at Supabase.',
|
||||
}
|
||||
|
||||
interface RootLayoutProps {
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
import { cn } from 'ui/src/lib/utils/cn'
|
||||
// import { Card } from '@ui/components/shadcn/ui/card'
|
||||
import color from 'ui/src/lib/tailwind-demo-classes'
|
||||
import { Grid, GridItem } from './grid'
|
||||
import { useState } from 'react'
|
||||
|
||||
const Colors = ({
|
||||
definition,
|
||||
}: {
|
||||
definition: 'background' | 'border' | 'text' | 'colors' | 'palletes'
|
||||
}) => {
|
||||
const [copiedIndex, setCopiedIndex] = useState<number | null>(null)
|
||||
|
||||
const handleCopy = async (value: string, index: number) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(value)
|
||||
setCopiedIndex(index)
|
||||
setTimeout(() => {
|
||||
setCopiedIndex(null)
|
||||
}, 2000)
|
||||
} catch (err) {
|
||||
console.error('Failed to copy text: ', err)
|
||||
}
|
||||
}
|
||||
const Example = ({ x }: { x: string }) => {
|
||||
switch (definition) {
|
||||
case 'background':
|
||||
@@ -53,10 +66,11 @@ const Colors = ({
|
||||
<GridItem
|
||||
key={i}
|
||||
className={cn(x.includes('contrast') && 'bg-foreground hover:bg-foreground-light')}
|
||||
onClick={() => handleCopy(x, i)}
|
||||
>
|
||||
<Example x={x} />
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground">
|
||||
{x}
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground text-center">
|
||||
{copiedIndex === i ? 'Copied!' : x}
|
||||
</span>
|
||||
</GridItem>
|
||||
)
|
||||
@@ -66,90 +80,4 @@ const Colors = ({
|
||||
)
|
||||
}
|
||||
|
||||
{
|
||||
/* <div className="flex flex-col gap-12 py-20">
|
||||
<div className="flex flex-row gap-12">
|
||||
<div>
|
||||
<h5 className="mb-3">Background</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.background.map((x: string, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">Border</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.border.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border-4')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">texts</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.text.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<span className={cn(x, 'relative w-12 h-12 flex items-center justify-center')}>
|
||||
###
|
||||
</span>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row gap-12">
|
||||
<div>
|
||||
<h5 className="mb-3">Colors</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.colors.map((x: string, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="mb-3">Palletes</h5>
|
||||
<div className="flex flex-col gap-3">
|
||||
{color.palletes.map((x, i) => {
|
||||
return (
|
||||
<div className="flex gap-3 items-center" key={i}>
|
||||
<div className={cn(x, 'relative w-12 h-12 border border-overlay shadow')}></div>
|
||||
<div className="font-mono text-sm bg-surface-100 px-2 py-0.5 rounded-full">
|
||||
{x}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */
|
||||
}
|
||||
|
||||
export { Colors }
|
||||
@@ -38,13 +38,13 @@ export const docsConfig: DocsConfig = {
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Color usage',
|
||||
href: '/docs/color-usage',
|
||||
title: 'Tailwind Classes',
|
||||
href: '/docs/tailwind-classes',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Tailwind classes',
|
||||
href: '/docs/tailwind-classes',
|
||||
title: 'Color Usage',
|
||||
href: '/docs/color-usage',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,6 +4,13 @@ description: Latest updates and announcements.
|
||||
toc: false
|
||||
---
|
||||
|
||||
## 1st Sep 2025 - Update button styles
|
||||
|
||||
- [`Color usage`](/design-system/docs/color-usage) page updated
|
||||
- Color tokens improved for accessibility
|
||||
|
||||
[PR](https://github.com/supabase/supabase/pull/38343)
|
||||
|
||||
## 18th Oct 2024 - Update multi-select
|
||||
|
||||
Improved Multi Select with combobox, badge limit, and more examples.
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
---
|
||||
title: Color usage
|
||||
description: Colors system breakdown with best practice
|
||||
description: Colors system breakdown with best practices.
|
||||
---
|
||||
|
||||
Colors available in the Supabase Design System
|
||||
The shorthand utility classes below simplify our full color palette by providing sensible, contrast-checked defaults. Use them whenever possible to ensure accessible text colors and balanced background fills.
|
||||
|
||||
These are examples of using colors with shorthands.
|
||||
## Text
|
||||
|
||||
Use accent text colors (e.g. text-destructive, text-warning) sparingly to avoid visual overload.
|
||||
|
||||
<Colors definition={'text'} />
|
||||
|
||||
## Background
|
||||
|
||||
@@ -60,15 +64,8 @@ This is not to be confused with `Dialogs`, they require to use the same app back
|
||||
|
||||
<Colors definition={'border'} />
|
||||
|
||||
## Text
|
||||
|
||||
These can also be accessed with `foreground`. Like `text-foreground-light`.
|
||||
|
||||
<Colors definition={'text'} />
|
||||
|
||||
## Other Colors
|
||||
|
||||
These can also be accessed with `foreground`. Like `text-foreground-light`.
|
||||
|
||||
<Colors definition={'colors'} />
|
||||
```
|
||||
@@ -1,37 +1,37 @@
|
||||
---
|
||||
title: Tailwind Classes
|
||||
description: Icons system breakdown. Copy values of Icons.
|
||||
description: Theming support for Tailwind classes.
|
||||
---
|
||||
|
||||
Supabase is migrating to use tailwind classes that use CSS properties.
|
||||
Supabase uses Tailwind classes that in turn use CSS properties.
|
||||
This is to support the concept of theming, so that:
|
||||
|
||||
1. It is easy for the team to update the theme without changing 100s of files.
|
||||
2. We could offer custom or additional themes in future.
|
||||
1. We can update themes from one place.
|
||||
2. We can offer custom or additional themes in the future.
|
||||
|
||||
## Primitives
|
||||
|
||||
We (the Supabase Design team ✨) define primitive color values using Figma Variables.
|
||||
We define primitive color values using these tokens:
|
||||
|
||||
- `background`
|
||||
- `foreground`
|
||||
- `border`
|
||||
- `brand`
|
||||
- `destructive`
|
||||
- `warning`
|
||||
- `destructive`
|
||||
|
||||
These values are exported from Figma as a .json file and transformed into tailwind utilities through some scripts under `packages/ui/internals/tokens`.
|
||||
These values are exported from Figma as a .json file and transformed into Tailwind utilities through some scripts under `packages/ui/internals/tokens`.
|
||||
|
||||
Any of these colors are available on any tailwind utility that accepts color. For example:
|
||||
Any of these colors are available on any Tailwind utility that accepts color. For example:
|
||||
|
||||
```jsx
|
||||
// this uses the default foreground color
|
||||
// this uses the default foreground color for this theme
|
||||
<span className="text-foreground"></span>
|
||||
|
||||
// this uses the 'light' foreground color
|
||||
// this uses the 'light' foreground color for this theme (one notch 'softer' than the default)
|
||||
<span className="text-foreground-light"></span>
|
||||
|
||||
// this uses the default warning color
|
||||
// this uses the default warning color for this theme
|
||||
<span className="text-warning"></span>
|
||||
|
||||
// this uses the '500' warning color
|
||||
@@ -48,12 +48,12 @@ We support shorthand classes for `background`, `foreground` and `border`. For ex
|
||||
|
||||
This will stop you from needing to 'double type' the same utility name.
|
||||
|
||||
You might notice we use `foreground` and `background` as prefixes, this is only because it is a Design Token standard, where as tailwind uses `bg` and `text`.
|
||||
You might notice we use `foreground` and `background` as prefixes, this is only because it is a Design Token standard, where as Tailwind uses `bg` and `text`.
|
||||
|
||||
## Mixing colors
|
||||
|
||||
Even with shorthands, remember you can use any color. For example, `foreground-light` can also be applied on borders and backgrounds as `border-foreground-light` and `bg-foreground-light`, if needed.
|
||||
Similarly, background and border primitives can be used on other tailwind utilities.
|
||||
Similarly, background and border primitives can be used on other Tailwind utilities.
|
||||
|
||||
```jsx
|
||||
// use the text light color for some text
|
||||
@@ -61,13 +61,13 @@ Similarly, background and border primitives can be used on other tailwind utilit
|
||||
|
||||
// we can use the same color for a background
|
||||
<div className="bg-foreground-light">
|
||||
<span>I have the same color background as the left example</span>
|
||||
<span>I have the same background color as the above example</span>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Opacity support
|
||||
|
||||
All the colors are generated using tailwind opacity, like `hsl(--background-default) / var(--tw-bg-opacity)`.
|
||||
All colors are generated using Tailwind opacity, like `hsl(--background-default) / var(--tw-bg-opacity)`.
|
||||
This means all the color options in our themes can support opacity rules. For example:
|
||||
|
||||
```jsx
|
||||
@@ -82,7 +82,9 @@ This means all the color options in our themes can support opacity rules. For ex
|
||||
|
||||
## Usage
|
||||
|
||||
The following tailwind classes are a combination of tailwind utilities and our primitives. They're under development and are likely to change but most are now in use and will probably be permanent fixtures.
|
||||
The following Tailwind classes are a combination of Tailwind utilities and our primitives.
|
||||
|
||||
Note that the shade of the `DEFAULT` value on each scale pattern is variable. Sometimes it is fixed at a particular shade (such as `500` or `600`), but only when contrast is sufficient.
|
||||
|
||||
### Foreground (Text)
|
||||
|
||||
@@ -118,7 +120,7 @@ Examples:
|
||||
| `background-control` | Inputs, Radios, Checkboxes |
|
||||
| `background-button-{DEFAULT}` | Button default |
|
||||
|
||||
The `background` part can be omitted when used on the `bg` tailwind utility.
|
||||
The `background` part can be omitted when used on the `bg` Tailwind utility.
|
||||
|
||||
Examples:
|
||||
|
||||
|
||||
@@ -268,7 +268,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="Explore more resources"
|
||||
url="/guides/resources"
|
||||
className="no-underline text-brand text-sm"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -328,7 +328,7 @@ const HomePage = () => (
|
||||
<TextLink
|
||||
label="More on Self-Hosting"
|
||||
url="/guides/self-hosting"
|
||||
className="no-underline text-brand text-sm"
|
||||
className="no-underline text-brand-link text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -161,7 +161,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
'[transition-property:opacity,transform,color] [transition-duration:150ms,250ms,250ms]',
|
||||
'motion-reduce:[transition-duration:150ms,1ms,300ms]',
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
!isNo && 'hover:text-warning-600 hover:border-warning-500',
|
||||
!isNo && 'hover:text-warning hover:border-warning-500',
|
||||
isNo && `bg-warning text-warning-200 !border-warning disabled:opacity-100`,
|
||||
!showNo && 'opacity-0 invisible'
|
||||
)}
|
||||
|
||||
@@ -58,7 +58,7 @@ function FeedbackModal({ visible, page, onCancel, onSubmit }: FeedbackModalProps
|
||||
href="https://supabase.com/dashboard/support/new"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand hover:underline"
|
||||
className="text-brand-link hover:underline"
|
||||
>
|
||||
support request
|
||||
</a>
|
||||
|
||||
@@ -20,7 +20,7 @@ function AiPrompt({ className }: { className?: string }) {
|
||||
className={cn(
|
||||
'group',
|
||||
'w-fit rounded-full border px-3 py-1 flex gap-2 items-center text-foreground-light text-sm',
|
||||
'hover:border-brand hover:text-brand focus-visible:text-brand',
|
||||
'hover:border-brand hover:text-brand-link focus-visible:text-brand-link',
|
||||
'transition-colors',
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -22,7 +22,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
<li key={id} className="function-link-item text-foreground-lighter leading-3">
|
||||
<Link
|
||||
href={`#${id}`}
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand flex gap-3"
|
||||
className="cursor-pointer transition text-foreground-lighter text-sm hover:text-brand-link flex gap-3"
|
||||
>
|
||||
{icon && <img className="w-3" src={`${BASE_PATH}${icon}`} />}
|
||||
{title}
|
||||
@@ -99,7 +99,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
href={`${menu.parent ?? '/'}`}
|
||||
className={[
|
||||
'flex items-center gap-1 text-xs group mb-3',
|
||||
'text-base transition-all duration-200 text-brand hover:text-brand-600 hover:cursor-pointer ',
|
||||
'text-base transition-all duration-200 text-brand-link hover:text-brand-600 hover:cursor-pointer ',
|
||||
].join(' ')}
|
||||
>
|
||||
<div className="relative w-2">
|
||||
|
||||
@@ -19,7 +19,7 @@ const HeaderLink = React.memo(function HeaderLink(props: {
|
||||
className={[
|
||||
' ',
|
||||
!props.title && 'capitalize',
|
||||
props.url === pathname ? 'text-brand' : 'hover:text-brand text-foreground',
|
||||
props.url === pathname ? 'text-brand-link' : 'hover:text-brand-link text-foreground',
|
||||
].join(' ')}
|
||||
>
|
||||
{props.title ?? props.id}
|
||||
@@ -75,7 +75,7 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
'flex items-center gap-2',
|
||||
'cursor-pointer transition text-sm',
|
||||
activeItem
|
||||
? 'text-brand font-medium'
|
||||
? 'text-brand-link font-medium'
|
||||
: 'hover:text-foreground text-foreground-lighter',
|
||||
].join(' ')}
|
||||
parent={props.subItem.parent}
|
||||
@@ -104,8 +104,8 @@ const ContentAccordionLink = React.memo(function ContentAccordionLink(props: any
|
||||
className={[
|
||||
'cursor-pointer transition text-sm',
|
||||
subSubItem.url === pathname
|
||||
? 'text-brand'
|
||||
: 'hover:text-brand text-foreground-lighter',
|
||||
? 'text-brand-link'
|
||||
: 'hover:text-brand-link text-foreground-lighter',
|
||||
].join(' ')}
|
||||
>
|
||||
{subSubItem.name}
|
||||
|
||||
@@ -105,7 +105,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
{group.label}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -119,7 +119,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 px-5 rounded text-sm transition',
|
||||
`${
|
||||
section.url === pathname
|
||||
? 'bg-background text-brand'
|
||||
? 'bg-background text-brand-link'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
@@ -144,7 +144,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
size={14}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<span className="text-foreground text-sm group-hover:text-brand transition">
|
||||
<span className="text-foreground text-sm group-hover:text-brand-link transition">
|
||||
{section.name}
|
||||
</span>
|
||||
</Accordion.Trigger>
|
||||
@@ -157,7 +157,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
'py-1.5 ml-4 px-5 rounded text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand'
|
||||
? 'bg-background text-brand-link'
|
||||
: 'text-foreground-light hover:text-foreground'
|
||||
}`,
|
||||
].join(' ')}
|
||||
|
||||
@@ -40,7 +40,7 @@ function ClientLibHeader({ menuData, className }: ClientLibHeaderProps) {
|
||||
href={menuData.pkg.repo}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
className="hover:text-brand focus-visible:text-brand transition-colors"
|
||||
className="hover:text-brand-link focus-visible:text-brand-link transition-colors"
|
||||
>
|
||||
<span className="sr-only">View on GitHub</span>
|
||||
<Github size={18} />
|
||||
|
||||
@@ -221,7 +221,7 @@ function ParamOrTypeDetails({ paramOrType }: { paramOrType: object }) {
|
||||
/>
|
||||
{/* @ts-ignore */}
|
||||
{paramOrType?.comment?.tags?.some((tag) => tag.tag === 'deprecated') && (
|
||||
<span className="text-xs text-warning-600">Deprecated</span>
|
||||
<span className="text-xs text-warning">Deprecated</span>
|
||||
)}
|
||||
<span className="text-xs text-foreground-muted">{getTypeName(paramOrType)}</span>
|
||||
</div>
|
||||
@@ -353,7 +353,7 @@ export function ApiSchemaParamDetails({ param }: { param: IApiEndPoint['paramete
|
||||
{param.name}
|
||||
</span>
|
||||
<RequiredBadge isOptional={!param.required} />
|
||||
{param.schema?.deprecated && <span className="text-xs text-warning-600">Deprecated</span>}
|
||||
{param.schema?.deprecated && <span className="text-xs text-warning">Deprecated</span>}
|
||||
{param.schema && (
|
||||
<span className="text-xs text-foreground-muted">
|
||||
{getTypeDisplayFromSchema(param.schema)?.displayName ?? ''}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import dayjs from 'dayjs'
|
||||
import { useMemo, useRef } from 'react'
|
||||
import { ReactNode, useMemo, useRef } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import AlertError from 'components/ui/AlertError'
|
||||
import { FormHeader } from 'components/ui/Forms/FormHeader'
|
||||
import { APIKeysData, useAPIKeysQuery } from 'data/api-keys/api-keys-query'
|
||||
import useLogsQuery from 'hooks/analytics/useLogsQuery'
|
||||
import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions'
|
||||
import { Card, CardContent, EyeOffIcon, Skeleton, WarningIcon, cn } from 'ui'
|
||||
import { Card, CardContent, EyeOffIcon, Skeleton, cn } from 'ui'
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
@@ -52,8 +53,9 @@ export const SecretAPIKeys = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const {
|
||||
data: apiKeysData,
|
||||
isLoading: isLoadingApiKeys,
|
||||
error,
|
||||
isLoading: isLoadingApiKeys,
|
||||
isError: isErrorApiKeys,
|
||||
} = useAPIKeysQuery({ projectRef, reveal: false })
|
||||
|
||||
const { can: canReadAPIKeys, isLoading: isLoadingPermissions } = useAsyncCheckProjectPermissions(
|
||||
@@ -90,14 +92,14 @@ export const SecretAPIKeys = () => {
|
||||
</TableRow>
|
||||
)
|
||||
|
||||
const TableContainer = ({ children }: { children: React.ReactNode }) => (
|
||||
const TableContainer = ({ children, className }: { children: ReactNode; className?: string }) => (
|
||||
<div className="pb-30">
|
||||
<FormHeader
|
||||
title="Secret keys"
|
||||
description="These API keys allow privileged access to your project's APIs. Use in servers, functions, workers or other backend components of your application."
|
||||
actions={<CreateSecretAPIKeyDialog />}
|
||||
/>
|
||||
<Card className={cn('w-full overflow-hidden', !empty && 'bg-surface-100')}>
|
||||
<Card className={cn('w-full overflow-hidden', !empty && 'bg-surface-100', className)}>
|
||||
<CardContent className="p-0">
|
||||
<Table className="p-5 table-auto">
|
||||
<TableHeader>
|
||||
@@ -147,14 +149,10 @@ export const SecretAPIKeys = () => {
|
||||
)
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (isErrorApiKeys) {
|
||||
return (
|
||||
<TableContainer>
|
||||
<div className="!rounded-b-md overflow-hidden py-12 flex flex-col gap-1 items-center justify-center">
|
||||
<WarningIcon />
|
||||
<p className="text-sm text-warning-600">Error loading Secret API Keys</p>
|
||||
<p className="text-warning/75">{error.message}</p>
|
||||
</div>
|
||||
<TableContainer className="border-0">
|
||||
<AlertError error={error} subject="Failed to load secret API keys" />
|
||||
</TableContainer>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,10 +127,7 @@ export const UserLogs = ({ user }: UserLogsProps) => {
|
||||
)}
|
||||
>
|
||||
{(is400 || is500) && (
|
||||
<CriticalIcon
|
||||
hideBackground
|
||||
className={cn(is400 && 'text-warning-600')}
|
||||
/>
|
||||
<CriticalIcon hideBackground className={cn(is400 && 'text-warning')} />
|
||||
)}
|
||||
{status}
|
||||
</div>
|
||||
|
||||
@@ -52,24 +52,24 @@ export const PipelineStatus = ({
|
||||
if (requestStatus === PipelineStatusRequestStatus.RestartRequested) {
|
||||
return {
|
||||
label: 'Restarting',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning" />,
|
||||
color: 'text-warning',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
if (requestStatus === PipelineStatusRequestStatus.StartRequested) {
|
||||
return {
|
||||
label: 'Starting',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning" />,
|
||||
color: 'text-warning',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
if (requestStatus === PipelineStatusRequestStatus.StopRequested) {
|
||||
return {
|
||||
label: 'Stopping',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning" />,
|
||||
color: 'text-warning',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
}
|
||||
@@ -86,8 +86,8 @@ export const PipelineStatus = ({
|
||||
case PipelineStatusName.STARTING:
|
||||
return {
|
||||
label: 'Starting',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning-600" />,
|
||||
color: 'text-warning-600',
|
||||
dot: <Loader2 className="animate-spin w-3 h-3 text-warning" />,
|
||||
color: 'text-warning',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
case PipelineStatusName.STARTED:
|
||||
@@ -108,7 +108,7 @@ export const PipelineStatus = ({
|
||||
return {
|
||||
label: 'Unknown',
|
||||
dot: <div className="w-2 h-2 bg-warning-600 rounded-full" />,
|
||||
color: 'text-warning-600',
|
||||
color: 'text-warning',
|
||||
tooltip: stateMessages.message,
|
||||
}
|
||||
default:
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ export const getStatusConfig = (state: TableState['state']) => {
|
||||
return {
|
||||
badge: <Badge variant="warning">Queued</Badge>,
|
||||
description: 'Waiting to start replication',
|
||||
color: 'text-warning-600',
|
||||
color: 'text-warning',
|
||||
}
|
||||
case 'copying_table':
|
||||
return {
|
||||
@@ -41,7 +41,7 @@ export const getStatusConfig = (state: TableState['state']) => {
|
||||
return {
|
||||
badge: <Badge variant="warning">Unknown</Badge>,
|
||||
description: 'Unknown status',
|
||||
color: 'text-warning-600',
|
||||
color: 'text-warning',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { calculateDiskSizePrice } from '../DiskManagement.utils'
|
||||
import { BillingChangeBadge } from '../ui/BillingChangeBadge'
|
||||
import { DiskType, PLAN_DETAILS } from '../ui/DiskManagement.constants'
|
||||
import { DiskManagementDiskSizeReadReplicas } from '../ui/DiskManagementReadReplicas'
|
||||
import DiskSpaceBar from '../ui/DiskSpaceBar'
|
||||
import { DiskSpaceBar } from '../ui/DiskSpaceBar'
|
||||
import { DiskTypeRecommendationSection } from '../ui/DiskTypeRecommendationSection'
|
||||
import FormMessage from '../ui/FormMessage'
|
||||
import { InputPostTab } from '../ui/InputPostTab'
|
||||
|
||||
@@ -19,7 +19,7 @@ interface DiskSpaceBarProps {
|
||||
form: UseFormReturn<DiskStorageSchemaType>
|
||||
}
|
||||
|
||||
export default function DiskSpaceBar({ form }: DiskSpaceBarProps) {
|
||||
export const DiskSpaceBar = ({ form }: DiskSpaceBarProps) => {
|
||||
const { ref } = useParams()
|
||||
const { resolvedTheme } = useTheme()
|
||||
const { formState, watch } = form
|
||||
@@ -94,7 +94,7 @@ export default function DiskSpaceBar({ form }: DiskSpaceBarProps) {
|
||||
<div
|
||||
className={cn(
|
||||
'h-[35px] relative border rounded-sm w-full transition',
|
||||
showNewSize ? 'bg-selection border border-brand-button' : 'bg-surface-300'
|
||||
showNewSize ? 'bg-selection border border-brand' : 'bg-surface-300'
|
||||
)}
|
||||
>
|
||||
<AnimatePresence>
|
||||
|
||||
@@ -103,7 +103,7 @@ const LintPageTabs = ({
|
||||
tab.id === LINTER_LEVELS.ERROR
|
||||
? 'text-destructive-600'
|
||||
: tab.id === LINTER_LEVELS.WARN
|
||||
? 'text-warning-600'
|
||||
? 'text-warning'
|
||||
: 'text-brand-500'
|
||||
}
|
||||
>
|
||||
|
||||
@@ -87,7 +87,7 @@ export const RegionSelector = ({
|
||||
<>
|
||||
<p>Select the region closest to your users for the best performance.</p>
|
||||
{showNonProdFields && (
|
||||
<div className="mt-2 text-warning-600">
|
||||
<div className="mt-2 text-warning">
|
||||
<p>Only these regions are supported for local/staging projects:</p>
|
||||
<ul className="list-disc list-inside mt-1">
|
||||
<li>East US (North Virginia)</li>
|
||||
|
||||
+3
-5
@@ -25,17 +25,15 @@ export const ColumnRenderer: Column<LogData, unknown>[] = [
|
||||
<div
|
||||
className={cn(
|
||||
'flex justify-center items-center min-w-[24px]',
|
||||
isErrorLog(data.row) ? 'text-warning-600' : 'text-green-900'
|
||||
isErrorLog(data.row) ? 'text-warning' : 'text-green-900'
|
||||
)}
|
||||
>
|
||||
{ICONS[type]}
|
||||
</div>
|
||||
<span className={cn('font-mono', isErrorLog(data.row) ? '!text-warning-600' : '')}>
|
||||
<span className={cn('font-mono', isErrorLog(data.row) ? '!text-warning' : '')}>
|
||||
{new Date(data.row.timestamp).toISOString()}
|
||||
</span>
|
||||
<span
|
||||
className={cn('truncate font-mono', isErrorLog(data.row) ? '!text-warning-600' : '')}
|
||||
>
|
||||
<span className={cn('truncate font-mono', isErrorLog(data.row) ? '!text-warning' : '')}>
|
||||
{JSON.stringify(data.row.metadata)}
|
||||
</span>
|
||||
</RowLayout>
|
||||
|
||||
+2
-2
@@ -86,7 +86,7 @@ export const GitHubStatus = () => {
|
||||
{hasGitBranchSync ? (
|
||||
<CheckCircle2 size={12} className="text-brand-600" />
|
||||
) : (
|
||||
<AlertCircle size={12} className="text-warning-600" />
|
||||
<AlertCircle size={12} className="text-warning" />
|
||||
)}
|
||||
<span>
|
||||
{hasGitBranchSync
|
||||
@@ -98,7 +98,7 @@ export const GitHubStatus = () => {
|
||||
{hasAutomaticBranching ? (
|
||||
<CheckCircle2 size={12} className="text-brand-600" />
|
||||
) : (
|
||||
<AlertCircle size={12} className="text-warning-600" />
|
||||
<AlertCircle size={12} className="text-warning" />
|
||||
)}
|
||||
<span>
|
||||
{hasAutomaticBranching
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@ const VercelIntegrationConnectionForm = ({
|
||||
</div>
|
||||
|
||||
{form.formState.isDirty ? (
|
||||
<p className="mt-2 text-sm text-warning-600">
|
||||
<p className="mt-2 text-sm text-warning">
|
||||
Note: Changing these settings will <strong>not</strong> trigger a resync of
|
||||
environment variables.
|
||||
</p>
|
||||
|
||||
@@ -391,7 +391,7 @@ export const LogsDatePicker = ({
|
||||
/>
|
||||
</div>
|
||||
{isLargeRange && !hideWarnings && (
|
||||
<div className="text-xs px-3 py-1.5 border-y bg-warning-300 text-warning-foreground border-warning-500 text-warning-600">
|
||||
<div className="text-xs px-3 py-1.5 border-y bg-warning-300 text-warning-foreground border-warning-500 text-warning">
|
||||
Large ranges may result in memory errors for <br /> big projects.
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -107,8 +107,8 @@ export function getStatusColor(value?: number | string): Record<'text' | 'bg' |
|
||||
case 'warning':
|
||||
case 'redirect':
|
||||
return {
|
||||
text: 'text-warning-600 dark:text-warning',
|
||||
bg: 'bg-warning-300 dark:bg-waning-200',
|
||||
text: 'text-warning',
|
||||
bg: 'bg-warning-300 dark:bg-warning-200',
|
||||
border: 'border border-warning-400/50 dark:border-warning-400/50',
|
||||
}
|
||||
case '5':
|
||||
|
||||
@@ -58,7 +58,7 @@ const Footer = (props: Props) => {
|
||||
<SectionContainer className="grid grid-cols-2 md:flex items-center justify-between text-foreground md:justify-center gap-8 md:gap-16 xl:gap-28 !py-6 md:!py-10 text-sm">
|
||||
<div className="flex flex-col md:flex-row gap-2 md:items-center">
|
||||
We protect your data.
|
||||
<Link href="/security" className="text-brand hover:underline">
|
||||
<Link href="/security" className="text-brand-link hover:underline">
|
||||
More on Security
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -76,7 +76,7 @@ const CustomerQuotesSection = (props: Props) => {
|
||||
{customer.author}, {customer.role}
|
||||
</p>
|
||||
{customer.url && (
|
||||
<div className="text-brand border-t mt-4 pt-4 cursor-pointer text-sm flex items-center justify-between">
|
||||
<div className="text-brand-link border-t mt-4 pt-4 cursor-pointer text-sm flex items-center justify-between">
|
||||
<span>Read Customer Story</span>
|
||||
<ArrowUpRight />
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,7 @@ const DPA = () => {
|
||||
href="https://supabase.com/downloads/docs/Supabase+DPA+250805.pdf"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand hover:underline"
|
||||
className="text-brand-link hover:underline"
|
||||
onClick={() =>
|
||||
sendTelemetryEvent({
|
||||
action: 'dpa_pdf_opened',
|
||||
@@ -42,7 +42,7 @@ const DPA = () => {
|
||||
href="https://supabase.com/dashboard/org/_/documents"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-brand hover:underline"
|
||||
className="text-brand-link hover:underline"
|
||||
>
|
||||
request it from the legal documents page
|
||||
</a>{' '}
|
||||
|
||||
@@ -248,7 +248,7 @@ const PartnerDetails = ({ partner }: { partner: Partner }) => {
|
||||
<span className="text-lighter">Category</span>
|
||||
<Link
|
||||
href={`/partners/integrations#${partner.category.toLowerCase()}`}
|
||||
className="text-brand hover:underline transition-colors"
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
>
|
||||
{partner.category}
|
||||
</Link>
|
||||
@@ -260,7 +260,7 @@ const PartnerDetails = ({ partner }: { partner: Partner }) => {
|
||||
href={partner.website}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-brand hover:underline transition-colors"
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
>
|
||||
{new URL(partner.website).host}
|
||||
</a>
|
||||
@@ -273,7 +273,7 @@ const PartnerDetails = ({ partner }: { partner: Partner }) => {
|
||||
href={partner.docs}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-brand hover:underline transition-colors"
|
||||
className="text-brand-link hover:underline transition-colors"
|
||||
>
|
||||
<span className="flex items-center space-x-1">
|
||||
<span>Learn</span>
|
||||
|
||||
@@ -119,7 +119,7 @@ export const GlassPanel = ({
|
||||
</div>
|
||||
|
||||
{children && <span className="text-sm text-foreground-light flex-grow">{children}</span>}
|
||||
{showLink && <span className="text-brand justify-end text-sm">Learn more</span>}
|
||||
{showLink && <span className="text-brand-link justify-end text-sm">Learn more</span>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -102,7 +102,7 @@ export const IconPanel = ({
|
||||
{children && (
|
||||
<span className="text-sm text-foreground-light not-prose">{children}</span>
|
||||
)}
|
||||
{showLink && <span className="text-brand justify-end text-sm">Learn more</span>}
|
||||
{showLink && <span className="text-brand-link justify-end text-sm">Learn more</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
--secondary-400: 0deg 0% 100%;
|
||||
--secondary-200: 0deg 0% 100%;
|
||||
--brand-link: 153.1deg 60.2% 52.7%;
|
||||
--brand-button: 151.8deg 47.1% 40.8%;
|
||||
--brand-default: 153.1deg 60.2% 52.7%;
|
||||
--brand-600: 153deg 59.5% 70%;
|
||||
--brand-500: 153.5deg 61.8% 21.6%;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
--secondary-400: 20deg 93.2% 40.4%;
|
||||
--secondary-200: 17.7deg 78.9% 27.8%;
|
||||
--brand-link: 163.9deg 53.2% 15.1%;
|
||||
--brand-button: 175.6deg 61.8% 21.6%;
|
||||
--brand-default: 163.9deg 53.2% 15.1%;
|
||||
--brand-600: 156.3deg 59.5% 70%;
|
||||
--brand-500: 175.6deg 61.8% 21.6%;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
--secondary-400: 248.3deg 54.5% 25.9%;
|
||||
--secondary-200: 248deg 53.6% 11%;
|
||||
--brand-link: 155deg 100% 38.6%;
|
||||
--brand-button: 154.9deg 100% 19.2%;
|
||||
--brand-default: 153.1deg 60.2% 52.7%;
|
||||
--brand-600: 154.9deg 59.5% 70%;
|
||||
--brand-500: 154.9deg 100% 19.2%;
|
||||
|
||||
@@ -12,14 +12,13 @@
|
||||
--secondary-400: 248.3deg 54.5% 25.9%;
|
||||
--secondary-200: 248deg 53.6% 11%;
|
||||
--brand-link: 155deg 100% 38.6%;
|
||||
--brand-button: 154.9deg 100% 19.2%;
|
||||
--brand-default: 153.1deg 60.2% 52.7%;
|
||||
--brand-600: 154.9deg 59.5% 70%;
|
||||
--brand-500: 154.9deg 100% 19.2%;
|
||||
--brand-400: 155.5deg 100% 9.6%;
|
||||
--brand-300: 155.1deg 100% 8%;
|
||||
--brand-200: 162deg 100% 2%;
|
||||
--warning-default: 38.9deg 100% 42.9%;
|
||||
--warning-default: 38.9deg 100% 42.9%; /* warning-600 */
|
||||
--warning-600: 38.9deg 100% 42.9%;
|
||||
--warning-500: 34.8deg 90.9% 21.6%;
|
||||
--warning-400: 33.2deg 100% 14.5%;
|
||||
|
||||
@@ -10,14 +10,13 @@
|
||||
--secondary-400: 248.3deg 54.5% 25.9%;
|
||||
--secondary-200: 248deg 53.6% 11%;
|
||||
--brand-link: 153.4deg 100% 36.7%;
|
||||
--brand-button: 151.8deg 47.1% 40.8%;
|
||||
--brand-default: 152.9deg 60% 52.9%;
|
||||
--brand-600: 156.5deg 86.5% 26.1%;
|
||||
--brand-500: 155.3deg 78.4% 40%;
|
||||
--brand-400: 151.3deg 66.9% 66.9%;
|
||||
--brand-300: 147.5deg 72% 80.4%;
|
||||
--brand-200: 147.6deg 72.5% 90%;
|
||||
--warning-default: 38.9deg 100% 57.1%;
|
||||
--warning-default: 30.3deg 80.3% 47.8%; /* warning-600 */
|
||||
--warning-600: 30.3deg 80.3% 47.8%;
|
||||
--warning-500: 36.3deg 85.7% 67.1%;
|
||||
--warning-400: 41.9deg 100% 81.8%;
|
||||
|
||||
@@ -603,10 +603,6 @@ module.exports = {
|
||||
cssVariable: 'var(--brand-default)',
|
||||
value: 'hsl(153.10000000000002, 60.2%, 52.7%)',
|
||||
},
|
||||
'brand-button': {
|
||||
cssVariable: 'var(--brand-button)',
|
||||
value: 'hsl(154.89999999999998, 100%, 19.2%)',
|
||||
},
|
||||
'brand-link': {
|
||||
cssVariable: 'var(--brand-link)',
|
||||
value: 'hsl(155, 100%, 38.6%)',
|
||||
|
||||
@@ -177,7 +177,7 @@ const IconContainerVariants = cva('', {
|
||||
link: 'text-brand-600',
|
||||
text: 'text-foreground-lighter',
|
||||
danger: 'text-destructive-600',
|
||||
warning: 'text-warning-600',
|
||||
warning: 'text-warning',
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -195,7 +195,7 @@ const loadingVariants = cva('', {
|
||||
link: 'text-brand-600',
|
||||
text: 'text-foreground-muted',
|
||||
danger: 'text-destructive-600',
|
||||
warning: 'text-warning-600',
|
||||
warning: 'text-warning',
|
||||
},
|
||||
loading: {
|
||||
default: '',
|
||||
|
||||
@@ -91,7 +91,7 @@ const WarningIcon: React.FC<SVGProps<SVGSVGElement> & StatusIconProps> = ({
|
||||
className={cn(
|
||||
!hideBackground
|
||||
? 'w-4 h-4 p-0.5 bg-warning-600 text-warning-200 rounded'
|
||||
: 'w-3 h-3 text-warning-600',
|
||||
: 'w-3 h-3 text-warning',
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
@@ -151,7 +151,7 @@ const EyeIcon: React.FC<SVGProps<SVGSVGElement> & StatusIconProps> = ({
|
||||
className={cn(
|
||||
!hideBackground
|
||||
? 'w-4 h-4 p-0.5 bg-warning-600 text-warning-200 rounded'
|
||||
: 'w-3 h-3 text-warning-600',
|
||||
: 'w-3 h-3 text-warning',
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
@@ -180,7 +180,7 @@ const EyeOffIcon: React.FC<SVGProps<SVGSVGElement> & StatusIconProps> = ({
|
||||
className={cn(
|
||||
!hideBackground
|
||||
? 'w-4 h-4 p-0.5 bg-foreground-light text-background rounded'
|
||||
: 'w-3 h-3 text-warning-600',
|
||||
: 'w-3 h-3 text-warning',
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ const badgeVariants = cva(
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-surface-200 text-foreground-light border border-strong',
|
||||
warning: 'bg-warning text-warning-600 border border-warning-500',
|
||||
warning: 'bg-warning text-warning border border-warning-500',
|
||||
success: 'bg-brand text-brand-600 border border-brand-500',
|
||||
destructive: 'bg-destructive text-destructive-600 border border-destructive-500',
|
||||
brand: 'bg-brand text-brand-600 border border-brand-500',
|
||||
|
||||
@@ -31,7 +31,16 @@ export default {
|
||||
'border-button',
|
||||
'border-button-hover',
|
||||
],
|
||||
text: ['text', 'text-light', 'text-lighter', 'text-muted', 'text-contrast'],
|
||||
text: [
|
||||
'text',
|
||||
'text-light',
|
||||
'text-lighter',
|
||||
'text-muted',
|
||||
'text-contrast',
|
||||
'text-destructive',
|
||||
'text-warning',
|
||||
'text-brand',
|
||||
],
|
||||
colors: [
|
||||
'bg-destructive-200',
|
||||
'bg-destructive-300',
|
||||
@@ -51,7 +60,6 @@ export default {
|
||||
'bg-brand-500',
|
||||
'bg-brand-600',
|
||||
'bg-brand',
|
||||
'bg-brand-button',
|
||||
'bg-brand-link',
|
||||
'bg-_secondary-200',
|
||||
'bg-_secondary-400',
|
||||
|
||||
Reference in new issue
Block a user