본문으로 건너뛰기

ADR-0007: 적응형 UI의 판정 축과 구현 패턴을 고정하고 네이티브 위임을 기각한다

상태

Accepted

날짜

2026-08-10

맥락

웹 애플리케이션이 데스크탑과 모바일에서 모두 사용됩니다. 레이아웃만 바뀌는 것으로는 부족한 경우가 있습니다. 셀렉트박스가 데스크탑에서는 앵커 드롭다운으로 뜨지만 모바일에서는 액션시트로 떠야 조작이 가능합니다.

이 영역을 라이브러리가 해결해 주지 않습니다. shadcn은 Dialog와 Drawer를 조합하는 방법을 문서에 예시로 싣고 useMediaQuery("(min-width: 768px)")로 분기하라고 안내할 뿐이며, 이 공백을 메우려는 서드파티 래퍼가 별도로 존재합니다.

그 레시피의 판정 축에 결함이 있습니다. 액션시트가 필요한 이유는 화면이 작아서가 아니라 손가락으로 조작하고 호버가 없기 때문입니다. 너비로 판정하면 터치 노트북, 태블릿 가로, 좁게 줄인 데스크탑 창이 모두 오판됩니다.

결정

판정 축

미디어 쿼리 역할
(pointer: coarse) 1차 축
(hover: none) 1차 축
(min-width: ...) 2차 축. 레이아웃 배치에만 사용

두 1차 축이 모두 참일 때 touch, 그 외에는 pointer로 판정합니다.

컴포넌트가 미디어 쿼리 문자열을 직접 갖는 것을 금지하고, shared/lib/adaptive/의 의미 신호(injectInteractionMode())만 사용합니다. 판정 기준이 바뀌면 그 파일 하나만 고칩니다. 구현에는 이미 의존성에 있는 CDK BreakpointObserver를 사용합니다.

구현 패턴과 판정 순서

위에서부터 판정하고 먼저 해당하는 항목에서 멈춥니다.

순서 패턴 조건
1 오버레이 위치 전략 교체 표시 위치만 다름
2 표현 컴포넌트 교체 상호작용 모델이 다름
3 2번에 @defer 추가 번들 문제가 측정으로 확인됨

표현 컴포넌트는 슬라이스 공개 API로 내보내지 않으며, 두 표현은 동일한 입출력 계약을 갖습니다.

세부 규칙은 적응형 UI가 원본입니다.

검토한 대안

화면 너비(min-width)로 판정

구분 내용
장점 널리 쓰이는 방식이라 참고 자료가 많고 구현이 단순합니다
단점 입력 방식과 화면 크기는 독립적인 축입니다. 터치 노트북과 태블릿 가로가 오판됩니다
기각 사유 판정하려는 대상이 화면 크기가 아니라 조작 방식입니다. 상관관계가 있을 뿐 인과관계가 아닙니다

네이티브 위임 — 터치 환경에서 OS 기본 UI 사용

구분 내용
장점 접근성·현지화·제스처를 OS가 처리합니다. 날짜 선택기처럼 접근성 결함이 자주 나오는 컴포넌트의 구현 부담이 사라집니다
단점 OS와 브라우저마다 외형이 달라집니다. 디자인 토큰이 적용되지 않습니다
기각 사유 화면 통제를 포기하는 것이며, 같은 화면이 기기마다 다르게 보이는 것을 허용할 수 없습니다

패턴을 고정하지 않고 사례마다 판단

구분 내용
장점 각 상황에 최적인 방식을 선택할 수 있습니다
단점 같은 성격의 컴포넌트가 서로 다른 방식으로 구현됩니다
기각 사유 1순위 품질 목표가 예측 가능성입니다. 판정 순서가 없으면 구현 방식이 작성자마다 갈립니다

결과

기기 판정 기준이 한 파일에 모이고, 구현 방식이 판정 순서로 결정됩니다. 표현 컴포넌트를 비공개로 두므로 상위 계층은 적응형 여부를 알지 못하며, 나중에 패턴을 바꿔도 사용처를 수정하지 않습니다.

감수하는 사항은 다음과 같습니다.

  • 날짜 선택기의 표현을 직접 만들어야 합니다. 네이티브 위임을 기각한 직접적 결과입니다. 다만 접근성 부담은 확인 결과 크지 않습니다. brain의 캘린더가 방향키·Home·End·PageUp·PageDown 이동, 로빙 탭인덱스, role="grid"와 셀 단위 ARIA를 제공하므로 직접 만드는 것은 마크업과 두 표현이며 키보드 모델이 아닙니다. 남는 몫은 라벨의 한국어화입니다.
  • 적응형 컴포넌트마다 두 표현을 유지합니다. 패턴 2를 적용하면 파일 수와 테스트 수가 두 배가 됩니다.
  • 정적 생성 경로에서 적응형 컴포넌트를 사용할 수 없습니다. 서버에는 포인터가 없어 하이드레이션 불일치가 발생합니다. 자동 강제 수단이 없어 코드 리뷰에서 확인합니다.
  • 두 모드 테스트가 자동 강제되지 않습니다. 코드 리뷰에서 존재를 확인합니다.

개정

  • 2026-08-11: 판정 순서의 전제 세 건을 확인했습니다. 결정은 바뀌지 않습니다.

    • @spartan-ng/brain이 위치 전략 교체를 허용합니다. BrnOverlaypositionStrategy 입력이 기본 전략보다 우선하고, 주입 범위 전체에는 provideBrnOverlayDefaultOptions()를 씁니다. 패턴 1을 유지하며 판정 순서를 그대로 둡니다.
    • brain의 캘린더가 APG 그리드의 키보드 모델과 ARIA를 제공합니다. 결과 절의 날짜 선택기 항목을 이에 맞게 완화했습니다.
    • CDK BreakpointObserver가 서버에서 예외 없이 matches: false를 즉시 방출합니다. 정적 생성 경로의 오용이 예외로 드러나지 않으므로 결과 절의 코드 리뷰 확인 항목이 그대로 필요합니다.

    확인 방법과 근거는 개발 환경 7절이 원본입니다.

© 2026 dev.goraebap