Widgets

Modal'lar

Giriş

Nylo Website, alt sayfa modal'ları etrafında inşa edilmiş bir modal sistemi sağlar.

BottomSheetModal sınıfı, eylemler, başlıklar, kapatma düğmeleri ve özel stil ile içerik katmanları görüntülemek için esnek bir API sunar.

Modal'lar şunlar için kullanışlıdır:

  • Onay diyalogları (örn. çıkış, silme)
  • Hızlı giriş formları
  • Birden fazla seçenekli eylem sayfaları
  • Bilgilendirme katmanları

Modal Oluşturma

Metro CLI kullanarak yeni bir modal oluşturabilirsiniz:

metro make:bottom_sheet_modal payment_options

Bu iki şey oluşturur:

  1. lib/resources/widgets/bottom_sheet_modals/modals/payment_options_modal.dart konumunda bir modal içerik widget'ı:
import 'package:flutter/material.dart';

/// Payment Options Modal
///
/// Used in BottomSheetModal.showPaymentOptions()
class PaymentOptionsModal extends StatelessWidget {
  const PaymentOptionsModal({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('PaymentOptionsModal').headingLarge(),
      ],
    );
  }
}
  1. lib/resources/widgets/bottom_sheet_modals/bottom_sheet_modals.dart dosyasındaki BottomSheetModal sınıfınıza eklenen statik bir metot:
/// Show Payment Options modal
static Future<void> showPaymentOptions(BuildContext context) {
  return displayModal(
    context,
    isScrollControlled: false,
    child: const PaymentOptionsModal(),
  );
}

Ardından modal'ı herhangi bir yerden görüntüleyebilirsiniz:

BottomSheetModal.showPaymentOptions(context);

Aynı isimde bir modal zaten varsa, üzerine yazmak için --force bayrağını kullanın:

metro make:bottom_sheet_modal payment_options --force

Temel Kullanım

BottomSheetModal kullanarak bir modal görüntüleyin:

BottomSheetModal.showLogout(context);

Modal Oluşturma

Önerilen yaklaşım, her modal türü için statik metotları olan bir BottomSheetModal sınıfı oluşturmaktır. Şablon bu yapıyı sağlar:

import 'package:flutter/material.dart';
import 'package:nylo_framework/nylo_framework.dart';

class BottomSheetModal extends NyBaseModal {
  static ModalShowFunction get displayModal => displayModal;

  /// Show Logout modal
  static Future<void> showLogout(
    BuildContext context, {
    Function()? onLogoutPressed,
    Function()? onCancelPressed,
  }) {
    return displayModal(
      context,
      isScrollControlled: false,
      child: const LogoutModal(),
      actionsRow: [
        Button.secondary(
          text: "Logout",
          onPressed: onLogoutPressed ?? () => routeToInitial(),
        ),
        Button(
          text: "Cancel",
          onPressed: onCancelPressed ?? () => Navigator.pop(context),
        ),
      ],
    );
  }
}

Herhangi bir yerden çağırın:

BottomSheetModal.showLogout(context);

// With custom callbacks
BottomSheetModal.showLogout(
  context,
  onLogoutPressed: () {
    // Custom logout logic
  },
  onCancelPressed: () {
    Navigator.pop(context);
  },
);

BottomSheetModal

displayModal<T>(), modal'ları görüntülemek için temel metottur.

Parametreler

Parametre Tür Varsayılan Açıklama
context BuildContext zorunlu Modal için build context
child Widget zorunlu Ana içerik widget'ı
actionsRow List<Widget> [] Yatay sırada görüntülenen eylem widget'ları
actionsColumn List<Widget> [] Dikey olarak görüntülenen eylem widget'ları
height double? null Modal için sabit yükseklik
header Widget? null Üstteki başlık widget'ı
useSafeArea bool true İçeriği SafeArea ile sar
isScrollControlled bool false Modal'ın kaydırılabilir olmasına izin ver
showCloseButton bool false X kapatma düğmesini göster
headerPadding EdgeInsets? null Başlık mevcut olduğunda dolgu
backgroundColor Color? null Modal arka plan rengi
showHandle bool true Üstteki sürükleme tutamacını göster
closeButtonColor Color? null Kapatma düğmesi arka plan rengi
closeButtonIconColor Color? null Kapatma düğmesi ikon rengi
modalDecoration BoxDecoration? null Modal kapsayıcı için özel dekorasyon
handleColor Color? null Sürükleme tutamacının rengi

Eylemler

Eylemler, modal'ın altında görüntülenen düğmelerdir.

Satır eylemleri yan yana yerleştirilir ve her biri eşit alan kaplar:

