Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2953a15
poc for floating header
renefloor May 27, 2026
86e911f
Add snapshot test and gallery update
renefloor May 27, 2026
b2e4352
Add theming for floating config
renefloor May 28, 2026
583b7f7
Streamscaffold
renefloor May 29, 2026
84bc87e
Add `StreamBottomNavBar` item
renefloor May 29, 2026
a17dfda
fix default color scaffold
renefloor Jun 9, 2026
34ac0db
fix layout disabled floating button
renefloor Jun 9, 2026
693e6dd
Add option for shadow on avatar
renefloor Jun 12, 2026
0fd3fba
chore: Update Goldens
renefloor Jun 12, 2026
20628f9
fix badge size on nav bar
renefloor Jun 12, 2026
9b781a8
Add gradient to floating bottom nav
renefloor Jun 12, 2026
682d15f
Add accessibility for bottom bar
renefloor Jun 16, 2026
ceb2d07
update changelog
renefloor Jun 17, 2026
9a9de37
fix composer in bottom
renefloor Jun 17, 2026
ef83513
Use null-aware marker
renefloor Jun 17, 2026
bed95c6
fix(ui): avatar shadow, unified floating button disabled state, share…
renefloor Jun 17, 2026
fbcd55c
fix golden tests
renefloor Jun 17, 2026
7eaab16
chore: Update Goldens
renefloor Jun 17, 2026
2eb0496
improve avatar theming for shadows
renefloor Jun 17, 2026
cd94bd3
chore: Update Goldens
renefloor Jun 17, 2026
bf3d4fa
feat(ui): replace showShadow with elevation for avatar components
xsahil03x Jun 17, 2026
10995e4
Merge remote-tracking branch 'origin/main' into feat/floating-header
xsahil03x Jun 17, 2026
76562ac
chore: Update Goldens
xsahil03x Jun 17, 2026
66fabb7
improve elevation properties
renefloor Jun 17, 2026
a54e4c8
Update appstyle theming
renefloor Jun 17, 2026
f3bed7d
Rename StreamAppBarBehavior
renefloor Jun 19, 2026
8476faa
Merge remote-tracking branch 'origin/main' into feat/floating-header
renefloor Jun 19, 2026
f94d9cc
update test imports
renefloor Jun 19, 2026
7c55b73
export scaffold and appstyle
renefloor Jun 19, 2026
ee041cd
fix border on streamavatar
renefloor Jun 19, 2026
66ee511
chore: Update Goldens
renefloor Jun 19, 2026
20b98ec
Merge branch 'main' into feat/floating-header
renefloor Jul 17, 2026
a58a7b1
Add unit tests
renefloor Jul 17, 2026
9564b9e
refactor(ui): rework StreamBottomNavBar with a dedicated theme + factory
xsahil03x Jul 20, 2026
ad88b65
fix(gallery): guard ScopedSemanticsDebugger against a null pipeline o…
xsahil03x Jul 20, 2026
111b96a
chore: Update Goldens
xsahil03x Jul 20, 2026
f212d5a
refactor(ui): align StreamAppBar background resolution with StreamBot…
xsahil03x Jul 20, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ import 'package:design_system_gallery/components/toolbar/stream_app_bar.dart'
as _design_system_gallery_components_toolbar_stream_app_bar;
import 'package:design_system_gallery/components/toolbar/stream_bottom_app_bar.dart'
as _design_system_gallery_components_toolbar_stream_bottom_app_bar;
import 'package:design_system_gallery/components/toolbar/stream_bottom_nav_bar.dart'
as _design_system_gallery_components_toolbar_stream_bottom_nav_bar;
import 'package:design_system_gallery/components/toolbar/stream_sheet_header.dart'
as _design_system_gallery_components_toolbar_stream_sheet_header;
import 'package:design_system_gallery/primitives/colors.dart'
Expand Down Expand Up @@ -1232,6 +1234,23 @@ final directories = <_widgetbook.WidgetbookNode>[
),
],
),
_widgetbook.WidgetbookComponent(
name: 'StreamBottomNavBar',
useCases: [
_widgetbook.WidgetbookUseCase(
name: 'Playground',
builder:
_design_system_gallery_components_toolbar_stream_bottom_nav_bar
.buildStreamBottomNavBarPlayground,
),
_widgetbook.WidgetbookUseCase(
name: 'Showcase',
builder:
_design_system_gallery_components_toolbar_stream_bottom_nav_bar
.buildStreamBottomNavBarShowcase,
),
],
),
_widgetbook.WidgetbookComponent(
name: 'StreamSheetHeader',
useCases: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ Widget buildStreamAvatarPlayground(BuildContext context) {
description: 'Whether to show a border around the avatar.',
);

final isFloating = context.knobs.boolean(
label: 'Is Floating',
description: 'Whether to show a drop shadow around the avatar.',
);

final initials = context.knobs.string(
label: 'Initials',
initialValue: 'JD',
Expand All @@ -46,6 +51,7 @@ Widget buildStreamAvatarPlayground(BuildContext context) {
imageUrl: (imageUrl?.isNotEmpty ?? false) ? imageUrl : null,
size: size,
showBorder: showBorder,
isFloating: isFloating,
placeholder: (context) => Text(
initials.substring(0, initials.length.clamp(0, 2)).toUpperCase(),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,17 @@ Widget buildStreamAvatarGroupPlayground(BuildContext context) {
description: 'Use images or show initials placeholder.',
);

final isFloating = context.knobs.boolean(
label: 'Is Floating',
description: 'Whether to show a drop shadow around each individual avatar.',
);

final palette = context.streamColorScheme.avatarPalette;

return Center(
child: StreamAvatarGroup(
size: size,
isFloating: isFloating,
children: List.generate(
avatarCount,
(index) => StreamAvatar(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ Widget buildStreamAvatarStackPlayground(BuildContext context) {
description: 'Use images or show initials placeholder.',
);

final isFloating = context.knobs.boolean(
label: 'Is Floating',
description: 'Whether to show a drop shadow around each individual avatar.',
);

final colorScheme = context.streamColorScheme;
final palette = colorScheme.avatarPalette;

Expand All @@ -66,6 +71,7 @@ Widget buildStreamAvatarStackPlayground(BuildContext context) {
size: size,
overlap: overlap,
max: maxAvatars,
isFloating: isFloating,
children: [
for (var i = 0; i < avatarCount; i++)
StreamAvatar(
Expand Down
137 changes: 114 additions & 23 deletions apps/design_system_gallery/lib/components/toolbar/stream_app_bar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,31 +53,62 @@ Widget buildStreamAppBarPlayground(BuildContext context) {
description: 'Horizontal gap between leading, heading, and trailing.',
);

return Align(
alignment: Alignment.topCenter,
child: StreamAppBar(
style: StreamAppBarStyle(
padding: EdgeInsets.all(padding),
spacing: spacing,
),
leading: showLeading
? StreamButton.icon(
icon: Icon(context.streamIcons.chevronLeft),
style: StreamButtonStyle.secondary,
type: StreamButtonType.ghost,
onPressed: () {},
)
: null,
title: (title != null && title.isNotEmpty) ? Text(title) : null,
subtitle: (subtitle != null && subtitle.isNotEmpty) ? Text(subtitle) : null,
trailing: showTrailing
? StreamButton.icon(
icon: Icon(context.streamIcons.plus),
onPressed: () {},
)
: null,
final floating = context.knobs.boolean(
label: 'Floating',
description:
'When true, the app bar floats above content with a gradient fade '
'instead of a solid background and a bottom border.',
);

final colorScheme = context.streamColorScheme;

final Widget bar = StreamAppBar(
primary: false,
style: StreamAppBarStyle(
behavior: floating ? StreamAppBarBehavior.floating : StreamAppBarBehavior.regular,
padding: EdgeInsets.all(padding),
spacing: spacing,
),
leading: showLeading
? StreamButton.icon(
icon: Icon(context.streamIcons.chevronLeft),
style: StreamButtonStyle.secondary,
type: floating ? StreamButtonType.outline : StreamButtonType.ghost,
isFloating: floating,
onPressed: () {},
)
: null,
title: (title != null && title.isNotEmpty) ? Text(title) : null,
subtitle: (subtitle != null && subtitle.isNotEmpty) ? Text(subtitle) : null,
trailing: showTrailing
? StreamButton.icon(
icon: Icon(context.streamIcons.plus),
isFloating: floating,
onPressed: () {},
)
: null,
);

if (floating) {
return Stack(
children: [
Positioned.fill(
child: ColoredBox(
color: colorScheme.backgroundApp,
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 32),
decoration: BoxDecoration(
color: colorScheme.accentPrimary,
),
),
),
),
Align(alignment: Alignment.topCenter, child: bar),
],
);
}

return Align(alignment: Alignment.topCenter, child: bar);
}

// =============================================================================
Expand Down Expand Up @@ -227,6 +258,31 @@ Widget buildStreamAppBarShowcase(BuildContext context) {
),
),
SizedBox(height: spacing.md),
_AppBarExample(
label: 'Floating — gradient fade over content',
bar: _FloatingAppBarPreview(
bar: StreamAppBar(
automaticallyImplyLeading: false,
primary: false,
style: const StreamAppBarStyle(behavior: StreamAppBarBehavior.floating),
leading: StreamButton.icon(
icon: Icon(context.streamIcons.chevronLeft),
style: StreamButtonStyle.secondary,
type: StreamButtonType.outline,
isFloating: true,
onPressed: () {},
),
title: const Text('Group chat'),
subtitle: const Text('5 members, 3 online'),
trailing: StreamButton.icon(
icon: Icon(context.streamIcons.plus),
isFloating: true,
onPressed: () {},
),
),
),
),
SizedBox(height: spacing.md),
const _AutoImplyLeadingDemo(),
],
),
Expand Down Expand Up @@ -303,6 +359,41 @@ class _AutoImplyLeadingDemo extends StatelessWidget {
}
}

/// Renders a floating [StreamAppBar] over a simulated gradient background so
/// the fade effect is clearly visible in the Showcase.
class _FloatingAppBarPreview extends StatelessWidget {
const _FloatingAppBarPreview({required this.bar});

final Widget bar;

@override
Widget build(BuildContext context) {
final colorScheme = context.streamColorScheme;
return SizedBox(
height: kStreamToolbarHeight * 2,
child: Stack(
children: [
Positioned.fill(
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
colorScheme.accentPrimary.withAlpha(0x40),
colorScheme.backgroundApp,
],
),
),
),
),
Positioned(top: 0, left: 0, right: 0, child: bar),
],
),
);
}
}

class _AppBarExample extends StatelessWidget {
const _AppBarExample({required this.label, required this.bar});

Expand Down
Loading
Loading