22
33import { useMemo , useState } from 'react'
44import { INTEGRATION_METADATA } from '@sim/deployment-config/integration-metadata'
5- import { ArrowRight , ChevronDown , cn , Expandable , ExpandableContent , OverflowText } from '@sim/emcn'
5+ import { ArrowRight , cn , OverflowText } from '@sim/emcn'
66import { Table } from '@sim/emcn/icons'
77import { stripVersionSuffix } from '@sim/utils/string'
88import { useParams } from 'next/navigation'
99import { usePostHog } from 'posthog-js/react'
10+ import { HomeSection } from '@/components/home/home-section'
1011import { GmailIcon , SlackIcon } from '@/components/icons'
1112import {
1213 resolveOAuthServiceForIntegration ,
@@ -317,65 +318,36 @@ export function SuggestedActions({ onSelectPrompt }: SuggestedActionsProps) {
317318 }
318319
319320 return (
320- < div className = 'group/suggested mx-auto mt-7 w-full max-w-chat' >
321- { /* Full width so the whole line toggles, not just the label and chevron. */ }
322- < button
323- type = 'button'
324- onClick = { handleToggleExpanded }
325- aria-expanded = { expanded }
326- className = 'group/toggle flex w-full cursor-pointer items-center gap-2'
321+ < >
322+ < HomeSection
323+ title = 'Suggested actions'
324+ expanded = { expanded }
325+ animationsEnabled = { animationsEnabled }
326+ onToggle = { handleToggleExpanded }
327327 >
328- < span className = 'text-[var(--text-muted)] text-caption' > Suggested actions</ span >
329- { /*
330- * Revealed by hovering anywhere in the section — the group sits on the
331- * section wrapper rather than this row, so the action rows below arm it just
332- * as the header does. Focus is keyed off the toggle instead, the only element
333- * here that can hold it, and matters because globals clear focus outlines.
334- * One transition covers the fade and the rotation so the two cannot drift
335- * apart. Mirrors the sidebar's section headers.
336- */ }
337- < ChevronDown
338- className = { cn (
339- 'size-[14px] shrink-0 text-[var(--text-icon)] opacity-0 transition-[opacity,transform] duration-150' ,
340- 'group-hover/suggested:opacity-100 group-focus-visible/toggle:opacity-100' ,
341- ! expanded && '-rotate-90'
342- ) }
343- />
344- </ button >
345- < Expandable expanded = { expanded } >
346- < ExpandableContent className = { cn ( ! animationsEnabled && 'animate-none!' ) } >
347- { /* 6px, matching a sidebar section header to its first item — both headers
348- are an 18px box around 12px text, so equal padding reads as equal
349- distance. Padding an inner wrapper rather than the animated element:
350- `collapsible-up`/`-down` interpolate height alone, so a margin here
351- would hold its full value through the close and then vanish on unmount,
352- snapping the content below up. */ }
353- < div className = 'flex flex-col pt-1.5' >
354- { actions . map ( ( action , i ) => {
355- const Icon = action . icon
356- return (
357- < button
358- key = { action . id }
359- type = 'button'
360- onClick = { ( ) => handleSelect ( action , i ) }
361- className = { cn (
362- 'flex items-center gap-2 border-[var(--border)] px-2 py-2 text-left transition-colors hover-hover:bg-[var(--surface-5)]' ,
363- i > 0 && 'border-t'
364- ) }
365- >
366- < BrandIcon icon = { Icon } className = 'size-[16px] shrink-0' />
367- < OverflowText
368- label = { action . label }
369- className = 'flex-1 text-[var(--text-body)] text-sm'
370- focusTarget = 'nearest-interactive'
371- />
372- < ArrowRight className = 'size-[16px] shrink-0 text-[var(--text-icon)]' />
373- </ button >
374- )
375- } ) }
376- </ div >
377- </ ExpandableContent >
378- </ Expandable >
328+ { actions . map ( ( action , i ) => {
329+ const Icon = action . icon
330+ return (
331+ < button
332+ key = { action . id }
333+ type = 'button'
334+ onClick = { ( ) => handleSelect ( action , i ) }
335+ className = { cn (
336+ 'flex items-center gap-2 border-[var(--border)] px-2 py-2 text-left transition-colors hover-hover:bg-[var(--surface-5)]' ,
337+ i > 0 && 'border-t'
338+ ) }
339+ >
340+ < BrandIcon icon = { Icon } className = 'size-[16px] shrink-0' />
341+ < OverflowText
342+ label = { action . label }
343+ className = 'flex-1 text-[var(--text-body)] text-sm'
344+ focusTarget = 'nearest-interactive'
345+ />
346+ < ArrowRight className = 'size-[16px] shrink-0 text-[var(--text-icon)]' />
347+ </ button >
348+ )
349+ } ) }
350+ </ HomeSection >
379351 { oauthTarget && workspaceId && (
380352 < ConnectOAuthModal
381353 mode = 'connect'
@@ -391,6 +363,6 @@ export function SuggestedActions({ onSelectPrompt }: SuggestedActionsProps) {
391363 serviceIcon = { oauthTarget . serviceIcon }
392364 />
393365 ) }
394- </ div >
366+ </ >
395367 )
396368}
0 commit comments