Merge branch 'main' of https://github.com/flutter/samples into compass-app

pull/2449/head
Eric Windmill 1 week ago
commit 415fdbbf1b

@ -27,7 +27,7 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
with:
distribution: 'zulu'
java-version: '17'
@ -43,7 +43,7 @@ jobs:
# if: github.repository == 'flutter/samples'
# steps:
# - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
# - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
# - uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
# with:
# distribution: 'zulu'
# java-version: '17'
@ -59,7 +59,7 @@ jobs:
if: github.repository == 'flutter/samples'
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
with:
distribution: 'zulu'
java-version: '17'

@ -28,7 +28,7 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
with:
distribution: 'zulu'
java-version: '17'
@ -53,7 +53,7 @@ jobs:
# if: github.repository == 'flutter/samples'
# steps:
# - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
# - uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
# - uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
# with:
# distribution: 'zulu'
# java-version: '17'
@ -67,7 +67,7 @@ jobs:
if: github.repository == 'flutter/samples'
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- uses: actions/setup-java@6a0805fcefea3d4657a47ac4c165951e33482018
- uses: actions/setup-java@2dfa2011c5b2a0f1489bf9e433881c92c1631f88
with:
distribution: 'zulu'
java-version: '17'

@ -1,55 +0,0 @@
name: Scorecards supply-chain security
on:
# Only the default branch is supported.
branch_protection_rule:
push:
branches: [ main ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecards analysis
runs-on: ubuntu-latest
if: ${{ github.repository == 'flutter/samples' }}
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
actions: read
contents: read
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46
with:
results_file: results.sarif
results_format: sarif
# Read-only PAT token. To create it,
# follow the steps in https://github.com/ossf/scorecard-action#pat-token-creation.
repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}
# Publish the results to enable scorecard badges. For more details, see
# https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories, `publish_results` will automatically be set to `false`,
# regardless of the value entered here.
publish_results: true
# Upload the results as artifacts (optional).
- name: "Upload artifact"
uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93
with:
sarif_file: results.sarif

@ -14,7 +14,7 @@ dependencies:
ffi: ^2.1.2
dev_dependencies:
ffigen: ^13.0.0
ffigen: ^14.0.0
jnigen: ^0.11.0
flutter_test:
sdk: flutter

@ -33,7 +33,7 @@ dev_dependencies:
flutter_lints: ^4.0.0
flutter_test:
sdk: flutter
flutter_launcher_icons: ^0.13.0
flutter_launcher_icons: ^0.14.0
test: ^1.19.0
flutter:

@ -1,6 +1,14 @@
package com.example.material_3_demo
import io.flutter.embedding.android.FlutterActivity
import android.os.Bundle
import androidx.core.view.WindowCompat
class MainActivity: FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
}
}

@ -14,5 +14,19 @@
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
<!-- values-v29/themes.xml -->
<item name="android:navigationBarColor">
@android:color/transparent
</item>
<!-- Optional: set to transparent if your app is drawing behind the status bar. -->
<item name="android:statusBarColor">
@android:color/transparent
</item>
<!-- Optional: set for a light status bar with dark content. -->
<item name="android:windowLightStatusBar">
true
</item>
</style>
</resources>

@ -0,0 +1,93 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class ColorBox extends StatefulWidget {
const ColorBox(
{super.key,
required this.label,
required this.tone,
required this.color,
required this.onColor,
required this.height,
required this.width,
this.displayPaletteInfo = false});
final String label;
final String tone;
final Color color, onColor;
final double height, width;
final bool displayPaletteInfo;
@override
State<ColorBox> createState() => _ColorBoxState();
}
class _ColorBoxState extends State<ColorBox> {
bool hovered = false;
@override
Widget build(BuildContext context) {
final fonts = Theme.of(context).textTheme;
return MouseRegion(
onEnter: (_) {
if (mounted) setState(() => hovered = true);
},
onExit: (_) {
if (mounted) setState(() => hovered = false);
},
child: Container(
color: widget.color,
height: widget.height,
width: widget.width,
child: DefaultTextStyle(
style: fonts.labelSmall!.copyWith(color: widget.onColor),
child: Stack(
children: [
Positioned(
top: 10,
left: 10,
child: Text(widget.label),
),
Positioned(
bottom: 10,
right: 10,
child: Text(widget.displayPaletteInfo ? widget.tone : ''),
),
if (hovered)
Positioned(
top: 0,
right: 0,
child: IconButton(
padding: EdgeInsets.zero,
color: widget.onColor,
tooltip: 'Copy hex color',
icon: const Icon(Icons.copy, size: 24),
onPressed: () async {
final messenger = ScaffoldMessenger.of(context);
// Copy color as hex to clipboard
String hex = '#';
final c = widget.color;
// Will change from int 0-255 to double 0.0-1.0 in 3.26+
// The properties also change from red/green/blue to r/g/b
// hex += (c.[r g b] * 255.0).round().toRadixString(16).padLeft(2, '0');
hex += c.red.toRadixString(16).padLeft(2, '0');
hex += c.green.toRadixString(16).padLeft(2, '0');
hex += c.blue.toRadixString(16).padLeft(2, '0');
final data = ClipboardData(text: hex);
await Clipboard.setData(data);
messenger.hideCurrentSnackBar();
messenger.showSnackBar(
SnackBar(
content: Text('Copied $hex to clipboard'),
),
);
},
),
),
],
),
),
),
);
}
}

