Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## [next]

- feat: add logical start/end overflow direction support to `DynamicOverflow` ([#1359](https://github.com/bdlukaa/fluent_ui/pull/1359))
- refactor: `CommandBar` now uses an anchored, CommandBar-owned overflow popup with stable layout, end alignment, outside-tap dismissal, keyboard/touch-friendly interaction, and WinUI-inspired presenter styling ([#1359](https://github.com/bdlukaa/fluent_ui/pull/1359))
- dynamically overflowed primary commands remain in the primary command collection and retain their labels, shortcut/help text, enabled state, and semantics when shown in the overflow menu
- overflow presenter sizing, acrylic backgrounds, borders, and CommandBar colors now follow the native WinUI CommandBar theme resources
- fix: secondary CommandBar menus open correctly on touch platforms, including iOS, and tapping outside the menu no longer activates controls behind it
- refactor: Rework `ComboBox`. Rebuilt the popup using Flutter overlay infrastructure with viewport-aware positioning, configurable popup constraints, variable-height items, text scaling support, keyboard navigation, type-ahead search, and open/close callbacks. ([#1360](https://github.com/bdlukaa/fluent_ui/pull/1360), [#485](https://github.com/bdlukaa/fluent_ui/issues/485), [#1007](https://github.com/bdlukaa/fluent_ui/issues/1007), [#1230](https://github.com/bdlukaa/fluent_ui/issues/1230), and [#1256](https://github.com/bdlukaa/fluent_ui/issues/1256))
- refactor: Flutter 3.47.1 support ([#1353](https://github.com/bdlukaa/fluent_ui/pull/1353))
- migrate Material UI imports to the standalone `material_ui` package. [learn more](https://flutter.dev/blog/decoupling-material-cupertino)
Expand Down
150 changes: 89 additions & 61 deletions example/lib/screens/surface/commandbars.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,99 +13,102 @@ class CommandBarsPage extends StatefulWidget {
class _CommandBarsPageState extends State<CommandBarsPage> with PageMixin {
final key = GlobalKey<CommandBarState>();

final simpleCommandBarItems = <CommandBarItem>[
List<CommandBarItem> get simpleCommandBarItems => [
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.add),
label: const Text('New'),
tooltip: 'Create something new!',
onPressed: () {},
tooltip: 'Ctrl+N',
onPressed: () => _runAction('New playlist'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.delete),
label: const Text('Delete'),
tooltip: 'Delete what is currently selected!',
onPressed: () {},
tooltip: 'Delete',
onPressed: () => _runAction('Removed selected track'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.file_explorer),
label: const Text('Archive'),
onPressed: () {},
label: const Text('Add to playlist'),
tooltip: 'Ctrl+L',
onPressed: () => _runAction('Added to playlist'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.move),
label: const Text('Move'),
onPressed: () {},
tooltip: 'Ctrl+Shift+M',
onPressed: () => _runAction('Move requested'),
),
const CommandBarButton(
icon: WindowsIcon(WindowsIcons.cancel),
label: Text('Disabled'),
label: Text('Unavailable'),
tooltip: 'Unavailable',
onPressed: null,
),
];

final moreCommandBarItems = <CommandBarItem>[
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.mail_reply),
label: const Text('Reply'),
onPressed: () {},
label: const Text('Play next'),
tooltip: 'Alt+N',
onPressed: () => _runAction('Queued next'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.mail_reply_all),
label: const Text('Reply All'),
onPressed: () {},
label: const Text('Add to queue'),
tooltip: 'Q',
onPressed: () => _runAction('Added to queue'),
),
];

List<CommandBarItem> get moreCommandBarItems => [
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.forward),
label: const Text('Forward'),
onPressed: () {},
label: const Text('Share'),
tooltip: 'Ctrl+S',
onPressed: () => _runAction('Share requested'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.search),
label: const Text('Search'),
onPressed: () {},
label: const Text('Search library'),
tooltip: 'Ctrl+F',
onPressed: () => _runAction('Search requested'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.pin),
label: const Text('Pin'),
onPressed: () {},
label: const Text('Pin playlist'),
tooltip: 'Ctrl+P',
onPressed: () => _runAction('Playlist pinned'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.unpin),
label: const Text('Unpin'),
onPressed: () {},
label: const Text('Remove pin'),
tooltip: 'Ctrl+Shift+P',
onPressed: () => _runAction('Playlist unpinned'),
),
];

final evenMoreCommandBarItems = <CommandBarItem>[
List<CommandBarItem> get evenMoreCommandBarItems => [
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.accept),
label: const Text('Accept'),
onPressed: () {},
label: const Text('Mark played'),
tooltip: 'M',
onPressed: () => _runAction('Marked as played'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.calculator_multiply),
label: const Text('Reject'),
onPressed: () {},
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.share),
label: const Text('Share'),
onPressed: () {},
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.favorite_star),
label: const Text('Add Favorite'),
onPressed: () {},
label: const Text('Remove from queue'),
tooltip: 'Delete',
onPressed: () => _runAction('Removed from queue'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.back),
label: const Text('Backward'),
onPressed: () {},
label: const Text('Previous'),
tooltip: 'Left Arrow',
onPressed: () => _runAction('Previous track'),
),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.forward),
label: const Text('Forward'),
onPressed: () {},
label: const Text('Next'),
tooltip: 'Right Arrow',
onPressed: () => _runAction('Next track'),
),
];

Expand All @@ -114,16 +117,40 @@ class _CommandBarsPageState extends State<CommandBarsPage> with PageMixin {
bool _compact = false;
CommandBarOverflowBehavior overflowBehavior =
CommandBarOverflowBehavior.dynamicOverflow;
String _lastAction = 'Ready to play';

void _runAction(String action) {
setState(() => _lastAction = action);
}

@override
Widget build(final BuildContext context) {
return ScaffoldPage.scrollable(
header: const PageHeader(title: Text('CommandBar')),
children: [
const Text(
"Command bars provide users with easy access to your app's most "
'common tasks. Command bars can provide access to app-level or '
'page-specific commands and can be used with any navigation pattern.',
'This sample mirrors the WinUI Gallery media command bar. '
'Primary commands stay visible when possible; secondary commands '
'and dynamically overflowed commands appear in the More menu.',
),
const SizedBox(height: 8),
Card(
child: Row(
children: [
const Icon(FluentIcons.music_note, size: 32),
const SizedBox(width: 12),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Now playing', style: TextStyle(fontSize: 16)),
Text('The track selected in the WinUI Gallery sample'),
],
),
),
Text(_lastAction),
],
),
),
const SizedBox(height: 8),
Card(
Expand Down Expand Up @@ -200,9 +227,7 @@ class _CommandBarsPageState extends State<CommandBarsPage> with PageMixin {
],
),
),
subtitle(
content: const Text('Command bar with many items (dynamic overflow)'),
),
subtitle(content: const Text('Media player command bar')),
CodeSnippetCard(
codeSnippet:
'''final commandBarKey = GlobalKey<CommandBarState>();
Expand All @@ -213,20 +238,24 @@ CommandBar(
primaryItems: [
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.add),
label: const Text('New'),
tooltip: 'Create something new!',
onPressed: () {
// Create something new!
},
label: const Text('New playlist'),
tooltip: 'Ctrl+N',
onPressed: () {},
),
const CommandBarSeparator(),
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.delete),
label: const Text('Delete'),
tooltip: 'Delete what is currently selected!',
onPressed: () {
// Delete what is currently selected!
},
label: const Text('Remove'),
tooltip: 'Delete',
onPressed: () {},
),
],
secondaryItems: [
CommandBarButton(
icon: const WindowsIcon(WindowsIcons.share),
label: const Text('Share'),
tooltip: 'Ctrl+S',
onPressed: () {},
),
],
);
Expand All @@ -247,10 +276,9 @@ commandBarKey.currentState?.toggleSecondaryMenu();
primaryItems: [
...simpleCommandBarItems,
const CommandBarSeparator(),
...moreCommandBarItems,
const CommandBarSeparator(),
...evenMoreCommandBarItems,
],
secondaryItems: moreCommandBarItems,
),
),
),
Expand Down
8 changes: 5 additions & 3 deletions lib/src/controls/flyouts/tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,9 @@ class TooltipThemeData with Diagnosticable {
}(),
showDuration: const Duration(milliseconds: 1500),
waitDuration: const Duration(seconds: 1),
textStyle: theme.typography.caption,
textStyle: theme.typography.caption?.copyWith(
color: theme.resources.textFillColorPrimary,
),
decoration: () {
final radius = BorderRadius.circular(4);
final shadow = [
Expand All @@ -562,13 +564,13 @@ class TooltipThemeData with Diagnosticable {
];
if (theme.brightness == Brightness.light) {
return BoxDecoration(
color: Colors.white,
color: theme.resources.systemFillColorSolidNeutralBackground,
borderRadius: radius,
boxShadow: shadow,
);
} else {
return BoxDecoration(
color: Colors.grey,
color: theme.resources.systemFillColorSolidNeutralBackground,
borderRadius: radius,
boxShadow: shadow,
);
Expand Down
Loading
Loading