| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| /// @docImport 'interface_level.dart'; |
| /// @docImport 'theme.dart'; |
| library; |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'colors.dart'; |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Values derived from https://developer.apple.com/design/resources/. |
| const TextStyle _kDefaultTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemText', |
| fontSize: 17.0, |
| letterSpacing: -0.41, |
| color: CupertinoColors.label, |
| decoration: TextDecoration.none, |
| ); |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Values derived from https://developer.apple.com/design/resources/. |
| // See [iOS 17 + iPadOS 17 UI Kit](https://www.figma.com/community/file/1248375255495415511) for details. |
| const TextStyle _kDefaultActionTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemText', |
| fontSize: 17.0, |
| letterSpacing: -0.41, |
| color: CupertinoColors.activeBlue, |
| decoration: TextDecoration.none, |
| ); |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Values derived from https://developer.apple.com/design/resources/. |
| // See [iOS 17 + iPadOS 17 UI Kit](https://www.figma.com/community/file/1248375255495415511) for details. |
| const TextStyle _kDefaultActionSmallTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemText', |
| fontSize: 15.0, |
| letterSpacing: -0.23, |
| color: CupertinoColors.activeBlue, |
| decoration: TextDecoration.none, |
| ); |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Values derived from https://developer.apple.com/design/resources/. |
| const TextStyle _kDefaultTabLabelTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemText', |
| fontSize: 10.0, |
| fontWeight: FontWeight.w500, |
| letterSpacing: -0.24, |
| color: CupertinoColors.inactiveGray, |
| ); |
| |
| const TextStyle _kDefaultMiddleTitleTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemText', |
| fontSize: 17.0, |
| fontWeight: FontWeight.w600, |
| letterSpacing: -0.41, |
| color: CupertinoColors.label, |
| ); |
| |
| const TextStyle _kDefaultLargeTitleTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemDisplay', |
| fontSize: 34.0, |
| fontWeight: FontWeight.w700, |
| letterSpacing: 0.38, |
| color: CupertinoColors.label, |
| ); |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Inspected on iOS 13 simulator with "Debug View Hierarchy". |
| // Value extracted from off-center labels. Centered labels have a font size of 25pt. |
| // |
| // The letterSpacing sourced from iOS 14 simulator screenshots for comparison. |
| // See also: |
| // |
| // * https://github.com/flutter/flutter/pull/65501#discussion_r486557093 |
| const TextStyle _kDefaultPickerTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemDisplay', |
| fontSize: 21.0, |
| fontWeight: FontWeight.w400, |
| letterSpacing: -0.6, |
| color: CupertinoColors.label, |
| ); |
| |
| // Please update _TextThemeDefaultsBuilder accordingly after changing the default |
| // color here, as their implementation depends on the default value of the color |
| // field. |
| // |
| // Inspected on iOS 13 simulator with "Debug View Hierarchy". |
| // Value extracted from off-center labels. Centered labels have a font size of 25pt. |
| const TextStyle _kDefaultDateTimePickerTextStyle = TextStyle( |
| inherit: false, |
| fontFamily: 'CupertinoSystemDisplay', |
| fontSize: 21, |
| letterSpacing: 0.4, |
| fontWeight: FontWeight.normal, |
| color: CupertinoColors.label, |
| ); |
| |
| TextStyle? _resolveTextStyle(TextStyle? style, BuildContext context) { |
| // This does not resolve the shadow color, foreground, background, etc. |
| return style?.copyWith( |
| color: CupertinoDynamicColor.maybeResolve(style.color, context), |
| backgroundColor: CupertinoDynamicColor.maybeResolve(style.backgroundColor, context), |
| decorationColor: CupertinoDynamicColor.maybeResolve(style.decorationColor, context), |
| ); |
| } |
| |
| /// Cupertino typography theme in a [CupertinoThemeData]. |
| @immutable |
| class CupertinoTextThemeData with Diagnosticable { |
| /// Create a [CupertinoTextThemeData]. |
| /// |
| /// The [primaryColor] is used to derive TextStyle defaults of other attributes |
| /// such as [navActionTextStyle] and [actionTextStyle]. It must not be null when |
| /// either [navActionTextStyle] or [actionTextStyle] is null. Defaults to |
| /// [CupertinoColors.systemBlue]. |
| /// |
| /// Other [TextStyle] parameters default to default iOS text styles when |
| /// unspecified. |
| const CupertinoTextThemeData({ |
| Color primaryColor = CupertinoColors.systemBlue, |
| TextStyle? textStyle, |
| TextStyle? actionTextStyle, |
| TextStyle? actionSmallTextStyle, |
| TextStyle? tabLabelTextStyle, |
| TextStyle? navTitleTextStyle, |
| TextStyle? navLargeTitleTextStyle, |
| TextStyle? navActionTextStyle, |
| TextStyle? pickerTextStyle, |
| TextStyle? dateTimePickerTextStyle, |
| }) : this._raw( |
| const _TextThemeDefaultsBuilder(CupertinoColors.label, CupertinoColors.inactiveGray), |
| primaryColor, |
| textStyle, |
| actionTextStyle, |
| actionSmallTextStyle, |
| tabLabelTextStyle, |
| navTitleTextStyle, |
| navLargeTitleTextStyle, |
| navActionTextStyle, |
| pickerTextStyle, |
| dateTimePickerTextStyle, |
| ); |
| |
| const CupertinoTextThemeData._raw( |
| this._defaults, |
| this._primaryColor, |
| this._textStyle, |
| this._actionTextStyle, |
| this._actionSmallTextStyle, |
| this._tabLabelTextStyle, |
| this._navTitleTextStyle, |
| this._navLargeTitleTextStyle, |
| this._navActionTextStyle, |
| this._pickerTextStyle, |
| this._dateTimePickerTextStyle, |
| ) : assert((_navActionTextStyle != null && _actionTextStyle != null) || _primaryColor != null); |
| |
| final _TextThemeDefaultsBuilder _defaults; |
| final Color? _primaryColor; |
| |
| final TextStyle? _textStyle; |
| |
| /// The [TextStyle] of general text content for Cupertino widgets. |
| TextStyle get textStyle => _textStyle ?? _defaults.textStyle; |
| |
| final TextStyle? _actionTextStyle; |
| |
| /// The [TextStyle] of interactive text content such as text in a button without background. |
| TextStyle get actionTextStyle { |
| return _actionTextStyle ?? _defaults.actionTextStyle(primaryColor: _primaryColor); |
| } |
| |
| final TextStyle? _actionSmallTextStyle; |
| |
| /// The [TextStyle] of interactive text content such as text in a small button. |
| TextStyle get actionSmallTextStyle { |
| return _actionSmallTextStyle ?? _defaults.actionSmallTextStyle(primaryColor: _primaryColor); |
| } |
| |
| final TextStyle? _tabLabelTextStyle; |
| |
| /// The [TextStyle] of unselected tabs. |
| TextStyle get tabLabelTextStyle => _tabLabelTextStyle ?? _defaults.tabLabelTextStyle; |
| |
| final TextStyle? _navTitleTextStyle; |
| |
| /// The [TextStyle] of titles in standard navigation bars. |
| TextStyle get navTitleTextStyle => _navTitleTextStyle ?? _defaults.navTitleTextStyle; |
| |
| final TextStyle? _navLargeTitleTextStyle; |
| |
| /// The [TextStyle] of large titles in sliver navigation bars. |
| TextStyle get navLargeTitleTextStyle => |
| _navLargeTitleTextStyle ?? _defaults.navLargeTitleTextStyle; |
| |
| final TextStyle? _navActionTextStyle; |
| |
| /// The [TextStyle] of interactive text content in navigation bars. |
| TextStyle get navActionTextStyle { |
| return _navActionTextStyle ?? _defaults.navActionTextStyle(primaryColor: _primaryColor); |
| } |
| |
| final TextStyle? _pickerTextStyle; |
| |
| /// The [TextStyle] of pickers. |
| TextStyle get pickerTextStyle => _pickerTextStyle ?? _defaults.pickerTextStyle; |
| |
| final TextStyle? _dateTimePickerTextStyle; |
| |
| /// The [TextStyle] of date time pickers. |
| TextStyle get dateTimePickerTextStyle => |
| _dateTimePickerTextStyle ?? _defaults.dateTimePickerTextStyle; |
| |
| /// Returns a copy of the current [CupertinoTextThemeData] with all the colors |
| /// resolved against the given [BuildContext]. |
| /// |
| /// If any of the [InheritedWidget]s required to resolve this |
| /// [CupertinoTextThemeData] is not found in [context], any unresolved |
| /// [CupertinoDynamicColor]s will use the default trait value |
| /// ([Brightness.light] platform brightness, normal contrast, |
| /// [CupertinoUserInterfaceLevelData.base] elevation level). |
| CupertinoTextThemeData resolveFrom(BuildContext context) { |
| return CupertinoTextThemeData._raw( |
| _defaults.resolveFrom(context), |
| CupertinoDynamicColor.maybeResolve(_primaryColor, context), |
| _resolveTextStyle(_textStyle, context), |
| _resolveTextStyle(_actionTextStyle, context), |
| _resolveTextStyle(_actionSmallTextStyle, context), |
| _resolveTextStyle(_tabLabelTextStyle, context), |
| _resolveTextStyle(_navTitleTextStyle, context), |
| _resolveTextStyle(_navLargeTitleTextStyle, context), |
| _resolveTextStyle(_navActionTextStyle, context), |
| _resolveTextStyle(_pickerTextStyle, context), |
| _resolveTextStyle(_dateTimePickerTextStyle, context), |
| ); |
| } |
| |
| /// Returns a copy of the current [CupertinoTextThemeData] instance with |
| /// specified overrides. |
| CupertinoTextThemeData copyWith({ |
| Color? primaryColor, |
| TextStyle? textStyle, |
| TextStyle? actionTextStyle, |
| TextStyle? actionSmallTextStyle, |
| TextStyle? tabLabelTextStyle, |
| TextStyle? navTitleTextStyle, |
| TextStyle? navLargeTitleTextStyle, |
| TextStyle? navActionTextStyle, |
| TextStyle? pickerTextStyle, |
| TextStyle? dateTimePickerTextStyle, |
| }) { |
| return CupertinoTextThemeData._raw( |
| _defaults, |
| primaryColor ?? _primaryColor, |
| textStyle ?? _textStyle, |
| actionTextStyle ?? _actionTextStyle, |
| actionSmallTextStyle ?? _actionSmallTextStyle, |
| tabLabelTextStyle ?? _tabLabelTextStyle, |
| navTitleTextStyle ?? _navTitleTextStyle, |
| navLargeTitleTextStyle ?? _navLargeTitleTextStyle, |
| navActionTextStyle ?? _navActionTextStyle, |
| pickerTextStyle ?? _pickerTextStyle, |
| dateTimePickerTextStyle ?? _dateTimePickerTextStyle, |
| ); |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| const defaultData = CupertinoTextThemeData(); |
| properties.add( |
| DiagnosticsProperty<TextStyle>('textStyle', textStyle, defaultValue: defaultData.textStyle), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'actionTextStyle', |
| actionTextStyle, |
| defaultValue: defaultData.actionTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'actionSmallTextStyle', |
| actionSmallTextStyle, |
| defaultValue: defaultData.actionSmallTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'tabLabelTextStyle', |
| tabLabelTextStyle, |
| defaultValue: defaultData.tabLabelTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'navTitleTextStyle', |
| navTitleTextStyle, |
| defaultValue: defaultData.navTitleTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'navLargeTitleTextStyle', |
| navLargeTitleTextStyle, |
| defaultValue: defaultData.navLargeTitleTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'navActionTextStyle', |
| navActionTextStyle, |
| defaultValue: defaultData.navActionTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'pickerTextStyle', |
| pickerTextStyle, |
| defaultValue: defaultData.pickerTextStyle, |
| ), |
| ); |
| properties.add( |
| DiagnosticsProperty<TextStyle>( |
| 'dateTimePickerTextStyle', |
| dateTimePickerTextStyle, |
| defaultValue: defaultData.dateTimePickerTextStyle, |
| ), |
| ); |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is CupertinoTextThemeData && |
| other._defaults == _defaults && |
| other._primaryColor == _primaryColor && |
| other._textStyle == _textStyle && |
| other._actionTextStyle == _actionTextStyle && |
| other._actionSmallTextStyle == _actionSmallTextStyle && |
| other._tabLabelTextStyle == _tabLabelTextStyle && |
| other._navTitleTextStyle == _navTitleTextStyle && |
| other._navLargeTitleTextStyle == _navLargeTitleTextStyle && |
| other._navActionTextStyle == _navActionTextStyle && |
| other._pickerTextStyle == _pickerTextStyle && |
| other._dateTimePickerTextStyle == _dateTimePickerTextStyle; |
| } |
| |
| @override |
| int get hashCode => Object.hash( |
| _defaults, |
| _primaryColor, |
| _textStyle, |
| _actionTextStyle, |
| _actionSmallTextStyle, |
| _tabLabelTextStyle, |
| _navTitleTextStyle, |
| _navLargeTitleTextStyle, |
| _navActionTextStyle, |
| _pickerTextStyle, |
| _dateTimePickerTextStyle, |
| ); |
| } |
| |
| @immutable |
| class _TextThemeDefaultsBuilder { |
| const _TextThemeDefaultsBuilder(this.labelColor, this.inactiveGrayColor); |
| |
| final Color labelColor; |
| final Color inactiveGrayColor; |
| |
| static TextStyle _applyLabelColor(TextStyle original, Color color) { |
| return original.color == color ? original : original.copyWith(color: color); |
| } |
| |
| TextStyle get textStyle => _applyLabelColor(_kDefaultTextStyle, labelColor); |
| TextStyle get tabLabelTextStyle => |
| _applyLabelColor(_kDefaultTabLabelTextStyle, inactiveGrayColor); |
| TextStyle get navTitleTextStyle => _applyLabelColor(_kDefaultMiddleTitleTextStyle, labelColor); |
| TextStyle get navLargeTitleTextStyle => |
| _applyLabelColor(_kDefaultLargeTitleTextStyle, labelColor); |
| TextStyle get pickerTextStyle => _applyLabelColor(_kDefaultPickerTextStyle, labelColor); |
| TextStyle get dateTimePickerTextStyle => |
| _applyLabelColor(_kDefaultDateTimePickerTextStyle, labelColor); |
| |
| TextStyle actionTextStyle({Color? primaryColor}) => |
| _kDefaultActionTextStyle.copyWith(color: primaryColor); |
| TextStyle actionSmallTextStyle({Color? primaryColor}) => |
| _kDefaultActionSmallTextStyle.copyWith(color: primaryColor); |
| TextStyle navActionTextStyle({Color? primaryColor}) => |
| actionTextStyle(primaryColor: primaryColor); |
| |
| _TextThemeDefaultsBuilder resolveFrom(BuildContext context) { |
| final Color resolvedLabelColor = CupertinoDynamicColor.resolve(labelColor, context); |
| final Color resolvedInactiveGray = CupertinoDynamicColor.resolve(inactiveGrayColor, context); |
| return resolvedLabelColor == labelColor && resolvedInactiveGray == CupertinoColors.inactiveGray |
| ? this |
| : _TextThemeDefaultsBuilder(resolvedLabelColor, resolvedInactiveGray); |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is _TextThemeDefaultsBuilder && |
| other.labelColor == labelColor && |
| other.inactiveGrayColor == inactiveGrayColor; |
| } |
| |
| @override |
| int get hashCode => Object.hash(labelColor, inactiveGrayColor); |
| } |