Skip to main content

Overview

The DropDown component is a reusable accordion UI element that displays a question/heading with two collapsible answer sections. It’s used by the Ethos component to create an interactive philosophy section.

Props Interface

src/components/DropDown.tsx
interface DropDownProps {
  question: string;
  answer1: string;
  answer2: string;
  isExpanded: boolean;
}
question
string
required
The main heading text that’s always visible (e.g., an investment principle)
answer1
string
required
First supporting detail revealed when expanded
answer2
string
required
Second supporting detail revealed when expanded
isExpanded
boolean
required
Controls the expanded/collapsed state. When true, shows the answer sections with a scale-in animation.

Visual States

The component has two distinct visual states:
  • Background opacity: 10%
  • Plus icon (+) displayed
  • Answer sections scaled to 0 height
  • Only question text visible

Animation Behavior

// Transition properties
transition-all origin-top duration-500 ease-in-out

// Collapsed state
scale-y-0 max-h-0

// Expanded state
scale-y-100 max-h-28 // 7rem = 112px
The component uses a vertical scale transform with origin-top for a smooth accordion effect. The 500ms ease-in-out transition creates a professional reveal animation.

Usage Example

From Ethos.tsx:
import DropDown from '@/components/DropDown';
import { useState } from 'react';

function Ethos() {
  const [active, setActive] = useState(0);

  return (
    <div>
      {/* First principle */}
      <button onClick={() => setActive(active === 1 ? 0 : 1)}>
        <DropDown 
          question="We often write the first check to visionaries who act with urgency."
          answer1="We back founders with original insights, technical acumen, and insatiable ambition."
          answer2="Well before their founder journeys begin, we build deep-rooted, long-term relationships with product artisans who build with intention."
          isExpanded={active === 1}
        />
      </button>

      {/* Second principle */}
      <button onClick={() => setActive(active === 2 ? 0 : 2)}>
        <DropDown 
          question="We partner with emerging category-defining leaders that endure."
          answer1="We invest in N-of-1 companies that marry defensible technology with novel go-to-market."
          answer2="Many create new markets or reimagine legacy industries through robust software, delightful UX, and superior incentives."
          isExpanded={active === 2}
        />
      </button>
    </div>
  );
}
The parent component manages which accordion is open via the active state. Only one can be expanded at a time - clicking the active item collapses it, clicking an inactive item opens it.

Styling

Background & Layout

The component uses:
  • Dark green background with opacity-based states
  • Full width container with rounded corners (rounded-lg)
  • Responsive padding: px-6 py-3 xl:py-4 2xl:py-8
  • Minimum height scales with breakpoint: lg:min-h-16 xl:min-h-24 2xl:min-h-28

Typography

Question (heading):
  • font-semibold
  • Responsive sizes: lg:text-b3xs xl:text-bxs 2xl:text-bsm
Answers (details):
  • Left-aligned text
  • Responsive sizes: lg:text-b4xs xl:text-b2xs 2xl:text-bxs
  • Scrollable when content exceeds max height

Icon Toggle

<img 
  src={isExpanded ? '/images/x.svg' : '/images/plus.svg'} 
  alt={isExpanded ? 'x' : '+'} 
  className='lg:h-4 lg:w-4 xl:h-8 xl:w-8 2xl:h-10 2xl:w-10' 
/>

Responsive Design

The component adapts across three main breakpoints:
BreakpointText SizePadding YMin HeightIcon Size
lg (1024px)b3xs / b4xs3 (0.75rem)16 (4rem)4 (1rem)
xl (1440px)bxs / b2xs4 (1rem)24 (6rem)8 (2rem)
2xl (1920px)bsm / bxs8 (2rem)28 (7rem)10 (2.5rem)

Accessibility Considerations

The component is wrapped in a <button> by its parent, which is good for keyboard navigation. However, the inner structure also uses a <button> element, creating nested buttons which is invalid HTML.Recommendation: Change the outer wrapper in the source to a <div> and add proper ARIA attributes:
<div 
  role="button" 
  tabIndex={0}
  onClick={() => setActive(...)}
  onKeyDown={(e) => e.key === 'Enter' && setActive(...)}
>
  <DropDown {...props} />
</div>

Integration Points

This component is used exclusively by the Ethos component to display Sunflower Capital’s four investment principles. Each principle gets its own DropDown instance with unique question and answer content.

Ethos Component

See how DropDown is integrated into the philosophy section

Custom Animations

Learn about the scale-y animation pattern

Build docs developers (and LLMs) love