Skip to content

아이콘 ​

레지스트리에 등록된 아이콘 전부를 직접 훑어보고, 이름을 고르는 규칙과 새로 등록하는 방법을 찾아보세요.

아이콘 레지스트리 · Web / Mobile · 진행 중(WIP) · 문서 포맷 시범 적용

Interactive playground ​

packages/components/src/icons.ts에 등록된 아이콘 전부를 렌더한 목록이에요. 이 페이지는 레지스트리를 빌드 시점에 그대로 불러오기 때문에, 새 아이콘을 등록하면 다음 배포에서 이 목록도 자동으로 같이 늘어나요 — 별도로 옮겨 적을 필요가 없습니다.

셀을 클릭하면 이름이 클립보드에 복사돼요. 화면에서는 이 이름을 그대로 $icon('이름')에 넣습니다.

html
<span class="ds-ico w-4 h-4 text-label-normal" x-html="$icon('ic-folder')"></span>
미리보기 크기
194 / 194개

브랜드 자산 (logo-*)

위 아이콘과 달리 currentColor가 아니라 하드코딩 hex(그라디언트 · 워드마크)를 쓰는 예외예요 — 브랜드 규칙 참고.

packages/components/src/icons.ts 레지스트리를 빌드 시점에 그대로 불러와 렌더해요 — 새 아이콘을 등록하면 이 페이지도 다음 배포에서 자동으로 같이 늘어나요(따로 옮겨 적지 않아도 됩니다). 실제 화면에서는 <span class="ds-ico w-4 h-4" x-html="$icon('이름')"></span>처럼 크기·색을 래퍼가 갖는 형태로 씁니다. 크기 토글로 12~24px을 오가며 각 아이콘이 작은 크기에서도 뭉개지거나 획이 너무 가늘어지지 않는지 확인해 보세요 — 굵기는 16px 표시에서 1.33px로 전부 같습니다(ic-spinner만 굵은 링이 목적이라 예외예요). 이 페이지에서 나란히 놓고 보다가 굵기가 5가지로 갈려 있던 걸 찾아 통일했어요.

규칙 (강제) · 코딩 에이전트용

⚠️ 아이콘 토큰·사이즈 스케일은 아직 정리 중입니다. 아래는 지금 지켜야 하는 것입니다.

  • 인라인 <svg> 를 화면에 그리지 않는다 — .ds-ico 래퍼 + $icon('이름') 으로 부른다. 반복 목록의 고정 아이콘은 x-icon="ic-folder"처럼 이름을 직접 지정할 수 있다. 이름·획 굵기가 바뀌는 경우에는 기존 x-html="$icon(...)"을 유지한다. pnpm check:icons(pre-commit blocking)가 새로 추가된 <svg 와 레지스트리에 없는 이름을 막는다(getIcon() 이 "" 를 돌려주므로 오타는 에러 없이 아이콘을 지운다).
  • 크기·색은 래퍼가 갖는다 — w-4 h-4 · text-* 는 래퍼에, 글리프는 currentColor 만 쓴다. .ds-ico 를 빼면 <span> 이 display:inline 이라 크기 유틸이 안 먹고 주입된 <svg> 가 부모를 가득 채운다.
  • 신규 아이콘 스타일은 24px viewBox · 아웃라인 · stroke="currentColor" · stroke-width 2 · round cap/join(스타일 규칙). 굵기 기준은 「16px 표시에서 1.33px」이고, viewBox 가 24 가 아니면 stroke-width = viewBox ÷ 12 로 환산한다. 예외는 ic-spinner 하나뿐.
  • 이름은 ic-{의미}-{형태}-{채움}(이름 규칙). 채움 자리는 fill 일 때만 쓰고 line 은 접미사가 없다. 한 의미에 한 쌍만 둔다.
  • 알림 아이콘은 형태가 심각도를 나눈다(알림 아이콘) — 오류 ic-exclamation-circle(원+!) · 경고 ic-warning(삼각형+!) · 안내 ic-info-circle(원+i). 색만으로 구분하지 말 것.
  • 크기는 viewBox 숫자가 아니라 채움 비율로 맞춘다(크기). 고칠 때는 d 좌표가 아니라 viewBox 를 조정하고, 오차 8% 이내는 손대지 않는다.
  • 같은 LNB 안에서 아이콘을 중복해 쓰지 않는다. LNB ↔ 페이지 헤더 ↔ embed 레지스트리는 같은 화면이면 같은 아이콘을 쓴다.
  • 새 아이콘은 packages/components/src/icons.ts 에 자립형으로 추가하고 pnpm icons:build 로 packages/static/icons/*.svg 파생본을 함께 갱신한다. Tailwind 유틸(class="stroke-white")로 색을 받게 하지 말 것 — 그 문자열을 스캔하지 않은 앱에서는 유틸이 생성되지 않아 아이콘이 단색 원으로 렌더된다.
  • 브랜드 자산(logo-*)은 이 규칙 밖이다 — currentColor 가 아니라 하드코딩 hex(그라디언트·워드마크)를 쓰는 유일한 예외다. 정본은 브랜드 · BI.

단일 출처 ​

packages/components/src/icons.ts — getIcon(name) / hasIcon(name)으로 조회. LNB·PageHeader 등 공유 컴포넌트와 앱 메뉴 설정(lnbConfig, embed 레지스트리)이 이 레지스트리 이름을 사용한다.

사용 규칙 ​

반복 목록에서 이름이 고정된 아이콘은 x-icon을 쓰면 같은 SVG를 문서별로 한 번 파싱하고 각 위치에 복제해요. 값은 자바스크립트 표현식이 아닌 레지스트리 이름이며, 크기·색·애니메이션은 기존처럼 .ds-ico 래퍼가 가져요. x-icon과 x-html은 같은 요소에 함께 쓰지 않아요. pnpm check:icons가 x-icon의 이름도 검사해요.

html
<span class="ds-ico w-4 h-4" x-icon="ic-clock"></span>

아이콘을 새로 그리는 게 아니라 고르는 화면이라면 이 페이지에서 이름을 찾고, 화면 쪽 마크업·크기·색 규칙은 .claude/rules/frontend/design-system-docs.md가 가리키는 CLAUDE.md의 "아이콘은 레지스트리에서" 절이 정본이에요. 요약하면:

  • 인라인 <svg>를 직접 그리지 않고 .ds-ico 래퍼 + $icon('이름')으로 불러온다 (pnpm check:icons가 새로 추가된 인라인 <svg>를 막아요).

  • 크기·색은 래퍼(w-4 h-4, text-*)가 갖고, 글리프 자체는 currentColor만 쓴다 — 위 미리보기의 크기 토글로 각 아이콘이 12~24px 전 구간에서 뭉개지지 않는지 확인할 수 있어요.

  • 새 아이콘을 등록할 땐 packages/components/src/icons.ts에 자립형(스스로 완결된) SVG로 추가하고 pnpm icons:build로 packages/static/icons/*.svg 파생본을 같이 갱신한다.

  • 브랜드 자산(logo-*)은 위 목록 아래 별도 절로 분리돼 있어요 — currentColor가 아니라 하드코딩 hex(그라디언트·워드마크)를 쓰는 유일한 예외라서 나머지 아이콘과 성격이 달라요. 자세한 규칙은 브랜드 문서를 참고하세요.

  • 같은 내비게이션(LNB) 안에서 중복 금지 — 메뉴 식별이 목적. 의미가 동일한 메뉴(예: 섹션이 다른 두 "설정")만 같은 아이콘 허용

  • LNB ↔ 페이지 헤더 ↔ embed 레지스트리 아이콘 일치 — 같은 화면은 어디서든 같은 아이콘

  • 새 아이콘이 필요하면 통상적(관례적) 의미의 형태로 위 스타일 규칙에 맞춰 레지스트리에 추가

스타일 규칙 ​

  • 24px viewBox · 아웃라인 · stroke="currentColor" · stroke-width 2 · round cap/join — 신규 아이콘은 이 스타일을 따른다 (일부 레거시 16px fill 아이콘 존재: ic-workspace, ic-money, ic-user)
  • 굵기 기준은 "16px 표시에서 1.33px"이다 (2026-08-25 개정). 아이콘은 대부분 w-4(16px)로 쓰는데 굵기는 viewBox 좌표계로 적는 값이라, 적은 숫자와 보이는 굵기가 다르다 — 실제 굵기는 stroke-width ÷ viewBox 비율이 정한다. 그래서 24 좌표계의 2가 16px 화면에서 1.33px로 보인다. Heroicons·Lucide도 같은 값이다
  • viewBox가 24가 아니면 비례로 환산한다 — stroke-width = viewBox ÷ 12. 16 → 1.3333, 32 → 2.6667. 숫자만 맞추면 굵기가 어긋나므로 반드시 나눠서 적을 것
  • 예외는 ic-spinner 하나뿐이다(굵은 링이 목적이라 굵기 축 밖)
  • 색은 항상 currentColor — 컨텍스트 텍스트 색을 따르므로 아이콘 자체에 색을 넣지 않는다

이름 규칙 ​

ic-{의미}-{형태}-{채움} 순서로 적고, 채움 자리는 fill일 때만 쓴다 — line 은 접미사가 없다.

linefill
형태가 있는 것ic-info-circleic-info-circle-fill
형태가 없는 것ic-moneyic-money-fill
  • 한 의미에 한 쌍만 둔다. 같은 뜻을 두 이름으로 나눠 두면 화면마다 다른 그림이 뜬다 — 2026-08-25 에 중복이던 ic-info 를 ic-info-circle 로 합쳤다

알림 아이콘은 세 가지다 ​

형태가 심각도를 나눈다. 색(.ds-notice 변형)만으로 구분하지 말 것 — 빨간 상자 안에 안내 기호가 들어가면 톤이 어긋난다.

뜻아이콘모양쓰는 자리
오류ic-exclamation-circle원 + !.ds-notice--danger · 로그인/저장 실패 · 처리 못 한 건수
경고ic-warning삼각형 + !.ds-notice--warning · 조건 미충족 · 데이터 없음 경고
안내ic-info-circle원 + i.ds-notice--info · 툴팁 도움말 · 부가 설명
  • 두 원(ic-exclamation-circle · ic-info-circle)은 같은 원(r=9)에 막대와 점만 상하 반전 한 형제다. 한쪽을 고치면 다른 쪽도 같이 본다
  • 2026-08-26 에 실제로 어긋나 있었다 — 오류 공지 29곳이 안내 기호(ⓘ)를 쓰고 있었다
  • 쌍은 같은 글자로 그린다. ic-info-circle-fill 의 i 가 line 쪽과 다른 모양(눌린 글자 + 이상한 발)이었다. 새 fill 은 line 과 같은 좌표에서 같은 위치·굵기로 그린 뒤 fill-rule="evenodd" 로 안쪽을 파낸다

크기를 맞출 때 보는 값 ​

viewBox 숫자가 아니라 "글리프가 박스를 채우는 비율"을 맞춘다. 둘은 별개다 — 실측(2026-08-26)에서 ic-menu(24↔16)와 ic-refresh(24↔20)는 viewBox 가 달라도 채움 비율이 같아 멀쩡했고, 반대로 viewBox 가 같은 ic-lock(24↔24)이 17% 어긋나 있었다. viewBox 만 보고 판단하면 멀쩡한 쌍을 건드리고 어긋난 쌍은 놓친다.

채움 비율 = (글리프 bbox 최대변 + stroke-width) ÷ viewBox 크기
  • 고치는 방법은 viewBox 조정이다 — d 좌표는 건드리지 않는다. 글리프를 그대로 두고 박스만 넓히거나 좁히면 비율이 바뀌고, path 를 다시 쓰지 않으니 도형이 깨질 위험이 없다. 예: ic-check-circle-fill 은 "0 0 16 16" → "-1.5 -1.5 18 18" 로 박스만 넓혔다
  • 오차 8% 이내는 손대지 않는다. solid 는 같은 크기여도 무겁게 읽혀 원래 조금 작게 그린다 — ic-message(0.91x) · ic-user(0.92x) 는 정상 범위다
  • fill 안쪽의 파낸 마크는 line 의 획보다 얇아도 된다. 검은 바탕 위 흰 영역은 같은 폭이어도 더 두껍게 보이므로(irradiation), 얇게 그린 것이 오히려 맞다. 굵기를 line 에 맞춰 키우지 말 것

변경 이력 ​

날짜내용
2026-06-12LNB 중복 제거용 13종 추가: ic-id-badge ic-file-text ic-table ic-clock ic-sliders ic-calendar-clock ic-calendar-check ic-clock-plus ic-chart-bar ic-tag ic-map-pin ic-gauge ic-list-check