Skip to content

Commit b4b7a86

Browse files
chore: made requested changes
1 parent 48782d2 commit b4b7a86

File tree

2 files changed

+42
-23
lines changed

2 files changed

+42
-23
lines changed

apps/sim/app/(landing)/components/hero/components/icon-button.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ interface IconButtonProps {
88
onMouseEnter?: () => void
99
style?: React.CSSProperties
1010
'aria-label': string
11-
isAutoHovered?: boolean
1211
highlightFromParent?: boolean
1312
}
1413

@@ -18,25 +17,19 @@ export function IconButton({
1817
onMouseEnter,
1918
style,
2019
'aria-label': ariaLabel,
21-
isAutoHovered = false,
2220
highlightFromParent = false,
2321
}: IconButtonProps) {
24-
const showOwnHighlight = !highlightFromParent && isAutoHovered
25-
const hoverHighlight = !highlightFromParent
26-
? 'hover:border-[#E5E5E5] hover:shadow-[0_2px_4px_0_rgba(0,0,0,0.08)]'
27-
: ''
22+
const hoverHighlight = highlightFromParent
23+
? ''
24+
: 'hover:border-[#E5E5E5] hover:shadow-[0_2px_4px_0_rgba(0,0,0,0.08)]'
2825

2926
return (
3027
<button
3128
type='button'
3229
aria-label={ariaLabel}
3330
onClick={onClick}
3431
onMouseEnter={onMouseEnter}
35-
className={`flex items-center justify-center rounded-xl border p-2 outline-none transition-all duration-300 ${
36-
showOwnHighlight
37-
? 'border-[#E5E5E5] shadow-[0_2px_4px_0_rgba(0,0,0,0.08)]'
38-
: `border-transparent ${hoverHighlight}`
39-
}`}
32+
className={`flex items-center justify-center rounded-xl border border-transparent p-2 outline-none transition-all duration-300 ${hoverHighlight}`}
4033
style={style}
4134
>
4235
{children}

apps/sim/app/(landing)/components/hero/hero.tsx

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ export default function Hero() {
151151
const [autoHoverIndex, setAutoHoverIndex] = React.useState(1)
152152
const [isUserHovering, setIsUserHovering] = React.useState(false)
153153
const [lastHoveredIndex, setLastHoveredIndex] = React.useState<number | null>(null)
154+
const [selectedIconIndex, setSelectedIconIndex] = React.useState<number | null>(null)
154155
const intervalRef = React.useRef<NodeJS.Timeout | null>(null)
155156

156157
const iconRowRef = React.useRef<HTMLDivElement | null>(null)
@@ -166,7 +167,12 @@ export default function Hero() {
166167
/**
167168
* Handle service icon click to populate textarea with template
168169
*/
169-
const handleServiceClick = (service: keyof typeof SERVICE_TEMPLATES) => {
170+
const handleServiceClick = (index: number, service: keyof typeof SERVICE_TEMPLATES) => {
171+
setSelectedIconIndex(index)
172+
if (intervalRef.current) {
173+
clearInterval(intervalRef.current)
174+
intervalRef.current = null
175+
}
170176
setTextValue(SERVICE_TEMPLATES[service])
171177
}
172178

@@ -188,6 +194,21 @@ export default function Hero() {
188194
return () => window.removeEventListener('resize', updateVisibleIcons)
189195
}, [])
190196

197+
React.useEffect(() => {
198+
const maxIndex = visibleIconCount - 1
199+
setAutoHoverIndex((i) => Math.min(i, maxIndex))
200+
setLastHoveredIndex((idx) =>
201+
idx !== null ? Math.min(idx, maxIndex) : null
202+
)
203+
setSelectedIconIndex((idx) =>
204+
idx !== null ? Math.min(idx, maxIndex) : null
205+
)
206+
}, [visibleIconCount])
207+
208+
React.useEffect(() => {
209+
if (textValue.trim().length === 0) setSelectedIconIndex(null)
210+
}, [textValue])
211+
191212
/**
192213
* Service icons array for easier indexing
193214
*/
@@ -216,25 +237,20 @@ export default function Hero() {
216237
* Auto-hover animation effect
217238
*/
218239
React.useEffect(() => {
219-
// Start the interval when component mounts
220240
const startInterval = () => {
221241
intervalRef.current = setInterval(() => {
222242
setAutoHoverIndex((prev) => (prev + 1) % visibleIconCount)
223243
}, 2000)
224244
}
225245

226-
// Only run interval when user is not hovering
227-
if (!isUserHovering) {
228-
startInterval()
229-
}
246+
if (selectedIconIndex === null && !isUserHovering) startInterval()
230247

231-
// Cleanup on unmount or when hovering state changes
232248
return () => {
233249
if (intervalRef.current) {
234250
clearInterval(intervalRef.current)
235251
}
236252
}
237-
}, [isUserHovering, visibleIconCount])
253+
}, [selectedIconIndex, isUserHovering, visibleIconCount])
238254

239255
/**
240256
* Handle mouse enter on icon container
@@ -258,11 +274,19 @@ export default function Hero() {
258274
}
259275

260276
const activeIconIndex =
261-
isUserHovering && lastHoveredIndex !== null ? lastHoveredIndex : autoHoverIndex
277+
selectedIconIndex !== null
278+
? selectedIconIndex
279+
: isUserHovering && lastHoveredIndex !== null
280+
? lastHoveredIndex
281+
: autoHoverIndex
282+
const pillTargetIndex = Math.max(
283+
0,
284+
Math.min(activeIconIndex, visibleIconCount - 1)
285+
)
262286

263287
React.useLayoutEffect(() => {
264288
const container = iconRowRef.current
265-
const target = buttonRefs.current[activeIconIndex]
289+
const target = buttonRefs.current[pillTargetIndex]
266290
if (!container || !target) return
267291
const cr = container.getBoundingClientRect()
268292
const tr = target.getBoundingClientRect()
@@ -272,7 +296,7 @@ export default function Hero() {
272296
width: tr.width,
273297
height: tr.height,
274298
})
275-
}, [activeIconIndex, layoutVersion, visibleIconCount])
299+
}, [pillTargetIndex, layoutVersion, visibleIconCount])
276300

277301
React.useEffect(() => {
278302
const onResize = () => setLayoutVersion((v) => v + 1)
@@ -445,7 +469,9 @@ export default function Hero() {
445469
>
446470
<IconButton
447471
aria-label={service.label}
448-
onClick={() => handleServiceClick(service.key as keyof typeof SERVICE_TEMPLATES)}
472+
onClick={() =>
473+
handleServiceClick(index, service.key as keyof typeof SERVICE_TEMPLATES)
474+
}
449475
onMouseEnter={() => setLastHoveredIndex(index)}
450476
style={service.style}
451477
highlightFromParent

0 commit comments

Comments
 (0)