Skip to content

Commit

Permalink
tabs with tab content
Browse files Browse the repository at this point in the history
  • Loading branch information
Daviiddoo committed Jun 16, 2024
1 parent 1164475 commit 071e395
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 70 deletions.
8 changes: 8 additions & 0 deletions forui/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ class ExampleWidget extends StatelessWidget {
'text-lg',
style: TextStyle(fontSize: font.lg).withFont(font),
),
const SizedBox(height: 10),
FTabs(
tabs: [
('Account', FTabContent(child: Column(children: [Container(color: Colors.red, height: 30,)],),)),
('Password', FTabContent(child: Column(children: [Container(color: Colors.blue, height: 30,)],),)),
],

)
],
);
}
Expand Down
12 changes: 6 additions & 6 deletions forui/example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@ packages:
dependency: "direct dev"
description:
name: build_runner
sha256: "1414d6d733a85d8ad2f1dfcb3ea7945759e35a123cb99ccfac75d0758f75edfa"
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7"
url: "https://pub.dev"
source: hosted
version: "2.4.10"
version: "2.4.11"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe
url: "https://pub.dev"
source: hosted
version: "7.3.0"
version: "7.3.1"
built_collection:
dependency: transitive
description:
Expand Down Expand Up @@ -485,10 +485,10 @@ packages:
dependency: transitive
description:
name: platform
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
Expand Down
1 change: 1 addition & 0 deletions forui/lib/forui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ export 'src/widgets/header/header.dart';
export 'src/widgets/box.dart';
export 'src/widgets/separator.dart';
export 'src/widgets/switch.dart';
export 'src/widgets/tabs/tabs.dart';
95 changes: 95 additions & 0 deletions forui/lib/src/widgets/tabs/tab_content.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
part of 'tabs.dart';

final class FTabContent extends StatelessWidget {
final String? title;
final String? subtitle;
final Widget? child;
final FCardContentStyle? style;

const FTabContent({this.title, this.subtitle, this.child, this.style, super.key});

@override
Widget build(BuildContext context) {
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.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),
child: child!,
),
],
),
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(StringProperty('title', title))
..add(StringProperty('subtitle', subtitle))
..add(DiagnosticsProperty('style', style));
}
}

/// A card content's style.
final class FTabContentStyle with Diagnosticable {

/// The padding.
final EdgeInsets padding;

/// The title.
final TextStyle title;

/// The subtitle.
final TextStyle subtitle;

/// Creates a [FTabContentStyle].
const FTabContentStyle({required this.padding, required this.title, required this.subtitle});

/// Creates a [FCardContentStyle] that inherits its properties from [colorScheme] and [font].
FTabContentStyle.inherit({required FColorScheme colorScheme, required FFont font}):
padding = const EdgeInsets.fromLTRB(16, 12, 16, 16),
title = TextStyle(
fontSize: font.base,
fontWeight: FontWeight.w600,
color: colorScheme.foreground,
),
subtitle = TextStyle(
fontSize: font.sm,
color: colorScheme.mutedForeground,
);

/// Creates a copy of this [FCardContentStyle] with the given properties replaced.
FTabContentStyle copyWith({EdgeInsets? padding, TextStyle? title, TextStyle? subtitle}) => FTabContentStyle(
padding: padding ?? this.padding,
title: title ?? this.title,
subtitle: subtitle ?? this.subtitle,
);

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(DiagnosticsProperty('padding', padding))
..add(DiagnosticsProperty('title', title))
..add(DiagnosticsProperty('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;
}
94 changes: 53 additions & 41 deletions forui/lib/src/widgets/tabs/tabs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,23 @@ import 'package:flutter/foundation.dart';

part 'tabs_style.dart';

part 'tab_content.dart';

/// A [FTabs] that allows switching between tabs.
class FTabs extends StatelessWidget {
/// The tab and it's corresponding view.
final List<(String, Widget)> tabs;

/// The heigh of the toggle bar.
/// The height of the tab button.
final double? height;

/// The padding around the tabs.
final EdgeInsets padding;
/// The spacing between the tabs and its content.
final double spacing;

/// A callback that returns the tab that was tapped.
final ValueChanged<int>? onTap;

/// The initial tab that is displayed.
/// The initial tab that is selected.
final int initialIndex;

/// The style.
Expand All @@ -28,7 +30,7 @@ class FTabs extends StatelessWidget {
const FTabs({
required this.tabs,
this.height,
this.padding = EdgeInsets.zero,
this.spacing = 2,
this.onTap,
this.initialIndex = 0,
this.style,
Expand All @@ -40,43 +42,53 @@ class FTabs extends StatelessWidget {
final style = this.style ?? context.theme.tabsStyle;

return DefaultTabController(
initialIndex: initialIndex,
length: tabs.length,
child: Column(
children: [
Container(
padding: padding,
child: DecoratedBox(
decoration: style.decoration,
child: TabBar(
indicatorSize: TabBarIndicatorSize.tab,
onTap: onTap,
padding: style.padding,
unselectedLabelColor: style.unselectedColor,
unselectedLabelStyle: style.unselectedLabel,
labelStyle: style.selectedLabel,
labelColor: style.selectedColor,
indicatorColor: Colors.transparent,
dividerColor: Colors.transparent,
indicator: style.indicator,
tabs: [
for (final (text, _) in tabs)
Tab(
height: height,
child: Text(text),
)
],
),
),
initialIndex: initialIndex,
length: tabs.length,
child: Column(
children: [
DecoratedBox(
decoration: style.decoration,
child: TabBar(
indicatorSize: TabBarIndicatorSize.tab,
onTap: onTap,
padding: style.padding,
unselectedLabelStyle: style.unselectedLabel,
unselectedLabelColor: style.unselectedColor,
labelStyle: style.selectedLabel,
labelColor: style.selectedColor,
indicatorColor: Colors.transparent,
dividerColor: Colors.transparent,
indicator: style.indicator,
tabs: [
for (final (text, _) in tabs)
Tab(
height: height,
child: Text(text),
)
],
),
Expanded(
child: TabBarView(
physics: const BouncingScrollPhysics(),
children: [for (final (_, widget) in tabs) widget],
),
),
SizedBox(height: spacing),
Flexible(
child: TabBarView(
physics: const BouncingScrollPhysics(),
children: [for (final (_, widget) in tabs) widget],
),
],
),
);
),
],
),
);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties
..add(IterableProperty<(String, Widget)>('tabs', tabs))
..add(DoubleProperty('height', height))
..add(DiagnosticsProperty<double>('spacing', spacing))
..add(ObjectFlagProperty<ValueChanged<int>?>.has('onTap', onTap))
..add(IntProperty('initialIndex', initialIndex))
..add(DiagnosticsProperty<FTabsStyle?>('style', style));
}
}
Loading

0 comments on commit 071e395

Please sign in to comment.