├── .meteor ├── cordova-plugins ├── .gitignore ├── release ├── platforms ├── .id ├── .finished-upgraders ├── packages └── versions ├── client ├── views │ ├── items.js │ ├── buttons.js │ ├── blank.js │ ├── tab2.html │ ├── tab1.html │ ├── headers.html │ ├── app.html │ ├── blank.html │ ├── text.html │ ├── tab4.html │ ├── utility.html │ ├── items.html │ ├── tab3.html │ └── buttons.html └── styles │ └── app.styl ├── packages ├── native-spinner │ ├── README.md │ ├── native-spinner.js │ └── package.js ├── tap-feedback │ ├── tap-feedback.css │ ├── tap-feedback.js │ ├── package.js │ └── README.md ├── native-transitions-stylus │ ├── mixins.import.styl │ ├── README.md │ ├── package.js │ ├── images.import.styl │ ├── reset.import.styl │ ├── variables.import.styl │ ├── forms.import.styl │ └── core.import.styl ├── native-transitions-header │ ├── README.md │ ├── native-transitions-header.js │ └── package.js ├── native-transitions-components │ ├── ntBackButton.js │ ├── ntBackButton.html │ ├── ntElement.html │ ├── package.js │ ├── ntModal.css │ ├── README.md │ ├── ntSliderZoom.js │ ├── ntSlide.css │ └── ntElement.js ├── scroll-history │ ├── package.js │ ├── README.md │ └── scroll-history.js ├── native-transitions-tabs │ ├── package.js │ ├── native-transitions-tabs.js │ ├── native-transitions-tabs.html │ ├── native-transitions-tabs.css │ └── README.md └── native-transitions │ ├── package.js │ ├── README.md │ └── native-transitions.js ├── mobile-config.js ├── lib ├── demo.js ├── statusbar.js └── router.js └── README.md /.meteor/cordova-plugins: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.3-beta.11 -------------------------------------------------------------------------------- /client/views/items.js: -------------------------------------------------------------------------------- 1 | Template.items.transition(); -------------------------------------------------------------------------------- /client/views/buttons.js: -------------------------------------------------------------------------------- 1 | Template.buttons.transition(); 2 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | android 2 | browser 3 | ios 4 | server 5 | -------------------------------------------------------------------------------- /packages/native-spinner/README.md: -------------------------------------------------------------------------------- 1 | #A native cordova spinner 2 | -------------------------------------------------------------------------------- /mobile-config.js: -------------------------------------------------------------------------------- 1 | App.setPreference('CrosswalkAnimatable', 'true'); -------------------------------------------------------------------------------- /client/views/blank.js: -------------------------------------------------------------------------------- 1 | Template.blank.transition({ 2 | noHeader: true, 3 | noTabs: true 4 | }); 5 | -------------------------------------------------------------------------------- /packages/tap-feedback/tap-feedback.css: -------------------------------------------------------------------------------- 1 | .tap-feedback-active { 2 | background-color: #E1E1E1 !important; 3 | } -------------------------------------------------------------------------------- /packages/native-transitions-stylus/mixins.import.styl: -------------------------------------------------------------------------------- 1 | border-radius(n) 2 | -webkit-border-radius n 3 | border-radius n -------------------------------------------------------------------------------- /packages/native-transitions-header/README.md: -------------------------------------------------------------------------------- 1 | #Native Transitions Header 2 | Headers that work well with the `native-transitions` package. -------------------------------------------------------------------------------- /lib/demo.js: -------------------------------------------------------------------------------- 1 | if (Meteor.isClient) { 2 | 3 | Template.registerHelper("list", function() { 4 | return _.range(100); 5 | }); 6 | 7 | } 8 | 9 | -------------------------------------------------------------------------------- /packages/native-transitions-components/ntBackButton.js: -------------------------------------------------------------------------------- 1 | Template.registerHelper('ntBackDirection', function () { 2 | return nt.defaults.backDirection; 3 | }); -------------------------------------------------------------------------------- /packages/native-transitions-stylus/README.md: -------------------------------------------------------------------------------- 1 | #Styles to make your app look native 2 | Works really well with the native transitions package 3 | 4 | Need to write documentation for this but take a look at the example app for ideas. 5 | -------------------------------------------------------------------------------- /packages/native-transitions-components/ntBackButton.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/statusbar.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function() { 2 | if (Meteor.isCordova) { 3 | //Format the status bar 4 | StatusBar.overlaysWebView(false); 5 | StatusBar.styleLightContent(); 6 | StatusBar.backgroundColorByHexString("#2f3339"); 7 | } 8 | }); 9 | 10 | -------------------------------------------------------------------------------- /packages/native-transitions-components/ntElement.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 1q2j0if5bzhsfpkikpt 8 | -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | 1.2.0-standard-minifiers-package 10 | 1.2.0-meteor-platform-split 11 | 1.2.0-cordova-changes 12 | 1.2.0-breaking-changes 13 | -------------------------------------------------------------------------------- /client/styles/app.styl: -------------------------------------------------------------------------------- 1 | //Import 2 | @import '{jamielob:native-transitions-stylus}/variables.import.styl'; 3 | @import '{jamielob:native-transitions-stylus}/mixins.import.styl'; 4 | @import '{jamielob:native-transitions-stylus}/reset.import.styl'; 5 | @import '{jamielob:native-transitions-stylus}/core.import.styl'; 6 | @import '{jamielob:native-transitions-stylus}/forms.import.styl'; 7 | @import '{jamielob:native-transitions-stylus}/images.import.styl'; -------------------------------------------------------------------------------- /packages/native-transitions-header/native-transitions-header.js: -------------------------------------------------------------------------------- 1 | if (Meteor.isCordova) { 2 | //Set the fixedPixelTop to the height of the header 3 | nt.defaults.fixedPixelsTop = 44; 4 | //Makes the transition pretty 5 | //nt.defaults.fadeHeader = true; 6 | 7 | //Check for no-header clicks 8 | $(document) 9 | .on('click', '.nt-no-header a', function(event) { 10 | //Disable the fixedPixelTop for the next transition 11 | nt.fixedPixelsTop = 0; 12 | }); 13 | } -------------------------------------------------------------------------------- /client/views/tab2.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/native-spinner/native-spinner.js: -------------------------------------------------------------------------------- 1 | nativeSpinner = {}; 2 | 3 | nativeSpinner.spin = function(text, noTimeout) { 4 | 5 | 6 | 7 | if (Meteor.isCordova) { 8 | SpinnerPlugin.activityStart(text); 9 | 10 | //Add's safety timer, that stops the spinner after x seconds no matter what 11 | if (!noTimeout) { 12 | spinnerTimeout = Meteor.setTimeout(function() { 13 | SpinnerPlugin.activityStop(); 14 | }, 5000); 15 | } 16 | 17 | } 18 | 19 | } 20 | 21 | nativeSpinner.stop = function() { 22 | 23 | if (Meteor.isCordova) { 24 | SpinnerPlugin.activityStop(); 25 | clearTimeout(spinnerTimeout); 26 | } 27 | 28 | } 29 | 30 | -------------------------------------------------------------------------------- /client/views/tab1.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/tap-feedback/tap-feedback.js: -------------------------------------------------------------------------------- 1 | Template.body.events({ 2 | 3 | 'touchstart .tap-feedback': function (event, template) { 4 | tapFeedbackDelay = Meteor.setTimeout(function() { 5 | $(event.currentTarget).addClass('tap-feedback-active'); 6 | }, 25); 7 | }, 8 | 9 | 'touchmove .tap-feedback': function (event, template) { 10 | clearTimeout(tapFeedbackDelay); 11 | $(event.currentTarget).removeClass('tap-feedback-active'); 12 | }, 13 | 14 | 'touchend .tap-feedback': function (event, template) { 15 | clearTimeout(tapFeedbackDelay); 16 | Meteor.setTimeout(function() { 17 | $(event.currentTarget).removeClass('tap-feedback-active'); 18 | }, 25); 19 | } 20 | 21 | }); -------------------------------------------------------------------------------- /client/views/headers.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{#ntTabs template1="tab1" template2="tab2" template3="tab3" template4="tab4"}} 8 | 9 | {{#ntTab position="1"}} 10 | 11 | Tab 1 12 | {{/ntTab}} 13 | 14 | {{#ntTab position="2"}} 15 | 16 | Tab 2 17 | {{/ntTab}} 18 | 19 | {{#ntTab position="3"}} 20 | 21 | Tab 3 22 | {{/ntTab}} 23 | 24 | {{#ntTab position="4"}} 25 | 26 | Tab 4 27 | {{/ntTab}} 28 | 29 | {{/ntTabs}} 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /packages/native-transitions-header/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-transitions-header', 3 | version: '1.0.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Headers that work well with the native-transitions package.', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use(['jquery'], 'client'); 17 | api.use('jamielob:native-transitions', 'client'); 18 | api.addFiles('native-transitions-header.js', 'client'); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/tap-feedback/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:tap-feedback', 3 | version: '1.0.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Highlight taps (helpful for slower devices)', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use(['templating', 'jquery'], ['client']); 17 | api.use(['gwendall:body-events@0.1.6'], 'client'); 18 | api.addFiles('tap-feedback.js', 'client'); 19 | api.addFiles('tap-feedback.css', 'client'); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/native-spinner/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-spinner', 3 | version: '1.0.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Native spinner', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Cordova.depends({ 14 | 'cordova-plugin-spinner': '1.0.0' 15 | }); 16 | 17 | Package.onUse(function(api) { 18 | api.versionsFrom('1.3-beta.11'); 19 | api.use('ecmascript'); 20 | api.use(['templating', 'session', 'jquery'], ['client']); 21 | api.addFiles('native-spinner.js', 'client'); 22 | 23 | api.export("nativeSpinner"); 24 | 25 | }); 26 | 27 | -------------------------------------------------------------------------------- /client/views/blank.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/text.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/tab4.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/scroll-history/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:scroll-history', 3 | version: '1.0.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Remembers the scroll position when heading back to a page', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use(['templating', 'jquery'], ['client']); 17 | api.use(['kadira:flow-router@2.10.1'], 'client'); 18 | api.use(['gwendall:body-events@0.1.6'], 'client'); 19 | api.addFiles('scroll-history.js', 'client'); 20 | 21 | //Exposes options and defaults so user can override 22 | api.export("scrollHistory"); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /client/views/utility.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/native-transitions-tabs/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-transitions-tabs', 3 | version: '1.0.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Tabbed core pages that remember scroll + content', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use(['templating','jquery','tracker','session'], 'client'); 17 | api.use('kadira:flow-router', 'client'); 18 | api.use('jamielob:native-transitions', 'client'); 19 | api.addFiles('native-transitions-tabs.html', 'client'); 20 | api.addFiles('native-transitions-tabs.js', 'client'); 21 | api.addFiles('native-transitions-tabs.css', 'client'); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-transitions-stylus', 3 | version: '0.5.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Stylus styles to make your app look native on iOS and Android', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use('stylus'); 17 | api.imply('stylus'); 18 | api.addFiles('variables.import.styl', 'client', {isImport: true}); 19 | api.addFiles('mixins.import.styl', 'client', {isImport: true}); 20 | api.addFiles('reset.import.styl', 'client', {isImport: true}); 21 | api.addFiles('core.import.styl', 'client', {isImport: true}); 22 | api.addFiles('forms.import.styl', 'client', {isImport: true}); 23 | api.addFiles('images.import.styl', 'client', {isImport: true}); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/native-transitions-tabs/native-transitions-tabs.js: -------------------------------------------------------------------------------- 1 | if (Meteor.isCordova) { 2 | //Set the fixedPixelBottom to the height of the tabs 3 | nt.defaults.fixedPixelsBottom = 50; 4 | 5 | //Check for no-tabs clicks 6 | $(document) 7 | .on('click', '.nt-no-tabs a', function(event) { 8 | //Disable the fixedPixelBottom for the next transition 9 | nt.fixedPixelsBottom = 0; 10 | }); 11 | } 12 | 13 | if (Meteor.isClient) { 14 | 15 | //Set the default tab 16 | Session.setDefault('ntCurrentTab', 'nt-tab-1'); 17 | 18 | //Watch tab pages changes 19 | Tracker.autorun(function () { 20 | //Get the current tab param 21 | var tab = FlowRouter.getQueryParam("nt-tab"); 22 | var tabClass = 'nt-tab-' + tab; 23 | Session.set('ntCurrentTab', 'nt-tab-' + tab); 24 | }); 25 | 26 | //Add transition to empty placeholder - used so that native transitons work when going ot the tabs, which are really just always there in the background 27 | Template.ntPlaceholder.onRendered(function() { 28 | nt.transition(); 29 | }); 30 | 31 | //Current tab helper 32 | Template.registerHelper('ntCurrentTab', function() { 33 | return Session.get('ntCurrentTab'); 34 | }); 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /client/views/items.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/native-transitions-tabs/native-transitions-tabs.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 48 | 49 | -------------------------------------------------------------------------------- /packages/tap-feedback/README.md: -------------------------------------------------------------------------------- 1 | #Scroll History 2 | 3 | Remembers the scroll position on pages as you leave them 4 | 5 | - Requires FlowRouter 6 | - Works great with the Native Transitions packages 7 | 8 | Each time you leave a page it remembers the scroll position. When you re-enter that page it scrolls to it. 9 | 10 | ##Setup 11 | 12 | `meteor add jamielob:scroll-position` 13 | 14 | Simply call the scrollHistory function in your onRendered or equivalent template. 15 | 16 | ``` 17 | scrollHistory(jQueryObject); 18 | ``` 19 | 20 | The `jQueryObject` refers to the object you want to scroll. For example, if you are using this with the `native-transitions-stylus` package you would: 21 | 22 | ``` 23 | Template.templateName.onRendered(function() { 24 | 25 | var self = this; 26 | 27 | //Remember scroll position 28 | scrollHistory(self.$('.nt-content')); 29 | 30 | ``` 31 | 32 | ##Options 33 | 34 | Optional flag to keep scroll position in both forward and back directions. Default is only when travelling back. 35 | 36 | ``` 37 | scrollHistory(self.$('.nt-content'), true); //Remembers scroll position in both directions 38 | ``` 39 | 40 | This plugin detects hardware back buttons, the `ntBackButton` helper from the `native-transitions-components` package and any buttons with a class of `nt-backButton`. -------------------------------------------------------------------------------- /packages/scroll-history/README.md: -------------------------------------------------------------------------------- 1 | #Scroll History 2 | 3 | Remembers the scroll position on pages as you leave them 4 | 5 | - Requires FlowRouter 6 | - Works great with the Native Transitions packages 7 | 8 | Each time you leave a page it remembers the scroll position. When you re-enter that page it scrolls to it. 9 | 10 | ##Setup 11 | 12 | `meteor add jamielob:scroll-position` 13 | 14 | Simply call the scrollHistory function in your onRendered or equivalent template. 15 | 16 | ``` 17 | scrollHistory(jQueryObject); 18 | ``` 19 | 20 | The `jQueryObject` refers to the object you want to scroll. For example, if you are using this with the `native-transitions-stylus` package you would: 21 | 22 | ``` 23 | Template.templateName.onRendered(function() { 24 | 25 | var self = this; 26 | 27 | //Remember scroll position 28 | scrollHistory(self.$('.nt-content')); 29 | 30 | ``` 31 | 32 | ##Options 33 | 34 | Optional flag to keep scroll position in both forward and back directions. Default is only when travelling back. 35 | 36 | ``` 37 | scrollHistory(self.$('.nt-content'), true); //Remembers scroll position in both directions 38 | ``` 39 | 40 | This plugin detects hardware back buttons, the `ntBackButton` helper from the `native-transitions-components` package and any buttons with a class of `nt-backButton`. -------------------------------------------------------------------------------- /packages/native-transitions-components/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-transitions-components', 3 | version: '1.0.0', 4 | // Components for the native transitions framework, including back button, slider zoom, slid down and slide up menus, modals 5 | summary: 'Great components to use with the native-transitions package.', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3-beta.11'); 15 | api.use('ecmascript'); 16 | api.use(['templating', 'jquery'], 'client'); 17 | api.use('jamielob:native-transitions', 'client'); 18 | api.use('gwendall:body-events@0.1.6', 'client'); 19 | api.use('velocityjs:velocityjs@1.2.1', 'client'); 20 | 21 | api.addFiles('ntBackButton.html', 'client'); 22 | api.addFiles('ntBackButton.js', 'client'); 23 | 24 | api.addFiles('ntSliderZoom.js', 'client'); 25 | 26 | api.addFiles('ntElement.html', 'client'); 27 | api.addFiles('ntElement.js', 'client'); 28 | api.addFiles('ntModal.css', 'client'); 29 | api.addFiles('ntSlide.css', 'client'); 30 | 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /packages/native-transitions-tabs/native-transitions-tabs.css: -------------------------------------------------------------------------------- 1 | /* Containers are hidden and show using pure CSS and a single Session variable as it is much quicker than jQuery hide/show */ 2 | 3 | /* Container for tab pages - basically the same at nt-container but hidded by default */ 4 | /*.nt-tab-container { 5 | position: absolute; 6 | top: 0; 7 | right: 0; 8 | bottom: 0; 9 | left: 0; 10 | background-color: #FFF; 11 | display: none; 12 | }*/ 13 | 14 | /* Hide tabs by default */ 15 | .nt-tab-container { 16 | display: none; 17 | } 18 | 19 | /* Show the current tab */ 20 | .nt-tab-1 .nt-tab-container.nt-tab-1, 21 | .nt-tab-2 .nt-tab-container.nt-tab-2, 22 | .nt-tab-3 .nt-tab-container.nt-tab-3, 23 | .nt-tab-4 .nt-tab-container.nt-tab-4, 24 | .nt-tab-5 .nt-tab-container.nt-tab-5 { 25 | display: block; 26 | } 27 | 28 | 29 | 30 | 31 | /* Fixes z-index problem with scrolling items underneath */ 32 | .nt-tab-undefined .nt-content { 33 | overflow: hidden; 34 | } 35 | 36 | 37 | /* nt-heavy can be added to any "heavy" content on a tab. It hides content by default so that it doesn't slow down the transitions */ 38 | /*.nt-tab-undefined .nt-heavy { 39 | display: none; 40 | }*/ 41 | 42 | /* Show the "heavy" content a split second after we show the page */ 43 | /*.nt-tab-1 .nt-heavy, 44 | .nt-tab-2 .nt-heavy, 45 | .nt-tab-3 .nt-heavy, 46 | .nt-tab-4 .nt-heavy, 47 | .nt-tab-5 .nt-heavy { 48 | display: block; 49 | } 50 | */ -------------------------------------------------------------------------------- /.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-base # Packages every Meteor app needs to have 8 | mobile-experience # Packages for a great mobile UX 9 | mongo # The database Meteor supports right now 10 | blaze-html-templates # Compile .html files into Meteor Blaze views 11 | session # Client-side reactive dictionary for your app 12 | jquery # Helpful client-side library 13 | tracker # Meteor's client-side reactive programming library 14 | 15 | standard-minifiers # JS/CSS minifiers run for production mode 16 | es5-shim # ECMAScript 5 compatibility for older browsers. 17 | ecmascript # Enable ECMAScript2015+ syntax in app code 18 | 19 | autopublish # Publish all data to the clients (for prototyping) 20 | insecure # Allow all DB writes from clients (for prototyping) 21 | kadira:flow-router 22 | kadira:blaze-layout 23 | 24 | jamielob:native-transitions 25 | jamielob:native-transitions-stylus 26 | jamielob:native-transitions-tabs 27 | jamielob:native-transitions-header 28 | jamielob:native-transitions-components 29 | 30 | pagebakers:ionicons 31 | reactive-var 32 | #stylus 33 | crosswalk 34 | -------------------------------------------------------------------------------- /lib/router.js: -------------------------------------------------------------------------------- 1 | if (Meteor.isClient) { 2 | 3 | FlowRouter.route('/', { 4 | name: 'tabs', 5 | action: function() { 6 | //Set the default tab 7 | if (!FlowRouter.getQueryParam('nt-tab')) FlowRouter.setQueryParams({'nt-tab': 1 }); 8 | //Render the placeholder 9 | BlazeLayout.render('ntPlaceholder'); 10 | } 11 | }); 12 | 13 | 14 | FlowRouter.route('/profile', { 15 | name: 'profile', 16 | action: function() { 17 | BlazeLayout.render('profile'); 18 | } 19 | }); 20 | 21 | 22 | 23 | 24 | FlowRouter.route('/items', { 25 | name: 'items', 26 | action: function() { 27 | BlazeLayout.render('items'); 28 | } 29 | }); 30 | 31 | FlowRouter.route('/blank', { 32 | name: 'blank', 33 | action: function() { 34 | BlazeLayout.render('blank'); 35 | } 36 | }); 37 | 38 | FlowRouter.route('/text', { 39 | name: 'text', 40 | action: function() { 41 | BlazeLayout.render('text'); 42 | } 43 | }); 44 | 45 | FlowRouter.route('/buttons', { 46 | name: 'buttons', 47 | action: function() { 48 | BlazeLayout.render('buttons'); 49 | } 50 | }); 51 | 52 | FlowRouter.route('/utility', { 53 | name: 'utility', 54 | action: function() { 55 | BlazeLayout.render('utility'); 56 | } 57 | }); 58 | 59 | FlowRouter.route('/headers', { 60 | name: 'headers', 61 | action: function() { 62 | BlazeLayout.render('headers'); 63 | } 64 | }); 65 | 66 | } -------------------------------------------------------------------------------- /packages/native-transitions-components/ntModal.css: -------------------------------------------------------------------------------- 1 | .nt-modal .nt-element { 2 | position: absolute; 3 | z-index: 3; 4 | width: 80%; 5 | background-color: #FFFFFF; 6 | position: absolute; 7 | left: 50%; 8 | top: 50%; 9 | opacity: 0; 10 | transform: translate3d(100%, 0, 0); 11 | -webkit-transform: translate3d(100%, 0, 0); 12 | display: none; 13 | } 14 | 15 | .nt-modal.nt-element-in .nt-element { 16 | display: block; 17 | transform: translate(-50%, -50%); 18 | -webkit-transform: translate(-50%, -50%); 19 | opacity: 1; 20 | -webkit-animation: nt-fade-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 21 | animation: nt-fade-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 22 | } 23 | @-webkit-keyframes nt-fade-in { 24 | from { opacity: 0; } 25 | to { opacity: 1; } 26 | } 27 | @keyframes nt-fade-in { 28 | from { opacity: 0; } 29 | to { opacity: 1; } 30 | } 31 | 32 | 33 | .nt-modal.nt-element-out .nt-element { 34 | display: block; 35 | transform: translate(-50%, -50%); 36 | -webkit-transform: translate(-50%, -50%); 37 | opacity: 1; 38 | -webkit-animation: nt-fade-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 39 | animation: nt-fade-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 40 | } 41 | @-webkit-keyframes nt-fade-out { 42 | from { opacity: 1; } 43 | to { opacity: 0; } 44 | } 45 | @keyframes nt-fade-out { 46 | from { opacity: 1; } 47 | to { opacity: 0; } 48 | } 49 | 50 | 51 | 52 | 53 | /*MODAL*/ 54 | .nt-overlay { 55 | z-index: 2; 56 | position: absolute; 57 | top: 0; 58 | left: 0; 59 | width: 100%; 60 | height: 100%; 61 | display: none; 62 | } 63 | .nt-element-in .nt-overlay { 64 | display: block; 65 | background-color: transparent; 66 | } 67 | -------------------------------------------------------------------------------- /packages/native-transitions-components/README.md: -------------------------------------------------------------------------------- 1 | #Native Transitions Components 2 | Components for use with the `native-transitions` and `native-transitions-stylus` packages. 3 | 4 | ##ntBackButton 5 | A back button component that uses the Ionicons package 6 | 7 | ``` 8 | meteor add pagebakers:ionicons 9 | ``` 10 | 11 | You can easily roll your own back button template an use whatever icon or text you like. For example: 12 | 13 | ``` 14 | 15 | 16 | 17 | ``` 18 | 19 | If you want to use text, don't forget the `.nt-text` class. You can find out more in the readme for the `native-transitions-stylus` package readme. 20 | 21 | 22 | 23 | ##ntElements 24 | 25 | Put the elements as the last thing inside the `nt-container` div so that is kept outside of the scrolling area. 26 | 27 | `{{>ntElement name="demoMenu" type="slideDown"}}` 28 | 29 | Then just put your element content in a template with the same name: 30 | 31 | ``` 32 | 35 | ``` 36 | 37 | If you have headers or tabs, wrap your element content in a div with the relevant class. For example, if you have a slideDown and a header, you can add the `nt-header-padding` class to a wrapper div. If you have a slideUp and tabs, you can add the `nt-tabs-padding` class to a wrapper div. 38 | 39 | ``` 40 | 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/images.import.styl: -------------------------------------------------------------------------------- 1 | .nt-image 2 | border-radius(2px) 3 | 4 | &.nt-block 5 | display block 6 | width 100% 7 | height auto 8 | 9 | .nt-slider 10 | width 100% 11 | //height $sliderHeight 12 | overflow-y hidden 13 | overflow-x scroll 14 | display block 15 | white-space nowrap 16 | -webkit-overflow-scrolling touch 17 | padding-right $sliderSpacing + 3 //Add back in margin removed below 18 | 19 | .nt-photo //Whatever the first elements are within the slider, whether they are images, divs, anchors, etc 20 | border-radius(2px) 21 | position relative 22 | display inline-block 23 | //height 100% 24 | //min-width 100px //So something is show while loading 25 | margin-left $sliderSpacing 26 | margin-right -3px //Remove inline block extra spacing 27 | margin-top $sliderSpacing 28 | margin-bottom $sliderSpacing 29 | overflow hidden 30 | 31 | img 32 | height $sliderHeight 33 | // -webkit-transition all 300ms 34 | // transition all 300ms 35 | //min-width 10vw 36 | 37 | // .nt-enlarged 38 | // min-width 100vw 39 | // height auto 40 | 41 | .nt-caption 42 | font-size 0.7em 43 | 44 | 45 | 46 | 47 | //PHOTOS 48 | .nt-photo 49 | position relative 50 | 51 | //Captions 52 | .nt-caption 53 | position absolute 54 | bottom 0 55 | left 0 56 | width 100% 57 | height auto 58 | border-radius(2px) 59 | padding 10px 60 | background-color $colorGreyDark 61 | color $colorTextLight 62 | font-size 0.8em 63 | opacity 0.8 64 | white-space normal 65 | 66 | 67 | //Ready for nt-lazy 68 | //If minimum 100vw, stops all the horizontal images from loading immediately because they all have 0 width and are therefore all in view 69 | .nt-slider 70 | [data-src] 71 | width 100vw 72 | -------------------------------------------------------------------------------- /packages/native-transitions/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'jamielob:native-transitions', 3 | version: '1.2.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Actual native transitions for your Meteor app on iOS and Android', 6 | // URL to the Git repository containing the source code for this package. 7 | git: '', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Cordova.depends({ 14 | // 'com.telerik.plugins.nativepagetransitions': '0.6.0' 15 | //Fixes topOffsetPixel adding margin https://github.com/Telerik-Verified-Plugins/NativePageTransitions/tarball/7409e2f9a28a069095862d7b1d14d03207acffb9 16 | //Fixes console log warning 17 | //'com.telerik.plugins.nativepagetransitions': 'https://github.com/Telerik-Verified-Plugins/NativePageTransitions/tarball/e0b9839315353db9329cbf7fe25fb5f548c1dd7f' 18 | //0.6.1 19 | //'com.telerik.plugins.nativepagetransitions': 'https://github.com/Telerik-Verified-Plugins/NativePageTransitions/tarball/2d7cbc23bb10312e676f3ef51ca42b8fbe4d4105' 20 | //0.6.2 21 | //'com.telerik.plugins.nativepagetransitions': 'https://github.com/Telerik-Verified-Plugins/NativePageTransitions/tarball/860e2f60df294195a1bdb07103f7d954f2bd9af2' 22 | //0.6.3 23 | 'com.telerik.plugins.nativepagetransitions': 'https://github.com/Telerik-Verified-Plugins/NativePageTransitions/tarball/611528b80cb5e50c836da74bdcf5e26793fcc0d6' 24 | }); 25 | 26 | Package.onUse(function(api) { 27 | api.versionsFrom('1.3-beta.11'); 28 | api.use('ecmascript'); 29 | api.use(['templating', 'jquery'], ['client']); 30 | api.addFiles('native-transitions.js', 'client'); 31 | 32 | //Exposes options and defaults so user can override 33 | api.export("nt"); 34 | 35 | }); 36 | -------------------------------------------------------------------------------- /client/views/tab3.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/scroll-history/scroll-history.js: -------------------------------------------------------------------------------- 1 | var scrollHistoryPositions = {}; 2 | var scrollHistoryHeights = {}; 3 | var isBack = false; 4 | 5 | scrollHistory = function(jQueryObject, bothDirections) { 6 | 7 | //Get the current route 8 | var routeName = FlowRouter.current().path; 9 | 10 | //Check if it came from a back button 11 | if (isBack || bothDirections) { 12 | 13 | //Add a temp div so that the scrolling works even when all content isn't loaded 14 | jQueryObject.append('
'); 15 | 16 | //Wait for Dom 17 | Meteor.defer(function() { 18 | 19 | //Scroll to the last position 20 | jQueryObject.scrollTop(scrollHistoryPositions[routeName]); 21 | 22 | //Remove the temp div 23 | Meteor.setTimeout(function() { 24 | jQueryObject.find('#scrollHistoryTempDiv').remove(); 25 | }, 500); 26 | 27 | //Reset isBack 28 | isBack = false; 29 | 30 | }); 31 | } 32 | 33 | 34 | //Monitor the scroll 35 | jQueryObject.scroll(function(event) { 36 | 37 | //Save the new position 38 | var scrollPosition = jQueryObject.scrollTop(); 39 | scrollHistoryPositions[routeName] = scrollPosition; 40 | 41 | //Save the current height 42 | var scrollHeight = jQueryObject.outerHeight(); 43 | scrollHistoryHeights[routeName] = scrollPosition; 44 | 45 | }); 46 | 47 | } 48 | 49 | //Listen for back buttons 50 | document.addEventListener("backbutton", function() { 51 | isBack = true; 52 | //Reset after 500ms - this means even pages that don't call the scrollHistory function will rest the direction correctly 53 | Meteor.setTimeout(function() { 54 | isBack = false; 55 | }, 500); 56 | }, false); 57 | 58 | 59 | Template.body.events({ 60 | 'click .nt-backButton': function () { 61 | isBack = true; 62 | //Reset after 500ms - this means even pages that don't call the scrollHistory function will rest the direction correctly 63 | Meteor.setTimeout(function() { 64 | isBack = false; 65 | }, 500); 66 | } 67 | }); -------------------------------------------------------------------------------- /packages/native-transitions-components/ntSliderZoom.js: -------------------------------------------------------------------------------- 1 | Template.body.events({ 2 | 3 | 'click .nt-slider-zoom .nt-photo': function (event, template) { 4 | 5 | //Get the img, container and content 6 | var $img = $(event.currentTarget).find('img'); 7 | var $container = $(event.currentTarget).parents('.nt-slider'); 8 | var $content = $(event.currentTarget).parents('.nt-content'); 9 | 10 | //Scroll up 11 | var offsetTop = $container[0].offsetTop; 12 | $content.animate({scrollTop: offsetTop }, 200); 13 | 14 | //Check if it's already enlarged 15 | if ($img.hasClass('nt-enlarged')) { 16 | //Return to normal 17 | $img.velocity({ 18 | width: $img.data('originalWidth'), 19 | height: $img.data('originalHeight') 20 | }, { duration: 200 }); 21 | 22 | //Toggle the enlarged class 23 | $img.removeClass('nt-enlarged'); 24 | 25 | } else { 26 | //Reduce any other enlarged images 27 | var $enlarged = $container.find('.nt-enlarged'); 28 | $enlarged.velocity({ 29 | width: $enlarged.data('originalWidth'), 30 | height: $enlarged.data('originalHeight') 31 | }, { 32 | duration: 200, 33 | complete: function() { 34 | $(this).removeClass('nt-enlarged'); 35 | } 36 | }); 37 | //$enlarged.css('width', $enlarged.data('originalWidth')); 38 | //$enlarged.css('height', $enlarged.data('originalHeight')); 39 | 40 | //Save the original sizes 41 | $img.data('originalWidth', $img.width()); 42 | $img.data('originalHeight', $img.height()); 43 | 44 | //Calculate the bigger size (100% of the viewport) 45 | var ratio = $(window).width() / $img.width(); 46 | var newWidth = $(window).width() + 'px'; 47 | var newHeight = ( $img.height() * ratio ) + 'px'; 48 | //Animate 49 | $img.velocity({ 50 | width: newWidth, 51 | height: newHeight 52 | }, { 53 | duration: 200, 54 | complete: function() { 55 | var offsetLeft = event.currentTarget.offsetLeft; 56 | $container.animate({scrollLeft: offsetLeft }, 200); 57 | $img.addClass('nt-enlarged'); 58 | } 59 | 60 | }); 61 | 62 | // //Scroll into place 63 | // Meteor.setTimeout(function() { 64 | 65 | // }, 500); 66 | 67 | } 68 | 69 | 70 | } 71 | }); 72 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Native Transitions Demo 2 | 3 | 4 | 5 | This is a demo repo for the `native transitions for mobile` packages that I'm building for Meteor 1.3. Everything in here is liable to change without notice so use at your own risk. 6 | 7 | The native transitions package is usable on it's own without any of the other packages and is as simple to use as calling the function inside onRendered: 8 | ``` 9 | Template.templateName.onRendered(function() { 10 | nt.transition(); 11 | }); 12 | ``` 13 | 14 | The repo contains several packages: 15 | 16 | ##native-transitions 17 | This is the core transitions package. It implements the [Telerik Cordova plugin](http://plugins.telerik.com/cordova/plugin/native-page-transitions) with a Meteor friendly interface. 18 | > When invoked, the plugin immediately grabs a screenshot of your webview, then waits a little for the new content to load, and then performs the transition by animating out the screenshot and in the view. 19 | 20 | The package and readme can be found [here](packages/native-transitions) 21 | 22 | ##native-transitions-stylus 23 | This package is a set of styles to enable quick app layouts as seen [here](https://twitter.com/JamieLoberman/status/697152622805938177). Package is [here](packages/native-transitions-stylus) 24 | 25 | ##native-transitions-tabs 26 | This is a package to allow tab functionality in your app. It keeps the place of long lists by keeping the tabs "alive" in the background. 27 | Package is [here](packages/native-transitions-tabs) 28 | 29 | ##native-transitions-header 30 | This is a package to allow static header functionality in your app. It keeps the header in place when transitioning between two views that have headers. 31 | Package is [here](packages/native-transitions-header) 32 | 33 | ##native-transitions-components 34 | This package currently just contains a back button helper, but will also contain other componenents that work well with the native transitions, such as modals and slide down menus. 35 | Package is [here](packages/native-transitions-components) 36 | 37 | ##native-spinner 38 | This is a native spinner for iOS and Android. It provide a Meteor interface for [cordova-plugin-spinner](https://www.npmjs.com/package/cordova-plugin-spinner) 39 | Package is [here](packages/native-spinner). 40 | -------------------------------------------------------------------------------- /.meteor/versions: -------------------------------------------------------------------------------- 1 | allow-deny@1.0.1-beta.11 2 | autopublish@1.0.4 3 | autoupdate@1.2.5-beta.11 4 | babel-compiler@6.4.0-beta.11 5 | babel-runtime@0.1.5-beta.11 6 | base64@1.0.5-beta.11 7 | binary-heap@1.0.5-beta.11 8 | blaze@2.1.4-beta.11 9 | blaze-html-templates@1.0.1 10 | blaze-tools@1.0.5-beta.11 11 | boilerplate-generator@1.0.5-beta.11 12 | caching-compiler@1.0.1-beta.11 13 | caching-html-compiler@1.0.3-beta.11 14 | callback-hook@1.0.5-beta.11 15 | check@1.1.1-beta.11 16 | coffeescript@1.0.12-beta.11 17 | cosmos:browserify@0.9.3 18 | crosswalk@1.4.0-beta.11 19 | ddp@1.2.2 20 | ddp-client@1.2.2-beta.11 21 | ddp-common@1.2.2 22 | ddp-server@1.2.3-beta.11 23 | deps@1.0.9 24 | diff-sequence@1.0.2-beta.11 25 | ecmascript@0.4.0-beta.11 26 | ecmascript-runtime@0.2.7-beta.11 27 | ejson@1.0.8-beta.11 28 | es5-shim@4.3.2-beta.11 29 | fastclick@1.0.8-beta.11 30 | geojson-utils@1.0.5-beta.11 31 | gwendall:body-events@0.1.6 32 | hot-code-push@1.0.1-beta.11 33 | html-tools@1.0.6-beta.11 34 | htmljs@1.0.6-beta.11 35 | http@1.1.2-beta.11 36 | id-map@1.0.4 37 | insecure@1.0.4 38 | jamielob:native-transitions@1.1.0 39 | jamielob:native-transitions-components@1.0.0 40 | jamielob:native-transitions-header@1.0.0 41 | jamielob:native-transitions-stylus@0.5.0 42 | jamielob:native-transitions-tabs@1.0.0 43 | jquery@1.11.5-beta.11 44 | kadira:blaze-layout@2.3.0 45 | kadira:flow-router@2.10.1 46 | launch-screen@1.0.6-beta.11 47 | livedata@1.0.15 48 | logging@1.0.9-beta.11 49 | meteor@1.1.11-beta.11 50 | meteor-base@1.0.1 51 | meteor-env-dev@0.0.1-beta.11 52 | meteor-env-prod@0.0.1-beta.11 53 | minifier-css@1.1.8-beta.11 54 | minifier-js@1.1.8-beta.11 55 | minimongo@1.0.11-beta.11 56 | mobile-experience@1.0.1 57 | mobile-status-bar@1.0.8-beta.11 58 | modules@0.5.0-beta.11 59 | modules-runtime@0.5.0-beta.11 60 | mongo@1.1.4-beta.11 61 | mongo-id@1.0.1 62 | npm-mongo@1.4.40-beta.11 63 | observe-sequence@1.0.8-beta.11 64 | ordered-dict@1.0.4 65 | pagebakers:ionicons@2.0.1_1 66 | promise@0.5.2-beta.11 67 | random@1.0.6-beta.11 68 | reactive-dict@1.1.4-beta.11 69 | reactive-var@1.0.6 70 | reload@1.1.5-beta.11 71 | retry@1.0.4 72 | routepolicy@1.0.7-beta.11 73 | session@1.1.2-beta.11 74 | spacebars@1.0.8-beta.11 75 | spacebars-compiler@1.0.8-beta.11 76 | standard-minifier-css@1.0.3-beta.11 77 | standard-minifier-js@1.0.3-beta.11 78 | standard-minifiers@1.0.3-beta.11 79 | stylus@2.511.2-beta.11 80 | templating@1.1.6-beta.11 81 | templating-tools@1.0.1-beta.11 82 | tracker@1.0.10-beta.11 83 | ui@1.0.8 84 | underscore@1.0.5-beta.11 85 | url@1.0.6-beta.11 86 | velocityjs:velocityjs@1.2.1 87 | webapp@1.2.5-beta.11 88 | webapp-hashing@1.0.6-beta.11 89 | -------------------------------------------------------------------------------- /packages/native-transitions-components/ntSlide.css: -------------------------------------------------------------------------------- 1 | .nt-slideDown .nt-element { 2 | position: absolute; 3 | z-index: 3; 4 | top:0; 5 | left:0; 6 | width: 100%; 7 | background-color: #FFFFFF; 8 | transform: translate3d(0, -100%, 0); 9 | -webkit-transform: translate3d(0, -100%, 0); 10 | } 11 | 12 | 13 | .nt-slideDown.nt-element-in .nt-element { 14 | -webkit-animation: nt-slideDown-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 15 | animation: nt-slideDown-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 16 | } 17 | @-webkit-keyframes nt-slideDown-in { 18 | from { -webkit-transform: translate3d(0, -100%, 0); } 19 | to { -webkit-transform: translate3d(0, 0, 0); } 20 | } 21 | @keyframes nt-slideDown-in { 22 | from { transform: translate3d(0, -100%, 0); } 23 | to { transform: translate3d(0, 0, 0); } 24 | } 25 | 26 | 27 | .nt-slideDown.nt-element-out .nt-element { 28 | -webkit-animation: nt-slideDown-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 29 | animation: nt-slideDown-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 30 | } 31 | @-webkit-keyframes nt-slideDown-out { 32 | from { -webkit-transform: translate3d(0, 0, 0); } 33 | to { -webkit-transform: translate3d(0, -100%, 0); } 34 | } 35 | @keyframes nt-slideDown-out { 36 | from { transform: translate3d(0, 0, 0); } 37 | to { transform: translate3d(0, -100%, 0); } 38 | } 39 | 40 | 41 | .nt-slideUp .nt-element { 42 | position: absolute; 43 | z-index: 3; 44 | bottom:0; 45 | left:0; 46 | width: 100%; 47 | background-color: #FFFFFF; 48 | transform: translate3d(0, 100%, 0); 49 | -webkit-transform: translate3d(0, 100%, 0); 50 | } 51 | 52 | .nt-slideUp.nt-element-in .nt-element { 53 | -webkit-animation: nt-slideUp-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 54 | animation: nt-slideUp-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 55 | } 56 | @-webkit-keyframes nt-slideUp-in { 57 | from { -webkit-transform: translate3d(0, 100%, 0); } 58 | to { -webkit-transform: translate3d(0, 0, 0); } 59 | } 60 | @keyframes nt-slideUp-in { 61 | from { transform: translate3d(0, 100%, 0); } 62 | to { transform: translate3d(0, 0, 0); } 63 | } 64 | 65 | 66 | .nt-slideUp.nt-element-out .nt-element { 67 | -webkit-animation: nt-slideUp-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 68 | animation: nt-slideUp-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both; 69 | } 70 | @-webkit-keyframes nt-slideUp-out { 71 | from { -webkit-transform: translate3d(0, 0, 0); } 72 | to { -webkit-transform: translate3d(0, 100%, 0); } 73 | } 74 | @keyframes nt-slideUp-out { 75 | from { transform: translate3d(0, 0, 0); } 76 | to { transform: translate3d(0, 100%, 0); } 77 | } 78 | -------------------------------------------------------------------------------- /packages/native-transitions-components/ntElement.js: -------------------------------------------------------------------------------- 1 | Template.body.events({ 2 | 'click [nt-target]': function (event, template) { 3 | //Get the target name 4 | var $ntElement = $(event.currentTarget); 5 | nt.triggerElement($ntElement); 6 | }, 7 | }); 8 | 9 | nt.triggerElement = function($ntElement) { 10 | 11 | ntTarget = $ntElement.attr('nt-target'); 12 | 13 | //Hide any others that are showing 14 | var $ntOtherTargets = $('[nt-element]').not('[nt-element="' + ntTarget + '"]'); 15 | if ( $ntOtherTargets.hasClass('nt-element-in') ) { 16 | $ntOtherTargets.removeClass('nt-element-in'); 17 | } 18 | 19 | //Get the target element 20 | var $ntTarget = $('[nt-element="' + ntTarget + '"]'); 21 | //If it's showing 22 | if ( $ntTarget.hasClass('nt-element-in') ) { 23 | 24 | //If the element has an href, hide it immediately 25 | if( $ntElement.attr("href") ) { 26 | $ntTarget.removeClass('nt-element-in').removeClass('nt-element-out'); 27 | } else { 28 | 29 | //Otherwise animate it out of view 30 | $ntTarget.addClass('nt-element-out').removeClass('nt-element-in').on("animationend oAnimationEnd webkitAnimationEnd", function(event) { 31 | //Make sure it's only on the out animation 32 | if (!$(event .currentTarget).hasClass('nt-element-out')) return; 33 | $(this).off("animationend oAnimationEnd webkitAnimationEnd"); 34 | //Removing the class onon end so we can hide the overlay easily using css 35 | $(this).removeClass('nt-element-out') 36 | }); 37 | } 38 | 39 | //Need to move to using js on mobile because of CSS flicker (reduced using fix already implemented) 40 | //http://stackoverflow.com/questions/17747239/ios-flicker-bug-when-the-css-overflowscroll-is-changed-to-overflowhidden 41 | //But couldn't figure out a way of doing it cleanly, so leaving it as CSS with flicker for now 42 | //Don't implement the same delay below up here, as it takes too long to re-implement scrolling that way. 43 | $('.nt-current .nt-content').not('.nt-element .nt-content').css('overflow-y', '') 44 | 45 | 46 | //Otherwise 47 | } else { 48 | //Animate it in to view 49 | $ntTarget.addClass('nt-element-in').removeClass('nt-element-out').on("animationend oAnimationEnd webkitAnimationEnd", function(event) { 50 | //Make sure it's only on the in animation 51 | if (!$(event.currentTarget).hasClass('nt-element-in')) return; 52 | $(this).off("animationend oAnimationEnd webkitAnimationEnd"); 53 | //Disable scrolling underneath - Doing at the end of the animation seems to reduce/remove the flicker mentioned above 54 | $('.nt-current .nt-content').not('.nt-element .nt-content').css('overflow-y', 'hidden'); 55 | }); 56 | 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /client/views/buttons.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/reset.import.styl: -------------------------------------------------------------------------------- 1 | //RESET 2 | /* 3 | html5doctor.com Reset Stylesheet 4 | v1.6.1 5 | Last Updated: 2010-09-17 6 | Author: Richard Clark - http://richclarkdesign.com 7 | Twitter: @rich_clark 8 | Stylus-ized by 9 | dale tan 10 | http://www.whatthedale.com 11 | @HellaTan 12 | */ 13 | 14 | html, body, span, object, iframe, 15 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 16 | abbr, address, cite, code, 17 | del, dfn, em, img, ins, kbd, q, samp, 18 | small, strong, sub, sup, var, 19 | b, i, 20 | dl, dt, dd, ol, ul, li, 21 | fieldset, form, label, legend, 22 | table, caption, tbody, tfoot, thead, tr, th, td, 23 | article, aside, canvas, details, figcaption, figure, 24 | footer, header, hgroup, menu, nav, section, summary, 25 | time, mark, audio, video, button 26 | background transparent 27 | border 0 28 | font-size 100% 29 | margin 0 30 | outline 0 31 | padding 0 32 | // vertical-align middle 33 | font-weight $fontWeight 34 | font-family $fontFamily 35 | line-height $lineHeight //Causing style issues in plugins (e.g. Constellation) when applied to div (just removed div from list above) 36 | -webkit-touch-callout none 37 | -webkit-user-select none 38 | -khtml-user-select none 39 | -moz-user-select none 40 | -ms-user-select none 41 | user-select none 42 | 43 | body 44 | line-height:1; 45 | 46 | article, aside, details, figcaption, figure, 47 | footer, header, hgroup, menu, nav, section 48 | display block 49 | 50 | nav ul 51 | list-style none 52 | 53 | blockquote, q 54 | quotes none 55 | 56 | blockquote:before, blockquote:after, 57 | q:before, q:after 58 | content '' 59 | content none 60 | 61 | a 62 | background transparent 63 | font-size 100% 64 | margin 0 65 | padding 0 66 | vertical-align middle 67 | 68 | strong 69 | font-weight 400 70 | vertical-align bottom 71 | 72 | /* change colours to suit your needs */ 73 | ins 74 | background-color #ff9 75 | color #000 76 | text-decoration none 77 | 78 | /* change colours to suit your needs */ 79 | mark 80 | background-color #ff9 81 | color #000 82 | font-style italic 83 | font-weight bold 84 | 85 | del 86 | text-decoration line-through 87 | 88 | abbr[title], dfn[title] 89 | border-bottom 1px dotted 90 | cursor help 91 | 92 | table 93 | border-collapse collapse 94 | border-spacing 0 95 | 96 | /* change border colour to suit your needs */ 97 | hr 98 | border 0 99 | border-top 1px solid #ccc 100 | display block 101 | height 1px 102 | margin 1em 0 103 | padding 0 104 | 105 | input, select 106 | vertical-align middle 107 | 108 | h1, h2, h3, h4, h5 ,h6, p 109 | position relative 110 | 111 | 112 | //Icons 113 | i 114 | font-size 1.5em 115 | 116 | 117 | //Box Model reset 118 | html { 119 | -webkit-box-sizing: border-box; 120 | -moz-box-sizing: border-box; 121 | box-sizing: border-box; 122 | } 123 | *, *:before, *:after { 124 | -webkit-box-sizing: inherit; 125 | -moz-box-sizing: inherit; 126 | box-sizing: inherit; 127 | } 128 | 129 | 130 | // Remove tap highlight on iOS 131 | *, 132 | input, 133 | textarea, 134 | button, 135 | select, 136 | label, 137 | a { 138 | -webkit-tap-highlight-color: rgba(0,0,0,0); 139 | } 140 | 141 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/variables.import.styl: -------------------------------------------------------------------------------- 1 | //GENERAL & LAYOUT 2 | $padding ?= 20px 3 | $verticalSpacing ?= 5px 4 | $largeMultiplier ?= 1.3 5 | $smallMultiplier ?= 0.7 6 | 7 | //HEADER 8 | $headerHeight ?= 44px 9 | $headerBackgroundColor ?= $colorPrimary 10 | $headerColor ?= $colorTextLight 11 | 12 | //SUBHEADER 13 | $subheaderHeight ?= 44px 14 | $subheaderBackgroundColor ?= $colorSecondary 15 | $subheaderColor ?= $colorTextDark 16 | 17 | //SCROLL 18 | $ntScrollBackgroundColor ?= #FFFFFF 19 | 20 | //FOOTER 21 | $footerHeight ?= 44px 22 | $footerBackgroundColor ?= #FFFFFF 23 | $footerColor ?= $colorTextDark 24 | 25 | //STATUS BAR 26 | $statusBarHeight ?= 22px 27 | $statusBarBackgroundColor ?= $headerBackgroundColor 28 | 29 | //TEXT 30 | $fontFamily ?= "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif 31 | $fontWeight ?= 300 32 | $lineHeight ?= 130% 33 | $fontSize ?= 1em 34 | $fontSizeLarge ?= 1.4em 35 | $linkColor ?= $colorPrimary 36 | 37 | 38 | //COLORS 39 | $colorPrimary ?= #007aff 40 | $colorSecondary ?= #34aadc 41 | $colorDarkPrimary ?= #003064 42 | $colorDarkSecondary ?= #001f41 43 | $colorFacebook ?= #3b5998 44 | $colorGreyDark ?= #666666 45 | $colorGreyMedium ?= #7b7b7b 46 | $colorGreyLight ?= #e3e3e3 47 | $colorTextLight ?= #FFFFFF 48 | $colorTextDark ?= #333333 49 | $colorOffWhite ?= #F1F1F1 50 | $colorBorder ?= #8c8c8c 51 | 52 | 53 | //VISUAL 54 | $borderRadius ?= 2px 55 | 56 | //AVATARS 57 | $avatarSize ?= 55px 58 | 59 | //RANKS 60 | $rankSize ?= 55px 61 | 62 | //RANK 63 | $rankBackgroundColor ?= $colorPrimary 64 | $rankColor ?= $colorTextLight 65 | $rankFontSize ?= 1.7em 66 | 67 | 68 | 69 | //SLIDER 70 | $sliderSpacing ?= 5px 71 | $sliderHeight ?= 175px 72 | 73 | 74 | 75 | 76 | //TABS 77 | $tabsHeight ?= 50px 78 | $tabsBackgroundColor ?= $colorOffWhite 79 | $tabsColor ?= $colorGreyDark 80 | $tabsBorderColor ?= $colorGreyLight 81 | $tabsBorderWidth ?= 0px 82 | $tabsBorderStyle ?= solid 83 | $tabsActiveColor ?= $colorPrimary 84 | $tabsDividerColor ?= $colorGreyLight 85 | $tabsDividerWidth ?= 1px 86 | $tabsDividerStyle ?= solid 87 | 88 | 89 | //BUTTONS 90 | $buttonBorderColor ?= $colorGreyLight 91 | $buttonBorderStyle ?= solid 92 | $buttonBorderWidth ?= 1px 93 | $buttonPaddingVertical ?= 15px 94 | $buttonPaddingHorizontal ?= 15px 95 | $buttonBackgroundColor ?= $colorSecondary 96 | $buttonColor ?= $colorTextLight 97 | 98 | //OVERLAY 99 | $overlayBackgroundColor ?= $colorGreyDark 100 | $overlayOpacity ?= 0.9 101 | 102 | 103 | //DIVIDER 104 | $dividerBackgroundColor ?= $colorGreyDark 105 | $dividerColor ?= $colorTextLight 106 | $dividerHeight ?= 10px 107 | 108 | //ITEMS 109 | $itemHeaderBackgroundColor ?= $colorGreyDark 110 | $itemHeaderColor ?= $colorTextLight 111 | 112 | 113 | //FORMS 114 | 115 | //INPUT 116 | $inputColor ?= $colorTextDark 117 | $inputBorderColor ?= $colorGreyLight 118 | $inputBorderWidth ?= 1px 119 | $inputBorderStyle ?= solid 120 | $inputBorderRadius ?= 0 121 | $inputPadding ?= 13px 122 | $inputFontWeight ?= $fontWeight 123 | $inputIconColor ?= $colorGreyMedium 124 | 125 | //INPUT - CHECKBOX 126 | $checkboxBackgroundColor ?= $colorPrimary 127 | $checkboxBorderColor ?= $colorGreyLight 128 | 129 | //TAP FEEDBACK 130 | $activeBackgroundColor = $colorGreyLight 131 | 132 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/forms.import.styl: -------------------------------------------------------------------------------- 1 | //Reset 2 | 3 | textarea 4 | input[type="text"] 5 | input[type="password"] 6 | input[type="datetime"] 7 | input[type="datetime-local"] 8 | input[type="date"] 9 | input[type="month"] 10 | input[type="time"] 11 | input[type="week"] 12 | input[type="number"] 13 | input[type="email"] 14 | input[type="url"] 15 | input[type="search"] 16 | input[type="tel"] 17 | input[type="color"] 18 | select 19 | display block 20 | padding $inputPadding 21 | color $inputColor 22 | background-color #FFFFFF 23 | vertical-align middle 24 | font-size 0.9em 25 | width 100% 26 | -webkit-appearance none 27 | border-radius 0 28 | border none 29 | font-weight $inputFontWeight 30 | 31 | 32 | //INPUT 33 | 34 | 35 | .nt-input 36 | position relative 37 | display -webkit-flex 38 | display flex 39 | align-items center 40 | -webkit-align-items center 41 | width 100% 42 | border-radius $inputBorderRadius 43 | border-color $inputBorderColor 44 | border-width $inputBorderWidth 45 | border-style $inputBorderStyle 46 | height 50px 47 | 48 | label 49 | -webkit-flex-basis 40% 50 | flex-basis 40% 51 | padding-left $padding 52 | 53 | i 54 | -webkit-flex-basis 30px 55 | flex-basis 30px 56 | -webkit-flex-grow 0 57 | flex-grow 0 58 | -webkit-flex-shrink 0 59 | flex-shrink 0 60 | text-align right 61 | color $inputIconColor 62 | padding-top 10px 63 | padding-bottom 10px 64 | font-size 1.1em 65 | 66 | &.nt-clear 67 | text-align left 68 | 69 | &.nt-clear:active 70 | opacity 0.5 71 | 72 | 73 | input 74 | -webkit-flex-basis auto 75 | flex-basis auto 76 | padding-left 10px 77 | padding-right $padding 78 | 79 | select 80 | -webkit-flex-basis 220px 81 | flex-basis 220px 82 | -webkit-flex-grow 1 83 | flex-grow 1 84 | direction rtl 85 | -webkit-appearance none 86 | appearance none 87 | text-indent 0.01px 88 | text-overflow ellipsis 89 | white-space nowrap 90 | padding-right 40px 91 | font-size 0.7em 92 | 93 | &:active 94 | opacity 0.5 95 | 96 | 97 | //SELECT 98 | .nt-select 99 | position relative 100 | 101 | &:after 102 | position absolute 103 | top 20px 104 | right 20px 105 | content "" 106 | border-top 5px solid 107 | border-right 5px solid rgba(0, 0, 0, 0) 108 | border-left 5px solid rgba(0, 0, 0, 0) 109 | color $inputIconColor 110 | pointer-events none 111 | 112 | 113 | //Input - checkbox 114 | .nt-checkbox 115 | display block 116 | position relative 117 | width 100% 118 | padding-top 1px 119 | border-bottom $colorGreyLight 1px solid 120 | 121 | //Hide the checkbox, but size it correctly 122 | input[type="checkbox"] 123 | display inline-block 124 | height 45px 125 | margin-left $padding 126 | margin-right 20px 127 | -webkit-appearance none 128 | appearance none 129 | border 0 130 | background transparent 131 | 132 | //Add the newly styled circle 133 | input[type="checkbox"]:before 134 | display table 135 | margin-top 8.5px 136 | width 26px 137 | height 26px 138 | border-width 1px 139 | border-style solid 140 | border-radius 100% 141 | border-color $checkboxBorderColor 142 | background #fff 143 | content ' ' 144 | -webkit-transition background-color 20ms ease-in-out 145 | transition background-color 20ms ease-in-out 146 | 147 | //Change the color when it's selected 148 | input[type="checkbox"]:checked:before 149 | border none 150 | background $checkboxBackgroundColor 151 | 152 | //Add the checmark 153 | input[type="checkbox"]:checked:after 154 | -webkit-transition opacity 0.05s ease-in-out 155 | transition opacity 0.05s ease-in-out 156 | -webkit-transform rotate(-45deg) 157 | transform rotate(-45deg) 158 | position absolute 159 | top 20px 160 | left $padding + 6px 161 | display table 162 | width 14px 163 | height 6px 164 | border 1px solid #fff 165 | border-top 0 166 | border-right 0 167 | content ' ' 168 | 169 | .nt-crossbox 170 | @extend .nt-checkbox 171 | 172 | input[type="checkbox"]:checked:after 173 | -webkit-transition opacity 0.05s ease-in-out 174 | transition opacity 0.05s ease-in-out 175 | -webkit-transform rotate(0) 176 | transform rotate(0) 177 | position absolute 178 | top 12px 179 | display table 180 | width 14px 181 | height 6px 182 | border none 183 | color #FFFFFF 184 | font-size 1.7em 185 | text-align center 186 | content 'x' -------------------------------------------------------------------------------- /packages/native-transitions/README.md: -------------------------------------------------------------------------------- 1 | #Native Transitions for Meteor Mobile Apps 2 | 3 | ##Setup 4 | 5 | `meteor add jamielob:native-transitions` 6 | 7 | Simply add the following to your template's onRendered function: 8 | 9 | ``` 10 | nt.transition(); 11 | ``` 12 | 13 | If you want to set the options, just pass in an object: 14 | 15 | ``` 16 | nt.transition({ 17 | type: 'flip', 18 | direction: 'left' 19 | }); 20 | ``` 21 | 22 | ##Status bar 23 | You'll need to style your status bar to make things look nice. 24 | ```meteor add mobile-status-bar``` 25 | 26 | ``` 27 | Meteor.startup(function() { 28 | if (Meteor.isCordova) { 29 | //Format the status bar 30 | StatusBar.overlaysWebView(false); 31 | StatusBar.styleLightContent(); 32 | StatusBar.backgroundColorByHexString("#2f3339"); 33 | } 34 | }); 35 | ``` 36 | 37 | ##Default settings and options 38 | 39 | If you want to change any of the default global settings you can create a file with any of the following: 40 | 41 | ``` 42 | //Default transition - options are slide, flip, fade 43 | nt.defaults.type = 'slide' 44 | 45 | //Default transition direction - options are left, right, up, down, depending on the transition type 46 | nt.defaults.direction = 'left'; 47 | 48 | //Default back transition direction 49 | nt.defaults.backDirection = 'right'; 50 | 51 | //Default transition duration 52 | nt.defaults.duration = 350; 53 | 54 | //Default delays 55 | nt.defaults.iosdelay = 0; 56 | nt.defaults.androiddelay = 0; 57 | 58 | //Fixed pixels 59 | nt.defaults.fixedPixelsTop = 0; 60 | nt.defaults.fixedPixelsBottom = 0; 61 | 62 | //Slow down factor (overla;) 63 | nt.defaults.slowdownfactor = 4; 64 | 65 | //Callbacks 66 | nt.defaults.onCompleted = null; 67 | ``` 68 | 69 | 70 | ##Header bar 71 | If you want your header bar to remain static while the page transitions and don't want to do it manually with the fixedPixels setting, then you can add the `jamielob:native-transitions-header` package. 72 | 73 | 74 | ##Completed callback 75 | 76 | You can pass a callback function in to the options and it will be called once the transition is completed. 77 | 78 | ``` 79 | nt.transition({ 80 | type: 'flip', 81 | direction: 'left', 82 | onCompleted: function() { 83 | alert('Transition completed!'); 84 | } 85 | }); 86 | ``` 87 | 88 | 89 | ##Speed 90 | Don't put too much on a single page otherwise the transition will have a delay. Check out the native-transitions-tabs package for your core app pages. 91 | 92 | 93 | ##Router 94 | Although this package doesn't depend on FlowRouter, it's the best one to use with it. 95 | The native-transitions-tabs package does depend on FlowRouter, making use of the reactive query params. 96 | 97 | 98 | ##Companion app warning 99 | 100 | ```Probably running inside a companion app, your app may crash if your html file is not in the root!``` 101 | 102 | This warning is generated by the cordova plugin and can be safely ignored for your Meteor app. I'm working on hiding it. 103 | 104 | ##Flickers and slow downs 105 | 106 | This could be because you are doing something in your onRendered that is interefering with the transition, e.g. a method call or subscribes. Try placing anything heavy in a defer. 107 | 108 | If you are seeing a flicker of the page that you are headed to at the start of your transition then you might just need some more content! It usually happens because the page that you are loading is loaded so quickly that you see it before the screenshot of the old page can be displayed. Try adding some dummy CSS styles content and see if it fixes it for you. 109 | 110 | You can also try changing the duration. 111 | 112 | Autoruns can cause trouble if they are running multiple times during the transition period. Comment them out and see if the problem persists. 113 | 114 | At the other end of the spectrum, flickers and slow downs can sometimes be because a page has too much content. Try lightening the load and be sure to text on older devices! 115 | 116 | If you see a "ghost" image on every transition, this could be because of a bug related to two quick successive transitions in a row. I have seen this happen for example with the Facebook Cordova plugin after a succesful login. It can be fixed in that example by placing a short delay after the succesful login before redirecting. 117 | 118 | ##Crosswalk 119 | If you are using crosswalk then you will need to add a line to your `mobile-config.js` file: 120 | ``` 121 | App.setPreference('CrosswalkAnimatable', 'true'); 122 | ``` 123 | 124 | Without this line you'll see an error stating `Unfortunately, APPNAME has stopped`. -------------------------------------------------------------------------------- /packages/native-transitions-tabs/README.md: -------------------------------------------------------------------------------- 1 | #Native Transitions Tabs 2 | Tabbed core pages that remember scroll position and content 3 | 4 | ```meteor add jamielob:native-transitions-tabs``` 5 | 6 | The readme below is pretty comprehensive, but it's really simple to get this working. I've provided a demo repo that you can use for setup reference too. 7 | 8 | ##Dependencies 9 | 10 | This is an extension for the `jamielob:native-transitions` package. 11 | 12 | ```meteor add jamielob:native-transitions``` 13 | 14 | The native-transitions-tabs package depends on FlowRouter, making use of the reactive query params to track when the tab has changed and update the view. 15 | 16 | ```meteor add kadira:flow-router``` 17 | 18 | It also needs to render a placeholder template on a route (explained below). For this I reccomend using BlazeLayout 19 | 20 | ```meteor add kadira:blaze-layout``` 21 | 22 | You could roll your own styles in theory, but it is reccomended that you add the `jamielob:native-transitions-stylus` package to your project if you haven't already. 23 | 24 | ```meteor add jamielob:native-transitions-stylus``` 25 | 26 | If you want the tab icons that I've included in the examples below to work (optional), you'll need to add the `pagebakers:ionicons` package to your project. 27 | 28 | ```meteor add pagebakers:ionicons``` 29 | 30 | 31 | ##Setup 32 | 33 | Designate a single route in your app to handle all of the tabs. This is so the native transitions can work, without losing our scroll position or destroying the content on the tabs. Add the following to your router. 34 | 35 | ``` 36 | FlowRouter.route('/', { 37 | name: 'tabs', 38 | action: function() { 39 | if (!FlowRouter.getQueryParam('nt-tab')) FlowRouter.setQueryParams({'nt-tab': 1 }); 40 | BlazeLayout.render('ntPlaceholder'); 41 | } 42 | }); 43 | ``` 44 | 45 | The route itself and name can be anything you like, but just make sure that it renders the `ntPlaceholder` template which is provided by this package. To pick which tab container is displayed first change the tab number that is set by FlowRouter in the snippet above. 46 | 47 | In the of your app use the following to set up the templates you want to use for the tabs and pages, as well as the buttons along the bottom. You can have up to 5 tabs. 48 | 49 | ``` 50 | {{#ntTabs template1="tab1" template2="tab2" template3="tab3" template4="tab4"}} 51 | 52 | {{#ntTab position="1"}} 53 | 54 | Tab 1 55 | {{/ntTab}} 56 | 57 | {{#ntTab position="2"}} 58 | 59 | Tab 2 60 | {{/ntTab}} 61 | 62 | {{#ntTab position="3"}} 63 | 64 | Tab 3 65 | {{/ntTab}} 66 | 67 | {{#ntTab position="4"}} 68 | 69 | Tab 4 70 | {{/ntTab}} 71 | 72 | {{/ntTabs}} 73 | 74 | ``` 75 | 76 | Each of the tab pages should be wrapped in a div with classes of `nt-container` just like any other native-transitions page. 77 | 78 | ``` 79 |
80 | ... 81 |
82 | ``` 83 | 84 | 85 | 86 | ##Pages without tabs 87 | 88 | Tabs stay visible at the bottom of every page by default 89 | 90 | If you have a page that you don't want the tabs to appear on then simply add `.nt-no-tabs` on the `.nt-container` div. 91 | 92 | ``` 93 |
94 | ... 95 |
96 | ``` 97 | 98 | This does three things. First it increases the z-index above the tabs essentially hiding them, second it reduces the pixelsOffsetBottom to zero when entering the page and third it makes sure any links on that page set the pixelOffsetBottom of the native transitions package back to 0 too. Magic! 99 | 100 | 101 | ##Tab height 102 | 103 | Tabs height is set to 50px by default to match the css in the `native-transitions-stylus` package 104 | If you change the height of the tabs, you'll also need to change the `fixedPixelsBottom` setting to match. 105 | 106 | In your lib directory or similar create a file called `nt-settings.js` or similar and include the following in it 107 | 108 | ``` 109 | if (Meteor.isCordova) { 110 | nt.defaults.fixedPixelsBottom = 60; //This number should equal the height of your tabs in px 111 | } 112 | ``` 113 | 114 | 115 | ##Helpers and classes 116 | 117 | The `.nt-tabs-undefined` class is added the the tabs-conainer when they aren't showing. This is used internally to disable scrolling in the underlying `.nt-content` when they aren't being shown to fix a z-index bug on mobile that allows the scrolling of a hidden div. 118 | 119 | The `nt-tabs-x` class is added the the tabs-conainer to show which tab is currently showing where `x` is the tab number. 120 | 121 | You can access this in your template if needed using the `{{ntCurrentTab}}` helper. 122 | 123 | ##Help! My project went blank! 124 | 125 | This usually happens when you've specified a template that doesn't exist. Check all of your template tabs are pointing to the correct templates in your project. -------------------------------------------------------------------------------- /packages/native-transitions/native-transitions.js: -------------------------------------------------------------------------------- 1 | nt = {}; 2 | 3 | //Set defaults 4 | nt.defaults = {}; 5 | 6 | //Default transition - options are slide, flip, fade 7 | nt.defaults.type = 'slide' 8 | 9 | //Default transition direction - options are left, right, up, down, depending on the transition type 10 | nt.defaults.direction = 'left'; 11 | 12 | //Default back transition direction 13 | nt.defaults.backDirection = 'right'; 14 | 15 | //Default transition duration 16 | nt.defaults.duration = 325; 17 | 18 | //Default delays 19 | nt.defaults.iosdelay = 0; 20 | nt.defaults.androiddelay = 0; 21 | 22 | //Fixed pixels 23 | nt.defaults.fixedPixelsTop = 0; 24 | nt.defaults.fixedPixelsBottom = 0; 25 | 26 | //Header and tabs flags 27 | nt.defaults.noHeader = false; 28 | //nt.defaults.fadeHeader = false; 29 | nt.defaults.noTabs = false; 30 | 31 | //Slow down factor (overlap) 32 | nt.defaults.slowdownfactor = 4; 33 | 34 | //Slide pixes 35 | nt.defaults.slidePixels = 0; 36 | 37 | //Callbacks 38 | // nt.defaults.onCompleted = null; 39 | 40 | nt.reset = function() { 41 | nt.type = nt.defaults.type; 42 | nt.direction = nt.defaults.direction; 43 | nt.duration = nt.defaults.duration; 44 | nt.iosdelay = nt.defaults.iosdelay; 45 | nt.androiddelay = nt.defaults.androiddelay; 46 | nt.fixedPixelsTop = nt.defaults.fixedPixelsTop; 47 | nt.fixedPixelsBottom = nt.defaults.fixedPixelsBottom; 48 | nt.noHeader = nt.defaults.noHeader; 49 | //nt.fadeHeader = nt.defaults.fadeHeader; 50 | nt.noTabs = nt.defaults.noTabs; 51 | nt.slowdownfactor = nt.defaults.slowdownfactor; 52 | nt.slidePixels = nt.defaults.slidePixels; 53 | // nt.onCompleted = nt.defaults.onCompleted; 54 | } 55 | 56 | //Extend the template with transition 57 | nt.transition = function(options) { 58 | 59 | //Init options 60 | if (!options) options = {}; 61 | 62 | //Notabs and noheader checks outside of cordova so that they are hidden on desktop also 63 | //Check if noTabs flag is set 64 | if (nt.noTabs || options.noTabs) { 65 | //Set the bottom pixels 66 | nt.fixedPixelsBottom = 0; 67 | //Be sure not to hide the tabs on the tab pages themselves (as they are always live) 68 | $('.nt-container').not('.nt-tab-container .nt-container').addClass('nt-no-tabs'); 69 | } 70 | 71 | //Check if noHeader flag is set 72 | if (nt.noHeader || options.noHeader) { 73 | nt.fixedPixelsTop = 0; 74 | $('.nt-container').not('.nt-tab-container .nt-container').addClass('nt-no-header'); 75 | } 76 | 77 | var isAndroid = /(android)/i.test(navigator.userAgent); 78 | if (isAndroid && nt.disableAndroid) return; 79 | 80 | //Cordova check is inside function so that it isn't undefined on desktop 81 | if (Meteor.isCordova) { 82 | 83 | //Needs to be defered to give time for the click handlers to override any vars 84 | Meteor.defer(function() { 85 | 86 | //Merge in any option overrites over the nt values 87 | var mergedOptions = _.extend(nt, options); 88 | 89 | //Set the options to use this time 90 | var theseOptions = { 91 | "direction" : mergedOptions.direction, // 'left|right|up|down', default 'left' (which is like 'next') 92 | "duration" : mergedOptions.duration, // in milliseconds (ms), default 400 93 | "iosdelay" : mergedOptions.iosdelay, // ms to wait for the iOS webview to update before animation kicks in, default 60 94 | "androiddelay" : mergedOptions.androiddelay, // same as above but for Android, default 70 95 | "slowdownfactor" : mergedOptions.slowdownfactor, // overlap views (higher number is more) or no overlap (1). -1 doesn't slide at all. Default 4 96 | "slidePixels" : mergedOptions.slidePixels, // optional, works nice with slowdownfactor -1 to create a 'material design'-like effect. Default not set so it slides the entire page 97 | //"winphonedelay" : 250, // same as above but for Windows Phone, default 200, 98 | "fixedPixelsTop" : mergedOptions.fixedPixelsTop, // the number of pixels of your fixed header, default 0 (iOS and Android) 99 | "fixedPixelsBottom": mergedOptions.fixedPixelsBottom // the number of pixels of your fixed footer (f.i. a tab bar), default 0 (iOS and Android) 100 | }; 101 | 102 | //Init the transition 103 | //Make sure everything is init (e.g. after a hot code push) 104 | if (typeof window.plugins.nativepagetransitions !== "undefined" && mergedOptions.type) { 105 | 106 | window.plugins.nativepagetransitions[mergedOptions.type]( 107 | theseOptions, 108 | //Completed function 109 | function () { 110 | //Check for completed callback 111 | if (options.onCompleted) options.onCompleted(); 112 | }, 113 | //Check for error 114 | function (error) { if (error) console.log('Native Transitions Error:' + error) }, 115 | ); 116 | 117 | } 118 | 119 | //Reset all to default 120 | nt.reset() 121 | 122 | }); 123 | 124 | } 125 | 126 | } 127 | 128 | 129 | if (Meteor.isCordova) { 130 | 131 | Meteor.startup(function() { 132 | 133 | //Set timeout is important here - this makes sure that the offsets aret't set on the initial transition after a hot code refresh. 134 | Meteor.setTimeout(function() { 135 | 136 | nt.reset(); 137 | 138 | document.addEventListener("backbutton", function() { 139 | //Set the direction to the default back direction 140 | nt.direction = nt.defaults.backDirection; 141 | //Navigate back 142 | window.history.back(); 143 | }, false); 144 | 145 | //Check for type, direction and duration changes on click 146 | $(document) 147 | .on('click', '[nt-type]', function(event) { 148 | nt.type = $(event.currentTarget).attr('nt-type'); 149 | }) 150 | .on('click', '[nt-direction]', function(event) { 151 | nt.direction = $(event.currentTarget).attr('nt-direction'); 152 | }) 153 | .on('click', '[nt-duration]', function(event) { 154 | nt.duration = $(event.currentTarget).attr('nt-duration'); 155 | }) 156 | .on('click', '[nt-iosdelay]', function(event) { 157 | nt.iosdelay = $(event.currentTarget).attr('nt-iosdelay'); 158 | }) 159 | .on('click', '[nt-androiddelay]', function(event) { 160 | nt.androiddelay = $(event.currentTarget).attr('nt-androiddelay'); 161 | }) 162 | .on('click', '[nt-fixedPixelsTop]', function(event) { 163 | nt.fixedPixelsTop = $(event.currentTarget).attr('nt-fixedPixelsTop'); 164 | }) 165 | .on('click', '[nt-fixedPixelsBottom]', function(event) { 166 | nt.fixedPixelsBottom = $(event.currentTarget).attr('nt-fixedPixelsBottom'); 167 | }) 168 | .on('click', '[nt-slowdownfactor]', function(event) { 169 | nt.slowdownfactor = $(event.currentTarget).attr('nt-slowdownfactor'); 170 | }); 171 | 172 | }, 500); 173 | 174 | }); 175 | 176 | } 177 | 178 | 179 | -------------------------------------------------------------------------------- /packages/native-transitions-stylus/core.import.styl: -------------------------------------------------------------------------------- 1 | //CONTAINER 2 | .nt-container 3 | position absolute 4 | top 0 5 | right 0 6 | bottom 0 7 | left 0 8 | background-color #FFF 9 | z-index 6 10 | overflow hidden 11 | 12 | &.nt-no-tabs 13 | z-index 8 14 | 15 | 16 | //LINKS 17 | a 18 | text-decoration none 19 | color inherit 20 | 21 | 22 | 23 | 24 | //TEXT 25 | h1, h2, h3, h4, h5, h6 26 | padding-bottom $verticalSpacing 27 | 28 | h1 29 | font-size 1.8em 30 | h2 31 | font-size 1.2em 32 | h3 33 | font-size 1.1em 34 | h4 35 | font-size 1em 36 | h5 37 | font-size 0.9em 38 | h6 39 | font-size 0.8em 40 | 41 | p 42 | padding-bottom $verticalSpacing 43 | 44 | a 45 | vertical-align top 46 | color $linkColor 47 | 48 | &.nt-small 49 | font-size $fontSize * $smallMultiplier 50 | 51 | &.nt-large 52 | font-size $fontSize * $largeMultiplier 53 | 54 | .nt-text-center 55 | text-align center !important 56 | 57 | .nt-text-left 58 | text-align left !important 59 | 60 | .nt-text-right 61 | text-align right !important 62 | 63 | a 64 | cursor pointer 65 | 66 | ul 67 | margin 0 68 | padding-left $padding + 5px 69 | padding-bottom $padding 70 | padding-top $padding 71 | 72 | 73 | //Utility 74 | .nt-no-flicker 75 | -webkit-backface-visibility hidden 76 | backface-visibility hidden 77 | -webkit-perspective 1000 78 | perspective 1000 79 | -webkit-transform-style preserve-3d 80 | 81 | .nt-background-white 82 | background-color #FFF !important 83 | 84 | .nt-background-primary 85 | background-color $colorPrimary !important 86 | 87 | .nt-background-secondary 88 | background-color $colorPrimary !important 89 | 90 | 91 | //Add the drop shadow 92 | 93 | // .nt-content 94 | // -webkit-box-shadow 0px 0px 10px 0px rgba(0,0,0,0.1) 95 | // box-shadow 0px 0px 10px 0px rgba(0,0,0,0.1) 96 | 97 | //Buttons 98 | .nt-button 99 | position relative 100 | display inline-block 101 | padding-top $buttonPaddingVertical - 1px 102 | padding-bottom $buttonPaddingVertical + 1px 103 | padding-left $buttonPaddingHorizontal 104 | padding-right $buttonPaddingHorizontal 105 | margin-top $verticalSpacing 106 | margin-bottom $verticalSpacing 107 | border-width $buttonBorderWidth 108 | border-color $buttonBorderColor 109 | border-style $buttonBorderStyle 110 | vertical-align middle 111 | cursor pointer 112 | border-radius($borderRadius) 113 | 114 | &.nt-large 115 | font-size $fontSize * $largeMultiplier 116 | padding-top $buttonPaddingVertical * $largeMultiplier - 1px 117 | padding-bottom $buttonPaddingVertical * $largeMultiplier + 1px 118 | 119 | &.nt-small 120 | font-size $fontSize * $smallMultiplier 121 | padding-top $buttonPaddingVertical * $smallMultiplier - 1px 122 | padding-bottom $buttonPaddingVertical * $smallMultiplier + 1px 123 | 124 | &.nt-block 125 | display block 126 | width 100% 127 | 128 | &.nt-solid 129 | background-color $buttonBackgroundColor 130 | color $buttonColor 131 | border none 132 | 133 | &:active 134 | border-color darken($buttonBorderColor, 30%) 135 | 136 | &.nt-solid:active 137 | background-color darken($buttonBackgroundColor, 30%) 138 | 139 | 140 | 141 | //PADDING 142 | .nt-padding 143 | padding $padding 144 | 145 | &.nt-small 146 | padding-top $padding * $smallMultiplier 147 | padding-bottom $padding * $smallMultiplier 148 | 149 | &.nt-large 150 | padding-top $padding * $largeMultiplier 151 | padding-bottom $padding * $largeMultiplier 152 | 153 | 154 | //BORDERS 155 | 156 | .nt-border 157 | border 1px solid $colorBorder 158 | 159 | .nt-border-top 160 | border-top 1px solid $colorBorder 161 | 162 | .nt-border-right 163 | border-right 1px solid $colorBorder 164 | 165 | .nt-border-bottom 166 | border-bottom 1px solid $colorBorder 167 | 168 | .nt-border-left 169 | border-left 1px solid $colorBorder 170 | 171 | 172 | //HEADER 173 | 174 | .nt-header-placeholder 175 | position absolute 176 | top 0 177 | width 100% 178 | height $headerHeight 179 | background-color $headerBackgroundColor 180 | color $headerColor 181 | z-index 7 182 | overflow hidden 183 | 184 | .nt-header 185 | position absolute 186 | top 0 187 | width 100% 188 | height $headerHeight 189 | background-color $headerBackgroundColor 190 | color $headerColor 191 | z-index 7 192 | overflow hidden 193 | 194 | h1 195 | display block 196 | width 75% 197 | margin 0 auto 198 | text-align center 199 | line-height $headerHeight - 2px 200 | font-size 1em 201 | white-space nowrap 202 | overflow hidden 203 | text-overflow ellipsis 204 | 205 | .nt-button 206 | position absolute 207 | left 0 208 | top 0 209 | width 15% 210 | height 100% 211 | line-height $headerHeight - 4px 212 | padding 0 213 | margin 0 214 | border none 215 | text-align center 216 | 217 | i 218 | vertical-align middle 219 | // position absolute 220 | // top 50% 221 | // -webkit-transform translateY(-50%) 222 | // transform translateY(-50%) 223 | // margin-top -2px 224 | 225 | &.nt-text 226 | font-size 0.7em 227 | width auto 228 | padding 0 10px 229 | margin-top 4px 230 | margin-right 10px 231 | height auto 232 | line-height $headerHeight - 9px 233 | 234 | &.nt-right 235 | right 0 236 | left auto 237 | 238 | &.nt-block 239 | top 0 240 | width 100% 241 | height 100% 242 | margin 0 243 | padding 0 $padding 244 | line-height $headerHeight - 2px 245 | border-radius(0) 246 | 247 | &:active 248 | background-color darken($headerBackgroundColor, 30%) 249 | 250 | 251 | 252 | 253 | 254 | //SUBHEADER 255 | .nt-subheader 256 | @extend .nt-header 257 | top $headerHeight 258 | height $subheaderHeight 259 | background-color $subheaderBackgroundColor 260 | color $headerColor 261 | padding-top 0 262 | z-index 2 263 | 264 | .nt-button 265 | &.nt-block 266 | line-height $subheaderHeight - 2px 267 | 268 | &.nt-icon-right i:last-child 269 | right 22px 270 | 271 | 272 | //FOOTER 273 | .nt-footer 274 | @extend .nt-header 275 | top auto 276 | bottom 0 277 | height $footerHeight 278 | background-color $footerBackgroundColor 279 | color $footerColor 280 | 281 | .nt-button 282 | &.nt-block 283 | line-height $footerHeight - 2px 284 | 285 | 286 | 287 | //SCROLLING CONTENT 288 | .nt-content 289 | overflow-x hidden 290 | overflow-y scroll 291 | -webkit-overflow-scrolling touch 292 | top 0 293 | right 0 294 | bottom 0 295 | left 0 296 | position absolute 297 | z-index 1 298 | background-color $ntScrollBackgroundColor 299 | 300 | .nt-element .nt-content 301 | overflow-x hidden 302 | overflow-y scroll 303 | -webkit-overflow-scrolling touch 304 | top 0 305 | right 0 306 | bottom 0 307 | left 0 308 | position relative 309 | z-index 1 310 | 311 | &.nt-padding 312 | padding-top $padding 313 | 314 | 315 | 316 | 317 | //Adjust nt-content for different elements 318 | .nt-content.nt-has-header 319 | top $headerHeight 320 | 321 | .nt-content.nt-has-subheader 322 | top $headerHeight + $subheaderHeight 323 | 324 | [nt-tabs] .nt-content, 325 | .nt-content.nt-has-tabs 326 | bottom $tabsHeight 327 | 328 | .nt-content.nt-has-footer 329 | bottom $footerHeight 330 | 331 | [nt-tabs] .nt-slideUp .nt-element 332 | bottom $tabsHeight 333 | 334 | 335 | 336 | //Fixes z-index problem with scrolling items underneath in fast-ui and fast-ui-swipe 337 | .nt-last .nt-content 338 | //overflow: hidden //Was causing a flicker so disabled. Doesn't seem to be a problem anymore. 339 | 340 | 341 | //HR 342 | hr 343 | border-top 1px solid $colorGreyLight 344 | padding 0 345 | margin $padding 0 346 | 347 | //DIVIDER 348 | .nt-divider 349 | background-color $dividerBackgroundColor 350 | color $dividerColor 351 | height $dividerHeight 352 | width 100% 353 | 354 | //ITEM HEADER 355 | .nt-item-header 356 | display block 357 | background-color $itemHeaderBackgroundColor 358 | color $itemHeaderColor 359 | font-size 0.9em 360 | padding-top $verticalSpacing * 2 361 | padding-bottom $verticalSpacing * 2 362 | padding-left $padding 363 | padding-right $padding 364 | text-align center 365 | line-height $lineHeight 366 | 367 | 368 | //ITEM 369 | .nt-item 370 | position relative 371 | display block 372 | border-bottom $colorGreyLight 1px solid 373 | padding $padding 374 | font-size 90% 375 | 376 | h2 377 | padding-bottom 3px 378 | text-overflow ellipsis 379 | white-space nowrap 380 | overflow hidden 381 | 382 | h3 383 | font-size 0.9em 384 | color $colorGreyMedium 385 | text-overflow ellipsis 386 | white-space nowrap 387 | overflow hidden 388 | 389 | p 390 | padding-bottom $verticalSpacing 391 | p:last-child 392 | padding-bottom 0 393 | 394 | &.nt-small 395 | padding-top: $padding * $smallMultiplier 396 | padding-bottom: $padding * $smallMultiplier 397 | 398 | .nt-stamp 399 | position absolute 400 | top $padding 401 | right $padding 402 | color $colorGreyMedium 403 | font-size 0.7em 404 | 405 | .nt-note 406 | position absolute 407 | top 11px 408 | right 11px 409 | display block 410 | font-size 10px 411 | text-align right 412 | font-weight 300 413 | color $colorGreyMedium 414 | 415 | // &:active 416 | // background-color $activeBackgroundColor 417 | 418 | 419 | //ICONS 420 | .nt-icon-right 421 | padding-right 50px 422 | 423 | i:last-child 424 | position absolute 425 | right 17px 426 | top 49.5% 427 | -webkit-transform translateY(-50%) 428 | transform translateY(-50%) 429 | width 15px 430 | text-align center 431 | 432 | &.nt-small 433 | padding-right 45px 434 | 435 | i:last-child 436 | right 16px 437 | 438 | &.nt-large 439 | padding-right 52px 440 | 441 | i:last-child 442 | right 22px 443 | 444 | 445 | .nt-icon-left 446 | padding-left 50px 447 | 448 | i:first-child 449 | position absolute 450 | left 17px 451 | top 49.5% 452 | -webkit-transform translateY(-50%) 453 | transform translateY(-50%) 454 | width 15px 455 | text-align center 456 | 457 | &.nt-small 458 | padding-left 45px 459 | 460 | i:first-child 461 | left 16px 462 | 463 | &.nt-large 464 | padding-left 52px 465 | 466 | i:first-child 467 | left 15px 468 | 469 | 470 | //AVATARS 471 | .nt-avatar 472 | border-radius(2px) 473 | width $avatarSize 474 | height $avatarSize 475 | display inline-block 476 | background-color $colorGreyLight 477 | 478 | .nt-avatar-right 479 | padding-right $avatarSize + $padding + 15px 480 | 481 | .nt-avatar:last-child 482 | position absolute 483 | right $padding 484 | top 50% 485 | -webkit-transform translateY(-50%) 486 | transform translateY(-50%) 487 | 488 | .nt-avatar-left 489 | padding-left $avatarSize + $padding + 15px 490 | 491 | .nt-avatar:first-child 492 | position absolute 493 | left $padding 494 | top 50% 495 | -webkit-transform translateY(-50%) 496 | transform translateY(-50%) 497 | 498 | h2 499 | padding-top 2px 500 | 501 | 502 | //RANKS 503 | .nt-rank 504 | border-radius(2px) 505 | width $rankSize 506 | height $rankSize 507 | display inline-block 508 | background-color $rankBackgroundColor 509 | color $rankColor 510 | font-size $rankFontSize 511 | text-align center 512 | padding-right 0.5px 513 | line-height $avatarSize - 3px 514 | 515 | &.nt-small 516 | width $rankSize * $smallMultiplier 517 | height $rankSize * $smallMultiplier 518 | line-height $avatarSize * $smallMultiplier - 1px 519 | font-size $rankFontSize * $smallMultiplier 520 | 521 | i 522 | position relative 523 | display block 524 | top 2px 525 | 526 | .nt-rank-right 527 | padding-right $rankSize + $padding + 15px 528 | 529 | .nt-rank:last-child 530 | position absolute 531 | right $padding 532 | top 50% 533 | -webkit-transform translateY(-50%) 534 | transform translateY(-50%) 535 | 536 | &.nt-small 537 | padding-right ($rankSize * $smallMultiplier) + $padding + 15px 538 | 539 | h2 540 | padding-top 2px 541 | 542 | .nt-rank-left 543 | padding-left $rankSize + $padding + 15px 544 | 545 | .nt-rank:first-child 546 | position absolute 547 | left $padding 548 | top 50% 549 | -webkit-transform translateY(-50%) 550 | transform translateY(-50%) 551 | 552 | &.nt-small 553 | padding-left ($rankSize * $smallMultiplier) + $padding + 15px 554 | 555 | h2 556 | padding-top 2px 557 | 558 | 559 | //ITEM LEFT 560 | // .nt-avatar-left 561 | // min-height $avatarSize 562 | // padding-left $avatarSize + 15px 563 | 564 | // > img 565 | // position absolute 566 | // top 0 567 | // left 0 568 | 569 | // &.nt-small 570 | // min-height $avatarSize * $smallMultiplier 571 | // padding-left $avatarSize * $smallMultiplier + 15px 572 | 573 | // > :first-child 574 | // width $avatarSize * $smallMultiplier 575 | // height $avatarSize * $smallMultiplier 576 | // font-size $rankFontSize * $smallMultiplier 577 | // line-height $avatarSize * $smallMultiplier 578 | // padding-right 0 579 | 580 | // h2 581 | // padding-bottom 0px 582 | // font-size 1em 583 | // margin-top -2px 584 | 585 | // h3 586 | // font-size 0.7em 587 | // color $colorGreyMedium 588 | 589 | 590 | 591 | //PILLS 592 | 593 | .nt-pill 594 | border-radius(20px) 595 | background-color $colorDarkPrimary 596 | color $colorTextLight 597 | width auto 598 | display inline-block 599 | padding 10px 15px 12px 15px 600 | font-size 0.8em 601 | 602 | 603 | //Tabs 604 | .nt-tabs 605 | display -webkit-flex 606 | display flex 607 | -webkit-justify-content space-around 608 | justify-content space-around 609 | align-items center 610 | -webkit-align-items center 611 | width 100% 612 | height $tabsHeight 613 | background-color $tabsBackgroundColor 614 | color $tabsColor 615 | border-top $tabsBorderColor $tabsBorderWidth $tabsBorderStyle 616 | overflow hidden 617 | 618 | a 619 | flex 1 620 | -webkit-flex 1 621 | flex-grow 1 622 | -webkit-flex-grow 1 623 | color $tabsColor 624 | height 100% 625 | display -webkit-flex 626 | display flex 627 | align-items center 628 | -webkit-align-items center 629 | justify-content center 630 | -webkit-justify-content center 631 | flex-direction column 632 | -webkit-flex-direction column 633 | font-size 0.7em 634 | line-height 0.5em 635 | text-align center 636 | 637 | a i 638 | display block 639 | font-size 2.7em 640 | text-align center 641 | line-height 1em 642 | margin-top -5px 643 | 644 | a.nt-active, a:active 645 | color $tabsActiveColor 646 | 647 | a:last-child 648 | border-right 0 649 | 650 | .nt-tabs-divider a 651 | border-right $tabsDividerWidth $tabsDividerStyle $tabsDividerColor 652 | 653 | 654 | .nt-tabs-fixed 655 | @extends .nt-tabs 656 | position absolute 657 | bottom 0 658 | left 0 659 | z-index 7 660 | 661 | .nt-tabs-indicators 662 | height $tabsHeight * 1.3 663 | 664 | a 665 | font-size 0.9em 666 | padding-top 8px 667 | color $colorGreyMedium 668 | 669 | i 670 | margin-top 0 671 | padding-top 5px 672 | font-size 2em 673 | visibility hidden 674 | 675 | 676 | //Highlight the current tab icon 677 | .nt-tab-1 [href='/?nt-tab=1'] 678 | .nt-tab-2 [href='/?nt-tab=2'] 679 | .nt-tab-3 [href='/?nt-tab=3'] 680 | .nt-tab-4 [href='/?nt-tab=4'] 681 | .nt-tab-5 [href='/?nt-tab=5'] 682 | color $tabsActiveColor 683 | 684 | 685 | //ELEMENTS 686 | .nt-slideDown .nt-element 687 | overflow-x hidden 688 | overflow-y scroll 689 | -webkit-overflow-scrolling touch 690 | 691 | 692 | .nt-modal .nt-element 693 | z-index 6 //Popups should be on top of headers 694 | // -webkit-box-shadow 0px 0px 20px 0px rgba(0,0,0,0.1) 695 | // box-shadow 0px 0px 20px 0px rgba(0,0,0,0.1) 696 | overflow hidden 697 | border-radius($borderRadius) 698 | 699 | 700 | .nt-modal.nt-element-in .nt-overlay 701 | z-index 6 //Popups should be on top of headers 702 | -webkit-animation nt-fade-modal-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both 703 | animation nt-fade-modal-in 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both 704 | background-color $overlayBackgroundColor 705 | 706 | @keyframes nt-fade-modal-in 707 | from 708 | opacity 0 709 | to 710 | opacity $overlayOpacity 711 | 712 | 713 | .nt-modal.nt-element-out .nt-overlay 714 | display block 715 | -webkit-animation nt-fade-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both 716 | animation nt-fade-out 0.35s 0s cubic-bezier(0.215, 0.610, 0.355, 1.000) both 717 | 718 | 719 | @keyframes nt-fade-out 720 | from 721 | opacity $overlayOpacity 722 | to 723 | opacity 0 724 | 725 | 726 | 727 | //PADDING - primarily used in elements to add the correct padding 728 | .nt-tabs-padding 729 | padding-bottom $tabsHeight 730 | 731 | .nt-header-padding 732 | padding-top $headerHeight 733 | 734 | .nt-subheader-padding 735 | padding-top $subheaderHeight 736 | 737 | .nt-header-padding.nt-subheader-padding 738 | padding-top $headerHeight + $subheaderHeight 739 | 740 | 741 | 742 | 743 | 744 | //COMMON 745 | .nt-button.nt-facebook 746 | @extend .nt-button.nt-solid 747 | background-color $colorFacebook 748 | 749 | &:active 750 | border-color darken($colorFacebook, 30%) 751 | 752 | &.nt-solid:active 753 | background-color darken($colorFacebook, 30%) 754 | 755 | 756 | 757 | //ACTIVE CLICKS 758 | // a:active 759 | // background-color $showClickBackgroundColor 760 | 761 | 762 | // //Tap feedback active 763 | // .tap-feedback-active 764 | // .tap-feedback:active 765 | // background-color $activeBackgroundColor !important 766 | 767 | 768 | --------------------------------------------------------------------------------