neobrutalism_ui 0.1.2
neobrutalism_ui: ^0.1.2 copied to clipboard
Platform-adaptive neobrutalism components for Flutter.
import 'package:flutter/material.dart';
import 'package:neobrutalism_ui/neobrutalism_ui.dart';
void main() => runApp(const ExampleApp());
class ExampleApp extends StatefulWidget {
const ExampleApp({super.key});
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
var _isDark = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'neobrutalism_ui',
debugShowCheckedModeBanner: false,
builder: (context, child) => NeoTheme(
data: _isDark ? NeoThemeData.dark() : NeoThemeData.light(),
child: child!,
),
home: _Gallery(
isDark: _isDark,
onBrightnessChanged: (value) => setState(() => _isDark = value),
),
);
}
}
class _Gallery extends StatefulWidget {
const _Gallery({required this.isDark, required this.onBrightnessChanged});
final bool isDark;
final ValueChanged<bool> onBrightnessChanged;
@override
State<_Gallery> createState() => _GalleryState();
}
class _GalleryState extends State<_Gallery> {
static const _menuEntries = [
NeoMenuEntry<String>.label(Text('Account')),
NeoMenuEntry<String>.item(value: 'profile', label: Text('Profile')),
NeoMenuEntry<String>.separator(),
NeoMenuEntry<String>.item(value: 'logout', label: Text('Log out')),
];
static const _selectOptions = [
NeoSelectOption(value: 'apple', label: Text('Apple')),
NeoSelectOption(value: 'banana', label: Text('Banana')),
];
static const _destinations = [
NeoNavDestination(
value: 'home',
icon: Icon(Icons.home_outlined),
selectedIcon: Icon(Icons.home),
label: Text('Home'),
),
NeoNavDestination(
value: 'profile',
icon: Icon(Icons.person_outline),
selectedIcon: Icon(Icons.person),
label: Text('Profile'),
),
];
var _tab = 'buttons';
var _destination = 'home';
var _checked = true;
var _switched = true;
var _slider = 0.4;
var _radio = 'one';
var _page = 2;
String? _selected;
DateTime? _date;
@override
Widget build(BuildContext context) {
final colors = NeoTheme.of(context).colors;
return ColoredBox(
color: colors.background,
child: SafeArea(
child: Column(
children: [
NeoNavbar<String>(
value: _destination,
leading: const Text('NEO'),
destinations: _destinations,
onChanged: (value) => setState(() => _destination = value),
),
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
spacing: 16,
children: [
_section('Theme', [
NeoButton(
onPressed: () =>
widget.onBrightnessChanged(!widget.isDark),
child: Text(
widget.isDark
? 'Switch to light'
: 'Switch to dark',
),
),
]),
_section('Buttons', [
for (final variant in NeoButtonVariant.values)
NeoButton(
variant: variant,
onPressed: () {},
child: Text(variant.name),
),
const NeoButton(onPressed: null, child: Text('Disabled')),
NeoButton(
isLoading: true,
onPressed: () {},
child: const Text('Loading'),
),
]),
_section('Overlays', [
NeoButton(
onPressed: () => showNeoDialog<void>(
context: context,
builder: (dialogContext) => NeoDialog(
title: const Text('Dialog'),
description: const Text('A neobrutalism dialog.'),
actions: [
NeoButton(
onPressed: Navigator.of(dialogContext).pop,
child: const Text('Close'),
),
],
),
),
child: const Text('Dialog'),
),
NeoButton(
onPressed: () => showNeoSheet<void>(
context: context,
builder: (sheetContext) => NeoSheet(
child: NeoButton(
onPressed: Navigator.of(sheetContext).pop,
child: const Text('Close sheet'),
),
),
),
child: const Text('Sheet'),
),
NeoButton(
onPressed: () => showNeoDrawer<void>(
context: context,
builder: (drawerContext) => NeoDrawer(
child: NeoButton(
onPressed: Navigator.of(drawerContext).pop,
child: const Text('Close drawer'),
),
),
),
child: const Text('Drawer'),
),
NeoButton(
onPressed: () => NeoSonner.show(
context,
title: const Text('Saved'),
description: const Text('Your changes are stored.'),
),
child: const Text('Toast'),
),
]),
_section('Form', [
NeoCheckbox(
value: _checked,
onChanged: (value) =>
setState(() => _checked = value ?? false),
),
NeoSwitch(
value: _switched,
onChanged: (value) => setState(() => _switched = value),
),
NeoDatePicker(
value: _date,
onChanged: (value) => setState(() => _date = value),
),
]),
const NeoTextField(placeholder: 'Text field'),
const NeoTextarea(placeholder: 'Textarea'),
const NeoInputOtp(length: 4),
NeoSelect<String>(
value: _selected,
options: _selectOptions,
onChanged: (value) => setState(() => _selected = value),
),
NeoSlider(
value: _slider,
onChanged: (value) => setState(() => _slider = value),
),
NeoRadioGroup<String>(
value: _radio,
options: const [
NeoRadioOption(value: 'one', label: Text('One')),
NeoRadioOption(value: 'two', label: Text('Two')),
],
onChanged: (value) => setState(() => _radio = value),
),
const NeoAlert(
title: Text('Heads up'),
description: Text('This is a neobrutalism alert.'),
),
const NeoCard(
padding: EdgeInsets.all(16),
child: Text('Card'),
),
const Row(
spacing: 8,
children: [
NeoAvatar(fallback: Text('AB')),
NeoBadge(child: Text('Badge')),
NeoLabel(child: Text('Label')),
],
),
const NeoProgress(value: 0.6),
const NeoSkeleton(width: 180),
const NeoAccordion(
items: [
NeoAccordionItem(
title: Text('What is neobrutalism?'),
content: Text('Hard shadows, thick borders.'),
),
],
),
NeoTabs<String>(
value: _tab,
items: const [
NeoTabItem(
value: 'buttons',
label: Text('Buttons'),
content: Text('Tab one content'),
),
NeoTabItem(
value: 'forms',
label: Text('Forms'),
content: Text('Tab two content'),
),
],
onChanged: (value) => setState(() => _tab = value),
),
const NeoTable(
headers: [Text('Name'), Text('Email')],
rows: [
[Text('Ada'), Text('ada@example.com')],
[Text('Grace'), Text('grace@example.com')],
],
),
const NeoBreadcrumb(
items: [
NeoBreadcrumbItem(label: Text('Home')),
NeoBreadcrumbItem(label: Text('Components')),
],
),
NeoPagination(
page: _page,
pageCount: 5,
onPageChanged: (value) => setState(() => _page = value),
),
NeoDropdownMenu<String>(
entries: _menuEntries,
onSelected: (value) => NeoSonner.show(
context,
title: Text('Selected $value'),
),
triggerBuilder: (context, toggle, isOpen) => NeoButton(
onPressed: toggle,
child: const Text('Dropdown'),
),
),
NeoPopover(
triggerBuilder: (context, toggle, isOpen) => NeoButton(
onPressed: toggle,
child: const Text('Popover'),
),
content: const Text('Popover content'),
),
const NeoTooltip(
message: 'Tooltip',
child: Text('Hover me'),
),
const NeoMarquee(
height: 32,
children: [Text('NEO'), Text('BRUTAL'), Text('UI')],
),
const NeoCalendar(),
],
),
),
),
NeoBottomBar<String>(
value: _destination,
destinations: _destinations,
onChanged: (value) => setState(() => _destination = value),
),
],
),
),
);
}
Widget _section(String title, List<Widget> children) {
final text = NeoTheme.of(context).textTheme;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 8,
children: [
Text(title, style: text.heading),
Wrap(spacing: 8, runSpacing: 8, children: children),
],
);
}
}