58 lines
1.8 KiB
Dart
58 lines
1.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
import 'package:flutter_portal/flutter_portal.dart';
|
|
import 'package:wayland_layer_shell/types.dart';
|
|
import 'package:wayland_layer_shell/wayland_layer_shell.dart';
|
|
|
|
class Bubble extends HookWidget {
|
|
final Widget child;
|
|
final Widget? popover;
|
|
const Bubble(this.child, {this.popover, super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final isVisible = useState(false);
|
|
return PortalTarget(
|
|
visible: isVisible.value,
|
|
anchor: const Filled(),
|
|
portalFollower: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: () {
|
|
isVisible.value = false;
|
|
WaylandLayerShell().setAnchor(ShellEdge.edgeTop, false);
|
|
},
|
|
),
|
|
child: PortalTarget(
|
|
visible: isVisible.value,
|
|
anchor: Aligned(
|
|
follower: Alignment.bottomCenter,
|
|
target: Alignment.topCenter,
|
|
),
|
|
portalFollower: popover,
|
|
child: Padding(
|
|
padding: const EdgeInsets.only(bottom: 6),
|
|
child: Material(
|
|
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
|
borderRadius: BorderRadius.circular(999),
|
|
child: InkWell(
|
|
borderRadius: BorderRadius.circular(999),
|
|
onTap: popover == null
|
|
? null
|
|
: () async {
|
|
await WaylandLayerShell().setAnchor(
|
|
ShellEdge.edgeTop,
|
|
true,
|
|
);
|
|
isVisible.value = true;
|
|
},
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
child: child,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|