# Mono Kit Widgets

> Use when utilizing mono_kit UI widgets, lifecycle observers, dialog helpers, or layout utilities in Flutter apps.

- Skill: `mono0926/mono-kit-widgets` (Agent Skill)
- Install (CLI): `npx skillmds@latest add mono0926/mono-kit-widgets`
- Raw SKILL.md: https://api.skillmd.com/api/skills/mono0926/mono-kit-widgets/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: mono0926 (https://skillmd.com/u/mono0926)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/mono0926/mono-kit-widgets

---


# mono_kit Flutter Utilities & Widgets Guide

`mono_kit` is an opinionated collection of practical Flutter UI widgets, lifecycle listeners, and extension utilities created to streamline daily Flutter development.

## Guidelines

- **BetterPlaceholder**:
  - Use `BetterPlaceholder` instead of Flutter's default `Placeholder` when wireframing or creating mock UI sections, providing customizable color schemes, labels, and borders.
- **UnfocusOnTap**:
  - Wrap page roots or scroll views with `UnfocusOnTap` to dismiss the soft keyboard automatically whenever the user taps outside text fields.
- **LifecycleObserver**:
  - Use `LifecycleObserver` to observe `AppLifecycleState` transitions (resumed, paused, detached) with clean callback functions rather than manually implementing `WidgetsBindingObserver`.
- **Extension Helpers**:
  - Utilize context extensions (e.g. `context.theme`, `context.mediaQuery`, `context.colorScheme`) and collection/string extensions provided by `mono_kit`.

## Examples

### 1. Dismissing Keyboard with `UnfocusOnTap`

```dart
import 'package:flutter/material.dart';
import 'package:mono_kit/mono_kit.dart';

class FormScreen extends StatelessWidget {
  const FormScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return UnfocusOnTap(
      child: Scaffold(
        appBar: AppBar(title: const Text('Input Form')),
        body: ListView(
          padding: const EdgeInsets.all(16),
          children: const [
            TextField(decoration: InputDecoration(labelText: 'Name')),
            SizedBox(height: 16),
            TextField(decoration: InputDecoration(labelText: 'Email')),
          ],
        ),
      ),
    );
  }
}
```

### 2. App Lifecycle Observation

```dart
import 'package:flutter/material.dart';
import 'package:mono_kit/mono_kit.dart';

class TrackedScreen extends StatefulWidget {
  const TrackedScreen({super.key});

  @override
  State<TrackedScreen> createState() => _TrackedScreenState();
}

class _TrackedScreenState extends State<TrackedScreen> {
  late final LifecycleObserver _lifecycleObserver;

  @override
  void initState() {
    super.initState();
    _lifecycleObserver = LifecycleObserver(
      onResume: () => debugPrint('App resumed: refreshing real-time feeds'),
      onPause: () => debugPrint('App paused: pausing background timers'),
    );
  }

  @override
  void dispose() {
    _lifecycleObserver.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const Scaffold(
      body: Center(child: Text('Lifecycle Monitored')),
    );
  }
}
```

## Common Pitfalls & Anti-Patterns

- ❌ **Anti-pattern**: Forgetting to call `_lifecycleObserver.dispose()`, leaking global `WidgetsBindingObserver` callbacks.
  - ✔️ **Correct**: Always dispose `LifecycleObserver` within `State.dispose()`.

