diff --git a/CHANGELOG.md b/CHANGELOG.md index 19ac8dd3..d10d09a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.12.0 + +- **FEAT**: Add `axis`, `spacing`, `runSpacing`, `alignment`, `runAlignment`, `crossAxisAlignment` and `crossAxisAlignment` to `ShadRadioGroup` and `ShadRadioGroupFormField`. + ## 0.11.1 - **FEAT**: Add `headers` to `ShadImage` to allow custom headers in the network requests. diff --git a/example/lib/pages/radio_group.dart b/example/lib/pages/radio_group.dart index 8934f088..9477f65f 100644 --- a/example/lib/pages/radio_group.dart +++ b/example/lib/pages/radio_group.dart @@ -1,6 +1,6 @@ -import 'package:awesome_flutter_extensions/awesome_flutter_extensions.dart'; import 'package:example/common/base_scaffold.dart'; import 'package:example/common/properties/bool_property.dart'; +import 'package:example/common/properties/enum_property.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:shadcn_ui/shadcn_ui.dart'; @@ -29,6 +29,7 @@ class RadioPage extends StatefulWidget { class _RadioPageState extends State { NotifyAbout? value; bool enabled = true; + Axis axis = Axis.vertical; @override Widget build(BuildContext context) { @@ -41,22 +42,27 @@ class _RadioPageState extends State { value: enabled, onChanged: (value) => setState(() => enabled = value), ), + MyEnumProperty( + label: 'Axis', + value: axis, + onChanged: (value) => setState(() => axis = value), + values: Axis.values, + ), ], children: [ - ShadRadioGroup( + ShadRadioGroup( enabled: enabled, initialValue: value, onChanged: (v) { print('onChange $v'); }, - items: NotifyAbout.values - .map( - (e) => ShadRadio( - value: e, - label: Text(e.message), - ), - ) - .separatedBy(const SizedBox(height: 4)), + axis: axis, + items: NotifyAbout.values.map( + (e) => ShadRadio( + value: e, + label: Text(e.message), + ), + ), ), ], ); diff --git a/example/lib/pages/radio_group_form_field.dart b/example/lib/pages/radio_group_form_field.dart index 8d91c624..4077c701 100644 --- a/example/lib/pages/radio_group_form_field.dart +++ b/example/lib/pages/radio_group_form_field.dart @@ -2,7 +2,6 @@ import 'dart:convert'; -import 'package:awesome_flutter_extensions/awesome_flutter_extensions.dart'; import 'package:example/common/base_scaffold.dart'; import 'package:example/common/properties/bool_property.dart'; import 'package:example/common/properties/enum_property.dart'; @@ -86,14 +85,12 @@ class _RadioGroupFormFieldPageState extends State { enabled: enabled, initialValue: initialValue, valueTransformer: (value) => value?.name, - items: NotifyAbout.values - .map( - (e) => ShadRadio( - value: e, - label: Text(e.message), - ), - ) - .separatedBy(const SizedBox(height: 4)), + items: NotifyAbout.values.map( + (e) => ShadRadio( + value: e, + label: Text(e.message), + ), + ), label: const Text('Notify me about'), validator: (v) { if (v == null) { diff --git a/lib/src/components/form/fields/radio.dart b/lib/src/components/form/fields/radio.dart index 1833a501..49d090a2 100644 --- a/lib/src/components/form/fields/radio.dart +++ b/lib/src/components/form/fields/radio.dart @@ -22,6 +22,24 @@ class ShadRadioGroupFormField extends ShadFormBuilderField { super.focusNode, super.validator, required Iterable items, + + /// {@macro ShadRadioGroup.axis} + Axis? axis, + + /// {@macro ShadRadioGroup.spacing} + double? spacing, + + /// {@macro ShadRadioGroup.runSpacing} + double? runSpacing, + + /// {@macro ShadRadioGroup.alignment} + WrapAlignment? alignment, + + /// {@macro ShadRadioGroup.runAlignment} + WrapAlignment? runAlignment, + + /// {@macro ShadRadioGroup.crossAxisAlignment} + WrapCrossAlignment? crossAxisAlignment, }) : super( decorationBuilder: (context) => ShadTheme.of(context).radioTheme.decoration ?? @@ -31,8 +49,14 @@ class ShadRadioGroupFormField extends ShadFormBuilderField { return ShadRadioGroup( items: items, onChanged: state.didChange, - enabled: enabled, + enabled: state.enabled, initialValue: initialValue, + axis: axis, + spacing: spacing, + runSpacing: runSpacing, + alignment: alignment, + runAlignment: runAlignment, + crossAxisAlignment: crossAxisAlignment, ); }, ); diff --git a/lib/src/components/radio.dart b/lib/src/components/radio.dart index c92d38cb..50ec65d2 100644 --- a/lib/src/components/radio.dart +++ b/lib/src/components/radio.dart @@ -15,20 +15,67 @@ class ShadRadioGroup extends StatefulWidget { this.initialValue, this.onChanged, this.enabled = true, + this.axis, + this.alignment, + this.runAlignment, + this.crossAxisAlignment, + this.spacing, + this.runSpacing, }); + /// {@template ShadRadioGroup.initialValue} /// The initial value of the radio group. + /// {@endtemplate} final T? initialValue; + /// {@template ShadRadioGroup.items} /// The items of the radio group, any Widget can be used. + /// {@endtemplate} final Iterable items; + /// {@template ShadRadioGroup.onChanged} /// Called when the user toggles a radio on. + /// {@endtemplate} final ValueChanged? onChanged; + /// {@template ShadRadioGroup.enabled} /// Whether the radio [items] are enabled, defaults to true. + /// {@endtemplate} final bool enabled; + /// {@template ShadRadioGroup.axis} + /// The axis of the radio group, defaults to [Axis.vertical]. + /// {@endtemplate} + final Axis? axis; + + /// {@template ShadRadioGroup.spacing} + /// The main axis spacing of the radio group items, defaults to 4 + /// {@endtemplate} + final double? spacing; + + /// {@template ShadRadioGroup.runSpacing} + /// The cross axis spacing of the radio group items, defaults to 0 + /// {@endtemplate} + final double? runSpacing; + + /// {@template ShadRadioGroup.alignment} + /// The main axis alignment of the radio group items, defaults to + /// [WrapAlignment.start] + /// {@endtemplate} + final WrapAlignment? alignment; + + /// {@template ShadRadioGroup.runAlignment} + /// The cross axis alignment of the radio group items, defaults to + /// [WrapAlignment.start] + /// {@endtemplate} + final WrapAlignment? runAlignment; + + /// {@template ShadRadioGroup.crossAxisAlignment} + /// The cross axis alignment of the radio group items, defaults to + /// [WrapCrossAlignment.start] + /// {@endtemplate} + final WrapCrossAlignment? crossAxisAlignment; + @override State> createState() => ShadRadioGroupState(); @@ -64,11 +111,30 @@ class ShadRadioGroupState extends State> { @override Widget build(BuildContext context) { + final theme = ShadTheme.of(context); + + final effectiveAxis = widget.axis ?? theme.radioTheme.axis ?? Axis.vertical; + final effectiveSpacing = widget.spacing ?? theme.radioTheme.spacing ?? 4; + final effectiveRunSpacing = + widget.runSpacing ?? theme.radioTheme.runSpacing ?? 0; + final effectiveAlignment = + widget.alignment ?? theme.radioTheme.alignment ?? WrapAlignment.start; + final effectiveRunAlignment = widget.runAlignment ?? + theme.radioTheme.runAlignment ?? + WrapAlignment.start; + final effectiveWrapCrossAlignment = widget.crossAxisAlignment ?? + theme.radioTheme.crossAxisAlignment ?? + WrapCrossAlignment.start; + return ShadInheritedRadioGroupContainer( data: this, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: Wrap( + direction: effectiveAxis, + spacing: effectiveSpacing, + runSpacing: effectiveRunSpacing, + alignment: effectiveAlignment, + runAlignment: effectiveRunAlignment, + crossAxisAlignment: effectiveWrapCrossAlignment, children: widget.items.toList(), ), ); diff --git a/lib/src/theme/components/radio.dart b/lib/src/theme/components/radio.dart index 7c77fc81..df0c4d4c 100644 --- a/lib/src/theme/components/radio.dart +++ b/lib/src/theme/components/radio.dart @@ -14,6 +14,12 @@ class ShadRadioTheme { this.size, this.padding, this.circleSize, + this.axis, + this.spacing, + this.runSpacing, + this.alignment, + this.runAlignment, + this.crossAxisAlignment, }); final bool merge; @@ -30,6 +36,24 @@ class ShadRadioTheme { final double? circleSize; + /// {@macro ShadRadioGroup.axis} + final Axis? axis; + + /// {@macro ShadRadioGroup.spacing} + final double? spacing; + + /// {@macro ShadRadioGroup.runSpacing} + final double? runSpacing; + + /// {@macro ShadRadioGroup.alignment} + final WrapAlignment? alignment; + + /// {@macro ShadRadioGroup.runAlignment} + final WrapAlignment? runAlignment; + + /// {@macro ShadRadioGroup.crossAxisAlignment} + final WrapCrossAlignment? crossAxisAlignment; + static ShadRadioTheme lerp( ShadRadioTheme a, ShadRadioTheme b, @@ -44,6 +68,12 @@ class ShadRadioTheme { size: lerpDouble(a.size, b.size, t), padding: EdgeInsets.lerp(a.padding, b.padding, t), circleSize: lerpDouble(a.circleSize, b.circleSize, t), + axis: t < 0.5 ? a.axis : b.axis, + spacing: lerpDouble(a.spacing, b.spacing, t), + runSpacing: lerpDouble(a.runSpacing, b.runSpacing, t), + alignment: t < 0.5 ? a.alignment : b.alignment, + runAlignment: t < 0.5 ? a.runAlignment : b.runAlignment, + crossAxisAlignment: t < 0.5 ? a.crossAxisAlignment : b.crossAxisAlignment, ); } @@ -55,6 +85,12 @@ class ShadRadioTheme { ShadDecoration? decoration, EdgeInsets? padding, double? circleSize, + Axis? axis, + double? spacing, + double? runSpacing, + WrapAlignment? alignment, + WrapAlignment? runAlignment, + WrapCrossAlignment? crossAxisAlignment, }) { return ShadRadioTheme( merge: merge ?? this.merge, @@ -64,6 +100,12 @@ class ShadRadioTheme { color: color ?? this.color, padding: padding ?? this.padding, circleSize: circleSize ?? this.circleSize, + axis: axis ?? this.axis, + spacing: spacing ?? this.spacing, + runSpacing: runSpacing ?? this.runSpacing, + alignment: alignment ?? this.alignment, + runAlignment: runAlignment ?? this.runAlignment, + crossAxisAlignment: crossAxisAlignment ?? this.crossAxisAlignment, ); } @@ -77,6 +119,12 @@ class ShadRadioTheme { size: other.size, padding: other.padding, circleSize: other.circleSize, + axis: other.axis, + spacing: other.spacing, + runSpacing: other.runSpacing, + alignment: other.alignment, + runAlignment: other.runAlignment, + crossAxisAlignment: other.crossAxisAlignment, ); } @@ -91,7 +139,13 @@ class ShadRadioTheme { other.duration == duration && other.decoration == decoration && other.padding == padding && - other.circleSize == circleSize; + other.circleSize == circleSize && + other.axis == axis && + other.spacing == spacing && + other.runSpacing == runSpacing && + other.alignment == alignment && + other.runAlignment == runAlignment && + other.crossAxisAlignment == crossAxisAlignment; } @override @@ -102,6 +156,12 @@ class ShadRadioTheme { duration.hashCode ^ decoration.hashCode ^ padding.hashCode ^ - circleSize.hashCode; + circleSize.hashCode ^ + axis.hashCode ^ + spacing.hashCode ^ + runSpacing.hashCode ^ + alignment.hashCode ^ + runAlignment.hashCode ^ + crossAxisAlignment.hashCode; } } diff --git a/lib/src/theme/themes/default_theme_no_secondary_border_variant.dart b/lib/src/theme/themes/default_theme_no_secondary_border_variant.dart index b13888fe..19a7effb 100644 --- a/lib/src/theme/themes/default_theme_no_secondary_border_variant.dart +++ b/lib/src/theme/themes/default_theme_no_secondary_border_variant.dart @@ -450,6 +450,11 @@ class ShadDefaultThemeNoSecondaryBorderVariant extends ShadThemeVariant { ), focusedBorder: ShadBorder.all(radius: radius.add(radius / 2), width: 2), ), + spacing: 4, + alignment: WrapAlignment.start, + runAlignment: WrapAlignment.start, + crossAxisAlignment: WrapCrossAlignment.start, + axis: Axis.vertical, ); } diff --git a/lib/src/theme/themes/default_theme_variant.dart b/lib/src/theme/themes/default_theme_variant.dart index 734ed470..c05f16d3 100644 --- a/lib/src/theme/themes/default_theme_variant.dart +++ b/lib/src/theme/themes/default_theme_variant.dart @@ -422,6 +422,11 @@ class ShadDefaultThemeVariant extends ShadThemeVariant { padding: const EdgeInsets.all(2), ), ), + spacing: 4, + alignment: WrapAlignment.start, + runAlignment: WrapAlignment.start, + crossAxisAlignment: WrapCrossAlignment.start, + axis: Axis.vertical, ); } diff --git a/pubspec.yaml b/pubspec.yaml index 18ba820e..c60902c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: shadcn_ui description: shadcn-ui ported in Flutter. Awesome UI components for Flutter, fully customizable. -version: 0.11.1 +version: 0.12.0 homepage: https://mariuti.com/shadcn-ui repository: https://github.com/nank1ro/flutter-shadcn-ui documentation: https://mariuti.com/shadcn-ui