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

fix(UX-1242): Fixed extended app bar alignment #189

Merged
merged 8 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
78 changes: 9 additions & 69 deletions example/lib/pages/components/top_app_bar_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,7 @@ class TopAppBarExample extends StatefulWidget {
}

class _TopAppBarExampleState extends State<TopAppBarExample> {
final _searchControllerExtended = ZetaSearchController();
final _searchControllerRegular = ZetaSearchController();

void _showHideSearchExtended() {
_searchControllerExtended.isEnabled
? _searchControllerExtended.closeSearch()
: _searchControllerExtended.startSearch();
}

void _showHideSearchRegular() {
_searchControllerRegular.isEnabled
? _searchControllerRegular.closeSearch()
: _searchControllerRegular.startSearch();
}
final _searchController = ZetaSearchController();

@override
Widget build(BuildContext context) {
Expand Down Expand Up @@ -78,8 +65,7 @@ class _TopAppBarExampleState extends State<TopAppBarExample> {
],
),
Text('Centered', style: ZetaTextStyles.titleLarge),
ZetaTopAppBar(
type: ZetaTopAppBarType.centeredTitle,
ZetaTopAppBar.centered(
leading: IconButton(
onPressed: () {},
icon: ZetaIcon(Icons.menu),
Expand Down Expand Up @@ -119,24 +105,20 @@ class _TopAppBarExampleState extends State<TopAppBarExample> {
],
),
Text('Search', style: ZetaTextStyles.titleLarge),
ZetaTopAppBar(
type: ZetaTopAppBarType.centeredTitle,
leading: BackButton(),
ZetaTopAppBar.search(
leading: IconButton(
onPressed: () {},
icon: ZetaIcon(Icons.menu),
),
title: Text("Title"),
actions: [
IconButton(
onPressed: _showHideSearchRegular,
icon: ZetaIcon(ZetaIcons.search),
)
],
searchController: _searchControllerRegular,
searchController: _searchController,
onSearch: (text) => debugPrint('search text: $text'),
onSearchMicrophoneIconPressed: () async {
var sampleTexts = ['This is a sample text', 'Another sample', 'Speech recognition text', 'Example'];

var generatedText = sampleTexts[Random().nextInt(sampleTexts.length)];

_searchControllerRegular.text = generatedText;
_searchController.text = generatedText;
},
),
Text('Extended', style: ZetaTextStyles.titleLarge),
Expand Down Expand Up @@ -188,48 +170,6 @@ class _TopAppBarExampleState extends State<TopAppBarExample> {
],
),
),
Text('Extended Search', style: ZetaTextStyles.titleLarge),
SizedBox(
width: 800,
height: 200,
child: CustomScrollView(
slivers: [
ZetaTopAppBar.extended(
leading: BackButton(),
title: Text("Title"),
actions: [
IconButton(
onPressed: _showHideSearchExtended,
icon: ZetaIcon(ZetaIcons.search),
)
],
searchController: _searchControllerExtended,
onSearch: (text) => debugPrint('search text: $text'),
onSearchMicrophoneIconPressed: () async {
var sampleTexts = [
'This is a sample text',
'Another sample',
'Speech recognition text',
'Example'
];
var generatedText = sampleTexts[Random().nextInt(sampleTexts.length)];
_searchControllerExtended.text = generatedText;
},
),
SliverToBoxAdapter(
child: Container(
width: 800,
height: 800,
color: Zeta.of(context).colors.surfaceSelectedHover,
child: CustomPaint(
painter: Painter(context: context),
size: Size(800, 800),
),
),
),
],
),
),
].gap(20),
),
),
Expand Down
1 change: 0 additions & 1 deletion example/widgetbook/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ class _HotReloadState extends State<HotReload> {
useCases: [
WidgetbookUseCase(name: 'Default', builder: (context) => defaultTopAppBarUseCase(context)),
WidgetbookUseCase(name: 'Search', builder: (context) => searchTopAppBarUseCase(context)),
WidgetbookUseCase(name: 'Extended', builder: (context) => extendedTopAppBarUseCase(context)),
],
),
WidgetbookComponent(
Expand Down
107 changes: 4 additions & 103 deletions example/widgetbook/pages/components/top_app_bar_widgetbook.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Widget defaultTopAppBarUseCase(BuildContext context) {
label: "Title Alignment",
options: [
ZetaTopAppBarType.defaultAppBar,
ZetaTopAppBarType.centeredTitle,
ZetaTopAppBarType.centered,
],
initialOption: ZetaTopAppBarType.defaultAppBar,
labelBuilder: (option) {
Expand Down Expand Up @@ -53,7 +53,7 @@ Widget defaultTopAppBarUseCase(BuildContext context) {
icon: ZetaIcon(ZetaIcons.more_vertical),
)
]
: null,
: [],
),
],
));
Expand Down Expand Up @@ -84,7 +84,7 @@ class _SearchUseCaseState extends State<_SearchUseCase> {
label: "Title Alignment",
options: [
ZetaTopAppBarType.defaultAppBar,
ZetaTopAppBarType.centeredTitle,
ZetaTopAppBarType.centered,
],
initialOption: ZetaTopAppBarType.defaultAppBar,
labelBuilder: (option) {
Expand All @@ -101,7 +101,7 @@ class _SearchUseCaseState extends State<_SearchUseCase> {
initialValue: false,
);

return ZetaTopAppBar(
return ZetaTopAppBar.search(
leading: IconButton(
onPressed: () {},
icon: ZetaIcon(leadingIcon),
Expand All @@ -118,105 +118,6 @@ class _SearchUseCaseState extends State<_SearchUseCase> {
searchController.text = generatedText;
}
: null,
actions: [
IconButton(
onPressed: () {
searchController.isEnabled ? searchController.closeSearch() : searchController.startSearch();
},
icon: ZetaIcon(ZetaIcons.search)),
],
);
}
}

Widget extendedTopAppBarUseCase(BuildContext context) => ExtendedSearch();
thelukewalton marked this conversation as resolved.
Show resolved Hide resolved

class ExtendedSearch extends StatefulWidget {
const ExtendedSearch({super.key});

@override
State<ExtendedSearch> createState() => _ExtendedSearchState();
}

class _ExtendedSearchState extends State<ExtendedSearch> {
final _searchControllerExtended = ZetaSearchController();

void _showHideSearchExtended() {
_searchControllerExtended.isEnabled
? _searchControllerExtended.closeSearch()
: _searchControllerExtended.startSearch();
}

@override
Widget build(BuildContext context) {
final title = context.knobs.string(label: "Title", initialValue: "Title");

final leadingIcon = iconKnob(context, name: 'Leading Icon', initial: ZetaIcons.hamburger_menu);

final showSearch = context.knobs.boolean(label: 'Search variant', initialValue: false);

return WidgetbookScaffold(
removeBody: true,
builder: (context, constraints) => SafeArea(
child: SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
child: CustomScrollView(
slivers: [
ZetaTopAppBar.extended(
leading: IconButton(icon: ZetaIcon(leadingIcon), onPressed: () {}),
title: Text(title),
actions: showSearch
? [
IconButton(
onPressed: _showHideSearchExtended,
icon: ZetaIcon(ZetaIcons.search),
)
]
: [
IconButton(
onPressed: () {},
icon: ZetaIcon(Icons.language),
),
IconButton(
onPressed: () {},
icon: ZetaIcon(Icons.favorite),
),
IconButton(
onPressed: () {},
icon: ZetaIcon(ZetaIcons.more_vertical),
)
],
searchController: showSearch ? _searchControllerExtended : null,
onSearch: showSearch ? (text) => debugPrint('search text: $text') : null,
onSearchMicrophoneIconPressed: showSearch
? () async {
var sampleTexts = [
'This is a sample text',
'Another sample',
'Speech recognition text',
'Example'
];
var generatedText = sampleTexts[Random().nextInt(sampleTexts.length)];
_searchControllerExtended.text = generatedText;
}
: null,
),
SliverToBoxAdapter(
child: Container(
width: constraints.maxWidth,
height: constraints.maxHeight * 4,
color: Zeta.of(context).colors.surfaceSecondary,
child: CustomPaint(
painter: Painter(context: context, constraints: constraints),
size: Size(constraints.maxWidth, constraints.maxHeight * 4),
),
),
),
],
),
),
),
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class ZetaScreenHeaderBar extends ZetaStatelessWidget {
title: title,
titleTextStyle: ZetaTextStyles.titleLarge,
actions: actionButtonLabel == null
? null
? []
: [
ZetaButton(
label: actionButtonLabel!,
Expand Down
50 changes: 21 additions & 29 deletions lib/src/components/top_app_bar/extended_top_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ class ZetaExtendedAppBarDelegate extends SliverPersistentHeaderDelegate {
required this.shrinks,
this.actions,
this.leading,
this.searchController,
});

/// Title of the app bar.
Expand All @@ -27,56 +26,49 @@ class ZetaExtendedAppBarDelegate extends SliverPersistentHeaderDelegate {
/// Widget displayed first in the app bar row.
final Widget? leading;

/// Used to control the search textfield and states.
final ZetaSearchController? searchController;

/// If `ZetaTopAppBarType.extend` shrinks. Does not affect other types of app bar.
final bool shrinks;

static const double _maxExtent = 104;
static const double _minExtent = 52;
static const double _minExtent = 56;

@override
Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
final searchBarOffsetTop = Zeta.of(context).spacing.minimum * 1.5;
final searchBarOffsetRight = Zeta.of(context).spacing.minimum * 22;
final maxExtent = Zeta.of(context).spacing.minimum * 26;
final leftMin = Zeta.of(context).spacing.large;
final topMin = Zeta.of(context).spacing.xl;
final topMax = Zeta.of(context).spacing.minimum * 15;
final spacing = Zeta.of(context).spacing;

final maxExtent = spacing.minimum * 26;
final leftMin = spacing.large;
final topMin = spacing.xl;
final topMax = spacing.minimum * 15;

/// If there is no leading widget, the left margin should not change
/// If there is a leading widget, the left margin should be the same as the leading widget's width plus padding
final leftMax = leading == null ? leftMin : _minExtent + Zeta.of(context).spacing.small;
final leftMax = leading == null ? leftMin : _minExtent + spacing.small;

final top = shrinks
? (topMax + (-1 * shrinkOffset)).clamp(
topMin - (spacing.minimum),
topMax - (spacing.minimum),
)
: topMax;

return ConstrainedBox(
constraints: BoxConstraints(minHeight: Zeta.of(context).spacing.xl_9, maxHeight: maxExtent),
constraints: BoxConstraints(minHeight: spacing.xl_9, maxHeight: maxExtent),
child: ColoredBox(
color: Zeta.of(context).colors.surfacePrimary,
child: Stack(
children: [
Positioned(
top: shrinks
? (topMax + (-1 * shrinkOffset)).clamp(
topMin -
(searchController != null && searchController!.isEnabled
? searchBarOffsetTop
: Zeta.of(context).spacing.none),
topMax,
)
: topMax,
top: top,
left: shrinks ? ((shrinkOffset / maxExtent) * _maxExtent).clamp(leftMin, leftMax) : leftMin,
right: searchController != null && searchController!.isEnabled
? searchBarOffsetRight
: Zeta.of(context).spacing.none,
right: spacing.none,
child: title,
),
if (leading != null)
Positioned(top: Zeta.of(context).spacing.medium, left: Zeta.of(context).spacing.small, child: leading!),
if (leading != null) Positioned(top: spacing.small, left: spacing.small, child: leading!),
if (actions != null)
Positioned(
top: Zeta.of(context).spacing.medium,
right: Zeta.of(context).spacing.small,
top: spacing.small,
right: spacing.small,
child: Row(children: actions!),
),
],
Expand Down
10 changes: 1 addition & 9 deletions lib/src/components/top_app_bar/search_top_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,12 @@ class _ZetaTopAppBarSearchFieldState extends State<ZetaTopAppBarSearchField> wit

@override
void initState() {
_textFocusNode.addListener(_onFocusChanged);
widget.searchController?.addListener(_onSearchControllerChanged);
widget.searchController?.textEditingController ??= TextEditingController();

super.initState();
}

void _onFocusChanged() {
final text = widget.searchController?.text ?? '';
final shouldCloseSearch = _isSearching && text.isEmpty && !_textFocusNode.hasFocus;

if (shouldCloseSearch) _closeSearch();
}

void _onSearchControllerChanged() {
final controller = widget.searchController;
if (controller == null) return;
Expand Down Expand Up @@ -151,7 +143,7 @@ class _ZetaTopAppBarSearchFieldState extends State<ZetaTopAppBarSearchField> wit
children: [
Row(
mainAxisAlignment:
widget.type == ZetaTopAppBarType.centeredTitle ? MainAxisAlignment.center : MainAxisAlignment.start,
widget.type == ZetaTopAppBarType.centered ? MainAxisAlignment.center : MainAxisAlignment.start,
children: [
widget.child ?? const Nothing(),
],
Expand Down
Loading