Skip to content

Commit

Permalink
feat: add lightbox support for images
Browse files Browse the repository at this point in the history
  • Loading branch information
CaliCastle committed Jun 24, 2023
1 parent a82249b commit 02325f4
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 15 deletions.
2 changes: 1 addition & 1 deletion app/(main)/blog/BlogPostTableOfContents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export function BlogPostTableOfContents({ headings }: { headings: Node[] }) {
return () => {
window.removeEventListener('scroll', handleScroll)
}
}, [outline])
}, [outline, scrollY])

return (
<motion.ul
Expand Down
2 changes: 1 addition & 1 deletion components/links/RichLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const RichLink = React.forwardRef<HTMLAnchorElement, RichLinkProps>(
const hrefHost = new URL(href).host
const faviconUrl = React.useMemo(
() => (href.startsWith('http') ? `/api/favicon?url=${hrefHost}` : null),
[hrefHost]
[href, hrefHost]
)

// if it's a relative link, use a fallback Link
Expand Down
90 changes: 80 additions & 10 deletions components/portable-text/PortableTextImage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
'use client'

import { type PortableTextComponentProps } from '@portabletext/react'
import * as Dialog from '@radix-ui/react-dialog'
import { AnimatePresence, motion } from 'framer-motion'
import Image from 'next/image'
import React from 'react'

Expand All @@ -18,22 +20,90 @@ export function PortableTextImage({
}
lqip?: string
}>) {
const [isZoomed, setIsZoomed] = React.useState(false)

return (
<div data-blockid={value._key} className="group relative pr-3 md:pr-0">
<ClientOnly>
<Commentable className="z-30" blockId={value._key} />
</ClientOnly>

<Image
src={value.url}
width={value.dimensions.width}
height={value.dimensions.height}
unoptimized
placeholder={value.lqip ? 'blur' : 'empty'}
blurDataURL={value.lqip}
className="relative z-20 rounded-xl dark:brightness-75 dark:transition-[filter] dark:hover:brightness-100 md:rounded-3xl"
alt=""
/>
<Dialog.Root open={isZoomed} onOpenChange={setIsZoomed}>
{isZoomed && (
<div
className="relative"
style={{
width: value.dimensions.width,
height: value.dimensions.height,
}}
/>
)}

<AnimatePresence>
{!isZoomed && (
<motion.div className="relative" layoutId={`image_${value._key}`}>
<Dialog.Trigger>
<Image
src={value.url}
width={value.dimensions.width}
height={value.dimensions.height}
placeholder={value.lqip ? 'blur' : 'empty'}
blurDataURL={value.lqip}
className="relative z-20 cursor-zoom-in rounded-xl dark:brightness-75 dark:transition-[filter] dark:hover:brightness-100 md:rounded-3xl"
alt=""
fetchPriority="high"
/>
</Dialog.Trigger>
</motion.div>
)}
</AnimatePresence>

<AnimatePresence>
{isZoomed && (
<Dialog.Portal forceMount>
<Dialog.Close className="fixed inset-0 z-50 flex h-screen w-screen cursor-zoom-out items-center justify-center">
{/* Overlay */}
<Dialog.Overlay asChild>
<motion.div
className="absolute inset-0 bg-black/50"
initial={{ opacity: 0, backdropFilter: 'blur(0)' }}
animate={{ opacity: 1, backdropFilter: 'blur(12px)' }}
exit={{ opacity: 0, backdropFilter: 'blur(0)' }}
/>
</Dialog.Overlay>

<Dialog.Content className="w-full overflow-hidden">
<div className="relative flex aspect-[3/2] items-center justify-center">
<div className="relative flex aspect-[3/2] w-full max-w-7xl items-center">
<motion.div
layoutId={`image_${value._key}`}
className="absolute inset-0"
transition={{
type: 'spring',
stiffness: 300,
damping: 30,
duration: 0.5,
}}
>
<Image
src={value.url}
width={value.dimensions.width}
height={value.dimensions.height}
placeholder={value.lqip ? 'blur' : 'empty'}
blurDataURL={value.lqip}
className="mx-auto h-full overflow-hidden object-contain"
alt=""
unoptimized
/>
</motion.div>
</div>
</div>
</Dialog.Content>
</Dialog.Close>
</Dialog.Portal>
)}
</AnimatePresence>
</Dialog.Root>
</div>
)
}
3 changes: 2 additions & 1 deletion drizzle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import type { Config } from 'drizzle-kit'
dotenv.config()

export default {
driver: 'mysql2',
schema: './db/schema.ts',
out: './db/migrations',
connectionString: process.env.DATABASE_URL,
dbCredentials: { connectionString: process.env.DATABASE_URL || '' },
} satisfies Config
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"@portabletext/react": "^3.0.3",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-hover-card": "^1.0.6",
"@radix-ui/react-portal": "^1.0.3",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-tooltip": "^1.0.6",
"@react-email/body": "^0.0.2",
Expand Down
7 changes: 5 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 02325f4

Please sign in to comment.