Resizable
A box which children can be resized along either the horizontal or vertical axis.
Preview
Code
class TimeOfDay extends StatelessWidget {
@override
Widget build(BuildContext context) => DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: context.theme.colors.border),
borderRadius: BorderRadius.circular(8),
),
child: FResizable(
axis: Axis.vertical,
crossAxisExtent: 300,
children: [
FResizableRegion(
initialExtent: 250,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sunrise, label: 'Morning'),
),
FResizableRegion(
initialExtent: 100,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sun, label: 'Afternoon'),
),
FResizableRegion(
initialExtent: 250,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sunset, label: 'Evening'),
),
],
),
);
}
class Label extends StatelessWidget {
static final DateFormat format = DateFormat.jm(); // Requires package:intl
final FResizableRegionData data;
final IconData icon;
final String label;
const Label({required this.data, required this.icon, required this.label, super.key});
@override
Widget build(BuildContext context) {
final FThemeData(:colors, :typography) = context.theme;
final start = DateTime.fromMillisecondsSinceEpoch(
(data.offsetPercentage.min * Duration.millisecondsPerDay).round(),
isUtc: true,
);
final end = DateTime.fromMillisecondsSinceEpoch(
(data.offsetPercentage.max * Duration.millisecondsPerDay).round(),
isUtc: true,
);
return Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 15, color: colors.foreground),
const SizedBox(width: 3),
Text(label, style: typography.sm.copyWith(color: colors.foreground)),
],
),
const SizedBox(height: 5),
Text(
'${format.format(start)} - ${format.format(end)}',
style: typography.sm.copyWith(color: colors.foreground),
),
],
),
);
}
}
Usage
FResizable(...)
FResizable(
controller: FResizableController.cascade(
onResizeUpdate: (regions) => print(regions),
onResizeEnd: (regions) => print(regions),
),
axis: Axis.vertical,
divider: FResizableDivider.dividerWithThumb,
crossAxisExtent: 400,
onChange: (regions) => print('Regions changed: $regions'),
children: [
FResizableRegion(
initialExtent: 200,
minExtent: 100,
builder: (context, data, child) => child!,
child: const Placeholder(),
),
],
);
Examples
Without Cascading
Preview
Code
class TimeOfDay extends StatelessWidget {
@override
Widget build(BuildContext context) => DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: context.theme.colors.border),
borderRadius: BorderRadius.circular(8),
),
child: FResizable(
axis: Axis.vertical,
controller: FResizableController(),
crossAxisExtent: 300,
children: [
FResizableRegion(
initialExtent: 200,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sunrise, label: 'Morning'),
),
FResizableRegion(
initialExtent: 200,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sun, label: 'Afternoon'),
),
FResizableRegion(
initialExtent: 200,
minExtent: 100,
builder: (_, data, __) => Label(data: data, icon: FIcons.sunset, label: 'Evening'),
),
],
),
);
}
class Label extends StatelessWidget {
static final DateFormat format = DateFormat.jm(); // Requires package:intl
final FResizableRegionData data;
final IconData icon;
final String label;
const Label({required this.data, required this.icon, required this.label, super.key});
@override
Widget build(BuildContext context) {
final FThemeData(:colors, :typography) = context.theme;
final start = DateTime.fromMillisecondsSinceEpoch(
(data.offsetPercentage.min * Duration.millisecondsPerDay).round(),
isUtc: true,
);
final end = DateTime.fromMillisecondsSinceEpoch(
(data.offsetPercentage.max * Duration.millisecondsPerDay).round(),
isUtc: true,
);
return Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 15, color: colors.foreground),
const SizedBox(width: 3),
Text(label, style: typography.sm.copyWith(color: colors.foreground)),
],
),
const SizedBox(height: 5),
Text(
'${format.format(start)} - ${format.format(end)}',
style: typography.sm.copyWith(color: colors.foreground),
),
],
),
);
}
}
Horizontal
Preview
Code
DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: context.theme.colors.border),
borderRadius: BorderRadius.circular(8),
),
child: FResizable(
axis: Axis.horizontal,
crossAxisExtent: 300,
children: [
FResizableRegion(
initialExtent: 100,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Sidebar', style: context.theme.typography.sm),
),
),
FResizableRegion(
initialExtent: 300,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Content', style: context.theme.typography.sm),
),
),
],
),
);
Divider with No Thumb
Preview
Code
DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: context.theme.colors.border),
borderRadius: BorderRadius.circular(8),
),
child: FResizable(
axis: Axis.horizontal,
divider: FResizableDivider.divider,
crossAxisExtent: 300,
children: [
FResizableRegion(
initialExtent: 100,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Sidebar', style: context.theme.typography.sm),
),
),
FResizableRegion(
initialExtent: 300,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Content', style: context.theme.typography.sm),
),
),
],
),
);
Without Divider
Preview
Code
DecoratedBox(
decoration: BoxDecoration(
border: Border.all(color: context.theme.colors.border),
borderRadius: BorderRadius.circular(8),
),
child: FResizable(
axis: Axis.horizontal,
divider: FResizableDivider.none,
crossAxisExtent: 300,
children: [
FResizableRegion(
initialExtent: 100,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Sidebar', style: context.theme.typography.sm),
),
),
FResizableRegion(
initialExtent: 300,
minExtent: 100,
builder: (context, data, _) => Align(
child: Text('Content', style: context.theme.typography.sm),
),
),
],
),
);
Last updated on