Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
## Unreleased

### New

- `SignatureNode` (`signature`), a draw-to-sign pad. Its value is the list
of strokes drawn (each a list of `[x, y]` points), bindable through
`variables.value` and settable with a set value action; `changed` fires
when a stroke ends. Properties: ink color and width, background, border
and error border, corner radius, placeholder, sign line, and bindable
`error` and `enabled`.
- `BaseNode.loopAnimation` (`LoopAnimation`: pulse, fade, scale or spin,
with duration, delay, reverse, curve and from/to scale, opacity or
turns), on every node type and left out of the JSON when null.
`loopAnimationEnabled` can be bound to turn it on and off.
- Nodes with a click trigger also offer `cursorEnter` and `cursorExit`;
the trigger docs say what `hover`, `cursorEnter` and `cursorExit` mean.
- `DialogPresentation.sideSheet`, and `ShowDialogAction.sheetWidth`,
`maxHeightFactor` (1: no cap) and `showDragHandle` (false) for sheets,
so saved bottom sheets look as before.
`copyWith` keeps `nonBlocking` and `enabled`.
- `ConfirmAction.presentation`, `sheetWidth`, `maxHeightFactor` and
`showDragHandle`, as on `ShowDialogAction`.
- `ShowToastAction.accentColor`, `accentWidth` (4), `iconColor`,
`fontFamily` and `cornerRadius`.
- `FrameNode.contentFit` (a `Fit`, null for none) and `contentAlignment`
(center).
- `TextFieldNode.propertyVariables` lists `errorText` and `error`.
- All new fields are left out of the JSON at their defaults.
- `GridDelegateProperties.shrinkWrapRows`: each row of a grid is as tall
as its tallest item (like a `Row` in an `IntrinsicHeight`) instead of a
fixed `mainAxisExtent` or `childAspectRatio`. Default false, left out of
the JSON.

### Fixes

- `SpacerNode.fromJson` defaults `positioningMode` (align),
`aspectRatioLock` (false) and `reactions` ([]) like every other node, and
`GridViewNode.fromJson` defaults `isScrollable` (true) and
`useFlutterListView` (false). Both still write those keys for older
readers.

## 6.2.0

### Layout
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ or image texture.
- `PaintModel`: Defines the style properties such as the type of paint (`type`), its visibility (`visible`), and its
opacity (`opacity`), among others. Depending on the type of paint, it might have properties like color (`color`),
gradient transform (`gradientTransform`), gradient stops (`gradientStops`), or image transform (`imageTransform`).
A gradient can repeat past its ends (`tileMode`) over a set length in pixels (`gradientExtent`), which makes stripes.

### Flutter parity

Expand Down
37 changes: 37 additions & 0 deletions lib/src/api/models/action/confirm_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ part 'confirm_action.g.dart';
/// back" action whose params hold [resultKey]: `true` confirms, anything else
/// cancels. Closing the dialog any other way cancels. The params popped with a
/// confirm are the `${result}` the [actions] read.
///
/// Either dialog can be presented as a centered dialog, a bottom sheet or a
/// side sheet ([presentation]), like [ShowDialogAction.presentation].
@JsonSerializable()
class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
/// The dialog's title. Supports variables and formulas.
Expand Down Expand Up @@ -71,6 +74,23 @@ class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
/// Corner radius of the built-in dialog. Null follows the app's buttons.
final double? cornerRadius;

/// How the dialog is presented: centered, as a bottom sheet or as a side
/// sheet. See [ShowDialogAction.presentation].
@JsonKey(unknownEnumValue: DialogPresentation.dialog)
final DialogPresentation presentation;

/// Width of a [DialogPresentation.sideSheet], in logical pixels. Null takes
/// the [dialogId] canvas's width, or 400 for the built-in dialog.
final double? sheetWidth;

/// The most of the screen's height a [DialogPresentation.bottomSheet] takes,
/// from 0 to 1.
final double maxHeightFactor;

/// Whether a [DialogPresentation.bottomSheet] shows a grab handle at its
/// top.
final bool showDragHandle;

/// The key of the "Navigate back" params that answers a [dialogId] dialog.
static const String resultKey = 'confirmed';

