Files
Gnuboard7/docs/frontend/dark-mode.md
T
HeuJung 8328b1db77 docs(core,extensions): 확장 개발자 문서 9세트 집필과 생성기 정합 보강
S1 파일럿 3종(sirsoft-board · sirsoft-gdpr · sirsoft-admin_basic)에 이어
결제·본인인증 동형군 6종의 AGENTS.md · README.md · docs/ 5문서를 집필했다.
확장을 고치려는 쪽이 매번 src/ 를 훑어 구조를 재발견하지 않도록, 설계 의도와
확장점(발행·구독 훅)·수정 시 동반 의무·금지 패턴을 코드 근거로 서술했다.

생성기(ExtensionDocScaffolder)에서 표를 무의미하게 만들던 세 결함을 함께 고쳤다.
getLayoutExtensions 기본 구현이 돌려주는 절대경로가 파일 목록과 중복돼 로컬
머신 경로가 커밋 문서에 실리던 문제, getNotificationDefinitions 를 'key'/'event'
로 읽어 모든 행이 '-' 로 찍히던 문제, getSettingsLayout 절대경로가 정규화 없이
노출되던 문제다. 셋 다 예외를 남기지 않고 표만 조용히 망가뜨리므로
ExtensionDocContractTest 에 각각의 되돌림 red 를 확인한 단언을 두었다.
템플릿의 extensions/{id}/ 는 모듈·플러그인의 발행과 반대 방향(오버라이드)이라
별도 블록(template-overrides)으로 분리했다.

sirsoft-admin_basic 의 컴포넌트·핸들러·레이아웃 문서를 코어 docs/ 에서 그 템플릿
소유로 이관하고, 남은 참조 6축을 재는 가드를 추가했다. 이관 후 남은 옛 경로는
오류가 아니라 헛걸음으로만 나타나 드러나지 않는다. 의 상대 링크가
한 단계 얕아 공유 docs/ 대신 를 가리키던 문제도 함께 고쳤다.

README 상단의 확장명 이미지 배지를 평문 H1 로 바꿨다( 지시 2026-08-31).
루트 README.md · README.ko.md 도 같은 기준을 적용했다. 정보 배지는 유지한다.

sirsoft-gdpr: 회원탈퇴로 자동 철회된 동의가 관리자 동의 이력 화면의 출처 필터로
걸러지지 않던 문제를 고쳤다. Repository 가 'withdraw' 리터럴을 직접 UPDATE 에
싣는데 그 값이 ConsentSource enum 에 없어, 화면 필터 옵션·라벨 어느 쪽에도
도달하지 못했다. 어휘를 enum 단일 출처로 모으고 ko·en·ja 라벨과 필터 옵션을
함께 채웠으며, 어휘 대조 테스트의 모집단에 Repository 를 편입했다.
2026-08-31 15:57:44 +09:00

8.7 KiB

다크 모드 지원 (engine-v1.1.0+)

상위 문서: 프론트엔드 가이드 인덱스

그누보드7 템플릿 시스템은 Tailwind CSS dark mode variant를 활용하여 다크 모드를 전면 지원합니다.


TL;DR (5초 요약)

1. Tailwind dark: variant 사용 (예: bg-white dark:bg-gray-800)
2. 배경: bg-white dark:bg-gray-800/900
3. 텍스트: text-gray-900 dark:text-white
4. 테두리: border-gray-200 dark:border-gray-700
5. 항상 light/dark 쌍으로 지정 필수!

템플릿별 지원 현황

템플릿 식별자 features.dark_mode 설명
sirsoft-admin_basic 미선언 ThemeToggle 존재, dark: variant 동작
sirsoft-basic true template.json에 선언, 완전 지원

상세 컴포넌트 목록: sirsoft-admin_basic, sirsoft-basic


