Skip to content

Commit

Permalink
feat(react-dom): add FadeIn
Browse files Browse the repository at this point in the history
  • Loading branch information
manudeli committed Nov 18, 2024
1 parent fbb937b commit d4d6c66
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/fresh-flies-wash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@suspensive/react-dom": minor
---

feat(react-dom): add `<FadeIn/>`
3 changes: 3 additions & 0 deletions examples/visualization/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<li>
<Link href="/react-dom/InView">{`<InView/>`}</Link>
</li>
<li>
<Link href="/react-dom/FadeIn">{`<FadeIn/>`}</Link>
</li>
</details>
</li>
<li>
Expand Down
68 changes: 68 additions & 0 deletions examples/visualization/src/app/react-dom/FadeIn/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client'

import { ErrorBoundary, Suspense } from '@suspensive/react'
import { FadeIn } from '@suspensive/react-dom'
import { SuspenseQuery, queryOptions } from '@suspensive/react-query'
import axios from 'axios'
import { delay } from '~/utils'

const query = {
user: (userId: number) =>
queryOptions({
queryKey: ['users', userId],
queryFn: () =>
delay(3000).then(() =>
axios
.get<{
id: number
username: string
maidenName: string
age: number
gender: string
email: string
image: 'https://dummyjson.com/icon/emilys/128'
userAgent: string
}>(`https://dummyjson.com/users/${userId}`)
.then(({ data }) => data)
),
}),
}

export default function Page() {
const userId = 1

return (
<ErrorBoundary fallback={({ error }) => <>{error.message}</>}>
<Suspense
clientOnly
fallback={
<FadeIn delay={200} duration={1000}>
{skeleton}
</FadeIn>
}
>
<SuspenseQuery {...query.user(userId)}>
{({ data: user }) => (
<FadeIn duration={200} className="max-w-[344px]">
<h1 className="text-lg font-bold">{user.username}</h1>
<p className="text-xs">{user.userAgent}</p>
<p>{user.age}</p>
<p>{user.maidenName}</p>
</FadeIn>
)}
</SuspenseQuery>
</Suspense>
</ErrorBoundary>
)
}

const skeleton = (
<div role="status" className="animate-pulse space-y-2">
<div className="h-4 w-[42px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
<div className="h-2 w-[34px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
<div className="h-2 w-[344px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
<div className="h-2 w-[344px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
<div className="h-4 w-[42px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
<div className="h-4 w-[34px] rounded-sm bg-gray-300 dark:bg-gray-600"></div>
</div>
)
1 change: 0 additions & 1 deletion examples/visualization/src/app/react-dom/InView/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ export default function Page() {
return (
<div>
{Array.from({ length: 200 }).map((_, i) => (
// eslint-disable-next-line @eslint-react/no-duplicate-key
<InView key={i} threshold={0.8} delay={200} triggerOnce initialInView>
{({ inView, ref }) => (
<div ref={ref}>
Expand Down
34 changes: 34 additions & 0 deletions packages/react-dom/src/FadeIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { type CSSProperties, type ComponentPropsWithoutRef, type ElementType } from 'react'
import { useInView } from './useInView'

type FadInBaseProps = {
delay?: number
duration?: number
timingFunction?: CSSProperties['animationTimingFunction']
}
type FadeInProps<TAs extends ElementType> = {
as?: TAs
} & Omit<ComponentPropsWithoutRef<TAs>, 'as' | keyof FadInBaseProps> &
FadInBaseProps

export function FadeIn<TAs extends ElementType = 'div'>({
as,
delay = 0,
duration = 200,
timingFunction = 'linear',
...rest
}: FadeInProps<TAs>) {
const Component = as || 'div'
const { inView, ref } = useInView()
return (
<Component
{...rest}
ref={ref}
style={{
opacity: inView ? 1 : 0,
willChange: 'opacity',
transition: `opacity ${duration}ms ${timingFunction} ${delay}ms`,
}}
/>
)
}
1 change: 1 addition & 0 deletions packages/react-dom/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { InView } from './InView'
export { useInView } from './useInView'
export { FadeIn } from './FadeIn'

0 comments on commit d4d6c66

Please sign in to comment.