-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathmenu_toggle.dart
More file actions
75 lines (65 loc) · 2.04 KB
/
menu_toggle.dart
File metadata and controls
75 lines (65 loc) · 2.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// Copyright 2025 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:jaspr/dom.dart';
import 'package:jaspr/jaspr.dart';
import 'package:universal_web/js_interop.dart';
import 'package:universal_web/web.dart' as web;
import '../common/material_icon.dart';
@client
final class MenuToggle extends StatefulComponent {
const MenuToggle();
@override
State<MenuToggle> createState() => _MenuToggleState();
}
final class _MenuToggleState extends State<MenuToggle> {
@override
void initState() {
if (kIsWeb) {
// Set up an event listener to close the wide sidenav if
// switching to a wider site layout.
web.window.addEventListener('resize', _handleResize.toJS);
// Set up an event listener to close the sidenav
// if it is open and somewhere else is clicked on.
web.window.addEventListener('click', _handleClickOutsideSidenav.toJS);
}
super.initState();
}
@override
Component build(BuildContext context) => button(
id: 'menu-toggle',
classes: 'icon-button',
type: ButtonType.button,
attributes: {
'aria-controls': 'sidenav',
'aria-label': 'Toggle navigation menu.',
'title': 'Toggle navigation menu.',
},
events: {
'click': (_) {
web.document.body?.classList.toggle('open_menu');
},
},
const [
MaterialIcon('menu'),
MaterialIcon('close'),
],
);
}
void _handleResize(web.Event _) {
if (web.window.innerWidth > 1025) {
web.document.body?.classList.remove('open_menu');
}
}
void _handleClickOutsideSidenav(web.MouseEvent clickEvent) {
if (clickEvent.target case final web.HTMLElement clickedElement) {
if (clickedElement.closest('#sidenav') == null &&
clickedElement.closest('#menu-toggle') == null) {
final bodyClasses = web.document.body!.classList;
if (bodyClasses.contains('open_menu')) {
clickEvent.preventDefault();
bodyClasses.remove('open_menu');
}
}
}
}