Skip to content
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

Don't require a ShadApp #276

Closed
matthew-carroll opened this issue Jan 29, 2025 · 9 comments
Closed

Don't require a ShadApp #276

matthew-carroll opened this issue Jan 29, 2025 · 9 comments
Assignees
Labels
accepted A valid and reproducible issue bug Something isn't working

Comments

@matthew-carroll
Copy link

matthew-carroll commented Jan 29, 2025

Steps to reproduce

I just added shadcn_ui to another one of my apps. I did so just to use a few widgets. But I can't use those widgets without changing my entire app widget.

I switched to ShadApp.material() but now, because my theming is light, a bunch of my text has turned white on a white background and I can't see it.

I tried to setting the ShadThemeData to a light brightness and a light color scheme, but the text is still white on white.

The fundamental issue here is that I couldn't just use a few widgets. I had to impact my entire application. This is frustrating even with a tiny app. I would be that this could be a deal killer for larger apps.

Specific Problem:
At the moment, I can't figure out how to truly get a light theme. I'm using the following code and still getting white text and light borders throughout my app:

    ShadApp.material(
      title: 'Space Pod',
      theme: ShadThemeData(
        brightness: Brightness.light,
        colorScheme: const ShadNeutralColorScheme.light(),
      ),
      home: const MainScreen(),
      debugShowCheckedModeBanner: false,
    )

Expected results

I can add a widget without changing my whole app.

Actual results

I have to impact my entire app to use a single widget.

shadcn_ui version

0.18.4

Platform

MacOS

Code sample

Code sample
[Paste your code here]

Screenshots or Video

Screenshots / Video demonstration

[Upload media here]

Logs

Logs
[Paste your logs here]

Flutter Doctor output

Doctor output
[Paste your output here]
@matthew-carroll matthew-carroll added bug Something isn't working triage Issues that need assessment and prioritization labels Jan 29, 2025
@nank1ro
Copy link
Owner

nank1ro commented Jan 29, 2025

Did you set the theme mode to light?

You can use ShadApp.custom which allows you to create a custom app implementation if the default one provided by shadcn doesn't satisfy you.
https://flutter-shadcn-ui.mariuti.com/#shadcn--custom-app
You can use MaterialApp in the appBuilder

@matthew-carroll
Copy link
Author

@nank1ro I added the code snippet in the issue ticket. I set both obvious properties to "light"

@matthew-carroll
Copy link
Author

@nank1ro I adjusted the code to the following:

return ShadApp.material(
      title: 'Space Pod',
      builder: (context, child) {
        return MaterialApp(
          home: child,
        );
      },
      home: const MainScreen(),
      debugShowCheckedModeBanner: false,
    );

That seems to unbreak my widget, but I'm still getting unexpected results from Shad widgets:

Screen.Recording.2025-01-29.at.1.48.03.PM.mov

@matthew-carroll
Copy link
Author

PS - While my immediate problem is around correct configuration, I still think the root issue is that using just 1 widget requires making a modification that literally spans the entire app.

@nank1ro
Copy link
Owner

nank1ro commented Jan 30, 2025

There is surely a bug here because the two themes are not in sync.
We've two ways to fix this but let me explain why it's happening first.

Material Theme behavior

By default MaterialApp uses ThemeData.light() and if you don't specify the darkTheme you always see the light theme

Opt-in (to dark mode)

Add darkTheme: ThemeData.dark()

Opt-out (from dark mode)

By default, because darkTheme is null.

Shad Theme behavior

By default ShadApp handles both the light and the dark mode, using the ThemeMode.system.
This means that if the device is in light mode, a light ShadTheme is used.
If the device is in dark mode, a dark ShadTheme is used.

In fact the themes are not needed on ShadApp because they already have a default, unless you need to override some properties. You can avoid passing theme and darkTheme.

Opt-in (to dark mode)

By default, even if you don't specify a darkTheme to ShadApp, it defaults to

 ShadThemeData(
  colorScheme: const ShadSlateColorScheme.dark(),
  brightness: Brightness.dark,
);

Opt-out (from dark mode)

To opt-out from dark mode the user has to specify themeMode: ThemeMode.light to ShadApp.

Options

  1. I can add ThemeData.dark() to the default MaterialApp created internally, to keep the Material ThemeData in sync the Shad ThemeData
  2. I can make the behavior equal to Material, and opt-in to the dark theme by specifying darkTheme.

@matthew-carroll let me know which behavior do you prefer.

@nank1ro nank1ro self-assigned this Jan 30, 2025
@nank1ro nank1ro added accepted A valid and reproducible issue waiting for customer response Cannot make further progress on this issue until the original reporter responds and removed triage Issues that need assessment and prioritization labels Jan 30, 2025
@nank1ro
Copy link
Owner

nank1ro commented Jan 30, 2025

PS - While my immediate problem is around correct configuration, I still think the root issue is that using just 1 widget requires making a modification that literally spans the entire app.

Regarding the modifications needed to replace MaterialApp with ShadApp you can use:

return ShadApp.custom(
          themeMode: ThemeMode.light,
          appBuilder: (context, theme) => MaterialApp(
            theme: theme, // Default ThemeData created by ShadApp, you can rely on it or not
            builder: (context, child) {
              return ShadToaster(child: child!);
            },
            ...
          ),
        )

In this way you have to change very few things and you can easily test ShadApp.

@MarkOSullivan94
Copy link

Why do you need to use ShadApp? Why can't it be optional?

@nank1ro
Copy link
Owner

nank1ro commented Jan 30, 2025

Why do you need to use ShadApp? Why can't it be optional?

@MarkOSullivan94
Because it's the correct way to implement a design system.
Material has MaterialApp
Cupertino has CupertinoApp
fluent_ui has FluentApp
macos_ui has MacosApp

Every implementation uses the low level WidgetsApp.

The reason for this is because there is a lot of complexity hidden in an app implementation.
It's not just a ThemeData wrap.

If the user takes all this complexity on its own, if I add new components and put new widgets or new logic in ShadApp, the user has to update the code very often, and it's very error prone.
It will not be a simple dependency update.

The fact that you have ShadApp.material etc it's a "nice-have".
The library has not all the components implemented yet, so I decided to allow using two design systems simultaneously.

But the typical usage I would expect from the user perspective is to stick to a single design system, and just use ShadApp().

@nank1ro
Copy link
Owner

nank1ro commented Feb 3, 2025

Made the dark theme behavior equal to material

@nank1ro nank1ro closed this as completed Feb 3, 2025
@nank1ro nank1ro removed the waiting for customer response Cannot make further progress on this issue until the original reporter responds label Feb 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted A valid and reproducible issue bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants