Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions apps/design-system/__registry__/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2623,6 +2623,17 @@ export const Index: Record<string, any> = {
subcategory: "undefined",
chunks: []
},
"connect-interstitial-action-error": {
name: "connect-interstitial-action-error",
type: "components:example",
registryDependencies: undefined,
component: React.lazy(() => import("@/registry/default/example/connect-interstitial-action-error")),
source: "",
files: ["registry/default/example/connect-interstitial-action-error.tsx"],
category: "undefined",
subcategory: "undefined",
chunks: []
},
"connect-interstitial-logo-pair": {
name: "connect-interstitial-logo-pair",
type: "components:example",
Expand Down
Binary file removed apps/design-system/app/fonts/CustomFont-Black.woff2
Binary file not shown.
Binary file not shown.
Binary file removed apps/design-system/app/fonts/CustomFont-Bold.woff2
Binary file not shown.
Binary file not shown.
Binary file removed apps/design-system/app/fonts/CustomFont-Book.woff2
Binary file not shown.
Binary file not shown.
Binary file removed apps/design-system/app/fonts/CustomFont-Medium.woff2
Binary file not shown.
53 changes: 0 additions & 53 deletions apps/design-system/app/fonts/index.ts

This file was deleted.

6 changes: 3 additions & 3 deletions apps/design-system/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import '@/styles/globals.css'

import type { Metadata, Viewport } from 'next'

import { customFont, sourceCodePro } from './fonts'
import { Providers } from './Providers'
import { Toaster } from './toaster'
import { inter, manrope, sourceCodePro } from '@/lib/fonts'

const className = `${customFont.variable} ${sourceCodePro.variable}`
const className = `${inter.variable} ${manrope.variable} ${sourceCodePro.variable}`

const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || '/design-system'

Expand Down Expand Up @@ -126,7 +126,7 @@ export default async function Layout({ children }: RootLayoutProps) {
{/* [Danny]: This has to be an inline style tag here and not a separate component due to next/font */}
<style
dangerouslySetInnerHTML={{
__html: `:root{--font-custom:${customFont.style.fontFamily};--font-source-code-pro:${sourceCodePro.style.fontFamily};}`,
__html: `:root{--font-sans:${inter.style.fontFamily};--font-heading:${manrope.style.fontFamily};--font-source-code-pro:${sourceCodePro.style.fontFamily};}`,
}}
/>
</head>
Expand Down
15 changes: 15 additions & 0 deletions apps/design-system/content/docs/components/sonner.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,21 @@ import { toast } from 'sonner'
toast('Event has been created.')
```

## When to use

Use a toast for short-lived, non-blocking feedback or to confirm an operation
after its originating surface has closed or navigated away.

Do not use a toast as the only feedback for:

- Field validation. Use `FormMessage` or `FieldError` beside the field.
- A failed submission that leaves the form or interstitial visible. Show a
`role="alert"` message in destructive text near the actions.
- A blocking or materially changed page state. Use an inline state component
such as `Admonition` or `ErrorDisplay`.

Keep error copy specific and include the next step when it is not obvious.

## Expand

You can change the amount of toasts visible through the visibleToasts prop.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,48 @@ for new states instead of inventing a parallel card style.
Prefer one full-width primary action. A full-width text button is fine for a
secondary action that still belongs in the flow.

### Action feedback

Match feedback to its scope:

- Use `FormMessage` or `FieldError` beside a field when that field needs to
change.
- Show a submission or action failure as simple destructive text below the
actions. Separate it with a subtle divider when needed for composition. Keep
the current account, selections, and actions visible so the user can retry.
- Use `Admonition` when the whole interstitial is blocked or has materially
changed state, such as an invalid link, wrong account, or partially completed
setup.
- Use a toast only for non-blocking feedback or a completed action whose
originating surface is no longer visible. A toast must not be the only
feedback for a failure the user needs to resolve on the current card.

```tsx
{
actionError && (
<div className="mt-3 border-t border-muted pt-5">
<p role="alert" className="text-center text-xs text-destructive text-balance">
{actionError}
</p>
</div>
)
}
```

Clear stale action feedback when the user retries or changes a relevant
selection. Error copy should say what failed and, when it is not obvious, what
the user can do next.

<ComponentPreview
name="connect-interstitial-action-error"
description="Retryable action error shown beside the actions"
align="start"
className="p-0"
padded={false}
peekCode
wide
/>

## States

Keep loading, invalid, error, and success states inside the same card when the
Expand Down
4 changes: 2 additions & 2 deletions apps/design-system/content/docs/ui-patterns/forms.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Keep repeated-row validation in the form schema or shared validation helper, not

Build a custom row when the cells are mixed controls, such as an input paired with a `Select`.

## Best Practices
## Best practices

1. **Always use FormItemLayout**: Use `FormItemLayout` instead of manually composing `FormItem`, `FormLabel`, `FormMessage`, and `FormDescription`.

Expand All @@ -57,7 +57,7 @@ Build a custom row when the cells are mixed controls, such as an input paired wi

5. **Handle dirty state**: Show cancel buttons and disable save buttons based on `form.formState.isDirty`. Make sure you destructure `isDirty` from `form.formState` (see https://react-hook-form.com/docs/useform/formstate)

6. **Error handling**: Always use mutations with `onSuccess` and `onError` callbacks that show toast notifications.
6. **Error handling**: Match feedback to its scope. Use `FormMessage` or `FieldError` for field validation. Show submission failures inline near the form actions when the user needs to retry or change something. Reserve toasts for non-blocking feedback or completed operations whose originating surface is no longer visible.

7. **Loading states**: Show loading states on submit buttons using the `loading` prop.

Expand Down
23 changes: 23 additions & 0 deletions apps/design-system/lib/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Inter, Manrope, Source_Code_Pro } from 'next/font/google'

export const manrope = Manrope({
variable: '--font-manrope',
display: 'swap',
fallback: ['system-ui', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'],
subsets: ['latin'],
})

export const inter = Inter({
variable: '--font-inter',
display: 'swap',
fallback: ['system-ui', 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif'],
subsets: ['latin'],
})

export const sourceCodePro = Source_Code_Pro({
subsets: ['latin'],
fallback: ['Source Code Pro', 'Office Code Pro', 'Menlo', 'monospace'],
variable: '--font-source-code-pro',
display: 'swap',
weight: ['400', '500', '600', '700'],
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Button } from 'ui'

import {
AccountRow,
InterstitialShell,
LogoPair,
StripeLogo,
SupabaseLogo,
} from './connect-interstitial-shared'

export default function ConnectInterstitialActionError() {
return (
<InterstitialShell
logo={<LogoPair left={<StripeLogo />} right={<SupabaseLogo />} />}
title="Authorize Stripe Projects"
description="This will create an organization on your behalf in Supabase"
>
<div className="flex flex-col gap-4">
<AccountRow displayName="alex@example.com" />
<div className="flex flex-col gap-2">
<Button variant="primary" block>
Authorize Stripe Projects
</Button>
<Button variant="text" block>
Cancel
</Button>
<div className="mt-3 border-t border-muted pt-5">
<p role="alert" className="text-center text-xs text-destructive text-balance">
Failed to authorize Stripe Projects. Please try again.
</p>
</div>
</div>
</div>
</InterstitialShell>
)
}
5 changes: 5 additions & 0 deletions apps/design-system/registry/examples.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1408,6 +1408,11 @@ export const examples: Registry = [
type: 'components:example',
files: ['example/connect-interstitial-demo.tsx'],
},
{
name: 'connect-interstitial-action-error',
type: 'components:example',
files: ['example/connect-interstitial-action-error.tsx'],
},
{
name: 'connect-interstitial-logo-pair',
type: 'components:example',
Expand Down
62 changes: 59 additions & 3 deletions apps/design-system/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,30 @@
@source './../../../packages/ui/src/**/*.{tsx,ts,js}';
@source './../../../packages/ui-patterns/src/**/*.{tsx,ts,js}';

@theme inline {
--font-sans:
var(--font-inter), Inter, Helvetica Neue, Helvetica, ui-sans-serif, system-ui, sans-serif;
--font-heading: var(--font-manrope, var(--font-sans));
--font-mono: var(--font-source-code-pro), 'Source Code Pro', ui-monospace, Menlo, monospace;
}

@theme {
/* added to get max-w-site */
--container-site: 128rem;
/* font sizing and weights optimized for Inter */
--text-sm: 0.8125rem;
--text-base: 0.9375rem;
--text-lg: 1rem;
--text-xl: 1.125rem;
--text-2xl: 1.375rem;
--text-3xl: 1.75rem;
--text-4xl: 2.125rem;
--text-5xl: 2.875rem;
--text-6xl: 3.625rem;
--text-7xl: 4.375rem;
--text-8xl: 5.875rem;
--text-9xl: 7.875rem;
--font-weight-normal: 450;
}

@layer base {
Expand All @@ -30,23 +51,43 @@
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}

@layer base {
* {
@apply border-border;
}
html {
@apply scroll-smooth;
}
body {
@apply bg-default text-foreground;
@apply bg-default text-foreground font-normal;
/* font-feature-settings: "rlig" 1, "calt" 1; */
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

code,
.code-content,
pre,
kbd,
samp,
.font-mono {
--text-xs: 0.75rem;
--text-sm: 0.875rem;
--text-base: 1rem;
--text-lg: 1.125rem;
--text-xl: 1.25rem;
--text-2xl: 1.5rem;
--text-3xl: 1.875rem;
--text-4xl: 2.25rem;
--text-5xl: 3rem;
--text-6xl: 3.75rem;
--text-7xl: 4.5rem;
--text-8xl: 6rem;
--text-9xl: 8rem;
--font-weight-normal: 400;
}
}

@layer utilities {
Expand Down Expand Up @@ -76,6 +117,21 @@
}
}

h1:not(.font-mono),
h2:not(.font-mono),
h3:not(.font-mono),
h4:not(.font-mono),
h5:not(.font-mono),
h6:not(.font-mono),
.h1:not(.font-mono),
.h2:not(.font-mono),
.h3:not(.font-mono),
.h4:not(.font-mono),
.h5:not(.font-mono),
.h6:not(.font-mono) {
@apply font-heading font-semibold;
}

.rdg-cell {
padding-inline: 0.5rem;
}
22 changes: 10 additions & 12 deletions apps/docs/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -396,18 +396,16 @@ const HomePage = () => (
</div>
</div>

<div className="col-span-8 grid grid-cols-12 not-prose">
<IconLinkList
labelledBy="self-hosting"
className="col-span-full lg:col-span-8"
itemClassName="col-span-6"
items={selfHostingOptions.map((option) => ({
title: option.title,
href: option.href,
icon: <IconLinkMenuIcon icon={option.icon} />,
}))}
/>
</div>
<IconLinkList
labelledBy="self-hosting"
className="col-span-8 not-prose"
itemClassName="col-span-6"
items={selfHostingOptions.map((option) => ({
title: option.title,
href: option.href,
icon: <IconLinkMenuIcon icon={option.icon} />,
}))}
/>
</div>
)}
</div>
Expand Down
Loading
Loading