Skip to content

Commit 9dc5085

Browse files
committed
ThemedTabStyle
1 parent 6b7dc90 commit 9dc5085

7 files changed

Lines changed: 93 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Changelog
22

3+
## 7.4.10
4+
5+
- New `ThemedTabStyle` enum to define the style of the `ThemedTabView` tabs.
6+
37
## 7.4.9
8+
49
- Add `additionalWidgets` in `ThemedTabView`.
510

611
## 7.4.8

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ packages:
374374
path: ".."
375375
relative: true
376376
source: path
377-
version: "7.4.9"
377+
version: "7.4.10"
378378
leak_tracker:
379379
dependency: transitive
380380
description:

lib/src/tabs/src/style.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
part of '../tabs.dart';
2+
3+
enum ThemedTabStyle {
4+
/// Styling as a text button when active with an underline
5+
underline,
6+
7+
/// Styling as a filled tonal button when active
8+
filledTonal,
9+
}

lib/src/tabs/src/tab.dart

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ class ThemedTab extends StatelessWidget {
3838
/// This information is only used when the tab is a child of a [ThemedTabView]
3939
final Widget child;
4040

41+
/// [style] is the style of the tab
42+
final ThemedTabStyle style;
43+
4144
/// [ThemedTab] is a tab for the [TabBar] widget
4245
const ThemedTab({
4346
super.key,
@@ -51,34 +54,75 @@ class ThemedTab extends StatelessWidget {
5154
this.padding = const EdgeInsets.all(10),
5255
this.color,
5356
this.child = const SizedBox(),
57+
this.style = ThemedTabStyle.filledTonal,
5458
}) : assert(labelText != null || label != null);
5559

60+
ThemedTab overrideStyle(ThemedTabStyle newStyle) {
61+
return ThemedTab(
62+
key: key,
63+
labelText: labelText,
64+
label: label,
65+
iconSize: iconSize,
66+
leading: leading,
67+
leadingIcon: leadingIcon,
68+
trailing: trailing,
69+
trailingIcon: trailingIcon,
70+
padding: padding,
71+
color: color,
72+
child: child,
73+
style: newStyle,
74+
);
75+
}
76+
5677
@override
5778
Widget build(BuildContext context) {
58-
return Padding(
79+
final primary = Theme.of(context).colorScheme.primary;
80+
Color backgroundColor = color ?? DefaultTextStyle.of(context).style.color ?? primary;
81+
final bool redMatch = primary.r == backgroundColor.r;
82+
final bool greenMatch = primary.g == backgroundColor.g;
83+
final bool blueMatch = primary.b == backgroundColor.b;
84+
85+
final isActive = redMatch && greenMatch && blueMatch;
86+
87+
return AnimatedContainer(
88+
duration: const Duration(milliseconds: 200),
5989
padding: padding,
60-
child: Row(
61-
children: [
62-
if (leading != null || leadingIcon != null) ...[
63-
leading ??
64-
Icon(
65-
leadingIcon!,
66-
size: iconSize,
67-
color: color,
90+
decoration: style == ThemedTabStyle.filledTonal
91+
? BoxDecoration(
92+
color: isActive ? backgroundColor.withAlpha((255 * 0.2).toInt()) : Colors.transparent,
93+
borderRadius: BorderRadius.circular(8),
94+
)
95+
: null,
96+
child: Padding(
97+
padding: const EdgeInsets.symmetric(horizontal: 10),
98+
child: RichText(
99+
text: TextSpan(
100+
children: [
101+
if (leading != null || leadingIcon != null) ...[
102+
WidgetSpan(
103+
alignment: PlaceholderAlignment.middle,
104+
child: leading ?? Icon(leadingIcon!, size: iconSize, color: backgroundColor),
105+
),
106+
const WidgetSpan(child: SizedBox(width: 10)),
107+
],
108+
if (label != null) ...[
109+
WidgetSpan(child: label!),
110+
] else ...[
111+
TextSpan(
112+
text: labelText,
113+
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: backgroundColor),
68114
),
69-
const SizedBox(width: 10),
70-
],
71-
label ?? Text(labelText ?? '', style: TextStyle(color: color)),
72-
if (trailing != null || trailingIcon != null) ...[
73-
const SizedBox(width: 10),
74-
trailing ??
75-
Icon(
76-
trailingIcon!,
77-
size: iconSize,
78-
color: color,
115+
],
116+
if (trailing != null || trailingIcon != null) ...[
117+
const WidgetSpan(child: SizedBox(width: 10)),
118+
WidgetSpan(
119+
alignment: PlaceholderAlignment.middle,
120+
child: trailing ?? Icon(trailingIcon!, size: iconSize, color: backgroundColor),
79121
),
80-
],
81-
],
122+
],
123+
],
124+
),
125+
),
82126
),
83127
);
84128
}

lib/src/tabs/src/view.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class ThemedTabView extends StatefulWidget {
3939
/// [additionalWidgets] are additional widgets to display in the tab bar view
4040
final List<Widget> additionalWidgets;
4141

42+
/// [style] is the style of the tab view
43+
final ThemedTabStyle style;
44+
4245
/// [ThemedTabView] is a tab for the [TabBar] widget
4346
///
4447
/// Be careful!
@@ -57,6 +60,7 @@ class ThemedTabView extends StatefulWidget {
5760
this.initialPosition = 0,
5861
this.onTabIndex,
5962
this.additionalWidgets = const [],
63+
this.style = ThemedTabStyle.filledTonal,
6064
});
6165

6266
@override
@@ -122,7 +126,10 @@ class _ThemedTabViewState extends State<ThemedTabView> with TickerProviderStateM
122126
children: [
123127
Theme(
124128
data: Theme.of(context).copyWith(
125-
tabBarTheme: Theme.of(context).tabBarTheme.copyWith(tabAlignment: TabAlignment.start),
129+
tabBarTheme: Theme.of(context).tabBarTheme.copyWith(
130+
tabAlignment: TabAlignment.start,
131+
indicatorColor: widget.style == ThemedTabStyle.filledTonal ? Colors.transparent : null,
132+
),
126133
),
127134
child: Row(
128135
children: [
@@ -146,7 +153,9 @@ class _ThemedTabViewState extends State<ThemedTabView> with TickerProviderStateM
146153
Expanded(
147154
child: TabBar(
148155
isScrollable: true,
149-
tabs: widget.tabs,
156+
tabs: widget.tabs.map((e) => e.overrideStyle(widget.style)).toList(),
157+
labelPadding: EdgeInsets.zero,
158+
splashBorderRadius: widget.style == ThemedTabStyle.filledTonal ? BorderRadius.circular(8) : null,
150159
controller: _tabController,
151160
),
152161
),

lib/src/tabs/tabs.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ import 'package:layrz_theme/src/buttons/buttons.dart';
66

77
part 'src/tab.dart';
88
part 'src/view.dart';
9+
part 'src/style.dart';

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: layrz_theme
22
description: Layrz standard styling library for Flutter. Widget library following the Material Design 3 guidelines, with a focus on reliavility and functionality.
3-
version: "7.4.9"
3+
version: "7.4.10"
44
homepage: https://theme.layrz.com
55
repository: https://github.com/goldenm-software/layrz_theme
66

0 commit comments

Comments
 (0)