more work on menu

This commit is contained in:
Sacha Greif 2015-10-07 21:50:48 +09:00
parent ba53b99927
commit 98f7352daf
9 changed files with 240 additions and 186 deletions

View file

@ -24,7 +24,7 @@ The name of the menu. Used to set a `*name*-menu` CSS class on the menu.
##### `menuLabel` (String/Function)
The menu title label, or a function that returns a label.
The menu title label, or a function that returns a label. Note that this is required for dropdown menus.
##### `menuLabelTemplate` (String)
@ -38,6 +38,10 @@ An optional CSS class given to the menu
A custom template used to display individual menu items (defaults to "defaultMenuItem")
##### `startPosition` (String)
For collapsible menus only, defines whether the menu should start off as `expanded` or `collapsed`. Defaults to `collapsed`.
### Menu Items Properties
Menu items can have the following properties:
@ -86,7 +90,7 @@ The parent node's id.
##### `isExpanded` (Boolean)
Whether the item's sub-menu should be expanded
Whether the item's sub-menu should start off expanded
### The Menu Item Template
@ -108,11 +112,7 @@ The current item to display.
Out of the box, the menu component accepts a few classes
#### No Class
If you pass no class to the menu, it will not receive any styling at all.
#### `menu-list`
#### `menu-list` (default)
A simple list. Serves as the base for the other styles.

View file

