shadcn_flutter icon indicating copy to clipboard operation
shadcn_flutter copied to clipboard

Toast incorrectly capture Data and InheritedTheme

Open sunarya-thito opened this issue 7 months ago • 3 comments

Discussed in https://github.com/sunarya-thito/shadcn_flutter/discussions/266

Originally posted by azliR May 26, 2025 Hi, thank you for this great package, I really love it! I have a question with toast and sheet, when i call it from a dialog, i got this error: E/flutter ( 4193): [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: 'package:flutter/src/widgets/inherited_theme.dart': Failed assertion: line 122 pos 7: 'debugDidFindAncestor': The provided `to` context must be an ancestor of the `from` context. When i provided the context from the page, the toast show under the dialog. Can you help me please? Thank you in advance!

sunarya-thito avatar May 26 '25 00:05 sunarya-thito

I have happend to find the same bug, I want to use a Drawer and display a Toast when something has happened inside the drawer. But due to the same issue, this is not possible.

bastigerner avatar Aug 20 '25 07:08 bastigerner

I found a solution: use the navigatorKey in order to get the context of the app.

  1. Create a GlobalKey
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey(debugLabel: 'root');
  1. Use it in ShadcnApp (or GoRouter if you're using ShadcnApp.router())
ShadcnApp(
  navigatorKey: rootNavigatorKey,
  // ...
)

// OR

GoRouter(
  navigatorKey: rootNavigatorKey,
  //...
)
  1. Use it to show toast
// I use a static helper to show toast
  static void toast({required Widget child}) {
    if (rootNavigatorKey.currentContext == null) {
      return;
    }
    showToast(
      location: ToastLocation.bottomCenter,
      context: rootNavigatorKey.currentContext!,
      builder: (context, overlay) => SurfaceCard(
        child: child,
      ),
    );
  }

xdidx avatar Oct 31 '25 22:10 xdidx

Code to reproduce:

import 'package:shadcn_flutter/shadcn_flutter.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return ShadcnApp(
      title: 'Flutter Demo',
      themeMode: ThemeMode.dark,
      home: MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      child: SafeArea(
        child: Column(
          children: [
            PrimaryButton(
              onPressed: () => openSheet(
                context: context,
                builder: (BuildContext context) => TestModal(),
                position: OverlayPosition.bottom,
              ),
              child: Text('Open sheet from page'),
            ),
            TestWidget(),
            TestModal(),
          ],
        ).gap(16),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return PrimaryButton(
      onPressed: () => openSheet(
        context: context,
        builder: (BuildContext context) => TestModal(),
        position: OverlayPosition.bottom,
      ),
      child: Text('Open sheet from widget'),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return PrimaryButton(
      child: Text(
        'Show toast from modal (NOT OK only if it is from the modal)',
      ),
      onPressed: () => showToast(
        context: context,
        builder: (context, overlay) => SurfaceCard(child: Text('test')),
      ),
    );
  }
}

xdidx avatar Nov 05 '25 01:11 xdidx