Flutter adaptive design system
Platform-adaptive Flutter design system generating native-quality UI for iOS (Cupertino) and Android (Material 3). Use when: (1) Creating adaptive widgets that render natively per platform, (2) Building Flutter UI that looks like a real iOS or Android app — not a generic cross-platform hybrid, (3) Generating Cupertino/Material widget pairs with consistent API, (4) Implementing adaptive navigation, dialogs, forms, inputs, or layouts, (5) Setting up a Flutter project's design system foundation with platform detection. Triggers: "adaptive widget", "cupertino material", "platform adaptive", "ios android widget", "design system flutter", "native look flutter", "platform widget", "cupertino", "material design", "adaptive UI"From its SKILL.md
npx -y skills add abdouldotdev/flutter-adaptive-design-systemAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
14.5 KB, ~3.5k tokens by cl100k_base, as published. Nobody here has run it
Flutter Adaptive Design System
Brought to you by Appbiz Studio LLC
Generate platform-native Flutter UI. iOS renders Cupertino widgets; Android renders Material 3. Single codebase, two native experiences.
Package requirement: hugeicons for all icons (never CupertinoIcons or Icons for app icons).
Configuration
All widgets use the Adaptive prefix (AdaptiveButton, AdaptiveScaffold, AdaptiveDialog, etc.). This is fixed — no custom prefix. Keeps it consistent across all projects.
Template Files — Ready to Copy
All 41 production-tested adaptive widget files are in the templates/ directory, organized by category:
templates/
├── foundation/ # PlatformUtils, PlatformWidget, PlatformBuilder, AdaptiveThemeScope
└── widgets/
├── layout/ # Scaffold, AppBar, BottomNav, Card, Divider, ListTile, ListSection, SliverAppBar, TabScaffold
├── buttons/ # Button, FAB, IconButton, TextButton
├── inputs/ # TextField, SearchBar, Switch, Slider, Checkbox, Radio, SegmentedControl, Picker, FormField
├── feedback/ # Dialog, ActionSheet, SnackBar, ProgressIndicator, RefreshIndicator, Tooltip
├── chips/ # Chip, FilterChip
├── navigation/ # NavigationDrawer, PageRoute, PopupMenu, TabBar
├── pickers/ # DatePicker, TimePicker, Picker
└── context_menu/ # ContextMenu
How to install in a new project
Copy the templates verbatim into lib/shared/:
lib/shared/
├── foundation/ ← copy from templates/foundation/
└── widgets/ ← copy from templates/widgets/
Then create a barrel file lib/shared/widgets.dart exporting everything.
Only thing to adjust: Nothing. The templates use relative imports and only depend on flutter and hugeicons. No package-specific imports to replace.
Foundation
Three files power the system. See foundation.md for full code.
PlatformUtils — Detection engine
abstract final class PlatformUtils {
static bool get isCupertino => Platform.isIOS || Platform.isMacOS;
static bool get isMaterial => !isCupertino;
}
Three Implementation Patterns
Pattern A — PlatformWidget<M, C> base class
Best when both platforms return a Widget with similar constructor shape.
class AdaptiveSwitch extends PlatformWidget<Switch, CupertinoSwitch> {
final bool value;
final ValueChanged<bool>? onChanged;
const AdaptiveSwitch({super.key, required this.value, this.onChanged});
@override
Switch buildMaterialWidget(BuildContext context) =>
Switch(value: value, onChanged: onChanged);
@override
CupertinoSwitch buildCupertinoWidget(BuildContext context) =>
CupertinoSwitch(value: value, onChanged: onChanged);
}
Pattern B — StatelessWidget with direct dispatch Best when platform widgets have very different APIs or need custom wrapping.
class AdaptiveButton extends StatelessWidget {
final VoidCallback? onPressed;
final Widget child;
const AdaptiveButton({super.key, this.onPressed, required this.child});
@override
Widget build(BuildContext context) {
if (PlatformUtils.isCupertino) {
return CupertinoButton.filled(onPressed: onPressed, child: child);
}
return FilledButton(onPressed: onPressed, child: child);
}
}
Pattern C — Static methods for imperative APIs
Best for dialogs, sheets, pickers that use show*() functions.
class AdaptiveDialog {
const AdaptiveDialog._();
static Future<T?> show<T>({
required BuildContext context,
required String title,
String? content,
List<AdaptiveDialogAction> actions = const [],
}) {
if (PlatformUtils.isCupertino) return _showCupertino<T>(...);
return _showMaterial<T>(...);
}
}
Pattern Decision Tree
Need adaptive widget?
├─ Both platforms have similar Widget constructors?
│ └─ YES → Pattern A (PlatformWidget<M, C>)
├─ Platforms need very different params / wrapping?
│ └─ YES → Pattern B (StatelessWidget + if/else)
├─ Widget is shown imperatively (showDialog, showModalBottomSheet)?
│ └─ YES → Pattern C (static methods)
└─ Need function-level platform split (one-off)?
└─ Use PlatformBuilder(materialBuilder:, cupertinoBuilder:)
Supporting Utilities
// Function-based one-off platform split
class PlatformBuilder extends StatelessWidget {
final WidgetBuilder materialBuilder;
final WidgetBuilder cupertinoBuilder;
Widget build(context) => PlatformUtils.isCupertino
? cupertinoBuilder(context) : materialBuilder(context);
}
// Theme scope wrapper
class AdaptiveThemeScope extends StatelessWidget {
final ThemeData materialTheme;
final CupertinoThemeData cupertinoTheme;
final Widget child;
Widget build(context) => PlatformUtils.isCupertino
? CupertinoTheme(data: cupertinoTheme, child: child)
: Theme(data: materialTheme, child: child);
}
Widget Catalog (37 widgets)
See widgets.md for implementation code of each widget.
Navigation & Structure
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveScaffold | Scaffold | CupertinoPageScaffold | A |
AdaptiveAppBar | AppBar | CupertinoNavigationBar | B |
AdaptiveBottomNav | NavigationBar | CupertinoTabBar | B |
AdaptiveTabScaffold | Scaffold+NavigationBar | CupertinoTabScaffold | B |
AdaptiveSliverAppBar | SliverAppBar | CupertinoSliverNavigationBar | B |
AdaptivePageRoute | MaterialPageRoute | CupertinoPageRoute | C |
AdaptiveTabBar | TabBar+TabBarView | SegmentedControl+IndexedStack | B |
AdaptiveNavigationDrawer | NavigationDrawer | Custom drawer | B |
Content & Lists
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveCard | Card (M3) | Styled Container | A |
AdaptiveListTile | ListTile | CupertinoListTile | A |
AdaptiveListSection | Column+dividers | CupertinoListSection | B |
AdaptiveDivider | Divider | 0.5px Container | A |
Buttons & Actions
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveButton | FilledButton | CupertinoButton.filled | B |
AdaptiveTextButton | TextButton | CupertinoButton | B |
AdaptiveIconButton | IconButton | CupertinoButton(icon) | B |
AdaptiveFAB | FloatingActionButton | Hidden / nav bar button | B |
AdaptivePopupMenu | PopupMenuButton | CupertinoContextMenu | B |
AdaptiveContextMenu | ContextMenuController | CupertinoContextMenu | B |
Forms & Inputs
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveTextField | TextField (outlined) | CupertinoTextField | B |
AdaptiveSearchBar | SearchBar | CupertinoSearchTextField | B |
AdaptiveSwitch | Switch | CupertinoSwitch | A |
AdaptiveSlider | Slider | CupertinoSlider | A |
AdaptiveCheckbox | Checkbox | CupertinoCheckbox | A |
AdaptiveRadio | Radio | Custom Cupertino radio | B |
AdaptiveSegmentedControl | SegmentedButton | CupertinoSlidingSegmentedControl | B |
AdaptivePicker | ListWheelScrollView | CupertinoPicker | C |
AdaptiveFormField | TextFormField | CupertinoTextField+validator | B |
Chips & Tags
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveChip | Chip | Styled Container | B |
AdaptiveFilterChip | FilterChip | Styled toggle Container | B |
Feedback & Overlays
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveDialog | AlertDialog | CupertinoAlertDialog | C |
AdaptiveActionSheet | BottomSheet | CupertinoActionSheet | C |
AdaptiveSnackBar | SnackBar | Custom toast overlay | C |
AdaptiveProgressIndicator | CircularProgressIndicator | CupertinoActivityIndicator | A |
AdaptiveTooltip | Tooltip | Custom overlay | B |
Scroll & Refresh
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveRefreshIndicator | RefreshIndicator | CupertinoSliverRefreshControl | B |
Pickers & Dates
| Widget | Material 3 | Cupertino | Pattern |
|---|---|---|---|
AdaptiveDatePicker | showDatePicker() | CupertinoDatePicker modal | C |
AdaptiveTimePicker | showTimePicker() | CupertinoDatePicker(time) | C |
Iconography — HugeIcons
import 'package:hugeicons/hugeicons.dart';
HugeIcon(
icon: HugeIcons.strokeRoundedHome01,
color: CupertinoColors.label,
size: 24.0,
)
| Platform | Preferred style | Reason |
|---|---|---|
| Android | strokeRounded* | Matches Material outlined icons |
| iOS | solid* | Matches SF Symbols filled style |
Adaptive helper:
Widget adaptiveIcon(IconData stroke, IconData solid, {double size = 24, Color? color}) {
return HugeIcon(
icon: PlatformUtils.isCupertino ? solid : stroke,
size: size,
color: color,
);
}
Common mappings: Home01, Settings01, Search01, Notification01, User, Lock, Book01, Wallet01, ArrowLeft01, Add01, Cancel01, CheckmarkCircle01, Share01, Filter, Analytics01.
Typography
M3 DisplayLarge ↔ iOS largeTitle — 34px bold
M3 HeadlineMedium ↔ iOS title1 — 28px bold
M3 TitleLarge ↔ iOS title2 — 22px bold
M3 TitleMedium ↔ iOS headline — 17px semibold
M3 BodyLarge ↔ iOS body — 17px regular
M3 BodyMedium ↔ iOS callout — 16px regular
M3 LabelLarge ↔ iOS subheadline — 15px regular
M3 LabelSmall ↔ iOS caption1 — 12px regular
Colors
| Role | iOS System | M3 Equivalent |
|---|---|---|
| Primary | systemBlue #007AFF | primary |
| Destructive | systemRed #FF3B30 | error |
| Success | systemGreen #34C759 | custom |
| Warning | systemOrange #FF9500 | custom |
| Background | systemGroupedBackground | surface |
| Secondary BG | secondarySystemGroupedBackground | surfaceVariant |
| Label | label | onSurface |
| Secondary label | secondaryLabel | onSurfaceVariant |
Spacing & Border Radius
const double kPagePadding = 16.0;
const double kItemSpacing = 8.0;
const double kSectionSpacing = 24.0;
| Element | Android (M3) | iOS |
|---|---|---|
| Card | 12px | 10px |
| Button | 20px (pill) | 10px |
| Dialog | 28px | 14px |
| TextField | 4px | 8px |
| Chip | 8px | 6px |
Scroll, Gestures, Haptics
ScrollPhysics adaptiveScrollPhysics() => PlatformUtils.isCupertino
? const BouncingScrollPhysics()
: const ClampingScrollPhysics();
| Interaction | Android | iOS |
|---|---|---|
| Back | System back + edge swipe | Swipe from left edge |
| Long-press | Text selection | CupertinoContextMenu with preview |
| Overscroll | Blue glow | Bounce |
| Pull-to-refresh | Colored circle | Spinner |
Haptics: HapticFeedback.lightImpact() (tap), .mediumImpact() (action), .heavyImpact() (confirm), .selectionClick() (picker).
Animations
| Action | Duration |
|---|---|
| Micro (tap, toggle) | 100-150ms |
| UI transition (dialog) | 250-300ms |
| Page transition | 350-400ms |
| Usage | Android M3 | iOS |
|---|---|---|
| Page transition | easeInOutCubicEmphasized | easeInOut |
| Dialog appear | easeOutBack | easeOut |
| Element enter | fastOutSlowIn | easeOut |
Keyboard & Status Bar
// Dismiss keyboard on tap outside
GestureDetector(onTap: () => FocusScope.of(context).unfocus(), child: ...)
// Adaptive status bar
SystemChrome.setSystemUIOverlayStyle(
PlatformUtils.isCupertino ? SystemUiOverlayStyle.dark
: SystemUiOverlayStyle(statusBarColor: Colors.transparent, ...),
);
Performance Rules
Adaptive widgets dispatch hundreds of widgets per screen. See performance.md for full guide.
Critical rules:
- const constructors — Every adaptive widget MUST have
constconstructor. Useconstin widget trees. - Platform check is free —
PlatformUtils.isCupertinois a static bool read. Zero cost. No caching needed. - Only active branch runs —
PlatformWidget.buildcalls only one branch. Dead code is never executed. - ListView.builder always — Never
ListView(children: [...])for dynamic lists. Use.builder. - RepaintBoundary — Wrap interactive cards to prevent ripple/animation leaks.
- Extract const subtrees — Break large builds into small const-eligible widgets.
- Method refs over closures —
onPressed: _submitnotonPressed: () => _submit(). - Image decode at display size — Set
cacheWidth/cacheHeighton images. - FadeTransition over AnimatedOpacity — Avoids expensive
saveLayer.
Performance budgets: First frame < 2s, frame render < 16ms (60fps), list scroll 0 jank frames, memory < 100MB.
Extended References
For detailed implementation code and advanced patterns:
- foundation.md — PlatformWidget, PlatformUtils, PlatformBuilder, AdaptiveThemeScope, barrel file, app entry point
- widgets.md — Full implementation code for all 37 widgets
- accessibility.md — Semantics, Dynamic Type, VoiceOver/TalkBack, WCAG AA
- responsive.md — Breakpoints, LayoutBuilder, iPad/tablet, landscape
- states.md — Loading/shimmer, empty, error, disabled state patterns
- performance.md — const optimization, rebuild prevention, list performance, animation, profiling
What ships with it: 71 files
326.0 KB alongside SKILL.md
references/
- accessibility.md6.2 KB
- foundation.md9.2 KB
- performance.md8.4 KB
- responsive.md8.3 KB
- states.md13.1 KB
- widgets.md35.0 KB
templates/
- adaptive.dart3.3 KB
- foundation/adaptive_icons.dart5.9 KB
- foundation/adaptive_theme_scope.dart668 B
- foundation/adaptive_tokens.dart7.5 KB
- foundation/adaptive_typography.dart8.8 KB
- foundation/platform_builder.dart495 B
- foundation/platform_os_io.dart442 B
- foundation/platform_os_stub.dart356 B
- foundation/platform_utils.dart1.9 KB
- foundation/platform_widget.dart486 B
- responsive/adaptive_constrained_content.dart2.7 KB
- responsive/adaptive_master_detail.dart4.0 KB
- responsive/adaptive_responsive_grid.dart3.9 KB
- responsive/adaptive_responsive_scaffold.dart11.5 KB
- responsive/breakpoints.dart6.0 KB
- test/adaptive_widget_test_template.dart15.3 KB
- widgets/buttons/adaptive_button.dart1.7 KB
- widgets/buttons/adaptive_fab.dart2.7 KB
- widgets/buttons/adaptive_icon_button.dart1.4 KB
- widgets/buttons/adaptive_text_button.dart1.6 KB
- widgets/chips/adaptive_chip.dart4.2 KB
- widgets/chips/adaptive_filter_chip.dart4.7 KB
- widgets/context_menu/adaptive_context_menu.dart3.1 KB
- widgets/feedback/adaptive_action_sheet.dart5.7 KB
- widgets/feedback/adaptive_dialog.dart3.3 KB
- widgets/feedback/adaptive_progress_indicator.dart1.4 KB
- widgets/feedback/adaptive_refresh_indicator.dart1.8 KB
- widgets/feedback/adaptive_snack_bar.dart7.1 KB
- widgets/feedback/adaptive_tooltip.dart4.9 KB
- widgets/inputs/adaptive_checkbox.dart1.3 KB
- widgets/inputs/adaptive_form_field.dart7.8 KB
- .gitignore10 B
- LICENSE1.0 KB
- README.md9.0 KB
31 more files not listed here. See all 71 in the repository.