Skip to content

Feat: add nested submenus #69

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open

Conversation

willsmanley
Copy link

@willsmanley willsmanley commented Mar 12, 2025

I forked this awesome library to add optional behavior for a "nested submenu". In other words, you can hover over a "primary menu" option and it can provide an outer concentric circle with more sub-options.

This can be useful for more complicated use cases where you have categories of nested options.

If this is useful, I am happy to work together to try to get some version of this merged upstream here. If not I can maintain a separate fork, but will probably not go through the extra effort to publish the separate fork to pub.dev.

There are probably some things you would like to change about this implementation since this is only my first whack at it from one day, but its working pretty well so far. Here is a usage example:

import 'package:flutter/material.dart';
import 'package:pie_menu/pie_menu.dart';

class PieMenuSubmenusExample extends StatelessWidget {
  const PieMenuSubmenusExample({super.key});

  @override
  Widget build(BuildContext context) {
    return PieCanvas(
      theme: const PieTheme(
        delayDuration: Duration(milliseconds: 150),
        buttonTheme: PieButtonTheme(
          backgroundColor: Colors.blueGrey,
          iconColor: Colors.white,
        ),
        buttonThemeHovered: PieButtonTheme(
          backgroundColor: Colors.orange,
          iconColor: Colors.white,
        ),
        overlayColor: Colors.black54,
        radius: 80,
        tooltipTextStyle: TextStyle(
          fontSize: 18,
          fontWeight: FontWeight.bold,
        ),
      ),
      child: Center(
        child: PieMenu(
          actions: [
            // Regular action (no submenu)
            PieAction(
              tooltip: const Text('Share'),
              child: const Icon(Icons.share),
              onSelect: () {
                debugPrint('Share selected');
              },
            ),
            
            // Action with submenu
            PieAction.submenu(
              tooltip: const Text('Colors'),
              child: const Icon(Icons.palette),
              submenuActions: [
                PieAction(
                  tooltip: const Text('Red'),
                  child: const Icon(Icons.circle, color: Colors.red),
                  onSelect: () {
                    debugPrint('Red selected');
                  },
                ),
                PieAction(
                  tooltip: const Text('Green'),
                  child: const Icon(Icons.circle, color: Colors.green),
                  onSelect: () {
                    debugPrint('Green selected');
                  },
                ),
                PieAction(
                  tooltip: const Text('Blue'),
                  child: const Icon(Icons.circle, color: Colors.blue),
                  onSelect: () {
                    debugPrint('Blue selected');
                  },
                ),
              ],
            ),
            
            // Another action with submenu
            PieAction.submenu(
              tooltip: const Text('Tools'),
              child: const Icon(Icons.build),
              submenuActions: [
                PieAction(
                  tooltip: const Text('Settings'),
                  child: const Icon(Icons.settings),
                  onSelect: () {
                    debugPrint('Settings selected');
                  },
                ),
                PieAction(
                  tooltip: const Text('Edit'),
                  child: const Icon(Icons.edit),
                  onSelect: () {
                    debugPrint('Edit selected');
                  },
                ),
                PieAction(
                  tooltip: const Text('Delete'),
                  child: const Icon(Icons.delete),
                  onSelect: () {
                    debugPrint('Delete selected');
                  },
                ),
                PieAction(
                  tooltip: const Text('Add'),
                  child: const Icon(Icons.add),
                  onSelect: () {
                    debugPrint('Add selected');
                  },
                ),
              ],
            ),
            
            // Regular action (no submenu)
            PieAction(
              tooltip: const Text('Favorite'),
              child: const Icon(Icons.favorite),
              onSelect: () {
                debugPrint('Favorite selected');
              },
            ),
          ],
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              color: Colors.blue,
              borderRadius: BorderRadius.circular(12),
            ),
            child: const Center(
              child: Icon(
                Icons.touch_app,
                color: Colors.white,
                size: 40,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

@willsmanley
Copy link
Author

@rasitayaz FYI and thank you for the awesome foundation to build this upon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant