Skip to content

Commit

Permalink
fix/context-menu-right-click (#151)
Browse files Browse the repository at this point in the history
  • Loading branch information
nank1ro authored Sep 24, 2024
1 parent 790fd5e commit 869e6dd
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 158 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.9.8

- Improve the `ShadContextMenu` right click behavior on Web.

## 0.9.7

- Remove kind event from `ShadMouseArea`
Expand Down
1 change: 0 additions & 1 deletion lib/shadcn_ui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ export 'src/utils/provider.dart' hide ProviderReadExt, ProviderWatchExt;
export 'src/utils/responsive.dart';
export 'src/utils/states_controller.dart';
export 'src/utils/mouse_area.dart';
export 'src/utils/disable_context_menu/disable_context_menu.dart';

// External libraries
export 'package:flutter_animate/flutter_animate.dart' hide Effect;
Expand Down
12 changes: 0 additions & 12 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
// ignore_for_file: lines_longer_than_80_chars

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart'
show
GlobalCupertinoLocalizations,
Expand Down Expand Up @@ -557,15 +554,6 @@ class _ShadAppState extends State<ShadApp> {
yield GlobalWidgetsLocalizations.delegate;
}

@override
void initState() {
super.initState();
if (kIsWeb) {
// needed for disabling the native context menu on web
SemanticsBinding.instance.ensureSemantics();
}
}

@override
void dispose() {
heroController.dispose();
Expand Down
55 changes: 39 additions & 16 deletions lib/src/components/context_menu.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import 'dart:async';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/services.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:shadcn_ui/src/utils/disable_context_menu/disable_context_menu.dart';
import 'package:shadcn_ui/src/components/button.dart';
import 'package:shadcn_ui/src/components/popover.dart';
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/gesture_detector.dart';
import 'package:shadcn_ui/src/utils/mouse_area.dart';
import 'package:shadcn_ui/src/utils/provider.dart';

const kContextMenuGroupId = ValueKey('context-menu');
Expand Down Expand Up @@ -83,14 +89,15 @@ class ShadContextMenuRegion extends StatefulWidget {
}

class _ShadContextMenuRegionState extends State<ShadContextMenuRegion> {
final identifier = UniqueKey();
ShadContextMenuController? _controller;
ShadContextMenuController get controller =>
widget.controller ??
(_controller ??=
ShadContextMenuController(isOpen: widget.visible ?? false));
Offset? offset;

final isContextMenuAlreadyDisabled = kIsWeb && !BrowserContextMenu.enabled;

@override
void didUpdateWidget(covariant ShadContextMenuRegion oldWidget) {
super.didUpdateWidget(oldWidget);
Expand All @@ -106,6 +113,7 @@ class _ShadContextMenuRegionState extends State<ShadContextMenuRegion> {
}

void showAtOffset(Offset offset) {
if (!mounted) return;
setState(() => this.offset = offset);
controller.show();
}
Expand All @@ -114,8 +122,8 @@ class _ShadContextMenuRegionState extends State<ShadContextMenuRegion> {
controller.hide();
}

void show(TapDownDetails details) {
showAtOffset(details.globalPosition);
void show(Offset offset) {
showAtOffset(offset);
}

void onLongPress() {
Expand All @@ -125,9 +133,11 @@ class _ShadContextMenuRegionState extends State<ShadContextMenuRegion> {

@override
Widget build(BuildContext context) {
final platform = Theme.of(context).platform;
final effectiveLongPressEnabled = widget.longPressEnabled ??
(defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS);
(platform == TargetPlatform.android || platform == TargetPlatform.iOS);

final isWindows = platform == TargetPlatform.windows;

return ShadContextMenu(
anchor: offset == null ? null : ShadGlobalAnchor(offset!),
Expand All @@ -143,7 +153,21 @@ class _ShadContextMenuRegionState extends State<ShadContextMenuRegion> {
filter: widget.filter,
child: ShadGestureDetector(
onTapDown: (_) => hide(),
onSecondaryTapDown: show,
onSecondaryTapDown: (d) async {
if (kIsWeb && !isContextMenuAlreadyDisabled) {
await BrowserContextMenu.disableContextMenu();
}
if (!isWindows) show(d.globalPosition);
},
onSecondaryTapUp: (d) async {
if (isWindows) {
show(d.globalPosition);
await Future<void>.delayed(Duration.zero);
}
if (kIsWeb && !isContextMenuAlreadyDisabled) {
await BrowserContextMenu.enableContextMenu();
}
},
onLongPressStart: effectiveLongPressEnabled
? (d) {
offset = d.globalPosition;
Expand Down Expand Up @@ -297,6 +321,7 @@ class ShadContextMenuState extends State<ShadContextMenu> {
effects: effectiveEffects,
shadows: effectiveShadows,
filter: effectiveFilter,
useSameGroupIdForChild: false,
popover: (context) {
return ShadMouseArea(
groupId: widget.groupId,
Expand All @@ -319,13 +344,11 @@ class ShadContextMenuState extends State<ShadContextMenu> {
),
);
},
child: DisableWebContextMenu(
child: ShadMouseArea(
groupId: widget.groupId,
onEnter: (_) => widget.onHoverArea?.call(true),
onExit: (_) => widget.onHoverArea?.call(false),
child: widget.child,
),
child: ShadMouseArea(
groupId: widget.groupId,
onEnter: (_) => widget.onHoverArea?.call(true),
onExit: (_) => widget.onHoverArea?.call(false),
child: widget.child,
),
);

Expand Down
50 changes: 31 additions & 19 deletions lib/src/components/popover.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class ShadPopover extends StatefulWidget {
this.filter,
this.groupId,
this.areaGroupId,
this.useSameGroupIdForChild = true,
}) : assert(
(controller != null) ^ (visible != null),
'Either controller or visible must be provided',
Expand Down Expand Up @@ -132,6 +133,13 @@ class ShadPopover extends StatefulWidget {
/// {@macro ShadMouseArea.groupId}
final Object? areaGroupId;

/// {@template ShadPopover.useSameGroupIdForChild}
/// Whether the [groupId] should be used for the child widget, defaults to
/// `true`. This teams that taps on the child widget will be handled as inside
/// the popover.
/// {@endtemplate}
final bool useSameGroupIdForChild;

@override
State<ShadPopover> createState() => _ShadPopoverState();
}
Expand Down Expand Up @@ -239,26 +247,30 @@ class _ShadPopoverState extends State<ShadPopover> {
);
}

return TapRegion(
groupId: groupId,
child: ListenableBuilder(
listenable: controller,
builder: (context, _) {
return CallbackShortcuts(
bindings: {
const SingleActivator(LogicalKeyboardKey.escape): () {
controller.hide();
},
Widget child = ListenableBuilder(
listenable: controller,
builder: (context, _) {
return CallbackShortcuts(
bindings: {
const SingleActivator(LogicalKeyboardKey.escape): () {
controller.hide();
},
child: ShadPortal(
portalBuilder: (_) => popover,
visible: controller.isOpen,
anchor: effectiveAnchor,
child: widget.child,
),
);
},
),
},
child: ShadPortal(
portalBuilder: (_) => popover,
visible: controller.isOpen,
anchor: effectiveAnchor,
child: widget.child,
),
);
},
);
if (widget.useSameGroupIdForChild) {
child = TapRegion(
groupId: groupId,
child: child,
);
}
return child;
}
}

This file was deleted.

18 changes: 0 additions & 18 deletions lib/src/utils/disable_context_menu/non_web.dart

This file was deleted.

90 changes: 0 additions & 90 deletions lib/src/utils/disable_context_menu/web.dart

This file was deleted.

2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: shadcn_ui
description: shadcn-ui ported in Flutter. Awesome UI components for Flutter, fully customizable.
version: 0.9.7
version: 0.9.8
homepage: https://mariuti.com/shadcn-ui
repository: https://github.com/nank1ro/flutter-shadcn-ui
documentation: https://mariuti.com/shadcn-ui
Expand Down

0 comments on commit 869e6dd

Please sign in to comment.