Skip to content
Open
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
15 changes: 9 additions & 6 deletions apps/www/app/(blog)/blog/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import Link from "next/link"
import { notFound } from "next/navigation"
import { mdxComponents } from "@/mdx-components"
import { ArrowLeftIcon } from "lucide-react"
import { Badge } from "@/components/ui/badge"
import type { BlogPosting, BreadcrumbList, WithContext } from "schema-dts"

import { siteConfig } from "@/config/site"
import { blogSource } from "@/lib/source"
import { absoluteUrl, calculateReadingTime, formatDate } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
import { buttonVariants } from "@/components/ui/button"
import { BlogTableOfContents } from "@/components/blog/table-of-contents"
import { MobileTOC } from "@/components/blog/mobile-toc"
import { BlogTableOfContents } from "@/components/blog/table-of-contents"
import { SidebarCTA } from "@/components/sidebar-cta"

export const revalidate = false
Expand Down Expand Up @@ -188,7 +189,7 @@ export default async function BlogPage({ params }: PageProps) {
<img
src={doc.image}
alt={doc.title}
className="size-full rounded-xl object-cover object-left border border-border"
className="border-border size-full rounded-xl border object-cover object-left"
/>
</div>
<div className="mx-auto flex flex-col items-center justify-center gap-y-2 p-5">
Expand Down Expand Up @@ -219,14 +220,16 @@ export default async function BlogPage({ params }: PageProps) {

return (
tags.length > 0 && (
<div className="flex flex-wrap gap-1 items-center justify-center">
<div className="flex flex-wrap items-center justify-center gap-1">
{tags.map((tag) => (
<Link
key={tag}
href={`/blog?tag=${encodeURIComponent(tag)}`}

>
<Badge variant="secondary" className="border border-border text-xs">
<Badge
variant="secondary"
className="border-border border text-xs"
>
{tag}
</Badge>
</Link>
Expand Down
28 changes: 15 additions & 13 deletions apps/www/app/(blog)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export default async function Page({
__html: serializedBreadcrumbStructuredData,
}}
/>
<main className="container mx-auto py-10 md:py-14 px-10">
<main className="container mx-auto px-10 py-10 md:py-14">
<header className="mb-12 space-y-3">
<div>
<h1 className="text-3xl font-semibold tracking-tight">Blog</h1>
Expand Down Expand Up @@ -202,20 +202,20 @@ export default async function Page({
>
<Link href={post.url} className="flex h-full flex-col">
{post.data?.image && (
<div className="border-b overflow-hidden rounded-t-lg">
<div className="overflow-hidden rounded-t-lg border-b">
<img
src={post.data.image}
alt={post.data?.title ?? post.url}
width={640}
height={360}
className="w-full h-auto object-contain transition-transform duration-300 group-hover:scale-[1.02]"
className="h-auto w-full object-contain transition-transform duration-300 group-hover:scale-[1.02]"
/>
</div>
)}

<div className="flex flex-1 flex-col space-y-3 p-6">
<div className="flex-1 space-y-2">
<h2 className="group-hover:text-primary line-clamp-2 text-xl font-semibold leading-tight transition-colors">
<h2 className="group-hover:text-primary line-clamp-2 text-xl leading-tight font-semibold transition-colors">
{post.data?.title ?? post.url}
</h2>
{post.data?.description && (
Expand All @@ -239,15 +239,17 @@ export default async function Page({

{normalizeTag(post.data?.tags).length > 0 && (
<div className="flex flex-wrap gap-1.5">
{normalizeTag(post.data.tags).slice(0, 3).map((tag) => (
<Badge
key={tag}
variant="secondary"
className="border border-border text-xs"
>
{tag}
</Badge>
))}
{normalizeTag(post.data.tags)
.slice(0, 3)
.map((tag) => (
<Badge
key={tag}
variant="secondary"
className="border-border border text-xs"
>
{tag}
</Badge>
))}
</div>
)}
</div>
Expand Down
4 changes: 2 additions & 2 deletions apps/www/components/blog/table-of-contents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ const generateHeadingId = (text: string) => {
.trim()
}

export function BlogTableOfContents({
export function BlogTableOfContents({
className,
onLinkClick,
}: {
}: {
className?: string
onLinkClick?: () => void
}) {
Expand Down
6 changes: 6 additions & 0 deletions apps/www/config/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ export const docsConfig: DocsConfig = {
href: `/docs/components/magic-card`,
items: [],
},
{
title: "Glare Hover",
href: `/docs/components/glare-hover`,
items: [],
label: "New",
},
{
title: "Meteors",
href: `/docs/components/meteors`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ This comparison isn't about crowning a winner. It’s about helping you make the
<div className="my-6 w-full overflow-x-auto rounded-lg border">
<table className="relative w-full text-sm">
<thead className="bg-muted border-b">
<tr className="m-0 border-b transition-colors hover:bg-muted/50">
<tr className="hover:bg-muted/50 m-0 border-b transition-colors">
<th
scope="col"
className="min-w-[120px] px-4 py-3 text-left font-semibold"
Expand All @@ -61,7 +61,7 @@ This comparison isn't about crowning a winner. It’s about helping you make the
</tr>
</thead>
<tbody>
<tr className="m-0 border-b transition-colors hover:bg-muted/50">
<tr className="hover:bg-muted/50 m-0 border-b transition-colors">
<td className="min-w-[120px] px-4 py-3 text-left font-medium">
Project Scope
</td>
Expand All @@ -73,7 +73,7 @@ This comparison isn't about crowning a winner. It’s about helping you make the
maintainability.
</td>
</tr>
<tr className="m-0 border-b transition-colors hover:bg-muted/50">
<tr className="hover:bg-muted/50 m-0 border-b transition-colors">
<td className="min-w-[120px] px-4 py-3 text-left font-medium">
Error Detection
</td>
Expand All @@ -84,7 +84,7 @@ This comparison isn't about crowning a winner. It’s about helping you make the
Catches type-related errors during compilation, before code is run.
</td>
</tr>
<tr className="m-0 border-b transition-colors hover:bg-muted/50 last:border-b-0">
<tr className="hover:bg-muted/50 m-0 border-b transition-colors last:border-b-0">
<td className="min-w-[120px] px-4 py-3 text-left font-medium">
Developer Experience
</td>
Expand Down
124 changes: 124 additions & 0 deletions apps/www/content/docs/components/glare-hover.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
title: Glare Hover
date: 2024-12-19
description: A component that creates a subtle glare effect that animates across the element on hover.
author: magicui
published: true
---

<ComponentPreview name="glare-hover-demo" />

## Examples

### Custom Color - Blue

<ComponentPreview name="glare-hover-demo-blue" />

### Custom Color - Purple

<ComponentPreview name="glare-hover-demo-purple" />

## Installation

<Tabs defaultValue="cli">

<TabsList>
<TabsTrigger value="cli">CLI</TabsTrigger>
<TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">

```bash
npx shadcn@latest add @magicui/glare-hover
```

</TabsContent>

<TabsContent value="manual">

<Steps>

<Step>Copy and paste the following code into your project.</Step>

<ComponentSource name="glare-hover" />

<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</Tabs>

## Usage

```tsx showLineNumbers
import { GlareHover } from "@/registry/magicui/glare-hover"
```

```tsx showLineNumbers
<GlareHover className="rounded-lg">
<Card>
<CardContent>
<CardTitle>Hello World</CardTitle>
<CardDescription>Hover over this card to see the effect</CardDescription>
</CardContent>
</Card>
</GlareHover>
```

```tsx showLineNumbers
<GlareHover className="rounded-lg" rotate={30}>
<Card>
<CardContent>
<CardTitle>Custom Rotation</CardTitle>
<CardDescription>With custom rotation angle</CardDescription>
</CardContent>
</Card>
</GlareHover>
```

### Customizing the Glare Color

You can customize the glare effect color by using the `glareClassName` prop with Tailwind's `via-<color>` utility classes. The component uses a gradient with `via-black/15` by default (and `via-white/50` in dark mode), which you can override.

```tsx showLineNumbers
<GlareHover
className="rounded-lg"
glareClassName="via-blue-500/30 dark:via-blue-400/40"
>
<Card>
<CardContent>
<CardTitle>Custom Color</CardTitle>
<CardDescription>With blue glare effect</CardDescription>
</CardContent>
</Card>
</GlareHover>
```

```tsx showLineNumbers
<GlareHover
className="rounded-lg"
glareClassName="via-purple-500/40 dark:via-purple-300/50"
>
<Card>
<CardContent>
<CardTitle>Purple Glare</CardTitle>
<CardDescription>With purple glare effect</CardDescription>
</CardContent>
</Card>
</GlareHover>
```

## Props

### GlareHover

| Prop name | Type | Default | Description |
| ---------------- | ----------------- | ------- | ---------------------------------------------------- |
| `children` | `React.ReactNode` | `-` | The content to be wrapped with the glare effect |
| `className` | `string` | `-` | Additional CSS classes for the root container |
| `glareClassName` | `string` | `-` | Additional CSS classes for the glare element. Use `via-<color>` Tailwind classes to customize the glare color (e.g., `via-blue-500/30`) |
| `rotate` | `number` | `45` | Rotation angle in degrees for the glare effect |

The glare effect uses a gradient that automatically adapts to light and dark themes, creating a subtle shine effect that moves across the element on hover. By default, it uses `via-black/15` in light mode and `via-white/50` in dark mode, but you can customize it using the `glareClassName` prop with Tailwind's `via-<color>` utility classes.
36 changes: 13 additions & 23 deletions apps/www/mdx-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ export const mdxComponents = {
/>
),
p: ({ className, ...props }: React.ComponentProps<"p">) => (
<p
className={cn("leading-relaxed not-first:mt-6", className)}
{...props}
/>
<p className={cn("leading-relaxed not-first:mt-6", className)} {...props} />
),
strong: ({ className, ...props }: React.HTMLAttributes<HTMLElement>) => (
<strong className={cn("font-medium", className)} {...props} />
Expand All @@ -119,7 +116,10 @@ export const mdxComponents = {
),
blockquote: ({ className, ...props }: React.ComponentProps<"blockquote">) => (
<blockquote
className={cn("mt-6 border-l-2 pl-6 pr-4 italic bg-muted/50 py-4 rounded-r-md", className)}
className={cn(
"bg-muted/50 mt-6 rounded-r-md border-l-2 py-4 pr-4 pl-6 italic",
className
)}
{...props}
/>
),
Expand All @@ -128,40 +128,30 @@ export const mdxComponents = {
<img className={cn("rounded-md", className)} alt={alt} {...props} />
),
iframe: ({ className, ...props }: React.ComponentProps<"iframe">) => (
<iframe
className={cn("mt-6 rounded-md w-full", className)}
{...props}
/>
<iframe className={cn("mt-6 w-full rounded-md", className)} {...props} />
),
hr: ({ className, ...props }: React.ComponentProps<"hr">) => (
<div className={cn("my-4 flex items-center justify-center md:my-8", className)}>
<div
className={cn("my-4 flex items-center justify-center md:my-8", className)}
>
<hr
className="mx-4 h-px w-full border-0 bg-linear-to-r from-transparent via-border to-transparent"
className="via-border mx-4 h-px w-full border-0 bg-linear-to-r from-transparent to-transparent"
{...props}
/>
</div>
),
table: ({ className, ...props }: React.ComponentProps<"table">) => (
<div className="my-6 w-full overflow-x-auto rounded-lg border">
<table
className={cn(
"relative w-full text-sm",
className
)}
{...props}
/>
<table className={cn("relative w-full text-sm", className)} {...props} />
</div>
),
thead: ({ className, ...props }: React.ComponentProps<"thead">) => (
<thead
className={cn("bg-muted border-b", className)}
{...props}
/>
<thead className={cn("bg-muted border-b", className)} {...props} />
),
tr: ({ className, ...props }: React.ComponentProps<"tr">) => (
<tr
className={cn(
"m-0 border-b transition-colors hover:bg-muted/50 last:border-b-0",
"hover:bg-muted/50 m-0 border-b transition-colors last:border-b-0",
className
)}
{...props}
Expand Down
Loading
Loading