diff --git a/gallery/gallery/lib/studies/shrine/app.dart b/gallery/gallery/lib/studies/shrine/app.dart index 1f6f97912..71ca521d5 100644 --- a/gallery/gallery/lib/studies/shrine/app.dart +++ b/gallery/gallery/lib/studies/shrine/app.dart @@ -8,14 +8,13 @@ import 'package:gallery/l10n/gallery_localizations.dart'; import 'package:gallery/layout/adaptive.dart'; import 'package:gallery/studies/shrine/backdrop.dart'; import 'package:gallery/studies/shrine/category_menu_page.dart'; -import 'package:gallery/studies/shrine/colors.dart'; import 'package:gallery/studies/shrine/expanding_bottom_sheet.dart'; import 'package:gallery/studies/shrine/home.dart'; import 'package:gallery/studies/shrine/login.dart'; import 'package:gallery/studies/shrine/model/app_state_model.dart'; import 'package:gallery/studies/shrine/page_status.dart'; import 'package:gallery/studies/shrine/scrim.dart'; -import 'package:gallery/studies/shrine/supplemental/cut_corners_border.dart'; +import 'package:gallery/studies/shrine/theme.dart'; import 'package:scoped_model/scoped_model.dart'; class ShrineApp extends StatefulWidget { @@ -102,7 +101,7 @@ class _ShrineAppState extends State with TickerProviderStateMixin { ), initialRoute: '/login', onGenerateRoute: _getRoute, - theme: _shrineTheme.copyWith( + theme: shrineTheme.copyWith( platform: GalleryOptions.of(context).platform, ), // L10n settings. @@ -125,71 +124,3 @@ Route _getRoute(RouteSettings settings) { fullscreenDialog: true, ); } - -final ThemeData _shrineTheme = _buildShrineTheme(); - -IconThemeData _customIconTheme(IconThemeData original) { - return original.copyWith(color: shrineBrown900); -} - -ThemeData _buildShrineTheme() { - final ThemeData base = ThemeData.light(); - return base.copyWith( - colorScheme: shrineColorScheme, - accentColor: shrineBrown900, - primaryColor: shrinePink100, - buttonColor: shrinePink100, - scaffoldBackgroundColor: shrineBackgroundWhite, - cardColor: shrineBackgroundWhite, - textSelectionColor: shrinePink100, - errorColor: shrineErrorRed, - buttonTheme: const ButtonThemeData( - colorScheme: shrineColorScheme, - textTheme: ButtonTextTheme.normal, - ), - primaryIconTheme: _customIconTheme(base.iconTheme), - inputDecorationTheme: const InputDecorationTheme( - border: CutCornersBorder( - borderSide: BorderSide(color: shrineBrown900, width: 0.5), - ), - contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 16), - ), - textTheme: _buildShrineTextTheme(base.textTheme), - primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), - accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), - iconTheme: _customIconTheme(base.iconTheme), - ); -} - -TextTheme _buildShrineTextTheme(TextTheme base) { - return base - .copyWith( - headline: base.headline.copyWith(fontWeight: FontWeight.w500), - title: base.title.copyWith(fontSize: 18), - caption: - base.caption.copyWith(fontWeight: FontWeight.w400, fontSize: 14), - body2: base.body2.copyWith(fontWeight: FontWeight.w500, fontSize: 16), - button: base.button.copyWith(fontWeight: FontWeight.w500, fontSize: 14), - ) - .apply( - fontFamily: 'Rubik', - displayColor: shrineBrown900, - bodyColor: shrineBrown900, - ); -} - -const ColorScheme shrineColorScheme = ColorScheme( - primary: shrinePink100, - primaryVariant: shrineBrown900, - secondary: shrinePink50, - secondaryVariant: shrineBrown900, - surface: shrineSurfaceWhite, - background: shrineBackgroundWhite, - error: shrineErrorRed, - onPrimary: shrineBrown900, - onSecondary: shrineBrown900, - onSurface: shrineBrown900, - onBackground: shrineBrown900, - onError: shrineSurfaceWhite, - brightness: Brightness.light, -); diff --git a/gallery/gallery/lib/studies/shrine/login.dart b/gallery/gallery/lib/studies/shrine/login.dart index 7d5769f69..2de189f04 100644 --- a/gallery/gallery/lib/studies/shrine/login.dart +++ b/gallery/gallery/lib/studies/shrine/login.dart @@ -10,6 +10,7 @@ import 'package:gallery/layout/adaptive.dart'; import 'package:gallery/layout/text_scale.dart'; import 'package:gallery/l10n/gallery_localizations.dart'; import 'package:gallery/studies/shrine/colors.dart'; +import 'package:gallery/studies/shrine/theme.dart'; const _horizontalPadding = 24.0; @@ -117,6 +118,7 @@ class _UsernameTextField extends StatelessWidget { decoration: InputDecoration( labelText: GalleryLocalizations.of(context).shrineLoginUsernameLabel, + labelStyle: TextStyle(letterSpacing: mediumLetterSpacing), ), ), ), @@ -143,6 +145,7 @@ class _PasswordTextField extends StatelessWidget { decoration: InputDecoration( labelText: GalleryLocalizations.of(context).shrineLoginPasswordLabel, + labelStyle: TextStyle(letterSpacing: mediumLetterSpacing), ), ), ), @@ -192,6 +195,7 @@ class _CancelAndNextButtons extends StatelessWidget { padding: buttonTextPadding, child: Text( GalleryLocalizations.of(context).shrineNextButtonCaption, + style: TextStyle(letterSpacing: largeLetterSpacing), ), ), elevation: 8, diff --git a/gallery/gallery/lib/studies/shrine/shopping_cart.dart b/gallery/gallery/lib/studies/shrine/shopping_cart.dart index 853c14751..7b62c2bb9 100644 --- a/gallery/gallery/lib/studies/shrine/shopping_cart.dart +++ b/gallery/gallery/lib/studies/shrine/shopping_cart.dart @@ -11,6 +11,7 @@ import 'package:gallery/studies/shrine/colors.dart'; import 'package:gallery/studies/shrine/expanding_bottom_sheet.dart'; import 'package:gallery/studies/shrine/model/app_state_model.dart'; import 'package:gallery/studies/shrine/model/product.dart'; +import 'package:gallery/studies/shrine/theme.dart'; import 'package:gallery/l10n/gallery_localizations.dart'; const _startColumnWidth = 60.0; @@ -99,6 +100,7 @@ class _ShoppingCartPageState extends State { child: Text( GalleryLocalizations.of(context) .shrineCartClearButtonCaption, + style: TextStyle(letterSpacing: largeLetterSpacing), ), ), onPressed: () { @@ -126,7 +128,10 @@ class ShoppingCartSummary extends StatelessWidget { Widget build(BuildContext context) { final TextStyle smallAmountStyle = Theme.of(context).textTheme.body1.copyWith(color: shrineBrown600); - final TextStyle largeAmountStyle = Theme.of(context).textTheme.display1; + final TextStyle largeAmountStyle = Theme.of(context) + .textTheme + .display1 + .copyWith(letterSpacing: mediumLetterSpacing); final NumberFormat formatter = NumberFormat.simpleCurrency( decimalDigits: 2, locale: Localizations.localeOf(context).toString(), diff --git a/gallery/gallery/lib/studies/shrine/theme.dart b/gallery/gallery/lib/studies/shrine/theme.dart new file mode 100644 index 000000000..9777c5e88 --- /dev/null +++ b/gallery/gallery/lib/studies/shrine/theme.dart @@ -0,0 +1,105 @@ +// Copyright 2019 The Flutter team. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; +import 'package:gallery/studies/shrine/colors.dart'; +import 'package:gallery/studies/shrine/supplemental/cut_corners_border.dart'; + +const defaultLetterSpacing = 0.03; +const mediumLetterSpacing = 0.04; +const largeLetterSpacing = 1.0; + +final ThemeData shrineTheme = _buildShrineTheme(); + +IconThemeData _customIconTheme(IconThemeData original) { + return original.copyWith(color: shrineBrown900); +} + +ThemeData _buildShrineTheme() { + final ThemeData base = ThemeData.light(); + return base.copyWith( + colorScheme: _shrineColorScheme, + accentColor: shrineBrown900, + primaryColor: shrinePink100, + buttonColor: shrinePink100, + scaffoldBackgroundColor: shrineBackgroundWhite, + cardColor: shrineBackgroundWhite, + textSelectionColor: shrinePink100, + errorColor: shrineErrorRed, + buttonTheme: const ButtonThemeData( + colorScheme: _shrineColorScheme, + textTheme: ButtonTextTheme.normal, + ), + primaryIconTheme: _customIconTheme(base.iconTheme), + inputDecorationTheme: const InputDecorationTheme( + border: CutCornersBorder( + borderSide: BorderSide(color: shrineBrown900, width: 0.5), + ), + contentPadding: EdgeInsets.symmetric(vertical: 20, horizontal: 16), + ), + textTheme: _buildShrineTextTheme(base.textTheme), + primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), + accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), + iconTheme: _customIconTheme(base.iconTheme), + ); +} + +TextTheme _buildShrineTextTheme(TextTheme base) { + return base + .copyWith( + headline: base.headline.copyWith( + fontWeight: FontWeight.w500, + letterSpacing: defaultLetterSpacing, + ), + title: base.title.copyWith( + fontSize: 18, + letterSpacing: defaultLetterSpacing, + ), + caption: base.caption.copyWith( + fontWeight: FontWeight.w400, + fontSize: 14, + letterSpacing: defaultLetterSpacing, + ), + body2: base.body2.copyWith( + fontWeight: FontWeight.w500, + fontSize: 16, + letterSpacing: defaultLetterSpacing, + ), + body1: base.body1.copyWith( + letterSpacing: defaultLetterSpacing, + ), + subhead: base.subhead.copyWith( + letterSpacing: defaultLetterSpacing, + ), + display1: base.display1.copyWith( + letterSpacing: defaultLetterSpacing, + ), + button: base.button.copyWith( + fontWeight: FontWeight.w500, + fontSize: 14, + letterSpacing: defaultLetterSpacing, + ), + ) + .apply( + fontFamily: 'Rubik', + displayColor: shrineBrown900, + bodyColor: shrineBrown900, + ); +} + +const ColorScheme _shrineColorScheme = ColorScheme( + primary: shrinePink100, + primaryVariant: shrineBrown900, + secondary: shrinePink50, + secondaryVariant: shrineBrown900, + surface: shrineSurfaceWhite, + background: shrineBackgroundWhite, + error: shrineErrorRed, + onPrimary: shrineBrown900, + onSecondary: shrineBrown900, + onSurface: shrineBrown900, + onBackground: shrineBrown900, + onError: shrineSurfaceWhite, + brightness: Brightness.light, +);