@ -4,6 +4,7 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:material_3_demo/scheme.dart';
import 'package:url_launcher/url_launcher.dart';
const Widget divider = SizedBox(height: 10);
@ -11,7 +12,7 @@ const Widget divider = SizedBox(height: 10);
// If screen content width is greater or equal to this value, the light and dark
// color schemes will be displayed in a column. Otherwise, they will
// be displayed in a row.
const double narrowScreenWidthThreshold = 400;
const double narrowScreenWidthThreshold = 500;
class ColorPalettesScreen extends StatelessWidget {
const ColorPalettesScreen({super.key});
@ -94,32 +95,32 @@ class ColorPalettesScreen extends StatelessWidget {
),
);
} else {
Color seed = Theme.of(context).colorScheme.primary;
ColorScheme lightScheme = ColorScheme.fromSeed(
seedColor: seed, brightness: Brightness.light);
ColorScheme darkScheme = ColorScheme.fromSeed(
seedColor: seed, brightness: Brightness.dark);
return SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 5),
padding: const EdgeInsets.all(8),
child: Column(
children: [
dynamicColorNotice(),
Row(
children: [
Expanded(
child: Column(
children: [
schemeLabel('Light ColorScheme'),
schemeView(lightTheme),
],
),
),
Expanded(
child: Column(
children: [
schemeLabel('Dark ColorScheme'),
schemeView(darkTheme),
],
),
),
],
SchemePreview(
label: "Light ColorScheme",
scheme: lightScheme,
brightness: Brightness.light,
contrast: 1.0,
colorMatch: false,
),
const SizedBox(height: 16),
SchemePreview(
label: "Dark ColorScheme",
scheme: darkScheme,
brightness: Brightness.dark,
contrast: 1.0,
colorMatch: false,
),
const SizedBox(height: 16),
],
),
),

