MeDo

AI 탭 생성기.

패널을 설명하면 MeDo가 완전한 탭 컴포넌트를 생성합니다 — 올바른 ARIA 역할, 화살표 키 내비게이션, 애니메이션 활성 인디케이터, 모바일 오버플로 처리, 그리고 URL과 동기화되어 새로고침 후에도 유지되는 활성 탭까지.

탭

탭은 스타일 결정으로 위장한 라우팅 결정입니다

탭 세트는 단순히 콘텐츠를 숨기는 것이 아니라, 하나의 URL을 공유하는 여러 뷰로 페이지를 나눕니다. 누군가 요금 탭을 공유하거나 지원 문서에서 링크하거나 위치를 잃지 않고 새로고침하려는 순간, 컴포넌트는 React 외부에 존재하는 실제 상태가 필요해집니다. 팀은 보통 탭을 출시한 뒤에야 이를 발견하고, 애니메이션과 초기 렌더링과 충돌하는 쿼리 문자열 처리를 나중에 덧붙입니다. 활성 탭을 로컬 상태가 아니라 URL에서 파생시키기로 처음부터 정하면 컴포넌트 전체가 단순해집니다. 트리거는 링크에 가까운 동작이 되고, 딥링크는 자연히 작동하며, 서버 렌더링이 첫 페인트에 올바른 패널을 만들어 냅니다. 마크업을 작성하는 방식 자체도 달라지기 때문에, 나중에 개조하는 것보다 처음부터 그렇게 생성하는 편이 훨씬 저렴합니다.

템플릿 6개

생성할 수 있는 탭 템플릿

모든 템플릿은 스크린샷이 아니라 실제 프롬프트입니다. 어떤 AI 에디터에든 붙여넣거나 MeDo에서 실행해 React + Tailwind 코드를 그대로 받으세요.

BasicUnderline

Underlined Tab Row With a Sliding Indicator

The default that reads as tabs without any explanation. Reach for it when the panels are static content and you want the indicator to do the signalling rather than a border box.

Create a tabs component with four triggers using the ARIA tabs pattern: role="tablist" on the container, role="tab" with aria-selected and aria-controls on each trigger, and role="tabpanel" with aria-labelledby on each panel. Use roving tabindex so only the selected tab has tabindex 0 and Tab moves out of the group entirely rather than through it. Left and Right arrows move focus and wrap at both ends, Home and End jump to the first and last tab, and activation is automatic because the panels are static text. Triggers are 40px tall with 15px medium labels, muted grey when inactive and near-black when active. Measure the active trigger and slide a 2px underline using translateX and scaleX over 200ms — never animate left or width.

MeDo에서 시도하기
SegmentedPill Segmented

Segmented Control With a Sliding Pill

Two or three mutually exclusive options that belong on one control, like monthly versus annual. Do not use it past four tabs — the track stops fitting on a phone and equal widths force truncation.

Create a segmented-control tabs component: one rounded 36px-tall track with a light grey background and 2px inner padding, holding three equal-width triggers. The active trigger is a white pill with a soft shadow that moves between positions with translateX over 180ms, so the label text never reflows mid-transition. Keep the full ARIA tabs roles and roving tabindex — Left and Right arrows move focus with wrapping, Home and End jump to the ends, and activation is automatic. Give every trigger the same explicit min-width so switching from a short label to a long one does not resize the track. Under prefers-reduced-motion, cross-fade the pill background instead of sliding it.

MeDo에서 시도하기
Deep linkableURL-Synced

Tabs Backed by a Query Parameter

The active tab lives in the URL, so support can link to one panel and a reload keeps your place. Worth doing before launch, because retrofitting it means rewriting the initial render.

Create a tabs component whose active tab is derived from a ?tab= query parameter rather than local state, so the first server render already paints the correct panel with no post-hydration flash. Read the parameter, validate it against the known tab ids, and fall back to the first tab when the value is unrecognised. On selection, write the new value with a replace-style navigation so the back button is not filled with tab switches, and preserve every other query parameter already on the URL. Keep the ARIA tabs wiring intact: roving tabindex, Left and Right arrows with wrapping, Home and End, and manual activation on Enter or Space.

