Skip to content

Commit

Permalink
Fix old Standard SearchBar and modify anchor with bar & controller
Browse files Browse the repository at this point in the history
  • Loading branch information
ManelRosPuig committed Sep 23, 2023
1 parent 100f0c1 commit a237fb2
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 22 deletions.
33 changes: 22 additions & 11 deletions lib/new/standard_search_anchor.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';

import 'package:standard_searchbar/new/standard_search_bar.dart';
import 'package:standard_searchbar/new/standard_suggestions.dart';
import 'package:standard_searchbar/new/standard_search_controller.dart';

/// If there is no StandardSearchController passed in the constructor of
Expand All @@ -10,21 +11,31 @@ class StandardSearchAnchor extends StatefulWidget {
super.key,
this.controller,
required this.searchBar,
required this.suggestions,
});

static late StandardSearchAnchorState state;

final StandardSearchController? controller;

final StandardSearchBar searchBar;
final StandardSuggestions suggestions;

@override
State<StandardSearchAnchor> createState() => StandardSearchAnchorState();
// ignore: no_logic_in_create_state
State<StandardSearchAnchor> createState() {
state = StandardSearchAnchorState();
return state;
}
}

class StandardSearchAnchorState extends State<StandardSearchAnchor> {
late final StandardSearchController controller;
final unfocus = [false, false];
final layerLink = LayerLink();
OverlayEntry? entry;

bool get isOpen => entry != null;

@override
void initState() {
super.initState();
Expand All @@ -34,16 +45,19 @@ class StandardSearchAnchorState extends State<StandardSearchAnchor> {
controller = StandardSearchController();
}
controller.anchor = this;
StandardSuggestions.controller = controller;
}

@override
Widget build(BuildContext context) {
return TapRegion(
onTapInside: (e) {
StandardSearchController.unfocus[1] = false;
controller.open();
},
onTapOutside: (e) {
controller.close();
StandardSearchController.unfocus[1] = true;
controller.requestClose();
},
child: CompositedTransformTarget(
link: layerLink,
Expand All @@ -52,10 +66,6 @@ class StandardSearchAnchorState extends State<StandardSearchAnchor> {
);
}

void clear() {
controller.clear();
}

void open() {
if (entry != null) return;
final renderBox = context.findRenderObject() as RenderBox;
Expand All @@ -69,10 +79,7 @@ class StandardSearchAnchorState extends State<StandardSearchAnchor> {
link: layerLink,
showWhenUnlinked: false,
offset: Offset(0, renderBox.size.height),
child: Container(
height: 200,
color: Colors.red,
),
child: widget.suggestions,
),
);
});
Expand All @@ -85,4 +92,8 @@ class StandardSearchAnchorState extends State<StandardSearchAnchor> {
entry = null;
}
}

void clear() {
controller.clear();
}
}
94 changes: 88 additions & 6 deletions lib/new/standard_search_bar.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,97 @@
import 'package:flutter/material.dart';
import 'package:standard_searchbar/new/standard_icons.dart';
import 'package:standard_searchbar/new/standard_search_anchor.dart';

class StandardSearchBar extends StatelessWidget {
const StandardSearchBar({super.key});
import 'package:standard_searchbar/new/standard_search_controller.dart';

class StandardSearchBar extends StatefulWidget {
const StandardSearchBar({
super.key,
this.width,
this.height = 56,
this.constraints = const BoxConstraints(maxWidth: 720),
this.padding = EdgeInsets.zero,
this.borderRadius = 28,
this.bgColor = Colors.white,
this.leading = const StandardIcons(
icons: [
Icon(Icons.search, size: 24, color: Colors.grey),
],
),
this.trailing,
});

final double? width;
final double height;
final BoxConstraints constraints;
final EdgeInsetsGeometry padding;
final double borderRadius;
final Color bgColor;

final StandardIcons leading;
final StandardIcons? trailing;

static StandardSearchAnchorState? of(BuildContext context) {
return context.findAncestorStateOfType<StandardSearchAnchorState>();
}

@override
State<StandardSearchBar> createState() => StandardSearchBarState();
}

class StandardSearchBarState extends State<StandardSearchBar> {
StandardSearchController? controller;

@override
void initState() {
super.initState();
controller = StandardSearchBar.of(context)?.controller;
controller?.searchBar = this;
}

@override
Widget build(BuildContext context) {
return Container(
width: 360,
height: 56,
color: Colors.yellow,
padding: const EdgeInsets.symmetric(horizontal: 16),
width: widget.width,
height: widget.height,
constraints: widget.constraints,
padding: widget.padding,
decoration: BoxDecoration(
borderRadius: getBorderRadius(),
color: widget.bgColor,
),
child: Row(
children: [
widget.leading,
Expanded(
child: TextField(
controller: controller,
decoration: const InputDecoration(
border: InputBorder.none,
hintText: 'Search',
hintStyle: TextStyle(
color: Colors.grey,
),
),
),
),
if (widget.trailing != null) widget.trailing!,
],
),
);
}

BorderRadiusGeometry getBorderRadius() {
assert(controller != null);
if (controller!.isOpen) {
return BorderRadius.only(
topLeft: Radius.circular(widget.borderRadius),
topRight: Radius.circular(widget.borderRadius),
);
} else {
return BorderRadius.all(
Radius.circular(widget.borderRadius),
);
}
}
}
37 changes: 35 additions & 2 deletions lib/new/standard_search_controller.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,47 @@
import 'package:flutter/material.dart';

import 'package:standard_searchbar/new/standard_search_anchor.dart';
import 'package:standard_searchbar/new/standard_search_bar.dart';
import 'package:standard_searchbar/new/standard_suggestions.dart';

class StandardSearchController extends TextEditingController {
// Anchor attached to this controller
StandardSearchAnchorState? _anchor;
set anchor(StandardSearchAnchorState anchor) => _anchor = anchor;

void open() => _anchor?.open();
void close() => _anchor?.close();
// SearchBar attached to this controller
StandardSearchBarState? _searchBar;
StandardSearchBarState get searchBar => _searchBar!;
set searchBar(StandardSearchBarState searchBar) => _searchBar = searchBar;

// Suggestions box attached to this controller
StandardSuggestionsState? _suggestions;
StandardSuggestionsState get suggestions => _suggestions!;
set suggestions(StandardSuggestionsState suggestions) => _suggestions = suggestions;

bool get isOpen => _anchor?.isOpen ?? false;

static final List<bool> unfocus = [false, false];

void open() {
_anchor?.open();
// ignore: invalid_use_of_protected_member
_searchBar?.setState(() {});
}

void requestClose() {
if (unfocus[0] && unfocus[1]) {
close();
unfocus[0] = false;
unfocus[1] = false;
}
}

void close() {
_anchor?.close();
// ignore: invalid_use_of_protected_member
_searchBar?.setState(() {});
}

@override
void clear() {
Expand Down
3 changes: 1 addition & 2 deletions lib/old/standard_icon.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ class StandardIcon extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(
left: iconPaddingLeft ?? 0, right: iconPaddingRight ?? 0),
padding: EdgeInsets.only(left: iconPaddingLeft ?? 0, right: iconPaddingRight ?? 0),
child: ClipOval(
child: Material(
color: Colors.transparent,
Expand Down
1 change: 0 additions & 1 deletion lib/old/standard_searchbar.dart
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ class _StandardSearchBarState extends State<StandardSearchBar> {

@override
Widget build(BuildContext context) {
SearchBar();
return TapRegion(
onTapInside: (e) {
if (suggestions == null) return;
Expand Down

0 comments on commit a237fb2

Please sign in to comment.