배율·최소 높이·기본값
coui Flutter resolver 는 테마의 `scaling`(앱이 `CoUIApp(scaling: AdaptiveScaling(k))` 등으로 정한 값)을 스타일 값에 곱한다. 앱이 정하지 않으면 모든 플랫폼에서 1 이다 — 휴대폰 기본값 `AdaptiveScaling.mobile` 은 coui_flutter 0.157 부터 1 이고, 그 전에...
1. 배율이 곱해지는 값#
coui Flutter resolver 는 테마의 scaling(앱이 CoUIApp(scaling: AdaptiveScaling(k))
등으로 정한 값)을 스타일 값에 곱한다. 앱이 정하지 않으면 모든 플랫폼에서 1 이다 — 휴대폰 기본값 AdaptiveScaling.mobile 은 coui_flutter 0.157 부터 1 이고, 그 전에는 1.25 였다.
scaling: 을 넘기지 않던 앱을 0.157 이전에서 올리면 iOS · Android 화면이 0.8 배(1 / 1.25)로 줄어든다 — 옛 크기를 지키려면
CoUIApp(scaling: const AdaptiveScaling(1.25)) 를 명시한다(이때는 데스크톱 · 웹도 1.25 가 되므로, 휴대폰에만 걸던 동작은 앱이 플랫폼을 보고 고른다).
호출부가 직접 준 값에도 곱한다. 아래는 coui_flutter 0.148~0.151 에서 확인한 것이다. 버전이 바뀌면 해당 컴포넌트의 resolve*
함수를 다시 읽는다.
| 곱해짐 | 곱해지지 않음 |
|---|---|
Button·Card·Tabs 등의
padding
,
borderRadius
(완전 원형 제외),
height
, 정사각 버튼의
iconShapePadding
|
width
·
minWidth
·
maxWidth
, Card
sizing: fixed
의 가로·세로
|
TextField 의 padding·borderRadius·borderWidth·커서 폭·포커스 링 |
명시한 TextStyle.fontSize(토큰 슬롯 크기는 곱해진다) |
Divider 의 thickness·indent·endIndent |
Button 의 borderWidth |
coui Icon(Iconify) 크기 |
TextArea 의 padding·테두리·높이(TextField 와 반대라 주의) |
같은 이름의 값이라도 컴포넌트마다 곱해지는지가 다를 수 있다. 헷갈리면 값을 두 배로 바꿔 렌더 크기가 2×k 배로 변하는지 확인한다.
2. 옛 값을 옮기는 공식#
옛 컴포넌트(특히 앱이 소유하던 래퍼)가 값을 배율 없이 그렸는지 먼저 소스로 확인한다. 대부분 명시값은 그대로 그리고 기본값에만 배율을 곱했다.
| 옛 동작 | 새 노브에 넣을 값 |
|---|---|
| 명시값을 배율 없이 그림 | 옛값 / k 에 가장 가까운 토큰 |
| 명시값에도 배율을 곱함 | 옛값 그대로 |
| 테두리가 있는 변형 | 테두리가 안쪽을 먹는지(디플레이트) 확인. 한 사례에서는 세로 패딩을 (옛값×k + 테두리)/k 로 맞춰야 같은 높이가 나왔다 |
| Divider 두께 | 옛 두께 / k |
-
간격·반경 토큰은 짝수 격자라
옛값 / k와 정확히 안 맞을 수 있다. 가장 가까운 토큰을 쓰고 이유를 주석에 남긴다. 형제 요소와 높이를 맞춰야 하는데 정확히 안 되면 후보(예: 78 대 84)를 보여 주고 사용자에게 고르게 한다. - 룩 변화를 수용하기로 한 컴포넌트(예: 카드 패딩이 배율만큼 커지는 것을 디자인이 받아들임)는 보정하지 않는다. 그 결정은 프로젝트 프로필에 적어 다음 작업자가 되돌리지 않게 한다.
3. 최소 높이(floor)#
| 노브 | 동작 | 옛 동작이 "내용 크기"였다면 |
|---|---|---|
Button 의 height |
최소 높이. 크기 토큰 높이 × k 가 바닥 | height: 0 |
| 정사각 버튼 | minWidth = height 로 정사각 강제 |
height: 0, minWidth: 0 |
Tabs 의 itemHeight |
탭 아이템 하나의 최소 높이(크기 미지정 시 기본 크기 토큰 × k). 바깥 tabBarPadding 이 그 위에 더해진다 |
itemHeight: 0 |
고정 높이가 필요하면 floor 가 아니라 바깥 SizedBox 로 제약한다.
4. 기본값 대조 — 호환 래퍼를 걷어낼 때#
앱이 coui 위에 자기 래퍼(옛 Card·Button·Text 체인 등)를 두고 있었다면, 래퍼를 걷는 순간 호출부가 값을 주지 않은 모든 곳이 coui 기본값으로 바뀐다. 패밀리마다 다음 표를 먼저 만든다.
| 속성 | 옛 래퍼 기본값 | coui 기본값(버전) | 차이 처리 |
|---|---|---|---|
| 테두리색 | (예) outlineVariant | (예) outlined 변형은 outline |
전역 테마로 복원 / 수용 |
| 테두리 폭 | |||
| 패딩 | px/k 보정 / 수용 | ||
| 반경 | |||
| 그림자 | |||
| 본문 텍스트 스타일 | |||
| 크기 기본값(sizing) |
-
차이를 한 곳에서 되돌릴 수 있으면 전역 컴포넌트 테마(
CoreComponentTheme의 해당 컴포넌트 theme, 변형별로는variantStyles)로 복원한다. 호출부 수십 곳을 고치지 않는다. - 그 기본값을 검증하는 골든 셀은 값을 명시하지 않는다(golden-gate.md 기본값 셀 규칙).
- 명시값이 없는 호출부 수를 세어 두면(예: 테두리색을 안 준 Card 수) 영향 범위를 PR 에 적을 수 있다.
5. 재는 조건#
테스트 기본 환경(기본 화면 크기, CoUIApp 기본 배율, 테스트 폰트)은 실기기와 다르다. 크기를 맞추는 작업은 다음 조건에서 잰다.
- 앱이 실제로 쓰는 논리 폭(반응형 스케일 박스가 있으면 그 폭)
- 앱과 같은 배율(
CoUIApp(scaling: AdaptiveScaling(k))) - 실제 폰트 로드(
FontLoader로 앱 폰트를 올린다 — 폴백 폰트는 줄 높이가 달라 높이가 틀어진다) - 그림자를 볼 때는
debugDisableShadows = false
가능하면 실기기 스크린샷으로 모델을 검증한다. 물리 픽셀 = 논리 픽셀 × devicePixelRatio 로 환산하고, 둥근 모서리 구간을 피해 가운데 열에서 잰다. 측정용 임시 테스트는 끝나면 지운다.