본문 바로가기
Frontend2025년 10월 28일9분 읽기

Radix UI 컴포넌트 커스터마이징 완벽 가이드

YS
김영삼
조회 579

Radix UI Primitives 소개

Radix UI는 접근성(a11y)이 완벽하게 구현된 헤드리스 UI 컴포넌트 라이브러리입니다. 스타일이 전혀 없어서 완전한 디자인 자유도를 제공하면서도, WAI-ARIA 패턴을 모두 준수합니다.

Dialog 컴포넌트 커스터마이징

import * as Dialog from '@radix-ui/react-dialog';
import { X } from 'lucide-react';

export function Modal({ trigger, title, children }) {
  return (
    <Dialog.Root>
      <Dialog.Trigger asChild>
        {trigger}
      </Dialog.Trigger>

      <Dialog.Portal>
        <Dialog.Overlay className="fixed inset-0 bg-black/50
          data-[state=open]:animate-in data-[state=open]:fade-in-0
          data-[state=closed]:animate-out data-[state=closed]:fade-out-0"
        />
        <Dialog.Content className="fixed left-1/2 top-1/2
          -translate-x-1/2 -translate-y-1/2
          w-full max-w-lg rounded-xl bg-white p-6 shadow-xl
          data-[state=open]:animate-in data-[state=open]:fade-in-0
          data-[state=open]:zoom-in-95">
          <Dialog.Title className="text-lg font-semibold">
            {title}
          </Dialog.Title>
          <div className="mt-4">{children}</div>
          <Dialog.Close asChild>
            <button className="absolute right-4 top-4 rounded-sm
              opacity-70 hover:opacity-100" aria-label="닫기">
              <X className="h-4 w-4" />
            </button>
          </Dialog.Close>
        </Dialog.Content>
      </Dialog.Portal>
    </Dialog.Root>
  );
}

Select 컴포넌트

import * as Select from '@radix-ui/react-select';
import { ChevronDown, Check } from 'lucide-react';

export function CustomSelect({ options, placeholder, value, onChange }) {
  return (
    <Select.Root value={value} onValueChange={onChange}>
      <Select.Trigger className="inline-flex items-center justify-between
        rounded-lg border border-gray-300 px-3 py-2 text-sm
        hover:border-gray-400 focus:outline-none focus:ring-2
        focus:ring-blue-500 min-w-[200px]">
        <Select.Value placeholder={placeholder} />
        <Select.Icon>
          <ChevronDown className="h-4 w-4 opacity-50" />
        </Select.Icon>
      </Select.Trigger>

      <Select.Portal>
        <Select.Content className="overflow-hidden rounded-lg border
          bg-white shadow-lg
          data-[state=open]:animate-in data-[state=open]:fade-in-0
          data-[state=open]:zoom-in-95">
          <Select.Viewport className="p-1">
            {options.map((opt) => (
              <Select.Item key={opt.value} value={opt.value}
                className="relative flex cursor-pointer items-center
                rounded-md py-2 pl-8 pr-4 text-sm outline-none
                data-[highlighted]:bg-blue-50 data-[highlighted]:text-blue-700">
                <Select.ItemIndicator className="absolute left-2">
                  <Check className="h-4 w-4" />
                </Select.ItemIndicator>
                <Select.ItemText>{opt.label}</Select.ItemText>
              </Select.Item>
            ))}
          </Select.Viewport>
        </Select.Content>
      </Select.Portal>
    </Select.Root>
  );
}

Tooltip 컴포넌트

import * as Tooltip from '@radix-ui/react-tooltip';

export function TooltipWrapper({ children, content, side = 'top' }) {
  return (
    <Tooltip.Provider delayDuration={200}>
      <Tooltip.Root>
        <Tooltip.Trigger asChild>
          {children}
        </Tooltip.Trigger>
        <Tooltip.Portal>
          <Tooltip.Content side={side} sideOffset={5}
            className="z-50 rounded-md bg-gray-900 px-3 py-1.5
            text-xs text-white shadow-md
            animate-in fade-in-0 zoom-in-95">
            {content}
            <Tooltip.Arrow className="fill-gray-900" />
          </Tooltip.Content>
        </Tooltip.Portal>
      </Tooltip.Root>
    </Tooltip.Provider>
  );
}

data 속성 기반 스타일링

data 속성Tailwind 클래스의미
data-state="open"data-[state=open]:...열린 상태
data-state="closed"data-[state=closed]:...닫힌 상태
data-highlighteddata-[highlighted]:...키보드/마우스 포커스
data-disableddata-[disabled]:...비활성 상태
  • Radix UI는 shadcn/ui의 기반 라이브러리이기도 합니다
  • asChild prop으로 트리거 요소를 커스텀 컴포넌트로 대체할 수 있습니다
  • 키보드 네비게이션, 스크린 리더 지원이 기본 내장되어 있습니다
  • 포커스 트랩, ESC 닫기, 외부 클릭 닫기 등 인터랙션 패턴이 완성되어 있습니다

Radix UI는 "접근성은 완벽하게, 스타일은 자유롭게"라는 철학을 실현한 라이브러리입니다. Tailwind CSS와 결합하면 빠르게 고품질 커스텀 UI를 만들 수 있습니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록