목차

  1. 다크 모드 설정
  2. 컴포넌트 다크 모드 적용 규칙
  3. 컴포넌트 개발 예시
  4. 레이아웃 JSON에서 다크 모드 사용
  5. ThemeToggle 컴포넌트
  6. 기존 컴포넌트 재사용 이점
  7. 컴포넌트 개발 체크리스트
  8. 테스트 요구사항
  9. 주의사항
  10. 참고 자료

1. 다크 모드 설정

main.css에 다크 모드 variant 정의:

@variant dark (.dark &);

동작 원리:

  • document.documentElement.classList.add('dark'): 다크 모드 활성화
  • document.documentElement.classList.remove('dark'): 라이트 모드 활성화
  • Tailwind CSS가 .dark 클래스 감지하여 dark: variant 적용

2. 컴포넌트 다크 모드 적용 규칙

모든 composite 및 layout 컴포넌트는 다크 모드를 지원해야 합니다.

핵심 규칙

주의: 다크 모드 전용 색상만 하드코딩 금지 (예: border-gray-700만 사용)
필수: light와 dark variant 항상 함께 지정
✅ 필수: 기존 색상 매핑 규칙 준수
✅ 필수: Tailwind CSS 유틸리티 클래스 사용

색상 매핑 규칙

Light 모드 Dark 모드 용도
bg-white dark:bg-gray-800 카드, 모달, 드롭다운 배경
bg-gray-50 dark:bg-gray-700 헤더, 서브 배경
bg-gray-100 dark:bg-gray-700 호버 배경
border-gray-200 dark:border-gray-700 주요 테두리
border-gray-300 dark:border-gray-600 입력 필드 테두리
text-gray-900 dark:text-white 제목, 중요 텍스트
text-gray-700 dark:text-gray-300 본문 텍스트
text-gray-600 dark:text-gray-400 보조 텍스트
text-gray-400 dark:text-gray-500 비활성화, 플레이스홀더

투명도 표현

색상 강조가 필요하지만 너무 진하지 않아야 할 경우 /20 투명도 사용:

// ✅ DO: 투명도로 강조 색상 표현
'bg-green-50 dark:bg-green-900/20'
'text-green-700 dark:text-green-400'
'border-green-200 dark:border-green-800'

// Success 상태
'bg-green-50 dark:bg-green-900/20 text-green-700 dark:text-green-400'

// Warning 상태
'bg-yellow-50 dark:bg-yellow-900/20 text-yellow-700 dark:text-yellow-400'

// Error 상태
'bg-red-50 dark:bg-red-900/20 text-red-700 dark:text-red-400'

액센트 색상

브랜드 색상(blue, red 등)은 다크 모드에서 약간 밝게 조정:

// Primary 버튼
'bg-blue-600 dark:bg-blue-500'
'hover:bg-blue-700 dark:hover:bg-blue-600'

// 링크 텍스트
'text-blue-600 dark:text-blue-400'

// 테두리
'border-blue-600 dark:border-blue-400'

3. 컴포넌트 개발 예시

올바른 예

// ✅ DO: 다크 모드 지원
import { Div } from '../basic/Div';
import { H2 } from '../basic/H2';
import { P } from '../basic/P';

export const Card: React.FC<CardProps> = ({ title, content }) => {
  return (
    <Div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-4">
      <H2 className="text-gray-900 dark:text-white font-bold mb-2">
        {title}
      </H2>
      <P className="text-gray-600 dark:text-gray-400">
        {content}
      </P>
    </Div>
  );
};

잘못된 예

// ❌ DON'T: 다크 모드 미지원
export const Card: React.FC<CardProps> = ({ title, content }) => {
  return (
    <Div className="bg-white border border-gray-200 rounded-lg p-4">
      <H2 className="text-gray-900 font-bold mb-2">{title}</H2>
      <P className="text-gray-600">{content}</P>
    </Div>
  );
};

