Skip to content

Commit acd1fc9

Browse files
authored
Merge pull request #29 from offirgolan/locked-open
[FEATURE] Locked + gesturesEnabled + use ember-lifeline
2 parents 7bb5d2b + bf39a2c commit acd1fc9

File tree

13 files changed

+294
-137
lines changed

13 files changed

+294
-137
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ This addon utilizes contextual components to be able to correctly control and an
120120

121121
**Default: 300**
122122

123+
- #### `locked`
124+
125+
Lock the menu in its current open / closed state. Please note that changes made
126+
directly via the burgerMenu service or {{burger.state.actions}} will still propagate.
127+
128+
**Default: false**
129+
123130
- #### `customAnimation`
124131

125132
Override of the menu's styles with your own implementation. See [Custom Animations](#custom-animations) for more details.
@@ -142,6 +149,12 @@ This addon utilizes contextual components to be able to correctly control and an
142149

143150
**Default: true**
144151

152+
- #### `gesturesEnabled`
153+
154+
Whether the menu can be open / closed using gestures. The only available gesture currently is swipe.
155+
156+
**Default: true**
157+
145158
- #### `minSwipeDistance`
146159

147160
The minimum distance (in px) the user must swipe to register as valid.

addon/components/bm-menu-item.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default Ember.Component.extend({
3636
},
3737

3838
click() {
39-
if (this.get('dismissOnClick')) {
39+
if (this.get('dismissOnClick') && !this.get('state.locked')) {
4040
this.set('state.open', false);
4141
}
4242
}

addon/components/burger-menu.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import Ember from 'ember';
22
import layout from '../templates/components/burger-menu';
33
import computedStyleFor from 'ember-burger-menu/computed/style-for';
4-
import SwipeSupport from 'ember-burger-menu/mixins/swipe-support';
4+
import SwipeSupportMixin from 'ember-burger-menu/mixins/swipe-support';
5+
import DomMixin from 'ember-lifeline/mixins/dom';
56

67
const {
78
$,
@@ -13,7 +14,7 @@ const {
1314
inject: { service }
1415
} = Ember;
1516

16-
export default Ember.Component.extend(SwipeSupport, {
17+
export default Ember.Component.extend(DomMixin, SwipeSupportMixin, {
1718
classNames: ['ember-burger-menu'],
1819
classNameBindings: ['open:is-open', 'translucentOverlay', 'animationClass', 'position'],
1920
attributeBindings: ['style'],
@@ -24,8 +25,10 @@ export default Ember.Component.extend(SwipeSupport, {
2425
translucentOverlay: true,
2526
dismissOnClick: true,
2627
dismissOnEsc: true,
28+
gesturesEnabled: true,
2729

2830
open: alias('state.open'),
31+
locked: alias('state.locked'),
2932
position: alias('state.position'),
3033
width: alias('state.width'),
3134
animation: alias('state.animation'),
@@ -41,35 +44,32 @@ export default Ember.Component.extend(SwipeSupport, {
4144
willDestroyElement() {
4245
this._super(...arguments);
4346
run.cancel(this._setupEventsTimer);
44-
this._teardownEvents();
4547
},
4648

47-
setupEvents: on('didInsertElement', observer('open', function() {
48-
let methodName = this.get('open') ? '_setupEvents' : '_teardownEvents';
49-
this._setupEventsTimer = run.scheduleOnce('afterRender', this, methodName);
49+
setupEvents: on('didInsertElement', observer('open', 'locked', function() {
50+
if (this.get('locked')) {
51+
this._setupEventsTimer = run.scheduleOnce('afterRender', this, '_teardownEvents');
52+
} else {
53+
let methodName = this.get('open') ? '_setupEvents' : '_teardownEvents';
54+
this._setupEventsTimer = run.scheduleOnce('afterRender', this, methodName);
55+
}
5056
})),
5157

5258
_setupEvents() {
53-
let $element = this.$();
54-
let onClick = this.onClick.bind(this);
55-
let onKeyUp = this.onKeyup.bind(this);
56-
5759
if (this.get('dismissOnClick')) {
58-
$element.on('click.bm', onClick);
59-
$element.on('touchstart.bm', onClick);
60+
this.addEventListener(this.$(), 'click', this.onClick);
61+
this.addEventListener(this.$(), 'touchstart', this.onClick);
6062
}
6163

6264
if (this.get('dismissOnEsc')) {
63-
$(document).on('keyup.bm', onKeyUp);
65+
this.addEventListener(document, 'keyup', this.onKeyup);
6466
}
6567
},
6668

6769
_teardownEvents() {
68-
let $element = this.$();
69-
70-
$element.off('click.bm');
71-
$element.off('touchstart.bm');
72-
$(document).off('keyup.bm');
70+
this.removeEventListener(this.$(), 'click', this.onClick);
71+
this.removeEventListener(this.$(), 'touchstart', this.onClick);
72+
this.removeEventListener(document, 'keyup', this.onKeyup);
7373
},
7474

7575
onClick(e) {
@@ -91,8 +91,14 @@ export default Ember.Component.extend(SwipeSupport, {
9191
onSwipe(direction, target) {
9292
let position = this.get('position');
9393
let open = this.get('open');
94+
let locked = this.get('locked');
95+
let gesturesEnabled = this.get('gesturesEnabled');
9496
let isMenuSwipe = $(target).closest('.bm-menu').length > 0;
9597

98+
if (!gesturesEnabled || locked) {
99+
return;
100+
}
101+
96102
if (open && isMenuSwipe && position === direction) {
97103
this.set('open', false);
98104
} else if (!open && position !== direction) {

addon/mixins/swipe-support.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import Ember from 'ember';
22

33
const {
4-
isNone
4+
isNone,
5+
inject: { service },
6+
computed: { alias }
57
} = Ember;
68

79
let meta;
810

911
export default Ember.Mixin.create({
10-
minSwipeDistance: 150,
11-
maxSwipeTime: 300,
12+
state: service('burgerMenu'),
13+
minSwipeDistance: alias('state.minSwipeDistance'),
14+
maxSwipeTime: alias('state.maxSwipeTime'),
1215

1316
onSwipe(/* direction, target */) {},
1417

addon/services/burger-menu.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,14 @@ const {
77

88
export default Ember.Service.extend({
99
open: false,
10+
locked: false,
1011
width: 300,
1112
position: 'left',
1213
animation: 'slide',
14+
15+
minSwipeDistance: 150,
16+
maxSwipeTime: 300,
17+
1318
itemAnimation: null,
1419
customAnimation: null,
1520

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"ember-cli-babel": "^5.1.7",
6060
"ember-cli-htmlbars": "^1.0.10",
6161
"ember-cli-sass": "^5.6.0",
62+
"ember-lifeline": "^1.0.4",
6263
"ember-require-module": "^0.1.1",
6364
"ember-wormhole": "^0.5.0"
6465
},

tests/dummy/app/controllers/application.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ import Ember from 'ember';
33
export default Ember.Controller.extend({
44
translucentOverlay: true,
55
dismissOnClick: true,
6-
dismissOnEsc: true
6+
dismissOnEsc: true,
7+
gesturesEnabled: true
78
});

tests/dummy/app/controllers/index.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,33 @@ import Ember from 'ember';
22

33
const {
44
inject,
5-
computed
5+
computed: { alias }
66
} = Ember;
77

88
export default Ember.Controller.extend({
99
queryParams: [
1010
'animation',
1111
'itemAnimation',
1212
'position',
13+
'locked',
1314
'translucentOverlay',
1415
'dismissOnClick',
15-
'dismissOnEsc'
16+
'dismissOnEsc',
17+
'gesturesEnabled'
1618
],
1719

1820
application: inject.controller(),
1921
burgerMenu: inject.service(),
2022

21-
animation: computed.alias('burgerMenu.animation'),
22-
itemAnimation: computed.alias('burgerMenu.itemAnimation'),
23-
position: computed.alias('burgerMenu.position'),
23+
animation: alias('burgerMenu.animation'),
24+
itemAnimation: alias('burgerMenu.itemAnimation'),
25+
position: alias('burgerMenu.position'),
26+
locked: alias('burgerMenu.locked'),
2427

25-
translucentOverlay: computed.alias('application.translucentOverlay'),
26-
dismissOnClick: computed.alias('application.dismissOnClick'),
27-
dismissOnEsc: computed.alias('application.dismissOnEsc'),
28+
translucentOverlay: alias('application.translucentOverlay'),
29+
dismissOnClick: alias('application.dismissOnClick'),
30+
dismissOnEsc: alias('application.dismissOnEsc'),
31+
gesturesEnabled: alias('application.gesturesEnabled'),
2832

2933
animations: [
3034
'slide',

tests/dummy/app/styles/app.scss

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ a {
3434
}
3535
}
3636

37+
::-webkit-scrollbar {
38+
display: none;
39+
}
40+
3741
.pointer {
3842
cursor: pointer;
3943
}
@@ -185,64 +189,82 @@ a {
185189
}
186190
}
187191

188-
.header {
189-
background: #233040;
190-
padding-top: 60px;
191-
192-
h1 {
193-
font-family: 'Bungee Hairline', cursive;
194-
font-weight: bold;
195-
}
192+
main {
193+
height: 100%;
196194

197-
.description {
198-
padding: 30px 0 30px;
199-
font-size: 16px;
195+
.header {
196+
background: #233040;
197+
padding: 10px;
198+
height: 50%;
199+
display: flex;
200+
align-items: center;
201+
justify-content: center;
202+
flex-direction: column;
203+
204+
img {
205+
width: 375px;
206+
max-width: 80%;
207+
}
200208

201-
> p {
202-
max-width: 500px;
203-
margin: 0 auto;
209+
h1 {
210+
font-family: 'Bungee Hairline', cursive;
211+
font-weight: bold;
204212
}
205-
}
206-
}
207213

208-
.container {
209-
padding-top: 30px;
214+
.description {
215+
padding: 30px 0 30px;
216+
font-size: 16px;
210217

211-
h4 {
212-
margin-bottom: 20px;
213-
font-size: 16px;
214-
font-weight: 400;
218+
> p {
219+
max-width: 500px;
220+
margin: 0 auto;
221+
}
222+
}
215223
}
216224

217-
.animations {
218-
min-height: 225px;
219-
border-right: 1px solid #ccc;
220-
padding-right: 25px;
225+
.content {
226+
height: 50%;
221227

222-
.btn-outline {
223-
margin: 0 0 10px 10px;
224-
}
225-
}
228+
.container {
229+
padding-top: 30px;
230+
231+
h4 {
232+
margin-bottom: 20px;
233+
font-size: 16px;
234+
font-weight: 400;
235+
}
226236

227-
.options {
228-
min-height: 225px;
229-
padding-left: 25px;
237+
.animations {
238+
min-height: 310px;
239+
border-right: 1px solid #ccc;
240+
padding-right: 25px;
230241

231-
.option {
232-
label {
233-
font-size: 15px;
234-
width: 160px;
242+
.btn-outline {
243+
margin: 0 0 10px 10px;
244+
}
235245
}
236-
.checkbox {
237-
cursor: pointer;
238-
display: inline-block;
239-
color: $accent-color;
240-
font-size: 18px;
246+
247+
.options {
248+
min-height: 310px;
249+
padding-left: 25px;
250+
251+
.option {
252+
label {
253+
font-size: 15px;
254+
width: 160px;
255+
}
256+
.checkbox {
257+
cursor: pointer;
258+
display: inline-block;
259+
color: $accent-color;
260+
font-size: 18px;
261+
}
262+
}
241263
}
242264
}
243-
}
244-
}
245265

246-
.inspiration {
247-
padding: 40px 0;
266+
.inspiration {
267+
padding: 40px 0;
268+
}
269+
}
248270
}

tests/dummy/app/templates/application.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
translucentOverlay=translucentOverlay
33
dismissOnClick=dismissOnClick
44
dismissOnEsc=dismissOnEsc
5+
gesturesEnabled=gesturesEnabled
56
as |burger|
67
}}
78
{{#burger.menu itemTagName="li" dismissOnItemClick=true as |menu|}}

0 commit comments

Comments
 (0)