customtextbutton.dart 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. // Copyright 2014 The Flutter Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. import 'dart:math' as math;
  5. import 'dart:ui' show lerpDouble;
  6. import 'package:flutter/foundation.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:flyinsonolite/controls/custom/custombuttonstylebutton.dart';
  9. import 'package:flyinsonolite/infrastructure/scale.dart';
  10. /// A Material Design "Text Button".
  11. ///
  12. /// Use text buttons on toolbars, in dialogs, or inline with other
  13. /// content but offset from that content with padding so that the
  14. /// button's presence is obvious. Text buttons do not have visible
  15. /// borders and must therefore rely on their position relative to
  16. /// other content for context. In dialogs and cards, they should be
  17. /// grouped together in one of the bottom corners. Avoid using text
  18. /// buttons where they would blend in with other content, for example
  19. /// in the middle of lists.
  20. ///
  21. /// A text button is a label [child] displayed on a (zero elevation)
  22. /// [Material] widget. The label's [Text] and [Icon] widgets are
  23. /// displayed in the [style]'s [ButtonStyle.foregroundColor]. The
  24. /// button reacts to touches by filling with the [style]'s
  25. /// [ButtonStyle.backgroundColor].
  26. ///
  27. /// The text button's default style is defined by [defaultStyleOf].
  28. /// The style of this text button can be overridden with its [style]
  29. /// parameter. The style of all text buttons in a subtree can be
  30. /// overridden with the [TextButtonTheme] and the style of all of the
  31. /// text buttons in an app can be overridden with the [Theme]'s
  32. /// [ThemeData.textButtonTheme] property.
  33. ///
  34. /// The static [styleFrom] method is a convenient way to create a
  35. /// text button [ButtonStyle] from simple values.
  36. ///
  37. /// If the [onPressed] and [onLongPress] callbacks are null, then this
  38. /// button will be disabled, it will not react to touch.
  39. ///
  40. /// {@tool dartpad}
  41. /// This sample shows how to render a disabled TextButton, an enabled TextButton
  42. /// and lastly a TextButton with gradient background.
  43. ///
  44. /// ** See code in examples/api/lib/material/text_button/text_button.0.dart **
  45. /// {@end-tool}
  46. ///
  47. /// {@tool dartpad}
  48. /// This sample demonstrates using the [statesController] parameter to create a button
  49. /// that adds support for [MaterialState.selected].
  50. ///
  51. /// ** See code in examples/api/lib/material/text_button/text_button.1.dart **
  52. /// {@end-tool}
  53. ///
  54. /// See also:
  55. ///
  56. /// * [CustomElevatedButton], a filled button whose material elevates when pressed.
  57. /// * [FilledButton], a filled button that doesn't elevate when pressed.
  58. /// * [FilledButton.tonal], a filled button variant that uses a secondary fill color.
  59. /// * [OutlinedButton], a button with an outlined border and no fill color.
  60. /// * <https://material.io/design/components/buttons.html>
  61. /// * <https://m3.material.io/components/buttons>
  62. class CustomTextButton extends CustomButtonStyleButton {
  63. /// Create a TextButton.
  64. ///
  65. /// The [autofocus] and [clipBehavior] arguments must not be null.
  66. const CustomTextButton({
  67. super.key,
  68. required super.onPressed,
  69. super.onLongPress,
  70. super.onHover,
  71. super.onFocusChange,
  72. super.style,
  73. super.focusNode,
  74. super.autofocus = false,
  75. super.clipBehavior = Clip.none,
  76. super.statesController,
  77. required Widget super.child,
  78. });
  79. /// Create a text button from a pair of widgets that serve as the button's
  80. /// [icon] and [label].
  81. ///
  82. /// The icon and label are arranged in a row and padded by 8 logical pixels
  83. /// at the ends, with an 8 pixel gap in between.
  84. ///
  85. /// The [icon] and [label] arguments must not be null.
  86. factory CustomTextButton.icon({
  87. Key? key,
  88. required VoidCallback? onPressed,
  89. VoidCallback? onLongPress,
  90. ValueChanged<bool>? onHover,
  91. ValueChanged<bool>? onFocusChange,
  92. ButtonStyle? style,
  93. FocusNode? focusNode,
  94. bool? autofocus,
  95. Clip? clipBehavior,
  96. MaterialStatesController? statesController,
  97. required Widget icon,
  98. required Widget label,
  99. }) = _TextButtonWithIcon;
  100. /// A static convenience method that constructs a text button
  101. /// [ButtonStyle] given simple values.
  102. ///
  103. /// The [foregroundColor] and [disabledForegroundColor] colors are used
  104. /// to create a [MaterialStateProperty] [ButtonStyle.foregroundColor], and
  105. /// a derived [ButtonStyle.overlayColor].
  106. ///
  107. /// The [backgroundColor] and [disabledBackgroundColor] colors are
  108. /// used to create a [MaterialStateProperty] [ButtonStyle.backgroundColor].
  109. ///
  110. /// Similarly, the [enabledMouseCursor] and [disabledMouseCursor]
  111. /// parameters are used to construct [ButtonStyle.mouseCursor].
  112. ///
  113. /// All of the other parameters are either used directly or used to
  114. /// create a [MaterialStateProperty] with a single value for all
  115. /// states.
  116. ///
  117. /// All parameters default to null. By default this method returns
  118. /// a [ButtonStyle] that doesn't override anything.
  119. ///
  120. /// For example, to override the default text and icon colors for a
  121. /// [CustomTextButton], as well as its overlay color, with all of the
  122. /// standard opacity adjustments for the pressed, focused, and
  123. /// hovered states, one could write:
  124. ///
  125. /// ```dart
  126. /// TextButton(
  127. /// style: TextButton.styleFrom(foregroundColor: Colors.green),
  128. /// child: const Text('Give Kate a mix tape'),
  129. /// onPressed: () {
  130. /// // ...
  131. /// },
  132. /// ),
  133. /// ```
  134. static ButtonStyle styleFrom({
  135. Color? foregroundColor,
  136. Color? backgroundColor,
  137. Color? disabledForegroundColor,
  138. Color? disabledBackgroundColor,
  139. Color? shadowColor,
  140. Color? surfaceTintColor,
  141. double? elevation,
  142. TextStyle? textStyle,
  143. EdgeInsetsGeometry? padding,
  144. Size? minimumSize,
  145. Size? fixedSize,
  146. Size? maximumSize,
  147. BorderSide? side,
  148. OutlinedBorder? shape,
  149. MouseCursor? enabledMouseCursor,
  150. MouseCursor? disabledMouseCursor,
  151. VisualDensity? visualDensity,
  152. MaterialTapTargetSize? tapTargetSize,
  153. Duration? animationDuration,
  154. bool? enableFeedback,
  155. AlignmentGeometry? alignment,
  156. InteractiveInkFeatureFactory? splashFactory,
  157. @Deprecated('Use foregroundColor instead. '
  158. 'This feature was deprecated after v3.1.0.')
  159. Color? primary,
  160. @Deprecated('Use disabledForegroundColor instead. '
  161. 'This feature was deprecated after v3.1.0.')
  162. Color? onSurface,
  163. }) {
  164. final Color? foreground = foregroundColor ?? primary;
  165. final Color? disabledForeground =
  166. disabledForegroundColor ?? onSurface?.withOpacity(0.38);
  167. final MaterialStateProperty<Color?>? foregroundColorProp =
  168. (foreground == null && disabledForeground == null)
  169. ? null
  170. : _TextButtonDefaultColor(foreground, disabledForeground);
  171. final MaterialStateProperty<Color?>? backgroundColorProp =
  172. (backgroundColor == null && disabledBackgroundColor == null)
  173. ? null
  174. : disabledBackgroundColor == null
  175. ? CustomButtonStyleButton.allOrNull<Color?>(backgroundColor)
  176. : _TextButtonDefaultColor(
  177. backgroundColor, disabledBackgroundColor);
  178. final MaterialStateProperty<Color?>? overlayColor =
  179. (foreground == null) ? null : _TextButtonDefaultOverlay(foreground);
  180. final MaterialStateProperty<MouseCursor>? mouseCursor =
  181. (enabledMouseCursor == null && disabledMouseCursor == null)
  182. ? null
  183. : _TextButtonDefaultMouseCursor(
  184. enabledMouseCursor!, disabledMouseCursor!);
  185. return ButtonStyle(
  186. textStyle: CustomButtonStyleButton.allOrNull<TextStyle>(textStyle),
  187. foregroundColor: foregroundColorProp,
  188. backgroundColor: backgroundColorProp,
  189. overlayColor: overlayColor,
  190. shadowColor: CustomButtonStyleButton.allOrNull<Color>(shadowColor),
  191. surfaceTintColor:
  192. CustomButtonStyleButton.allOrNull<Color>(surfaceTintColor),
  193. elevation: CustomButtonStyleButton.allOrNull<double>(elevation),
  194. padding: CustomButtonStyleButton.allOrNull<EdgeInsetsGeometry>(padding),
  195. minimumSize: CustomButtonStyleButton.allOrNull<Size>(minimumSize),
  196. fixedSize: CustomButtonStyleButton.allOrNull<Size>(fixedSize),
  197. maximumSize: CustomButtonStyleButton.allOrNull<Size>(maximumSize),
  198. side: CustomButtonStyleButton.allOrNull<BorderSide>(side),
  199. shape: CustomButtonStyleButton.allOrNull<OutlinedBorder>(shape),
  200. mouseCursor: mouseCursor,
  201. visualDensity: visualDensity,
  202. tapTargetSize: tapTargetSize,
  203. animationDuration: animationDuration,
  204. enableFeedback: enableFeedback,
  205. alignment: alignment,
  206. splashFactory: splashFactory,
  207. );
  208. }
  209. /// Defines the button's default appearance.
  210. ///
  211. /// {@template flutter.material.text_button.default_style_of}
  212. /// The button [child]'s [Text] and [Icon] widgets are rendered with
  213. /// the [ButtonStyle]'s foreground color. The button's [InkWell] adds
  214. /// the style's overlay color when the button is focused, hovered
  215. /// or pressed. The button's background color becomes its [Material]
  216. /// color and is transparent by default.
  217. ///
  218. /// All of the [ButtonStyle]'s defaults appear below.
  219. ///
  220. /// In this list "Theme.foo" is shorthand for
  221. /// `Theme.of(context).foo`. Color scheme values like
  222. /// "onSurface(0.38)" are shorthand for
  223. /// `onSurface.withOpacity(0.38)`. [MaterialStateProperty] valued
  224. /// properties that are not followed by a sublist have the same
  225. /// value for all states, otherwise the values are as specified for
  226. /// each state and "others" means all other states.
  227. ///
  228. /// The `textScaleFactor` is the value of
  229. /// `MediaQuery.of(context).textScaleFactor` and the names of the
  230. /// EdgeInsets constructors and `EdgeInsetsGeometry.lerp` have been
  231. /// abbreviated for readability.
  232. ///
  233. /// The color of the [ButtonStyle.textStyle] is not used, the
  234. /// [ButtonStyle.foregroundColor] color is used instead.
  235. /// {@endtemplate}
  236. ///
  237. /// ## Material 2 defaults
  238. ///
  239. /// * `textStyle` - Theme.textTheme.button
  240. /// * `backgroundColor` - transparent
  241. /// * `foregroundColor`
  242. /// * disabled - Theme.colorScheme.onSurface(0.38)
  243. /// * others - Theme.colorScheme.primary
  244. /// * `overlayColor`
  245. /// * hovered - Theme.colorScheme.primary(0.04)
  246. /// * focused or pressed - Theme.colorScheme.primary(0.12)
  247. /// * `shadowColor` - Theme.shadowColor
  248. /// * `elevation` - 0
  249. /// * `padding`
  250. /// * `textScaleFactor <= 1` - all(8)
  251. /// * `1 < textScaleFactor <= 2` - lerp(all(8), horizontal(8))
  252. /// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
  253. /// * `3 < textScaleFactor` - horizontal(4)
  254. /// * `minimumSize` - Size(64, 36)
  255. /// * `fixedSize` - null
  256. /// * `maximumSize` - Size.infinite
  257. /// * `side` - null
  258. /// * `shape` - RoundedRectangleBorder(borderRadius: BorderRadius.circular(4))
  259. /// * `mouseCursor`
  260. /// * disabled - SystemMouseCursors.basic
  261. /// * others - SystemMouseCursors.click
  262. /// * `visualDensity` - theme.visualDensity
  263. /// * `tapTargetSize` - theme.materialTapTargetSize
  264. /// * `animationDuration` - kThemeChangeDuration
  265. /// * `enableFeedback` - true
  266. /// * `alignment` - Alignment.center
  267. /// * `splashFactory` - InkRipple.splashFactory
  268. ///
  269. /// The default padding values for the [TextButton.icon] factory are slightly different:
  270. ///
  271. /// * `padding`
  272. /// * `textScaleFactor <= 1` - all(8)
  273. /// * `1 < textScaleFactor <= 2 `- lerp(all(8), horizontal(4))
  274. /// * `2 < textScaleFactor` - horizontal(4)
  275. ///
  276. /// The default value for `side`, which defines the appearance of the button's
  277. /// outline, is null. That means that the outline is defined by the button
  278. /// shape's [OutlinedBorder.side]. Typically the default value of an
  279. /// [OutlinedBorder]'s side is [BorderSide.none], so an outline is not drawn.
  280. ///
  281. /// ## Material 3 defaults
  282. ///
  283. /// If [ThemeData.useMaterial3] is set to true the following defaults will
  284. /// be used:
  285. ///
  286. /// {@template flutter.material.text_button.material3_defaults}
  287. /// * `textStyle` - Theme.textTheme.labelLarge
  288. /// * `backgroundColor` - transparent
  289. /// * `foregroundColor`
  290. /// * disabled - Theme.colorScheme.onSurface(0.38)
  291. /// * others - Theme.colorScheme.primary
  292. /// * `overlayColor`
  293. /// * hovered - Theme.colorScheme.primary(0.08)
  294. /// * focused or pressed - Theme.colorScheme.primary(0.12)
  295. /// * others - null
  296. /// * `shadowColor` - null
  297. /// * `surfaceTintColor` - null
  298. /// * `elevation` - 0
  299. /// * `padding`
  300. /// * `textScaleFactor <= 1` - all(8)
  301. /// * `1 < textScaleFactor <= 2` - lerp(all(8), horizontal(8))
  302. /// * `2 < textScaleFactor <= 3` - lerp(horizontal(8), horizontal(4))
  303. /// * `3 < textScaleFactor` - horizontal(4)
  304. /// * `minimumSize` - Size(64, 40)
  305. /// * `fixedSize` - null
  306. /// * `maximumSize` - Size.infinite
  307. /// * `side` - null
  308. /// * `shape` - StadiumBorder()
  309. /// * `mouseCursor`
  310. /// * disabled - SystemMouseCursors.basic
  311. /// * others - SystemMouseCursors.click
  312. /// * `visualDensity` - theme.visualDensity
  313. /// * `tapTargetSize` - theme.materialTapTargetSize
  314. /// * `animationDuration` - kThemeChangeDuration
  315. /// * `enableFeedback` - true
  316. /// * `alignment` - Alignment.center
  317. /// * `splashFactory` - Theme.splashFactory
  318. /// {@endtemplate}
  319. @override
  320. ButtonStyle defaultStyleOf(BuildContext context) {
  321. final ThemeData theme = Theme.of(context);
  322. final ColorScheme colorScheme = theme.colorScheme;
  323. return Theme.of(context).useMaterial3
  324. ? _TextButtonDefaultsM3(context)
  325. : styleFrom(
  326. foregroundColor: colorScheme.primary,
  327. disabledForegroundColor: colorScheme.onSurface.withOpacity(0.38),
  328. backgroundColor: Colors.transparent,
  329. disabledBackgroundColor: Colors.transparent,
  330. shadowColor: theme.shadowColor,
  331. elevation: 0,
  332. textStyle: theme.textTheme.labelLarge,
  333. padding: _scaledPadding(context),
  334. minimumSize: Size(64.s, 36.s),
  335. maximumSize: Size.infinite,
  336. shape: RoundedRectangleBorder(
  337. borderRadius: BorderRadius.all(Radius.circular(4.s))),
  338. enabledMouseCursor: SystemMouseCursors.click,
  339. disabledMouseCursor: SystemMouseCursors.basic,
  340. visualDensity: theme.visualDensity,
  341. tapTargetSize: theme.materialTapTargetSize,
  342. animationDuration: kThemeChangeDuration,
  343. enableFeedback: true,
  344. alignment: Alignment.center,
  345. splashFactory: InkRipple.splashFactory,
  346. );
  347. }
  348. /// Returns the [TextButtonThemeData.style] of the closest
  349. /// [TextButtonTheme] ancestor.
  350. @override
  351. ButtonStyle? themeStyleOf(BuildContext context) {
  352. return TextButtonTheme.of(context).style;
  353. }
  354. }
  355. EdgeInsetsGeometry _scaledPadding(BuildContext context) {
  356. return CustomButtonStyleButton.scaledPadding(
  357. EdgeInsets.all(8.s),
  358. EdgeInsets.symmetric(horizontal: 8.s),
  359. EdgeInsets.symmetric(horizontal: 4.s),
  360. MediaQuery.maybeOf(context)?.textScaleFactor ?? 1,
  361. );
  362. }
  363. @immutable
  364. class _TextButtonDefaultColor extends MaterialStateProperty<Color?> {
  365. _TextButtonDefaultColor(this.color, this.disabled);
  366. final Color? color;
  367. final Color? disabled;
  368. @override
  369. Color? resolve(Set<MaterialState> states) {
  370. if (states.contains(MaterialState.disabled)) {
  371. return disabled;
  372. }
  373. return color;
  374. }
  375. @override
  376. String toString() {
  377. return '{disabled: $disabled, otherwise: $color}';
  378. }
  379. }
  380. @immutable
  381. class _TextButtonDefaultOverlay extends MaterialStateProperty<Color?> {
  382. _TextButtonDefaultOverlay(this.primary);
  383. final Color primary;
  384. @override
  385. Color? resolve(Set<MaterialState> states) {
  386. if (states.contains(MaterialState.hovered)) {
  387. return primary.withOpacity(0.04);
  388. }
  389. if (states.contains(MaterialState.focused) ||
  390. states.contains(MaterialState.pressed)) {
  391. return primary.withOpacity(0.12);
  392. }
  393. return null;
  394. }
  395. @override
  396. String toString() {
  397. return '{hovered: ${primary.withOpacity(0.04)}, focused,pressed: ${primary.withOpacity(0.12)}, otherwise: null}';
  398. }
  399. }
  400. @immutable
  401. class _TextButtonDefaultMouseCursor extends MaterialStateProperty<MouseCursor>
  402. with Diagnosticable {
  403. _TextButtonDefaultMouseCursor(this.enabledCursor, this.disabledCursor);
  404. final MouseCursor enabledCursor;
  405. final MouseCursor disabledCursor;
  406. @override
  407. MouseCursor resolve(Set<MaterialState> states) {
  408. if (states.contains(MaterialState.disabled)) {
  409. return disabledCursor;
  410. }
  411. return enabledCursor;
  412. }
  413. }
  414. class _TextButtonWithIcon extends CustomTextButton {
  415. _TextButtonWithIcon({
  416. super.key,
  417. required super.onPressed,
  418. super.onLongPress,
  419. super.onHover,
  420. super.onFocusChange,
  421. super.style,
  422. super.focusNode,
  423. bool? autofocus,
  424. Clip? clipBehavior,
  425. super.statesController,
  426. required Widget icon,
  427. required Widget label,
  428. }) : assert(icon != null),
  429. assert(label != null),
  430. super(
  431. autofocus: autofocus ?? false,
  432. clipBehavior: clipBehavior ?? Clip.none,
  433. child: _TextButtonWithIconChild(icon: icon, label: label),
  434. );
  435. @override
  436. ButtonStyle defaultStyleOf(BuildContext context) {
  437. final EdgeInsetsGeometry scaledPadding =
  438. CustomButtonStyleButton.scaledPadding(
  439. EdgeInsets.all(8.s),
  440. EdgeInsets.symmetric(horizontal: 4.s),
  441. EdgeInsets.symmetric(horizontal: 4.s),
  442. MediaQuery.maybeOf(context)?.textScaleFactor ?? 1,
  443. );
  444. return super.defaultStyleOf(context).copyWith(
  445. padding: MaterialStatePropertyAll<EdgeInsetsGeometry>(scaledPadding),
  446. );
  447. }
  448. }
  449. class _TextButtonWithIconChild extends StatelessWidget {
  450. const _TextButtonWithIconChild({
  451. required this.label,
  452. required this.icon,
  453. });
  454. final Widget label;
  455. final Widget icon;
  456. @override
  457. Widget build(BuildContext context) {
  458. final double scale = MediaQuery.maybeOf(context)?.textScaleFactor ?? 1;
  459. final double gap =
  460. scale <= 1 ? 8 : lerpDouble(8, 4, math.min(scale - 1, 1))!;
  461. return Row(
  462. mainAxisSize: MainAxisSize.min,
  463. children: <Widget>[icon, SizedBox(width: gap), Flexible(child: label)],
  464. );
  465. }
  466. }
  467. // BEGIN GENERATED TOKEN PROPERTIES - TextButton
  468. // Do not edit by hand. The code between the "BEGIN GENERATED" and
  469. // "END GENERATED" comments are generated from data in the Material
  470. // Design token database by the script:
  471. // dev/tools/gen_defaults/bin/gen_defaults.dart.
  472. // Token database version: v0_132
  473. class _TextButtonDefaultsM3 extends ButtonStyle {
  474. _TextButtonDefaultsM3(this.context)
  475. : super(
  476. animationDuration: kThemeChangeDuration,
  477. enableFeedback: true,
  478. alignment: Alignment.center,
  479. );
  480. final BuildContext context;
  481. late final ColorScheme _colors = Theme.of(context).colorScheme;
  482. @override
  483. MaterialStateProperty<TextStyle?> get textStyle =>
  484. MaterialStatePropertyAll<TextStyle?>(
  485. Theme.of(context).textTheme.labelLarge);
  486. @override
  487. MaterialStateProperty<Color?>? get backgroundColor =>
  488. const MaterialStatePropertyAll<Color>(Colors.transparent);
  489. @override
  490. MaterialStateProperty<Color?>? get foregroundColor =>
  491. MaterialStateProperty.resolveWith((Set<MaterialState> states) {
  492. if (states.contains(MaterialState.disabled)) {
  493. return _colors.onSurface.withOpacity(0.38);
  494. }
  495. return _colors.primary;
  496. });
  497. @override
  498. MaterialStateProperty<Color?>? get overlayColor =>
  499. MaterialStateProperty.resolveWith((Set<MaterialState> states) {
  500. if (states.contains(MaterialState.hovered)) {
  501. return _colors.primary.withOpacity(0.08);
  502. }
  503. if (states.contains(MaterialState.focused)) {
  504. return _colors.primary.withOpacity(0.12);
  505. }
  506. if (states.contains(MaterialState.pressed)) {
  507. return _colors.primary.withOpacity(0.12);
  508. }
  509. return null;
  510. });
  511. @override
  512. MaterialStateProperty<Color>? get shadowColor =>
  513. const MaterialStatePropertyAll<Color>(Colors.transparent);
  514. @override
  515. MaterialStateProperty<Color>? get surfaceTintColor =>
  516. const MaterialStatePropertyAll<Color>(Colors.transparent);
  517. @override
  518. MaterialStateProperty<double>? get elevation =>
  519. const MaterialStatePropertyAll<double>(0.0);
  520. @override
  521. MaterialStateProperty<EdgeInsetsGeometry>? get padding =>
  522. MaterialStatePropertyAll<EdgeInsetsGeometry>(_scaledPadding(context));
  523. @override
  524. MaterialStateProperty<Size>? get minimumSize =>
  525. MaterialStatePropertyAll<Size>(Size(64.s, 40.s));
  526. // No default fixedSize
  527. @override
  528. MaterialStateProperty<Size>? get maximumSize =>
  529. const MaterialStatePropertyAll<Size>(Size.infinite);
  530. // No default side
  531. @override
  532. MaterialStateProperty<OutlinedBorder>? get shape =>
  533. const MaterialStatePropertyAll<OutlinedBorder>(StadiumBorder());
  534. @override
  535. MaterialStateProperty<MouseCursor?>? get mouseCursor =>
  536. MaterialStateProperty.resolveWith((Set<MaterialState> states) {
  537. if (states.contains(MaterialState.disabled)) {
  538. return SystemMouseCursors.basic;
  539. }
  540. return SystemMouseCursors.click;
  541. });
  542. @override
  543. VisualDensity? get visualDensity => Theme.of(context).visualDensity;
  544. @override
  545. MaterialTapTargetSize? get tapTargetSize =>
  546. Theme.of(context).materialTapTargetSize;
  547. @override
  548. InteractiveInkFeatureFactory? get splashFactory =>
  549. Theme.of(context).splashFactory;
  550. }
  551. // END GENERATED TOKEN PROPERTIES - TextButton