VisorVisor
FlutterWidgets

VisorConfirmSheet

Adaptive confirmation surface — bottom sheet on mobile, dialog on wider viewports — with standard and destructive variants.

VisorConfirmSheet shows a confirmation surface that adapts to viewport width: a bottom sheet under 600 dp wide, a centered dialog above. The static helper VisorConfirmSheet.show returns a Future<bool?> resolving to true on confirm, false on cancel, and null if dismissed by tapping outside.

Preview

When to Use

  • Confirming a user-initiated action before it executes
  • Gating irreversible or destructive actions behind explicit confirmation
  • Presenting a short confirmation that adapts mobile vs desktop automatically

When Not to Use

  • Simple one-tap notifications (use VisorSnackBar)
  • Multi-step forms or flows requiring more than a title + message
  • Blocking errors or system-level interruptions (use an alert dialog)
  • Any scenario where the user cannot cancel — confirmations must always be cancellable

Installation

npx visor add confirm-sheet --target flutter

Or copy components/flutter/visor_confirm_sheet/visor_confirm_sheet.dart into your project.

Basic Usage

import 'package:ui/ui.dart';

final confirmed = await VisorConfirmSheet.show(
  context: context,
  title: 'Archive project?',
  message: 'You can restore it from the archive at any time.',
  confirmLabel: 'Archive',
  onConfirm: _archive,
);

Variants

// Destructive — red palette + warning icon
await VisorConfirmSheet.show(
  context: context,
  title: 'Delete account?',
  message: 'This cannot be undone. All your data will be erased.',
  confirmLabel: 'Delete account',
  variant: VisorConfirmSheetVariant.destructive,
  onConfirm: _deleteAccount,
);

// Custom icon
await VisorConfirmSheet.show(
  context: context,
  title: 'Sign out?',
  message: 'You will need to log back in to continue.',
  confirmLabel: 'Sign out',
  icon: PhosphorIcons.signOut(),
  onConfirm: _signOut,
);

API Reference

VisorConfirmSheet.show static helper:

ParameterTypeDefaultDescription
contextBuildContextrequiredBuild context used to find ancestor Navigator
titleStringrequiredHeading text shown at the top of the surface
messageStringrequiredExplanatory body text
confirmLabelStringrequiredPrimary confirm button label
onConfirmVoidCallbackrequiredFires when the user confirms
cancelLabelString'Cancel'Secondary cancel button label
variantVisorConfirmSheetVariant.standard.standard or .destructive
iconIconData?nullOverride the leading icon on the confirm button
onCancelVoidCallback?nullFires when the user cancels

VisorConfirmSheetVariant

ValueDescription
.standardNeutral palette — for routine confirmations
.destructiveError palette — for irreversible / destructive actions

Accessibility

  • The surface is wrapped in Semantics(container: true, label: title) so screen readers announce the heading on appearance.
  • Confirm and cancel buttons share the 48 dp tap-target floor.
  • The future resolves on Android back / iOS swipe-dismiss with null.

Source

  • components/flutter/visor_confirm_sheet/visor_confirm_sheet.dart
  • Quality contract audit row: docs/flutter-widget-quality-contract.md (Rec8)