@ -0,0 +1,417 @@
import 'package:flutter/material.dart';
import '../color_box.dart';
class SchemePreview extends StatefulWidget {
const SchemePreview({
super.key,
required this.label,
required this.scheme,
required this.brightness,
required this.colorMatch,
required this.contrast,
});
final String label;
final ColorScheme scheme;
final Brightness brightness;
final bool colorMatch;
final double contrast;
@override
State<SchemePreview> createState() => _SchemePreviewState();
}
class _SchemePreviewState extends State<SchemePreview> {
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final fonts = theme.textTheme;
final colors = theme.colorScheme;
final dark = widget.brightness == Brightness.dark;
final scheme = widget.scheme;
return Theme(
data: theme.copyWith(colorScheme: scheme),
child: FittedBox(
fit: BoxFit.fitWidth,
child: Container(
width: 902,
decoration: BoxDecoration(
color: scheme.surface,
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: theme.brightness == widget.brightness
? colors.outlineVariant
: Colors.transparent,
),
),
padding: const EdgeInsets.only(
top: 16,
left: 16,
right: 16,
),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
widget.label,
style: fonts.titleMedium!.copyWith(
color: scheme.onSurface,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.start,
),
),
],
),
const SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisSize: MainAxisSize.min,
children: [
Column(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Primary',
tone: dark ? 'P-80' : 'P-40',
color: scheme.primary,
onColor: scheme.onPrimary,
height: 87,
width: 208,
),
ColorBox(
label: 'On Primary',
tone: dark ? 'P-20' : 'P-100',
color: scheme.onPrimary,
onColor: scheme.primary,
height: 40,
width: 208,
),
const SizedBox(height: 5),
ColorBox(
label: 'Primary Container',
tone: dark ? 'P-30' : 'P-90',
color: scheme.primaryContainer,
onColor: scheme.onPrimaryContainer,
height: 87,
width: 208,
),
ColorBox(
label: 'On Primary Container',
tone: dark ? 'P-90' : 'P-10',
color: scheme.onPrimaryContainer,
onColor: scheme.primaryContainer,
height: 40,
width: 208,
),
],
),
const SizedBox(width: 5),
Column(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Secondary',
tone: dark ? 'S-80' : 'S-40',
color: scheme.secondary,
onColor: scheme.onSecondary,
height: 87,
width: 208,
),
ColorBox(
label: 'On Secondary',
tone: dark ? 'S-20' : 'S-100',
color: scheme.onSecondary,
onColor: scheme.secondary,
height: 40,
width: 208,
),
const SizedBox(height: 5),
ColorBox(
label: 'Secondary Container',
tone: dark ? 'S-30' : 'S-90',
color: scheme.secondaryContainer,
onColor: scheme.onSecondaryContainer,
height: 87,
width: 208,
),
ColorBox(
label: 'On Secondary Container',
tone: dark ? 'S-90' : 'S-10',
color: scheme.onSecondaryContainer,
onColor: scheme.secondaryContainer,
height: 40,
width: 208,
),
],
),
const SizedBox(width: 5),
Column(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Tertiary',
tone: dark ? 'T-80' : 'T-40',
color: scheme.tertiary,
onColor: scheme.onTertiary,
height: 87,
width: 208,
),
ColorBox(
label: 'On Tertiary',
tone: dark ? 'T-20' : 'T-100',
color: scheme.onTertiary,
onColor: scheme.tertiary,
height: 40,
width: 208,
),
const SizedBox(height: 5),
ColorBox(
label: 'Tertiary Container',
tone: dark ? 'T-30' : 'T-90',
color: scheme.tertiaryContainer,
onColor: scheme.onTertiaryContainer,
height: 87,
width: 208,
),
ColorBox(
label: 'On Tertiary Container',
tone: dark ? 'T-90' : 'T-10',
color: scheme.onTertiaryContainer,
onColor: scheme.tertiaryContainer,
height: 40,
width: 208,
),
],
),
],
),
const SizedBox(height: 20),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Surface Dim',
tone: dark ? 'N-6' : 'N-87',
color: scheme.surfaceDim,
onColor: scheme.onSurface,
height: 105,
width: 211.45,
),
ColorBox(
label: 'Surface',
tone: dark ? 'N-6' : 'N-98',
color: scheme.surface,
onColor: scheme.onSurface,
height: 105,
width: 211.45,
),
ColorBox(
label: 'Surface Bright',
tone: dark ? 'N-24' : 'N-98',
color: scheme.surfaceBright,
onColor: scheme.onSurface,
height: 105,
width: 211.45,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Surf. Container\nLowest',
tone: dark ? 'N-4' : 'N-100',
color: scheme.surfaceContainerLowest,
onColor: scheme.onSurface,
height: 105,
width: 126.87,
),
ColorBox(
label: 'Surf. Container\nLow',
tone: dark ? 'N-10' : 'N-96',
color: scheme.surfaceContainerLow,
onColor: scheme.onSurface,
height: 105,
width: 126.87,
),
ColorBox(
label: 'Surf. Container',
tone: dark ? 'N-12' : 'N-94',
color: scheme.surfaceContainer,
onColor: scheme.onSurface,
height: 105,
width: 126.87,
),
ColorBox(
label: 'Surf. Container\nHigh',
tone: dark ? 'N-17' : 'N-92',
color: scheme.surfaceContainerHigh,
onColor: scheme.onSurface,
height: 105,
width: 126.87,
),
ColorBox(
label: 'Surf. Container\nHighest',
tone: dark ? 'N-24' : 'N-90',
color: scheme.surfaceContainerHighest,
onColor: scheme.onSurface,
height: 105,
width: 126.87,
),
],
),
const SizedBox(height: 5),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'On Surface',
tone: dark ? 'N-90' : 'N-10',
color: scheme.onSurface,
onColor: scheme.surface,
height: 40,
width: 158.59,
),
ColorBox(
label: 'On Surface Var.',
tone: dark ? 'NV-90' : 'NV-30',
color: scheme.onSurfaceVariant,
onColor: scheme.surfaceContainerHighest,
height: 40,
width: 158.59,
),
ColorBox(
label: 'Outline',
tone: dark ? 'NV-60' : 'NV-50',
color: scheme.outline,
onColor: scheme.surface,
height: 40,
width: 158.59,
),
ColorBox(
label: 'Outline Variant',
tone: dark ? 'NV-30' : 'NV-80',
color: scheme.outlineVariant,
onColor: scheme.onSurface,
height: 40,
width: 158.59,
),
],
),
],
),
const SizedBox(width: 20),
Column(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Error',
tone: dark ? 'E-80' : 'E-40',
color: scheme.error,
onColor: scheme.onError,
height: 87,
width: 208,
),
ColorBox(
label: 'On Error',
tone: dark ? 'E-20' : 'E-100',
color: scheme.onError,
onColor: scheme.error,
height: 40,
width: 208,
),
const SizedBox(height: 5),
ColorBox(
label: 'Error Container',
tone: dark ? 'E-30' : 'E-90',
color: scheme.errorContainer,
onColor: scheme.onErrorContainer,
height: 87,
width: 208,
),
ColorBox(
label: 'On Error Container',
tone: dark ? 'E-90' : 'E-10',
color: scheme.onErrorContainer,
onColor: scheme.errorContainer,
height: 40,
width: 208,
),
const SizedBox(height: 20),
ColorBox(
label: 'Inverse Surface',
tone: dark ? 'N-90' : 'N-20',
color: scheme.inverseSurface,
onColor: scheme.onInverseSurface,
height: 120,
width: 208,
),
ColorBox(
label: 'Inverse On Surface',
tone: dark ? 'N-20' : 'N-95',
color: scheme.onInverseSurface,
onColor: scheme.inverseSurface,
height: 40,
width: 208,
),
const SizedBox(height: 5),
ColorBox(
label: 'Inverse Primary',
tone: dark ? 'P-40' : 'P-80',
color: scheme.inversePrimary,
onColor: scheme.onSurface,
height: 40,
width: 208,
),
const SizedBox(height: 16),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ColorBox(
label: 'Scrim',
tone: 'N-0',
color: scheme.scrim,
onColor: Colors.white,
height: 40,
width: 96.31,
),
const SizedBox(width: 20),
ColorBox(
label: 'Shadow',
tone: 'N-0',
color: scheme.shadow,
onColor: Colors.white,
height: 40,
width: 96.31,
),
],
),
const SizedBox(height: 8),
],
),
],
),
],
),
),
),
);
}
}

