button-system

SKILL.md

Button System Architecture

Two-layer system:

  1. CupertinoButtonWidget - Base interactive widget for all tappable elements
  2. ButtonWidget - High-level themed button with automatic sizing and styling

CupertinoButtonWidget (Base Layer)

Low-level widget providing:

  • Opacity animation on press (default 0.8)
  • Tap, long press, double tap, drag gestures
  • Loading state with CupertinoActivityIndicator
  • Auto focus management

Basic Usage

CupertinoButtonWidget(
  onPressed: () {},
  color: theme.defaultColors.systemBlue,
  borderRadius: BorderRadius.circular(12),
  padding: EdgeInsets.all(16),
  child: Text('Button'),
)

With Loading State

CupertinoButtonWidget(
  onPressed: isLoading ? null : () {},
  displayCupertinoActivityIndicator: isLoading,
  color: theme.defaultColors.systemBlue,
  child: Text('Submit'),
)

With Gradient

CupertinoButtonWidget(
  onPressed: () {},
  backgroundGradient: LinearGradient(
    colors: [
      theme.defaultColors.systemPurple,
      theme.defaultColors.systemPink,
    ],
  ),
  child: Text('Premium'),
)

ButtonWidget (High Layer)

High-level button with automatic theming.

Label Button

ButtonWidget.label(
  size: const LargeButtonSize(),
  color: const BlueButtonColor(),
  label: 'Continue',
  leftIcon: CupertinoIcons.checkmark,
  onPressed: () {},
)

Icon-Only Button

ButtonWidget.icon(
  size: const MediumButtonSize(),
  color: const GreyTransparentButtonColor(),
  leftIcon: CupertinoIcons.add,
  onPressed: () {},
)

Button Sizes

SmallButtonSize

  • Min height: 28pt
  • Border radius: 14pt
  • Typography: subheadline (15pt)
  • Use for: Secondary actions, compact UIs

MediumButtonSize

  • Min height: 34pt
  • Border radius: 50pt (pill)
  • Typography: body (17pt)
  • Use for: Standard buttons, toolbars

LargeButtonSize

  • Min height: 50pt
  • Border radius: 12pt
  • Typography: body (17pt)
  • Use for: Primary CTAs, main actions

CustomButtonSize

Define your own dimensions:

const CustomButtonSize(
  borderRadius: BorderRadius.all(Radius.circular(16)),
  padding: EdgeInsets.symmetric(horizontal: 24, vertical: 18),
  iconSize: 22,
  boxConstraints: BoxConstraints(minHeight: 56, minWidth: 56),
)

Button Colors

BlueButtonColor (Primary)

  • Background: systemBlue (#007AFF → #0A84FF)
  • Label: White
  • Use for: Primary actions (Continue, Save, Submit)

GreyTransparentButtonColor (Secondary)

  • Background: Fill secondary (grey, adapts)
  • Label: systemBlue
  • Use for: Secondary actions (Cancel, Back)

BlueTransparentButtonColor (Tertiary)

  • Background: Blue tint (15% opacity)
  • Label: systemBlue
  • Use for: Tertiary actions (Learn More, Info)

CustomButtonColor

class RedButtonColor extends ButtonColor {
  const RedButtonColor();

  
  Color? backgroundEnabled({required BuildContext context}) {
    final theme = IosTheme.of(context);
    return theme.defaultColors.systemRed;
  }

  
  Color labelEnabled({required BuildContext context}) {
    final theme = IosTheme.of(context);
    return theme.defaultColors.systemWhite;
  }
}

Label Font Weights

RegularLabelFontWeight

  • Small: subheadlineRegular (400 weight)
  • Others: bodyRegular (400 weight)

BoldLabelFontWeight

  • Small: subheadlineBold (600 weight)
  • Others: bodyBold (600 weight)

Common Patterns

Primary Action

ButtonWidget.label(
  size: const LargeButtonSize(),
  color: const BlueButtonColor(),
  label: 'Continue',
  onPressed: () {},
)

Secondary with Icon

ButtonWidget.label(
  size: const MediumButtonSize(),
  color: const GreyTransparentButtonColor(),
  label: 'Share',
  leftIcon: CupertinoIcons.share,
  onPressed: () {},
)

Toolbar Icon Button

ButtonWidget.icon(
  size: const MediumButtonSize(),
  color: const GreyTransparentButtonColor(),
  leftIcon: CupertinoIcons.add,
  onPressed: () {},
)

Loading Button

ButtonWidget.label(
  size: const LargeButtonSize(),
  color: const BlueButtonColor(),
  label: 'Processing',
  displayCupertinoActivityIndicator: isLoading,
  onPressed: isLoading ? null : () {},
)

Destructive Action

ButtonWidget.label(
  size: const MediumButtonSize(),
  color: const CustomButtonColor(
    backgroundEnabled: theme.defaultColors.systemRed,
    labelEnabled: theme.defaultColors.systemWhite,
  ),
  label: 'Delete',
  leftIcon: CupertinoIcons.trash,
  onPressed: () {},
)

Animation Constants

kAnimationInDuration           // 180ms
kAnimationOutDuration          // 120ms
kCupertinoButtonPressedOpacity // 0.8

File Locations

  • Base widget: /lib/src/widgets/cupertino_button_widget.dart
  • High-level widget: /lib/src/widgets/button_widget.dart
Weekly Installs
2
GitHub Stars
18
First Seen
13 days ago
Installed on
cline2
github-copilot2
codex2
kimi-cli2
gemini-cli2
cursor2