overmark 0.1.2 copy "overmark: ^0.1.2" to clipboard
overmark: ^0.1.2 copied to clipboard

Spotlight coach marks for Flutter onboarding tours. Dims the screen, highlights any widget through a cut-out, and explains it in a fully customizable card. Zero dependencies.

Overmark #

Spotlight coach marks for Flutter onboarding tours. Dim the screen, cut a hole around a widget, explain it in a card, move on to the next one.

pub package license: MIT

Default Overmark tour    Custom-themed Overmark tour

Default theme · Custom theme

  • No dependencies. Just Flutter. Nothing is pulled into your app.
  • Fits any theme. Every colour and text style falls back to the ambient ThemeData, so the default look is neutral in light and dark alike.
  • Customisable to the pixel. Restyle through OvermarkTheme, or replace the card entirely with your own widget.
  • Behaves like a real route. The system back gesture ends the tour, and the call returns a future telling you how it ended.
  • Keeps up. The spotlight tracks its anchor through rotation, resize, and scrolling, and scrolls off-screen anchors into view for you.

Install #

dependencies:
  overmark: ^0.1.2

Quick start #

Attach a GlobalKey to each widget you want to highlight, then start a tour.

import 'package:overmark/overmark.dart';

final GlobalKey searchKey = GlobalKey();
final GlobalKey shelfKey = GlobalKey();

// ...

TextField(key: searchKey);

// ...

final OvermarkOutcome outcome = await Overmark.show(
  context,
  steps: <OvermarkStep>[
    OvermarkStep(
      anchorKey: searchKey,
      title: 'Find your next book',
      message: 'Search by title, author, or topic.',
    ),
    OvermarkStep(
      anchorKey: shelfKey,
      title: 'Tap any cover',
      message: 'Every book is a short visual summary.',
    ),
  ],
);

Steps whose anchor is not on screen are dropped, and the tour is skipped entirely when that leaves nothing to show — so it is safe to call on a screen whose content is still loading.

outcome is one of completed, skipped, dismissed, or notShown.

Show it only once #

showOnce is the usual first-run pattern. Without a storage it remembers for the current launch only:

await Overmark.showOnce(
  context,
  tourId: 'home_tour_v1',
  steps: steps,
);

To remember across launches, hand it somewhere to write. Overmark has no dependencies, so the adapter lives in your app — with shared_preferences it is six lines:

class PrefsOvermarkStorage implements OvermarkStorage {
  @override
  Future<bool> hasShown(String tourId) async =>
      (await SharedPreferences.getInstance()).getBool('tour_$tourId') ?? false;

  @override
  Future<void> markShown(String tourId) async =>
      (await SharedPreferences.getInstance()).setBool('tour_$tourId', true);
}

await Overmark.showOnce(
  context,
  tourId: 'home_tour_v1',
  storage: PrefsOvermarkStorage(),
  steps: steps,
);

The tour is marked as shown before it is displayed, so a crash midway through never traps a user in a tour that replays on every launch.

Bumping the tourId (home_tour_v2) is how you re-run a tour after redesigning a screen.

Theming #

Leave a field null and it is derived from Theme.of(context). Set only what you want to change:

await Overmark.show(
  context,
  theme: OvermarkTheme(
    scrimColor: const Color(0xFF1B0E2B).withAlpha(220),
    spotlightBorderColor: const Color(0xFFFFC857),
    spotlightRadius: 28,
    cardRadius: 28,
    buttonColor: const Color(0xFFFFC857),
  ),
  steps: steps,
);
Group Fields
Spotlight scrimColor, spotlightBorderColor, spotlightBorderWidth, spotlightRadius, spotlightPadding
Card cardColor, cardRadius, cardPadding, cardMargin, cardGap, cardShadows
Text titleStyle, messageStyle, skipStyle, buttonLabelStyle
Button buttonColor, buttonPadding, buttonRadius
Progress dots indicatorSize, indicatorSpacing, indicatorColor, indicatorActiveColor

Translate the controls with OvermarkLabels:

labels: const OvermarkLabels(next: 'Lanjut', skip: 'Lewati', done: 'Mengerti'),

Behaviour #

config: const OvermarkConfig(
  advanceOnBarrierTap: true,   // tap anywhere to move on
  showSkip: true,              // skip control before the last step
  showIndicator: true,         // progress dots
  animationDuration: Duration(milliseconds: 320),
  animationCurve: Curves.easeOutCubic,
  transitionDuration: Duration(milliseconds: 180),
  ensureVisible: true,         // scroll an off-screen anchor into view
  dismissible: true,           // system back ends the tour
  useRootNavigator: true,
),

Per-step overrides #

Any step can override the spotlight shape, corner radius, and padding:

OvermarkStep(
  anchorKey: profileTabKey,
  title: 'Your progress',
  message: 'Streaks and stats live here.',
  shape: OvermarkShape.circle,
  padding: const EdgeInsets.all(12),
)

Your own card #

When theming is not enough, replace the card for a step. You get the tour state and the navigation callbacks:

OvermarkStep(
  anchorKey: shelfKey,
  cardBuilder: (BuildContext context, OvermarkStepDetails details) {
    return MyCard(
      step: details.index + 1,
      of: details.stepCount,
      isLast: details.isLast,
      anchor: details.anchorRect,
      onNext: details.next,
      onBack: details.previous,
      onClose: details.skip,
    );
  },
)

Driving the tour yourself #

final OvermarkController controller = OvermarkController();

Overmark.show(context, controller: controller, steps: steps);

controller.next();
controller.previous();
controller.skip();
controller.finish();

Callbacks are available too: onStepChanged, onSkip, and onFinish.

Version support #

Dart >=3.4.0 <4.0.0
Flutter >=3.22.0
Platforms Android, iOS, web, macOS, Windows, Linux

Pure Dart and Flutter, so every platform is supported. CI runs the test suite on the oldest supported Flutter and on the current stable.

Example #

A runnable demo lives in example/: a first-run tour, a replay with a completely different theme, a light/dark toggle, and a shared_preferences storage adapter. The GIFs above were recorded from that app — default look on the left, custom OvermarkTheme on the right.

cd example
flutter run

License #

MIT

7
likes
160
points
226
downloads

Documentation

API reference

Publisher

verified publisherfirdanumar.com

Weekly Downloads

Spotlight coach marks for Flutter onboarding tours. Dims the screen, highlights any widget through a cut-out, and explains it in a fully customizable card. Zero dependencies.

Repository (GitHub)
View/report issues

Topics

#onboarding #coachmark #tutorial #overlay #spotlight

License

MIT (license)

Dependencies

flutter

More

Packages that depend on overmark