mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
[infra_ui][overlay] Implement option overlay
This commit is contained in:
parent
051240a2fb
commit
82e6856f75
@ -6,3 +6,5 @@ export 'src/keyboard/keyboard_visibility_detector.dart';
|
||||
|
||||
// Overlay
|
||||
export 'src/flowy_overlay/flowy_overlay.dart';
|
||||
export 'src/flowy_overlay/list_overlay.dart';
|
||||
export 'src/flowy_overlay/option_overlay.dart';
|
||||
|
@ -6,3 +6,5 @@ export 'src/keyboard/keyboard_visibility_detector.dart';
|
||||
|
||||
// Overlay
|
||||
export 'src/flowy_overlay/flowy_overlay.dart';
|
||||
export 'src/flowy_overlay/list_overlay.dart';
|
||||
export 'src/flowy_overlay/option_overlay.dart';
|
||||
|
@ -0,0 +1,97 @@
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui_web.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class OptionItem {
|
||||
const OptionItem(this.icon, this.title);
|
||||
|
||||
final Icon? icon;
|
||||
final String title;
|
||||
}
|
||||
|
||||
class OptionOverlay<T> extends StatelessWidget {
|
||||
const OptionOverlay({
|
||||
Key? key,
|
||||
required this.items,
|
||||
this.onHover,
|
||||
this.onTap,
|
||||
}) : super(key: key);
|
||||
|
||||
final List<T> items;
|
||||
final IndexedValueCallback<T>? onHover;
|
||||
final IndexedValueCallback<T>? onTap;
|
||||
|
||||
static void showWithAnchor<T>(
|
||||
BuildContext context, {
|
||||
required String identifier,
|
||||
required List<T> items,
|
||||
IndexedValueCallback<T>? onHover,
|
||||
IndexedValueCallback<T>? onTap,
|
||||
required BuildContext anchorContext,
|
||||
AnchorDirection? anchorDirection,
|
||||
FlowyOverlayDelegate? delegate,
|
||||
OverlapBehaviour? overlapBehaviour,
|
||||
}) {
|
||||
FlowyOverlay.of(context).insertWithAnchor(
|
||||
widget: OptionOverlay(
|
||||
items: items,
|
||||
onHover: onHover,
|
||||
onTap: onTap,
|
||||
),
|
||||
identifier: identifier,
|
||||
anchorContext: anchorContext,
|
||||
anchorDirection: anchorDirection,
|
||||
delegate: delegate,
|
||||
overlapBehaviour: overlapBehaviour,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final List<_OptionListItem> listItems = items.map((e) => _OptionListItem(e)).toList();
|
||||
return ListOverlay(
|
||||
itemBuilder: (context, index) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
onHover: onHover != null ? (_) => onHover!(items[index], index) : null,
|
||||
child: GestureDetector(
|
||||
onTap: onTap != null ? () => onTap!(items[index], index) : null,
|
||||
child: listItems[index],
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: listItems.length,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _OptionListItem<T> extends StatelessWidget {
|
||||
const _OptionListItem(
|
||||
this.value, {
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
final T value;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (T == String || T == OptionItem) {
|
||||
var children = <Widget>[];
|
||||
if (value is String) {
|
||||
children = [
|
||||
Text(value as String),
|
||||
];
|
||||
} else if (value is OptionItem) {
|
||||
final optionItem = value as OptionItem;
|
||||
children = [
|
||||
if (optionItem.icon != null) optionItem.icon!,
|
||||
Text(optionItem.title),
|
||||
];
|
||||
}
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: children,
|
||||
);
|
||||
}
|
||||
throw UnimplementedError('The type $T is not supported by option list.');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user