Expand Down Expand Up @@ -107,6 +127,10 @@ class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
this.textColor,
this.confirmColor,
this.cornerRadius,
this.presentation = DialogPresentation.dialog,
this.sheetWidth,
this.maxHeightFactor = 1,
this.showDragHandle = false,
super.nonBlocking,
super.enabled,
}) : actions = actions ?? [],
Expand Down Expand Up @@ -137,6 +161,11 @@ class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
bool clearConfirmColor = false,
double? cornerRadius,
bool clearCornerRadius = false,
DialogPresentation? presentation,
double? sheetWidth,
bool clearSheetWidth = false,
double? maxHeightFactor,
bool? showDragHandle,
}) => ConfirmAction(
title: title ?? this.title,
message: message ?? this.message,
Expand All @@ -155,6 +184,10 @@ class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
textColor: clearTextColor ? null : textColor ?? this.textColor,
confirmColor: clearConfirmColor ? null : confirmColor ?? this.confirmColor,
cornerRadius: clearCornerRadius ? null : cornerRadius ?? this.cornerRadius,
presentation: presentation ?? this.presentation,
sheetWidth: clearSheetWidth ? null : sheetWidth ?? this.sheetWidth,
maxHeightFactor: maxHeightFactor ?? this.maxHeightFactor,
showDragHandle: showDragHandle ?? this.showDragHandle,
nonBlocking: nonBlocking,
enabled: enabled,
);
Expand All @@ -176,6 +209,10 @@ class ConfirmAction extends ActionModel with Equatable, SerializableMixin {
textColor,
confirmColor,
cornerRadius,
presentation,
sheetWidth,
maxHeightFactor,
showDragHandle,
];

/// Creates an instance from a JSON object.
Expand Down
27 changes: 27 additions & 0 deletions lib/src/api/models/action/confirm_action.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 41 additions & 1 deletion lib/src/api/models/action/show_dialog_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import '../models.dart';

part 'show_dialog_action.g.dart';

/// An action that navigates to a new page.
/// An action that shows a canvas over the current page, as a dialog, a
/// bottom sheet or a side sheet (see [presentation]). A "Navigate back"
/// action in the canvas closes it.
@JsonSerializable()
class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
/// Destination canvas node's ID.
Expand All @@ -33,6 +35,17 @@ class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
/// default. Bottom sheets always sit at the bottom.
final AlignmentModel alignment;

/// Width of a [DialogPresentation.sideSheet], in logical pixels. Null takes
/// the destination canvas's width.
final double? sheetWidth;

/// The most of the screen's height a bottom sheet takes, from 0 to 1. A
/// taller canvas scrolls within it.
final double maxHeightFactor;

/// Whether a bottom sheet shows a grab handle at its top.
final bool showDragHandle;

/// Creates a new [ShowDialogAction].
ShowDialogAction({
required this.destinationId,
Expand All @@ -42,6 +55,9 @@ class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
this.showCloseButton = false,
this.presentation = DialogPresentation.dialog,
this.alignment = AlignmentModel.center,
this.sheetWidth,
this.maxHeightFactor = 1,
this.showDragHandle = false,
super.nonBlocking,
super.enabled,
}) : params = {...params ?? {}},
Expand All @@ -56,6 +72,9 @@ class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
showCloseButton,
presentation,
alignment,
sheetWidth,
maxHeightFactor,
showDragHandle,
];

