ThemeController#
ThemeController는 선택 가능한 테마 스와치를 줄바꿈 그리드로 표시하는 통합 테마 선택 컴포넌트입니다. 각 스와치는 테마의 팔레트 색상을 미리보기로 보여주며, 선택 시 테마 이름을
onThemeChanged로 전달합니다.
Live Preview#
Web
Flutter
Loading Flutter...
class ThemeControllerDefaultExample extends StatefulComponent {
const ThemeControllerDefaultExample({super.key});
@override
State<ThemeControllerDefaultExample> createState() =>
_ThemeControllerDefaultExampleState();
}
class _ThemeControllerDefaultExampleState
extends State<ThemeControllerDefaultExample> {
String _selected = 'Ocean';
@override
Component build(BuildContext context) {
return ThemeController(
selectedTheme: _selected,
onThemeChanged: (name) => setState(() => _selected = name),
themes: const [
CoreThemeOption(
name: 'Ocean',
primaryColor: CoreColor.fromRGB(14, 165, 233),
secondaryColor: CoreColor.fromRGB(99, 102, 241),
),
CoreThemeOption(
name: 'Forest',
primaryColor: CoreColor.fromRGB(34, 197, 94),
secondaryColor: CoreColor.fromRGB(132, 204, 22),
),
CoreThemeOption(
name: 'Sunset',
primaryColor: CoreColor.fromRGB(249, 115, 22),
secondaryColor: CoreColor.fromRGB(239, 68, 68),
),
],
);
}
}
class ThemeControllerDefaultExample extends StatefulWidget {
const ThemeControllerDefaultExample({super.key});
@override
State<ThemeControllerDefaultExample> createState() =>
_ThemeControllerDefaultExampleState();
}
class _ThemeControllerDefaultExampleState
extends State<ThemeControllerDefaultExample> {
String _selected = 'Ocean';
@override
Widget build(BuildContext context) {
return ThemeController(
selectedTheme: _selected,
onThemeChanged: (name) => setState(() => _selected = name),
themes: const [
CoreThemeOption(
name: 'Ocean',
primaryColor: CoreColor.fromRGB(14, 165, 233),
secondaryColor: CoreColor.fromRGB(99, 102, 241),
),
CoreThemeOption(
name: 'Forest',
primaryColor: CoreColor.fromRGB(34, 197, 94),
secondaryColor: CoreColor.fromRGB(132, 204, 22),
),
CoreThemeOption(
name: 'Sunset',
primaryColor: CoreColor.fromRGB(249, 115, 22),
secondaryColor: CoreColor.fromRGB(239, 68, 68),
),
],
);
}
}
사용 시기 (When to Use)#
이 컴포넌트를 사용하세요:
- 사용자가 여러 색상 테마 중 하나를 고르도록 할 때
- 설정 화면에서 테마 미리보기와 함께 선택지를 제공할 때
대신 다른 컴포넌트를 사용하세요:
Toggle: 라이트/다크 두 가지만 전환할 때Select: 색상 프리뷰 없이 텍스트 목록으로 충분할 때
기본 사용법 (Basic Usage)#
ThemeController(
selectedTheme: _selected,
onThemeChanged: (name) => setState(() => _selected = name),
themes: const [
CoreThemeOption(
name: 'Ocean',
primaryColor: CoreColor.fromRGB(14, 165, 233),
secondaryColor: CoreColor.fromRGB(99, 102, 241),
),
CoreThemeOption(
name: 'Forest',
primaryColor: CoreColor.fromRGB(34, 197, 94),
secondaryColor: CoreColor.fromRGB(132, 204, 22),
),
],
)
ThemeController(
selectedTheme: _selected,
onThemeChanged: (name) => setState(() => _selected = name),
themes: const [
CoreThemeOption(
name: 'Ocean',
primaryColor: CoreColor.fromRGB(14, 165, 233),
secondaryColor: CoreColor.fromRGB(99, 102, 241),
),
CoreThemeOption(
name: 'Forest',
primaryColor: CoreColor.fromRGB(34, 197, 94),
secondaryColor: CoreColor.fromRGB(132, 204, 22),
),
],
)
Props / Parameters#
ThemeController#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
themes |
List<CoreThemeOption> |
필수 | 선택 가능한 테마 옵션 목록 |
selectedTheme |
String? |
null |
현재 선택된 테마 이름 |
onThemeChanged |
void Function(String) |
필수 | 테마 선택 핸들러 (옵션 이름 전달) |
variant |
CoreThemeControllerVariant |
standard |
시각 변형 |
themeControllerStyle |
CoreThemeControllerStyle? |
null |
크롬 / 치수 스타일 오버라이드 |
CoreThemeOption#
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
name |
String |
필수 | 테마 이름 (onThemeChanged 식별자) |
primaryColor | CoreColor | 필수 | 주요 팔레트 색상 프리뷰 |
secondaryColor |
CoreColor? |
null |
보조 팔레트 색상 프리뷰 |
accentColor |
CoreColor? |
null |
액센트 팔레트 색상 프리뷰 |
neutralColor |
CoreColor? |
null |
중립 팔레트 색상 프리뷰 |
동작 스펙 (Behavior)#
인터랙션#
- 선택: 스와치 클릭 시
onThemeChanged(name)호출 -
선택 표시: 선택된 스와치는 강조 보더(
primary, 2px), 나머지는 기본 보더(outline, 1px)
접근성 (Accessibility)#
스크린 리더#
-
Flutter:
Semantics(selected: isSelected, button: true, label: themeName)자동 적용 -
Web: 각 스와치
role="button"+aria-pressed+aria-label적용
크로스 플랫폼 차이점 (Platform Differences)#
| 항목 | Flutter | Web |
|---|---|---|
| 클래스명 | ThemeController | ThemeController |
| 렌더 루트 | Wrap | <div> (flex flex-wrap) |
| 스와치 | Container + BoxDecoration |
<div> + inline CSS border |