Countdown#
숫자 값(0-99)을 표시하는 디스플레이 컴포넌트입니다. 값이 변경될 때 전환 애니메이션이 적용됩니다. 타이머 로직은 부모 컴포넌트에서 관리합니다.
Live Preview#
default
Web
42
Flutter
Loading Flutter...
class CountdownDefaultExample extends StatefulComponent {
const CountdownDefaultExample({super.key});
@override
State<CountdownDefaultExample> createState() =>
_CountdownDefaultExampleState();
}
class _CountdownDefaultExampleState extends State<CountdownDefaultExample> {
@override
Component build(BuildContext context) {
return Countdown(value: 42);
}
}
class CountdownDefaultExample extends StatefulWidget {
const CountdownDefaultExample({super.key});
@override
State<CountdownDefaultExample> createState() =>
_CountdownDefaultExampleState();
}
class _CountdownDefaultExampleState extends State<CountdownDefaultExample> {
@override
Widget build(BuildContext context) {
return const Countdown(value: 42);
}
}
chain
Web
42
Flutter
Loading Flutter...
class CountdownChainExample extends StatefulComponent {
const CountdownChainExample({super.key});
@override
State<CountdownChainExample> createState() => _CountdownChainExampleState();
}
class _CountdownChainExampleState extends State<CountdownChainExample> {
@override
Component build(BuildContext context) {
return Countdown(value: 42).withStyle(
const CoreCountdownStyle(
fontSize: CoreFontSize.s48,
color: CoreColor.token(CoreColors.primary),
animationDuration: Duration(milliseconds: CoreDuration.moderate),
),
);
}
}
class CountdownChainExample extends StatefulWidget {
const CountdownChainExample({super.key});
@override
State<CountdownChainExample> createState() => _CountdownChainExampleState();
}
class _CountdownChainExampleState extends State<CountdownChainExample> {
@override
Widget build(BuildContext context) {
return const Countdown(value: 42).withStyle(
const CoreCountdownStyle(
fontSize: CoreFontSize.s48,
color: CoreColor.token(CoreColors.primary),
animationDuration: Duration(milliseconds: CoreDuration.moderate),
),
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 카운트다운 숫자를 크게 표시할 때
- 시간 단위별 숫자를 개별 표시할 때 (시:분:초 각각)
- 세션 타임아웃 등 남은 시간을 숫자로 표시할 때
대신 다른 컴포넌트를 사용하세요:
NumberTicker: 일반적인 숫자 애니메이션이 필요할 때Progress: 남은 시간을 비율로 시각화할 때
기본 사용법 (Basic Usage)#
// 기본 카운트다운
Countdown(value: 42)
// 크기 조절
Countdown(
value: 42,
countdownStyle: CoreCountdownStyle(fontSize: 64),
)
// 시:분:초 조합
Row(
children: [
Countdown(value: hours),
Text(':'),
Countdown(value: minutes),
Text(':'),
Countdown(value: seconds),
],
)
// 기본 카운트다운
Countdown(value: 42)
// 크기 조절
Countdown(
value: 42,
countdownStyle: CoreCountdownStyle(fontSize: 64),
)
// 시:분:초 조합
div([
Countdown(value: hours),
Text(':'),
Countdown(value: minutes),
Text(':'),
Countdown(value: seconds),
], classes: 'flex items-center gap-${CoreSpace.scale.space4}')
빠른 오버라이드 (Chain)#
이미 만든 Countdown 인스턴스에 스타일을 빠르게 덧붙이고 싶다면 withStyle 체인을 쓸 수 있습니다. 생성자의 style 슬롯 인자와 동일하게 동작하지만, 이미 구성된 위젯 위에서 바로 이어 쓸 수 있습니다.
class CountdownChainExample extends StatefulWidget {
const CountdownChainExample({super.key});
@override
State<CountdownChainExample> createState() => _CountdownChainExampleState();
}
class _CountdownChainExampleState extends State<CountdownChainExample> {
@override
Widget build(BuildContext context) {
return const Countdown(value: 42).withStyle(
const CoreCountdownStyle(
fontSize: CoreFontSize.s48,
color: CoreColor.token(CoreColors.primary),
animationDuration: Duration(milliseconds: CoreDuration.moderate),
),
);
}
}
class CountdownChainExample extends StatefulComponent {
const CountdownChainExample({super.key});
@override
State<CountdownChainExample> createState() => _CountdownChainExampleState();
}
class _CountdownChainExampleState extends State<CountdownChainExample> {
@override
Component build(BuildContext context) {
return Countdown(value: 42).withStyle(
const CoreCountdownStyle(
fontSize: CoreFontSize.s48,
color: CoreColor.token(CoreColors.primary),
animationDuration: Duration(milliseconds: CoreDuration.moderate),
),
);
}
}
Props / Parameters#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
value |
int |
필수 | 표시할 숫자 값 (min~max 로 클램핑) |
min | int | 0 | 클램핑 하한 |
max | int | 99 | 클램핑 상한 |
countdownStyle |
CoreCountdownStyle? |
null |
폰트/색상/애니메이션 등 chrome override |
스타일 시스템 (Style System)#
모든 chrome / 애니메이션 override 는 countdownStyle 슬롯 하나로 흐릅니다.
CoreCountdownStyle 필드#
| 필드 | 타입 | 설명 |
|---|---|---|
fontSize |
double? |
Display font size override (logical px). No
default*
, and it must not get one. Both resolvers fold this flat field into an overlay that merges ON TOP of [defaultLabelStyle] ⊕ [labelStyle], so whatever sits here outranks both — and the resting font size is already stated, by the
headlineLarge
role inside [defaultLabelStyle]. A
static const
would therefore (a) make the [labelStyle] slot's own
fontSize
unreachable and (b) replace a token role with a raw scalar, which on Flutter also drops out of the text-scaling axis the role is materialised through. The resolvers rely on the overlay being null-only to stay a no-op; on Web a non-null one turns
emitTypography
from "role class, no inline" into a permanent inline
font-size
that beats the class.
|
color |
CoreColor? |
Display text colour override. No
default*
— same overlay position as [fontSize], and the resting colour is likewise already stated:
onSurface
, inside [defaultLabelStyle]. A default here would win over
labelStyle.color
, inverting the documented precedence, and would emit a standing inline
color
on Web where only the token class renders today.
|
animationDuration |
Duration? |
Digit transition / fade animation duration override.
NOT
the total countdown length — that is a semantic widget parameter (see contract
value
).
|
labelStyle |
CoreTextStyle? |
Label text style override (applied to the numeric child). |
fontSize / color 는 labelStyle 슬롯 위에 덧씌워지므로 flat 필드가 이깁니다.
Resolve chain#
CoreCountdownStyle.defaultX (static const, 단일 출처)
→ CoreCountdownTheme.style // 프로젝트 공통
→ widget.countdownStyle // 인스턴스별
동작 스펙 (Behavior)#
인터랙션#
- Countdown은 표시 전용 컴포넌트입니다. 인터랙션 없음.
- 부모 컴포넌트에서 Timer로
value를 업데이트해야 합니다.
애니메이션#
- Flutter:
AnimatedSwitcher+FadeTransition으로 값 변경 시 페이드 전환 - Web: CSS
transition으로 값 변경 시 페이드 전환 - 양쪽 모두
countdownStyle.animationDuration(기본CoreDuration.fast150ms)을 씁니다
사용 가이드라인 (Usage Guidelines)#
✅ Do#
시:분:초처럼 자릿수 단위로 인스턴스를 나눠서 표시
Row(
children: [
Countdown(value: hours),
Text(':'),
Countdown(value: minutes),
Text(':'),
Countdown(value: seconds),
],
)
Countdown은 min(기본 0)~max(기본 99) 범위의 두 자릿수 값 하나만 표시하도록 설계되어 있습니다 — 더 큰 시간 단위를 표현하려면 단위별로 인스턴스를 나눠야 합니다.
❌ Don't#
Countdown 내부에 타이머 로직이 있다고 기대하지 않기
// ❌ value를 한 번만 넘기고 자동으로 줄어들 거라 기대
Countdown(value: 60)
Countdown은 표시 전용 컴포넌트로 인터랙션도 내부 타이머도 없습니다 — 부모 컴포넌트가 Timer로 value를 직접 갱신해야 카운트다운이 동작합니다.
접근성 (Accessibility)#
스크린 리더#
- Flutter:
Semantics(liveRegion: true)로 값 변경 알림 - Web:
aria-live="polite"+aria-label로 값 변경 알림
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 클래스명 | Countdown | Countdown |
| 애니메이션 | AnimatedSwitcher fade | CSS transition |
| 숫자 정렬 | FontFeature.tabularFigures() | tabular-nums |
관련 컴포넌트 (Related Components)#
- NumberTicker: 일반 숫자 카운터 애니메이션
- Stat: 레이블 + 값 형식의 통계 표시