MeDo에서 시도하기
OverflowScrollable

Horizontally Scrolling Tablist

What happens when seven labels meet a 390px viewport. The part teams forget is scrolling the newly focused tab into view — arrow keys otherwise move focus to a tab nobody can see.

Create a tabs component that handles overflow by scrolling rather than wrapping or clipping. Under 640px the tablist scrolls horizontally with momentum, the scrollbar is hidden, and a gradient fade appears on either edge only while content remains in that direction. When Left or Right arrow moves the roving tabindex, call scrollIntoView with inline nearest on the newly focused trigger so keyboard focus is never off screen, and do the same for Home and End. Use scroll-snap-align on each trigger so a flick settles on a label boundary instead of mid-word. Keep the full ARIA roles and aria-controls wiring, and recompute the indicator position on scroll and on resize.

MeDo에서 시도하기
PerformanceLazy Panels

Tabs With Deferred Panel Mounting

Only the active panel mounts, so opening Settings does not fetch invoices nobody asked for. The catch is state loss, so name the panels that must survive a switch.

Create a tabs component that mounts only the active panel and keeps every inactive panel out of the DOM entirely, so charts, video players and data fetches for unseen tabs never run. Use manual activation — arrow keys move the roving tabindex and only Enter or Space commits the change — because automatic activation would fire a request for every tab a keyboard user passes through. Accept a keepMounted list of tab ids whose panels stay in the DOM hidden with the hidden attribute instead, for panels holding half-filled forms or scroll position. Show a skeleton inside a newly mounted panel while its data resolves, and keep the panel container height stable so the page below does not jump.

MeDo에서 시도하기
SidebarVertical

Vertical Tabs for Settings Screens

A left rail of labels beside one panel. The one thing that changes beyond layout is the arrow axis — Up and Down, not Left and Right, and aria-orientation has to say so.

Create a vertical tabs component for a settings screen: a 200px left rail of triggers with a single panel to its right. Set aria-orientation="vertical" on the tablist and bind Arrow Up and Arrow Down to move the roving tabindex with wrapping, since Left and Right are wrong on this axis; keep Home and End for the ends. Triggers are left-aligned rows, 36px tall, with a 2px indicator on the left edge that translates vertically over 200ms. Below 768px collapse the rail into a horizontal scrolling tablist above the panel and switch the arrow bindings and aria-orientation to match. Use manual activation, and give the panel tabindex="-1" so a programmatic focus move after selection is possible.

MeDo에서 시도하기

탭 커스터마이즈 방법

자동 활성화와 수동 활성화를 의도적으로 선택하세요

자동 활성화는 화살표 키로 포커스가 이동할 때마다 패널을 전환합니다. 빠르지만 패널의 렌더링 비용이 크거나 데이터를 가져올 때는 쓸 수 없습니다. 수동 활성화는 포커스만 먼저 옮기고 Enter 또는 Space에서만 활성화합니다. 키보드 처리 코드가 달라지므로 어느 쪽을 원하는지 명시하세요.

인디케이터는 width가 아닌 transform으로 애니메이션하세요

활성 트리거를 측정해 translateX와 scaleX로 이동하는 밑줄을 요청하세요. left와 width를 애니메이션하면 매 프레임마다 레이아웃이 재계산되고 서브픽셀 경계에서 떨리며, tablist가 스크롤 가능해지면 완전히 깨집니다.

탭이 넘칠 때의 동작을 결정하세요

짧은 라벨 4개는 휴대폰에 들어가지만 7개는 들어가지 않습니다. 하나의 동작을 골라 명시하세요. 가장자리를 페이드한 가로 스크롤 tablist, 두 번째 줄로 줄바꿈, 또는 특정 브레이크포인트 아래에서 네이티브 select로 접는 방식입니다. 지정하지 않으면 생성된 탭은 대개 그냥 잘립니다.

