mirror of
https://github.com/beestat/app.git
synced 2025-05-24 02:14:03 -04:00
185 lines
4.9 KiB
JavaScript
185 lines
4.9 KiB
JavaScript
/**
|
|
* Menu
|
|
*/
|
|
beestat.component.menu = function() {
|
|
beestat.component.apply(this, arguments);
|
|
};
|
|
beestat.extend(beestat.component.menu, beestat.component);
|
|
|
|
beestat.component.menu.prototype.decorate_ = function(parent) {
|
|
var self = this;
|
|
|
|
this.menu_items_ = [];
|
|
|
|
this.icon_ = new beestat.component.tile()
|
|
.set_type('pill')
|
|
.set_shadow(false)
|
|
.set_icon('dots_vertical')
|
|
.set_bubble_text(this.bubble_text_)
|
|
.set_bubble_color(this.bubble_color_)
|
|
.set_text_color('#fff')
|
|
.set_background_hover_color('rgba(255, 255, 255, 0.1')
|
|
.addEventListener('click', function() {
|
|
// Did I just try to open the same menu as last time?
|
|
var same_as_last = (beestat.component.menu.open_menu === self);
|
|
|
|
// Close any open menus (this deletes beestat.component.menu.open_menu)
|
|
if (beestat.component.menu.open_menu !== undefined) {
|
|
beestat.component.menu.open_menu.dispose();
|
|
}
|
|
|
|
if (same_as_last === false) {
|
|
self.open_();
|
|
}
|
|
})
|
|
.render(parent);
|
|
};
|
|
|
|
/**
|
|
* Close this menu by hiding the container and removing the event listeners.
|
|
*/
|
|
beestat.component.menu.prototype.dispose = function() {
|
|
var self = this;
|
|
beestat.component.menu.open_menu.rendered_ = false;
|
|
this.rendered_ = false;
|
|
|
|
if (beestat.component.menu.open_menu !== undefined) {
|
|
var container = beestat.component.menu.open_menu.container_;
|
|
container.style('transform', 'scale(0)');
|
|
|
|
delete beestat.component.menu.open_menu;
|
|
window.setTimeout(function() {
|
|
self.menu_items_.forEach(function(menu_item) {
|
|
menu_item.dispose();
|
|
});
|
|
|
|
container.parentNode().removeChild(container);
|
|
}, 200);
|
|
}
|
|
|
|
$('html').removeEventListener('click.menu');
|
|
$(window).removeEventListener('keydown.menu');
|
|
$(window).removeEventListener('resize.menu');
|
|
};
|
|
|
|
/**
|
|
* Open the menu.
|
|
*/
|
|
beestat.component.menu.prototype.open_ = function() {
|
|
var self = this;
|
|
|
|
var position = this.icon_.get_container().getBoundingClientRect();
|
|
|
|
var container = $.createElement('div')
|
|
.style({
|
|
'background': '#fff',
|
|
'color': '#444',
|
|
'position': 'absolute',
|
|
'top': (position.bottom + window.scrollY) + 'px',
|
|
'right': (window.innerWidth - position.right) + 'px',
|
|
'transition': 'all 200ms ease',
|
|
'transform': 'scale(0)',
|
|
'transform-origin': 'top right',
|
|
'padding': (beestat.style.size.gutter / 2) + 'px 0',
|
|
'box-shadow': '0 2px 4px rgba(0,0,0,0.16), 0 2px 4px rgba(0,0,0,0.23)',
|
|
'user-select': 'none',
|
|
'border-radius': beestat.style.size.border_radius
|
|
});
|
|
|
|
$('body').appendChild(container);
|
|
this.container_ = container;
|
|
beestat.component.menu.open_menu = this;
|
|
|
|
this.menu_items_.forEach(function(menu_item) {
|
|
menu_item.render(container);
|
|
});
|
|
|
|
// Transition the element in after it's been placed on the page.
|
|
window.setTimeout(function() {
|
|
container.style('transform', 'scale(1)');
|
|
|
|
/*
|
|
* Close the element when clicking outside of it. For now I'm relying on
|
|
* contains where possible, and falling back to saying "if you click on the
|
|
* html document then close it too". If this starts to breakdown probably
|
|
* just need to switch to checking against the bounding box.
|
|
*/
|
|
$('html').addEventListener('click.menu', function(e) {
|
|
if (
|
|
(
|
|
e.target.contains(container[0]) === false &&
|
|
container[0].contains(e.target) === false
|
|
) ||
|
|
e.target.nodeName === 'HTML'
|
|
) {
|
|
self.dispose();
|
|
}
|
|
});
|
|
|
|
$(window).addEventListener('keydown.menu', function(e) {
|
|
if (e.which === 27) {
|
|
self.dispose();
|
|
}
|
|
});
|
|
|
|
$(window).addEventListener('resize.menu', function() {
|
|
self.dispose();
|
|
});
|
|
}, 0);
|
|
};
|
|
|
|
/**
|
|
* Set the text of the bubble.
|
|
*
|
|
* @param {string} bubble_text
|
|
*
|
|
* @return {beestat.component.menu} This.
|
|
*/
|
|
beestat.component.menu.prototype.set_bubble_text = function(bubble_text) {
|
|
this.bubble_text_ = bubble_text;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Set the color of the bubble.
|
|
*
|
|
* @param {string} bubble_color
|
|
*
|
|
* @return {beestat.component.menu} This.
|
|
*/
|
|
beestat.component.menu.prototype.set_bubble_color = function(bubble_color) {
|
|
this.bubble_color_ = bubble_color;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Add an item to the menu.
|
|
*
|
|
* @param {beestat.component.menu_item} menu_item
|
|
*
|
|
* @return {beestat.component.menu} This.
|
|
*/
|
|
beestat.component.menu.prototype.add_menu_item = function(menu_item) {
|
|
this.menu_items_.push(menu_item);
|
|
|
|
menu_item.set_menu(this);
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Remove an item from the menu.
|
|
*
|
|
* @param {beestat.component.menu_item} menu_item
|
|
*
|
|
* @return {beestat.component.menu} This.
|
|
*/
|
|
beestat.component.menu.prototype.remove_menu_item = function(menu_item) {
|
|
this.menu_items_.splice(
|
|
this.menu_items_.indexOf(menu_item),
|
|
1
|
|
);
|
|
|
|
return this;
|
|
};
|