Skip to content

Commit

Permalink
feat: add text style editing support to bottom navigation bar theme e…
Browse files Browse the repository at this point in the history
…ditor (#549)
  • Loading branch information
zeshuaro authored Dec 18, 2022
1 parent 1d5d77a commit 6d96463
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 37 deletions.
14 changes: 13 additions & 1 deletion lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ class MyApp extends StatelessWidget {
unselectedLabelTextStyleCubit: tabBarUnselectedLabelTextStyleCubit,
);

final bottomNavigationBarThemeCubit = BottomNavigationBarThemeCubit();
final bottomNavigationBarLabelTextStyleCubit =
BottomNavigationBarLabelTextStyleCubit();
final bottomNavigationBarUnselectedLabelTextStyleCubit =
BottomNavigationBarUnselectedLabelTextStyleCubit();
final bottomNavigationBarThemeCubit = BottomNavigationBarThemeCubit(
labelTextStyleCubit: bottomNavigationBarLabelTextStyleCubit,
unselectedLabelTextStyleCubit:
bottomNavigationBarUnselectedLabelTextStyleCubit,
);

final floatingActionButtonThemeCubit = FloatingActionButtonThemeCubit();
final elevatedButtonThemeCubit = ElevatedButtonThemeCubit(
Expand Down Expand Up @@ -156,6 +164,10 @@ class MyApp extends StatelessWidget {
BlocProvider(create: (_) => tabBarLabelTextStyleCubit),
BlocProvider(create: (_) => tabBarUnselectedLabelTextStyleCubit),
BlocProvider(create: (_) => bottomNavigationBarThemeCubit),
BlocProvider(create: (_) => bottomNavigationBarLabelTextStyleCubit),
BlocProvider(
create: (_) => bottomNavigationBarUnselectedLabelTextStyleCubit,
),
BlocProvider(create: (_) => floatingActionButtonThemeCubit),
BlocProvider(create: (_) => elevatedButtonThemeCubit),
BlocProvider(create: (_) => outlinedButtonThemeCubit),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,70 @@
import 'dart:async';

import 'package:appainter/abstract_text_style/abstract_text_style.dart';
import 'package:appainter/services/services.dart';
import 'package:appainter_annotations/annotations.dart';
import 'package:bloc/bloc.dart';
import 'package:copy_with_extension/copy_with_extension.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:appainter/services/util_service.dart';

part 'bottom_navigation_bar_theme_cubit.g.dart';
part 'bottom_navigation_bar_theme_state.dart';

const _labelTypeScale = TypeScale.bodyText2;

@ThemeDocs(
apiClassName: 'BottomNavigationBarThemeData',
extraPropertyTypes: {'BottomNavigationBarType'},
)
class BottomNavigationBarThemeCubit
extends Cubit<BottomNavigationBarThemeState> {
BottomNavigationBarThemeCubit()
: super(const BottomNavigationBarThemeState());
BottomNavigationBarThemeCubit({
required this.labelTextStyleCubit,
required this.unselectedLabelTextStyleCubit,
}) : super(const BottomNavigationBarThemeState()) {
labelTextStyleCubitSubscription = labelTextStyleCubit.stream.listen(
(otherState) {
final theme = state.theme.copyWith(
selectedLabelStyle: otherState.style,
);
emit(state.copyWith(theme: theme));
},
);
unselectedLabelTextStyleCubitSubscription =
unselectedLabelTextStyleCubit.stream.listen(
(otherState) {
final theme = state.theme.copyWith(
unselectedLabelStyle: otherState.style,
);
emit(state.copyWith(theme: theme));
},
);
}

final BottomNavigationBarLabelTextStyleCubit labelTextStyleCubit;
final BottomNavigationBarUnselectedLabelTextStyleCubit
unselectedLabelTextStyleCubit;

late final StreamSubscription labelTextStyleCubitSubscription;
late final StreamSubscription unselectedLabelTextStyleCubitSubscription;

static final defaultLabelTextStyle = kWhiteTextStyles[_labelTypeScale]!;

@override
Future<void> close() {
labelTextStyleCubitSubscription.cancel();
unselectedLabelTextStyleCubitSubscription.cancel();
return super.close();
}

void themeChanged(BottomNavigationBarThemeData theme) {
labelTextStyleCubit.styleChanged(
theme.selectedLabelStyle ?? defaultLabelTextStyle,
);
unselectedLabelTextStyleCubit.styleChanged(
theme.unselectedLabelStyle ?? defaultLabelTextStyle,
);
emit(state.copyWith(theme: theme));
}

Expand Down Expand Up @@ -69,3 +116,14 @@ class BottomNavigationBarThemeCubit
}
}
}

class BottomNavigationBarLabelTextStyleCubit extends AbstractTextStyleCubit {
BottomNavigationBarLabelTextStyleCubit()
: super(typeScale: _labelTypeScale, isBaseStyleBlack: false);
}

class BottomNavigationBarUnselectedLabelTextStyleCubit
extends AbstractTextStyleCubit {
BottomNavigationBarUnselectedLabelTextStyleCubit()
: super(typeScale: _labelTypeScale, isBaseStyleBlack: false);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:appainter/abstract_text_style/abstract_text_style.dart';
import 'package:appainter/bottom_navigation_bar_theme/bottom_navigation_bar_theme.dart';
import 'package:appainter/color_theme/color_theme.dart';
import 'package:appainter/common/common.dart';
import 'package:appainter/services/services.dart';
import 'package:appainter/widgets/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class BottomNavigationBarThemeEditor extends ExpansionPanelItem {
const BottomNavigationBarThemeEditor({Key? key}) : super(key: key);
Expand All @@ -14,16 +15,32 @@ class BottomNavigationBarThemeEditor extends ExpansionPanelItem {

@override
Widget build(BuildContext context) {
return SideBySideList(
padding: kPaddingAll,
return NestedListView(
children: [
_TypeDropdown(),
_BackgroundColorPicker(),
_SelectedItemColorPicker(),
_UnselectedItemColorPicker(),
_ShowSelectedLabelsSwitch(),
_ShowUnselectedLabelsSwitch(),
_ElevationTextField(),
SideBySideList(
padding: kPaddingAll,
children: [
_TypeDropdown(),
_BackgroundColorPicker(),
_SelectedItemColorPicker(),
_UnselectedItemColorPicker(),
_ShowSelectedLabelsSwitch(),
_ShowUnselectedLabelsSwitch(),
_ElevationTextField(),
],
),
MyExpansionPanelList(
items: const [
_LabelTextStyleCard(
key: Key('bottomNavigationBarThemeEditor_labelTextStyleCard'),
),
_UnselectedLabelTextStyleCard(
key: Key(
'bottomNavigationBarThemeEditor_unselectedLabelTextStyleCard',
),
),
],
)
],
);
}
Expand Down Expand Up @@ -211,3 +228,25 @@ class _ElevationTextField extends StatelessWidget {
);
}
}

class _LabelTextStyleCard
extends AbstractTextStyleEditor<BottomNavigationBarLabelTextStyleCubit> {
const _LabelTextStyleCard({Key? key}) : super(key: key);

@override
String get header => 'Label text style';

@override
String? get tooltip => BottomNavigationBarThemeDocs.selectedLabelStyle;
}

class _UnselectedLabelTextStyleCard extends AbstractTextStyleEditor<
BottomNavigationBarUnselectedLabelTextStyleCubit> {
const _UnselectedLabelTextStyleCard({Key? key}) : super(key: key);

@override
String get header => 'Unselected label text style';

@override
String? get tooltip => BottomNavigationBarThemeDocs.unselectedLabelStyle;
}
2 changes: 1 addition & 1 deletion lib/tab_bar_theme/view/tab_bar_theme_editor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class TabBarThemeEditor extends ExpansionPanelItem {
key: Key('tabBarThemeEditor_unselectedLabelTextStyleCard'),
),
],
)
),
],
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,33 @@
import 'dart:math';

import 'package:appainter/abstract_text_style/abstract_text_style.dart';
import 'package:appainter/bottom_navigation_bar_theme/bottom_navigation_bar_theme.dart';
import 'package:appainter/services/services.dart';
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:appainter/bottom_navigation_bar_theme/bottom_navigation_bar_theme.dart';
import 'package:appainter/services/services.dart';
import 'package:random_color_scheme/random_color_scheme.dart';

import '../utils.dart';

void main() {
late BottomNavigationBarThemeCubit cubit;
late BottomNavigationBarLabelTextStyleCubit labelTextStyleCubit;
late BottomNavigationBarUnselectedLabelTextStyleCubit
unselectedLabelTextStyleCubit;

late BottomNavigationBarThemeData theme;
late Color color;
late double doubleValue;

setUp(() {
cubit = BottomNavigationBarThemeCubit();
labelTextStyleCubit = BottomNavigationBarLabelTextStyleCubit();
unselectedLabelTextStyleCubit =
BottomNavigationBarUnselectedLabelTextStyleCubit();
cubit = BottomNavigationBarThemeCubit(
labelTextStyleCubit: labelTextStyleCubit,
unselectedLabelTextStyleCubit: unselectedLabelTextStyleCubit,
);
color = getRandomColor();
doubleValue = Random().nextDouble();

Expand All @@ -25,10 +36,26 @@ void main() {
});

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit theme',
'emit theme',
build: () => cubit,
act: (cubit) => cubit.themeChanged(theme),
expect: () => [BottomNavigationBarThemeState(theme: theme)],
expect: () => [
BottomNavigationBarThemeState(theme: theme),
BottomNavigationBarThemeState(
theme: theme.copyWith(
selectedLabelStyle:
BottomNavigationBarThemeCubit.defaultLabelTextStyle,
),
),
BottomNavigationBarThemeState(
theme: theme.copyWith(
selectedLabelStyle:
BottomNavigationBarThemeCubit.defaultLabelTextStyle,
unselectedLabelStyle:
BottomNavigationBarThemeCubit.defaultLabelTextStyle,
),
),
],
);

group('test type', () {
Expand All @@ -37,7 +64,7 @@ void main() {
type == BottomNavigationBarType.shifting ? false : true;

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit $type',
'emit $type',
build: () => cubit,
act: (cubit) => cubit.typeChanged(UtilService.enumToString(type)),
expect: () {
Expand All @@ -55,7 +82,7 @@ void main() {
});

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit background color',
'emit background color',
build: () => cubit,
act: (cubit) => cubit.backgroundColorChanged(color),
expect: () {
Expand All @@ -68,7 +95,7 @@ void main() {
);

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit selected item color',
'emit selected item color',
build: () => cubit,
act: (cubit) => cubit.selectedItemColorChanged(color),
expect: () {
Expand All @@ -81,7 +108,7 @@ void main() {
);

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit unselected item color',
'emit unselected item color',
build: () => cubit,
act: (cubit) => cubit.unselectedItemColorChanged(color),
expect: () {
Expand All @@ -96,7 +123,7 @@ void main() {
group('test show selected labels', () {
for (var isShow in [true, false]) {
blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit $isShow',
'emit $isShow',
build: () => cubit,
act: (cubit) => cubit.showSelectedLabelsChanged(isShow),
expect: () {
Expand All @@ -113,7 +140,7 @@ void main() {
group('test show unselected labels', () {
for (var isShow in [true, false]) {
blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit $isShow',
'emit $isShow',
build: () => cubit,
act: (cubit) => cubit.showUnselectedLabelsChanged(isShow),
expect: () {
Expand All @@ -128,7 +155,7 @@ void main() {
});

blocTest<BottomNavigationBarThemeCubit, BottomNavigationBarThemeState>(
'should emit elevation',
'emit elevation',
build: () => cubit,
act: (cubit) => cubit.elevationChanged(doubleValue.toString()),
expect: () {
Expand All @@ -139,4 +166,16 @@ void main() {
];
},
);

test('initialise label text style cubit', () {
final cubit = BottomNavigationBarLabelTextStyleCubit();
expect(cubit.typeScale, equals(TypeScale.bodyText2));
expect(cubit.isBaseStyleBlack, equals(false));
});

test('initialise unselected label text style cubit', () {
final cubit = BottomNavigationBarUnselectedLabelTextStyleCubit();
expect(cubit.typeScale, equals(TypeScale.bodyText2));
expect(cubit.isBaseStyleBlack, equals(false));
});
}
Loading

0 comments on commit 6d96463

Please sign in to comment.