Skip to content

Commit 2812ab9

Browse files
chore: update changelog
1 parent a9ce0db commit 2812ab9

File tree

7 files changed

+189
-287
lines changed

7 files changed

+189
-287
lines changed

apps/sim/app/(landing)/blog/[slug]/animated-blocks.tsx

Lines changed: 32 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ const HOLD_MS = 3000
1010
const EXIT_STAGGER_MS = 120
1111
const EXIT_DURATION_MS = 500
1212

13-
interface BlockState {
14-
opacity: number
15-
transitioning: boolean
13+
const RE_ENTER_OPACITIES = [1, 0.8, 0.6, 0.9] as const
14+
15+
16+
function setBlockOpacity(el: HTMLSpanElement | null, opacity: number, animate: boolean) {
17+
if (!el) return
18+
el.style.transition = animate ? `opacity ${ENTER_DURATION_MS}ms ease-out` : 'none'
19+
el.style.opacity = String(opacity)
1620
}
1721

1822
export function AnimatedColorBlocks() {
1923
const prefersReducedMotion = usePrefersReducedMotion()
20-
const [blocks, setBlocks] = useState<BlockState[]>(
21-
COLORS.map(() => ({ opacity: prefersReducedMotion ? 1 : 0, transitioning: false }))
22-
)
24+
const blockRefs = useRef<(HTMLSpanElement | null)[]>([])
2325
const timers = useRef<ReturnType<typeof setTimeout>[]>([])
2426
const mounted = useRef(true)
2527

@@ -32,17 +34,18 @@ export function AnimatedColorBlocks() {
3234
useEffect(() => {
3335
mounted.current = true
3436
timers.current = []
37+
3538
if (prefersReducedMotion) {
36-
setBlocks(COLORS.map(() => ({ opacity: 1, transitioning: false })))
39+
blockRefs.current.forEach((el) => setBlockOpacity(el, 1, false))
3740
return
3841
}
3942

43+
blockRefs.current.forEach((el) => setBlockOpacity(el, 0, false))
44+
4045
COLORS.forEach((_, i) => {
4146
schedule(() => {
4247
if (!mounted.current) return
43-
setBlocks((prev) =>
44-
prev.map((b, idx) => (idx === i ? { opacity: 1, transitioning: true } : b))
45-
)
48+
setBlockOpacity(blockRefs.current[i], 1, true)
4649
}, i * ENTER_STAGGER_MS)
4750
})
4851

@@ -65,9 +68,7 @@ export function AnimatedColorBlocks() {
6568
COLORS.forEach((_, i) => {
6669
schedule(() => {
6770
if (!mounted.current) return
68-
setBlocks((prev) =>
69-
prev.map((b, idx) => (idx === i ? { opacity: 0.15, transitioning: true } : b))
70-
)
71+
setBlockOpacity(blockRefs.current[i], 0.15, true)
7172
}, i * EXIT_STAGGER_MS)
7273
})
7374

@@ -77,11 +78,7 @@ export function AnimatedColorBlocks() {
7778
COLORS.forEach((_, i) => {
7879
schedule(() => {
7980
if (!mounted.current) return
80-
setBlocks((prev) =>
81-
prev.map((b, idx) =>
82-
idx === i ? { opacity: [1, 0.8, 0.6, 0.9][i], transitioning: true } : b
83-
)
84-
)
81+
setBlockOpacity(blockRefs.current[i], RE_ENTER_OPACITIES[i], true)
8582
}, i * ENTER_STAGGER_MS)
8683
})
8784
}, exitTotalMs + 200)
@@ -96,12 +93,11 @@ export function AnimatedColorBlocks() {
9693
{COLORS.map((color, i) => (
9794
<span
9895
key={color}
99-
className='inline-block h-3 w-3'
100-
style={{
101-
backgroundColor: color,
102-
opacity: blocks[i]?.opacity ?? 0,
103-
transition: `opacity ${blocks[i]?.transitioning ? ENTER_DURATION_MS : 0}ms ease-out`,
96+
ref={(el) => {
97+
blockRefs.current[i] = el
10498
}}
99+
className='inline-block h-3 w-3'
100+
style={{ backgroundColor: color, opacity: 0 }}
105101
/>
106102
))}
107103
</div>
@@ -110,32 +106,30 @@ export function AnimatedColorBlocks() {
110106

111107
export function AnimatedColorBlocksVertical() {
112108
const prefersReducedMotion = usePrefersReducedMotion()
113-
const [blocks, setBlocks] = useState<BlockState[]>(
114-
COLORS.slice(0, 3).map(() => ({
115-
opacity: prefersReducedMotion ? 1 : 0,
116-
transitioning: false,
117-
}))
118-
)
109+
const blockRefs = useRef<(HTMLSpanElement | null)[]>([])
119110
const timers = useRef<ReturnType<typeof setTimeout>[]>([])
120111
const mounted = useRef(true)
121112

113+
const verticalColors = [COLORS[0], COLORS[1], COLORS[2]] as const
114+
122115
useEffect(() => {
123116
mounted.current = true
124117
timers.current = []
118+
125119
if (prefersReducedMotion) {
126-
setBlocks(COLORS.slice(0, 3).map(() => ({ opacity: 1, transitioning: false })))
120+
blockRefs.current.forEach((el) => setBlockOpacity(el, 1, false))
127121
return
128122
}
129123

124+
blockRefs.current.forEach((el) => setBlockOpacity(el, 0, false))
125+
130126
const baseDelay = COLORS.length * ENTER_STAGGER_MS + 100
131127

132-
COLORS.slice(0, 3).forEach((_, i) => {
128+
verticalColors.forEach((_, i) => {
133129
const id = setTimeout(
134130
() => {
135131
if (!mounted.current) return
136-
setBlocks((prev) =>
137-
prev.map((b, idx) => (idx === i ? { opacity: 1, transitioning: true } : b))
138-
)
132+
setBlockOpacity(blockRefs.current[i], 1, true)
139133
},
140134
baseDelay + i * ENTER_STAGGER_MS
141135
)
@@ -149,19 +143,16 @@ export function AnimatedColorBlocksVertical() {
149143
}
150144
}, [prefersReducedMotion])
151145

152-
const verticalColors = [COLORS[0], COLORS[1], COLORS[2]]
153-
154146
return (
155147
<div className='flex flex-col gap-0' aria-hidden='true'>
156148
{verticalColors.map((color, i) => (
157149
<span
158150
key={color}
159-
className='inline-block h-3 w-3'
160-
style={{
161-
backgroundColor: color,
162-
opacity: blocks[i]?.opacity ?? 0,
163-
transition: `opacity ${blocks[i]?.transitioning ? ENTER_DURATION_MS : 0}ms ease-out`,
151+
ref={(el) => {
152+
blockRefs.current[i] = el
164153
}}
154+
className='inline-block h-3 w-3'
155+
style={{ backgroundColor: color, opacity: 0 }}
165156
/>
166157
))}
167158
</div>

apps/sim/app/(landing)/blog/[slug]/back-link.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
1-
'use client'
2-
3-
import { useState } from 'react'
41
import { ArrowLeft, ChevronLeft } from 'lucide-react'
52
import Link from 'next/link'
63

74
export function BackLink() {
8-
const [isHovered, setIsHovered] = useState(false)
9-
105
return (
116
<Link
127
href='/blog'
138
className='group flex items-center gap-1 text-[#999] text-sm hover:text-[#ECECEC]'
14-
onMouseEnter={() => setIsHovered(true)}
15-
onMouseLeave={() => setIsHovered(false)}
169
>
17-
<span className='group-hover:-translate-x-0.5 inline-flex transition-transform duration-200'>
18-
{isHovered ? (
19-
<ArrowLeft className='h-4 w-4' aria-hidden='true' />
20-
) : (
21-
<ChevronLeft className='h-4 w-4' aria-hidden='true' />
22-
)}
10+
<span className='inline-flex transition-transform duration-200 group-hover:-translate-x-0.5'>
11+
<ChevronLeft className='h-4 w-4 block group-hover:hidden' aria-hidden='true' />
12+
<ArrowLeft className='h-4 w-4 hidden group-hover:block' aria-hidden='true' />
2313
</span>
2414
Back to Blog
2515
</Link>

apps/sim/app/(landing)/blog/[slug]/prose-studio.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,18 @@ body[data-toc-rail-hover="true"] [data-blog-main-content] {
232232
opacity: 0.58;
233233
}
234234

235+
.nav-label-softenable {
236+
transition:
237+
color 150ms ease-out,
238+
filter 150ms ease-out,
239+
opacity 150ms ease-out;
240+
}
241+
242+
nav[data-rail-hover] .nav-label-softenable[data-softenable] {
243+
opacity: 0.45;
244+
filter: blur(1.5px);
245+
}
246+
235247
/* Reduced motion */
236248
@media (prefers-reduced-motion: reduce) {
237249
[data-blog-main-content] {
@@ -241,4 +253,8 @@ body[data-toc-rail-hover="true"] [data-blog-main-content] {
241253
.prose-studio a {
242254
transition: none;
243255
}
256+
257+
.nav-label-softenable {
258+
transition: none;
259+
}
244260
}

0 commit comments

Comments
 (0)