mirror of
https://github.com/supabase/supabase.git
synced 2026-05-06 08:56:46 -04:00
chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4: - Removed `@tailwindcss/container-queries` plugin since it's included by default in v4, - Bump all instances of Tailwind to v4. Made minimal changes to the shared config to remove non-supported features (`alpha` mentions), - Migrate all apps to be compatible with v4 configs, - Fix the `typography.css` import in 3 apps, - Add missing rules which were included by default in v3, - Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot of classes - Rename all misnamed classes according to https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all apps. --------- Co-authored-by: Jordi Enric <jordi.err@gmail.com>
This commit is contained in:
@@ -71,7 +71,7 @@ export default function ChartComposedMetrics() {
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
@@ -89,7 +89,7 @@ export default function ChartComposedMetrics() {
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'react-data-grid/lib/styles.css'
|
||||
import '@/styles/globals.css'
|
||||
import 'config/typography.css'
|
||||
|
||||
import type { Metadata, Viewport } from 'next'
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const ClassLabel = React.forwardRef<HTMLSpanElement, { children: React.ReactNode
|
||||
return (
|
||||
<span
|
||||
ref={ref}
|
||||
className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground"
|
||||
className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground"
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function CodeBlockWrapper({
|
||||
</CollapsibleContent>
|
||||
<div
|
||||
className={cn(
|
||||
'absolute flex items-center justify-center bg-gradient-to-b from-zinc-700/30 to-zinc-950/90 p-2',
|
||||
'absolute flex items-center justify-center bg-linear-to-b from-zinc-700/30 to-zinc-950/90 p-2',
|
||||
isOpened ? 'inset-x-0 bottom-0 h-12' : 'inset-0'
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -51,7 +51,7 @@ export function CodeFragment({
|
||||
return (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Code fragment{' '}
|
||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
{name}
|
||||
</code>{' '}
|
||||
not found in registry.
|
||||
@@ -94,10 +94,10 @@ export function CodeFragment({
|
||||
)}
|
||||
>
|
||||
{showGrid && (
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
|
||||
)}
|
||||
{showDottedGrid && (
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
)}
|
||||
<div className="z-10 relative">{ComponentPreview}</div>
|
||||
</div>
|
||||
|
||||
@@ -70,7 +70,7 @@ const Colors = ({
|
||||
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 text-center">
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground text-center">
|
||||
{copiedIndex === i ? 'Copied!' : x}
|
||||
</span>
|
||||
</GridItem>
|
||||
|
||||
@@ -56,7 +56,7 @@ export function CommandMenu({ ...props }: DialogProps) {
|
||||
<Button
|
||||
type="outline"
|
||||
className={cn(
|
||||
`lg:flex hidden relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-foreground-muted shadow-none sm:pr-12 md:w-40 lg:w-64 hover:border-foreground-muted hover:bg-surface-100 hover:text-foreground-lighter
|
||||
`lg:flex hidden relative h-8 w-full justify-start rounded-lg bg-background text-sm font-normal text-foreground-muted shadow-none sm:pr-12 md:w-40 lg:w-64 hover:border-foreground-muted hover:bg-surface-100 hover:text-foreground-lighter
|
||||
`
|
||||
)}
|
||||
onClick={() => setOpen(true)}
|
||||
@@ -64,7 +64,7 @@ export function CommandMenu({ ...props }: DialogProps) {
|
||||
>
|
||||
<span className="hidden lg:inline-flex">Search Design System...</span>
|
||||
<span className="inline-flex lg:hidden">Search...</span>
|
||||
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-surface-200 px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex text-foreground-light">
|
||||
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded-sm border bg-surface-200 px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex text-foreground-light">
|
||||
<span className="text-sm">⌘</span>K
|
||||
</kbd>
|
||||
</Button>
|
||||
|
||||
@@ -55,7 +55,7 @@ export function ComponentPreview({
|
||||
return (
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Component{' '}
|
||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
{name}
|
||||
</code>{' '}
|
||||
not found in registry.
|
||||
@@ -99,10 +99,10 @@ export function ComponentPreview({
|
||||
)}
|
||||
>
|
||||
{showGrid && (
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
|
||||
)}
|
||||
{showDottedGrid && (
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
)}
|
||||
<div className="z-10 relative">{ComponentPreview}</div>
|
||||
{/* <div className="preview-grid-background"></div> */}
|
||||
@@ -144,10 +144,10 @@ export function ComponentPreview({
|
||||
})}
|
||||
>
|
||||
{showGrid && (
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-[size:24px_24px]"></div>
|
||||
<div className="pointer-events-none absolute h-full w-full bg-[linear-gradient(to_right,hsla(var(--foreground-default)/0.02)_1px,transparent_1px),linear-gradient(to_bottom,#80808012_1px,transparent_1px)] bg-size-[24px_24px]"></div>
|
||||
)}
|
||||
{showDottedGrid && (
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] [background-size:16px_16px] [mask-image:radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
<div className="z-0 pointer-events-none absolute h-full w-full bg-[radial-gradient(hsla(var(--foreground-default)/0.02)_1px,transparent_1px)] bg-size-[16px_16px] mask-[radial-gradient(ellipse_50%_50%_at_50%_50%,#000_70%,transparent_100%)]"></div>
|
||||
)}
|
||||
<div className="z-10 relative">{ComponentPreview}</div>
|
||||
</div>
|
||||
@@ -164,12 +164,12 @@ export function ComponentPreview({
|
||||
px-4 py-4
|
||||
border border-r
|
||||
group
|
||||
data-[state=closed]:rounded-bl-md data-[state=closed]:rounded-br-md
|
||||
data-closed:rounded-bl-md data-closed:rounded-br-md
|
||||
|
||||
`}
|
||||
>
|
||||
<ChevronRight
|
||||
className="transition-all group-data-[state=open]:rotate-90 text-foreground-lighter"
|
||||
className="transition-all group-data-open:rotate-90 text-foreground-lighter"
|
||||
size={14}
|
||||
/>
|
||||
View code
|
||||
|
||||
@@ -47,8 +47,8 @@ const GridItem = forwardRef<HTMLDivElement, React.HTMLProps<HTMLDivElement>>(
|
||||
transition
|
||||
group-hover:border
|
||||
group-hover:border-foreground-muted
|
||||
group-data-[state=open]:border
|
||||
group-data-[state=open]:border-foreground-muted
|
||||
group-data-open:border
|
||||
group-data-open:border-foreground-muted
|
||||
"
|
||||
></div>
|
||||
{children}
|
||||
|
||||
@@ -18,11 +18,8 @@ function Icons() {
|
||||
<DropdownMenu key={i} modal={false}>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<GridItem>
|
||||
<icon.component
|
||||
size={21}
|
||||
className="group-data-[state=open]:scale-125 transition-all"
|
||||
/>
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-[state=open]:text-foreground">
|
||||
<icon.component size={21} className="group-data-open:scale-125 transition-all" />
|
||||
<span className="bg-surface-100 rounded-full border px-2 font-mono text-xs text-foreground-lighter group-data-open:text-foreground">
|
||||
{icon.name}
|
||||
</span>
|
||||
</GridItem>
|
||||
|
||||
@@ -92,10 +92,7 @@ const components = {
|
||||
/>
|
||||
),
|
||||
p: ({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => (
|
||||
<p
|
||||
className={cn('leading-7 [&:not(:first-child)]:mt-6 text-foreground-light', className)}
|
||||
{...props}
|
||||
/>
|
||||
<p className={cn('leading-7 not-first:mt-6 text-foreground-light', className)} {...props} />
|
||||
),
|
||||
ul: ({ className, ...props }: React.HTMLAttributes<HTMLUListElement>) => (
|
||||
<ul className={cn('my-6 ml-6 list-disc', className)} {...props} />
|
||||
@@ -127,7 +124,7 @@ const components = {
|
||||
th: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
|
||||
<th
|
||||
className={cn(
|
||||
'border px-4 py-2 text-left font-normal [&[align=center]]:text-center [&[align=right]]:text-right',
|
||||
'border px-4 py-2 text-left font-normal [[align=center]]:text-center [[align=right]]:text-right',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -136,7 +133,7 @@ const components = {
|
||||
td: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
|
||||
<td
|
||||
className={cn(
|
||||
'border text-foreground-light px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right',
|
||||
'border text-foreground-light px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -199,7 +196,7 @@ const components = {
|
||||
code: ({ className, ...props }: React.HTMLAttributes<HTMLElement>) => (
|
||||
<code
|
||||
className={cn(
|
||||
'relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm',
|
||||
'relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -261,7 +258,7 @@ const components = {
|
||||
LinkedCard: ({ className, ...props }: React.ComponentProps<typeof Link>) => (
|
||||
<Link
|
||||
className={cn(
|
||||
'flex w-full flex-col items-center rounded-xl border bg-card p-6 text-card-foreground shadow transition-colors hover:bg-muted/50 sm:p-10',
|
||||
'flex w-full flex-col items-center rounded-xl border bg-card p-6 text-card-foreground shadow-sm transition-colors hover:bg-muted/50 sm:p-10',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -33,7 +33,7 @@ const ThemeSwitcherDropdown = () => {
|
||||
return null
|
||||
}
|
||||
|
||||
const iconClasses = 'text-foreground-lighter group-data-[state=open]:text-foreground'
|
||||
const iconClasses = 'text-foreground-lighter group-data-open:text-foreground'
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -13,7 +13,7 @@ export const TopNavigation = () => {
|
||||
const { toggle } = useMobileSidebar()
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 w-full bg-studio/95 backdrop-blur supports-[backdrop-filter]:bg-studio/60 border-b border-l border-r">
|
||||
<header className="sticky top-0 z-50 w-full bg-studio/95 backdrop-blur-sm supports-backdrop-filter:bg-studio/60 border-b border-l border-r">
|
||||
<nav className="py-3 w-full flex">
|
||||
<div className="max-w-site w-full flex flex-row items-center gap-6 mx-auto md:px-6 px-4 justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
@@ -417,7 +417,7 @@ const chartData = [
|
||||
#### Tailwind
|
||||
|
||||
```tsx
|
||||
<LabelList className="fill-[--color-desktop]" />
|
||||
<LabelList className="fill-(--color-desktop)" />
|
||||
```
|
||||
|
||||
## Tooltip
|
||||
|
||||
@@ -108,47 +108,47 @@ See the [Form](/docs/forms) documentation for building forms with the `Field` co
|
||||
|
||||
### Input
|
||||
|
||||
<ComponentPreview name="field-input" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-input" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Textarea
|
||||
|
||||
<ComponentPreview name="field-textarea" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-textarea" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Select
|
||||
|
||||
<ComponentPreview name="field-select" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-select" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Slider
|
||||
|
||||
<ComponentPreview name="field-slider" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-slider" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Fieldset
|
||||
|
||||
<ComponentPreview name="field-fieldset" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-fieldset" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Checkbox
|
||||
|
||||
<ComponentPreview name="field-checkbox" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-checkbox" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Radio
|
||||
|
||||
<ComponentPreview name="field-radio" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-radio" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Switch
|
||||
|
||||
<ComponentPreview name="field-switch" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-switch" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Choice Card
|
||||
|
||||
Wrap `Field` components inside `FieldLabel` to create selectable field groups. This works with `RadioItem`, `Checkbox` and `Switch` components.
|
||||
|
||||
<ComponentPreview name="field-choice-card" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-choice-card" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
### Field Group
|
||||
|
||||
Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
|
||||
|
||||
<ComponentPreview name="field-group" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview name="field-group" className="mb-4! [&_.preview]:p-6" />
|
||||
|
||||
## Responsive Layout
|
||||
|
||||
@@ -158,7 +158,7 @@ Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
|
||||
|
||||
<ComponentPreview
|
||||
name="field-responsive"
|
||||
className="!mb-4 [&_.preview]:h-[650px] [&_.preview]:p-6 [&_.preview]:md:h-[500px] [&_.preview]:md:p-10"
|
||||
className="mb-4! [&_.preview]:h-[650px] [&_.preview]:p-6 [&_.preview]:md:h-[500px] [&_.preview]:md:p-10"
|
||||
/>
|
||||
|
||||
## Validation and Errors
|
||||
|
||||
@@ -241,7 +241,7 @@ That's it. You now have a fully accessible form that is type-safe with client-si
|
||||
|
||||
<ComponentPreview
|
||||
name="input-form"
|
||||
className="[&_[role=tablist]]:hidden [&>div>div:first-child]:hidden"
|
||||
className="**:[[role=tablist]]:hidden [&>div>div:first-child]:hidden"
|
||||
/>
|
||||
|
||||
</Steps>
|
||||
|
||||
@@ -571,7 +571,7 @@ The following example adds a `<DropdownMenu>` to the `SidebarHeader`.
|
||||
<ChevronDown className="ml-auto" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-[--radix-popper-anchor-width]">
|
||||
<DropdownMenuContent className="w-(--radix-popper-anchor-width)">
|
||||
<DropdownMenuItem>
|
||||
<span>Acme Inc</span>
|
||||
</DropdownMenuItem>
|
||||
@@ -622,7 +622,7 @@ export function AppSidebar() {
|
||||
<ChevronUp className="ml-auto" />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent side="top" className="w-[--radix-popper-anchor-width]">
|
||||
<DropdownMenuContent side="top" className="w-(--radix-popper-anchor-width)">
|
||||
<DropdownMenuItem>
|
||||
<span>Account</span>
|
||||
</DropdownMenuItem>
|
||||
@@ -724,7 +724,7 @@ export function AppSidebar() {
|
||||
<SidebarGroupLabel asChild>
|
||||
<CollapsibleTrigger>
|
||||
Help
|
||||
<ChevronDown className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180" />
|
||||
<ChevronDown className="ml-auto transition-transform group-data-open/collapsible:rotate-180" />
|
||||
</CollapsibleTrigger>
|
||||
</SidebarGroupLabel>
|
||||
<CollapsibleContent>
|
||||
|
||||
@@ -6,7 +6,7 @@ source:
|
||||
shadcn: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="typography-demo" className="[&>div.min-h-[350px]]:p-6" peekCode wide />
|
||||
<ComponentPreview name="typography-demo" peekCode wide />
|
||||
|
||||
## h1
|
||||
|
||||
|
||||
@@ -53,12 +53,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shikijs/compat": "^1.1.7",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@types/lodash.template": "4.5.0",
|
||||
"@types/react": "catalog:",
|
||||
"@types/react-dom": "catalog:",
|
||||
"concurrently": "^8.2.2",
|
||||
"config": "workspace:^",
|
||||
"config": "workspace:*",
|
||||
"mdast-util-toc": "^6.1.1",
|
||||
"postcss": "catalog:",
|
||||
"rimraf": "^4.1.3",
|
||||
|
||||
@@ -71,7 +71,7 @@ export default function ChartComposedMetrics() {
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
@@ -89,7 +89,7 @@ export default function ChartComposedMetrics() {
|
||||
</ChartHeader>
|
||||
<ChartContent
|
||||
className="p-0"
|
||||
loadingState={<Skeleton className="w-full h-[6rem] rounded-none mt-4" />}
|
||||
loadingState={<Skeleton className="w-full h-24 rounded-none mt-4" />}
|
||||
>
|
||||
<ChartSparkline data={data} dataKey="value" />
|
||||
</ChartContent>
|
||||
|
||||
@@ -46,7 +46,7 @@ export default function AssistantChatCommands() {
|
||||
/>
|
||||
</AssistantCommandsPopover>
|
||||
<p className="text-xs mt-3 text-foreground-lighter">
|
||||
Press <span className="bg-surface-300 px-[3px] py-[2px] border rounded">/</span> to open
|
||||
Press <span className="bg-surface-300 px-[3px] py-[2px] border rounded-sm">/</span> to open
|
||||
commands
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -35,11 +35,11 @@ export default function Component() {
|
||||
{ name: 'Desktop', value: 186, fill: 'hsl(var(--chart-1))' },
|
||||
{ name: 'Mobile', value: 80, fill: 'hsl(var(--chart-2))' },
|
||||
]}
|
||||
className="w-[8rem]"
|
||||
className="w-32"
|
||||
/>
|
||||
</div>
|
||||
<div className="items-end">
|
||||
<div className="absolute left-[122px] top-[0px] z-10 text-sm font-medium">Name</div>
|
||||
<div className="absolute left-[122px] top-0 z-10 text-sm font-medium">Name</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="35"
|
||||
@@ -68,25 +68,25 @@ export default function Component() {
|
||||
{ name: 'Firefox', value: 1000, fill: 'hsl(var(--chart-4))' },
|
||||
]}
|
||||
indicator="dashed"
|
||||
className="w-[8rem]"
|
||||
className="w-32"
|
||||
/>
|
||||
</div>
|
||||
<div className="!hidden md:!flex">
|
||||
<div className="hidden! md:flex!">
|
||||
<TooltipDemo
|
||||
label="Page Views"
|
||||
payload={[{ name: 'Desktop', value: 12486, fill: 'hsl(var(--chart-3))' }]}
|
||||
className="w-[9rem]"
|
||||
className="w-36"
|
||||
indicator="line"
|
||||
/>
|
||||
</div>
|
||||
<div className="!items-start !justify-start">
|
||||
<div className="items-start! justify-start!">
|
||||
<div className="absolute left-[50px] top-[60px] z-10 text-sm font-medium">Indicator</div>
|
||||
<TooltipDemo
|
||||
label="Browser"
|
||||
hideLabel
|
||||
payload={[{ name: 'Chrome', value: 1286, fill: 'hsl(var(--chart-1))' }]}
|
||||
indicator="dot"
|
||||
className="w-[8rem]"
|
||||
className="w-32"
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -144,7 +144,7 @@ function TooltipDemo({
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl transition-all ease-in-out hover:-translate-y-0.5',
|
||||
'grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl transition-all ease-in-out hover:-translate-y-0.5',
|
||||
className
|
||||
)}
|
||||
>
|
||||
@@ -165,7 +165,7 @@ function TooltipDemo({
|
||||
{!hideIndicator && (
|
||||
<div
|
||||
className={cn(
|
||||
'shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]',
|
||||
'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',
|
||||
{
|
||||
'h-2.5 w-2.5': indicator === 'dot',
|
||||
'w-1': indicator === 'line',
|
||||
|
||||
@@ -6,35 +6,35 @@ import { ExampleLabel } from '@/components/example-label'
|
||||
export default function Demo() {
|
||||
return (
|
||||
<div className="bg-studio w-full h-[320px] flex flex-col items-center border border-dashed rounded-md overflow-hidden">
|
||||
<div className="bg-surface-200 border h-12 w-full rounded-t-md flex justify-center gap-3 items-center shadow">
|
||||
<div className="bg-surface-200 border h-12 w-full rounded-t-md flex justify-center gap-3 items-center shadow-sm">
|
||||
<div className="flex gap-3">
|
||||
<ExampleLabel>grid header</ExampleLabel>
|
||||
<ClassLabel>bg-surface-200</ClassLabel>
|
||||
<ClassLabel>border</ClassLabel>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
|
||||
<div className="flex gap-3">
|
||||
<ExampleLabel>content row</ExampleLabel>
|
||||
<ClassLabel>bg-200</ClassLabel>
|
||||
<ClassLabel>border-secondary</ClassLabel>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
|
||||
<div className="flex gap-3">
|
||||
<ExampleLabel>content row</ExampleLabel>
|
||||
<ClassLabel>bg-200</ClassLabel>
|
||||
<ClassLabel>border-secondary</ClassLabel>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
|
||||
<div className="flex gap-3">
|
||||
<ExampleLabel>content row</ExampleLabel>
|
||||
<ClassLabel>bg-200</ClassLabel>
|
||||
<ClassLabel>border-secondary</ClassLabel>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow">
|
||||
<div className="bg-200 border-b border-r border-l border-secondary h-14 w-full flex justify-center gap-3 items-center shadow-sm">
|
||||
<div className="flex gap-3">
|
||||
<ExampleLabel>content row</ExampleLabel>
|
||||
<ClassLabel>bg-200</ClassLabel>
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function CommandDialogDemo() {
|
||||
<>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Press{' '}
|
||||
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
|
||||
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded-sm border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100">
|
||||
<span className="text-xs">⌘</span>J
|
||||
</kbd>
|
||||
</p>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { useState } from 'react'
|
||||
import DataGrid, { Column, useRowSelection } from 'react-data-grid'
|
||||
|
||||
import 'react-data-grid/lib/styles.css'
|
||||
|
||||
import { Checkbox, cn } from 'ui'
|
||||
|
||||
type User = {
|
||||
@@ -153,7 +150,7 @@ export default function DataGridDemo() {
|
||||
return cn(
|
||||
'bg-surface-75',
|
||||
isSelected && 'bg-surface-200',
|
||||
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none',
|
||||
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-hidden [&>.rdg-cell]:shadow-none',
|
||||
'[&>.rdg-cell]:border-secondary [&>.rdg-cell:not(:last-child)]:border-r',
|
||||
!isLastRow && '[&>.rdg-cell]:border-b',
|
||||
'[&>.rdg-cell:nth-child(2)>div]:ml-8'
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { Users } from 'lucide-react'
|
||||
import DataGrid, { Column } from 'react-data-grid'
|
||||
|
||||
import 'react-data-grid/lib/styles.css'
|
||||
|
||||
import { cn } from 'ui'
|
||||
|
||||
/**
|
||||
@@ -33,7 +30,7 @@ export default function DataGridEmptyState() {
|
||||
rowClass={() => {
|
||||
return cn(
|
||||
'bg-surface-200 cursor-pointer',
|
||||
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-none [&>.rdg-cell]:shadow-none',
|
||||
'[&>.rdg-cell]:border-box [&>.rdg-cell]:outline-hidden [&>.rdg-cell]:shadow-none',
|
||||
'[&>.rdg-cell:first-child>div]:ml-8'
|
||||
)
|
||||
}}
|
||||
|
||||
@@ -42,16 +42,16 @@ export function FieldHear() {
|
||||
</FieldDescription>
|
||||
<FieldGroup className="flex flex-row flex-wrap gap-2 [--radius:9999rem]">
|
||||
{options.map((option) => (
|
||||
<FieldLabel htmlFor={option.value} key={option.value} className="!w-fit">
|
||||
<FieldLabel htmlFor={option.value} key={option.value} className="w-fit!">
|
||||
<Field
|
||||
orientation="horizontal"
|
||||
className="gap-1.5 overflow-hidden !px-3 !py-1.5 transition-all duration-100 ease-linear group-has-data-[state=checked]/field-label:!px-2"
|
||||
className="gap-1.5 overflow-hidden px-3! py-1.5! transition-all duration-100 ease-linear group-has-data-checked/field-label:px-2!"
|
||||
>
|
||||
<Checkbox
|
||||
value={option.value}
|
||||
id={option.value}
|
||||
defaultChecked={option.value === 'social-media'}
|
||||
className="-ml-6 -translate-x-1 rounded-full transition-all duration-100 ease-linear data-[state=checked]:ml-0 data-[state=checked]:translate-x-0"
|
||||
className="-ml-6 -translate-x-1 rounded-full transition-all duration-100 ease-linear data-checked:ml-0 data-checked:translate-x-0"
|
||||
/>
|
||||
<FieldTitle>{option.label}</FieldTitle>
|
||||
</Field>
|
||||
|
||||
@@ -439,7 +439,7 @@ export default function FormPatternsPageLayout() {
|
||||
{uploadedFiles.map((file, idx) => (
|
||||
<div
|
||||
key={`${file.name}-${idx}`}
|
||||
className="flex items-center justify-between gap-2 p-2 bg rounded border"
|
||||
className="flex items-center justify-between gap-2 p-2 bg rounded-sm border"
|
||||
>
|
||||
<span className="text-sm text-foreground-light truncate flex-1">
|
||||
{file.name}
|
||||
|
||||
@@ -424,7 +424,7 @@ export default function FormPatternsSidePanel() {
|
||||
{uploadedFiles.map((file, idx) => (
|
||||
<div
|
||||
key={`${file.name}-${idx}`}
|
||||
className="flex items-center justify-between gap-2 p-2 bg rounded border"
|
||||
className="flex items-center justify-between gap-2 p-2 bg rounded-sm border"
|
||||
>
|
||||
<span className="text-sm text-foreground-light truncate flex-1">
|
||||
{file.name}
|
||||
@@ -607,7 +607,7 @@ export default function FormPatternsSidePanel() {
|
||||
badgeLimit="wrap"
|
||||
showIcon={false}
|
||||
deletableBadge
|
||||
className="w-full !min-w-lg"
|
||||
className="w-full min-w-lg!"
|
||||
/>
|
||||
<MultiSelectorContent>
|
||||
<MultiSelectorList>
|
||||
|
||||
@@ -55,7 +55,7 @@ export default function InnerSideMenuEmpty() {
|
||||
<Heart className="text-light" size={13} />
|
||||
</div>
|
||||
<Pointer
|
||||
className="absolute -right-[6px] -bottom-2 text-lighter"
|
||||
className="absolute right-[-6px] -bottom-2 text-lighter"
|
||||
strokeWidth={1.5}
|
||||
size={16}
|
||||
/>
|
||||
|
||||
@@ -65,7 +65,7 @@ export default function NavigationMenuDemo() {
|
||||
<li className="row-span-3">
|
||||
<NavigationMenuLink asChild>
|
||||
<a
|
||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b border from-background-surface-100/20 to-background-surface-100 p-6 no-underline outline-none focus:shadow-md"
|
||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-linear-to-b border from-background-surface-100/20 to-background-surface-100 p-6 no-underline outline-hidden focus:shadow-md"
|
||||
href="/"
|
||||
>
|
||||
{/* <Icons.logo className="h-6 w-6" /> */}
|
||||
@@ -125,7 +125,7 @@ const ListItem = React.forwardRef<React.ElementRef<'a'>, React.ComponentPropsWit
|
||||
<a
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-surface-100/50 hover:text-foreground focus:bg-surface-100/50 focus:text-foreground',
|
||||
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-surface-100/50 hover:text-foreground focus:bg-surface-100/50 focus:text-foreground',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -66,7 +66,7 @@ export default function NavigationMenuDemo() {
|
||||
<li className="row-span-3">
|
||||
<NavigationMenuLink asChild>
|
||||
<a
|
||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
|
||||
className="flex h-full w-full select-none flex-col justify-end rounded-md bg-linear-to-b from-muted/50 to-muted p-6 no-underline outline-hidden focus:shadow-md"
|
||||
href="/"
|
||||
>
|
||||
{/* <Icons.logo className="h-6 w-6" /> */}
|
||||
@@ -170,7 +170,7 @@ const ListItem = React.forwardRef<React.ElementRef<'a'>, React.ComponentPropsWit
|
||||
<a
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-none transition-colors hover:bg-surface-100 hover:text-accent-foreground focus:bg-surface-100 focus:text-accent-foreground',
|
||||
'block select-none space-y-1 rounded-md p-3 leading-none no-underline outline-hidden transition-colors hover:bg-surface-100 hover:text-accent-foreground focus:bg-surface-100 focus:text-accent-foreground',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function ScrollAreaHorizontalDemo() {
|
||||
<Image
|
||||
src={artwork.art}
|
||||
alt={`Photo by ${artwork.artist}`}
|
||||
className="aspect-[3/4] h-fit w-fit object-cover"
|
||||
className="aspect-3/4 h-fit w-fit object-cover"
|
||||
width={300}
|
||||
height={400}
|
||||
/>
|
||||
|
||||
@@ -149,7 +149,7 @@ const TocComponent = () => {
|
||||
<h3 className="inline-flex items-center gap-1.5 font-mono text-xs uppercase text-foreground pl-[calc(1.5rem+6px)]">
|
||||
On this page
|
||||
</h3>
|
||||
<TOCScrollArea className="-ml-[2px]">
|
||||
<TOCScrollArea className="ml-[-2px]">
|
||||
<TOCItems items={toc} />
|
||||
</TOCScrollArea>
|
||||
</Toc>
|
||||
|
||||
@@ -149,7 +149,7 @@ const TocComponent = () => {
|
||||
<h3 className="inline-flex items-center gap-1.5 font-mono text-xs uppercase text-foreground pl-[calc(1.5rem+6px)]">
|
||||
On this page
|
||||
</h3>
|
||||
<TOCScrollArea className="-ml-[2px]">
|
||||
<TOCScrollArea className="ml-[-2px]">
|
||||
<TOCItems items={toc} />
|
||||
</TOCScrollArea>
|
||||
</Toc>
|
||||
|
||||
@@ -4,7 +4,7 @@ export default function TypographyDemo() {
|
||||
<h1 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
|
||||
The Joke Tax Chronicles
|
||||
</h1>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
Once upon a time, in a far-off land, there was a very lazy king who spent all day lounging
|
||||
on his throne. One day, his advisors came to him with a problem: the kingdom was running out
|
||||
of money.
|
||||
@@ -12,7 +12,7 @@ export default function TypographyDemo() {
|
||||
<h2 className="mt-10 scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0">
|
||||
The King's Plan
|
||||
</h2>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The king thought long and hard, and finally came up with{' '}
|
||||
<a href="#" className="font-medium text-primary underline underline-offset-4">
|
||||
a brilliant plan
|
||||
@@ -24,7 +24,7 @@ export default function TypographyDemo() {
|
||||
that they should pay for the privilege."
|
||||
</blockquote>
|
||||
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">The Joke Tax</h3>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The king's subjects were not amused. They grumbled and complained, but the king was
|
||||
firm:
|
||||
</p>
|
||||
@@ -33,7 +33,7 @@ export default function TypographyDemo() {
|
||||
<li>2nd level of jokes: 10 gold coins</li>
|
||||
<li>3rd level of one-liners : 20 gold coins</li>
|
||||
</ul>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
As a result, people stopped telling jokes, and the kingdom fell into a gloom. But there was
|
||||
one person who refused to let the king's foolishness get him down: a court jester named
|
||||
Jokester.
|
||||
@@ -41,12 +41,12 @@ export default function TypographyDemo() {
|
||||
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||
Jokester's Revolt
|
||||
</h3>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
Jokester began sneaking into the castle in the middle of the night and leaving jokes all
|
||||
over the place: under the king's pillow, in his soup, even in the royal toilet. The
|
||||
king was furious, but he couldn't seem to stop Jokester.
|
||||
</p>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
And then, one day, the people of the kingdom discovered that the jokes left by Jokester were
|
||||
so funny that they couldn't help but laugh. And once they started laughing, they
|
||||
couldn't stop.
|
||||
@@ -54,7 +54,7 @@ export default function TypographyDemo() {
|
||||
<h3 className="mt-8 scroll-m-20 text-2xl font-semibold tracking-tight">
|
||||
The People's Rebellion
|
||||
</h3>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The people of the kingdom, feeling uplifted by the laughter, started to tell jokes and puns
|
||||
again, and soon the entire kingdom was in on the joke.
|
||||
</p>
|
||||
@@ -62,48 +62,48 @@ export default function TypographyDemo() {
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
|
||||
King's Treasury
|
||||
</th>
|
||||
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
|
||||
People's happiness
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Empty
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Overflowing
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Modest
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Satisfied
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Full
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Ecstatic
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The king, seeing how much happier his subjects were, realized the error of his ways and
|
||||
repealed the joke tax. Jokester was declared a hero, and the kingdom lived happily ever
|
||||
after.
|
||||
</p>
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The moral of the story is: never underestimate the power of a good laugh and always be
|
||||
careful of bad ideas.
|
||||
</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default function TypographyInlineCode() {
|
||||
return (
|
||||
<code className="relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
|
||||
<code className="relative rounded-sm bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold">
|
||||
@radix-ui/react-alert-dialog
|
||||
</code>
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export default function TypographyP() {
|
||||
return (
|
||||
<p className="leading-7 [&:not(:first-child)]:mt-6">
|
||||
<p className="leading-7 not-first:mt-6">
|
||||
The king, seeing how much happier his subjects were, realized the error of his ways and
|
||||
repealed the joke tax.
|
||||
</p>
|
||||
|
||||
@@ -4,36 +4,36 @@ export default function TypographyTable() {
|
||||
<table className="w-full">
|
||||
<thead>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
|
||||
King's Treasury
|
||||
</th>
|
||||
<th className="border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<th className="border px-4 py-2 text-left font-bold [[align=center]]:text-center [[align=right]]:text-right">
|
||||
People's happiness
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Empty
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Overflowing
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Modest
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Satisfied
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="m-0 border-t p-0 even:bg-muted">
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Full
|
||||
</td>
|
||||
<td className="border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right">
|
||||
<td className="border px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right">
|
||||
Ecstatic
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@import './../../../packages/ui/build/css/source/global.css';
|
||||
@import './../../../packages/ui/build/css/themes/dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/classic-dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/light.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@config '../tailwind.config.js';
|
||||
|
||||
@import 'config/typography.css';
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
@@ -68,3 +70,7 @@
|
||||
@apply px-4;
|
||||
}
|
||||
}
|
||||
|
||||
.rdg-cell {
|
||||
padding-inline: 0.5rem;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@reference './globals.css';
|
||||
|
||||
/* [data-theme="light"] {
|
||||
display: block;
|
||||
} */
|
||||
|
||||
@@ -5,12 +5,12 @@ module.exports = config({
|
||||
'./app/**/*.{js,ts,jsx,tsx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx}',
|
||||
'./registry/**/*.{js,ts,jsx,tsx}',
|
||||
'./content/**/*.mdx',
|
||||
// purge styles from grid library
|
||||
//
|
||||
'./../../packages/ui/src/**/*.{tsx,ts,js}',
|
||||
'./../../packages/ui-patterns/src/**/*.{tsx,ts,js}',
|
||||
],
|
||||
plugins: [require('@tailwindcss/container-queries')],
|
||||
theme: {
|
||||
extend: {
|
||||
maxWidth: {
|
||||
|
||||
@@ -29,5 +29,5 @@ export default function GraphiQLPage() {
|
||||
notFound()
|
||||
}
|
||||
|
||||
return <LazyGraphiQL className="!h-[calc(100vh-var(--header-height))]" />
|
||||
return <LazyGraphiQL className="h-[calc(100vh-var(--header-height))]!" />
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ const DatabaseAdvisorDocs = async () => {
|
||||
.
|
||||
</Admonition>
|
||||
) : (
|
||||
<Tabs listClassNames="flex flex-wrap gap-2 [&>button]:!m-0" queryGroup="lint">
|
||||
<Tabs listClassNames="flex flex-wrap gap-2 [&>button]:m-0!" queryGroup="lint">
|
||||
{lints.map((lint) => (
|
||||
<TabPanel
|
||||
key={lint.path}
|
||||
|
||||
@@ -156,7 +156,7 @@ function Resources({ schema }: { schema: any }) {
|
||||
<li key={nestedAttribute}>
|
||||
{nestedAttribute}
|
||||
<ul>
|
||||
<li className="*:!m-0">
|
||||
<li className="*:m-0!">
|
||||
<ReactMarkdown>
|
||||
{
|
||||
schema[resource].block.attributes[attribute].nested_type
|
||||
@@ -285,7 +285,7 @@ function DataSources({ schema }: { schema: any }) {
|
||||
<li key={nestedAttribute}>
|
||||
{nestedAttribute}
|
||||
<ul>
|
||||
<li className="*:!m-0">
|
||||
<li className="*:m-0!">
|
||||
<ReactMarkdown>
|
||||
{
|
||||
schema[dataSource].block.attributes[attribute].nested_type
|
||||
|
||||
@@ -26,7 +26,7 @@ export default async function GlobalTroubleshootingPage() {
|
||||
const errors = await getAllTroubleshootingErrors()
|
||||
|
||||
return (
|
||||
<SidebarSkeleton hideSideNav className="w-full max-w-screen-lg mx-auto">
|
||||
<SidebarSkeleton hideSideNav className="w-full max-w-(--breakpoint-lg) mx-auto">
|
||||
<div className="py-8 px-5">
|
||||
<h1 className="text-4xl tracking-tight mb-7">Troubleshooting</h1>
|
||||
<p className="text-lg text-foreground-light">
|
||||
|
||||
@@ -62,18 +62,18 @@ const AuthSmsProviderConfig = () => {
|
||||
>
|
||||
{selectedProvider && (
|
||||
<DialogContent
|
||||
className="!w-[min(90vw,80ch)] !max-w-[min(90vw,80ch)] !max-h-[90dvh] prose overflow-auto"
|
||||
className="w-[min(90vw,80ch)]! max-w-[min(90vw,80ch)]! max-h-[90dvh]! prose overflow-auto"
|
||||
onOpenAutoFocus={(evt) => {
|
||||
evt.preventDefault()
|
||||
headingRef.current?.focus()
|
||||
}}
|
||||
>
|
||||
<DialogHeader className="pb-0 [&>h3]:!m-0 [&>h3>a]:!hidden [&>h3:focus-visible]:outline-none">
|
||||
<DialogHeader className="pb-0 [&>h3]:m-0! [&>h3>a]:hidden! [&>h3:focus-visible]:outline-hidden">
|
||||
<Heading tag="h3" ref={headingRef} tabIndex={-1}>
|
||||
{selectedProvider.name}
|
||||
</Heading>
|
||||
</DialogHeader>
|
||||
<DialogSection className="[&>:first-child]:mt-0">
|
||||
<DialogSection className="*:first:mt-0">
|
||||
{selectedProvider.name.toLowerCase().includes('messagebird') && <MessageBird />}
|
||||
{selectedProvider.name.toLowerCase().includes('twilio') && <Twilio />}
|
||||
{selectedProvider.name.toLowerCase().includes('vonage') && <Vonage />}
|
||||
|
||||
@@ -26,7 +26,7 @@ const BodyContentTypeDropdown = ({ types, onSelect }: IParamProps) => {
|
||||
border
|
||||
hover:border-control
|
||||
hover:bg-overlay-hover
|
||||
border-control px-2 h-[32px] rounded
|
||||
border-control px-2 h-[32px] rounded-sm
|
||||
font-mono
|
||||
flex items-center gap-1
|
||||
text-foreground text-sm group-hover:text-foreground transition
|
||||
|
||||
@@ -26,7 +26,7 @@ const ButtonCard: FC<Props> = ({
|
||||
<Link
|
||||
href={to}
|
||||
className={cn(
|
||||
'h-full block shadow-none bg-surface-100 rounded transition',
|
||||
'h-full block shadow-none bg-surface-100 rounded-sm transition',
|
||||
'border border-transparent hover:border-overlay',
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -154,7 +154,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
>
|
||||
<Button
|
||||
type="outline"
|
||||
rounded
|
||||
rounded-sm
|
||||
className={cn(
|
||||
'px-1 w-7 h-7',
|
||||
'text-foreground-light',
|
||||
@@ -162,7 +162,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
'motion-reduce:[transition-duration:150ms,1ms,300ms]',
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
!isNo && 'hover:text-warning hover:border-warning-500',
|
||||
isNo && `bg-warning text-warning-200 !border-warning disabled:opacity-100`,
|
||||
isNo && `bg-warning text-warning-200 border-warning! disabled:opacity-100`,
|
||||
!showNo && 'opacity-0 invisible'
|
||||
)}
|
||||
onClick={() => handleVote('no')}
|
||||
@@ -173,7 +173,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
</Button>
|
||||
<Button
|
||||
type="outline"
|
||||
rounded
|
||||
rounded-sm
|
||||
className={cn(
|
||||
'px-1 w-7 h-7',
|
||||
'text-foreground-light',
|
||||
@@ -182,7 +182,7 @@ function Feedback({ className }: { className?: string }) {
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
!isYes && 'hover:text-brand-600 hover:border-brand-500',
|
||||
isYes &&
|
||||
'bg-brand text-brand-200 !border-brand disabled:opacity-100 -translate-x-[calc(100%+var(--container-inline-flex-gap,0.5rem))]',
|
||||
'bg-brand text-brand-200 border-brand! disabled:opacity-100 -translate-x-[calc(100%+var(--container-inline-flex-gap,0.5rem))]',
|
||||
!showYes && 'opacity-0 invisible'
|
||||
)}
|
||||
onClick={() => handleVote('yes')}
|
||||
@@ -205,8 +205,8 @@ function Feedback({ className }: { className?: string }) {
|
||||
'[transition-delay:200ms,0ms]',
|
||||
'[transition-timing-function:cubic-bezier(.76,0,.23,1)]',
|
||||
'motion-reduce:[transition-duration:150ms,1ms]',
|
||||
'!ease-out',
|
||||
state.type === StateType.Followup && 'opacity-100 visible -translate-x-0'
|
||||
'ease-out!',
|
||||
state.type === StateType.Followup && 'opacity-100 visible translate-x-0'
|
||||
)}
|
||||
>
|
||||
{state.type === StateType.Followup && (
|
||||
|
||||
@@ -161,7 +161,7 @@ const HomePageCover = (props) => {
|
||||
return (
|
||||
<div className="relative z-10 w-full bg-alternative border-b max-w-none mb-16 md:mb-12 xl:mb-0">
|
||||
<div className="max-w-7xl px-5 mx-auto py-8 sm:pb-16 sm:pt-12 xl:pt-16 flex flex-col xl:flex-row justify-between gap-12 xl:gap-12">
|
||||
<div className="flex flex-col sm:flex-row gap-4 sm:gap-8 items-start sm:items-center w-full max-w-xl xl:max-w-[33rem]">
|
||||
<div className="flex flex-col sm:flex-row gap-4 sm:gap-8 items-start sm:items-center w-full max-w-xl xl:max-w-132">
|
||||
<DocsCoverLogo aria-hidden="true" />
|
||||
<div className="flex flex-col">
|
||||
<h1 className="m-0 mb-3 text-2xl sm:text-3xl text-foreground">
|
||||
|
||||
@@ -30,7 +30,7 @@ const listItem = {
|
||||
}
|
||||
|
||||
const itemClassName =
|
||||
'block py-2 pl-2 pr-3.5 text-sm text-foreground-light hover:bg-surface-200 focus-visible:ring-2 focus-visible:outline-none focus-visible:ring-foreground-lighter focus-visible:rounded'
|
||||
'block py-2 pl-2 pr-3.5 text-sm text-foreground-light hover:bg-surface-200 focus-visible:ring-2 focus-visible:outline-hidden focus-visible:ring-foreground-lighter focus-visible:rounded-sm'
|
||||
|
||||
const AccordionMenuItem = ({ section }: { section: DropdownMenuItem[] }) => {
|
||||
const activeLabel = useActiveMenuLabel(GLOBAL_MENU_ITEMS)
|
||||
@@ -38,7 +38,7 @@ const AccordionMenuItem = ({ section }: { section: DropdownMenuItem[] }) => {
|
||||
return (
|
||||
<m.div
|
||||
variants={listItem}
|
||||
className="border-b border-muted [&>div]:!rounded-none [&_div[data-state=open]>div]:py-1"
|
||||
className="border-b border-muted [&>div]:rounded-none! [&_div[data-state=open]>div]:py-1"
|
||||
key={section[0].label}
|
||||
>
|
||||
{section[0].menuItems ? (
|
||||
@@ -47,7 +47,7 @@ const AccordionMenuItem = ({ section }: { section: DropdownMenuItem[] }) => {
|
||||
id={section[0].label}
|
||||
className={cn(
|
||||
'relative',
|
||||
activeLabel === section[0].label && '!text-foreground',
|
||||
activeLabel === section[0].label && 'text-foreground!',
|
||||
itemClassName
|
||||
)}
|
||||
>
|
||||
@@ -75,7 +75,7 @@ const AccordionMenuItem = ({ section }: { section: DropdownMenuItem[] }) => {
|
||||
) : (
|
||||
<Link
|
||||
href={section[0].href || '#'}
|
||||
className={cn(activeLabel === section[0].label && '!text-foreground', itemClassName)}
|
||||
className={cn(activeLabel === section[0].label && 'text-foreground!', itemClassName)}
|
||||
>
|
||||
{section[0].label}
|
||||
</Link>
|
||||
@@ -126,9 +126,9 @@ const GlobalMobileMenu = ({ open, setOpen }: Props) => {
|
||||
initial="hidden"
|
||||
animate="show"
|
||||
exit="exit"
|
||||
className="bg-overlay fixed overflow-hidden inset-0 z-50 h-screen max-h-screen w-screen supports-[height:100cqh]:h-[100cqh] supports-[height:100svh]:h-[100svh] transform"
|
||||
className="bg-overlay fixed overflow-hidden inset-0 z-50 h-screen max-h-screen w-screen supports-[height:100cqh]:h-[100cqh] supports-[height:100svh]:h-svh transform"
|
||||
>
|
||||
<div className="absolute px-5 h-[var(--header-height)] flex items-center justify-between w-screen left-0 top-0 z-50 bg-overlay before:content[''] before:absolute before:w-full before:h-3 before:inset-0 before:top-full before:bg-gradient-to-b before:from-background-overlay before:to-transparent">
|
||||
<div className="absolute px-5 h-(--header-height) flex items-center justify-between w-screen left-0 top-0 z-50 bg-overlay before:content[''] before:absolute before:w-full before:h-3 before:inset-0 before:top-full before:bg-linear-to-b before:from-background-overlay before:to-transparent">
|
||||
<Link href="/" className="flex items-center gap-2">
|
||||
<Image
|
||||
className="cursor-pointer hidden dark:block"
|
||||
@@ -153,14 +153,14 @@ const GlobalMobileMenu = ({ open, setOpen }: Props) => {
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
type="button"
|
||||
className="inline-flex items-center justify-center focus:ring-brand bg-surface-100 hover:bg-surface-200 focus:outline-none focus:ring-2 focus:ring-inset border border-default bg-surface-100/75 text-foreground-light rounded min-w-[30px] w-[30px] h-[30px]"
|
||||
className="inline-flex items-center justify-center focus:ring-brand bg-surface-100 hover:bg-surface-200 focus:outline-hidden focus:ring-2 focus:ring-inset border border-default bg-surface-100/75 text-foreground-light rounded-sm min-w-[30px] w-[30px] h-[30px]"
|
||||
>
|
||||
<span className="sr-only">Close menu</span>
|
||||
<X />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-h-screen supports-[height:100cqh]:h-[100cqh] supports-[height:100svh]:h-[100svh] overflow-y-auto pt-12 pb-32 px-3">
|
||||
<div className="max-h-screen supports-[height:100cqh]:h-[100cqh] supports-[height:100svh]:h-svh overflow-y-auto pt-12 pb-32 px-3">
|
||||
<Menu />
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 right-0 top-auto w-full bg-alternative flex items-stretch p-4 gap-4">
|
||||
|
||||
@@ -59,7 +59,7 @@ export const useActiveMenuLabel = (menu: typeof GLOBAL_MENU_ITEMS) => {
|
||||
const GlobalNavigationMenu: FC = () => {
|
||||
const activeLabel = useActiveMenuLabel(GLOBAL_MENU_ITEMS)
|
||||
const triggerClassName =
|
||||
'h-[var(--header-height)] p-2 bg-transparent border-0 border-b-2 border-transparent font-normal rounded-none text-foreground-light hover:text-foreground data-[state=open]:!text-foreground data-[radix-collection-item]:focus-visible:ring-2 data-[radix-collection-item]:focus-visible:ring-foreground-lighter data-[radix-collection-item]:focus-visible:text-foreground h-full focus-visible:rounded !shadow-none outline-none transition-all outline-0 focus-visible:outline-4 focus-visible:outline-offset-1 focus-visible:outline-brand-600'
|
||||
'h-(--header-height) p-2 bg-transparent border-0 border-b-2 border-transparent font-normal rounded-none text-foreground-light hover:text-foreground data-open:text-foreground! data-radix-collection-item:focus-visible:ring-2 data-radix-collection-item:focus-visible:ring-foreground-lighter data-radix-collection-item:focus-visible:text-foreground h-full focus-visible:rounded-sm shadow-none! outline-hidden transition-all outline-0 focus-visible:outline-4 focus-visible:outline-offset-1 focus-visible:outline-brand-600'
|
||||
|
||||
return (
|
||||
<div className="flex relative gap-2 justify-start items-end w-full h-full">
|
||||
@@ -68,9 +68,9 @@ const GlobalNavigationMenu: FC = () => {
|
||||
skipDelayDuration={0}
|
||||
className="w-full flex justify-start h-full"
|
||||
renderViewport={false}
|
||||
viewportClassName="mt-0 max-w-screen overflow-hidden border-0 rounded-none mt-1.5 rounded-md !border-x"
|
||||
viewportClassName="mt-0 max-w-screen overflow-hidden border-0 rounded-none mt-1.5 rounded-md border-x!"
|
||||
>
|
||||
<NavigationMenuList className="px-6 space-x-2 h-[var(--header-height)]">
|
||||
<NavigationMenuList className="px-6 space-x-2 h-(--header-height)">
|
||||
{GLOBAL_MENU_ITEMS.filter((section) => section[0].enabled !== false).map(
|
||||
(section, sectionIdx) =>
|
||||
section[0].menuItems ? (
|
||||
@@ -91,7 +91,7 @@ const GlobalNavigationMenu: FC = () => {
|
||||
section[0].label
|
||||
)}
|
||||
</NavigationMenuTrigger>
|
||||
<NavigationMenuContent className="!top-[calc(100%+4px)] min-w-[14rem] max-h-[calc(100vh-4rem)] border-y w-screen md:w-64 overflow-hidden overflow-y-auto rounded-none md:rounded-md md:border border-overlay bg-overlay text-foreground-light shadow-md !duration-0">
|
||||
<NavigationMenuContent className="top-[calc(100%+4px)]! min-w-56 max-h-[calc(100vh-4rem)] border-y w-screen md:w-64 overflow-hidden overflow-y-auto rounded-none md:rounded-md md:border border-overlay bg-overlay text-foreground-light shadow-md duration-0!">
|
||||
<div className="p-3 md:p-1">
|
||||
{section[0].menuItems?.map((menuItem, menuItemIndex) => (
|
||||
<Fragment
|
||||
@@ -170,7 +170,7 @@ export const MenuItem = React.forwardRef<
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'group/menu-item flex items-center gap-2',
|
||||
'w-full flex h-8 items-center text-foreground-light text-sm hover:text-foreground select-none rounded-md p-2 leading-none no-underline !outline-none focus-visible:ring-2 focus-visible:ring-foreground-lighter focus-visible:text-foreground',
|
||||
'w-full flex h-8 items-center text-foreground-light text-sm hover:text-foreground select-none rounded-md p-2 leading-none no-underline outline-hidden! focus-visible:ring-2 focus-visible:ring-foreground-lighter focus-visible:text-foreground',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -112,7 +112,7 @@ const NavigationMenuCliList = ({ currentLevel, setLevel, id }) => {
|
||||
<div className="flex items-center gap-3 my-3">
|
||||
<img
|
||||
src={`${BASE_PATH}` + (menu.icon ?? `/img/icons/menu/${id}.svg`)}
|
||||
className="w-5 rounded"
|
||||
className="w-5 rounded-sm"
|
||||
/>
|
||||
|
||||
<h2 className={['text-foreground ', !menu.title && 'capitalize'].join(' ')}>
|
||||
|
||||
@@ -78,7 +78,7 @@ const FunctionLink = memo(function FunctionLink({
|
||||
{active && !isSubItem && (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className="absolute -left-[13px] top-0 bottom-0 w-[1px] bg-brand-600"
|
||||
className="absolute left-[-13px] top-0 bottom-0 w-px bg-brand-600"
|
||||
></div>
|
||||
)}
|
||||
{isParent && (
|
||||
|
||||
@@ -32,9 +32,9 @@ const TopNavBar: FC = () => {
|
||||
<>
|
||||
<nav
|
||||
aria-label="top bar"
|
||||
className="w-full z-40 flex flex-col border-b backdrop-blur backdrop-filter bg-default/75"
|
||||
className="w-full z-40 flex flex-col border-b backdrop-blur-sm backdrop-filter bg-default/75"
|
||||
>
|
||||
<div className="w-full px-5 lg:pl-10 flex justify-between h-[var(--header-height)] gap-3">
|
||||
<div className="w-full px-5 lg:pl-10 flex justify-between h-(--header-height) gap-3">
|
||||
<div className="hidden lg:flex h-full items-center justify-center gap-2">
|
||||
<HeaderLogo />
|
||||
<GlobalNavigationMenu />
|
||||
@@ -58,7 +58,7 @@ const TopNavBar: FC = () => {
|
||||
title="Menu dropdown button"
|
||||
className={cn(
|
||||
buttonVariants({ type: 'default' }),
|
||||
'flex lg:hidden border-default bg-surface-100/75 text-foreground-light rounded-md min-w-[30px] w-[30px] h-[30px] data-[state=open]:bg-overlay-hover/30'
|
||||
'flex lg:hidden border-default bg-surface-100/75 text-foreground-light rounded-md min-w-[30px] w-[30px] h-[30px] data-open:bg-overlay-hover/30'
|
||||
)}
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
>
|
||||
@@ -100,11 +100,11 @@ const HeaderLogo = memo(() => {
|
||||
href="/"
|
||||
className={cn(
|
||||
buttonVariants({ type: 'default' }),
|
||||
'flex shrink-0 items-center w-fit !bg-transparent !border-none !shadow-none'
|
||||
'flex shrink-0 items-center w-fit bg-transparent! border-none! shadow-none!'
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
className={cn('hidden dark:block !m-0', largeLogo && 'h-[36px]')}
|
||||
className={cn('hidden dark:block m-0!', largeLogo && 'h-[36px]')}
|
||||
src={navigationLogo?.dark ?? '/docs/supabase-dark.svg'}
|
||||
priority={true}
|
||||
loading="eager"
|
||||
@@ -113,7 +113,7 @@ const HeaderLogo = memo(() => {
|
||||
alt="Supabase wordmark"
|
||||
/>
|
||||
<Image
|
||||
className={cn('block dark:hidden !m-0', largeLogo && 'h-[36px]')}
|
||||
className={cn('block dark:hidden m-0!', largeLogo && 'h-[36px]')}
|
||||
src={navigationLogo?.light ?? '/docs/supabase-light.svg'}
|
||||
priority={true}
|
||||
loading="eager"
|
||||
|
||||
@@ -70,7 +70,7 @@ const TopNavDropdown = () => {
|
||||
title="Menu dropdown button"
|
||||
className={cn(
|
||||
buttonVariants({ type: 'default' }),
|
||||
'text-foreground-light border-default w-[30px] min-w-[30px] h-[30px] data-[state=open]:bg-overlay-hover/30 hover:border-strong data-[state=open]:border-stronger hover:!bg-overlay-hover/50 bg-transparent'
|
||||
'text-foreground-light border-default w-[30px] min-w-[30px] h-[30px] data-open:bg-overlay-hover/30 hover:border-strong data-open:border-stronger hover:bg-overlay-hover/50! bg-transparent'
|
||||
)}
|
||||
>
|
||||
<Menu size={18} strokeWidth={1} />
|
||||
|
||||
@@ -56,9 +56,9 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
</Link>
|
||||
{referenceMeta !== undefined && (
|
||||
<div className="my-5 flex items-center space-x-4">
|
||||
<div className="h-10 w-10 rounded bg-surface-100 flex items-center justify-center">
|
||||
<div className="h-10 w-10 rounded-sm bg-surface-100 flex items-center justify-center">
|
||||
<Image
|
||||
className="rounded"
|
||||
className="rounded-sm"
|
||||
width={24}
|
||||
height={24}
|
||||
alt={referenceMeta.name}
|
||||
@@ -77,7 +77,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
<div
|
||||
key={item.name}
|
||||
className={[
|
||||
'py-1.5 px-5 rounded text-sm transition',
|
||||
'py-1.5 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
@@ -116,7 +116,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
<Link href={section.url || '#'} key={section.name}>
|
||||
<div
|
||||
className={[
|
||||
'py-1.5 px-5 rounded text-sm transition',
|
||||
'py-1.5 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
section.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
@@ -154,7 +154,7 @@ const SideBar = ({ menuItems = [] }: { menuItems: any }) => {
|
||||
<div
|
||||
key={item.name}
|
||||
className={[
|
||||
'py-1.5 ml-4 px-5 rounded text-sm transition',
|
||||
'py-1.5 ml-4 px-5 rounded-sm text-sm transition',
|
||||
`${
|
||||
item.url === pathname
|
||||
? 'bg-background text-brand-link'
|
||||
|
||||
@@ -49,7 +49,7 @@ const RevVersionDropdown = ({
|
||||
border
|
||||
hover:border-control
|
||||
hover:bg-overlay-hover
|
||||
border-control px-2 h-[32px] rounded
|
||||
border-control px-2 h-[32px] rounded-sm
|
||||
font-mono
|
||||
flex items-center gap-1 text-foreground-muted text-xs group-hover:text-foreground transition
|
||||
"
|
||||
|
||||
@@ -6,7 +6,7 @@ export function RegionsList() {
|
||||
<ul>
|
||||
{Object.keys(AWS_REGIONS).map((region) => (
|
||||
<li key={region} className="flex flex-col gap-2">
|
||||
<span className="w-fit !mt-0">{AWS_REGIONS[region].displayName}</span>
|
||||
<span className="w-fit mt-0!">{AWS_REGIONS[region].displayName}</span>
|
||||
<code className="w-fit">{AWS_REGIONS[region].code}</code>
|
||||
</li>
|
||||
))}
|
||||
@@ -18,7 +18,7 @@ export function SmartRegionsList() {
|
||||
<ul>
|
||||
{[...SMART_REGION_TO_EXACT_REGION_MAP.entries()].map(([smartRegion, exactRegion]) => (
|
||||
<li key={smartRegion} className="flex flex-col gap-2">
|
||||
<span className="w-fit !mt-0">{smartRegion}</span>
|
||||
<span className="w-fit mt-0!">{smartRegion}</span>
|
||||
<code className="w-fit">{exactRegion}</code>
|
||||
</li>
|
||||
))}
|
||||
|
||||
@@ -77,7 +77,7 @@ const Step = ({ children, title, step }) => {
|
||||
"
|
||||
>
|
||||
<div className="flex items-center gap-6">
|
||||
<div className="border bg-selection border-strong flex w-7 h-7 items-center justify-center rounded text-base text-foreground font-semibold font-mono">
|
||||
<div className="border bg-selection border-strong flex w-7 h-7 items-center justify-center rounded-sm text-base text-foreground font-semibold font-mono">
|
||||
{step}
|
||||
</div>
|
||||
<h3 className="text-foreground text-xl" id={cleanTitleId}>
|
||||
|
||||
@@ -29,7 +29,7 @@ const Table = ({ children, ...props }: TableProps) => {
|
||||
<div className="relative">
|
||||
<span
|
||||
className={cn(
|
||||
'block md:hidden absolute inset-0 left-auto w-5 bg-gradient-to-r from-transparent to-background transition-opacity opacity-100',
|
||||
'block md:hidden absolute inset-0 left-auto w-5 bg-linear-to-r from-transparent to-background transition-opacity opacity-100',
|
||||
!showShadow && 'opacity-0 duration-300'
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -14,7 +14,7 @@ When a JWT is issued by Supabase Auth, the key used to create its [signature](ht
|
||||
|
||||
| System | Type | Description |
|
||||
| ----------------- | ------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes <span className="!whitespace-nowrap">the `anon` and `service_role`</span> keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/storage-from-createsignedurl). **No longer recommended.** Available for backward compatibility. |
|
||||
| Legacy | JWT secret | Initially Supabase was designed to use a single shared secret key to sign all JWTs. This includes <span className="whitespace-nowrap!">the `anon` and `service_role`</span> keys, all user access tokens including some [Storage pre-signed URLs](/docs/reference/javascript/storage-from-createsignedurl). **No longer recommended.** Available for backward compatibility. |
|
||||
| Signing keys | Asymmetric key (RSA, Elliptic Curves) | A JWT signing key based on [public-key cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography) (RSA, Elliptic Curves) that follows industry best practices and significantly improves the security, reliability and performance of your applications. |
|
||||
| Signing keys | Shared secret key | A JWT signing key based on a [shared secret](https://en.wikipedia.org/wiki/HMAC). |
|
||||
|
||||
@@ -101,12 +101,12 @@ Each action on a key is reversible (except permanent deletion).
|
||||
|
||||
| Action | Accepted JWT signatures | Description |
|
||||
| -------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="!whitespace-nowrap">Create a new key</span> | Current key only, new key has not created any JWTs yet. | When you initially create a key, after choosing the signing algorithm or importing a private key you already have, it starts out in the standby state. If using an asymmetric key (RSA, Elliptic Curve) its public key will be available in the discovery endpoint. Supabase Auth does not use this key to create new JWTs. |
|
||||
| <span className="!whitespace-nowrap">Rotate keys</span> | Both keys in the rotation. | Rotation only changes the key used by Supabase Auth to create new JWTs, but the trust relationship with both keys remains. |
|
||||
| <span className="!whitespace-nowrap">Revoke key</span> | <span className="!whitespace-nowrap">Only from the current key.</span> | Once all regularly valid JWTs have expired (or sooner) revoke the previously used key to revoke trust in it. |
|
||||
| <span className="!whitespace-nowrap">Move to standby</span> from revoked | Current and previously revoked key. | If you've made a mistake or need more time to adjust your application, you can move a revoked key to standby. Follow up with a rotation to ensure Auth starts using the originally revoked key again to make new JWTs. |
|
||||
| <span className="!whitespace-nowrap">Move to standby</span> from previously used | Both keys. | This only prepares the key from the last rotation to be used by Auth to make new JWTs with it. |
|
||||
| <span className="!whitespace-nowrap">Delete key</span> | - | Permanently destroys the private key or shared secret of a key, so it will not be possible to re-use or rotate again into it. |
|
||||
| <span className="whitespace-nowrap!">Create a new key</span> | Current key only, new key has not created any JWTs yet. | When you initially create a key, after choosing the signing algorithm or importing a private key you already have, it starts out in the standby state. If using an asymmetric key (RSA, Elliptic Curve) its public key will be available in the discovery endpoint. Supabase Auth does not use this key to create new JWTs. |
|
||||
| <span className="whitespace-nowrap!">Rotate keys</span> | Both keys in the rotation. | Rotation only changes the key used by Supabase Auth to create new JWTs, but the trust relationship with both keys remains. |
|
||||
| <span className="whitespace-nowrap!">Revoke key</span> | <span className="whitespace-nowrap!">Only from the current key.</span> | Once all regularly valid JWTs have expired (or sooner) revoke the previously used key to revoke trust in it. |
|
||||
| <span className="whitespace-nowrap!">Move to standby</span> from revoked | Current and previously revoked key. | If you've made a mistake or need more time to adjust your application, you can move a revoked key to standby. Follow up with a rotation to ensure Auth starts using the originally revoked key again to make new JWTs. |
|
||||
| <span className="whitespace-nowrap!">Move to standby</span> from previously used | Both keys. | This only prepares the key from the last rotation to be used by Auth to make new JWTs with it. |
|
||||
| <span className="whitespace-nowrap!">Delete key</span> | - | Permanently destroys the private key or shared secret of a key, so it will not be possible to re-use or rotate again into it. |
|
||||
|
||||
### Public key discovery and caching
|
||||
|
||||
@@ -135,12 +135,12 @@ Finally this multi-level cache is cleared every 20 minutes, or longer if you hav
|
||||
|
||||
To strike the right balance between performance, security and ease-of-use, JWT signing keys are based on capabilities available in the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API).
|
||||
|
||||
| Algorithm | <span className="!whitespace-nowrap">JWT `alg`</span> | Information |
|
||||
| Algorithm | <span className="whitespace-nowrap!">JWT `alg`</span> | Information |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="!whitespace-nowrap">[NIST P-256 Curve](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)</span><br/>(Asymmetric) | <span className="!whitespace-nowrap">`ES256`</span> | Elliptic Curves are a faster alternative than RSA, while providing comparable security. Especially important for Auth use cases is the fact that signatures using the P-256 curve are significantly shorter than those created by RSA, which reduces data transfer sizes and helps in managing cookie size. Web Crypto and most other cryptography libraries and runtimes support this curve. |
|
||||
| <span className="!whitespace-nowrap">[RSA 2048](https://en.wikipedia.org/wiki/RSA_cryptosystem)</span><br/>(Asymmetric) | <span className="!whitespace-nowrap">`RS256`</span> | RSA is the oldest and most widely supported public-key cryptosystem in use. While being easy to code by hand, it can be significantly slower than elliptic curves in certain aspects. We recommend using the P-256 elliptic curve instead. |
|
||||
| <span className="!whitespace-nowrap">[Ed25519 Curve](https://en.wikipedia.org/wiki/EdDSA#Ed25519)</span><br/>(Asymmetric) | <span className="!whitespace-nowrap">`EdDSA`</span> | Coming soon. This algorithm is based on a different elliptic curve cryptosystem developed in the open, unlike the P-256 curve. Web Crypto or other crypto libraries may not support it in all runtimes, making it difficult to work with. |
|
||||
| <span className="!whitespace-nowrap">[HMAC with shared secret](https://en.wikipedia.org/wiki/HMAC)</span><br/>(Symmetric) | <span className="!whitespace-nowrap">`HS256`</span> | **Not recommended for production applications.** A shared secret uses a message authentication code to verify the authenticity of a JSON Web Token. This requires that both the creator of the JWT (Auth) and the system verifying the JWT know the secret. As there is no public key counterpart, revoking this key might require deploying changes to your app's backend infrastructure. |
|
||||
| <span className="whitespace-nowrap!">[NIST P-256 Curve](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography)</span><br/>(Asymmetric) | <span className="whitespace-nowrap!">`ES256`</span> | Elliptic Curves are a faster alternative than RSA, while providing comparable security. Especially important for Auth use cases is the fact that signatures using the P-256 curve are significantly shorter than those created by RSA, which reduces data transfer sizes and helps in managing cookie size. Web Crypto and most other cryptography libraries and runtimes support this curve. |
|
||||
| <span className="whitespace-nowrap!">[RSA 2048](https://en.wikipedia.org/wiki/RSA_cryptosystem)</span><br/>(Asymmetric) | <span className="whitespace-nowrap!">`RS256`</span> | RSA is the oldest and most widely supported public-key cryptosystem in use. While being easy to code by hand, it can be significantly slower than elliptic curves in certain aspects. We recommend using the P-256 elliptic curve instead. |
|
||||
| <span className="whitespace-nowrap!">[Ed25519 Curve](https://en.wikipedia.org/wiki/EdDSA#Ed25519)</span><br/>(Asymmetric) | <span className="whitespace-nowrap!">`EdDSA`</span> | Coming soon. This algorithm is based on a different elliptic curve cryptosystem developed in the open, unlike the P-256 curve. Web Crypto or other crypto libraries may not support it in all runtimes, making it difficult to work with. |
|
||||
| <span className="whitespace-nowrap!">[HMAC with shared secret](https://en.wikipedia.org/wiki/HMAC)</span><br/>(Symmetric) | <span className="whitespace-nowrap!">`HS256`</span> | **Not recommended for production applications.** A shared secret uses a message authentication code to verify the authenticity of a JSON Web Token. This requires that both the creator of the JWT (Auth) and the system verifying the JWT know the secret. As there is no public key counterpart, revoking this key might require deploying changes to your app's backend infrastructure. |
|
||||
|
||||
<Admonition type="caution">
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ OrioleDB addresses Postgres's scalability limitations by removing bottlenecks in
|
||||
<Image
|
||||
alt="TPC-C (warehouses = 500)"
|
||||
src="/docs/img/database/orioledb-tpc-c-500-warehouse.png"
|
||||
className="max-w-[550px] !mx-auto border rounded-md"
|
||||
className="max-w-[550px] mx-auto! border rounded-md"
|
||||
width={1000}
|
||||
height={609}
|
||||
|
||||
@@ -54,7 +54,7 @@ To get started with OrioleDB you need to [create a new Supabase project](/dashbo
|
||||
light: '/docs/img/database/orioledb-creating-project--light.png',
|
||||
dark: '/docs/img/database/orioledb-creating-project.png',
|
||||
}}
|
||||
className="max-w-[550px] !mx-auto border rounded-md"
|
||||
className="max-w-[550px] mx-auto! border rounded-md"
|
||||
|
||||
width={1376}
|
||||
height={2034}
|
||||
|
||||
@@ -12,7 +12,7 @@ Table partitioning is a technique that allows you to divide a large table into s
|
||||
light: '/docs/img/database/partitions-light.png',
|
||||
dark: '/docs/img/database/partitions-dark.png',
|
||||
}}
|
||||
className="max-h-[400px] !mx-auto"
|
||||
className="max-h-[400px] mx-auto!"
|
||||
width={1600}
|
||||
height={1075}
|
||||
/>
|
||||
|
||||
@@ -119,7 +119,7 @@ We highly recommend turning on a 'required check' for the Supabase integration.
|
||||
|
||||
<Image
|
||||
|
||||
className="max-w-[700px] !mx-auto"
|
||||
className="max-w-[700px] mx-auto!"
|
||||
alt='Check the "Require status checks to pass before merging" option.'
|
||||
caption='Check the "Require status checks to pass before merging" option.'
|
||||
src="/docs/img/guides/platform/branching/github-required-check.jpg?v=1"
|
||||
|
||||
@@ -27,10 +27,10 @@ There are 4 types of API keys that you can use with Supabase:
|
||||
|
||||
| Type | Format | Privileges | Availability | Use |
|
||||
| ---------------------------------------------------------- | ---------------------------------------------------------------- | ---------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Publishable key | <span className="!whitespace-nowrap">`sb_publishable_...`</span> | Low | Platform | Safe to expose online: web page, mobile or desktop app, GitHub actions, CLIs, source code. |
|
||||
| Secret keys | <span className="!whitespace-nowrap">`sb_secret_...`</span> | Elevated | Platform | **Only use in backend components of your app:** servers, already secured APIs (admin panels), [Edge Functions](/docs/guides/functions), microservices, etc. They provide _full access_ to your project's data, bypassing [Row Level Security](/docs/guides/database/postgres/row-level-security). |
|
||||
| <span className="!whitespace-nowrap">`anon`</span> | JWT (long lived) | Low | <span className="!whitespace-nowrap">Platform, CLI</span> | Legacy version of publishable keys. |
|
||||
| <span className="!whitespace-nowrap">`service_role`</span> | JWT (long lived) | Elevated | <span className="!whitespace-nowrap">Platform, CLI</span> | Legacy version of secret keys. |
|
||||
| Publishable key | <span className="whitespace-nowrap!">`sb_publishable_...`</span> | Low | Platform | Safe to expose online: web page, mobile or desktop app, GitHub actions, CLIs, source code. |
|
||||
| Secret keys | <span className="whitespace-nowrap!">`sb_secret_...`</span> | Elevated | Platform | **Only use in backend components of your app:** servers, already secured APIs (admin panels), [Edge Functions](/docs/guides/functions), microservices, etc. They provide _full access_ to your project's data, bypassing [Row Level Security](/docs/guides/database/postgres/row-level-security). |
|
||||
| <span className="whitespace-nowrap!">`anon`</span> | JWT (long lived) | Low | <span className="whitespace-nowrap!">Platform, CLI</span> | Legacy version of publishable keys. |
|
||||
| <span className="whitespace-nowrap!">`service_role`</span> | JWT (long lived) | Elevated | <span className="whitespace-nowrap!">Platform, CLI</span> | Legacy version of secret keys. |
|
||||
|
||||
<Admonition type="caution" title="Changes to API keys">
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ You can freely transfer projects between different organizations. Head to your [
|
||||
light: '/docs/img/guides/platform/project-transfer-overview--light.png',
|
||||
dark: '/docs/img/guides/platform/project-transfer-overview.png',
|
||||
}}
|
||||
className="max-w-[600px] !mx-auto border rounded-md"
|
||||
className="max-w-[600px] mx-auto! border rounded-md"
|
||||
|
||||
width={677}
|
||||
height={224}
|
||||
@@ -24,7 +24,7 @@ height={224}
|
||||
light: '/docs/img/guides/platform/project-transfer-modal--light.png',
|
||||
dark: '/docs/img/guides/platform/project-transfer-modal.png',
|
||||
}}
|
||||
className="max-w-[600px] !mx-auto"
|
||||
className="max-w-[600px] mx-auto!"
|
||||
|
||||
width={773}
|
||||
height={581}
|
||||
|
||||
@@ -13,7 +13,7 @@ Read Replicas are additional databases kept in sync with your Primary database.
|
||||
<Image
|
||||
alt="Map view of all project databases."
|
||||
src="/docs/img/guides/platform/read-replicas/map-view.png?v=1"
|
||||
containerClassName="max-w-[700px] !mx-auto"
|
||||
containerClassName="max-w-[700px] mx-auto!"
|
||||
|
||||
width={2000}
|
||||
height={830}
|
||||
|
||||
@@ -75,7 +75,7 @@ Queue names can only be lowercase and hyphens and underscores are permitted.
|
||||
light: '/docs/img/queues-quickstart-create.png',
|
||||
}}
|
||||
|
||||
className="max-w-lg !mx-auto"
|
||||
className="max-w-lg mx-auto!"
|
||||
|
||||
width={1456}
|
||||
height={1420}
|
||||
@@ -214,13 +214,13 @@ const QueuesTest: React.FC = () => {
|
||||
<h2 className="text-2xl font-bold mb-4">Queue Test Component</h2>
|
||||
<button
|
||||
onClick={sendToQueue}
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 mr-4"
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded-sm hover:bg-blue-600 mr-4"
|
||||
>
|
||||
Add Message
|
||||
</button>
|
||||
<button
|
||||
onClick={popFromQueue}
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
|
||||
className="bg-blue-500 text-white px-4 py-2 rounded-sm hover:bg-blue-600"
|
||||
>
|
||||
Pop Message
|
||||
</button>
|
||||
|
||||
@@ -30,7 +30,7 @@ Pick the workflow that best matches your tooling. Cards link to Supabase-authore
|
||||
<img
|
||||
src="/docs/img/guides/platform/supabase-grafana-prometheus.png"
|
||||
alt="Supabase Grafana dashboard showcasing database metrics"
|
||||
className="mt-8 rounded-lg border border-foreground/10 shadow-sm"
|
||||
className="mt-8 rounded-lg border border-foreground/10 shadow-xs"
|
||||
/>
|
||||
|
||||
## Additional resources
|
||||
|
||||
@@ -47,7 +47,7 @@ This dashboard includes 200+ charts grouped by CPU, IO, connections, replication
|
||||
<img
|
||||
src="/docs/img/guides/platform/supabase-grafana-prometheus.png"
|
||||
alt="Supabase Grafana dashboard showcasing database metrics"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-sm"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-xs"
|
||||
/>
|
||||
|
||||
## 4. Configure alerts (optional)
|
||||
|
||||
@@ -66,7 +66,7 @@ You now have over 200 production-ready panels covering CPU, IO, WAL, replication
|
||||
<img
|
||||
src="/docs/img/guides/platform/supabase-grafana-prometheus.png"
|
||||
alt="Supabase Grafana dashboard showcasing database metrics"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-sm"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-xs"
|
||||
/>
|
||||
|
||||
## 4. Configure alerting
|
||||
|
||||
@@ -54,7 +54,7 @@ No matter which collector you use, you need to hit the Metrics API once per minu
|
||||
<img
|
||||
src="/docs/img/guides/platform/supabase-grafana-prometheus.png"
|
||||
alt="Supabase Grafana dashboard showcasing database metrics"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-sm"
|
||||
className="mt-6 rounded-lg border border-foreground/10 shadow-xs"
|
||||
/>
|
||||
|
||||
## 4. Alerts and automation
|
||||
|
||||
@@ -5,7 +5,7 @@ hideTitle: true
|
||||
---
|
||||
|
||||
<div className="flex items-start gap-6 not-prose" id="introduction">
|
||||
<img src="/docs/img/icons/menu/reference-analytics.svg" className="w-8 h-8 rounded" />
|
||||
<img src="/docs/img/icons/menu/reference-analytics.svg" className="w-8 h-8 rounded-sm" />
|
||||
<div className="flex flex-col gap-2">
|
||||
<h1 className="text-3xl text-foreground m-0">Self-Hosting Functions</h1>
|
||||
</div>
|
||||
|
||||
@@ -42,7 +42,7 @@ function MultipleSources({ children, sources }: PropsWithChildren<{ sources: (st
|
||||
{children}
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<button className="block -mt-4 mb-4 ml-auto text-foreground-lighter text-sm focus-visible:outline-none focus-visible:underline">
|
||||
<button className="block -mt-4 mb-4 ml-auto text-foreground-lighter text-sm focus-visible:outline-hidden focus-visible:underline">
|
||||
View sources
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
@@ -8,7 +8,7 @@ export function NamedCodeBlock({ name, children }: PropsWithChildren<{ name: str
|
||||
<h6
|
||||
className={cn(
|
||||
'w-fit flex items-center text-center',
|
||||
'shadow-sm rounded border border-stronger bg-selection',
|
||||
'shadow-xs rounded-sm border border-stronger bg-selection',
|
||||
'px-2.5 py-1',
|
||||
'text-xs text-foreground'
|
||||
)}
|
||||
|
||||
@@ -171,8 +171,8 @@ async function CliCommandSection({ link, section }: CliCommandSectionProps) {
|
||||
|
||||
return (
|
||||
<RefSubLayout.Section columns="double" link={link} {...section}>
|
||||
<StickyHeader title={command.title} className="col-[1_/_-1]" monoFont={true} />
|
||||
<div className="w-full min-w-0 prose break-words mb-8">
|
||||
<StickyHeader title={command.title} className="col-span-full" monoFont={true} />
|
||||
<div className="w-full min-w-0 prose wrap-break-word mb-8">
|
||||
{command.description && <ReactMarkdown>{command.description}</ReactMarkdown>}
|
||||
{command.usage && (
|
||||
<div className="mb-8">
|
||||
@@ -220,7 +220,7 @@ async function CliCommandSection({ link, section }: CliCommandSectionProps) {
|
||||
)}
|
||||
</div>
|
||||
{flag.description && (
|
||||
<div className="prose break-words text-sm">
|
||||
<div className="prose wrap-break-word text-sm">
|
||||
<ReactMarkdown>{flag.description}</ReactMarkdown>
|
||||
</div>
|
||||
)}
|
||||
@@ -320,7 +320,7 @@ async function ApiEndpointSection({ link, section, servicePath }: ApiEndpointSec
|
||||
)}
|
||||
</>
|
||||
}
|
||||
className="col-[1_/_-1]"
|
||||
className="col-span-full"
|
||||
/>
|
||||
<div className="flex flex-col gap-12">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -342,7 +342,7 @@ async function ApiEndpointSection({ link, section, servicePath }: ApiEndpointSec
|
||||
</code>
|
||||
</div>
|
||||
{endpointDetails.description && (
|
||||
<div className="prose break-words mb-8">
|
||||
<div className="prose wrap-break-word mb-8">
|
||||
<ReactMarkdown>{endpointDetails.description}</ReactMarkdown>
|
||||
</div>
|
||||
)}
|
||||
@@ -473,11 +473,11 @@ async function FunctionSection({
|
||||
|
||||
return (
|
||||
<RefSubLayout.Section columns="double" link={link} {...section}>
|
||||
<StickyHeader {...section} className="col-[1_/_-1]" />
|
||||
<StickyHeader {...section} className="col-span-full" />
|
||||
|
||||
{/* Display method signature below title */}
|
||||
{types && 'params' in types && formatMethodSignature(types) && (
|
||||
<div className="col-[1_/_-1] -mt-2 mb-4">
|
||||
<div className="col-span-full -mt-2 mb-4">
|
||||
<code className="text-sm text-foreground-muted font-mono">
|
||||
{formatMethodSignature(types)}
|
||||
</code>
|
||||
@@ -485,7 +485,7 @@ async function FunctionSection({
|
||||
)}
|
||||
|
||||
<div className="overflow-hidden flex flex-col gap-8">
|
||||
<div className="prose break-words text-sm">
|
||||
<div className="prose wrap-break-word text-sm">
|
||||
<MDXRemoteRefs source={fullDescription} />
|
||||
</div>
|
||||
<FnParameterDetails
|
||||
|
||||
@@ -40,7 +40,7 @@ function Section({ slug, link, columns = 'single', children }: SectionProps) {
|
||||
link={link}
|
||||
className={cn(
|
||||
'grid grid-cols-[1fr] gap-x-16 gap-y-8',
|
||||
singleColumn ? 'max-w-3xl' : '@4xl/article:grid-cols-[1fr,1fr]'
|
||||
singleColumn ? 'max-w-3xl' : '@4xl/article:grid-cols-[1fr_1fr]'
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
@@ -99,7 +99,7 @@ export function StickyHeader({ title, monoFont = false, className }: StickyHeade
|
||||
<h2
|
||||
tabIndex={-1} // For programmatic focus on auto-scroll to section
|
||||
className={cn(
|
||||
'sticky top-0 z-[1]',
|
||||
'sticky top-0 z-1',
|
||||
'w-full',
|
||||
// Enough padding to cover the background when stuck to the top,
|
||||
// then readjust with negative margin to prevent it looking too
|
||||
@@ -107,10 +107,10 @@ export function StickyHeader({ title, monoFont = false, className }: StickyHeade
|
||||
'pt-[calc(var(--header-height)+1rem)] -mt-[calc(var(--header-height)+1rem-2px)]',
|
||||
// Same for bottom
|
||||
'pb-8 -mb-3',
|
||||
'bg-gradient-to-b from-background from-85% to-transparent to-100%',
|
||||
'bg-linear-to-b from-background from-85% to-transparent to-100%',
|
||||
'text-2xl font-medium text-foreground',
|
||||
'scroll-mt-[calc(var(--header-height)+1rem)]',
|
||||
'focus:outline-none',
|
||||
'focus:outline-hidden',
|
||||
monoFont && 'font-mono',
|
||||
className
|
||||
)}
|
||||
@@ -127,19 +127,16 @@ export function CollapsibleDetails({ title, content }: { title: string; content:
|
||||
className={cn(
|
||||
'group',
|
||||
'w-full h-8',
|
||||
'border bg-surface-100 rounded',
|
||||
'border bg-surface-100 rounded-sm',
|
||||
'px-5',
|
||||
'flex items-center gap-3',
|
||||
'text-xs text-foreground-light',
|
||||
'data-[state=open]:bg-surface-200',
|
||||
'data-[state=open]:rounded-b-none data-[state=open]:border-b-0',
|
||||
'data-open:bg-surface-200',
|
||||
'data-open:rounded-b-none data-open:border-b-0',
|
||||
'transition-safe-all ease-out'
|
||||
)}
|
||||
>
|
||||
<ChevronRight
|
||||
size={12}
|
||||
className="group-data-[state=open]:rotate-90 transition-transform"
|
||||
/>
|
||||
<ChevronRight size={12} className="group-data-open:rotate-90 transition-transform" />
|
||||
{title}
|
||||
</CollapsibleTrigger_Shadcn_>
|
||||
<CollapsibleContent_Shadcn_
|
||||
@@ -294,8 +291,8 @@ function TypeSubDetails({
|
||||
'flex items-center gap-2',
|
||||
'text-left text-sm text-foreground-light',
|
||||
'hover:bg-surface-100',
|
||||
'data-[state=open]:w-full',
|
||||
'data-[state=open]:rounded-b-none data-[state=open]:rounded-tl-lg data-[state=open]:rounded-tr-lg',
|
||||
'data-open:w-full',
|
||||
'data-open:rounded-b-none data-open:rounded-tl-lg data-open:rounded-tr-lg',
|
||||
'transition [transition-property:width,background-color]',
|
||||
className
|
||||
)}
|
||||
@@ -304,7 +301,7 @@ function TypeSubDetails({
|
||||
size={14}
|
||||
className={cn(
|
||||
'text-foreground-muted',
|
||||
'group-data-[state=closed]:rotate-45',
|
||||
'group-data-closed:rotate-45',
|
||||
'transition-transform'
|
||||
)}
|
||||
/>
|
||||
@@ -352,7 +349,7 @@ export function ApiSchemaParamDetails({ param }: { param: IApiEndPoint['paramete
|
||||
)}
|
||||
</div>
|
||||
{param.description && (
|
||||
<div className="prose break-words text-sm">
|
||||
<div className="prose wrap-break-word text-sm">
|
||||
<ReactMarkdown>{param.description}</ReactMarkdown>
|
||||
</div>
|
||||
)}
|
||||
@@ -513,8 +510,8 @@ export function ApiSchemaParamSubdetails({
|
||||
'flex items-center gap-2',
|
||||
'text-left text-sm text-foreground-light',
|
||||
'hover:bg-surface-100',
|
||||
'data-[state=open]:w-full',
|
||||
'data-[state=open]:rounded-b-none data-[state=open]:rounded-tl-lg data-[state=open]:rounded-tr-lg',
|
||||
'data-open:w-full',
|
||||
'data-open:rounded-b-none data-open:rounded-tl-lg data-open:rounded-tr-lg',
|
||||
'transition [transition-property:width,background-color]',
|
||||
className
|
||||
)}
|
||||
@@ -523,7 +520,7 @@ export function ApiSchemaParamSubdetails({
|
||||
size={14}
|
||||
className={cn(
|
||||
'text-foreground-muted',
|
||||
'group-data-[state=closed]:rotate-45',
|
||||
'group-data-closed:rotate-45',
|
||||
'transition-transform'
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -16,7 +16,7 @@ export default async function TroubleshootingPage({ entry }: { entry: ITroublesh
|
||||
return (
|
||||
<SidebarSkeleton
|
||||
hideSideNav
|
||||
className="@container/troubleshooting-entry-layout w-full max-w-screen-lg mx-auto lg:py-8 lg:px-5"
|
||||
className="@container/troubleshooting-entry-layout w-full max-w-(--breakpoint-lg) mx-auto lg:py-8 lg:px-5"
|
||||
>
|
||||
<div className="px-5 py-8 lg:px-0 lg:py-0">
|
||||
<Breadcrumbs minLength={1} forceDisplayOnMobile />
|
||||
@@ -28,7 +28,7 @@ export default async function TroubleshootingPage({ entry }: { entry: ITroublesh
|
||||
</p>
|
||||
)}
|
||||
<hr className="my-7" aria-hidden />
|
||||
<div className="grid gap-10 @3xl/troubleshooting-entry-layout:grid-cols-[1fr,250px]">
|
||||
<div className="grid gap-10 @3xl/troubleshooting-entry-layout:grid-cols-[1fr_250px]">
|
||||
<div className="min-w-0">
|
||||
<MDXRemoteBase source={entry.content} />
|
||||
</div>
|
||||
|
||||
@@ -138,13 +138,10 @@ function TroubleshootingFilterMobileCollapsed(props: TroubleshootingFilterProps)
|
||||
<CollapsibleTrigger className="group w-full pb-6 text-foreground-light">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<span>Filters</span>
|
||||
<ChevronDown
|
||||
size={16}
|
||||
className="group-data-[state=open]:rotate-180 transition-transform"
|
||||
/>
|
||||
<ChevronDown size={16} className="group-data-open:rotate-180 transition-transform" />
|
||||
</div>
|
||||
{numberFiltersApplied > 0 && (
|
||||
<div className="group-data-[state=open]:hidden text-sm text-left">
|
||||
<div className="group-data-open:hidden text-sm text-left">
|
||||
{numberFiltersApplied} filter{numberFiltersApplied > 1 ? 's' : ''} applied
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -102,7 +102,7 @@ export function TroubleshootingHeader({
|
||||
errors: ITroubleshootingMetadata['errors']
|
||||
}) {
|
||||
return (
|
||||
<div className="lg:sticky lg:top-[var(--header-height)] lg:z-10 bg-background">
|
||||
<div className="lg:sticky lg:top-(--header-height) lg:z-10 bg-background">
|
||||
<div className="pt-8 pb-6 px-5">
|
||||
<h1 className="text-4xl tracking-tight mb-7">{title}</h1>
|
||||
<p className="text-lg text-foreground-light">{description}</p>
|
||||
|
||||
@@ -48,7 +48,7 @@ export function AnnotatedSpan({
|
||||
style={token.htmlStyle}
|
||||
className={cn(
|
||||
isTouchDevice &&
|
||||
'underline underline-offset-4 decoration-dashed [text-decoration-color:rgba(from_currentColor_r_g_b_/_0.5)]'
|
||||
'underline underline-offset-4 decoration-dashed decoration-[rgba(from_currentColor_r_g_b/0.5)]'
|
||||
)}
|
||||
>
|
||||
{token.content}
|
||||
|
||||
@@ -31,7 +31,7 @@ interface PopUpProps extends PropsWithChildren {
|
||||
|
||||
const buttonClassName = cn(
|
||||
'relative px-1 py-0 -my-px',
|
||||
'rounded bg-surface-200 border border-dashed',
|
||||
'rounded-sm bg-surface-200 border border-dashed',
|
||||
'transition-colors hover:border-strong group/inline-popup'
|
||||
)
|
||||
|
||||
@@ -83,7 +83,7 @@ const InfoTooltip = ({
|
||||
{children}
|
||||
<InfoIcon
|
||||
aria-hidden={true}
|
||||
className="absolute p-[1px] bg-background rounded-full -left-1.5 -top-1.5 w-3 h-3 text-foreground-lighter group-hover/inline-popup:text-foreground-light transition-colors"
|
||||
className="absolute p-px bg-background rounded-full -left-1.5 -top-1.5 w-3 h-3 text-foreground-lighter group-hover/inline-popup:text-foreground-light transition-colors"
|
||||
/>
|
||||
</span>
|
||||
</TooltipTrigger>
|
||||
@@ -108,7 +108,7 @@ const InfoTooltip = ({
|
||||
<ErrorBoundary FallbackComponent={() => <CommandEmpty_Shadcn_ />}>
|
||||
<SheetHeader className="flex items-center justify-between gap-2 px-0 py-2 mb-2 max-w-full">
|
||||
<div className="flex items-center gap-2 max-w-[90%]">
|
||||
<InfoIcon className="p-[1px] min-w-4 min-h-4 text-foreground-lighter" />
|
||||
<InfoIcon className="p-px min-w-4 min-h-4 text-foreground-lighter" />
|
||||
<p className="italic text-foreground-light truncate">{children}</p>
|
||||
</div>
|
||||
<Button type="text" onClick={() => setMobileSheetOpen(false)} className="px-1">
|
||||
|
||||
@@ -265,7 +265,7 @@ const MobileMenuBackdrop = memo(function MobileMenuBackdrop() {
|
||||
'left-0',
|
||||
'right-0',
|
||||
'z-10',
|
||||
'backdrop-blur-sm backdrop-filter bg-alternative/90',
|
||||
'backdrop-blur-xs backdrop-filter bg-alternative/90',
|
||||
mobileMenuOpen ? 'absolute h-full w-full top-0 left-0' : 'hidden h-0',
|
||||
// always hide on desktop
|
||||
'lg:hidden'
|
||||
@@ -305,7 +305,7 @@ const NavContainer = memo(function NavContainer({ children }: PropsWithChildren)
|
||||
'fixed lg:relative z-40 lg:z-auto',
|
||||
mobileMenuOpen ? 'w-[75%] sm:w-[50%] md:w-[33%] left-0' : 'w-0 -left-full',
|
||||
'lg:w-[420px] !lg:left-0',
|
||||
'lg:top-[var(--header-height)] lg:sticky',
|
||||
'lg:top-(--header-height) lg:sticky',
|
||||
'h-screen lg:h-[calc(100vh-var(--header-height))]',
|
||||
// desktop override any left styles
|
||||
'lg:left-0',
|
||||
@@ -318,13 +318,13 @@ const NavContainer = memo(function NavContainer({ children }: PropsWithChildren)
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
'top-0 lg:top-[var(--header-height)]',
|
||||
'top-0 lg:top-(--header-height)',
|
||||
'h-full',
|
||||
'relative lg:sticky',
|
||||
'w-full lg:w-auto',
|
||||
'h-fit lg:h-screen overflow-y-scroll lg:overflow-auto',
|
||||
'[overscroll-behavior:contain]',
|
||||
'backdrop-blur backdrop-filter bg-background',
|
||||
'overscroll-contain',
|
||||
'backdrop-blur-sm backdrop-filter bg-background',
|
||||
'flex flex-col grow'
|
||||
)}
|
||||
>
|
||||
@@ -332,7 +332,7 @@ const NavContainer = memo(function NavContainer({ children }: PropsWithChildren)
|
||||
Main menu
|
||||
</span>
|
||||
<div className="top-0 sticky h-0 z-10">
|
||||
<div className="bg-gradient-to-b from-background to-transparent h-4 w-full"></div>
|
||||
<div className="bg-linear-to-b from-background to-transparent h-4 w-full"></div>
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
@@ -411,7 +411,7 @@ function SidebarSkeleton({
|
||||
className={cn(
|
||||
'sticky',
|
||||
'transition-all top-0 z-10',
|
||||
'backdrop-blur backdrop-filter bg-background'
|
||||
'backdrop-blur-sm backdrop-filter bg-background'
|
||||
)}
|
||||
>
|
||||
{hideSideNav ? null : menuName ? (
|
||||
|
||||
@@ -111,7 +111,7 @@ const StickyHeader: FC<StickyHeader> = ({ icon, ...props }) => {
|
||||
return (
|
||||
<div className={['flex items-center gap-3 not-prose', icon && 'mb-8'].join(' ')}>
|
||||
{icon && (
|
||||
<div className="w-8 h-8 bg-brand-300 rounded flex items-center justify-center">
|
||||
<div className="w-8 h-8 bg-brand-300 rounded-sm flex items-center justify-center">
|
||||
<Image width={16} height={16} alt={icon} src={`${icon}.svg`} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
"@octokit/plugin-retry": "^8.1.0",
|
||||
"@sentry/nextjs": "catalog:",
|
||||
"@supabase/supabase-js": "catalog:",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"@tanstack/react-query": "^5.13.4",
|
||||
"acorn": "^8.11.3",
|
||||
"acorn-typescript": "^1.4.13",
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
|
||||
@import './../../../packages/ui/build/css/source/global.css';
|
||||
@import './../../../packages/ui/build/css/themes/dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/light.css';
|
||||
|
||||
@config '../tailwind.config.cjs';
|
||||
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: hsl(var(--border-default, currentColor));
|
||||
}
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'custom-font';
|
||||
src:
|
||||
@@ -123,7 +133,7 @@ pre[class*='language-'] {
|
||||
|
||||
.method-list-item-validation {
|
||||
code {
|
||||
@apply text-xs bg-control rounded;
|
||||
@apply text-xs bg-control rounded-sm;
|
||||
padding: 1px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@reference './main.css';
|
||||
/**
|
||||
* okaidia theme for JavaScript, CSS and HTML
|
||||
* Loosely based on Monokai textmate theme by http://www.monokai.nl/
|
||||
|
||||
@@ -22,6 +22,5 @@ module.exports = config({
|
||||
},
|
||||
})
|
||||
},
|
||||
require('@tailwindcss/container-queries'),
|
||||
],
|
||||
})
|
||||
|
||||
@@ -61,7 +61,7 @@ export function Command({ name, highlight, framework = 'react' }: CommandCopyPro
|
||||
<div className="w-full group relative rounded-lg bg-surface-200 dark:bg-surface-100 px-4 py-2 overflow-hidden">
|
||||
{highlight && (
|
||||
<motion.div
|
||||
className="absolute inset-0 bg-gradient-to-l from-transparent via-[#bbb] dark:via-white to-transparent opacity-10 z-0"
|
||||
className="absolute inset-0 bg-linear-to-l from-transparent via-[#bbb] dark:via-white to-transparent opacity-10 z-0"
|
||||
initial={{ x: '100%' }}
|
||||
animate={{ x: '-100%' }}
|
||||
transition={{
|
||||
|
||||
@@ -18,7 +18,7 @@ interface CourseHeroProps {
|
||||
|
||||
export function CourseHero({ title, subtitle, description, instructors }: CourseHeroProps) {
|
||||
return (
|
||||
<div className="relative w-full mx-auto py-16 sm:py-24 border-b bg-[radial-gradient(circle_at_top,_rgba(16,185,129,0.14),_transparent_55%),radial-gradient(circle_at_bottom,_rgba(34,197,94,0.10),_transparent_50%)]">
|
||||
<div className="relative w-full mx-auto py-16 sm:py-24 border-b bg-[radial-gradient(circle_at_top,rgba(16,185,129,0.14),transparent_55%),radial-gradient(circle_at_bottom,rgba(34,197,94,0.10),transparent_50%)]">
|
||||
{/* Chapter label */}
|
||||
<div className="flex items-center justify-center mb-6">
|
||||
<span className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-muted border border-border text-xs font-medium text-muted-foreground uppercase tracking-wider">
|
||||
@@ -27,7 +27,7 @@ export function CourseHero({ title, subtitle, description, instructors }: Course
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6 text-balance text-center bg-gradient-to-br from-foreground to-foreground/70 bg-clip-text text-transparent">
|
||||
<h1 className="text-4xl sm:text-5xl lg:text-6xl font-bold mb-6 text-balance text-center bg-linear-to-br from-foreground to-foreground/70 bg-clip-text text-transparent">
|
||||
{title}
|
||||
</h1>
|
||||
|
||||
|
||||
@@ -57,10 +57,7 @@ const components = {
|
||||
/>
|
||||
),
|
||||
p: ({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) => (
|
||||
<p
|
||||
className={cn('leading-7 [&:not(:first-child)]:mt-6 text-foreground-light', className)}
|
||||
{...props}
|
||||
/>
|
||||
<p className={cn('leading-7 not-first:mt-6 text-foreground-light', className)} {...props} />
|
||||
),
|
||||
ul: ({ className, ...props }: React.HTMLAttributes<HTMLUListElement>) => (
|
||||
<ul className={cn('my-6 ml-6 list-disc text-foreground-light', className)} {...props} />
|
||||
@@ -92,7 +89,7 @@ const components = {
|
||||
th: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
|
||||
<th
|
||||
className={cn(
|
||||
'border px-4 py-2 text-left font-normal [&[align=center]]:text-center [&[align=right]]:text-right',
|
||||
'border px-4 py-2 text-left font-normal [[align=center]]:text-center [[align=right]]:text-right',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -101,7 +98,7 @@ const components = {
|
||||
td: ({ className, ...props }: React.HTMLAttributes<HTMLTableCellElement>) => (
|
||||
<td
|
||||
className={cn(
|
||||
'border text-foreground-light px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right',
|
||||
'border text-foreground-light px-4 py-2 text-left [[align=center]]:text-center [[align=right]]:text-right',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -49,7 +49,7 @@ const ThemeSwitcherDropdown = () => {
|
||||
)
|
||||
}
|
||||
|
||||
const iconClasses = 'text-foreground-light group-data-[state=open]:text-foreground'
|
||||
const iconClasses = 'text-foreground-light group-data-open:text-foreground'
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -100,19 +100,19 @@ export function WhatWillILearn() {
|
||||
</div>
|
||||
<div className="col-span-6">
|
||||
<ul className="grid gap-6 text-foreground-light ">
|
||||
<li className="grid grid-cols-[auto,1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<li className="grid grid-cols-[auto_1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-md bg-brand-500/10 text-brand-500">
|
||||
<Timer className="h-5 w-5" />
|
||||
</span>
|
||||
<span>Real-time room monitoring that tracks live occupancy, sensor readings</span>
|
||||
</li>
|
||||
<li className="grid grid-cols-[auto,1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<li className="grid grid-cols-[auto_1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-md bg-brand-500/10 text-brand-500">
|
||||
<CalendarRange className="h-5 w-5" />
|
||||
</span>
|
||||
<span>Booking management with live status filters, calendar integrations.</span>
|
||||
</li>
|
||||
<li className="grid grid-cols-[auto,1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<li className="grid grid-cols-[auto_1fr] gap-3 border-b border-border/40 pb-3">
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-md bg-brand-500/10 text-brand-500">
|
||||
<History className="h-5 w-5" />
|
||||
</span>
|
||||
@@ -120,7 +120,7 @@ export function WhatWillILearn() {
|
||||
Advanced analytics that surface 30+ days of utilization trends and patterns.
|
||||
</span>
|
||||
</li>
|
||||
<li className="grid grid-cols-[auto,1fr] gap-3">
|
||||
<li className="grid grid-cols-[auto_1fr] gap-3">
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-md bg-brand-500/10 text-brand-500">
|
||||
<BarChart3 className="h-5 w-5" />
|
||||
</span>
|
||||
|
||||
@@ -43,8 +43,9 @@
|
||||
"@types/react": "catalog:",
|
||||
"config": "workspace:^",
|
||||
"mdast-util-toc": "^6.1.1",
|
||||
"shiki": "^1.1.7",
|
||||
"tailwindcss": "catalog:",
|
||||
"tsconfig": "workspace:*",
|
||||
"tsx": "catalog:",
|
||||
"shiki": "^1.1.7"
|
||||
"tsx": "catalog:"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@import './../../../packages/ui/build/css/source/global.css';
|
||||
@import './../../../packages/ui/build/css/themes/dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/classic-dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/light.css';
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@config '../tailwind.config.js';
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@reference './globals.css';
|
||||
|
||||
.dark [data-theme='light'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@import './../../../packages/ui/build/css/source/global.css';
|
||||
@import './../../../packages/ui/build/css/themes/dark.css';
|
||||
@import './../../../packages/ui/build/css/themes/light.css';
|
||||
|
||||
@tailwind components;
|
||||
@config '../tailwind.config.js';
|
||||
|
||||
@import 'config/typography.css';
|
||||
|
||||
@font-face {
|
||||
font-family: 'custom-font';
|
||||
|
||||
@@ -3,7 +3,6 @@ import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration }
|
||||
import type { Route } from './+types/root'
|
||||
|
||||
import './app.css'
|
||||
import 'config/typography.css'
|
||||
|
||||
export const links: Route.LinksFunction = () => [
|
||||
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user