-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Description
I'm working on a design system for a Flutter app. This design system supports Android and iOS only. Our component-housing of choice is Widgetbook. Widgetbook, along with many other ways of sharing design systems, is web based. Because of this, Platform reports itself as web. Alternatively, building Widgetbook as a desktop app reports the platform as macOS (or windows/linux). I'd like to see my widgets as if they are on the Android/iOS platform, regardless of true platform. This for some widgets is accomplished by using Theme.of(context).platform as specified in the documentation for defaultTargetPlatform here.
"Widgets from the material library should use [Theme.of] to determine the current platform for styling purposes, rather than using [defaultTargetPlatform]"
However, VisualDensity.adaptivePlatformDensity which is the default setting for Material button densities uses a switch case on defaultTargetPlatform instead of the ambient ThemeDatas platform. This means that without explicitly setting the visualDensity to comfortable in the individual button's styles or the elevatedButtonTheme (or outlined/text/etc) in ThemeData, there is no way to allow buttons to continue being platform adaptive AND force them to a specific platform in certain scenarios (like my Widgetbook).
The Material buttons, and other places that use VisualDensity should retrieve the target platform from ThemeData as the above comment suggests.
Steps to Reproduce
- Run a standard
flutter createapp on web or desktop with the following contents of the Scaffold body:
final theme = Theme.of(context);
return Row(
children: [
ElevatedButton(
onPressed: () {},
child: const Text('Button'),
),
Theme(
data: theme.copyWith(platform: TargetPlatform.android),
child: ElevatedButton(
onPressed: () {},
child: const Text('Button'),
),
),
],
);
Expected results:

The first button due to being on web/desktop platform would render with a compact density while the second renders with comfortable due to the ambient Theme supplying a new TargetPlatform
Actual results:

Two buttons that look the same with a compact density despite an explicit TargetPlatform.android and the knowledge from the documentation that "Widgets from the material library should use [Theme.of] to determine the current platform for styling purposes, rather than using [defaultTargetPlatform]".