Skip to content

Commit

Permalink
feat: Global Header (#38)
Browse files Browse the repository at this point in the history
Authored-by: Osman <[email protected]>
  • Loading branch information
ahmed-osman3 authored and thelukewalton committed May 9, 2024
1 parent ca51b1f commit 2da6aec
Show file tree
Hide file tree
Showing 12 changed files with 449 additions and 85 deletions.
2 changes: 2 additions & 0 deletions example/lib/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'package:zeta_example/pages/components/date_input_example.dart';
import 'package:zeta_example/pages/components/dialog_example.dart';
import 'package:zeta_example/pages/components/dialpad_example.dart';
import 'package:zeta_example/pages/components/dropdown_example.dart';
import 'package:zeta_example/pages/components/global_header_example.dart';
import 'package:zeta_example/pages/components/filter_selection_example.dart';
import 'package:zeta_example/pages/components/list_item_example.dart';
import 'package:zeta_example/pages/components/navigation_bar_example.dart';
Expand Down Expand Up @@ -67,6 +68,7 @@ final List<Component> components = [
Component(NavigationBarExample.name, (context) => const NavigationBarExample()),
Component(PaginationExample.name, (context) => const PaginationExample()),
Component(PasswordInputExample.name, (context) => const PasswordInputExample()),
Component(GroupHeaderExample.name, (context) => const GroupHeaderExample()),
Component(DropdownExample.name, (context) => const DropdownExample()),
Component(ProgressExample.name, (context) => const ProgressExample()),
Component(SegmentedControlExample.name, (context) => const SegmentedControlExample()),
Expand Down
57 changes: 57 additions & 0 deletions example/lib/pages/components/global_header_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:zeta_example/widgets.dart';
import 'package:zeta_flutter/zeta_flutter.dart';

class GroupHeaderExample extends StatefulWidget {
static final name = "GlobalHeader";
const GroupHeaderExample({super.key});

@override
State<GroupHeaderExample> createState() => _GroupHeaderExampleState();
}

class _GroupHeaderExampleState extends State<GroupHeaderExample> {
final childrenOne = List.filled(5, ZetaGlobalHeaderItem(label: 'Button'));
final childrenTwo = List.filled(10, ZetaGlobalHeaderItem(label: 'Button'));

@override
Widget build(BuildContext context) {
return ExampleScaffold(
name: "Global Header",
child: LayoutBuilder(builder: (context, constraints) {
return Center(
child: SingleChildScrollView(
child: Column(children: [
Text(constraints.maxWidth.toString()),
ZetaGlobalHeader(
title: "Title",
tabItems: childrenOne,
searchBar: ZetaSearchBar(shape: ZetaWidgetBorder.full, size: ZetaWidgetSize.large),
onAppsButton: () {},
actionButtons: [
IconButton(
onPressed: () {},
icon: const Icon(
ZetaIcons.alert_round,
),
),
IconButton(
onPressed: () {},
icon: const Icon(
ZetaIcons.help_round,
),
),
],
avatar: const ZetaAvatar(initials: 'PS'),
),
const SizedBox(
height: ZetaSpacing.x5,
),
ZetaGlobalHeader(title: "Title", tabItems: childrenTwo),
]),
),
);
}),
);
}
}
2 changes: 1 addition & 1 deletion example/macos/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78
sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec

PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7
Expand Down
57 changes: 21 additions & 36 deletions example/widgetbook/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import 'pages/components/date_input_widgetbook.dart';
import 'pages/components/dial_pad_widgetbook.dart';
import 'pages/components/dialog_widgetbook.dart';
import 'pages/components/dropdown_widgetbook.dart';
import 'pages/components/global_header_widgetbook.dart';
import 'pages/components/filter_selection_widgetbook.dart';
import 'pages/components/in_page_banner_widgetbook.dart';
import 'pages/components/list_item_widgetbook.dart';
Expand Down Expand Up @@ -62,14 +63,8 @@ class HotReload extends StatelessWidget {
WidgetbookComponent(
name: 'App Bar',
useCases: [
WidgetbookUseCase(
name: 'Default',
builder: (context) => defaultAppBarUseCase(context),
),
WidgetbookUseCase(
name: 'Search',
builder: (context) => searchAppBarUseCase(context),
),
WidgetbookUseCase(name: 'Default', builder: (context) => defaultAppBarUseCase(context)),
WidgetbookUseCase(name: 'Search', builder: (context) => searchAppBarUseCase(context)),
],
),
WidgetbookComponent(
Expand Down Expand Up @@ -99,11 +94,6 @@ class HotReload extends StatelessWidget {
WidgetbookUseCase(name: 'Group Button', builder: (context) => buttonGroupUseCase(context)),
],
),
WidgetbookUseCase(name: 'BreadCrumbs', builder: (context) => breadCrumbsUseCase(context)),
WidgetbookUseCase(name: 'Banners', builder: (context) => bannerUseCase(context)),
WidgetbookUseCase(name: "Dropdown", builder: (context) => dropdownUseCase(context)),
WidgetbookUseCase(name: 'In Page Banners', builder: (context) => inPageBannerUseCase(context)),
WidgetbookUseCase(name: 'Accordion', builder: (context) => accordionUseCase(context)),
WidgetbookComponent(
name: 'Chips',
useCases: [
Expand All @@ -112,40 +102,36 @@ class HotReload extends StatelessWidget {
WidgetbookUseCase(name: 'Assist Chip', builder: (context) => assistChipUseCase(context)),
],
),
WidgetbookUseCase(name: 'Password Input', builder: (context) => passwordInputUseCase(context)),
WidgetbookUseCase(name: 'Content', builder: (context) => bottomSheetContentUseCase(context)),
WidgetbookUseCase(name: 'Dial Pad', builder: (context) => dialPadUseCase(context)),
WidgetbookUseCase(name: 'List Item', builder: (context) => listItemUseCase(context)),
WidgetbookUseCase(name: 'Navigation Bar', builder: (context) => navigationBarUseCase(context)),
WidgetbookUseCase(name: 'Pagination', builder: (context) => paginationUseCase(context)),
WidgetbookComponent(
name: 'Progress',
useCases: [
WidgetbookUseCase(name: 'Bar', builder: (context) => progressBarUseCase(context)),
WidgetbookUseCase(name: 'Circle', builder: (context) => progressCircleUseCase(context))
],
),
WidgetbookUseCase(name: 'Accordion', builder: (context) => accordionUseCase(context)),
WidgetbookUseCase(name: 'Avatar', builder: (context) => avatarUseCase(context)),
WidgetbookUseCase(name: 'BreadCrumbs', builder: (context) => breadCrumbsUseCase(context)),
WidgetbookUseCase(name: 'Banners', builder: (context) => bannerUseCase(context)),
WidgetbookUseCase(name: 'Checkbox', builder: (context) => checkboxUseCase(context)),
WidgetbookUseCase(name: "Dropdown", builder: (context) => dropdownUseCase(context)),
WidgetbookUseCase(name: 'In Page Banners', builder: (context) => inPageBannerUseCase(context)),
WidgetbookUseCase(name: 'Password Input', builder: (context) => passwordInputUseCase(context)),
WidgetbookUseCase(name: 'Content', builder: (context) => bottomSheetContentUseCase(context)),
WidgetbookUseCase(name: 'Dial Pad', builder: (context) => dialPadUseCase(context)),
WidgetbookUseCase(name: 'Global Header', builder: (context) => globalHeaderUseCase(context)),
WidgetbookUseCase(name: 'List Item', builder: (context) => listItemUseCase(context)),
WidgetbookUseCase(name: 'Navigation Bar', builder: (context) => navigationBarUseCase(context)),
WidgetbookUseCase(name: 'Pagination', builder: (context) => paginationUseCase(context)),
WidgetbookUseCase(name: 'Radio Button', builder: (context) => radioButtonUseCase(context)),
WidgetbookUseCase(
name: 'Segmented Control',
builder: (context) => segmentedControlUseCase(context),
),
WidgetbookUseCase(name: 'Segmented Control', builder: (context) => segmentedControlUseCase(context)),
WidgetbookUseCase(name: 'Switch', builder: (context) => switchUseCase(context)),
WidgetbookUseCase(
name: 'Snack Bar',
builder: (context) => snackBarUseCase(context),
),
WidgetbookUseCase(name: 'Snack Bar', builder: (context) => snackBarUseCase(context)),
WidgetbookUseCase(name: 'Date Input', builder: (context) => dateInputUseCase(context)),
WidgetbookUseCase(name: 'Tabs', builder: (context) => tabsUseCase(context)),
WidgetbookUseCase(name: 'Phone Input', builder: (context) => phoneInputUseCase(context)),
WidgetbookUseCase(
name: 'Stepper',
builder: (context) => stepperUseCase(context),
),
WidgetbookUseCase(
name: 'Stepper Input',
builder: (context) => stepperInputUseCase(context),
),
WidgetbookUseCase(name: 'Stepper', builder: (context) => stepperUseCase(context)),
WidgetbookUseCase(name: 'Stepper Input', builder: (context) => stepperInputUseCase(context)),
WidgetbookUseCase(name: 'Dialog', builder: (context) => dialogUseCase(context)),
WidgetbookUseCase(name: 'Search Bar', builder: (context) => searchBarUseCase(context)),
WidgetbookUseCase(name: 'Navigation Rail', builder: (context) => navigationRailUseCase(context)),
Expand Down Expand Up @@ -177,7 +163,6 @@ class HotReload extends StatelessWidget {
DeviceFrameAddon(
devices: [
Devices.windows.wideMonitor,
Devices.macOS.wideMonitor,
Devices.ios.iPad,
Devices.ios.iPhone13,
Zebra.ec30,
Expand Down
38 changes: 38 additions & 0 deletions example/widgetbook/pages/components/global_header_widgetbook.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:widgetbook/widgetbook.dart';
import 'package:zeta_flutter/zeta_flutter.dart';

import '../../test/test_components.dart';

Widget globalHeaderUseCase(BuildContext context) {
final actionButtons = [
IconButton(
onPressed: () {},
icon: const Icon(
ZetaIcons.alert_round,
),
),
IconButton(
onPressed: () {},
icon: const Icon(
ZetaIcons.help_round,
),
),
];

return WidgetbookTestWidget(
widget: ZetaGlobalHeader(
title: context.knobs.string(label: "Title", initialValue: "Title"),
tabItems: List.generate(
context.knobs.int.slider(label: "Tabs"), (index) => ZetaGlobalHeaderItem(label: 'Button ${index + 1}')),
searchBar: context.knobs.boolean(label: 'Search bar', initialValue: true)
? ZetaSearchBar(shape: ZetaWidgetBorder.full, size: ZetaWidgetSize.large)
: null,
actionButtons: context.knobs.boolean(label: "Menu buttons", initialValue: true) ? actionButtons : [],
avatar: context.knobs.boolean(label: "Show Avatar", initialValue: true)
? const ZetaAvatar(initials: 'PS', size: ZetaAvatarSize.s)
: null,
onAppsButton: context.knobs.boolean(label: "Apps menu", initialValue: true) ? () => {} : null,
),
);
}
1 change: 1 addition & 0 deletions lib/src/components/app_bar/app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class ZetaAppBar extends StatefulWidget implements PreferredSizeWidget {
)
..add(StringProperty('searchHintText', searchHintText))
..add(EnumProperty<ZetaAppBarType>('type', type))
..add(EnumProperty<ZetaAppBarType>('type', type))
..add(DoubleProperty('titleSpacing', titleSpacing))
..add(DiagnosticsProperty<TextStyle?>('titleTextStyle', titleTextStyle));
}
Expand Down
120 changes: 72 additions & 48 deletions lib/src/components/avatars/avatar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@ class ZetaAvatar extends StatelessWidget {
/// Notification Badge shown at top right corner of avatar.
final ZetaAvatarBadge? upperBadge;

/// Return copy of avatar with certain changed fields
ZetaAvatar copyWith({
ZetaAvatarSize? size,
Widget? image,
String? initials,
Color? backgroundColor,
Color? borderColor,
ZetaAvatarBadge? lowerBadge,
ZetaAvatarBadge? upperBadge,
}) {
return ZetaAvatar(
size: size ?? this.size,
image: image ?? this.image,
initials: initials ?? this.initials,
backgroundColor: backgroundColor ?? this.backgroundColor,
borderColor: borderColor ?? this.borderColor,
lowerBadge: lowerBadge ?? this.lowerBadge,
upperBadge: upperBadge ?? this.upperBadge,
);
}

bool get _showPlaceholder => image == null && (initials == null || initials!.isEmpty);

@override
Expand All @@ -122,6 +143,7 @@ class ZetaAvatar extends StatelessWidget {
fontSize: size.fontSize,
letterSpacing: 0,
color: backgroundColor?.onColor,
fontWeight: FontWeight.w500,
),
),
)
Expand All @@ -132,57 +154,59 @@ class ZetaAvatar extends StatelessWidget {
child: innerChild,
);

return Stack(
children: [
Container(
width: sizePixels,
height: sizePixels,
decoration: BoxDecoration(
border: borderColor != null ? Border.all(color: borderColor!, width: 0) : null,
borderRadius: ZetaRadius.full,
color: backgroundColor ?? (_showPlaceholder ? zetaColors.surfacePrimary : zetaColors.cool.shade20),
),
child: borderColor != null
? Container(
width: contentSizePixels,
height: contentSizePixels,
decoration: BoxDecoration(
color: backgroundColor ?? zetaColors.surfaceHovered,
border: Border.all(color: borderColor!, width: borderSize),
borderRadius: ZetaRadius.full,
),
child: ClipRRect(
borderRadius: ZetaRadius.full,
child: innerContent,
),
)
: DecoratedBox(
decoration: BoxDecoration(
borderRadius: ZetaRadius.full,
color: backgroundColor ?? zetaColors.surfaceHovered,
),
child: ClipRRect(
borderRadius: ZetaRadius.full,
child: innerContent,
),
),
),
if (upperBadge != null)
Positioned(
right: 0,
child: upperBadge!.copyWith(
size: size,
return SelectionContainer.disabled(
child: Stack(
children: [
Container(
width: sizePixels,
height: sizePixels,
decoration: BoxDecoration(
border: borderColor != null ? Border.all(color: borderColor!, width: 0) : null,
borderRadius: ZetaRadius.full,
color: backgroundColor ?? (_showPlaceholder ? zetaColors.surfacePrimary : zetaColors.cool.shade20),
),
child: borderColor != null
? Container(
width: contentSizePixels,
height: contentSizePixels,
decoration: BoxDecoration(
color: backgroundColor ?? zetaColors.surfaceHovered,
border: Border.all(color: borderColor!, width: borderSize),
borderRadius: ZetaRadius.full,
),
child: ClipRRect(
borderRadius: ZetaRadius.full,
child: innerContent,
),
)
: DecoratedBox(
decoration: BoxDecoration(
borderRadius: ZetaRadius.full,
color: backgroundColor ?? zetaColors.surfaceHovered,
),
child: ClipRRect(
borderRadius: ZetaRadius.full,
child: innerContent,
),
),
),
if (lowerBadge != null)
Positioned(
right: 0,
bottom: 0,
child: lowerBadge!.copyWith(
size: size,
if (upperBadge != null)
Positioned(
right: 0,
child: upperBadge!.copyWith(
size: size,
),
),
),
],
if (lowerBadge != null)
Positioned(
right: 0,
bottom: 0,
child: lowerBadge!.copyWith(
size: size,
),
),
],
),
);
}

Expand Down
Loading

0 comments on commit 2da6aec

Please sign in to comment.