비활성 패널을 마운트 상태로 둘지 알려주세요

비활성 패널을 언마운트하면 DOM이 작게 유지되고 아무도 보지 않는 차트나 비디오 플레이어가 돌아가는 것을 막지만, 스크롤 위치와 절반쯤 입력한 폼 필드도 함께 버려집니다. 상태를 보존해야 하는 패널을 알려주면 그 패널은 대신 CSS로 숨겨집니다.

탭 컴포넌트를 사용하는 사람

요금 페이지

월간과 연간 결제를 하나의 가격 표 위에 두 개의 탭으로 배치하고, 선택을 URL에 기록해 영업이 연간 요금으로 바로 링크할 수 있고 연간 할인이 첫 로드에서 보이도록 합니다.

제품 문서

curl, Node, Python, Go 등 언어별로 나뉜 코드 샘플. 언어를 한 번 선택하면 페이지의 모든 탭 그룹에 적용되고 다음 방문에도 기억됩니다.

대시보드 또는 관리자 도구

프로필, 팀, 결제, API 키 탭이 있는 설정 화면으로, 각 패널이 지연 마운트되어 설정을 여는 것만으로 아무도 요청하지 않은 인보이스를 가져오지 않습니다.

이커머스 상품 페이지

갤러리 아래에 설명, 사양, 리뷰를 탭으로 배치하고 트리거 라벨에 리뷰 수를 표시하며, 설명은 페이지 본문에도 렌더링해 핵심 문구가 탭 뒤에서만 접근 가능하지 않도록 합니다.

웹사이트 유형별 탭 패턴

같은 탭 컴포넌트를 게시되는 사이트 유형에 맞춰 조정합니다.

01 / 06

SaaS Pricing Page Tabs

Monthly and annual billing as a two-tab segmented control above one price grid. Sync the choice to the URL so a sales email can open annual pricing directly — a pricing page where the discount is one unshareable click away is losing the conversation before it starts.

탭 스타일과 변형

페이지의 나머지 부분과 어울리는 변형을 골라 바로 생성하세요.

01 / 06

Underlined Tabs

A muted label row with a 2px indicator sliding beneath the active trigger. The most legible default because the underline gives the eye a single moving object to track. Animate it with translateX and scaleX — animating left and width thrashes layout every frame and jitters on subpixel boundaries.

React, Next.js, Vue, Svelte에서의 탭

React, Next.js, Vue 3, SvelteKit, Astro 또는 순수 HTML — 같은 탭을 여섯 가지 방식으로 넣을 수 있습니다.

01 / 06

React Tabs

Keep the selected id in one piece of state and derive tabindex from it — that is the whole roving tabindex mechanism. Hold refs to the triggers so the arrow handler can focus the next one directly.

src/components/Tabs.tsx

const [active, setActive] = useState(tabs[0].id)

<div role="tablist" onKeyDown={onArrowKeys}>
  {tabs.map((t) => (
    <button
      key={t.id}
      role="tab"
      aria-selected={t.id === active}
      aria-controls={`panel-${t.id}`}
      tabIndex={t.id === active ? 0 : -1}
      onClick={() => setActive(t.id)}
    >
      {t.label}
    </button>
  ))}
</div>

탭을 프로젝트에 추가하는 방법

탭 템플릿을 고르고 프로덕션에 배포하기까지 네 단계.

01~30s

Pick a Tabs Template

Choose by constraint, not by looks: segmented for two or three alternatives, scrollable once labels overflow a phone, vertical for a long settings rail, lazy when a panel fetches data.

02~10s

Copy the Prompt

Take the prompt into MeDo, Lovable, Bolt, v0 or Cursor, then edit two things — your real tab labels, and whether activation is automatic or manual. That second choice changes the keyboard code, so decide it before you generate.

03~1min

Generate and Refine

