├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── assets ├── css │ ├── _responsive.scss │ ├── _tabelinha.scss │ ├── _uk-form.scss │ ├── _vars.scss │ ├── config │ │ ├── _config.scss │ │ ├── _mixins.scss │ │ └── _system.scss │ ├── owl-theme │ │ ├── _theme-default.scss │ │ └── _theme.scss │ ├── style.css │ ├── style.css.map │ └── style.scss ├── favicon.png ├── fonts │ ├── AlexBrush-Regular.eot │ ├── AlexBrush-Regular.svg │ ├── AlexBrush-Regular.ttf │ ├── AlexBrush-Regular.woff │ ├── Aquino-Demo.eot │ ├── Aquino-Demo.svg │ ├── Aquino-Demo.ttf │ ├── Aquino-Demo.woff │ └── _fonts.scss ├── img │ ├── Thumbs.db │ ├── flavors-border.png │ ├── header-append.png │ ├── header-bg.jpg │ ├── i-header-1.png │ ├── i-header-2.png │ ├── i-header-3.png │ ├── i-header-4.png │ ├── i-header-5.png │ ├── i-header-6.png │ ├── menuchef-bg.png │ └── menuchef-logo.png └── js │ ├── MenuChef.js │ ├── MenuChef.js.map │ ├── rellax.min.js │ └── tabelinha.min.js ├── dist ├── MenuChef.js ├── MenuChef.js.map └── index.html ├── doc.json ├── favicon.ico ├── gulpfile.js ├── img └── menuchef-logo.png ├── index.html ├── package-lock.json ├── package.json ├── site ├── _footer.twig ├── _header.twig ├── base.twig ├── index.twig └── macros.twig ├── src ├── MenuChef.js ├── helpers │ ├── forEach.js │ ├── masterCook.js │ ├── setCssVar.js │ ├── setIF.js │ └── setPublicVar.js └── templates │ ├── button.html │ ├── default.html │ ├── full.scss │ ├── main.scss │ ├── mixins.scss │ ├── schemes │ ├── _black.scss │ ├── _blue.scss │ ├── _green.scss │ ├── _red.scss │ ├── _scheme.scss │ └── _yellow.scss │ └── side.scss ├── test ├── MenuChef.test.js ├── chai.js ├── index.html ├── mocha.css ├── mocha.js └── shim.min.js └── webpack.config.babel.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Matheus Falcão 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MenuChef 2 | 3 | []() 5 | [](http://standardjs.com/) 6 | 7 |
8 |
9 |
171 | MenuChef helps you to create hamburgers' menu easily even without knowing how to cook. You just need call the MenuChef.js in your page and initiate like the examples above. It's light (approximately 55kb, 13kb gzipped) and you don't need change the HTML code of the menu original. You can personalize it by CSS or by options. 172 |
173 | 174 |175 | You can download the latest version of MenuChef in Github or can use the unpkg CDN 176 |
177 | 178 |<script src="//unpkg.com/menuchef@{{version}}"></script>
179 |
180 | Variable | 201 |Type | 202 |Default | 203 |Description | 204 |
---|---|---|---|
{{ label(search(item.tags, 'title', 'type').description) }} | 211 |{{ search(item.tags, 'title', 'default').description }} | 212 |{{ search(item.tags, 'title', 'description').description }} | 213 |
Variable | 223 |Type | 224 |Default | 225 |Description | 226 |
---|---|---|---|
{{ label(search(item.tags, 'title', 'type').description) }} | 233 |{{ search(item.tags, 'title', 'default').description }} | 234 |{{ search(item.tags, 'title', 'description').description }} | 235 |
Variable | 245 |Type | 246 |Default | 247 |Description | 248 |
---|---|---|---|
{{ label(search(item.tags, 'title', 'type').description) }} | 255 |{{ search(item.tags, 'title', 'default').description }} | 256 |{{ search(item.tags, 'title', 'description').description }} | 257 |
Variable | 267 |Type | 268 |Default | 269 |Description | 270 |
---|---|---|---|
{{ label(search(item.tags, 'title', 'type').description) }} | 277 |{{ search(item.tags, 'title', 'default').description }} | 278 |{{ search(item.tags, 'title', 'description').description }} | 279 |
Variable | 289 |Type | 290 |Default | 291 |Description | 292 |
---|---|---|---|
{{ label(search(item.tags, 'title', 'type').description) }} | 299 |{{ search(item.tags, 'title', 'default').description }} | 300 |{{ search(item.tags, 'title', 'description').description }} | 301 |
310 | MenuChef was created with CSS variables, so it's very easy change some elements of the interface just changing a couple of variables, with sort, without change the CSS in fact. The support of CSS variables isn't complete yet in some browsers, so if you want support those browsers, you can overwrite CSS theme default below. If you choose overwrite the CSS theme, don't forget to put !important
because the MenuChef's style is injected by JS, so you CSS can't overwrite by cascade.
311 |
/* open hamburger button */
314 | .MenuChefOpen .hamburger-inner,
315 | .MenuChefOpen .hamburger-inner::before,
316 | .MenuChefOpen .hamburger-inner::after {
317 | background-color: #A0A1A5 !important; /* fallback */
318 | background-color: var(--MenuChef-scheme-color, #A0A1A5) !important; /* try use CSS var with fallback */
319 | }
320 |
321 | /* close hamburger button */
322 | .MenuChefOpen.is-active .hamburger-inner,
323 | .MenuChefOpen.is-active .hamburger-inner::before,
324 | .MenuChefOpen.is-active .hamburger-inner::after {
325 | background-color: #28292E !important; /* fallback */
326 | background-color: var(--MenuChef-scheme-color, #28292E) !important; /* try use CSS var with fallback */
327 | }
328 |
329 | /* Menuchef kitchen: link's area */
330 | .MenuChef {
331 | background-color: #28292E !important; /* fallback */
332 | background-color: var(--MenuChef-scheme-bgcolor, #28292E) !important; /* try use CSS var with fallback */
333 | }
334 |
335 | /* Menuchef links */
336 | .MenuChef .MenuChef-links-link {
337 | color: #A0A1A5 !important; /* fallback */
338 | color: var(--MenuChef-scheme-color, #A0A1A5) !important; /* try use CSS var with fallback */
339 | }
340 |
341 | /* Menuchef links hover */
342 | .MenuChef .MenuChef-links-link:hover {
343 | color: #86878c !important; /* fallback */
344 | color: var(--MenuChef-scheme-color-hover, #86878c) !important; /* try use CSS var with fallback */
345 | }
346 |
347 | Variable | 351 | 352 |Default | 353 |Description | 354 |
---|---|---|
It depend's of scheme | 360 |MenuChef kitchen's background color | 361 ||
It depend's of scheme | 366 |Links color | 367 ||
It depend's of scheme | 372 |Links hover color | 373 |
Variable | 383 | 384 |Default | 385 |Description | 386 |
---|---|---|
'Helvetica', 'Arial', sans-serif | 392 |Font family of links | 393 ||
16px | 397 |Font size of links | 398 ||
25px | 402 |Margin bottom between links | 403 ||
uppercase | 407 |Text transform of links | 408 ||
color linear .15s | 412 |Transition for links hover | 413 ||
bold | 417 |Links font weight | 418 ||
20% | 422 |Default width of MenuChef's kitchen | 423 ||
240px | 427 |Minimum width of MenuChef's kitchen | 428 |
436 | Example of all MenuChef default options 437 |
438 | 439 |new MenuChef('.old-menu a', {
440 | theme: {
441 | theme: 'full',
442 | effectOnOpen: '',
443 | direction: '',
444 | pageEffect: ''
445 | },
446 |
447 | scheme: 'black',
448 | closeOnClick: true,
449 | closeOnClickOutside: true,
450 |
451 | classes: {
452 | exclude: [],
453 | only: [],
454 | include: []
455 | },
456 |
457 | hamburger: 'boring',
458 | bodyClassOpen: '',
459 | kitchenClass: '',
460 | kitchenOpenClass: '',
461 |
462 | onOpen: function () {},
463 | onClose: function () {},
464 | onClick: function () {},
465 | onReady: function () {}
466 | });
467 |
468 | <i class="myicon"></i>
.
155 | * is-active
when MenuChef is open.
157 | */
158 | button: buttonDefault,
159 | /**
160 | * @module options
161 | * @variable classes
162 | * @type object
163 | * @default --
164 | * @released 1.1.0
165 | * @description Classes is a manager of classes in links passed to MenuChef. It reveives 3 properties. All properties receives ONLY array
of classes.
166 | * array
of classes
168 | * array
of classes
170 | * array
of classes
172 | * null
if MenuChef was never opened, true
/>false
classe
default is is-active
441 | * @description Toggle MenuChefthis
is passed, toggle is fired and return the classe
to the element this
. Only works when the function toggle() itself is triggered
442 | */
443 | MenuChef.toggle = function (el = false, classe = 'is-active') {
444 | if (self._kitchen.classList.contains(self._themeOpenClass)) {
445 | MenuChef.close()
446 | if (el) el.classList.remove(classe)
447 | } else {
448 | MenuChef.open()
449 | if (el) el.classList.add(classe)
450 | }
451 | }
452 | MenuChef._watcher = function (e) {
453 | const searchKitchen = (el) => {
454 | try {
455 | return el.getAttribute('onclick').includes('MenuChef.toggle')
456 | } catch (err) {}
457 |
458 | try {
459 | return el.classList.contains(self._kitchenLinksClass) || el.classList.contains(self._kitchenClass)
460 | } catch (err) {}
461 | }
462 | /**
463 | * @private
464 | * Close MenuChef if is clicked outside
465 | * Don't close if is clicked in kitchen or in a button with
466 | * MenuChef.toggle() function on onclick because the watcher
467 | * closes the MenuChef before the toggle(), who mistakenly opened
468 | */
469 |
470 | try {
471 | if (e.path.filter(searchKitchen).length === 0) MenuChef.close()
472 | } catch (e) {}
473 | }
474 | /**
475 | * @module public_methods
476 | * @variable MenuChef.destroy()
477 | * @type function
478 | * @default -
479 | * @description Destroy MenuChef instance, HTML inserts and watchers
480 | */
481 | MenuChef.destroy = function () {
482 | masterCook(document.body, self._classes.init.body, 'remove')
483 | const kitchen = document.querySelector(`.${self._kitchenClass}`)
484 | const kitchenButtonOpen = document.querySelector(`.MenuChefOpen`)
485 |
486 | kitchen.parentNode.removeChild(kitchen)
487 | kitchenButtonOpen.parentNode.removeChild(kitchenButtonOpen)
488 | }
489 | }
490 |
491 | chefObserver (type = 'addWatch') {
492 | if (type === 'addWatch') {
493 | document.addEventListener('click', MenuChef._watcher, true)
494 | }
495 |
496 | if (type === 'removeWatch') {
497 | document.removeEventListener('click', MenuChef._watcher, true)
498 | }
499 | }
500 | }
501 |
502 | window.MenuChef = MenuChef
503 |
--------------------------------------------------------------------------------
/src/helpers/forEach.js:
--------------------------------------------------------------------------------
1 | // https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
2 | // forEach method, could be shipped as part of an Object Literal/Module
3 | export default function (array, callback, scope) {
4 | for (let i = 0; i < array.length; i++) {
5 | callback.call(scope, i, array[i])
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/helpers/masterCook.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @function masterCook
4 | *
5 | * @description Add or remove automatically an array of classes in a Element
6 | *
7 | * @param {el} HTML Element @required
8 | * @param {classList} Array @required
9 | * @param {method} String add or remove @default add
10 | *
11 | * @return undefined
12 | *
13 | */
14 |
15 | export default function (el, classList, method = 'add') {
16 | // if (!!el) cosole.error('masterCook needs an element to manage')
17 | // if (!!classList) cosole.error('masterCook needs a classList to work with element')
18 |
19 | for (let classe in classList) {
20 | let _classe = classList[classe]
21 | if (!!_classe) { // eslint-disable-line no-extra-boolean-cast
22 | try {
23 | el.classList[method](_classe)
24 | } catch (e) {
25 | console.warn(e)
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/helpers/setCssVar.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @function setCssVar
4 | *
5 | * @description Try to set a CSS variable
6 | *
7 | * @param {variable} String variable @required
8 | * @param {value} String value @required
9 | *
10 | * @return null
11 | *
12 | */
13 |
14 | export default function (variable, value) {
15 | try {
16 | document.documentElement.style.setProperty(variable, value)
17 | } catch (e) {
18 | console.warn('MenuChef failed to change a CSS variable', e)
19 | }
20 | }
--------------------------------------------------------------------------------
/src/helpers/setIF.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @function setIF
4 | *
5 | * @description Verify determined condition and return passed value. If not, return default value
6 | * The condition don't need exist and don't break the program
7 | *
8 | * @param {val} String value @required
9 | * @param {condition} String condition to be analized @required
10 | * @param {defaultVal} String @default '' @optional
11 | *
12 | * @return val || defaultVal
13 | *
14 | */
15 |
16 | export default function (val, condition, defaultVal = '') {
17 | try {
18 | if (condition && val) return val
19 | } catch (e) {}
20 | return defaultVal
21 | }
22 |
--------------------------------------------------------------------------------
/src/helpers/setPublicVar.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @function setPublicVar
4 | *
5 | * @description Set readonly public variable to a object
6 | *
7 | * @param {obj} Object destination @required
8 | * @param {location} Object source @required
9 | * @param {variable} String source variable @required
10 | * @param {variableLocation} String if source variable isn't the same name
11 | *
12 | * @return Object.defineProperty
13 | *
14 | */
15 |
16 | export default function (obj, location, variable, variableLocation = variable) {
17 | if (obj['hasOwnProperty'](variable)) delete obj[variable]
18 | return Object.defineProperty(obj, variable, {
19 | configurable: true,
20 | get () {
21 | return location[variableLocation]
22 | },
23 | set (val) {
24 | console.warn(`${obj.name}.${variable} is readonly`)
25 | }
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/src/templates/button.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/templates/default.html:
--------------------------------------------------------------------------------
1 |