// ❌ DON'T: 다크 모드 전용 색상만 하드코딩
export const Card: React.FC<CardProps> = ({ title, content }) => {
  return (
    <Div className="bg-gray-800 border border-gray-700 rounded-lg p-4">
      <H2 className="text-white font-bold mb-2">{title}</H2>
      <P className="text-gray-400">{content}</P>
    </Div>
  );
};

4. 레이아웃 JSON에서 다크 모드 사용

{
  "type": "Div",
  "props": {
    "className": "bg-white dark:bg-gray-800 p-4 rounded-lg border border-gray-200 dark:border-gray-700"
  },
  "children": [
    {
      "type": "H2",
      "props": {
        "className": "text-gray-900 dark:text-white font-bold mb-2",
        "text": "$t:dashboard.title"
      }
    },
    {
      "type": "P",
      "props": {
        "className": "text-gray-600 dark:text-gray-400",
        "text": "{{stats.description}}"
      }
    }
  ]
}

5. ThemeToggle 컴포넌트

다크 모드 전환은 ThemeToggle composite 컴포넌트를 사용:

{
  "type": "composite",
  "name": "ThemeToggle",
  "props": {
    "className": "p-2"
  }
}

ThemeToggle 동작:

  • 클릭 시 document.documentElement.classList.toggle('dark') 실행
  • localStorage에 사용자 선호도 저장 (theme 키)
  • 페이지 로드 시 저장된 테마 자동 적용

6. 기존 컴포넌트 재사용 이점

모든 그누보드7 기본 composite 컴포넌트는 다크 모드를 지원합니다.

UI 컴포넌트

  • ActionMenu, Alert, AlertDialog, Breadcrumb, Card, CodeEditor
  • ConfirmDialog, DataGrid, Dialog, Dropdown, EmptyState
  • IconButton, LoadingSpinner, Modal, Pagination, SearchBar
  • StatCard, StatusBadge, TabNavigation, Toast
  • ProductCard, TemplateCard, FilterGroup

관리자 컴포넌트

  • AdminHeader, AdminFooter, AdminSidebar, NotificationCenter
  • UserProfile, PageHeader, LayoutEditorHeader, LayoutFileList
  • LayoutHistoryPanel

Layout 컴포넌트

  • Container, Flex, Grid, Section, ThreeColumnLayout

✅ 기존 컴포넌트 재사용 시 자동으로 다크 모드가 지원되므로, 신규 개발보다 재사용을 우선하세요.


7. 컴포넌트 개발 체크리스트

새로운 컴포넌트 개발 시 다음 사항을 확인하세요:

□ 기본 컴포넌트만 사용 (HTML 태그 직접 사용 금지)
□ 기존 composite 컴포넌트 재사용 검토
□ 모든 배경색에 dark: variant 추가
□ 모든 텍스트 색상에 dark: variant 추가
□ 모든 테두리 색상에 dark: variant 추가
□ 색상 매핑 규칙 준수
□ 라이트 모드에서 정상 표시 확인
□ 다크 모드 전환 시 정상 표시 확인
□ 다국어 처리
□ TypeScript 타입 정의
□ 단위 테스트 작성

8. 테스트 요구사항

다크 모드를 지원하는 컴포넌트 개발 시:

  1. 라이트 모드 테스트: 모든 요소가 적절히 표시되는지 확인
  2. 다크 모드 전환 테스트: ThemeToggle 클릭 시 모든 요소가 변경되는지 확인
  3. 색상 대비율 검증: WCAG 2.1 AA 기준 충족 여부 검토 (선택)

9. 주의사항

주의 사항

  • 다크 모드 전용 색상만 하드코딩 (예: border-gray-700만 사용)
  • 인라인 스타일로 색상 지정 (style={{ color: '#000' }})
  • JavaScript로 색상 동적 변경 (Tailwind 사용)

필수

  • 항상 light와 dark variant 함께 지정
  • Tailwind CSS 유틸리티 클래스 사용
  • 기존 색상 매핑 규칙 준수
  • 기존 컴포넌트 재사용 우선

10. 참고 자료


관련 문서