You get React + Tailwind back with a live preview. Follow up in plain English — "sync the active tab to ?tab=", "collapse to a select under 640px", "keep the chart panel mounted" — rather than editing the keydown handler by hand.

04~2min

Wire the Panels and Ship

Replace the placeholder panels with your real content and check three things with the keyboard only: Tab enters and leaves the group in one stop, arrows move within it, and a reload on a deep link opens the right panel.

탭에 대한 자주 묻는 질문

AI로 접근성 있는 탭 컴포넌트를 생성하는 방법은?

탭 라벨과 원하는 동작을, 활성화가 자동인지 수동인지까지 포함해 하나의 프롬프트로 설명하세요. MeDo는 tablist, tab, tabpanel 역할을 대응하는 aria-controls 및 aria-labelledby 연결과 함께 생성하고, roving tabindex를 적용해 화살표 키로 탭 사이를 이동하고 Tab 키로는 그룹 전체를 벗어나게 합니다.

자동 탭 활성화와 수동 탭 활성화의 차이는?

자동 활성화에서는 화살표 키로 포커스를 옮기는 즉시 해당 패널이 표시되어 가벼운 정적 콘텐츠에 적합합니다. 수동 활성화에서는 화살표 키가 포커스만 옮기고 사용자가 Enter 또는 Space로 확정합니다. 패널이 데이터를 가져오거나 차트를 그리거나 그 밖에 느린 경우에는 항상 수동을 사용하세요. 자동이라면 키보드 사용자가 지나치는 모든 탭마다 요청이 발생합니다.

특정 탭으로 바로 링크할 수 있나요?

네, 활성 탭이 컴포넌트 상태가 아니라 URL에 저장되어 있다면 가능합니다. ?tab=pricing 같은 쿼리 파라미터로 초기 렌더링을 결정하고 replace 방식 내비게이션으로 갱신하도록 요청하면 뒤로 가기 기록이 탭 전환으로 가득 차지 않습니다. 이 용도로 해시 프래그먼트는 피하세요. 브라우저가 같은 id를 가진 요소로 스크롤하려 하기 때문입니다.

비활성 탭에 숨겨진 콘텐츠가 SEO에 해로운가요?

검색 엔진은 패널이 시각적으로 숨겨져 있어도 HTML에 존재하는 텍스트를 인덱싱하므로 탭 콘텐츠가 보이지 않는 것은 아닙니다. 다만 방문자가 즉시 보는 콘텐츠보다 부차적으로 평가되는 것이 일반적이고, 클릭 후에만 렌더링되는 패널은 아예 크롤링되지 않을 수도 있습니다. 주요 제목, 가치 제안, 타깃 키워드는 항상 보이는 영역에 두고 탭은 보조 세부 정보에 사용하세요.

모바일에서 탭은 어떻게 동작해야 하나요?

라벨을 줄이는 대신 하나의 전략을 선택하세요. 넘치는 가장자리를 페이드 처리한 가로 스크롤 tablist는 짧은 라벨 여섯 개 정도까지 잘 작동합니다. 그 이상이면 네이티브 select로 접는 편이 터치 영역이 크고 숨겨진 탭도 생기지 않습니다. MeDo에 브레이크포인트와 전략을 알려주면 하나의 컴포넌트에서 두 레이아웃을 모두 생성합니다.

탭을 써야 할까요, 아코디언을 써야 할까요?

결제 주기나 코드 언어처럼 사용자가 한 번에 하나씩 비교하는 대안이 패널이고, 라벨이 한 줄에 들어갈 만큼 짧을 때는 탭을 쓰세요. 섹션이 독립적인 항목이라 동시에 여러 개를 열어두고 싶을 때, 라벨이 완전한 질문 문장일 때, 또는 내용이 길어 세로로 쌓는 편이 읽기 좋을 때는 아코디언을 쓰세요. FAQ 목록은 아코디언의 대표 사례이며 탭의 사례가 아닙니다.