feat(proj): init

This commit is contained in:
vl.arkhangelskii
2026-09-21 04:06:43 +03:00
commit c956b94983
1076 changed files with 50876 additions and 0 deletions
@@ -0,0 +1,66 @@
# 2026-09-19 — Мобильный UI-кит переведён на iOS (Cupertino)
## Запрос
Widgetbook запустился, но Material-компоненты визуально не устроили. Задача — сделать
компоненты «из iOS kit».
## Что сделано
### Токены и тема (`mobile/lib/theme/`)
- `tokens.dart` переписан под Apple HIG: семантические цвета (`label`, `secondaryLabel`,
`separator`, `opaqueSeparator`, `groupedBackground`, `groupedSurface`, `barBackground`)
и системная палитра (`systemRed/Orange/Green/Gray/Gray3/Gray5/Gray6`) объявлены как
`CupertinoDynamicColor.withBrightness` — light/dark резолвится самим фреймворком через
`AppColors.of(context, color)`.
- Бренд-тинт остался зелёным (`accent` = #12885A / #3CD68C в тёмной) и подменяет systemBlue.
- Типографика — шкала SF Pro: largeTitle 34 … caption2 11 с нативными letterSpacing.
- Размеры контролов: 50 / 44 / 34 pt, hairline 0.5, радиусы 6/10/12/16/capsule.
- `app_theme.dart` теперь возвращает `CupertinoThemeData` (`buildLightTheme` /
`buildDarkTheme`), шрифт — Inter через google_fonts как кросс-платформенная замена SF Pro
(на Windows/web SF недоступен).
### Компоненты (`mobile/lib/ui/`)
Material-версии удалены, вместо них Cupertino:
- atoms: `AppButton` (filled/tinted/gray/plain/destructive × large/medium/small),
`AppTextField` (CupertinoTextField + error/prefix/clear), `AppText` (именованные
конструкторы по шкале iOS) + `AppSectionHeader`, `AppIcon` + `AppIconBadge`
(Settings-style скруглённый квадрат).
- molecules: `AppListSection` (inset-grouped, header/footer, hairline с indent),
`AppListTile` (leading/value/chevron, press-highlight, destructive), `AppSwitchRow`
(CupertinoSwitch), `AppCard`, `AppChip` (капсула), `AppAvatar`.
- navigation: `AppNavBar` (реализует `ObstructingPreferredSizeWidget`, есть subtitle),
`AppLargeNavBar` (`CupertinoSliverNavigationBar`), `AppTabBar` (наследник
`CupertinoTabBar`, чтобы отдавать в `CupertinoTabScaffold`), `AppSegmentedControl`
(`CupertinoSlidingSegmentedControl`), `AppAlert` + `showAppAlert` + `showAppActionSheet`.
- feedback: `AppSpinner` (`CupertinoActivityIndicator`), `AppProgressBar` (4pt капсула),
`AppSkeleton` / `AppSkeletonRow`, `AppToast` + `showAppToast` (blur-капсула через
OverlayEntry — в iOS нет SnackBar).
- screens: Feed (large title + сегменты + группы + empty/loading), Detail (hero-сумма,
прогресс, группа параметров, кнопки), Profile (Settings-подобный экран со свитчами).
- `main.dart` переведён на `CupertinoApp` + `CupertinoTabScaffold`.
### Widgetbook (`mobile/widgetbook/`)
- `Widgetbook.cupertino` + `CupertinoThemeAddon` вместо material-варианта.
- Новый `lib/support/preview.dart``IosPreview` кладёт use-case на grouped-фон,
чтобы карточки и разделители читались как в приложении.
- Каталог: Atoms (Button/TextField/Typography/Icons), Molecules (Card/ListTile/SwitchRow/
Chip/Avatar), Navigation (NavBar/TabBar/SegmentedControl/Alert), Feedback (Progress/
Skeleton/Toast), Screens (Feed/Detail/Profile) — 42 use-case.
- Knobs: добавлены `knobEnum` и `knobTint` (дропдаун по системным тинтам), убран
deprecated `knobs.list`.
### Тесты
`widgetbook/test/catalog_smoke_test.dart` больше не проверяет только структуру: каждый
use-case пампится в light и dark внутри `WidgetbookScope` (knobs читают `WidgetbookState`
из контекста, иначе падает «No Widgetbook found in the context»). В тестах отключён
`GoogleFonts.config.allowRuntimeFetching` и вызван `TestWidgetsFlutterBinding.ensureInitialized()`.
## Результат
- `flutter analyze` (mobile + widgetbook) — 0 issues.
- `flutter test` — 84 теста в widgetbook + 1 в приложении, всё зелёное.
## Запуск
```powershell
cd mobile\widgetbook
.\run.ps1 -Device windows
```