Files
please-pay-me/context/2026-09-19_23-55-00_mobile-ios-kit.md
2026-09-21 04:06:43 +03:00

4.5 KiB
Raw Permalink Blame History

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.dartIosPreview кладёт 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 в приложении, всё зелёное.

Запуск

cd mobile\widgetbook
.\run.ps1 -Device windows