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
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,12 @@ Today we’re publishing the Prisma Next repo so you can follow the work as it h

If you want to stay close to the work, **star + watch** the repo.

<Button varient="ppg">

[Star and watch the repository](https://github.com/prisma/prisma-next)

<Button
variant="ppg"
href="https://github.com/prisma/prisma-next"
className="no-underline hover:no-underline w-1/3 mx-auto"
>
Star and watch the repository
</Button>

If you want to build alongside us, join `#prisma-next` on [Discord](http://pris.ly/discord?utm_campaign=prisma-next).
1 change: 0 additions & 1 deletion apps/blog/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ const config = {
assetPrefix: "/blog-static",
allowedDevOrigins,
reactStrictMode: true,
images: { unoptimized: true },
transpilePackages: ["@prisma/eclipse"],
experimental: {
globalNotFound: true,
Expand Down
22 changes: 12 additions & 10 deletions apps/blog/src/app/(blog)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ export function baseOptions() {
desc: "Make your database global",
url: "https://www.prisma.io/accelerate",
},
{
icon: "fa-regular fa-plug",
text: "Management API",
desc: "Offer Postgres to your users",
url: "https://www.prisma.io/management-api",
},
// {
// icon: "fa-regular fa-plug",
// text: "Management API",
// desc: "Offer Postgres to your users",
// url: "https://www.prisma.io/management-api",
// },
],
},
{
Expand All @@ -62,13 +62,14 @@ export function baseOptions() {
},
{
text: "Tutorials",
url: "https://www.prisma.io/learn",
icon: "fa-regular fa-clapperboard-play",
url: "https://www.prisma.io/docs/guides",
icon: "fa-regular fa-clapperboard-play"
},
{
text: "Examples",
url: "https://www.prisma.io/examples",
url: "https://github.com/prisma/prisma-examples",
icon: "fa-regular fa-grid-2",
external: true,
},
{
text: "Stack",
Expand All @@ -89,6 +90,7 @@ export function baseOptions() {
text: "Data guide",
url: "https://www.prisma.io/dataguide",
icon: "fa-regular fa-file-binary",
external: true,
},
],
},
Expand All @@ -107,7 +109,7 @@ export function baseOptions() {
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider defaultTheme="system" storageKey="theme">
<WebNavigation links={baseOptions().links} />
<WebNavigation links={baseOptions().links} utm={{source: "website", medium: "blog"}} />
{children}
<Footer />
</ThemeProvider>
Expand Down
2 changes: 2 additions & 0 deletions apps/blog/src/components/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export function PostCard({
</div>
{post.title && <h2 className={titleClassName}>{post.title}</h2>}
{post.excerpt && <p className={excerptClassName}>{post.excerpt}</p>}


</div>
{post.author && (
<AuthorAvatarGroup authors={[post.author]} className={authorClassName} />
Expand Down
39 changes: 22 additions & 17 deletions apps/eclipse/content/design-system/components/button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export function ButtonVariants() {
<Button variant="ppg">PPG</Button>
<Button variant="orm">ORM</Button>
<Button variant="error">Error</Button>
<Button variant="success">Success</Button>
<Button variant="link">Link</Button>
</div>
);
Expand All @@ -52,6 +53,7 @@ export function ButtonVariants() {
<Button variant="ppg">PPG</Button>
<Button variant="orm">ORM</Button>
<Button variant="error">Error</Button>
<Button variant="success">Success</Button>
<Button variant="link">Link</Button>
</div>

Expand All @@ -75,9 +77,9 @@ export function ButtonSizes() {
**Live Example:**

<div className="flex flex-wrap items-center gap-4 my-4">
<Button size="lg">Large</Button>
<Button size="lg">Large (Default)</Button>
<Button size="xl">Extra Large</Button>
<Button size="2xl">2X Large (Default)</Button>
<Button size="2xl">2X Large</Button>
<Button size="4xl">4X Large</Button>
</div>

Expand All @@ -101,18 +103,13 @@ export function InteractiveButton() {

**As Link**

Use the `asChild` prop with Next.js Link or other link components:
Use the `href` prop to render the button as an anchor element:

```tsx
import { Button } from "@prisma/eclipse";
import Link from "next/link";

export function LinkButton() {
return (
<Button variant="ppg" asChild>
<Link href="/docs">Go to Docs</Link>
</Button>
);
return <Button variant="ppg" href="/docs">Go to Docs</Button>;
}
```

Expand Down Expand Up @@ -157,8 +154,8 @@ export function FullWidthButton() {
### Button Props

- `variant` - The visual style variant (default: `"default"`)
- `size` - The button size (default: `"2xl"`)
- `asChild` - Use the child element as the button (boolean, default: false)
- `size` - The button size (default: `"lg"`)
- `href` - When provided, renders an anchor element instead of a button
- `disabled` - Whether the button is disabled (boolean, default: false)
- `onClick` - Click event handler (optional)
- `className` - Additional CSS classes (optional)
Expand Down Expand Up @@ -209,6 +206,13 @@ Error or danger variant for destructive actions.
<Button variant="error">Delete</Button>
```

#### success
Success variant for positive actions and confirmations.

```tsx
<Button variant="success">Saved</Button>
```

#### link
Link-styled button for navigation that looks like a text link.

Expand All @@ -220,9 +224,9 @@ Link-styled button for navigation that looks like a text link.

The Button component supports four sizes:

- `lg` - Large button
- `lg` - Large button (default)
- `xl` - Extra large button
- `2xl` - 2X large button (default)
- `2xl` - 2X large button
- `4xl` - 4X large button

```tsx
Expand All @@ -234,14 +238,14 @@ The Button component supports four sizes:

### Features

- ✅ Seven semantic variants
- ✅ Eight semantic variants
- ✅ Four size options
- ✅ Disabled state support
- ✅ Works as link with `asChild` prop
- ✅ Works as link with `href` prop
- ✅ Eclipse design system styling
- ✅ Hover and focus states
- ✅ Accessible keyboard navigation
- ✅ Built on Radix UI primitives
- ✅ Renders native `<button>` and `<a>` elements

### Best Practices

Expand All @@ -251,6 +255,7 @@ The Button component supports four sizes:
- Use **ppg** for Prisma Pulse & Accelerate specific features
- Use **orm** for Prisma ORM specific features
- Use **error** for destructive actions (delete, remove, etc.)
- Use **success** for positive confirmations and completion states
- Use **link** for navigation that should appear as text
- Choose appropriate sizes based on button importance and context
- Use `disabled` state to indicate unavailable actions
Expand Down Expand Up @@ -304,7 +309,7 @@ The Button component supports four sizes:
- Buttons have proper focus states for keyboard navigation
- Disabled buttons are not keyboard accessible
- Use semantic `<button>` elements for actions
- Use the `asChild` prop with links for navigation
- Use the `href` prop when the action should navigate
- Provide clear, descriptive button text
- Ensure sufficient color contrast for all variants
- Button states are visually distinct and accessible
Expand Down
49 changes: 35 additions & 14 deletions packages/eclipse/src/components/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,45 @@ const buttonVariants = cva(
},
});

export interface ButtonProps
extends
React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
type ButtonBaseProps = VariantProps<typeof buttonVariants>;

type ButtonAsButtonProps = ButtonBaseProps &
React.ButtonHTMLAttributes<HTMLButtonElement> & {
href?: undefined;
};

type ButtonAsAnchorProps = ButtonBaseProps &
React.AnchorHTMLAttributes<HTMLAnchorElement> & {
href: string;
};

export type ButtonProps = ButtonAsButtonProps | ButtonAsAnchorProps;

const Button = React.forwardRef<
HTMLButtonElement | HTMLAnchorElement,
ButtonProps
>(({ className, variant, size, href, ...props }, ref) => {
const classNames = cn(buttonVariants({ variant, size, className }));

if (href) {
return (
<a
className={classNames}
ref={ref as React.Ref<HTMLAnchorElement>}
href={href}
{...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)}
/>
);
}

return (
<button
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
className={classNames}
ref={ref as React.Ref<HTMLButtonElement>}
{...(props as React.ButtonHTMLAttributes<HTMLButtonElement>)}
/>
);
},
);
});

Button.displayName = "Button";

Expand Down
5 changes: 4 additions & 1 deletion packages/ui/src/components/navigation-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,14 @@ function Socials({
function MenuNavigationItem({
link,
}: {
link: { text: string; desc: string; icon: string; url: string };
link: { text: string; desc: string; icon: string; url: string; external?: boolean };
}) {
return (
<NavigationMenuLink
key={link.url}
href={link.url}
target={link.external ? "_blank" : "_self"}
rel={link.external ? "noopener noreferrer" : undefined}
className="flex gap-2 items-center justify-start hover:bg-background-ppg-strong w-full rounded-square! overflow-hidden"
>
<Action color="ppg" size="3xl">
Expand All @@ -288,6 +290,7 @@ function MenuNavigationItem({
<div className="flex flex-col gap-0">
<span className="text-md font-semibold text-foreground-neutral">
{link.text}
{link.external && <i className=" ml-1 fa-regular fa-arrow-up-right text-foreground-neutral text-sm" />}
</span>
<p className="text-xs text-foreground-neutral-weaker">{link.desc}</p>
</div>
Expand Down
22 changes: 18 additions & 4 deletions packages/ui/src/components/web-navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,34 @@ import { cn } from "../lib/cn";

interface Link {
text: string;
external?: boolean;
url?: string;
desc?: string;
col?: number;
sub?: Array<{
text: string;
external?: boolean;
url: string;
desc?: string;
}>;
}

interface WebNavigationProps {
links: Link[];
utm?: {
source: "website";
medium: string;
};
}

export function WebNavigation({ links }: WebNavigationProps) {
export function WebNavigation({ links, utm }: WebNavigationProps) {
const [mobileView, setMobileView] = useState(false);
const loginHref = utm
? `https://console.prisma.io/login?utm_source=${utm.source}&utm_medium=${utm.medium}&utm_campaign=login`
: "https://console.prisma.io/login";
const signupHref = utm
? `https://console.prisma.io/signup?utm_source=${utm.source}&utm_medium=${utm.medium}&utm_campaign=signup`
: "https://console.prisma.io/signup";

useEffect(() => {
if (mobileView) {
Expand All @@ -52,7 +64,7 @@ export function WebNavigation({ links }: WebNavigationProps) {
<NavigationMenuItem className="outline-none!">
<NavigationMenuLink
className="shrink-0 w-full p-0 hover:bg-transparent focus:bg-transparent focus-visible:outline-none focus-visible:ring-0"
href="/"
href="https://www.prisma.io"
>
{Logo}
</NavigationMenuLink>
Expand Down Expand Up @@ -94,10 +106,12 @@ export function WebNavigation({ links }: WebNavigationProps) {
>
<Socials include={["discord"]} />
<NavigationMenuItem className="ml-2 -mr-2 hidden sm:block">
<Button variant="default-stronger">Login</Button>
<Button variant="default-stronger" href={loginHref}>
Login
</Button>
</NavigationMenuItem>
<NavigationMenuItem className="hidden sm:block">
<Button variant="ppg" className="whitespace-nowrap">
<Button variant="ppg" className="whitespace-nowrap" href={signupHref}>
Get started
</Button>
</NavigationMenuItem>
Expand Down
Loading