Repository: macosui/macos_ui

Issue:
Support `ControlSize` in `PushButton`




Fix patch:
diff --git a/.github/workflows/dart_code_metrics.yaml b/.github/workflows/dart_code_metrics.yaml
index 16194aed..1dd9587a 100644
--- a/.github/workflows/dart_code_metrics.yaml
+++ b/.github/workflows/dart_code_metrics.yaml
@@ -9,10 +9,14 @@ jobs:
       - uses: actions/checkout@v3
 
       - name: Run Dart Code Metrics
-        uses: dart-code-checker/dart-code-metrics-action@v4.0.0
+        uses: subosito/flutter-action@v2
+        with:
+          channel: stable
+
+      - name: Install dependencies
+        run: flutter pub get
+      - uses: CQLabs/setup-dcm@v1.0.0
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
-          pull_request_comment: true
-          fatal_warnings: true
-          fatal_performance: true
-          fatal_style: true
+
+      - run: dcm analyze --ci-key="${{ secrets.DCM_CI_KEY }}" --email="${{ secrets.DCM_EMAIL }}" lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 627308cb..919e1927 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## [2.0.0-beta.5]
+🚨 Breaking Changes 🚨
+* `PushButton` has been updated to support the `ControlSize` enum.
+  * The `buttonSize` property has been changed to `controlSize`.
+  * Buttons can now be any of the following sizes: mini, small, regular, or large.
+* `PushButton.isSecondary` is now `PushButton.secondary`. 
+
+🔄 Updated 🔄
+* `PushButton`'s secondary and disabled colors more closely match their native counterparts. 
+
 ## [2.0.0-beta.4]
 🛠️ Fixed 🛠️
 * `ToolBar`s in use where a `SideBar` is not present will now have their title's avoid the traffic lights (native window controls).
