Skip to content

Commit 549fa2b

Browse files
authored
Add secondary tap & fix various issues with FSelect (#612)
* Add secondary press to FTappable * Add secondary press to FButton * Add secondary press to header, item & tile * Fix various issues with FSelect * Change shown getter to status field * Prepare Forui for review * Remove redundant test --------- Co-authored-by: Pante <[email protected]>
1 parent 9fac003 commit 549fa2b

File tree

26 files changed

+559
-124
lines changed

26 files changed

+559
-124
lines changed

docs/app/docs/form/button/page.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ FButton(
4242
style: FButtonStyle(...),
4343
mainAxisSize: MainAxisSize.min,
4444
onPress: () {},
45+
onSecondaryPress: () {},
46+
onSecondaryLongPress: () {},
4547
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
4648
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
4749
child: const Text('Button'),
@@ -54,6 +56,8 @@ FButton(
5456
FButton.raw(
5557
style: FButtonStyle(...),
5658
onPress: () {},
59+
onSecondaryPress: () {},
60+
onSecondaryLongPress: () {},
5761
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
5862
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
5963
child: const Text('Button'),

docs/app/docs/foundation/tappable/page.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ const FTappable(
6060
behavior: HitTestBehavior.translucent,
6161
onPress: () {},
6262
onLongPress: () {},
63+
onSecondaryPress: () {},
64+
onSecondaryLongPress: () {},
6365
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
6466
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
6567
builder: (context, state, child) => child!,
@@ -85,6 +87,8 @@ FTappable.static(
8587
behavior: HitTestBehavior.translucent,
8688
onPress: () {},
8789
onLongPress: () {},
90+
onSecondaryPress: () {},
91+
onSecondaryLongPress: () {},
8892
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
8993
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
9094
builder: (context, state, child) => child!,

docs/app/docs/overlay/persistent-sheet/page.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ It is part of [FScaffold](/docs/layout/scaffold), which should be preferred in m
4040
Widget build(BuildContext context) {
4141
VoidCallback onPress(FLayout side) => () {
4242
for (final MapEntry(:key, :value) in _controllers.entries) {
43-
if (key != side && value.shown) {
43+
if (key != side && value.status.isCompleted) {
4444
return;
4545
}
4646
}
@@ -210,7 +210,7 @@ showFPersistentSheet(
210210
Widget build(BuildContext context) {
211211
VoidCallback onPress(FLayout side) => () {
212212
for (final MapEntry(:key, :value) in _controllers.entries) {
213-
if (key != side && value.shown) {
213+
if (key != side && value.status.isCompleted) {
214214
return;
215215
}
216216
}

docs/app/docs/tile/tile/page.mdx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ FTile(
6060
onStateChange: (states) {},
6161
onPress: () {},
6262
onLongPress: () {},
63+
onSecondaryPress: () {},
64+
onSecondaryLongPress: () {},
6365
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
6466
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
6567
);
@@ -80,6 +82,8 @@ FTile.raw(
8082
onStateChange: (states) {},
8183
onPress: () {},
8284
onLongPress: () {},
85+
onSecondaryPress: () {},
86+
onSecondaryLongPress: () {},
8387
shortcuts: { SingleActivator(LogicalKeyboardKey.enter): ActivateIntent() },
8488
actions: { ActivateIntent: CallbackAction<ActivateIntent>(onInvoke: (_) {}) },
8589
);

forui/CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,39 @@
1+
## 0.14.0 (Next)
2+
3+
### `FButton`
4+
* Add `FButton.onSecondaryPress`.
5+
* Add `FButton.onSecondaryLongPress`.
6+
7+
8+
### `FHeaderAction`
9+
* Add `FHeaderAction.onSecondaryPress`.
10+
* Add `FHeaderAction.onSecondaryLongPress`.
11+
* Add `FHeaderAction.actions`.
12+
* Add `FHeaderAction.shortcuts`.
13+
14+
15+
### `FSelect`
16+
* Fix `FSelect` flickering when selecting an item on desktop.
17+
* Fix `FSelect` not scrolling to selected item when opened if the item is really far down the list.
18+
* Fix `FSelect` layout shifting when scrolling through a long list of items.
19+
20+
21+
### `FTappable`
22+
* Add `FTappable.onSecondaryPress`.
23+
* Add `FTappable.onSecondaryLongPress`.
24+
25+
26+
### `FTile`
27+
* Add `FTile.onSecondaryPress`.
28+
* Add `FTile.onSecondaryLongPress`.
29+
30+
31+
### Others
32+
* **Breaking** Change `FPersistentSheetController.shown` to `FPersistentSheetController.status`.
33+
* **Breaking** Change `FPopoverController.shown` to `FPopoverController.status`.
34+
* **Breaking** Change `FTooltipController.shown` to `FTooltipController.status`.
35+
36+
137
## 0.13.1
238

339
* Fix `FSelectTile` mixing in `FItemMixin` instead of `FTileMixin`.

forui/example/lib/sandbox.dart

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,6 @@ class _SandboxState extends State<Sandbox> with SingleTickerProviderStateMixin {
2525

2626
@override
2727
Widget build(BuildContext context) {
28-
return Column(
29-
spacing: 10,
30-
children: [
31-
FTileGroup.merge(
32-
children: [
33-
FTileGroup(
34-
style: FThemes.green.dark.tileGroupStyle,
35-
children: [
36-
FTile(
37-
prefix: const Icon(FIcons.wifi),
38-
title: const Text('WiFi'),
39-
details: const Text('FL (5G)'),
40-
suffix: const Icon(FIcons.chevronRight),
41-
onPress: () {},
42-
),
43-
FTile(
44-
prefix: const Icon(FIcons.bluetooth),
45-
title: const Text('Bluetooth'),
46-
subtitle: const Text('Fee, Fo'),
47-
details: const Text('FL (5G)'),
48-
suffix: const Icon(FIcons.chevronRight),
49-
),
50-
],
51-
),
52-
],
53-
),
54-
],
55-
);
28+
return Material(child: Column(spacing: 10, children: const [TextField(), FTimeField.picker(), TextField()]));
5629
}
5730
}

forui/lib/src/foundation/tappable.dart

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,47 @@ class FTappable extends StatefulWidget {
8686
/// {@template forui.foundation.FTappable.onPress}
8787
/// A callback for when the widget is pressed.
8888
///
89-
/// The widget will be disabled if both [onPress] and [onLongPress] are null.
89+
/// The widget will be disabled if the following are null:
90+
/// * [onPress]
91+
/// * [onLongPress]
92+
/// * [onSecondaryPress]
93+
/// * [onSecondaryLongPress]
9094
/// {@endtemplate}
9195
final VoidCallback? onPress;
9296

9397
/// {@template forui.foundation.FTappable.onLongPress}
9498
/// A callback for when the widget is long pressed.
9599
///
96-
/// The widget will be disabled if both [onPress] and [onLongPress] are null.
100+
/// The widget will be disabled if the following are null:
101+
/// * [onPress]
102+
/// * [onLongPress]
103+
/// * [onSecondaryPress]
104+
/// * [onSecondaryLongPress]
97105
/// {@endtemplate}
98106
final VoidCallback? onLongPress;
99107

108+
/// {@template forui.foundation.FTappable.onSecondaryPress}
109+
/// A callback for when the widget is pressed with a secondary button (usually right-click on desktop).
110+
///
111+
/// The widget will be disabled if the following are null:
112+
/// * [onPress]
113+
/// * [onLongPress]
114+
/// * [onSecondaryPress]
115+
/// * [onSecondaryLongPress]
116+
/// {@endtemplate}
117+
final VoidCallback? onSecondaryPress;
118+
119+
/// {@template forui.foundation.FTappable.onSecondaryLongPress}
120+
/// A callback for when the widget is pressed with a secondary button (usually right-click on desktop).
121+
///
122+
/// The widget will be disabled if the following are null:
123+
/// * [onPress]
124+
/// * [onLongPress]
125+
/// * [onSecondaryPress]
126+
/// * [onSecondaryLongPress]
127+
/// {@endtemplate}
128+
final VoidCallback? onSecondaryLongPress;
129+
100130
/// {@template forui.foundation.FTappable.shortcuts}
101131
/// The shortcuts. Defaults to calling [ActivateIntent] if [onPress] is not null.
102132
/// {@endtemplate}
@@ -136,6 +166,8 @@ class FTappable extends StatefulWidget {
136166
HitTestBehavior behavior,
137167
VoidCallback? onPress,
138168
VoidCallback? onLongPress,
169+
VoidCallback? onSecondaryPress,
170+
VoidCallback? onSecondaryLongPress,
139171
Map<ShortcutActivator, Intent>? shortcuts,
140172
Map<Type, Action<Intent>>? actions,
141173
ValueWidgetBuilder<Set<WidgetState>> builder,
@@ -161,6 +193,8 @@ class FTappable extends StatefulWidget {
161193
this.behavior = HitTestBehavior.translucent,
162194
this.onPress,
163195
this.onLongPress,
196+
this.onSecondaryPress,
197+
this.onSecondaryLongPress,
164198
this.actions,
165199
this.builder = _builder,
166200
this.child,
@@ -191,12 +225,15 @@ class FTappable extends StatefulWidget {
191225
..add(EnumProperty('behavior', behavior))
192226
..add(ObjectFlagProperty.has('onPress', onPress))
193227
..add(ObjectFlagProperty.has('onLongPress', onLongPress))
228+
..add(ObjectFlagProperty.has('onSecondaryPress', onSecondaryPress))
229+
..add(ObjectFlagProperty.has('onSecondaryLongPress', onSecondaryLongPress))
194230
..add(DiagnosticsProperty('shortcuts', shortcuts))
195231
..add(DiagnosticsProperty('actions', actions))
196232
..add(ObjectFlagProperty.has('builder', builder));
197233
}
198234

199-
bool get _disabled => onPress == null && onLongPress == null;
235+
bool get _disabled =>
236+
onPress == null && onLongPress == null && onSecondaryPress == null && onSecondaryLongPress == null;
200237
}
201238

202239
class _FTappableState<T extends FTappable> extends State<T> {
@@ -311,6 +348,8 @@ class _FTappableState<T extends FTappable> extends State<T> {
311348
behavior: widget.behavior,
312349
onTap: widget.onPress,
313350
onLongPress: widget.onLongPress,
351+
onSecondaryTap: widget.onSecondaryPress,
352+
onSecondaryLongPress: widget.onSecondaryLongPress,
314353
child: tappable,
315354
),
316355
),
@@ -354,6 +393,8 @@ class AnimatedTappable extends FTappable {
354393
super.behavior,
355394
super.onPress,
356395
super.onLongPress,
396+
super.onSecondaryPress,
397+
super.onSecondaryLongPress,
357398
super.shortcuts,
358399
super.actions,
359400
super.builder,

forui/lib/src/widgets/button/button.dart

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ class FButton extends StatelessWidget {
4141
/// {@macro forui.foundation.FTappable.onLongPress}
4242
final VoidCallback? onLongPress;
4343

44+
/// {@macro forui.foundation.FTappable.onSecondaryPress}
45+
final VoidCallback? onSecondaryPress;
46+
47+
/// {@macro forui.foundation.FTappable.onSecondaryLongPress}
48+
final VoidCallback? onSecondaryLongPress;
49+
4450
/// {@macro forui.foundation.doc_templates.autofocus}
4551
final bool autofocus;
4652

@@ -93,6 +99,8 @@ class FButton extends StatelessWidget {
9399
required Widget child,
94100
this.style = _primary,
95101
this.onLongPress,
102+
this.onSecondaryPress,
103+
this.onSecondaryLongPress,
96104
this.autofocus = false,
97105
this.focusNode,
98106
this.onFocusChange,
@@ -126,6 +134,8 @@ class FButton extends StatelessWidget {
126134
required Widget child,
127135
this.style = _outline,
128136
this.onLongPress,
137+
this.onSecondaryPress,
138+
this.onSecondaryLongPress,
129139
this.autofocus = false,
130140
this.focusNode,
131141
this.onFocusChange,
@@ -143,6 +153,8 @@ class FButton extends StatelessWidget {
143153
required this.child,
144154
this.style = _primary,
145155
this.onLongPress,
156+
this.onSecondaryPress,
157+
this.onSecondaryLongPress,
146158
this.autofocus = false,
147159
this.focusNode,
148160
this.onFocusChange,
@@ -171,6 +183,8 @@ class FButton extends StatelessWidget {
171183
onStateChange: onStateChange,
172184
onPress: onPress,
173185
onLongPress: onLongPress,
186+
onSecondaryPress: onSecondaryPress,
187+
onSecondaryLongPress: onSecondaryLongPress,
174188
selected: selected,
175189
builder: (_, states, _) => DecoratedBox(
176190
decoration: style.decoration.resolve(states),
@@ -186,6 +200,8 @@ class FButton extends StatelessWidget {
186200
..add(DiagnosticsProperty('style', style))
187201
..add(ObjectFlagProperty.has('onPress', onPress))
188202
..add(ObjectFlagProperty.has('onLongPress', onLongPress))
203+
..add(ObjectFlagProperty.has('onSecondaryPress', onSecondaryPress))
204+
..add(ObjectFlagProperty.has('onSecondaryLongPress', onSecondaryLongPress))
189205
..add(FlagProperty('autofocus', value: autofocus, defaultValue: false, ifTrue: 'autofocus'))
190206
..add(DiagnosticsProperty('focusNode', focusNode))
191207
..add(ObjectFlagProperty.has('onFocusChange', onFocusChange))

forui/lib/src/widgets/date_field/calendar/calendar_date_field.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ class _CalendarDatePickerState extends _FDateFieldState<_CalendarDateField> {
214214
}
215215

216216
void _onTap() {
217-
_controller.calendar.shown ? _focus.requestFocus() : _focus.unfocus();
217+
const {AnimationStatus.completed, AnimationStatus.reverse}.contains(_controller.calendar.status)
218+
? _focus.requestFocus()
219+
: _focus.unfocus();
218220
_controller.calendar.toggle();
219221
}
220222

0 commit comments

Comments
 (0)