Add a floating bottom bar style, user-configurable in Settings
Settings > Appearance > "Bottom bar" now switches between the original edge-to-edge bar and a floating one - inset 16px from both side edges and clear of the bottom safe area, 28px corners (the same radius the sheet top/drawer edge use), a 1px line border standing in for elevation instead of a shadow (product UI stays flat). Persisted via NooBottomBarStyle, defaulting to the existing attached behavior. On Android, floating's idle tabs drop their reserved label space - with no label to leave room for, the icon centers in the whole button and renders a touch bigger (27 vs 24px) instead of sitting high with a gap held open under it; the active tab's icon/pill/label position is unchanged. iOS's tab content is unchanged either way, only the container. main.dart sets Scaffold.extendBody while floating so the body scrolls behind the bar's transparent margin instead of stopping short of it, matching how the design canvas explored it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@ import '../../theme/design_tokens.dart';
|
||||
import '../noo/core/noo_segmented_control.dart';
|
||||
import '../noo/core/noo_toggle.dart';
|
||||
import '../noo/lists/noo_settings_row.dart';
|
||||
import '../noo/nav/noo_nav_style.dart';
|
||||
import '../noo/noo_layout.dart';
|
||||
import '../noo/overlays/noo_dialog.dart';
|
||||
import '../noo/overlays/noo_sheet.dart';
|
||||
@@ -47,7 +48,10 @@ class SettingsAppearanceSection extends StatelessWidget {
|
||||
children: [
|
||||
SettingsSection(
|
||||
title: 'Appearance',
|
||||
children: [_ThemeRow(settings: settings)],
|
||||
children: [
|
||||
_ThemeRow(settings: settings),
|
||||
_BottomBarStyleRow(settings: settings),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: NooSpace.xl),
|
||||
SettingsSection(
|
||||
@@ -156,6 +160,64 @@ class _ThemeRow extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// The "Bottom bar" row: same "label, then a full-width segmented control
|
||||
/// below it" shape as [_ThemeRow] right above it. Attached is the original
|
||||
/// edge-to-edge bar; floating insets it from both side/bottom edges with
|
||||
/// rounded corners - see [NooBottomBarStyle]'s own doc comment for the
|
||||
/// full visual rationale.
|
||||
class _BottomBarStyleRow extends StatelessWidget {
|
||||
final SettingsController settings;
|
||||
|
||||
const _BottomBarStyleRow({required this.settings});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final colors = context.nooColors;
|
||||
return Material(
|
||||
color: colors.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: NooSpace.md,
|
||||
vertical: 12,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Icon(LucideIcons.panelBottom, size: 20, color: colors.fg2),
|
||||
const SizedBox(width: 14),
|
||||
Text(
|
||||
'Bottom bar',
|
||||
style: NooText.bodyL.copyWith(color: colors.fg1),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
NooSegmentedControl<NooBottomBarStyle>(
|
||||
fill: true,
|
||||
value: settings.bottomBarStyle,
|
||||
onChanged: settings.setBottomBarStyle,
|
||||
options: const [
|
||||
NooSegmentOption(
|
||||
value: NooBottomBarStyle.attached,
|
||||
icon: LucideIcons.panelBottom,
|
||||
label: 'Attached',
|
||||
),
|
||||
NooSegmentOption(
|
||||
value: NooBottomBarStyle.floating,
|
||||
icon: LucideIcons.panelBottomOpen,
|
||||
label: 'Floating',
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The current accent-color choice, shown as a small filled circle in the
|
||||
/// "Accent color" row - a wallpaper icon when following the OS's dynamic
|
||||
/// color instead of a fixed swatch.
|
||||
|
||||
Reference in New Issue
Block a user