garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme, docs under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
106 lines
3.6 KiB
Dart
106 lines
3.6 KiB
Dart
import "package:flutter/widgets.dart";
|
|
import "package:google_fonts/google_fonts.dart";
|
|
|
|
import "package:garage_ui/theme/garage_theme.dart";
|
|
|
|
// The apps type scale. shadcn exposed a big Typography object; the GarageUI widgets
|
|
// only reach for the small set below. `small` is a size style, `medium`/`normal`
|
|
// are weight styles, and `mono` swaps the font family while inheriting the
|
|
// ambient size/weight unless a caller overrides them.
|
|
class Typography {
|
|
const Typography({
|
|
this.normal = const TextStyle(fontWeight: FontWeight.w400),
|
|
this.medium = const TextStyle(fontWeight: FontWeight.w500),
|
|
this.semiBold = const TextStyle(fontWeight: FontWeight.w600),
|
|
// `small` is the shared control font used by buttons, fields and selects.
|
|
// Prefer [Typography.forDensity] over setting this by hand - the size
|
|
// and line height belong to the density, and the whole control geometry
|
|
// chain hangs off them.
|
|
this.small = const TextStyle(
|
|
fontSize: 10,
|
|
height: 1.1,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
});
|
|
|
|
/// Builds the control type from the density, so `small` can never drift from
|
|
/// the line box the control heights are derived from.
|
|
factory Typography.forDensity(Density density) => Typography(
|
|
small: TextStyle(
|
|
fontSize: density.fontSize,
|
|
height: density.lineHeight,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
);
|
|
|
|
final TextStyle normal;
|
|
final TextStyle medium;
|
|
|
|
/// Emphasis above [medium] - section labels, a dialog's title. Was a
|
|
/// FontWeight.w600 literal in menu.dart, properties.dart and toast.dart.
|
|
final TextStyle semiBold;
|
|
final TextStyle small;
|
|
|
|
TextStyle sansStyle(TextStyle style) =>
|
|
GoogleFonts.geist(textStyle: style, fontWeight: style.fontWeight);
|
|
|
|
TextStyle get mono => GoogleFonts.geistMono();
|
|
|
|
TextStyle monoStyle(TextStyle style) =>
|
|
GoogleFonts.geistMono(textStyle: style, fontWeight: style.fontWeight);
|
|
}
|
|
|
|
// shadcn hung these little text helpers off every widget (usually a Text). they
|
|
// merge a style change over whatever DefaultTextStyle is in scope. sizes are
|
|
// multiplied by the theme scaling so they track the rest of the ui.
|
|
extension TextStyleExtension on Widget {
|
|
// sizes come off the density's text ladder, NOT a literal times scaling -
|
|
// see Density.textXs for why. scaling is left out on purpose: Density isn't
|
|
// scaled, and these have to stay in step with the control font.
|
|
Widget xSmall() => _StyledText(
|
|
child: this,
|
|
style: (t) => TextStyle(fontSize: t.density.textXs),
|
|
);
|
|
Widget small() => _StyledText(
|
|
child: this,
|
|
style: (t) => TextStyle(fontSize: t.density.textSm),
|
|
);
|
|
Widget large() => _StyledText(
|
|
child: this,
|
|
style: (t) => TextStyle(fontSize: t.density.textLg),
|
|
);
|
|
|
|
Widget medium() => _StyledText(
|
|
child: this,
|
|
style: (t) => const TextStyle(fontWeight: FontWeight.w500),
|
|
);
|
|
Widget semiBold() => _StyledText(
|
|
child: this,
|
|
style: (t) => const TextStyle(fontWeight: FontWeight.w600),
|
|
);
|
|
Widget bold() => _StyledText(
|
|
child: this,
|
|
style: (t) => const TextStyle(fontWeight: FontWeight.w700),
|
|
);
|
|
|
|
Widget muted() => _StyledText(
|
|
child: this,
|
|
style: (t) => TextStyle(color: t.colorScheme.mutedForeground),
|
|
);
|
|
}
|
|
|
|
typedef _StyleFromTheme = TextStyle Function(ThemeData theme);
|
|
|
|
class _StyledText extends StatelessWidget {
|
|
const _StyledText({required this.child, required this.style});
|
|
|
|
final Widget child;
|
|
final _StyleFromTheme style;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = GarageTheme.of(context);
|
|
return DefaultTextStyle.merge(style: style(theme), child: child);
|
|
}
|
|
}
|