super_form_field 1.8.0
super_form_field: ^1.8.0 copied to clipboard
GeniusLink design-system form fields for Flutter with unified InputDecoration APIs, OTP input, badge validation, responsive interactions, themes, and LTR/RTL support.
example/lib/main.dart
// ============================================================
// example/lib/main.dart
// ------------------------------------------------------------
// Gallery launcher for Super Form Field. Registers the SuperThemeData
// extension (light + dark parity), exposes a global Light/Dark + LTR/RTL
// toggle, and lists the package field demos.
// ============================================================
import 'package:flutter/material.dart';
import 'package:super_form_field/super_form_field.dart';
import 'demos/attachment_field_demo.dart';
import 'demos/bool_field_demo.dart';
import 'demos/choice_field_demo.dart';
import 'demos/date_field_demo.dart';
import 'demos/multi_select_field_demo.dart';
import 'demos/numeric_field_demo.dart';
import 'demos/otp_field_demo.dart';
import 'demos/phone_field_demo.dart';
import 'demos/select_field_demo.dart';
import 'demos/text_field_demo.dart';
final ValueNotifier<ThemeMode> _themeMode = ValueNotifier(ThemeMode.dark);
final ValueNotifier<TextDirection> _textDir = ValueNotifier(TextDirection.ltr);
SuperAppBar appBarBuild(BuildContext context, {Widget? title}) => SuperAppBar(
title: title,
actions: [
ValueListenableBuilder(
valueListenable: _themeMode,
builder: (context, mode, child) {
return IconButton(
tooltip: mode == ThemeMode.dark ? 'Light Theme' : 'Dark Theme',
icon: Icon(
mode == ThemeMode.dark
? Icons.light_mode_rounded
: Icons.dark_mode_rounded,
),
onPressed: () {
_themeMode.value = _themeMode.value == ThemeMode.dark
? ThemeMode.light
: ThemeMode.dark;
},
);
},
),
ValueListenableBuilder(
valueListenable: _textDir,
builder: (context, dir, child) {
return IconButton(
tooltip: dir == TextDirection.ltr ? 'Switch to RTL' : 'Switch to LTR',
icon: Icon(
dir == TextDirection.ltr
? Icons.format_textdirection_r_to_l_rounded
: Icons.format_textdirection_l_to_r_rounded,
),
onPressed: () {
_textDir.value = _textDir.value == TextDirection.ltr
? TextDirection.rtl
: TextDirection.ltr;
},
);
},
),
],
);
void main() => runApp(const ExampleApp());
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
@override
Widget build(BuildContext context) {
return ListenableBuilder(
listenable: Listenable.merge([_themeMode, _textDir]),
builder: (context, child) {
final mode = _themeMode.value;
final dir = _textDir.value;
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Super Form Field',
themeMode: mode,
theme: SuperMaterialThemeData.light(),
darkTheme: SuperMaterialThemeData.dark(),
locale: dir == TextDirection.rtl
? const Locale('ar')
: const Locale('en'),
localizationsDelegates: SuperFormLocalizations.localizationsDelegates,
supportedLocales: SuperFormLocalizations.supportedLocales,
builder: (context, child) =>
Directionality(textDirection: dir, child: child!),
home: _Launcher(mode: mode, dir: dir),
);
},
);
}
}
class _DemoItem {
const _DemoItem(this.title, this.subtitle, this.icon, this.builder);
final String title;
final String subtitle;
final IconData icon;
final WidgetBuilder builder;
}
class _Launcher extends StatelessWidget {
const _Launcher({required this.mode, required this.dir});
final ThemeMode mode;
final TextDirection dir;
static final _demos = <_DemoItem>[
_DemoItem(
'Super Text Field',
'Text · email · password · multiline · counter',
Icons.text_fields_rounded,
(_) => const TextFieldDemo(),
),
_DemoItem(
'Phone Text Field',
'International · country rules · formatters · Form save',
Icons.phone_android_rounded,
(_) => const PhoneFieldDemo(),
),
_DemoItem(
'Super OTP Field',
'SMS autofill · paste · secure PIN · completion',
Icons.password_rounded,
(_) => const OTPFieldDemo(),
),
_DemoItem(
'Super Numeric Field',
'Grouping · clamp · round · stepper · units',
Icons.pin_rounded,
(_) => const NumericFieldDemo(),
),
_DemoItem(
'Super Attachment Field',
'Drop zone · typed file list · validation',
Icons.attach_file_rounded,
(_) => const AttachmentFieldDemo(),
),
_DemoItem(
'Super Date Field',
'Masked date · mobile sheet · desktop popover · min/max',
Icons.event_rounded,
(_) => const DateFieldDemo(),
),
_DemoItem(
'Super Select Field',
'Searchable single-select dropdown · options',
Icons.arrow_drop_down_circle_outlined,
(_) => const SelectFieldDemo(),
),
_DemoItem(
'Super Multi-Select Field',
'Chips · checkable popover · min/max',
Icons.checklist_rounded,
(_) => const MultiSelectFieldDemo(),
),
_DemoItem(
'Super Bool Field',
'Toggle · checkbox · active flags · mustBeTrue',
Icons.toggle_on_outlined,
(_) => const BoolFieldDemo(),
),
_DemoItem(
'Super Choice Field',
'Segmented · radio · checkbox group',
Icons.tune_rounded,
(_) => const ChoiceFieldDemo(),
),
];
@override
Widget build(BuildContext context) {
final t = context.sffTheme;
return Scaffold(
appBar: appBarBuild(context, title: const Text('Super Form Field')),
body: SafeArea(
child: Center(
child: SingleChildScrollView(
padding: EdgeInsets.all(SuperThemeData.of(context).spacing.space10),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 680),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'SUPER FORM FIELD • GALLERY',
style: t.textTheme.eyebrow.copyWith(
color: Theme.of(context).colorScheme.primary,
),
),
SizedBox(height: SuperThemeData.of(context).spacing.space2),
Text(
'Form Fields حقول النماذج',
style: t.textTheme.h1.copyWith(color: t.fg1),
),
SizedBox(height: SuperThemeData.of(context).spacing.space8),
for (final d in _demos) ...[
_Card(item: d),
SizedBox(height: SuperThemeData.of(context).spacing.space3),
],
],
),
),
),
),
),
);
}
}
class _Card extends StatelessWidget {
const _Card({required this.item});
final _DemoItem item;
@override
Widget build(BuildContext context) {
final t = context.sffTheme;
return Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(
SuperThemeData.of(context).spacing.radiusCard,
),
onTap: () => Navigator.of(
context,
).push(MaterialPageRoute<void>(builder: item.builder)),
child: Container(
padding: EdgeInsets.all(SuperThemeData.of(context).spacing.space4),
decoration: BoxDecoration(
color: t.surface,
borderRadius: BorderRadius.circular(
SuperThemeData.of(context).spacing.radiusCard,
),
border: Border.all(color: t.border),
),
child: Row(
children: [
Container(
width: 44,
height: 44,
decoration: BoxDecoration(
color: Color.alphaBlend(
Theme.of(
context,
).colorScheme.primary.withValues(alpha: 0.14),
t.surface,
),
borderRadius: BorderRadius.circular(
SuperThemeData.of(context).spacing.radiusControl,
),
),
child: Icon(
item.icon,
size: 22,
color: Theme.of(context).colorScheme.primary,
),
),
SizedBox(width: SuperThemeData.of(context).spacing.space4),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
item.title,
style: t.textTheme.heading.copyWith(color: t.fg1),
),
const SizedBox(height: 2),
Text(
item.subtitle,
style: t.textTheme.caption.copyWith(color: t.fg3),
),
],
),
),
Icon(Icons.chevron_right, color: t.fg4),
],
),
),
),
);
}
}