@ -15,7 +15,7 @@ class TypographyScreen extends StatelessWidget {
return Expanded(
child: ListView(
children: <Widget>[
const SizedBox(height: 7),
const SizedBox(height: 8),
TextStyleExample(
name: 'Display Large', style: textTheme.displayLarge!),
TextStyleExample(

@ -6,6 +6,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:material_3_demo/color_palettes_screen.dart';
import 'package:material_3_demo/main.dart';
import 'package:material_3_demo/scheme.dart';
import 'component_screen_test.dart';
@ -69,6 +70,6 @@ void main() {
));
expect(find.text('Light ColorScheme'), findsOneWidget);
expect(find.text('Dark ColorScheme'), findsOneWidget);
expect(find.byType(ColorGroup, skipOffstage: false), findsNWidgets(18));
expect(find.byType(SchemePreview, skipOffstage: false), findsNWidgets(2));
});
}

@ -46,7 +46,8 @@ declare -ar PROJECT_NAMES=(
"infinite_list"
"ios_app_clip"
"isolate_example"
"material_3_demo"
# TODO @ewindmill -- Color.red is deprecated and should be Color.r (same for green and blue)
# "material_3_demo"
"navigation_and_routing"
"place_tracker"
"platform_channels"

@ -47,7 +47,8 @@ declare -ar PROJECT_NAMES=(
"infinite_list"
"ios_app_clip"
"isolate_example"
"material_3_demo"
# TODO @ewindmill -- Color.red is deprecated and should be Color.r (same for green and blue)
# "material_3_demo"
"navigation_and_routing"
"place_tracker"
"platform_channels"

@ -29,7 +29,7 @@ dev_dependencies:
path: ../analysis_defaults
flutter_test:
sdk: flutter
flutter_launcher_icons: ^0.13.0
flutter_launcher_icons: ^0.14.0
flutter:
assets:

@ -30,13 +30,13 @@
"@angular/cli": "~18.2.0",
"@angular/compiler-cli": "^18.0.1",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.2.0",
"jasmine-core": "~5.3.0",
"karma": "~6.4.2",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.5.3"
"typescript": "~5.6.2"
},
"sideEffects": false
}

Loading…
Cancel
Save