Skip to content

Commit

Permalink
Feat/order policy (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro authored Jan 7, 2025
1 parent 9149883 commit 20672ee
Show file tree
Hide file tree
Showing 23 changed files with 414 additions and 74 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## 0.17.5

-**FEAT**: Add `placeSelectedIconFirst` to `ShadOption`, defaults to `true`.
- **FEAT**: New `OrderPolicy`, `LinearOrderPolicy`, `ReverseOrderPolicy` and `CustomOrderPolicy` to update the order policy of the items in a list, this can be very useful to arrange the order of the parts of the shadcn components.
- **FEAT**: Add `orderPolicy` to `ShadOption`, `ShadAlert`, `ShadButton`, `ShadCheckbox`, `ShadCheckboxFormField`, `ShadDatePicker`, `ShadDatePickerFormField`, `ShadDateRangePickerFormField`, `ShadRadio`, `ShadSwitch`, `ShadSwitchFormField`, `ShadToast`.
- **FEAT**: Add `expands` to `ShadButton`, defaults to false. Use it if you want the button's child to expand to fill the available space.

## 0.17.4

Expand Down
1 change: 1 addition & 0 deletions lib/shadcn_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export 'src/utils/effects.dart';
export 'src/utils/extensions/breakpoints.dart';
export 'src/utils/extensions/date_time.dart';
export 'src/utils/extensions/duration.dart';
export 'src/utils/extensions/order_policy.dart';
export 'src/utils/gesture_detector.dart';
export 'src/utils/mouse_area.dart';
export 'src/utils/position.dart';
Expand Down
18 changes: 16 additions & 2 deletions lib/src/components/alert.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:shadcn_ui/src/components/image.dart';
import 'package:shadcn_ui/src/theme/components/decorator.dart';
import 'package:shadcn_ui/src/theme/theme.dart';
import 'package:shadcn_ui/src/utils/border.dart';
import 'package:shadcn_ui/src/utils/extensions/order_policy.dart';

enum ShadAlertVariant {
primary,
Expand All @@ -25,6 +26,7 @@ class ShadAlert extends StatelessWidget {
this.descriptionStyle,
this.mainAxisAlignment,
this.crossAxisAlignment,
this.orderPolicy,
}) : variant = ShadAlertVariant.primary;

const ShadAlert.destructive({
Expand All @@ -42,6 +44,7 @@ class ShadAlert extends StatelessWidget {
this.descriptionStyle,
this.mainAxisAlignment,
this.crossAxisAlignment,
this.orderPolicy,
}) : variant = ShadAlertVariant.destructive;

const ShadAlert.raw({
Expand All @@ -60,6 +63,7 @@ class ShadAlert extends StatelessWidget {
this.descriptionStyle,
this.mainAxisAlignment,
this.crossAxisAlignment,
this.orderPolicy,
});

final ShadAlertVariant variant;
Expand All @@ -77,6 +81,12 @@ class ShadAlert extends StatelessWidget {
final MainAxisAlignment? mainAxisAlignment;
final CrossAxisAlignment? crossAxisAlignment;

/// {@template ShadAlert.orderPolicy}
/// The order policy of the items that compose the alert, defaults to
/// [WidgetOrderPolicy.linear()].
/// {@endtemplate}
final WidgetOrderPolicy? orderPolicy;

@override
Widget build(BuildContext context) {
final theme = ShadTheme.of(context);
Expand Down Expand Up @@ -142,6 +152,10 @@ class ShadAlert extends StatelessWidget {
effectiveAlertTheme.crossAxisAlignment ??
CrossAxisAlignment.start;

final effectiveOrderPolicy = orderPolicy ??
effectiveAlertTheme.orderPolicy ??
const WidgetOrderPolicy.linear();

return ShadDecorator(
decoration: effectiveDecoration,
child: Row(
Expand All @@ -150,7 +164,7 @@ class ShadAlert extends StatelessWidget {
textDirection: textDirection,
children: [
if (effectiveIcon != null) effectiveIcon,
Flexible(
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
Expand All @@ -168,7 +182,7 @@ class ShadAlert extends StatelessWidget {
],
),
),
],
].order(effectiveOrderPolicy),
),
);
}
Expand Down
81 changes: 62 additions & 19 deletions lib/src/components/button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:shadcn_ui/src/theme/components/decorator.dart';
import 'package:shadcn_ui/src/theme/data.dart';
import 'package:shadcn_ui/src/theme/theme.dart';
import 'package:shadcn_ui/src/utils/debug_check.dart';
import 'package:shadcn_ui/src/utils/extensions/order_policy.dart';
import 'package:shadcn_ui/src/utils/gesture_detector.dart';
import 'package:shadcn_ui/src/utils/separated_iterable.dart';
import 'package:shadcn_ui/src/utils/states_controller.dart';
Expand Down Expand Up @@ -76,6 +77,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.primary;

const ShadButton.raw({
Expand Down Expand Up @@ -128,6 +131,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
});

const ShadButton.destructive({
Expand Down Expand Up @@ -179,6 +184,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.destructive;

const ShadButton.outline({
Expand Down Expand Up @@ -230,6 +237,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.outline;

const ShadButton.secondary({
Expand Down Expand Up @@ -281,6 +290,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.secondary;

const ShadButton.ghost({
Expand Down Expand Up @@ -332,6 +343,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.ghost;

const ShadButton.link({
Expand Down Expand Up @@ -382,6 +395,8 @@ class ShadButton extends StatefulWidget {
this.textDirection,
this.gap,
this.onFocusChange,
this.orderPolicy,
this.expands,
}) : variant = ShadButtonVariant.link,
icon = null;

Expand Down Expand Up @@ -412,6 +427,12 @@ class ShadButton extends StatefulWidget {
final bool enabled;
final ShadStatesController? statesController;

/// {@template ShadButton.orderPolicy}
/// The order policy of the items that compose the button, defaults to
/// [WidgetOrderPolicy.linear()].
/// {@endtemplate}
final WidgetOrderPolicy? orderPolicy;

/// {@template ShadButton.gap}
/// The gap between the icon and the text.
///
Expand Down Expand Up @@ -453,6 +474,11 @@ class ShadButton extends StatefulWidget {
final TextDirection? textDirection;
final ValueChanged<bool>? onFocusChange;

/// {@template ShadButton.expands}
/// Whether the child expands to fill the available space, defaults to false.
/// {@endtemplate}
final bool? expands;

@override
State<ShadButton> createState() => _ShadButtonState();
}
Expand Down Expand Up @@ -708,6 +734,13 @@ class _ShadButtonState extends State<ShadButton> {

final effectiveGap = widget.gap ?? buttonTheme(theme).gap ?? 8;

final effectiveOrderPolicy = widget.orderPolicy ??
buttonTheme(theme).orderPolicy ??
const WidgetOrderPolicy.linear();

final effectiveExpands =
widget.expands ?? buttonTheme(theme).expands ?? false;

return CallbackShortcuts(
bindings: {
const SingleActivator(LogicalKeyboardKey.enter): onTap,
Expand Down Expand Up @@ -744,6 +777,31 @@ class _ShadButtonState extends State<ShadButton> {
child: icon,
);
}

Widget? child = widget.child == null
? null
: DefaultTextStyle(
style: theme.textTheme.small.copyWith(
color: hasPressedForegroundColor && pressed
? pressedForegroundColor(theme)
: hovered
? hoverForeground(theme)
: foreground(theme),
decoration: textDecoration(
theme,
hovered: hovered,
),
decorationColor: foreground(theme),
decorationStyle: TextDecorationStyle.solid,
),
textAlign: TextAlign.center,
child: widget.child!,
);

if (child != null && effectiveExpands) {
child = Expanded(child: child);
}

return Semantics(
container: true,
button: true,
Expand Down Expand Up @@ -815,25 +873,10 @@ class _ShadButtonState extends State<ShadButton> {
textDirection: effectiveTextDirection,
children: [
if (icon != null) icon,
if (widget.child != null)
DefaultTextStyle(
style: theme.textTheme.small.copyWith(
color: hasPressedForegroundColor && pressed
? pressedForegroundColor(theme)
: hovered
? hoverForeground(theme)
: foreground(theme),
decoration: textDecoration(
theme,
hovered: hovered,
),
decorationColor: foreground(theme),
decorationStyle: TextDecorationStyle.solid,
),
textAlign: TextAlign.center,
child: widget.child!,
),
].separatedBy(SizedBox(width: effectiveGap)),
if (child != null) child,
]
.order(effectiveOrderPolicy)
.separatedBy(SizedBox(width: effectiveGap)),
),
),
),
Expand Down
14 changes: 13 additions & 1 deletion lib/src/components/checkbox.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:shadcn_ui/src/raw_components/focusable.dart';
import 'package:shadcn_ui/src/theme/components/decorator.dart';
import 'package:shadcn_ui/src/theme/theme.dart';
import 'package:shadcn_ui/src/utils/debug_check.dart';
import 'package:shadcn_ui/src/utils/extensions/order_policy.dart';

class ShadCheckbox extends StatefulWidget {
const ShadCheckbox({
Expand All @@ -26,6 +27,7 @@ class ShadCheckbox extends StatefulWidget {
this.padding,
this.direction,
this.crossAxisAlignment,
this.orderPolicy,
});

/// Whether the checkbox is on or off.
Expand Down Expand Up @@ -76,6 +78,12 @@ class ShadCheckbox extends StatefulWidget {
/// {@endtemplate}
final CrossAxisAlignment? crossAxisAlignment;

/// {@template ShadCheckbox.orderPolicy}
/// The order policy of the items that compose the checkbox, defaults to
/// [WidgetOrderPolicy.linear()].
/// {@endtemplate}
final WidgetOrderPolicy? orderPolicy;

@override
State<ShadCheckbox> createState() => _ShadCheckboxState();
}
Expand Down Expand Up @@ -134,6 +142,10 @@ class _ShadCheckboxState extends State<ShadCheckbox> {
theme.checkboxTheme.padding ??
const EdgeInsets.only(left: 8);

final effectiveOrderPolicy = widget.orderPolicy ??
theme.checkboxTheme.orderPolicy ??
const WidgetOrderPolicy.linear();

final checkbox = Semantics(
checked: widget.value,
child: ShadDisabled(
Expand Down Expand Up @@ -225,7 +237,7 @@ class _ShadCheckboxState extends State<ShadCheckbox> {
),
),
),
],
].order(effectiveOrderPolicy),
),
),
);
Expand Down
22 changes: 22 additions & 0 deletions lib/src/components/date_picker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:shadcn_ui/src/raw_components/portal.dart';
import 'package:shadcn_ui/src/theme/components/decorator.dart';
import 'package:shadcn_ui/src/theme/theme.dart';
import 'package:shadcn_ui/src/utils/extensions/date_time.dart';
import 'package:shadcn_ui/src/utils/extensions/order_policy.dart';
import 'package:shadcn_ui/src/utils/gesture_detector.dart';
import 'package:shadcn_ui/src/utils/states_controller.dart';

Expand Down Expand Up @@ -155,6 +156,8 @@ class ShadDatePicker extends StatefulWidget {
this.textDirection,
this.onFocusChange,
this.iconSrc,
this.orderPolicy,
this.expands,
}) : variant = ShadDatePickerVariant.single,
formatDateRange = null,
selectedRange = null;
Expand Down Expand Up @@ -295,6 +298,8 @@ class ShadDatePicker extends StatefulWidget {
this.textDirection,
this.onFocusChange,
this.iconSrc,
this.orderPolicy,
this.expands,
}) : variant = ShadDatePickerVariant.range,
selected = null,
formatDate = null,
Expand Down Expand Up @@ -439,6 +444,8 @@ class ShadDatePicker extends StatefulWidget {
this.iconSrc,
this.formatDateRange,
this.placeholder,
this.orderPolicy,
this.expands,
});

/// {@template ShadDatePicker.placeholder}
Expand Down Expand Up @@ -888,6 +895,12 @@ class ShadDatePicker extends StatefulWidget {
/// {@macro ShadButton.onFocusChange}
final ValueChanged<bool>? onFocusChange;

/// {@macro ShadButton.orderPolicy}
final WidgetOrderPolicy? orderPolicy;

/// {@macro ShadButton.expands}
final bool? expands;

@override
State<ShadDatePicker> createState() => _ShadDatePickerState();
}
Expand Down Expand Up @@ -970,6 +983,13 @@ class _ShadDatePickerState extends State<ShadDatePicker> {
theme.datePickerTheme.calendarDecoration ??
ShadDecoration.none;

final effectiveOrderPolicy = widget.orderPolicy ??
theme.datePickerTheme.orderPolicy ??
const WidgetOrderPolicy.linear();

final effectiveExpands =
widget.expands ?? theme.datePickerTheme.expands ?? false;

return ShadPopover(
controller: popoverController,
groupId: widget.groupId,
Expand Down Expand Up @@ -1209,6 +1229,8 @@ class _ShadDatePickerState extends State<ShadDatePicker> {
hoverStrategies:
widget.hoverStrategies ?? theme.datePickerTheme.hoverStrategies,
textDirection: widget.textDirection,
orderPolicy: effectiveOrderPolicy,
expands: effectiveExpands,
child: widget.buttonChild ??
(isSelected
? Text(
Expand Down
Loading

0 comments on commit 20672ee

Please sign in to comment.