@ -24,13 +24,13 @@ getRoute = function (item) {
};
toggleMenu = function ($menuItem) {
if ($menuItem.hasClass("item-expanded")) {
if ($menuItem.hasClass("js-expanded")) {
$menuItem.find(".js-menu-items").first().slideUp('fast', function () {
$menuItem.removeClass("item-expanded");
$menuItem.removeClass("js-expanded").addClass("js-collapsed");
});
} else {
$menuItem.find(".js-menu-items").first().slideDown('fast', function () {
$menuItem.addClass("item-expanded");
$menuItem.addClass("js-expanded").removeClass("js-collapsed");
});
}
};

View file

@ -13,78 +13,84 @@
.menu-list, .menu-dropdown, .menu-collapsible{
.menu-item{
margin: 10px 0;
a{
font-size:14px;
}
&:first-child{
margin-top: 0px;
}
&:last-child{
margin-bottom: 0px;
// .menu-item{
// margin: 10px 0;
// a{
// font-size:14px;
// }
// &:first-child{
// margin-top: 0px;
// }
// &:last-child{
// margin-bottom: 0px;
// }
// }
// .menu-items-toggle{
// display: none;
// }
// .menu-item-wrapper{
// // padding: 5px 0px;
// }
// .menu-label{
// display: block;
// font-weight: bold;
// cursor: pointer;
// }
// .menu-description{
// display: block;
// font-weight: normal;
// font-size: 12px;
// margin-top: 2px;
// // color: $medium-text;
// }
// .item-active{
// .dark-bg &, .medium-dark-bg &{
// background: white(0.1);
// }
// .light-bg &, .medium-light-bg &, white-bg &{
// background: black(0.1);
// }
// }
// .item-active.item-never-active{
// background: none;
// }
// .menu-top-label{
// cursor: pointer;
// }
// .menu-no-items{
// .menu-label{
// pointer-events: none;
// .menu-items-toggle{
// display: none;
// }
// }
// }
// active item
.item-active{
.menu-item-label-text{
&:before{
content: "> ";
}
}
}
// toggle icons
.menu-items-toggle{
display: none;
}
.menu-item-wrapper{
// padding: 5px 0px;
}
.menu-label{
display: block;
font-weight: bold;
cursor: pointer;
}
.menu-description{
display: block;
font-weight: normal;
font-size: 12px;
margin-top: 2px;
// color: $medium-text;
}
.item-admin{
.menu-label:after{
content: "[A]";
font-size: 10px;
// color: $red;
display: inline-block;
margin-left: 3px;
}
}
.item-active{
.dark-bg &, .medium-dark-bg &{
border-radius: 100%;
border: 1px solid white(0.3);
&:hover{
background: white(0.1);
}
.light-bg &, .medium-light-bg &, white-bg &{
background: black(0.1);
}
}
.item-active.item-never-active{
background: none;
}
.menu-top-label{
cursor: pointer;
}
.menu-child-items, .menu-collapsible .menu-items{
padding-left: 10px;
border-left: 5px solid rgba(0,0,0,0.1);
margin: 10px 0 10px 6px;
.medium-dark-bg &, .dark-bg & {
border-color: rgba(255,255,255,0.1);
}
.light-bg &, .menu-dropdown & {
border-color: rgba(0,0,0,0.1);
}
}
.menu-no-items{
.menu-label{
pointer-events: none;
.menu-items-toggle{
display: none;
}
}
}
.menu-icon{
@ -100,20 +106,109 @@
fill: currentColor;
}
}
}
// ------------------------------------ List ------------------------------------ //
.menu-list{
.show-more{
}
// ------------------------------------ Collapsible ------------------------------------ //
.menu-collapsible{
// menu
.menu-label{
display: flex;
justify-content: space-between;
}
.menu-label-text, .menu-items-toggle{
display: block;
}
.menu-items{
// hide menu items by default
display: none;
}
.item-active{
background: black(0.05);
.menu-items-toggle{
display: block;
}
.menu-items, .menu-child-items{
padding-left: 10px;
border-left: 5px solid rgba(0,0,0,0.1);
margin: 10px 0 10px 6px;
.medium-dark-bg &, .dark-bg & {
border-color: rgba(255,255,255,0.1);
}
.light-bg &, .menu-dropdown & {
border-color: rgba(0,0,0,0.1);
}
}
// expanded menu
&.menu-component.js-expanded{
&>.menu-label-wrapper .menu-icon-expand{
display: none;
}
.menu-items{
display: block;
}
}
// collapsed menu
&.menu-component.js-collapsed{
&>.menu-label-wrapper .menu-icon-collapse{
display: none;
}
.menu-items{
display: none;
}
}
// menu item
.menu-item-label-wrapper{
display: flex;
justify-content: space-between;
}
.menu-item-label-text, .menu-items-toggle{
display: block;
}
.menu-child-items{
display: none;
}
// expanded menu item
.menu-item.js-expanded{
&>.menu-item-label-wrapper .menu-icon-expand{
display: none;
}
.menu-child-items{
display: block;
}
}
// collapsed menu item
.menu-item.js-collapsed{
&>.menu-item-label-wrapper .menu-icon-collapse{
display: none;
}
.menu-child-items{
display: none;
}
}
}
// ------------------------------------ Dropdown ------------------------------------ //
.menu-dropdown{
text-align: left;
position:relative;
&.menu-has-items{
@ -131,106 +226,43 @@
font-size:8px;
}
}
&:hover{
.menu-items{
display:block;
}
// menu items
.menu-items{
display:none;
top:30px;
left:10px;
position:absolute;
// padding-top:20px;
z-index: 10000;
background:white;
padding: 10px;
overflow: hidden; // prevent margin collapsing
min-width:180px;
border-radius: 3px;
box-shadow: 0 1px 3px black(0.35);
list-style-type: none;
}
&:hover{
// show menu items
.menu-items{
display:block;
}
// add special pseudo-element to preserve hover continuity between menu label and menu items
.menu-label{
&:after{
content: " ";
display: block;
position: absolute;
top: 10px;
width: 100%;
height: 20px;
}
}
}
.menu-items{
display:none;
top:10px;
left:10px;
position:absolute;
padding-top:20px;
z-index: 10000;
&, a, a:link, a:visited{
// color: $text;
}
.menu-items{
background:white;
padding: 10px;
overflow: hidden; // prevent margin collapsing
min-width:180px;
border-radius: 3px;
box-shadow: 0 1px 3px black(0.35);
list-style-type: none;
}
}
.show-more{
display: none;
}
}
// ------------------------------------ Collapsible ------------------------------------ //
.menu-collapsible{
.menu-label{
display: flex;
justify-content: space-between;
>span{
display: block;
}
}
.menu-items{
display: none;
}
.menu-item-label-wrapper{
display: flex;
justify-content: space-between;
}
.menu-sub-level{
display: block;
}
.menu-items-toggle{
display: block;
border-radius: 100%;
border: 1px solid white(0.3);
&:hover{
background: white(0.1);
}
}
.menu-icon-expand{
display: flex;
}
.menu-icon-collapse{
display: none;
}
.menu-child-items{
display: none;
// max-height: 0px;
// transition: max-height 300ms ease-out;
// overflow: hidden;
}
}
.item-expanded{
.menu-items{
display: block;
}
&>.menu-label-wrapper, &>.menu-item-label-wrapper{
.menu-icon-expand{
display: none;
}
.menu-icon-collapse{
display: flex;
}
}
&>.menu-child-items{
display: block;
// max-height: none;
}
}
.menu-always-expanded{
.menu-items{
display: block;
padding-left: 0px;
border: none;
margin: 0;
}
.menu-label .menu-items-toggle{
display: none;
}
}

View file

@ -21,7 +21,9 @@ Template.menuComponent.helpers({
var count = this.menuItems.length;
if (!!this.menuClass) {
classes.push(this.menuClass)
classes.push(this.menuClass);
} else {
classes.push("menu-list");
}
if (count) {
@ -30,6 +32,16 @@ Template.menuComponent.helpers({
classes.push("menu-no-items");
}
if (!!this.startPosition) {
if (this.startPosition === "expanded") {
classes.push("js-expanded");
} else {
classes.push("js-collapsed");
}
} else {
classes.push("js-collapsed");
}
return _.unique(classes).join(" ");
},
@ -115,7 +127,9 @@ Template.menuItem.helpers({
}
if (Template.instance().expanded) {
itemClass += " item-expanded";
itemClass += " js-expanded";
} else {
itemClass += " js-collapsed";
}
if (this.item.itemClass) {

View file

@ -8,7 +8,7 @@ var getMenuItems = function () {
});
viewableItems = _.map(viewableItems, function (item) {
item.itemClass = "view-"+item.label;
item.itemClass = "view-"+item.name;
return item;
});

View file

@ -51,6 +51,11 @@ $red: #DD3416;
font-weight: normal;
opacity: 0.5;
}
.side-nav & .menu-items{
padding-left: 0;
border-left: none;
margin: 0;
}
}
.side-nav{
.categories-menu{

View file

@ -1,7 +1,7 @@
<template name="categories_menu">
<div class="categories-menu-wrapper {{moduleClass}}">
{{#if hasCategories}}
{{> menuComponent menuName="categories" itemTemplate="categories_menu_item" menuItems=menuItems menuClass=menuClass}}
{{> menuComponent menuName="categories" menuLabel=menuLabel itemTemplate="categories_menu_item" menuItems=menuItems menuClass=menuClass startPosition="expanded"}}
{{/if}}
</div>
</template>

View file

@ -11,6 +11,9 @@ Meteor.startup(function () {
hasCategories: function () {
return Categories.find().count();
},
menuLabel: function () {
return i18n.t("categories");
},
menuItems: function () {
var activeCategories = FlowRouter.getQueryParam("cat");

View file

@ -51,10 +51,10 @@
border-radius: 3px;
padding: 10px;
margin-bottom: 10px;
.menu-top-level, .menu-wrapper, .menu-contents, .menu-item{
.menu-label-wrapper, .menu-items, .menu-item{
display: inline-block;
}
.menu-top-level{
.menu-label-wrapper{
margin-right: 10px;
&:after{
content: ": ";