├── .gitignore
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── dist
├── css
│ ├── astro.css
│ └── astro.min.css
└── js
│ ├── astro.js
│ └── astro.min.js
├── docs
├── dist
│ ├── css
│ │ ├── astro.css
│ │ └── astro.min.css
│ └── js
│ │ ├── astro.js
│ │ └── astro.min.js
└── index.html
├── gulpfile.js
├── package.json
└── src
├── docs
├── _templates
│ ├── _footer.html
│ └── _header.html
└── index.md
├── js
└── astro.js
└── sass
├── _config.scss
├── _mixins.scss
├── astro.scss
└── components
└── _astro.scss
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node
2 | node_modules
3 | test/results
4 | test/coverage
5 |
6 | ## OS X
7 | .DS_Store
8 | ._*
9 | .Spotlight-V100
10 | .Trashes
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | before_script:
5 | - npm install -g gulp
6 | script: gulp
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | I'm delighted that you're helping make this open source project better. Here are a few quick guidelines to make this an easier and better process for everyone.
4 |
5 |
6 |
7 | ## Reporting a bug
8 |
9 | First, **make sure the bug hasn't already been reported** by searching GitHub's issues section.
10 |
11 | If no existing issue exists, go ahead and create one. **Please be sure to include all of the following:**
12 |
13 | 1. A clear, descriptive title (ie. "A bug" is *not* a good title).
14 | 2. [A reduced test case.](https://css-tricks.com/reduced-test-cases/) In order to debug code issues, I need to see actual code in a browser.
15 | 3. The browser and OS that you're using.
16 |
17 |
18 |
19 | ## Asking a question
20 |
21 | Before asking, please **make sure the question hasn't already been asked** by searching GitHub's issues section.
22 |
23 |
24 |
25 | ## Submitting a Pull Request
26 |
27 | Please make sure your code meets the following code standards:
28 |
29 | - Camel case for JavaScript variables.
30 | - [Object-Oriented CSS](http://www.slideshare.net/stubbornella/object-oriented-css) for CSS selectors.
31 | - Favor readable code over brevity. The build process will reduce size, so opt for readability. (ex. `var navigation` is better than `var n`)
32 | - Order CSS properties alphabetically.
33 | - Hard tabs.
34 |
35 | Before submitting, make sure that you've:
36 |
37 | - Updated the version number using semantic versioning.
38 | - Made your changes in the `src` folder.
39 | - Run the Gulp build to compile, minify, and update version numbers into the `dist` folder. If you cannot do this, please note this in the Pull Request.
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # The MIT License (MIT)
2 |
3 | Copyright (c) Go Make Things, LLC
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 | # Astro [](https://travis-ci.org/cferdinandi/astro)
2 | A mobile-first navigation pattern, with an optional expand-and-collapse menu on small screens.
3 |
4 | [Download Astro](https://github.com/cferdinandi/astro/archive/master.zip) / [View the demo](http://cferdinandi.github.io/astro/)
5 |
6 |
7 |
8 |
9 | ### Want to learn how to write your own vanilla JS plugins? Check out ["The Vanilla JS Guidebook"](https://gomakethings.com/vanilla-js-guidebook/) and level-up as a web developer. 🚀
10 |
11 |
12 |
13 |
14 |
15 | ## Getting Started
16 |
17 | Compiled and production-ready code can be found in the `dist` directory. The `src` directory contains development code.
18 |
19 | ### 1. Include Astro on your site.
20 |
21 | ```html
22 |
23 |
24 | ```
25 |
26 | The optional expand-and-collapse menu on smaller screens requires `astro.js`. Basic versions can omit this file.
27 |
28 | ### 2. Add the markup to your HTML.
29 |
30 | Make sure that the `[data-nav-toggle]` value matches the ID of the `.nav-menu` section. To activate expand-and-collapse functionality, add the `.nav-collapse` class to the `.nav-wrap` element.
31 |
32 | ```html
33 |
43 | ```
44 |
45 |
46 | ### 3. Initialize Astro.
47 |
48 | If you're using the expand-and-collapse menu for smaller screens, initialize Astro in the footer of your page, after the content. And that's it, you're done. Nice work!
49 |
50 | ```html
51 |
54 | ```
55 |
56 |
57 |
58 | ## Installing with Package Managers
59 |
60 | You can install Astro with your favorite package manager.
61 |
62 | * **NPM:** `npm install cferdinandi/astro`
63 | * **Bower:** `bower install https://github.com/cferdinandi/astro.git`
64 | * **Component:** `component install cferdinandi/astro`
65 |
66 |
67 |
68 | ## Working with the Source Files
69 |
70 | If you would prefer, you can work with the development code in the `src` directory using the included [Gulp build system](http://gulpjs.com/). This compiles, lints, and minifies code.
71 |
72 | ### Dependencies
73 | Make sure these are installed first.
74 |
75 | * [Node.js](http://nodejs.org)
76 | * [Gulp](http://gulpjs.com) `sudo npm install -g gulp`
77 |
78 | ### Quick Start
79 |
80 | 1. In bash/terminal/command line, `cd` into your project directory.
81 | 2. Run `npm install` to install required files.
82 | 3. When it's done installing, run one of the task runners to get going:
83 | * `gulp` manually compiles files.
84 | * `gulp watch` automatically compiles files and applies changes using [LiveReload](http://livereload.com/).
85 |
86 |
87 |
88 | ## Active Link Styling
89 |
90 | There's a placeholder in the CSS to add styling to the current page in the navigation menu.
91 |
92 | ```css
93 | /* Placeholder for active link styling */
94 | /* .nav > li.active > a { */
95 | /* Add your styles here */
96 | /* } */
97 | ```
98 |
99 | ***Note:*** *If you're using WordPress, check out [this great tutorial by Todd Motto](http://www.toddmotto.com/highlight-your-current-page-with-wordpress-conditionals) on how to add the `.active` class using a simple PHP function.*
100 |
101 |
102 |
103 | ## Options and Settings
104 |
105 | Astro includes smart defaults and works right out of the box. But if you want to customize things, it also has a robust API that provides multiple ways for you to adjust the default options and settings.
106 |
107 | ### Global Settings
108 |
109 | You can pass options and callbacks into Astro through the `init()` function:
110 |
111 | ```javascript
112 | astro.init({
113 | selector: '[data-nav-toggle]', // Navigation toggle selector
114 | toggleActiveClass: 'active', // Class added to active dropdown toggles on small screens
115 | navActiveClass: 'active', // Class added to active dropdown content areas on small screens
116 | initClass: 'js-astro', // Class added to `` element when initiated
117 | callback: function ( toggle, navID ) {} // Function that's run after a dropdown is toggled
118 | });
119 | ```
120 |
121 | ***Note:*** *If you change the `selector`, you still need to include the `[data-nav-toggle]` attribute in order to pass in the selector for the navigation menu.*
122 |
123 | ### Use Astro events in your own scripts
124 |
125 | You can also call Astro's navigation toggle event in your own scripts.
126 |
127 | #### toggleNav()
128 | Expand or collapse a navigation menu.
129 |
130 | ```javascript
131 | astro.toggleNav(
132 | toggle, // Node that toggles the dropdown action. ex. document.querySelector('#toggle')
133 | navID, // ID of the navigation content wrapper. ex. '#nav-menu'
134 | options, // Classes and callbacks. Same options as those passed into the init() function.
135 | event // Optional, if a DOM event was triggered.
136 | );
137 | ```
138 |
139 | **Example**
140 |
141 | ```javascript
142 | astro.toggleNav( null, '#nav-menu' );
143 | ```
144 |
145 | #### destroy()
146 | Destroy the current `astro.init()`. This is called automatically during the init function to remove any existing initializations.
147 |
148 | ```javascript
149 | astro.destroy();
150 | ```
151 |
152 |
153 | ## Browser Compatibility
154 |
155 | Astro works in all modern browsers, and IE 10 and above. You can extend browser support back to IE 9 with the [classList.js polyfill](https://github.com/eligrey/classList.js/).
156 |
157 | Astro is built with modern JavaScript APIs, and uses progressive enhancement. If the JavaScript file fails to load, or if your site is viewed on older and less capable browsers, the Basic navigation patterns will be displayed instead of the Plus versions.
158 |
159 |
160 |
161 | ## How to Contribute
162 |
163 | In lieu of a formal style guide, take care to maintain the existing coding style. Please apply fixes to both the development and production code. Don't forget to update the version number, and when applicable, the documentation.
164 |
165 |
166 |
167 | ## License
168 |
169 | The code is available under the [MIT License](LICENSE.md).
--------------------------------------------------------------------------------
/dist/css/astro.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Astro v10.2.0: Mobile-first navigation patterns
3 | * (c) 2016 Chris Ferdinandi
4 | * MIT License
5 | * http://github.com/cferdinandi/astro
6 | */
7 |
8 | /**
9 | * Text alignment
10 | */
11 | /* line 4, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
12 | .nav-wrap {
13 | text-align: center;
14 | }
15 |
16 | @media (max-width: 40em) {
17 | /* line 8, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
18 | .js-astro .nav-wrap.nav-collapse {
19 | text-align: left;
20 | }
21 | }
22 |
23 | @media (min-width: 40em) {
24 | /* line 4, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
25 | .nav-wrap {
26 | text-align: left;
27 | }
28 | }
29 |
30 | /**
31 | * Logo
32 | */
33 | /* line 22, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
34 | .logo {
35 | color: #272727;
36 | display: inline-block;
37 | font-size: 1.2em;
38 | line-height: 1.2;
39 | margin-bottom: 0.5em;
40 | text-decoration: none;
41 | }
42 |
43 | /* line 30, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
44 | .logo:hover {
45 | color: #272727;
46 | text-decoration: none;
47 | }
48 |
49 | @media (min-width: 40em) {
50 | /* line 36, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
51 | .js-astro .nav-collapse .logo {
52 | float: left;
53 | }
54 | }
55 |
56 | @media (min-width: 40em) {
57 | /* line 22, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
58 | .logo {
59 | float: left;
60 | }
61 | }
62 |
63 | /**
64 | * Navigation Menu Container
65 | */
66 | @media (max-width: 40em) {
67 | /* line 53, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
68 | .js-astro .nav-collapse .nav-menu {
69 | box-sizing: border-box;
70 | display: none;
71 | width: 100%;
72 | }
73 | /* line 58, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
74 | .js-astro .nav-collapse .nav-menu.active {
75 | display: block;
76 | }
77 | /* line 62, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
78 | .js-astro .nav-collapse .nav-menu li {
79 | display: block;
80 | width: 100%;
81 | padding-top: 0.25em;
82 | padding-bottom: 0.25em;
83 | box-sizing: border-box;
84 | }
85 | }
86 |
87 | /**
88 | * Navigation Menu
89 | */
90 | /* line 77, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
91 | .nav {
92 | list-style: none;
93 | margin: 0 -0.5em;
94 | padding: 0;
95 | }
96 |
97 | /* line 82, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
98 | .nav > li {
99 | display: inline-block;
100 | float: none;
101 | margin-left: 0.5em;
102 | margin-right: 0.5em;
103 | }
104 |
105 | @media (max-width: 40em) {
106 | /* line 93, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
107 | .js-astro .nav-collapse .nav {
108 | text-align: left;
109 | }
110 | }
111 |
112 | @media (min-width: 40em) {
113 | /* line 77, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
114 | .nav {
115 | text-align: right;
116 | }
117 | }
118 |
119 | /**
120 | * Navigation Toggle
121 | */
122 | /* line 107, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
123 | .nav-toggle {
124 | display: none;
125 | visibility: hidden;
126 | }
127 |
128 | @media (max-width: 40em) {
129 | /* line 112, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
130 | .js-astro .nav-collapse .nav-toggle {
131 | display: block;
132 | float: right;
133 | visibility: visible;
134 | }
135 | }
136 |
137 | /**
138 | * Clearfix
139 | */
140 | /* line 125, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
141 | .nav-wrap:before,
142 | .nav-wrap:after {
143 | display: table;
144 | content: "";
145 | }
146 |
147 | /* line 131, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
148 | .nav-wrap:after {
149 | clear: both;
150 | }
151 |
--------------------------------------------------------------------------------
/dist/css/astro.min.css:
--------------------------------------------------------------------------------
1 | /*! Astro v10.2.0 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/astro */
2 | .nav-wrap{text-align:center}@media (max-width:40em){.js-astro .nav-wrap.nav-collapse{text-align:left}}@media (min-width:40em){.nav-wrap{text-align:left}}.logo{display:inline-block;font-size:1.2em;line-height:1.2;margin-bottom:.5em}.logo,.logo:hover{color:#272727;text-decoration:none}@media (min-width:40em){.js-astro .nav-collapse .logo,.logo{float:left}}@media (max-width:40em){.js-astro .nav-collapse .nav-menu{box-sizing:border-box;display:none;width:100%}.js-astro .nav-collapse .nav-menu.active{display:block}.js-astro .nav-collapse .nav-menu li{display:block;width:100%;padding-top:.25em;padding-bottom:.25em;box-sizing:border-box}}.nav{list-style:none;margin:0 -.5em;padding:0}.nav>li{display:inline-block;float:none;margin-left:.5em;margin-right:.5em}@media (max-width:40em){.js-astro .nav-collapse .nav{text-align:left}}@media (min-width:40em){.nav{text-align:right}}.nav-toggle{display:none;visibility:hidden}@media (max-width:40em){.js-astro .nav-collapse .nav-toggle{display:block;float:right;visibility:visible}}.nav-wrap:after,.nav-wrap:before{display:table;content:""}.nav-wrap:after{clear:both}
--------------------------------------------------------------------------------
/dist/js/astro.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Astro v10.2.0: Mobile-first navigation patterns
3 | * (c) 2016 Chris Ferdinandi
4 | * MIT License
5 | * http://github.com/cferdinandi/astro
6 | */
7 |
8 | (function (root, factory) {
9 | if ( typeof define === 'function' && define.amd ) {
10 | define([], factory(root));
11 | } else if ( typeof exports === 'object' ) {
12 | module.exports = factory(root);
13 | } else {
14 | root.astro = factory(root);
15 | }
16 | })(typeof global !== 'undefined' ? global : this.window || this.global, (function (root) {
17 |
18 | 'use strict';
19 |
20 | //
21 | // Variables
22 | //
23 |
24 | var astro = {}; // Object for public APIs
25 | var supports = 'querySelector' in document && 'addEventListener' in root && 'classList' in document.createElement('_'); // Feature test
26 | var settings;
27 |
28 | // Default settings
29 | var defaults = {
30 | selector: '[data-nav-toggle]',
31 | toggleActiveClass: 'active',
32 | navActiveClass: 'active',
33 | initClass: 'js-astro',
34 | callback: function () {}
35 | };
36 |
37 |
38 | //
39 | // Methods
40 | //
41 |
42 | /**
43 | * Merge defaults with user options
44 | * @private
45 | * @param {Object} defaults Default settings
46 | * @param {Object} options User options
47 | * @returns {Object} Merged values of defaults and options
48 | */
49 | var extend = function () {
50 |
51 | // Variables
52 | var extended = {};
53 | var deep = false;
54 | var i = 0;
55 | var length = arguments.length;
56 |
57 | // Check if a deep merge
58 | if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) {
59 | deep = arguments[0];
60 | i++;
61 | }
62 |
63 | // Merge the object into the extended object
64 | var merge = function (obj) {
65 | for ( var prop in obj ) {
66 | if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
67 | // If deep merge and property is an object, merge properties
68 | if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {
69 | extended[prop] = buoy.extend( true, extended[prop], obj[prop] );
70 | } else {
71 | extended[prop] = obj[prop];
72 | }
73 | }
74 | }
75 | };
76 |
77 | // Loop through each object and conduct a merge
78 | for ( ; i < length; i++ ) {
79 | var obj = arguments[i];
80 | merge(obj);
81 | }
82 |
83 | return extended;
84 |
85 | };
86 |
87 | /**
88 | * Get the closest matching element up the DOM tree.
89 | * @private
90 | * @param {Element} elem Starting element
91 | * @param {String} selector Selector to match against
92 | * @return {Boolean|Element} Returns null if not match found
93 | */
94 | var getClosest = function ( elem, selector ) {
95 |
96 | // Element.matches() polyfill
97 | if (!Element.prototype.matches) {
98 | Element.prototype.matches =
99 | Element.prototype.matchesSelector ||
100 | Element.prototype.mozMatchesSelector ||
101 | Element.prototype.msMatchesSelector ||
102 | Element.prototype.oMatchesSelector ||
103 | Element.prototype.webkitMatchesSelector ||
104 | function(s) {
105 | var matches = (this.document || this.ownerDocument).querySelectorAll(s),
106 | i = matches.length;
107 | while (--i >= 0 && matches.item(i) !== this) {}
108 | return i > -1;
109 | };
110 | }
111 |
112 | // Get closest match
113 | for ( ; elem && elem !== document; elem = elem.parentNode ) {
114 | if ( elem.matches( selector ) ) return elem;
115 | }
116 |
117 | return null;
118 |
119 | };
120 |
121 | /**
122 | * Show and hide navigation menu
123 | * @public
124 | * @param {Element} toggle Element that triggered the toggle
125 | * @param {String} navID The ID of the navigation element to toggle
126 | * @param {Object} settings
127 | * @param {Event} event
128 | */
129 | astro.toggleNav = function ( toggle, navID, options, event ) {
130 |
131 | // Selectors and variables
132 | var settings = extend( settings || defaults, options || {} ); // Merge user options with defaults
133 | var nav = document.querySelector(navID);
134 |
135 | toggle.classList.toggle( settings.toggleActiveClass ); // Toggle the '.active' class on the toggle element
136 | nav.classList.toggle( settings.navActiveClass ); // Toggle the '.active' class on the menu
137 | settings.callback( toggle, navID ); // Run callbacks after toggling nav
138 |
139 | };
140 |
141 | /**
142 | * Handle click event methods
143 | * @private
144 | */
145 | var eventHandler = function (event) {
146 | var toggle = getClosest(event.target, settings.selector);
147 | if ( toggle ) {
148 | // Prevent default click event
149 | if ( toggle.tagName.toLowerCase() === 'a') {
150 | event.preventDefault();
151 | }
152 | // Toggle nav
153 | astro.toggleNav( toggle, toggle.getAttribute('data-nav-toggle'), settings );
154 | }
155 | };
156 |
157 | /**
158 | * Destroy the current initialization.
159 | * @public
160 | */
161 | astro.destroy = function () {
162 | if ( !settings ) return;
163 | document.documentElement.classList.remove( settings.initClass );
164 | document.removeEventListener('click', eventHandler, false);
165 | settings = null;
166 | };
167 |
168 | /**
169 | * Initialize Astro
170 | * @public
171 | * @param {Object} options User settings
172 | */
173 | astro.init = function ( options ) {
174 |
175 | // feature test
176 | if ( !supports ) return;
177 |
178 | // Destroy any existing initializations
179 | astro.destroy();
180 |
181 | // Selectors and variables
182 | settings = extend( defaults, options || {} ); // Merge user options with defaults
183 |
184 | // Listeners and methods
185 | document.documentElement.classList.add( settings.initClass ); // Add class to HTML element to activate conditional CSS
186 | document.addEventListener('click', eventHandler, false); // Listen for click events and run event handler
187 |
188 | };
189 |
190 |
191 | //
192 | // Public APIs
193 | //
194 |
195 | return astro;
196 |
197 | }));
--------------------------------------------------------------------------------
/dist/js/astro.min.js:
--------------------------------------------------------------------------------
1 | /*! Astro v10.2.0 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/astro */
2 | !(function(t,e){"function"==typeof define&&define.amd?define([],e(t)):"object"==typeof exports?module.exports=e(t):t.astro=e(t)})("undefined"!=typeof global?global:this.window||this.global,(function(t){"use strict";var e,o={},n="querySelector"in document&&"addEventListener"in t&&"classList"in document.createElement("_"),c={selector:"[data-nav-toggle]",toggleActiveClass:"active",navActiveClass:"active",initClass:"js-astro",callback:function(){}},l=function(){var t={},e=!1,o=0,n=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(e=arguments[0],o++);for(var c=function(o){for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e&&"[object Object]"===Object.prototype.toString.call(o[n])?t[n]=buoy.extend(!0,t[n],o[n]):t[n]=o[n])};o=0&&e.item(o)!==this;);return o>-1});t&&t!==document;t=t.parentNode)if(t.matches(e))return t;return null};o.toggleNav=function(t,e,o,n){var r=l(r||c,o||{}),a=document.querySelector(e);t.classList.toggle(r.toggleActiveClass),a.classList.toggle(r.navActiveClass),r.callback(t,e)};var a=function(t){var n=r(t.target,e.selector);n&&("a"===n.tagName.toLowerCase()&&t.preventDefault(),o.toggleNav(n,n.getAttribute("data-nav-toggle"),e))};return o.destroy=function(){e&&(document.documentElement.classList.remove(e.initClass),document.removeEventListener("click",a,!1),e=null)},o.init=function(t){n&&(o.destroy(),e=l(c,t||{}),document.documentElement.classList.add(e.initClass),document.addEventListener("click",a,!1))},o}));
--------------------------------------------------------------------------------
/docs/dist/css/astro.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Astro v10.2.0: Mobile-first navigation patterns
3 | * (c) 2016 Chris Ferdinandi
4 | * MIT License
5 | * http://github.com/cferdinandi/astro
6 | */
7 |
8 | /**
9 | * Text alignment
10 | */
11 | /* line 4, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
12 | .nav-wrap {
13 | text-align: center;
14 | }
15 |
16 | @media (max-width: 40em) {
17 | /* line 8, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
18 | .js-astro .nav-wrap.nav-collapse {
19 | text-align: left;
20 | }
21 | }
22 |
23 | @media (min-width: 40em) {
24 | /* line 4, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
25 | .nav-wrap {
26 | text-align: left;
27 | }
28 | }
29 |
30 | /**
31 | * Logo
32 | */
33 | /* line 22, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
34 | .logo {
35 | color: #272727;
36 | display: inline-block;
37 | font-size: 1.2em;
38 | line-height: 1.2;
39 | margin-bottom: 0.5em;
40 | text-decoration: none;
41 | }
42 |
43 | /* line 30, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
44 | .logo:hover {
45 | color: #272727;
46 | text-decoration: none;
47 | }
48 |
49 | @media (min-width: 40em) {
50 | /* line 36, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
51 | .js-astro .nav-collapse .logo {
52 | float: left;
53 | }
54 | }
55 |
56 | @media (min-width: 40em) {
57 | /* line 22, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
58 | .logo {
59 | float: left;
60 | }
61 | }
62 |
63 | /**
64 | * Navigation Menu Container
65 | */
66 | @media (max-width: 40em) {
67 | /* line 53, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
68 | .js-astro .nav-collapse .nav-menu {
69 | box-sizing: border-box;
70 | display: none;
71 | width: 100%;
72 | }
73 | /* line 58, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
74 | .js-astro .nav-collapse .nav-menu.active {
75 | display: block;
76 | }
77 | /* line 62, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
78 | .js-astro .nav-collapse .nav-menu li {
79 | display: block;
80 | width: 100%;
81 | padding-top: 0.25em;
82 | padding-bottom: 0.25em;
83 | box-sizing: border-box;
84 | }
85 | }
86 |
87 | /**
88 | * Navigation Menu
89 | */
90 | /* line 77, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
91 | .nav {
92 | list-style: none;
93 | margin: 0 -0.5em;
94 | padding: 0;
95 | }
96 |
97 | /* line 82, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
98 | .nav > li {
99 | display: inline-block;
100 | float: none;
101 | margin-left: 0.5em;
102 | margin-right: 0.5em;
103 | }
104 |
105 | @media (max-width: 40em) {
106 | /* line 93, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
107 | .js-astro .nav-collapse .nav {
108 | text-align: left;
109 | }
110 | }
111 |
112 | @media (min-width: 40em) {
113 | /* line 77, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
114 | .nav {
115 | text-align: right;
116 | }
117 | }
118 |
119 | /**
120 | * Navigation Toggle
121 | */
122 | /* line 107, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
123 | .nav-toggle {
124 | display: none;
125 | visibility: hidden;
126 | }
127 |
128 | @media (max-width: 40em) {
129 | /* line 112, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
130 | .js-astro .nav-collapse .nav-toggle {
131 | display: block;
132 | float: right;
133 | visibility: visible;
134 | }
135 | }
136 |
137 | /**
138 | * Clearfix
139 | */
140 | /* line 125, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
141 | .nav-wrap:before,
142 | .nav-wrap:after {
143 | display: table;
144 | content: "";
145 | }
146 |
147 | /* line 131, /Users/cferdinandi/Sites/astro/src/sass/components/_astro.scss */
148 | .nav-wrap:after {
149 | clear: both;
150 | }
151 |
--------------------------------------------------------------------------------
/docs/dist/css/astro.min.css:
--------------------------------------------------------------------------------
1 | /*! Astro v10.2.0 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/astro */
2 | .nav-wrap{text-align:center}@media (max-width:40em){.js-astro .nav-wrap.nav-collapse{text-align:left}}@media (min-width:40em){.nav-wrap{text-align:left}}.logo{display:inline-block;font-size:1.2em;line-height:1.2;margin-bottom:.5em}.logo,.logo:hover{color:#272727;text-decoration:none}@media (min-width:40em){.js-astro .nav-collapse .logo,.logo{float:left}}@media (max-width:40em){.js-astro .nav-collapse .nav-menu{box-sizing:border-box;display:none;width:100%}.js-astro .nav-collapse .nav-menu.active{display:block}.js-astro .nav-collapse .nav-menu li{display:block;width:100%;padding-top:.25em;padding-bottom:.25em;box-sizing:border-box}}.nav{list-style:none;margin:0 -.5em;padding:0}.nav>li{display:inline-block;float:none;margin-left:.5em;margin-right:.5em}@media (max-width:40em){.js-astro .nav-collapse .nav{text-align:left}}@media (min-width:40em){.nav{text-align:right}}.nav-toggle{display:none;visibility:hidden}@media (max-width:40em){.js-astro .nav-collapse .nav-toggle{display:block;float:right;visibility:visible}}.nav-wrap:after,.nav-wrap:before{display:table;content:""}.nav-wrap:after{clear:both}
--------------------------------------------------------------------------------
/docs/dist/js/astro.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Astro v10.2.0: Mobile-first navigation patterns
3 | * (c) 2016 Chris Ferdinandi
4 | * MIT License
5 | * http://github.com/cferdinandi/astro
6 | */
7 |
8 | (function (root, factory) {
9 | if ( typeof define === 'function' && define.amd ) {
10 | define([], factory(root));
11 | } else if ( typeof exports === 'object' ) {
12 | module.exports = factory(root);
13 | } else {
14 | root.astro = factory(root);
15 | }
16 | })(typeof global !== 'undefined' ? global : this.window || this.global, (function (root) {
17 |
18 | 'use strict';
19 |
20 | //
21 | // Variables
22 | //
23 |
24 | var astro = {}; // Object for public APIs
25 | var supports = 'querySelector' in document && 'addEventListener' in root && 'classList' in document.createElement('_'); // Feature test
26 | var settings;
27 |
28 | // Default settings
29 | var defaults = {
30 | selector: '[data-nav-toggle]',
31 | toggleActiveClass: 'active',
32 | navActiveClass: 'active',
33 | initClass: 'js-astro',
34 | callback: function () {}
35 | };
36 |
37 |
38 | //
39 | // Methods
40 | //
41 |
42 | /**
43 | * Merge defaults with user options
44 | * @private
45 | * @param {Object} defaults Default settings
46 | * @param {Object} options User options
47 | * @returns {Object} Merged values of defaults and options
48 | */
49 | var extend = function () {
50 |
51 | // Variables
52 | var extended = {};
53 | var deep = false;
54 | var i = 0;
55 | var length = arguments.length;
56 |
57 | // Check if a deep merge
58 | if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) {
59 | deep = arguments[0];
60 | i++;
61 | }
62 |
63 | // Merge the object into the extended object
64 | var merge = function (obj) {
65 | for ( var prop in obj ) {
66 | if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
67 | // If deep merge and property is an object, merge properties
68 | if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {
69 | extended[prop] = buoy.extend( true, extended[prop], obj[prop] );
70 | } else {
71 | extended[prop] = obj[prop];
72 | }
73 | }
74 | }
75 | };
76 |
77 | // Loop through each object and conduct a merge
78 | for ( ; i < length; i++ ) {
79 | var obj = arguments[i];
80 | merge(obj);
81 | }
82 |
83 | return extended;
84 |
85 | };
86 |
87 | /**
88 | * Get the closest matching element up the DOM tree.
89 | * @private
90 | * @param {Element} elem Starting element
91 | * @param {String} selector Selector to match against
92 | * @return {Boolean|Element} Returns null if not match found
93 | */
94 | var getClosest = function ( elem, selector ) {
95 |
96 | // Element.matches() polyfill
97 | if (!Element.prototype.matches) {
98 | Element.prototype.matches =
99 | Element.prototype.matchesSelector ||
100 | Element.prototype.mozMatchesSelector ||
101 | Element.prototype.msMatchesSelector ||
102 | Element.prototype.oMatchesSelector ||
103 | Element.prototype.webkitMatchesSelector ||
104 | function(s) {
105 | var matches = (this.document || this.ownerDocument).querySelectorAll(s),
106 | i = matches.length;
107 | while (--i >= 0 && matches.item(i) !== this) {}
108 | return i > -1;
109 | };
110 | }
111 |
112 | // Get closest match
113 | for ( ; elem && elem !== document; elem = elem.parentNode ) {
114 | if ( elem.matches( selector ) ) return elem;
115 | }
116 |
117 | return null;
118 |
119 | };
120 |
121 | /**
122 | * Show and hide navigation menu
123 | * @public
124 | * @param {Element} toggle Element that triggered the toggle
125 | * @param {String} navID The ID of the navigation element to toggle
126 | * @param {Object} settings
127 | * @param {Event} event
128 | */
129 | astro.toggleNav = function ( toggle, navID, options, event ) {
130 |
131 | // Selectors and variables
132 | var settings = extend( settings || defaults, options || {} ); // Merge user options with defaults
133 | var nav = document.querySelector(navID);
134 |
135 | toggle.classList.toggle( settings.toggleActiveClass ); // Toggle the '.active' class on the toggle element
136 | nav.classList.toggle( settings.navActiveClass ); // Toggle the '.active' class on the menu
137 | settings.callback( toggle, navID ); // Run callbacks after toggling nav
138 |
139 | };
140 |
141 | /**
142 | * Handle click event methods
143 | * @private
144 | */
145 | var eventHandler = function (event) {
146 | var toggle = getClosest(event.target, settings.selector);
147 | if ( toggle ) {
148 | // Prevent default click event
149 | if ( toggle.tagName.toLowerCase() === 'a') {
150 | event.preventDefault();
151 | }
152 | // Toggle nav
153 | astro.toggleNav( toggle, toggle.getAttribute('data-nav-toggle'), settings );
154 | }
155 | };
156 |
157 | /**
158 | * Destroy the current initialization.
159 | * @public
160 | */
161 | astro.destroy = function () {
162 | if ( !settings ) return;
163 | document.documentElement.classList.remove( settings.initClass );
164 | document.removeEventListener('click', eventHandler, false);
165 | settings = null;
166 | };
167 |
168 | /**
169 | * Initialize Astro
170 | * @public
171 | * @param {Object} options User settings
172 | */
173 | astro.init = function ( options ) {
174 |
175 | // feature test
176 | if ( !supports ) return;
177 |
178 | // Destroy any existing initializations
179 | astro.destroy();
180 |
181 | // Selectors and variables
182 | settings = extend( defaults, options || {} ); // Merge user options with defaults
183 |
184 | // Listeners and methods
185 | document.documentElement.classList.add( settings.initClass ); // Add class to HTML element to activate conditional CSS
186 | document.addEventListener('click', eventHandler, false); // Listen for click events and run event handler
187 |
188 | };
189 |
190 |
191 | //
192 | // Public APIs
193 | //
194 |
195 | return astro;
196 |
197 | }));
--------------------------------------------------------------------------------
/docs/dist/js/astro.min.js:
--------------------------------------------------------------------------------
1 | /*! Astro v10.2.0 | (c) 2016 Chris Ferdinandi | MIT License | http://github.com/cferdinandi/astro */
2 | !(function(t,e){"function"==typeof define&&define.amd?define([],e(t)):"object"==typeof exports?module.exports=e(t):t.astro=e(t)})("undefined"!=typeof global?global:this.window||this.global,(function(t){"use strict";var e,o={},n="querySelector"in document&&"addEventListener"in t&&"classList"in document.createElement("_"),c={selector:"[data-nav-toggle]",toggleActiveClass:"active",navActiveClass:"active",initClass:"js-astro",callback:function(){}},l=function(){var t={},e=!1,o=0,n=arguments.length;"[object Boolean]"===Object.prototype.toString.call(arguments[0])&&(e=arguments[0],o++);for(var c=function(o){for(var n in o)Object.prototype.hasOwnProperty.call(o,n)&&(e&&"[object Object]"===Object.prototype.toString.call(o[n])?t[n]=buoy.extend(!0,t[n],o[n]):t[n]=o[n])};o=0&&e.item(o)!==this;);return o>-1});t&&t!==document;t=t.parentNode)if(t.matches(e))return t;return null};o.toggleNav=function(t,e,o,n){var r=l(r||c,o||{}),a=document.querySelector(e);t.classList.toggle(r.toggleActiveClass),a.classList.toggle(r.navActiveClass),r.callback(t,e)};var a=function(t){var n=r(t.target,e.selector);n&&("a"===n.tagName.toLowerCase()&&t.preventDefault(),o.toggleNav(n,n.getAttribute("data-nav-toggle"),e))};return o.destroy=function(){e&&(document.documentElement.classList.remove(e.initClass),document.removeEventListener("click",a,!1),e=null)},o.init=function(t){n&&(o.destroy(),e=l(c,t||{}),document.documentElement.classList.add(e.initClass),document.addEventListener("click",a,!1))},o}));
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Astro
7 |
8 |
9 |
10 |
11 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |