Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for text #20

Merged
merged 6 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/forui_example_build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ jobs:
- run: flutter analyze
- run: flutter test
- run: pod repo update
working-directory: samples/ios
working-directory: forui/example/ios
- run: flutter build ios --debug --no-codesign --no-pub
40 changes: 40 additions & 0 deletions forui/lib/src/theme/font.dart
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,43 @@ final class FFont with Diagnosticable {
heightScalar.hashCode;

}

/// Provides functions for working with [FFont]s.
extension FontTextStyle on TextStyle {

/// Returns a [TextStyle] scaled using the given [font].
///
/// ```dart
/// final font = FFont(
/// family: 'packages/forui/my-font',
/// sizeScalar: 2,
/// letterSpacingScalar: 3,
/// wordSpacingScalar: 4,
/// heightScalar: 5,
/// );
///
/// final style = TextStyle(
/// fontFamily: 'default-font',
/// fontSize: 1,
/// letterSpacing: 1,
/// wordSpacing: 1,
/// height: 1,
/// ).withFont(font);
///
/// print(style.fontFamily); // 'packages/forui/my-font'
/// print(style.fontSize); // 2
/// print(style.letterSpacing); // 3
/// print(style.wordSpacing); // 4
/// print(style.height); // 5
/// ```
TextStyle withFont(FFont font) => TextStyle(
fontFamily: font.family,
fontSize: _scale(fontSize, font.sizeScalar),
letterSpacing: _scale(letterSpacing, font.letterSpacingScalar),
wordSpacing: _scale(wordSpacing, font.wordSpacingScalar),
height: _scale(height, font.heightScalar),
);

double? _scale(double? value, double factor) => value == null ? null : value * factor;

}
12 changes: 9 additions & 3 deletions forui/lib/src/theme/style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@ final class FStyle with Diagnosticable {
final BorderRadius borderRadius;

/// Creates an [FStyle].
FStyle({BorderRadius? borderRadius}) : borderRadius = borderRadius ?? BorderRadius.circular(8);
FStyle({BorderRadius? borderRadius}):
borderRadius = borderRadius ?? BorderRadius.circular(8);

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius));
properties
.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius));
}

@override
bool operator ==(Object other) => identical(this, other) || other is FStyle && borderRadius == other.borderRadius;
bool operator ==(Object other) =>
identical(this, other) ||
other is FStyle &&
runtimeType == other.runtimeType &&
borderRadius == other.borderRadius;

@override
int get hashCode => borderRadius.hashCode;
Expand Down
30 changes: 27 additions & 3 deletions forui/lib/src/theme/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ import 'package:flutter/material.dart';

import 'package:forui/forui.dart';

/// Represents a ForUI theme.
/// Represents a Forui theme.
///
/// See [ThemeBuildContext.theme] for accessing the current theme.
class FTheme extends StatelessWidget {
/// Retrieves the theme data.

/// Retrieves the current theme data.
///
/// It is recommended to use [ThemeBuildContext.theme] to access the current theme instead.
static FThemeData of(BuildContext context) {
final theme = context.dependOnInheritedWidgetOfExactType<_InheritedTheme>();
return theme?.data ?? FThemes.zinc.light;
Expand Down Expand Up @@ -35,7 +40,14 @@ class FTheme extends StatelessWidget {
data: data,
child: Directionality(
textDirection: textDirection ?? Directionality.of(context),
child: child,
child: DefaultTextStyle(
// TODO: replace with configurable default font.
style: data.font.toTextStyle(
fontSize: 10,
color: data.colorScheme.foreground,
),
child: child,
),
),
);

Expand All @@ -55,3 +67,15 @@ class _InheritedTheme extends InheritedWidget {
@override
bool updateShouldNotify(covariant _InheritedTheme old) => data != old.data;
}

/// Provides functions for accessing the current [FThemeData].
extension ThemeBuildContext on BuildContext {

/// Retrieves the current [FThemeData] from an ancestor [FTheme]. Defaults to [FThemes.zinc.light] if there is no
/// ancestor [FTheme].
FThemeData get theme {
final theme = dependOnInheritedWidgetOfExactType<_InheritedTheme>();
return theme?.data ?? FThemes.zinc.light;
}

}
4 changes: 2 additions & 2 deletions forui/lib/src/theme/theme_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class FThemeData with Diagnosticable {
required this.font,
required this.style,
}):
boxStyle = FBoxStyle.inherit(colorScheme: colorScheme, font: font),
cardStyle = FCardStyle.inherit(colorScheme: colorScheme, font: font, style: style);
boxStyle = FBoxStyle.inherit(colorScheme: colorScheme),
cardStyle = FCardStyle.inherit(colorScheme: colorScheme, style: style);

/// Creates a copy of this [FThemeData] with the given properties replaced.
FThemeData copyWith({
Expand Down
9 changes: 4 additions & 5 deletions forui/lib/src/widgets/box/box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ class FBox extends StatelessWidget {

@override
Widget build(BuildContext context) {
final style = this.style ?? FTheme.of(context).boxStyle;

final FBoxStyle(:color, :text) = style ?? context.theme.boxStyle;
return ColoredBox(
color: style.color,
color: color,
child: Text(
text,
style: style.text,
this.text,
style: text.withFont(context.theme.font),
),
);
}
Expand Down
7 changes: 4 additions & 3 deletions forui/lib/src/widgets/box/box_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class FBoxStyle {
/// Creates a [FBoxStyle].
const FBoxStyle({required this.color, required this.text});

/// Creates a [FBoxStyle] that inherits its properties from [font] and [colorScheme].
FBoxStyle.inherit({required FColorScheme colorScheme, required FFont font}):
color = colorScheme.muted, text = font.toTextStyle(fontSize: 20);
/// Creates a [FBoxStyle] that inherits its properties from [colorScheme].
FBoxStyle.inherit({required FColorScheme colorScheme}):
color = colorScheme.muted,
text = const TextStyle(fontSize: 20);
}
7 changes: 4 additions & 3 deletions forui/lib/src/widgets/card/card.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';

import 'package:forui/forui.dart';

Expand Down Expand Up @@ -28,8 +29,8 @@ class FCard extends StatelessWidget {

@override
Widget build(BuildContext context) {
final style = this.style ?? FTheme.of(context).cardStyle;

final theme = context.theme;
final style = this.style ?? theme.cardStyle;
return DecoratedBox(
decoration: style.decoration,
child: child,
Expand Down
8 changes: 4 additions & 4 deletions forui/lib/src/widgets/card/card_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ final class FCardContent extends StatelessWidget {

@override
Widget build(BuildContext context) {
final style = this.style ?? FTheme.of(context).cardStyle.content;

final font = context.theme.font;
final style = this.style ?? context.theme.cardStyle.content;
return Padding(
padding: style.padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (title != null) Text(title!, style: style.title),
if (subtitle != null) Text(subtitle!, style: style.subtitle),
if (title != null) Text(title!, style: style.title.withFont(font)),
if (subtitle != null) Text(subtitle!, style: style.subtitle.withFont(font)),
if (child != null)
Padding(
padding: (title == null && subtitle == null) ? const EdgeInsets.only(top: 4) : const EdgeInsets.only(top: 10),
Expand Down
27 changes: 23 additions & 4 deletions forui/lib/src/widgets/card/card_content_style.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
part of 'card.dart';

/// [FCardContent]'s style.
class FCardContentStyle {
class FCardContentStyle with Diagnosticable {
/// The padding.
final EdgeInsets padding;

Expand All @@ -14,10 +14,10 @@ class FCardContentStyle {
/// Creates a [FCardContentStyle].
const FCardContentStyle({required this.padding, required this.title, required this.subtitle});

/// Creates a [FCardContentStyle] that inherits its properties from [colorScheme] and [font].
FCardContentStyle.inherit({required FColorScheme colorScheme, required FFont font}):
/// Creates a [FCardContentStyle] that inherits its properties from [colorScheme].
FCardContentStyle.inherit({required FColorScheme colorScheme}):
padding = const EdgeInsets.fromLTRB(16, 12, 16, 16),
title = font.toTextStyle(
title = TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: colorScheme.foreground,
Expand All @@ -27,4 +27,23 @@ class FCardContentStyle {
color: colorScheme.mutedForeground,
);

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty<EdgeInsets>('padding', padding))
..add(DiagnosticsProperty<TextStyle>('title', title))
..add(DiagnosticsProperty<TextStyle>('subtitle', subtitle));
}

@override
bool operator ==(Object other) => identical(this, other) || other is FCardContentStyle &&
runtimeType == other.runtimeType &&
padding == other.padding &&
title == other.title &&
subtitle == other.subtitle;

@override
int get hashCode => padding.hashCode ^ title.hashCode ^ subtitle.hashCode;

}
33 changes: 25 additions & 8 deletions forui/lib/src/widgets/card/card_style.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
part of 'card.dart';

/// [FCard]'s style.
class FCardStyle {
final class FCardStyle with Diagnosticable {
/// The decoration.
final BoxDecoration decoration;

Expand All @@ -11,11 +11,28 @@ class FCardStyle {
/// Creates a [FCardStyle].
FCardStyle({required this.decoration, required this.content});

/// Creates a [FCardStyle] that inherits its properties from [colorScheme] and [font].
FCardStyle.inherit({required FColorScheme colorScheme, required FFont font, required FStyle style})
: decoration = BoxDecoration(
border: Border.all(color: colorScheme.border),
borderRadius: style.borderRadius,
),
content = FCardContentStyle.inherit(colorScheme: colorScheme, font: font);
/// Creates a [FCardStyle] that inherits its properties from [colorScheme] and [style].
FCardStyle.inherit({required FColorScheme colorScheme, required FStyle style}):
decoration = BoxDecoration(
border: Border.all(color: colorScheme.border),
borderRadius: style.borderRadius,
),
content = FCardContentStyle.inherit(colorScheme: colorScheme);

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
.add(DiagnosticsProperty<FCardContentStyle>('content', content));
}

@override
bool operator ==(Object other) => identical(this, other) || other is FCardStyle &&
runtimeType == other.runtimeType &&
decoration == other.decoration &&
content == other.content;

@override
int get hashCode => decoration.hashCode ^ content.hashCode;

}
Loading