displayModal(
  context,
  child: Text("Are you sure?"),
  actionsRow: [
    ElevatedButton(
      onPressed: () => Navigator.pop(context, true),
      child: Text("Yes"),
    ),
    TextButton(
      onPressed: () => Navigator.pop(context, false),
      child: Text("No"),
    ),
  ],
);

Sütun eylemleri dikey olarak istiflenir:

displayModal(
  context,
  child: Text("Choose an option"),
  actionsColumn: [
    ElevatedButton(
      onPressed: () => Navigator.pop(context, true),
      child: Text("Yes"),
    ),
    TextButton(
      onPressed: () => Navigator.pop(context, false),
      child: Text("No"),
    ),
  ],
);

Başlık

Ana içeriğin üstüne bir başlık ekleyin:

displayModal(
  context,
  header: Container(
    padding: EdgeInsets.all(16),
    color: Colors.blue,
    child: Text(
      "Modal Title",
      style: TextStyle(color: Colors.white, fontSize: 18),
    ),
  ),
  child: Text("Modal content goes here"),
);

Kapatma Düğmesi

Sağ üst köşede bir kapatma düğmesi görüntüleyin:

displayModal(
  context,
  showCloseButton: true,
  closeButtonColor: Colors.grey.shade200,
  closeButtonIconColor: Colors.black,
  child: Padding(
    padding: EdgeInsets.all(24),
    child: Text("Content with close button"),
  ),
);

Özel Dekorasyon

Modal kapsayıcısının görünümünü özelleştirin:

displayModal(
  context,
  backgroundColor: Colors.transparent,
  modalDecoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
    boxShadow: [
      BoxShadow(color: Colors.black26, blurRadius: 10),
    ],
  ),
  handleColor: Colors.grey.shade400,
  child: Text("Custom styled modal"),
);

BottomModalSheetStyle

BottomModalSheetStyle, form seçicileri ve diğer bileşenler tarafından kullanılan alt sayfa modal'larının görünümünü yapılandırır:

BottomModalSheetStyle(
  backgroundColor: NyColor(light: Colors.white, dark: Colors.grey.shade900),
  barrierColor: NyColor(light: Colors.black54, dark: Colors.black87),
  useRootNavigator: false,
  titleStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
  itemStyle: TextStyle(fontSize: 16),
  clearButtonStyle: TextStyle(color: Colors.red),
)
Özellik Tür Açıklama
backgroundColor NyColor? Modal'ın arka plan rengi
barrierColor NyColor? Modal'ın arkasındaki katman rengi
useRootNavigator bool Kök navigatörü kullan (varsayılan: false)
routeSettings RouteSettings? Modal için rota ayarları
titleStyle TextStyle? Başlık metni stili
itemStyle TextStyle? Liste öğesi metni stili
clearButtonStyle TextStyle? Temizle düğmesi metni stili

Örnekler

Onay Modal'ı

static Future<bool?> showConfirm(
  BuildContext context, {
  required String message,
}) {
  return displayModal<bool>(
    context,
    child: Padding(
      padding: EdgeInsets.symmetric(vertical: 16),
      child: Text(message, textAlign: TextAlign.center),
    ),
    actionsRow: [
      ElevatedButton(
        onPressed: () => Navigator.pop(context, true),
        child: Text("Confirm"),
      ),
      TextButton(
        onPressed: () => Navigator.pop(context, false),
        child: Text("Cancel"),
      ),
    ],
  );
}

// Usage
bool? confirmed = await BottomSheetModal.showConfirm(
  context,
  message: "Delete this item?",
);
if (confirmed == true) {
  // delete the item
}

Kaydırılabilir İçerik Modal'ı

displayModal(
  context,
  isScrollControlled: true,
  height: MediaQuery.of(context).size.height * 0.8,
  showCloseButton: true,
  header: Padding(
    padding: EdgeInsets.all(16),
    child: Text("Terms of Service", style: TextStyle(fontSize: 20)),
  ),
  child: SingleChildScrollView(
    child: Text(longTermsText),
  ),
);

Eylem Sayfası

displayModal(
  context,
  showHandle: true,
  child: Text("Share via", style: TextStyle(fontSize: 18)),
  actionsColumn: [
    ListTile(
      leading: Icon(Icons.email),
      title: Text("Email"),
      onTap: () {
        Navigator.pop(context);
        shareViaEmail();
      },
    ),
    ListTile(
      leading: Icon(Icons.message),
      title: Text("Message"),
      onTap: () {
        Navigator.pop(context);
        shareViaMessage();
      },
    ),
    ListTile(
      leading: Icon(Icons.copy),
      title: Text("Copy Link"),
      onTap: () {
        Navigator.pop(context);
        copyLink();
      },
    ),
  ],
);