halkyon/packages/halkyon_ui/README.md
Tizian 「ティツィアーン」 80fa7b9628
Halkyon's shared packages
A pub workspace of the Dart packages Halkyon's apps share: halkyon_ui,
Halkyon's look (the theme, fonts, layout and shared widgets, with texts
in English and German), halkyon_core's low-level primitives and
halkyon_interop's cross-app contracts. Dart 3.13 with LeanCode's lints,
configured once at the root; apps take a package by git, pinned to a
signed commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-18 21:50:15 +02:00

4.3 KiB

halkyon_ui

Halkyon's look, shared by its apps (Learn, Todo, Train): one theme around the kingfisher's cobalt and copper, the bundled Noto Sans, Material 3's window sizes, and the widgets every app's screens are built of, with their texts in British English, American English and German.

Written as the apps are: Dart 3.13's primary constructors, Material from package:material_ui (never package:flutter/material.dart), Lucide icons, LeanCode's lints.

What it holds

  • Theme (lib/src/theme/): appTheme(brightness, extensions: …), Material 3 with hand-written light and dark schemes (primary cobalt, tertiary copper, cobalt-tinted neutrals), Material 3 Expressive's 64 dp navigation bar, flat app bars, floating snack bars; Brand; ThemeExtras, the status colours Material has no role for (Theme.of(context).extras); PaletteColor, the 20 colours a person can give content, each with a text colour held to WCAG AA by a test; FittedSnackBars.
  • Fonts: Noto Sans for Latin, Greek and Cyrillic, every weight in one variable file, as appFontFamily (packages/halkyon_ui/Noto Sans). Chinese, Japanese and Korean fall back to Noto Sans JP, SC, TC and KR, which an app bundles itself if it needs them (appFontFallbackFor puts a language's own first).
  • Layout (lib/src/layout/): WindowSize (context.windowSize) and readableContentMaxWidth.
  • Widgets (lib/src/widget/): showAdaptiveSheet with SheetScaffold; TopGradient, ScreenTint, ScreenColor, TintFrame, FramedScreen and TabVisibility; FloatingNavigationBar; AppLoadingIndicator, ButtonLoadingIndicator, AppRefreshIndicator; SectionCard, SliverCentered, EmptyListMessage, CountBadge, TitleWithKicker, CollapsingRow, ScrollHidingFab, liftWhileDragged, ReorderToggle, ReorderGrip; ChevronField, requiredDecoration, FieldInfoButton, CountStepper, PaletteColorPicker, TextLimits with nearLimitCounter; confirmDestructiveAction, showUndoSnackBar, showMoreInfoSheet; FoundById; KeyboardBackOnResume; BrandWordmark and LaunchScreen, which take the app's word and icon.

What belongs to one app stays in it: its own colours (an extension passed to appTheme), routes, repositories, editors and texts.

Using it in an app

Depend on it by git, pinned to a signed commit, as the apps pin their forks:

dependencies:
  halkyon_ui:
    git:
      url: https://code.halkyon.app/project-halkyon/halkyon_shared.git
      path: packages/halkyon_ui
      ref: <signed commit>

While changing both at once, point the app at a local checkout with a git-ignored pubspec_overrides.yaml beside the app's workspace root:

dependency_overrides:
  halkyon_ui:
    path: ../halkyon_shared/packages/halkyon_ui

The lockfile then records the path: never commit it so, as CI has no such folder.

Then set the app up as example/lib/main.dart does:

MaterialApp(
  theme: appTheme(Brightness.light, extensions: [MyColors.light]),
  darkTheme: appTheme(Brightness.dark, extensions: [MyColors.dark]),
  localizationsDelegates: const [
    AppLocalizations.delegate,
    HalkyonUiLocalizations.delegate,
    // material_ui's: flutter_localizations' serve only the SDK's Material.
    ...GlobalMaterialLocalizations.delegates,
  ],
  supportedLocales: AppLocalizations.supportedLocales,
  builder: (context, child) => FittedSnackBars(child: child!),
  …
);

and call registerFontLicenses() at start. An app bundling the CJK fonts declares them in its own pubspec.yaml under exactly the names appFontFallback lists (no packages/ prefix) and registers their licence itself.

Texts

lib/l10n/halkyon_ui_en.arb is the template (British English, also the fallback); halkyon_ui_de.arb German, informal "du"; halkyon_ui_en_US.arb only what American English spells differently; halkyon_ui_en_GB.arb empty. A new text goes into the template and German together (test/l10n/ fails otherwise). flutter pub get writes lib/l10n/halkyon_ui_localizations*.dart, which are committed (apps take the package by git) and never edited or formatted by hand.

Checks

From the workspace root: dart analyze --fatal-infos; then flutter test in packages/halkyon_ui and in packages/halkyon_ui/example, whose tests check what only an app sees (the font under the name an app finds it by, its licence).