The developer's choice of 7 Nov 2026 (the mockup's variant E): a tap on another destination sends a radial glow in the app's colour over the bar from that destination's centre, solid to 35 % of its radius and gone at 70 %, growing to cover the bar (cubic(.2, .7, .2, 1)) while it fades from half its strength in dark mode and a third in light, over 1.2 s, behind the destinations and clipped to the bar. None for the destination already chosen, none with animations off, and none for a tab changed without a tap (a link, back): the wave answers the finger. The destination chosen takes the app's colour, its indicator tinted 22 % with it, without Material's ripple or the indicator growing; the bar's top corners are rounded, 20 dp, the screen showing through them. Each app gives the frame its colour (NavigationFrame's accent, from PaletteColor): Learn's purple, its icon's last colour, Todo's strawberry, Train's carrot and Meditate's fern, their screens' wash. For trying it on a phone, a debug build's Settings has a section Navigation bar (debug), halkyon_ui's NavigationBarDebugSection, switching live, in memory alone: the variant (A Material only, C the wave with Material's fill, E without it, F without the indicator too), the wave's time (0.7 to 2 s) and the corners (0 to 28 dp). Release builds never read it and show shippingNavigationBarStyle, the debug section's start: to remove it, delete the section from the four Settings screens and debugNavigationBarStyle, and let effectiveNavigationBarStyle return the shipping style. Whats-New: Tapping a tab sends a soft wave in the app's colour across the navigation bar, now with rounded corners. Whats-New-De: Ein Tipp auf einen Tab schickt eine sanfte Welle in der Farbe der App über die Navigationsleiste, jetzt mit abgerundeten Ecken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
97 lines
4.4 KiB
Markdown
97 lines
4.4 KiB
Markdown
# 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`; `FlushNavigationBar`, and `NavigationFrame`, every
|
|
app's frame around its tabs (the rail with the app's icon, the bar flush
|
|
with the foot with a fade above it, its rounded top corners and the
|
|
wave in the app's colour a tap sends over it, `shippingNavigationBarStyle`,
|
|
switched live in a debug build's `NavigationBarDebugSection`, a tick on every choice, a status such as a recording under way above
|
|
the bar), whichever router drives it;
|
|
`AppLoadingIndicator`, `ButtonLoadingIndicator`, `AppRefreshIndicator`;
|
|
`SectionCard`, `SliverCentered`, `EmptyListMessage`, `CountBadge`,
|
|
`TitleWithKicker`, `CollapsingRow`, `ScrollHidingFab`, `Shimmer` and `SkeletonBox`, `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 path, within the repository's workspace (an app's packages sit in
|
|
`apps/<app>/`), so a change to the package and to the apps using it is one commit:
|
|
|
|
```yaml
|
|
dependencies:
|
|
halkyon_ui:
|
|
path: ../../../packages/halkyon_ui
|
|
```
|
|
|
|
Then set the app up as `example/lib/main.dart` does:
|
|
|
|
```dart
|
|
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 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).
|