107 lines
3.9 KiB
Dart
107 lines
3.9 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:manager_app/constants.dart';
|
||
import 'package:manager_app/l10n/app_localizations.dart';
|
||
|
||
/// Dialogue de confirmation, partagé par douze écrans.
|
||
///
|
||
/// La signature positionnelle est celle d'origine : les appelants existants ne
|
||
/// changent pas. Les deux paramètres nommés sont là pour ceux qui ont quelque
|
||
/// chose de plus précis à dire qu'« Oui ».
|
||
///
|
||
/// Ce qu'il corrige : « Oui » / « Non » écrits en dur et en français, deux boutons
|
||
/// de 150 × 70 en `spaceEvenly`, une question à 25 px sans titre, un rayon de 20 —
|
||
/// et surtout un bouton de confirmation en couleur primaire, de sorte qu'une
|
||
/// suppression ressemblait à une action ordinaire.
|
||
void showConfirmationDialog(
|
||
String question,
|
||
Function onNo,
|
||
Function onYes,
|
||
BuildContext context, {
|
||
String? confirmLabel,
|
||
bool isDestructive = false,
|
||
}) {
|
||
showDialog(
|
||
context: context,
|
||
builder: (BuildContext context) {
|
||
final l = AppLocalizations.of(context)!;
|
||
final accent = isDestructive ? kError : kPrimaryColor;
|
||
|
||
return Dialog(
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(kRadiusShell),
|
||
side: const BorderSide(color: kLine),
|
||
),
|
||
clipBehavior: Clip.antiAlias,
|
||
child: SizedBox(
|
||
width: 420,
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.fromLTRB(kSpace6, kSpace6, kSpace6, kSpace5),
|
||
child: Row(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Icon(
|
||
isDestructive
|
||
? Icons.delete_outline
|
||
: Icons.help_outline_rounded,
|
||
size: 20,
|
||
color: accent,
|
||
),
|
||
const SizedBox(width: kSpace4),
|
||
Expanded(
|
||
child: Text(question,
|
||
style: const TextStyle(fontSize: 14.5, color: kInk, height: 1.45)),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
Container(
|
||
padding: const EdgeInsets.all(kSpace4),
|
||
decoration: const BoxDecoration(
|
||
color: kSurface2,
|
||
border: Border(top: BorderSide(color: kLineSoft)),
|
||
),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.end,
|
||
children: [
|
||
TextButton(
|
||
onPressed: () {
|
||
onNo();
|
||
Navigator.of(context).pop();
|
||
},
|
||
child: Text(l.cancel,
|
||
style: const TextStyle(fontSize: 13, color: kInk2)),
|
||
),
|
||
const SizedBox(width: kSpace2),
|
||
FilledButton(
|
||
onPressed: () {
|
||
onYes();
|
||
Navigator.of(context).pop();
|
||
},
|
||
style: FilledButton.styleFrom(
|
||
backgroundColor: accent,
|
||
padding: const EdgeInsets.symmetric(
|
||
horizontal: kSpace5, vertical: kSpace3),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(kRadiusPill)),
|
||
),
|
||
child: Text(
|
||
confirmLabel ?? (isDestructive ? l.delete : l.yes),
|
||
style: const TextStyle(
|
||
fontSize: 13, fontWeight: FontWeight.w600),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
},
|
||
);
|
||
}
|