diff --git a/README.md b/README.md
index 19a5ea75..cf586f34 100644
--- a/README.md
+++ b/README.md
@@ -632,23 +632,22 @@ MacosPopupButton<String>(
 
 ## PushButton
 
-A push button appears within a view and initiates an instantaneous app-specific action, such as printing a document or 
-deleting a file. Push buttons contain text—not icons—and often open a separate window, dialog, or app so the user can 
+Push buttons are the standard button type in macOS. Push buttons contain text—not icons—and often open a separate window, dialog, or app so the user can 
 complete a task. [Learn more](https://developer.apple.com/design/human-interface-guidelines/macos/buttons/push-buttons/)
 
 | Dark Theme                                 | Light Theme                                |
-| ------------------------------------------ | ------------------------------------------ |
-| <img src="https://imgur.com/GsShoF6.jpg"/> | <img src="https://imgur.com/klWHTAX.jpg"/> |
-| <img src="https://imgur.com/v99ekWA.jpg"/> | <img src="https://imgur.com/hj6uGhI.jpg"/> |
-| <img src="https://imgur.com/wt0K6u4.jpg"/> | <img src="https://imgur.com/7khWnwt.jpg"/> |
-| <img src="https://imgur.com/TgfjJdQ.jpg"/> | <img src="https://imgur.com/83cEMeP.jpg"/> |
+|--------------------------------------------|--------------------------------------------|
+| <img src="https://imgur.com/iWNuPqs.png"/> | <img src="https://imgur.com/QPIHrJt.png"/> |
+
+ℹ️ **Note** ℹ️
+Native push buttons can be styled as text-only, text with an icon, or icon-only. Currently, text-only push buttons are supported. To create an icon-only button, use the `MacosIconButton` widget.
 
 Here's an example of how to create a basic push button:
 
 ```dart
 PushButton(
   child: Text('button'),
-  buttonSize: ButtonSize.large,
+  controlSize: ControlSize.regular,
   onPressed: () {
     print('button pressed');
   },
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 74448811..7ed9076e 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -5,8 +5,6 @@ linter:
     - use_super_parameters
 
 analyzer:
-  plugins:
-    - dart_code_metrics
   exclude:
     - test/mock_canvas.dart
     - test/recording_canvas.dart
diff --git a/example/lib/pages/buttons_page.dart b/example/lib/pages/buttons_page.dart
index befbaef1..3bf5fe5d 100644
--- a/example/lib/pages/buttons_page.dart
+++ b/example/lib/pages/buttons_page.dart
@@ -146,71 +146,410 @@ class _ButtonsPageState extends State<ButtonsPage> {
                           ],
                         ),
                         const SizedBox(height: 20),
-                        const Text('PushButton'),
+                        const Text('Primary PushButton'),
                         const SizedBox(height: 8),
-                        Row(
-                          mainAxisAlignment: MainAxisAlignment.center,
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
                           children: [
-                            PushButton(
-                              buttonSize: ButtonSize.large,
-                              child: const Text('Large'),
-                              onPressed: () {
-                                MacosWindowScope.of(context).toggleSidebar();
-                              },
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.center,
+                              children: [
+                                PushButton(
+                                  controlSize: ControlSize.mini,
+                                  child: const Text('Mini'),
+                                  onPressed: () {
+                                    MacosWindowScope.of(context)
+                                        .toggleSidebar();
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.small,
+                                  child: const Text('Small'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                          ControlSize.regular,
+                                                      child:
+                                                          const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                    ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                        Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.regular,
+                                  child: const Text('Regular'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                      ControlSize.regular,
+                                                      child:
+                                                      const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                    Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.large,
+                                  child: const Text('Large'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                      ControlSize.regular,
+                                                      child:
+                                                      const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                    Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                              ],
                             ),
-                            const SizedBox(width: 20),
-                            PushButton(
-                              buttonSize: ButtonSize.small,
-                              child: const Text('Small'),
-                              onPressed: () {
-                                Navigator.of(context).push(
-                                  MaterialPageRoute(
-                                    builder: (_) {
-                                      return MacosScaffold(
-                                        toolBar: const ToolBar(
-                                          title: Text('New page'),
-                                        ),
-                                        children: [
-                                          ContentArea(
-                                            builder: (context, _) {
-                                              return Center(
-                                                child: PushButton(
-                                                  buttonSize: ButtonSize.large,
-                                                  child: const Text('Go Back'),
-                                                  onPressed: () {
-                                                    Navigator.of(context)
-                                                        .maybePop();
-                                                  },
-                                                ),
-                                              );
-                                            },
-                                          ),
-                                          ResizablePane(
-                                            minSize: 180,
-                                            startSize: 200,
-                                            windowBreakpoint: 700,
-                                            resizableSide: ResizableSide.left,
-                                            builder: (_, __) {
-                                              return const Center(
-                                                child: Text('Resizable Pane'),
-                                              );
-                                            },
-                                          ),
-                                        ],
-                                      );
-                                    },
-                                  ),
-                                );
-                              },
+                          ],
+                        ),
+                        const SizedBox(height: 8),
+                        const Text('Secondary PushButton'),
+                        const SizedBox(height: 8),
+                        Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.center,
+                              children: [
+                                PushButton(
+                                  controlSize: ControlSize.mini,
+                                  secondary: true,
+                                  child: const Text('Mini'),
+                                  onPressed: () {
+                                    MacosWindowScope.of(context)
+                                        .toggleSidebar();
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.small,
+                                  secondary: true,
+                                  child: const Text('Small'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                      ControlSize.regular,
+                                                      child:
+                                                      const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                    Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.regular,
+                                  secondary: true,
+                                  child: const Text('Regular'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                      ControlSize.regular,
+                                                      child:
+                                                      const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                    Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                                const SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.large,
+                                  secondary: true,
+                                  child: const Text('Large'),
+                                  onPressed: () {
+                                    Navigator.of(context).push(
+                                      MaterialPageRoute(
+                                        builder: (_) {
+                                          return MacosScaffold(
+                                            toolBar: const ToolBar(
+                                              title: Text('New page'),
+                                            ),
+                                            children: [
+                                              ContentArea(
+                                                builder: (context, _) {
+                                                  return Center(
+                                                    child: PushButton(
+                                                      controlSize:
+                                                      ControlSize.regular,
+                                                      child:
+                                                      const Text('Go Back'),
+                                                      onPressed: () {
+                                                        Navigator.of(context)
+                                                            .maybePop();
+                                                      },
+                                                    ),
+                                                  );
+                                                },
+                                              ),
+                                              ResizablePane(
+                                                minSize: 180,
+                                                startSize: 200,
+                                                windowBreakpoint: 700,
+                                                resizableSide:
+                                                ResizableSide.left,
+                                                builder: (_, __) {
+                                                  return const Center(
+                                                    child:
+                                                    Text('Resizable Pane'),
+                                                  );
+                                                },
+                                              ),
+                                            ],
+                                          );
+                                        },
+                                      ),
+                                    );
+                                  },
+                                ),
+                              ],
                             ),
-                            const SizedBox(width: 20),
-                            PushButton(
-                              buttonSize: ButtonSize.large,
-                              isSecondary: true,
-                              child: const Text('Secondary'),
-                              onPressed: () {
-                                MacosWindowScope.of(context).toggleSidebar();
-                              },
+                          ],
+                        ),
+                        const SizedBox(height: 8),
+                        const Text('Disabled Primary PushButton'),
+                        const SizedBox(height: 8),
+                        const Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.center,
+                              children: [
+                                PushButton(
+                                  controlSize: ControlSize.mini,
+                                  child: Text('Mini'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.small,
+                                  child: Text('Small'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.regular,
+                                  child: Text('Regular'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.large,
+                                  child: Text('Large'),
+                                ),
+                              ],
+                            ),
+                          ],
+                        ),
+                        const SizedBox(height: 8),
+                        const Text('Disabled Secondary PushButton'),
+                        const SizedBox(height: 8),
+                        const Column(
+                          mainAxisSize: MainAxisSize.min,
+                          children: [
+                            Row(
+                              mainAxisAlignment: MainAxisAlignment.center,
+                              children: [
+                                PushButton(
+                                  controlSize: ControlSize.mini,
+                                  secondary: true,
+                                  child: Text('Mini'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.small,
+                                  secondary: true,
+                                  child: Text('Small'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.regular,
+                                  secondary: true,
+                                  child: Text('Regular'),
+                                ),
+                                SizedBox(width: 8),
+                                PushButton(
+                                  controlSize: ControlSize.large,
+                                  secondary: true,
+                                  child: Text('Large'),
+                                ),
+                              ],
                             ),
                           ],
                         ),
diff --git a/example/lib/pages/dialogs_page.dart b/example/lib/pages/dialogs_page.dart
index b7645978..9046b61c 100644
--- a/example/lib/pages/dialogs_page.dart
+++ b/example/lib/pages/dialogs_page.dart
@@ -36,7 +36,7 @@ class _DialogsPageState extends State<DialogsPage> {
                 child: Column(
                   children: [
                     PushButton(
-                      buttonSize: ButtonSize.large,
+                      controlSize: ControlSize.regular,
                       child: const Text('Show Alert Dialog 1'),
                       onPressed: () => showMacosAlertDialog(
                         context: context,
@@ -52,7 +52,7 @@ class _DialogsPageState extends State<DialogsPage> {
                           ),
                           //horizontalActions: false,
                           primaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
+                            controlSize: ControlSize.regular,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Primary'),
                           ),
@@ -61,7 +61,7 @@ class _DialogsPageState extends State<DialogsPage> {
                     ),
                     const SizedBox(height: 16),
                     PushButton(
-                      buttonSize: ButtonSize.large,
+                      controlSize: ControlSize.regular,
                       child: const Text('Show Alert Dialog 2'),
                       onPressed: () => showMacosAlertDialog(
                         context: context,
@@ -78,13 +78,13 @@ class _DialogsPageState extends State<DialogsPage> {
                           ),
                           //horizontalActions: false,
                           primaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
+                            controlSize: ControlSize.regular,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Primary'),
                           ),
                           secondaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
-                            isSecondary: true,
+                            controlSize: ControlSize.regular,
+                            secondary: true,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Secondary'),
                           ),
@@ -93,7 +93,7 @@ class _DialogsPageState extends State<DialogsPage> {
                     ),
                     const SizedBox(height: 16),
                     PushButton(
-                      buttonSize: ButtonSize.large,
+                      controlSize: ControlSize.regular,
                       child: const Text('Show Alert Dialog 3'),
                       onPressed: () => showMacosAlertDialog(
                         context: context,
@@ -110,13 +110,13 @@ class _DialogsPageState extends State<DialogsPage> {
                           ),
                           horizontalActions: false,
                           primaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
+                            controlSize: ControlSize.regular,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Primary'),
                           ),
                           secondaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
-                            isSecondary: true,
+                            controlSize: ControlSize.regular,
+                            secondary: true,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Secondary'),
                           ),
@@ -125,7 +125,7 @@ class _DialogsPageState extends State<DialogsPage> {
                     ),
                     const SizedBox(height: 16),
                     PushButton(
-                      buttonSize: ButtonSize.large,
+                      controlSize: ControlSize.regular,
                       child: const Text('Show Alert Dialog 4'),
                       onPressed: () => showMacosAlertDialog(
                         context: context,
@@ -143,13 +143,13 @@ class _DialogsPageState extends State<DialogsPage> {
                           ),
                           horizontalActions: false,
                           primaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
+                            controlSize: ControlSize.regular,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Primary'),
                           ),
                           secondaryButton: PushButton(
-                            buttonSize: ButtonSize.large,
-                            isSecondary: true,
+                            controlSize: ControlSize.regular,
+                            secondary: true,
                             onPressed: Navigator.of(context).pop,
                             child: const Text('Secondary'),
                           ),
@@ -159,7 +159,7 @@ class _DialogsPageState extends State<DialogsPage> {
                     ),
                     const SizedBox(height: 16),
                     PushButton(
-                      buttonSize: ButtonSize.large,
+                      controlSize: ControlSize.regular,
                       child: const Text('Show sheet'),
                       onPressed: () {
                         showMacosSheet(
@@ -249,7 +249,7 @@ class DemoSheet extends StatelessWidget {
             ),
             const Spacer(),
             PushButton(
-              buttonSize: ButtonSize.large,
+              controlSize: ControlSize.regular,
               child: const Text('Get started'),
               onPressed: () => Navigator.of(context).pop(),
             ),
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 727c8aac..44b2f9a3 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -97,7 +97,7 @@ packages:
       path: ".."
       relative: true
     source: path
-    version: "2.0.0-beta.4"
+    version: "2.0.0-beta.5"
   macos_window_utils:
     dependency: transitive
     description:
diff --git a/lib/src/buttons/push_button.dart b/lib/src/buttons/push_button.dart
index 6f759c1d..4fa2258a 100644
--- a/lib/src/buttons/push_button.dart
+++ b/lib/src/buttons/push_button.dart
@@ -5,36 +5,120 @@ import 'package:flutter/rendering.dart';
 import 'package:macos_ui/macos_ui.dart';
 import 'package:macos_ui/src/library.dart';
 
-/// The sizes a [PushButton] can be.
-enum ButtonSize {
-  /// A large [PushButton].
-  large,
-
-  /// A small [PushButton].
-  small,
-}
-
-const EdgeInsetsGeometry _kSmallButtonPadding = EdgeInsets.symmetric(
-  vertical: 3.0,
-  horizontal: 8.0,
+const _kMiniButtonSize = Size(26.0, 11.0);
+const _kSmallButtonSize = Size(39.0, 14.0);
+const _kRegularButtonSize = Size(60.0, 18.0);
+const _kLargeButtonSize = Size(48.0, 26.0);
+
+const _kMiniButtonPadding = EdgeInsets.only(left: 6.0, right: 6.0, bottom: 1.0);
+const _kSmallButtonPadding = EdgeInsets.symmetric(
+  vertical: 1.0,
+  horizontal: 7.0,
 );
-const EdgeInsetsGeometry _kLargeButtonPadding = EdgeInsets.symmetric(
-  vertical: 6.0,
-  horizontal: 8.0,
+const _kRegularButtonPadding = EdgeInsets.only(
+  left: 8.0,
+  right: 8.0,
+  top: 1.0,
+  bottom: 4.0,
 );
+const _kLargeButtonPadding = EdgeInsets.only(
+  right: 8.0,
+  left: 8.0,
+  bottom: 1.0,
+);
+
+const _kMiniButtonRadius = BorderRadius.all(Radius.circular(2.0));
+const _kSmallButtonRadius = BorderRadius.all(Radius.circular(2.0));
+const _kRegularButtonRadius = BorderRadius.all(Radius.circular(5.0));
+const _kLargeButtonRadius = BorderRadius.all(Radius.circular(7.0));
+
+/// Shortcuts for various [PushButton] properties based on the [ControlSize].
+extension PushButtonControlSizeX on ControlSize {
+  /// Determines the padding of the button's text.
+  EdgeInsetsGeometry get padding {
+    switch (this) {
+      case ControlSize.mini:
+        return _kMiniButtonPadding;
+      case ControlSize.small:
+        return _kSmallButtonPadding;
+      case ControlSize.regular:
+        return _kRegularButtonPadding;
+      case ControlSize.large:
+        return _kLargeButtonPadding;
+    }
+  }
+
+  /// Determines the button's border radius.
+  BorderRadiusGeometry get borderRadius {
+    switch (this) {
+      case ControlSize.mini:
+        return _kMiniButtonRadius;
+      case ControlSize.small:
+        return _kSmallButtonRadius;
+      case ControlSize.regular:
+        return _kRegularButtonRadius;
+      case ControlSize.large:
+        return _kLargeButtonRadius;
+    }
+  }
+
+  /// Determines the styling of the button's text.
+  TextStyle textStyle(TextStyle baseStyle) {
+    switch (this) {
+      case ControlSize.mini:
+        return baseStyle.copyWith(fontSize: 9.0);
+      case ControlSize.small:
+        return baseStyle.copyWith(fontSize: 11.0);
+      case ControlSize.regular:
+        return baseStyle.copyWith(fontSize: 13.0);
+      case ControlSize.large:
+        return baseStyle;
+    }
+  }
 
-const BorderRadius _kSmallButtonRadius = BorderRadius.all(Radius.circular(5.0));
-const BorderRadius _kLargeButtonRadius = BorderRadius.all(Radius.circular(7.0));
+  /// Determines the button's minimum size.
+  BoxConstraints get constraints {
+    switch (this) {
+      case ControlSize.mini:
+        return BoxConstraints(
+          minHeight: _kMiniButtonSize.height,
+          minWidth: _kMiniButtonSize.width,
+        );
+      case ControlSize.small:
+        return BoxConstraints(
+          minHeight: _kSmallButtonSize.height,
+          minWidth: _kSmallButtonSize.width,
+        );
+      case ControlSize.regular:
+        return BoxConstraints(
+          minHeight: _kRegularButtonSize.height,
+          minWidth: _kRegularButtonSize.width,
+        );
+      case ControlSize.large:
+        return BoxConstraints(
+          minHeight: _kLargeButtonSize.height,
+          minWidth: _kLargeButtonSize.width,
+        );
+    }
+  }
+}
 
 /// {@template pushButton}
-/// A macOS-style button.
+/// A control that initiates an action.
+///
+/// Push Buttons are the standard button type in macOS.
+///
+/// Reference:
+/// * [Button (SwiftUI)](https://developer.apple.com/documentation/SwiftUI/Button)
+/// * [NSButton (AppKit)](https://developer.apple.com/documentation/appkit/nsbutton)
+/// * [Buttons (Human Interface Guidelines)](https://developer.apple.com/design/human-interface-guidelines/buttons)
 /// {@endtemplate}
 class PushButton extends StatefulWidget {
   /// {@macro pushButton}
   const PushButton({
     super.key,
     required this.child,
-    required this.buttonSize,
+    required this.controlSize,
     this.padding,
     this.color,
     this.disabledColor,
@@ -44,7 +128,7 @@ class PushButton extends StatefulWidget {
     this.alignment = Alignment.center,
     this.semanticLabel,
     this.mouseCursor = SystemMouseCursors.basic,
-    this.isSecondary,
+    this.secondary,
   }) : assert(pressedOpacity == null ||
             (pressedOpacity >= 0.0 && pressedOpacity <= 1.0));
 
@@ -55,12 +139,8 @@ class PushButton extends StatefulWidget {
 
   /// The size of the button.
   ///
-  /// Must be either [ButtonSize.small] or [ButtonSize.large].
   ///
-  /// Small buttons have a `padding` of [_kSmallButtonPadding] and a
-  /// `borderRadius` of [_kSmallButtonRadius]. Large buttons have a `padding`
-  /// of [_kLargeButtonPadding] and a `borderRadius` of [_kLargeButtonRadius].
-  final ButtonSize buttonSize;
+  final ControlSize controlSize;
 
   /// The amount of space to surround the child inside the bounds of the button.
   ///
@@ -116,8 +196,8 @@ class PushButton extends StatefulWidget {
   /// Whether the button is used as a secondary action button (e.g. Cancel buttons in dialogs)
   ///
   /// Sets its background color to [PushButtonThemeData]'s [secondaryColor] attributes (defaults
-  /// are gray colors). Can still be overriden if the [color] attribute is non-null.
-  final bool? isSecondary;
+  /// are gray colors). Can still be overridden if the [color] attribute is non-null.
+  final bool? secondary;
 
   /// Whether the button is enabled or disabled. Buttons are disabled by default. To
   /// enable a button, set its [onPressed] property to a non-null value.
@@ -126,7 +206,7 @@ class PushButton extends StatefulWidget {
   @override
   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
     super.debugFillProperties(properties);
-    properties.add(EnumProperty<ButtonSize>('buttonSize', buttonSize));
+    properties.add(EnumProperty<ControlSize>('controlSize', controlSize));
     properties.add(ColorProperty('color', color));
     properties.add(ColorProperty('disabledColor', disabledColor));
     properties.add(DoubleProperty('pressedOpacity', pressedOpacity));
@@ -138,7 +218,7 @@ class PushButton extends StatefulWidget {
       value: enabled,
       ifFalse: 'disabled',
     ));
-    properties.add(DiagnosticsProperty('isSecondary', isSecondary));
+    properties.add(DiagnosticsProperty('secondary', secondary));
   }
 
   @override
@@ -224,7 +304,7 @@ class PushButtonState extends State<PushButton>
   Widget build(BuildContext context) {
     assert(debugCheckHasMacosTheme(context));
     final bool enabled = widget.enabled;
-    final bool isSecondary = widget.isSecondary != null && widget.isSecondary!;
+    final bool isSecondary = widget.secondary != null && widget.secondary!;
     final MacosThemeData theme = MacosTheme.of(context);
     final Color backgroundColor = MacosDynamicColor.resolve(
       widget.color ??
@@ -234,22 +314,9 @@ class PushButtonState extends State<PushButton>
       context,
     );
 
-    final Color disabledColor = MacosDynamicColor.resolve(
-      widget.disabledColor ?? theme.pushButtonTheme.disabledColor!,
-      context,
-    );
-
-    final EdgeInsetsGeometry? buttonPadding = widget.padding == null
-        ? widget.buttonSize == ButtonSize.small
-            ? _kSmallButtonPadding
-            : _kLargeButtonPadding
-        : widget.padding;
-
-    final BorderRadiusGeometry? borderRadius = widget.borderRadius == null
-        ? widget.buttonSize == ButtonSize.small
-            ? _kSmallButtonRadius
-            : _kLargeButtonRadius
-        : widget.borderRadius;
+    final disabledColor = !isSecondary
+        ? backgroundColor.withOpacity(0.5)
+        : backgroundColor.withOpacity(0.25);
 
     final Color foregroundColor = widget.enabled
         ? textLuminance(backgroundColor)
@@ -257,7 +324,7 @@ class PushButtonState extends State<PushButton>
             ? const Color.fromRGBO(255, 255, 255, 0.25)
             : const Color.fromRGBO(0, 0, 0, 0.25);
 
-    final TextStyle textStyle =
+    final baseStyle =
         theme.typography.headline.copyWith(color: foregroundColor);
 
     return MouseRegion(
@@ -272,25 +339,25 @@ class PushButtonState extends State<PushButton>
           button: true,
           label: widget.semanticLabel,
           child: ConstrainedBox(
-            constraints: const BoxConstraints(
-              minWidth: 49,
-              minHeight: 20,
-            ),
+            constraints: widget.controlSize.constraints,
             child: FadeTransition(
               opacity: _opacityAnimation,
               child: DecoratedBox(
-                decoration: BoxDecoration(
-                  borderRadius: borderRadius,
-                  color: !enabled ? disabledColor : backgroundColor,
+                decoration: ShapeDecoration(
+                  shape: RoundedRectangleBorder(
+                    borderRadius: widget.controlSize.borderRadius,
+                  ),
+                  // color: !enabled ? disabledColor : backgroundColor,
+                  color: enabled ? backgroundColor : disabledColor,
                 ),
                 child: Padding(
-                  padding: buttonPadding!,
+                  padding: widget.controlSize.padding,
                   child: Align(
                     alignment: widget.alignment,
                     widthFactor: 1.0,
                     heightFactor: 1.0,
                     child: DefaultTextStyle(
-                      style: textStyle,
+                      style: widget.controlSize.textStyle(baseStyle),
                       child: widget.child,
                     ),
                   ),
diff --git a/lib/src/theme/macos_theme.dart b/lib/src/theme/macos_theme.dart
index 78508f00..6de99369 100644
--- a/lib/src/theme/macos_theme.dart
+++ b/lib/src/theme/macos_theme.dart
@@ -225,8 +225,8 @@ class MacosThemeData with Diagnosticable {
     pushButtonTheme ??= PushButtonThemeData(
       color: primaryColor,
       secondaryColor: isDark
-          ? const Color.fromRGBO(56, 56, 56, 1.0)
-          : const Color.fromRGBO(218, 218, 223, 1.0),
+          ? const Color.fromRGBO(110, 109, 112, 1.0)
+          : MacosColors.white,
       disabledColor: isDark
           ? const Color.fromRGBO(255, 255, 255, 0.1)
           : const Color.fromRGBO(244, 245, 245, 1.0),
diff --git a/pubspec.lock b/pubspec.lock
index 4408d237..f80cd1d5 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -17,22 +17,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "5.11.1"
-  analyzer_plugin:
-    dependency: transitive
-    description:
-      name: analyzer_plugin
-      sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.11.2"
-  ansicolor:
-    dependency: transitive
-    description:
-      name: ansicolor
-      sha256: "607f8fa9786f392043f169898923e6c59b4518242b68b8862eb8a8b7d9c30b4a"
-      url: "https://pub.dev"
-    source: hosted
-    version: "2.0.1"
   args:
     dependency: transitive
     description:
@@ -105,38 +89,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.3"
-  csslib:
-    dependency: transitive
-    description:
-      name: csslib
-      sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.17.2"
-  dart_code_metrics:
-    dependency: "direct dev"
-    description:
-      name: dart_code_metrics
-      sha256: "1dc1fa763b73ed52147bd91b015d81903edc3f227b77b1672fcddba43390ed18"
-      url: "https://pub.dev"
-    source: hosted
-    version: "5.7.5"
-  dart_code_metrics_presets:
-    dependency: transitive
-    description:
-      name: dart_code_metrics_presets
-      sha256: "22e27f98e8c7d8b11cca43d2656a822935280747050ae65e8cd03c52d09c0d1c"
-      url: "https://pub.dev"
-    source: hosted
-    version: "1.7.0"
-  dart_style:
-    dependency: transitive
-    description:
-      name: dart_style
-      sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad
-      url: "https://pub.dev"
-    source: hosted
-    version: "2.3.1"
   fake_async:
     dependency: transitive
     description:
@@ -187,22 +139,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.1"
-  html:
-    dependency: transitive
-    description:
-      name: html
-      sha256: "58e3491f7bf0b6a4ea5110c0c688877460d1a6366731155c4a4580e7ded773e8"
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.15.3"
-  http:
-    dependency: transitive
-    description:
-      name: http
-      sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.13.6"
   http_multi_server:
     dependency: transitive
     description:
@@ -235,14 +171,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "0.6.7"
-  json_annotation:
-    dependency: transitive
-    description:
-      name: json_annotation
-      sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
-      url: "https://pub.dev"
-    source: hosted
-    version: "4.8.1"
   lints:
     dependency: transitive
     description:
@@ -331,22 +259,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.8.3"
-  petitparser:
-    dependency: transitive
-    description:
-      name: petitparser
-      sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
-      url: "https://pub.dev"
-    source: hosted
-    version: "5.4.0"
-  platform:
-    dependency: transitive
-    description:
-      name: platform
-      sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76"
-      url: "https://pub.dev"
-    source: hosted
-    version: "3.1.0"
   pool:
     dependency: transitive
     description:
@@ -355,14 +267,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.5.1"
-  process:
-    dependency: transitive
-    description:
-      name: process
-      sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09"
-      url: "https://pub.dev"
-    source: hosted
-    version: "4.2.4"
   pub_semver:
     dependency: transitive
     description:
@@ -371,14 +275,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.1.4"
-  pub_updater:
-    dependency: transitive
-    description:
-      name: pub_updater
-      sha256: "05ae70703e06f7fdeb05f7f02dd680b8aad810e87c756a618f33e1794635115c"
-      url: "https://pub.dev"
-    source: hosted
-    version: "0.3.0"
   shelf:
     dependency: transitive
     description:
@@ -504,14 +400,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.3.2"
-  uuid:
-    dependency: transitive
-    description:
-      name: uuid
-      sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
-      url: "https://pub.dev"
-    source: hosted
-    version: "3.0.7"
   vector_math:
     dependency: transitive
     description:
@@ -552,14 +440,6 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.0"
-  xml:
-    dependency: transitive
-    description:
-      name: xml
-      sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
-      url: "https://pub.dev"
-    source: hosted
-    version: "6.3.0"
   yaml:
     dependency: transitive
     description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 740361b5..bed7d3d6 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
 name: macos_ui
 description: Flutter widgets and themes implementing the current macOS design language.
-version: 2.0.0-beta.4
+version: 2.0.0-beta.5
 homepage: "https://macosui.dev"
 repository: "https://github.com/GroovinChip/macos_ui"
 
@@ -16,7 +16,6 @@ dependencies:
 dev_dependencies:
   flutter_test:
     sdk: flutter
-  dart_code_metrics: ^5.7.5
   flutter_lints: ^2.0.2
   mocktail: ^0.3.0
 


Test patch:
diff --git a/test/buttons/push_button_test.dart b/test/buttons/push_button_test.dart
index 3843c6a2..8bb294a0 100644
--- a/test/buttons/push_button_test.dart
+++ b/test/buttons/push_button_test.dart
@@ -27,7 +27,7 @@ void main() {
                 ContentArea(
                   builder: (context, _) {
                     return PushButton(
-                      buttonSize: ButtonSize.small,
+                      controlSize: ControlSize.regular,
                       onPressed: mockOnPressedFunction.handler,
                       child: const Text('Push me'),
                     );
@@ -61,7 +61,7 @@ void main() {
                 ContentArea(
                   builder: (context, _) {
                     return PushButton(
-                      buttonSize: ButtonSize.small,
+                      controlSize: ControlSize.regular,
                       key: pushButtonKey,
                       onPressed: mockOnTapCancelFunction.handler,
                       child: const Text('Push me'),
@@ -84,7 +84,7 @@ void main() {
     testWidgets('debugFillProperties', (tester) async {
       final builder = DiagnosticPropertiesBuilder();
       const PushButton(
-        buttonSize: ButtonSize.small,
+        controlSize: ControlSize.regular,
         child: Text('Test'),
       ).debugFillProperties(builder);
 
@@ -96,7 +96,7 @@ void main() {
       expect(
         description,
         [
-          'buttonSize: small',
+          'controlSize: regular',
           'color: null',
           'disabledColor: null',
           'pressedOpacity: 0.4',
@@ -104,7 +104,7 @@ void main() {
           'semanticLabel: null',
           'borderRadius: BorderRadius.circular(4.0)',
           'disabled',
-          'isSecondary: null',
+          'secondary: null',
         ],
       );
     });
diff --git a/test/theme/push_button_theme_test.dart b/test/theme/push_button_theme_test.dart
index a26619f8..2ff90243 100644
--- a/test/theme/push_button_theme_test.dart
+++ b/test/theme/push_button_theme_test.dart
@@ -1,7 +1,7 @@
 import 'package:flutter/foundation.dart';
-import 'package:flutter/widgets.dart';
 import 'package:flutter_test/flutter_test.dart';
 import 'package:macos_ui/macos_ui.dart';
+import 'package:macos_ui/src/library.dart';
 
 void main() {
   group('PushButton theme tests', () {
@@ -65,7 +65,7 @@ void main() {
                   builder: (context, _) {
                     capturedContext = context;
                     return const PushButton(
-                      buttonSize: ButtonSize.small,
+                      controlSize: ControlSize.regular,
                       child: Text('Push me'),
                     );
                   },
@@ -78,8 +78,8 @@ void main() {
 
       final theme = PushButtonTheme.of(capturedContext);
       expect(theme.color, const Color(0xff007aff));
-      expect(theme.disabledColor, const Color(0xfff4f5f5));
-      expect(theme.secondaryColor, const Color(0xffdadadf));
+      expect(theme.disabledColor, const Color.fromRGBO(244, 245, 245, 1.0));
+      expect(theme.secondaryColor, MacosColors.white);
     });
   });
 }