/// Duplicates this [ShowDialogAction] with given data overrides.
Expand All @@ -67,6 +86,10 @@ class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
bool? showCloseButton,
DialogPresentation? presentation,
AlignmentModel? alignment,
double? sheetWidth,
bool clearSheetWidth = false,
double? maxHeightFactor,
bool? showDragHandle,
}) => ShowDialogAction(
destinationId: destinationId ?? this.destinationId,
params: {...this.params, ...params ?? {}},
Expand All @@ -75,6 +98,11 @@ class ShowDialogAction extends ActionModel with Equatable, SerializableMixin {
showCloseButton: showCloseButton ?? this.showCloseButton,
presentation: presentation ?? this.presentation,
alignment: alignment ?? this.alignment,
sheetWidth: clearSheetWidth ? null : sheetWidth ?? this.sheetWidth,
maxHeightFactor: maxHeightFactor ?? this.maxHeightFactor,
showDragHandle: showDragHandle ?? this.showDragHandle,
nonBlocking: nonBlocking,
enabled: enabled,
);

/// Creates a new [ShowDialogAction] instance from a JSON data.
Expand All @@ -99,4 +127,16 @@ enum DialogPresentation {

/// A bottom sheet on phones (narrower than 600 px), a dialog otherwise.
adaptive,

/// Anchored to the right edge, as tall as the screen and
/// [ShowDialogAction.sheetWidth] wide. Slides in from the right.
sideSheet;

/// Displayable name.
String get prettify => switch (this) {
DialogPresentation.dialog => 'Dialog',
DialogPresentation.bottomSheet => 'Bottom Sheet',
DialogPresentation.adaptive => 'Adaptive',
DialogPresentation.sideSheet => 'Side Sheet',
};
}
11 changes: 11 additions & 0 deletions lib/src/api/models/action/show_dialog_action.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 45 additions & 1 deletion lib/src/api/models/action/show_toast_action.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ enum ToastPosition {
/// [actions].
///
/// Its colors come from [style] and the app's theme unless [backgroundColor]
/// or [textColor] are set. Its font is the app's.
/// or [textColor] are set. Its font is the app's unless [fontFamily] is set.
/// An [accentColor] draws a bar down its left edge, and [iconColor] colors
/// its [icon].
@JsonSerializable()
class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
/// The message. Supports variables and formulas, e.g.
Expand Down Expand Up @@ -91,6 +93,24 @@ class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
/// [ToastPosition.bottom].
final double bottomOffset;

/// Color of a bar down the toast's left edge, e.g. a yellow or red accent.
/// Null draws no bar.
final ColorRGBA? accentColor;

/// Width of the [accentColor] bar.
final double accentWidth;

/// Color of the [icon]. Null takes the message color.
final ColorRGBA? iconColor;

/// Font family of the message and button, e.g. `Barlow`. Null takes the
/// app's font.
final String? fontFamily;

/// Corner radius of the toast. Null makes a pill, or follows the app's
/// buttons when the toast has a button.
final double? cornerRadius;

/// Creates a new [ShowToastAction].
ShowToastAction({
required this.message,
Expand All @@ -103,6 +123,11 @@ class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
List<ActionModel>? actions,
this.icon,
this.bottomOffset = 104,
this.accentColor,
this.accentWidth = 4,
this.iconColor,
this.fontFamily,
this.cornerRadius,
super.nonBlocking,
super.enabled,
}) : actions = actions ?? [],
Expand All @@ -123,6 +148,11 @@ class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
actions,
icon,
bottomOffset,
accentColor,
accentWidth,
iconColor,
fontFamily,
cornerRadius,
];

/// Duplicates this [ShowToastAction] with given data overrides.
Expand All @@ -140,6 +170,15 @@ class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
MultiSourceIconModel? icon,
bool clearIcon = false,
double? bottomOffset,
ColorRGBA? accentColor,
bool clearAccentColor = false,
double? accentWidth,
ColorRGBA? iconColor,
bool clearIconColor = false,
String? fontFamily,
bool clearFontFamily = false,
double? cornerRadius,
bool clearCornerRadius = false,
}) => ShowToastAction(
message: message ?? this.message,
duration: duration ?? this.duration,
Expand All @@ -153,6 +192,11 @@ class ShowToastAction extends ActionModel with Equatable, SerializableMixin {
actions: actions ?? this.actions,
icon: clearIcon ? null : icon ?? this.icon,
bottomOffset: bottomOffset ?? this.bottomOffset,
accentColor: clearAccentColor ? null : accentColor ?? this.accentColor,
accentWidth: accentWidth ?? this.accentWidth,
iconColor: clearIconColor ? null : iconColor ?? this.iconColor,
fontFamily: clearFontFamily ? null : fontFamily ?? this.fontFamily,
cornerRadius: clearCornerRadius ? null : cornerRadius ?? this.cornerRadius,
nonBlocking: nonBlocking,
enabled: enabled,
);
Expand Down
Loading
Loading