모션
얼마나 오래, 어떤 곡선으로 움직이는지 정한다. 무엇이 움직이는지 정하면 시간이 따라온다.
시간
0.2초가 경계다. 버튼 눌림과 포커스, 회전 같은 마이크로 모션은 duration-4 이하를 쓴다. 팝업 개폐와 시트 슬라이드, 페이지 전환은 duration-4 를 넘는다.
색 · 테두리 · 배경 전환은 duration-3(150ms) 하나다. hover · error · disabled 로 바뀌는 순간 전부가 여기 해당하고, 눌림(duration-pressed)과 같은 시계다.
막대 길이가 곧 시간이다. 4번이 경계선이다.
곡선
나타날 때와 사라질 때 다른 곡선을 쓴다. 나타날 때는 천천히 끝나 결과를 인지할 시간을 준다. 사라질 때는 빠르게 끝나 이미 끝난 일에 시간을 쓰지 않는다. 하나의 곡선으로 양방향을 처리하면 이 차이가 사라진다.
왼쪽 아래가 시작, 오른쪽 위가 끝이다. enter 는 초반에 가파르고 exit 는 후반에 가파르다.
| 토큰 | 언제 |
|---|---|
| --nui-easing-standard | 기능적 마이크로 — 색 · 테두리 전환 |
| --nui-easing-enter | 나타남 — 빠르게 시작해 천천히 안착 |
| --nui-easing-exit | 사라짐 — 천천히 시작해 빠르게 빠짐 |
| --nui-easing-enter-emphasized | 강조가 필요한 등장 |
| --nui-easing-exit-emphasized | 강조가 필요한 퇴장 |
| --nui-easing-expand | 크기가 변하는 것 — 접힘/펼침. easing-enter 를 쓰지 않는다 |
모션 줄이기
OS 에서 동작 줄이기를 켜면 prefers-reduced-motion: reduce 가 전달되고 duration 토큰이 전부 1ms 가 된다. 라이브러리 컴포넌트는 이 설정을 따른다.
커스텀 애니메이션에 시간을 하드코딩하면 이 장치를 우회한다. 0.2s 라고 직접 적는 대신 duration 토큰을 참조한다.
reducedMotion 기본값이 "never" 라 useReducedMotion() 으로 분기해야 설정이 반영된다. 라이브러리의 Popup 과 Toast, Tooltip 은 분기해 두었다.const shouldReduceMotion = useReducedMotion();
<motion.div
initial={shouldReduceMotion ? { opacity: 0 } : { opacity: 0, y: -8, scale: 0.98 }}
transition={shouldReduceMotion ? { duration: 0 } : motionTransition.popover}
/>눌림
눌림은 배율과 시간, 곡선 세 축을 함께 쓴다. 하나만 골라 쓰면 같은 눌림이 컴포넌트마다 다르게 느껴진다.
| 축 | 토큰 |
|---|---|
| 변형량 | --nui-scale-94 작은 요소 · -96 중간 · -98 큰 요소 |
| 시간 | --nui-duration-pressed |
| 곡선 | --nui-easing-pressed |
큰 요소일수록 덜 줄여야 같은 정도로 눌린 느낌이 난다. 전면 버튼을 0.94 로 줄이면 과하게 움츠러들고 작은 버튼을 0.98 로 줄이면 티가 안 난다.
| 토큰 | 값 | 비고 |
|---|---|---|
| --nui-scale-94 | 0.94 | 작은 요소 — 아이콘 버튼 · 칩 |
| --nui-scale-96 | 0.96 | 중간 |
| --nui-scale-98 | 0.98 | 큰 요소 — 전면 버튼 · 카드 |
전체 토큰
| 토큰 | 값 | 비고 |
|---|---|---|
| --nui-duration-1 | 50ms | — |
| --nui-duration-2 | 100ms | — |
| --nui-duration-3 | 150ms | — |
| --nui-duration-4 | 200ms | — |
| --nui-duration-5 | 250ms | — |
| --nui-duration-6 | 300ms | — |
| --nui-duration-7 | 350ms | — |
| --nui-duration-8 | 400ms | — |
| --nui-easing-standard | cubic-bezier(0.2, 0, 0, 1) | 기능적 마이크로 |
| --nui-easing-enter | cubic-bezier(0, 0, 0.15, 1) | ease-out 계열 |
| --nui-easing-exit | cubic-bezier(0.35, 0, 1, 1) | ease-in 계열 |
| --nui-easing-enter-emphasized | cubic-bezier(0.16, 1, 0.3, 1) | — |
| --nui-easing-exit-emphasized | cubic-bezier(0.35, 0, 0.95, 0.55) | — |
| --nui-easing-expand | cubic-bezier(0.5, 1, 0.89, 1) | — |
| --nui-duration-pressed | var(--nui-duration-3) | 별칭 |
| --nui-easing-pressed | cubic-bezier(0, 0, 0.15, 1) | — |