타입 스케일·공통 크롬을 Figma 기준으로 정렬 — 상단 내비게이션 · 하단 탭 아이콘 · 버튼 · 시트
This commit is contained in:
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import '../config/feature_flags.dart';
|
||||
import '../theme/tokens.dart';
|
||||
import '../ui/app_icons.dart';
|
||||
import '../../features/auth/auth_repository.dart';
|
||||
import '../../features/auth/login_screen.dart';
|
||||
import '../../features/galaxy/galaxy_screen.dart';
|
||||
@@ -22,7 +24,9 @@ class AppTab {
|
||||
/// **계약 고정 문자열.** 한글화·치환·순서 변경 금지.
|
||||
final String label;
|
||||
final String path;
|
||||
final IconData icon;
|
||||
|
||||
/// Figma Bottom Navigation 아이콘. 색은 NavigationBar 테마가 입힌다.
|
||||
final Widget icon;
|
||||
|
||||
/// 이 탭을 여는 원격 플래그. null 이면 항상 보인다.
|
||||
///
|
||||
@@ -39,24 +43,29 @@ class AppTab {
|
||||
/// - 시안 `시안/screens/S-*.html` 의 `<nav class="tabbar">` (5개 루트 화면 전부 동일)
|
||||
///
|
||||
/// 라벨 문자열과 순서는 스모크 테스트가 정확 일치로 검증한다.
|
||||
/// 아이콘은 아직 확정 자산이 없어 Material 기본 아이콘을 쓴다(README 「미투입 항목」).
|
||||
/// 아이콘은 Figma Iconset(house · message-square · badge · circle-user-round)이다.
|
||||
/// STATION 은 Figma 하단 탭에 없어(1차 비노출) Material 아이콘을 둔다.
|
||||
///
|
||||
/// **이 목록은 계약이지 화면이 아니다.** 지금 하단 탭에 실제로 그려지는 것은
|
||||
/// [visibleTabs] 이고 STATION 은 원격 플래그가 켜질 때까지 빠진다 — 목록에서
|
||||
/// 지우면 `design/craft-allowlist.yaml` 과 어긋나고, 켜려면 재배포가 필요해진다.
|
||||
const List<AppTab> appTabs = [
|
||||
AppTab(label: 'HOME', path: '/home', icon: Icons.home_outlined),
|
||||
AppTab(label: 'INSIDE', path: '/inside', icon: Icons.chat_bubble_outline),
|
||||
AppTab(label: 'GALAXY', path: '/galaxy', icon: Icons.auto_awesome_outlined),
|
||||
AppTab(label: 'HOME', path: '/home', icon: ImageIcon(AppIcons.house)),
|
||||
AppTab(
|
||||
label: 'INSIDE',
|
||||
path: '/inside',
|
||||
icon: ImageIcon(AppIcons.messageSquare),
|
||||
),
|
||||
AppTab(label: 'GALAXY', path: '/galaxy', icon: ImageIcon(AppIcons.badge)),
|
||||
// 별첨 B v1.4 — *1차에서는 사용자 탭과 Coming Soon 을 모두 비노출하고
|
||||
// Route/데이터 구조만 유지해 향후 앱 재배포 없이 활성화합니다.*
|
||||
AppTab(
|
||||
label: 'STATION',
|
||||
path: '/station',
|
||||
icon: Icons.storefront_outlined,
|
||||
icon: Icon(Icons.storefront_outlined),
|
||||
gatedBy: _stationGate,
|
||||
),
|
||||
AppTab(label: 'MY', path: '/my', icon: Icons.account_circle_outlined),
|
||||
AppTab(label: 'MY', path: '/my', icon: ImageIcon(AppIcons.circleUserRound)),
|
||||
];
|
||||
|
||||
bool _stationGate(FeatureFlags flags) => flags.stationTab;
|
||||
@@ -159,18 +168,25 @@ class AppShell extends StatelessWidget {
|
||||
final selected = branches.indexOf(shell.currentIndex);
|
||||
return Scaffold(
|
||||
body: shell,
|
||||
bottomNavigationBar: NavigationBar(
|
||||
// 숨긴 탭에 머무는 동안(딥링크 등)에는 선택 표시를 첫 탭으로 둔다.
|
||||
selectedIndex: selected < 0 ? 0 : selected,
|
||||
onDestinationSelected: (i) => shell.goBranch(
|
||||
branches[i],
|
||||
// initialLocation: true 를 주면 이미 열려 있는 탭을 다시 누를 때 루트로 되돌아간다.
|
||||
initialLocation: branches[i] == shell.currentIndex,
|
||||
// Figma 탭 줄은 좌우 16 을 비우고 칸을 나눈다(350:215853).
|
||||
bottomNavigationBar: ColoredBox(
|
||||
color: AppColors.cosmicVoid,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: NavigationBar(
|
||||
// 숨긴 탭에 머무는 동안(딥링크 등)에는 선택 표시를 첫 탭으로 둔다.
|
||||
selectedIndex: selected < 0 ? 0 : selected,
|
||||
onDestinationSelected: (i) => shell.goBranch(
|
||||
branches[i],
|
||||
// initialLocation: true 를 주면 이미 열려 있는 탭을 다시 누를 때 루트로 되돌아간다.
|
||||
initialLocation: branches[i] == shell.currentIndex,
|
||||
),
|
||||
destinations: [
|
||||
for (final tab in tabs)
|
||||
NavigationDestination(icon: tab.icon, label: tab.label),
|
||||
],
|
||||
),
|
||||
),
|
||||
destinations: [
|
||||
for (final tab in tabs)
|
||||
NavigationDestination(icon: Icon(tab.icon), label: tab.label),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user