material_ribbon 1.1.0 copy "material_ribbon: ^1.1.0" to clipboard
material_ribbon: ^1.1.0 copied to clipboard

Material 3 ribbon components for Flutter desktops, webs, phones, and adaptive layouts.

Material Ribbon #

Material 3 ribbon components for Flutter desktop, web, phone, and adaptive layouts. material_ribbon provides an Office-inspired command surface built from tabs, groups, commands, galleries, and compact form controls.

Features #

  • Material 3 ribbon tabs with horizontal scrolling for constrained widths.
  • Contextual tabs that appear only for a matching editor selection.
  • Small, medium, and large commands, including action, toggle, menu, split, and gallery variants.
  • A customizable Quick Access Toolbar, optional persistence, and optional command search.
  • Keyboard key tips (Alt, F10, or a tab/command key tip) and Ctrl+F1 to collapse or expand the ribbon.
  • Ribbon-ready gallery, colour picker, combo box, font picker, text box, and spin box controls.
  • An adaptive compact layout below 720 logical pixels, or whenever compact is set explicitly.

Installation #

flutter pub add material_ribbon
import 'package:material_ribbon/material_ribbon.dart';

Quick start #

MaterialRibbon is controlled by the host: provide current editor state in RibbonContext and update state from callbacks.

class EditorPage extends StatefulWidget {
  const EditorPage({super.key});

  @override
  State<EditorPage> createState() => _EditorPageState();
}

class _EditorPageState extends State<EditorPage> {
  bool _collapsed = false;
  String? _selectionType;

  @override
  Widget build(BuildContext context) {
    final ribbonContext = RibbonContext(
      selectionType: _selectionType,
      selectionCount: _selectionType == null ? 0 : 1,
    );

    return Scaffold(
      body: Column(
        children: [
          MaterialRibbon(
            context: ribbonContext,
            collapsed: _collapsed,
            onCollapsedChanged: (value) => setState(() => _collapsed = value),
            quickAccessCommands: [
              RibbonCommand(
                id: 'save',
                label: 'Save',
                icon: Icons.save_outlined,
                shortcut: 'Ctrl+S',
                keyTip: 'S',
                onInvoke: () {/* save the document */},
              ),
            ],
            tabs: [
              RibbonTab(
                id: 'home',
                label: 'Home',
                keyTip: 'H',
                groups: [
                  RibbonGroup(
                    label: 'Clipboard',
                    commands: [
                      RibbonCommand(
                        id: 'paste',
                        label: 'Paste',
                        icon: Icons.content_paste_outlined,
                        size: RibbonCommandSize.large,
                        onInvoke: () {/* paste */},
                      ),
                    ],
                  ),
                ],
              ),
              RibbonTab(
                id: 'picture-format',
                label: 'Picture Format',
                isVisible: (value) => value.selectionType == 'image',
                groups: const [],
              ),
            ],
          ),
          const Expanded(child: Placeholder()),
        ],
      ),
    );
  }
}

Commands and groups #

Use RibbonCommand for each operation and place commands in a RibbonGroup. Large commands span the group command height; small and medium commands tile vertically. rows controls the number of command rows (from 1 through 3).

RibbonGroup(
  label: 'Paragraph',
  rows: 2,
  commands: [
    RibbonCommand(
      id: 'bold',
      label: 'Bold',
      icon: Icons.format_bold,
      type: RibbonCommandType.toggle,
      checkState: (_) => isBold
          ? RibbonCheckState.checked
          : RibbonCheckState.unchecked,
      onInvoke: toggleBold,
    ),
    RibbonCommand(
      id: 'align',
      label: 'Align',
      icon: Icons.format_align_left,
      type: RibbonCommandType.menu,
      menuCommands: alignmentCommands,
      onInvoke: () {},
    ),
  ],
)

Set isEnabled, isBusy, and disabledReason to derive command state from the current RibbonContext. The ribbon disables unavailable or busy commands and displays the reason in their tooltip.

Contextual tabs #

RibbonTab.isVisible is evaluated whenever the supplied RibbonContext changes, making it suitable for selection-sensitive tooling:

RibbonTab(
  id: 'table-layout',
  label: 'Table Layout',
  isVisible: (context) => context.selectionType == 'table',
  groups: tableGroups,
)

Ribbon controls and galleries #

RibbonGroup.controls accepts any widget. The package includes compact, controlled widgets intended for this area: RibbonGallery, RibbonColorPicker, RibbonComboBox, RibbonFontPicker, RibbonTextBox, and RibbonSpinBox.

For a gallery, onPreview is called while a pointer enters a cell and onPreviewEnd is called when it leaves the gallery. This lets an editor show a temporary preview and restore the committed value afterwards.

RibbonColorPicker(
  colors: const [Colors.black, Colors.red, Colors.blue],
  value: committedColor,
  onChanged: (color) => setState(() {
    committedColor = color;
    previewColor = color;
  }),
  onPreview: (color) => setState(() => previewColor = color),
  onPreviewEnd: () => setState(() => previewColor = committedColor),
)

Quick Access Toolbar and personalization #

Pass quickAccessCommands to set the default Quick Access Toolbar. The older leadingCommands property remains supported as an alias. To allow users to customize the toolbar, provide onPersonalizationChanged, a RibbonPersonalizationStore, or both. The store is application-owned, so it can use shared preferences, a database, or another persistence mechanism.

RibbonPersonalization stores Quick Access command IDs, tab ordering, and hidden tab IDs. Command IDs and tab IDs should therefore be stable and unique.

Optional command palette #

RibbonCommandPalette is independent of the ribbon. Place it in MaterialRibbon.commandPalette to show a search field in the desktop ribbon header. It is automatically omitted on narrow layouts.

MaterialRibbon(
  // ...tabs and context...
  commandPalette: RibbonCommandPalette(
    commands: commands,
    context: ribbonContext,
  ),
)

Example #

The runnable sample is in example/material_ribbon_example.dart. After creating the example platforms, run it with:

cd example
flutter create --platforms=windows,web .
flutter run -d windows -t material_ribbon_example.dart

API reference #

See API.md for the complete public API, constructor parameters, and behaviour notes.

Development #

flutter analyze
flutter test
0
likes
150
points
98
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Material 3 ribbon components for Flutter desktops, webs, phones, and adaptive layouts.

Repository (GitHub)
View/report issues

Topics

#flutter #material-design #ribbon #desktop #web

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on material_ribbon