quiet_dock 0.1.0
quiet_dock: ^0.1.0 copied to clipboard
A glassmorphic Flutter navigation dock with swipeable pages, quick actions, and responsive wide-screen navigation.
import 'package:flutter/material.dart';
import 'package:quiet_dock/quiet_dock.dart';
void main() => runApp(const ExampleApp());
/// Demo application showing the dock, swipe sliding and the quick grid.
class ExampleApp extends StatelessWidget {
/// Creates the demo app.
const ExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'quiet_dock demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorSchemeSeed: const Color(0xFF7A6A55),
useMaterial3: true,
),
darkTheme: ThemeData(
colorSchemeSeed: const Color(0xFF7A6A55),
brightness: Brightness.dark,
useMaterial3: true,
),
home: const DemoShell(),
);
}
}
/// The shell wiring [QuietDockScaffold] to five demo pages.
class DemoShell extends StatefulWidget {
/// Creates the demo shell.
const DemoShell({super.key});
@override
State<DemoShell> createState() => _DemoShellState();
}
class _DemoShellState extends State<DemoShell> {
final QuietDockController _controller = QuietDockController();
static const List<QuietDockDestination> _destinations =
<QuietDockDestination>[
QuietDockDestination(
icon: Icons.home_outlined,
selectedIcon: Icons.home_rounded,
label: 'Home',
),
QuietDockDestination(
icon: Icons.checklist_outlined,
selectedIcon: Icons.task_alt_rounded,
label: 'Todos',
),
QuietDockDestination(
icon: Icons.notes_outlined,
selectedIcon: Icons.sticky_note_2_rounded,
label: 'Notes',
),
QuietDockDestination(
icon: Icons.settings_outlined,
selectedIcon: Icons.settings_rounded,
label: 'Settings',
),
];
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _openTile(String label) {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) => Scaffold(
appBar: AppBar(title: Text(label)),
body: Center(child: Text('$label screen')),
),
),
);
}
@override
Widget build(BuildContext context) {
return QuietDockScaffold(
controller: _controller,
destinations: _destinations,
onDestinationSelected: (int index) {
debugPrint('tab -> ${_destinations[index].label}');
},
centerAction: QuietDockCenterAction(
items: <QuickGridItem>[
for (final (IconData icon, String label)
in const <(IconData, String)>[
(Icons.repeat_rounded, 'Habits'),
(Icons.alt_route_rounded, 'Routines'),
(Icons.calendar_month_rounded, 'Calendar'),
(Icons.flag_rounded, 'Goals'),
(Icons.menu_book_rounded, 'Journal'),
(Icons.school_rounded, 'Courses'),
(Icons.insights_rounded, 'Analytics'),
(Icons.access_time_rounded, 'Clock'),
(Icons.auto_awesome, 'AI'),
])
QuickGridItem(
icon: icon,
label: label,
onTap: () => _openTile(label),
),
],
),
pageBuilder: (BuildContext context, int index) =>
_DemoPage(destination: _destinations[index], index: index),
);
}
}
class _DemoPage extends StatelessWidget {
const _DemoPage({required this.destination, required this.index});
final QuietDockDestination destination;
final int index;
@override
Widget build(BuildContext context) {
final ColorScheme colors = Theme.of(context).colorScheme;
return ListView.builder(
padding: const EdgeInsets.fromLTRB(16, 64, 16, 120),
itemCount: 30,
itemBuilder: (BuildContext context, int i) {
if (i == 0) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Text(
destination.label,
style: Theme.of(context).textTheme.headlineMedium,
),
);
}
return Card(
color: colors.surfaceContainerHighest,
child: ListTile(
leading: Icon(destination.selectedIcon),
title: Text('${destination.label} item $i'),
subtitle: const Text('Swipe left or right to slide between tabs'),
),
);
},
);
}
}