├── .bowerrc ├── .gitignore ├── .jsbeautifyrc ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── README.md ├── bower.json ├── example ├── app.js ├── example-controller.js ├── example.html ├── index.html └── user │ ├── accounts.html │ └── settings │ ├── settings-controller.js │ └── settings.html ├── karma.conf.js ├── package.json └── src ├── ui-router-tabs.js └── ui-router-tabs.spec.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory" : "bower_components" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | bower_components 3 | node_modules 4 | .idea 5 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "indent_size": 2, 3 | "indent_char": " ", 4 | "indent_level": 0, 5 | "indent_with_tabs": false, 6 | "preserve_newlines": true, 7 | "max_preserve_newlines": 2, 8 | "jslint_happy": false, 9 | "brace_style": "end-expand", 10 | "indent_scripts": "keep", 11 | "keep_array_indentation": true, 12 | "keep_function_indentation": false, 13 | "space_before_conditional": true, 14 | "break_chained_methods": false, 15 | "eval_code": false, 16 | "unescape_strings": false, 17 | "wrap_line_length": 0 18 | } 19 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globalstrict": true, 3 | "debug": false, 4 | "node": false, 5 | "devel": true, 6 | "boss": true, 7 | "curly": false, 8 | "eqeqeq": true, 9 | "eqnull": true, 10 | "expr": true, 11 | "immed": true, 12 | "loopfunc": true, 13 | "noarg": true, 14 | "onevar": false, 15 | "quotmark": "single", 16 | "smarttabs": true, 17 | "trailing": true, 18 | "undef": true, 19 | "unused": true, 20 | "globals": { 21 | "angular": false, 22 | "$": false, 23 | "jQuery": false, 24 | "Backbone": false, 25 | "_": false, 26 | "document": false, 27 | "module": false, 28 | "exports": false 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.1" 4 | before_script: 5 | - npm install -g bower 6 | - bower install 7 | script: "grunt" 8 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(grunt) { 4 | 5 | var beautifyFiles = ['!Gruntfile.js', '!npm-shrinkwrap.json', 'src/**/*.{html,js}', '!app/bower_components/**/*']; 6 | 7 | // Load grunt tasks automatically 8 | require('load-grunt-tasks')(grunt); 9 | 10 | // Define the configuration for all the tasks 11 | grunt.initConfig({ 12 | 13 | connect: { 14 | server: { 15 | options: { 16 | port: 9000 17 | } 18 | } 19 | }, 20 | 21 | watch: { 22 | scripts: { 23 | files: ['src/**/*'], 24 | tasks: ['jshint', 'karma'], 25 | options: { 26 | spawn: false 27 | } 28 | } 29 | 30 | }, 31 | 32 | // verifies we have formatted our js and HTML according to our style conventions 33 | jsbeautifier: { 34 | verify : { 35 | src: beautifyFiles, 36 | options: { 37 | config: '.jsbeautifyrc', 38 | mode: 'VERIFY_ONLY' 39 | } 40 | }, 41 | update: { 42 | src: beautifyFiles, 43 | options: { 44 | config: '.jsbeautifyrc' 45 | } 46 | } 47 | 48 | }, 49 | 50 | // Make sure code styles are up to par and there are no obvious mistakes 51 | jshint: { 52 | options: { 53 | jshintrc: '.jshintrc', 54 | reporter: require('jshint-stylish') 55 | }, 56 | src: ['src/!(*spec).js'] 57 | }, 58 | 59 | // Test settings 60 | karma: { 61 | unit: { 62 | options: { 63 | logLevel: 'DEBUG' 64 | }, 65 | browsers: ['PhantomJS'], 66 | configFile: 'karma.conf.js', 67 | singleRun: true, 68 | autoWatch: false 69 | } 70 | }, 71 | coveralls: { 72 | options: { 73 | coverage_dir:'coverage', 74 | directory:'coverage/lcov.info', 75 | debug: true, 76 | dryRun: false, 77 | recursive: false 78 | } 79 | } 80 | }); 81 | 82 | grunt.registerTask('serve', ['connect', 'watch']); 83 | grunt.registerTask('beautify', ['jsbeautifier:update']); 84 | grunt.registerTask('default', [ 85 | 'jsbeautifier:verify', 'jshint', 'karma', 'coveralls' 86 | ]); 87 | }; 88 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Robert Pocklington 2 | http://github.com/rpocklin/ui-router-tabs 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UI Router Tabs 2 | 3 | Leverages [UI Bootstrap](http://angular-ui.github.io/bootstrap/) and [UI Router](https://github.com/angular-ui/ui-router) to give you full-strength route-driven tabs in Angular.js. 4 | 5 | [![Build Status](https://secure.travis-ci.org/rpocklin/ui-router-tabs.svg)](http:/travis-ci.org/rpocklin/ui-router-tabs) 6 | [![Coverage Status](https://coveralls.io/repos/rpocklin/ui-router-tabs/badge.svg)](https://coveralls.io/r/rpocklin/ui-router-tabs) 7 |     8 | [![Gratipay](https://img.shields.io/gratipay/rpocklin.svg)](https://gratipay.com/rpocklin/) 9 | 10 | 11 | ## Example / Demo 12 | [Link](http://rpocklin.github.io/ui-router-tabs/example/index.html) 13 | 14 | ## How to Install / Usage 15 | 16 | 1. Install the plugin into your Angular.js project, manually or via `bower install angular-ui-router-tabs` 17 | 1. Add `ui.router.tabs` as a new module dependency in your angular app. 18 | 19 | 1. Define your routes in a hierarchy that makes sense for a tabbed layout, Eg: 20 | ```javascript 21 | $stateProvider.state('user', { 22 | url: '', 23 | controller: 'UserCtrl', 24 | templateUrl: 'example.html' 25 | }).state('user.settings', { 26 | url: '/user/settings', 27 | templateUrl: 'user/settings.html' 28 | }).state('user.accounts', { 29 | url: '/user/accounts', 30 | templateUrl: 'user/accounts.html' 31 | }); 32 | ``` 33 | 34 | 1. Define your `tabData` (or similiar variable) in the root view controller of your tabs (ie. `UserCtrl` in the case above) Eg: 35 | ```javascript 36 | $scope.tabData = [ 37 | { 38 | heading: 'Settings', 39 | route: 'user.settings' 40 | }, 41 | { 42 | heading: 'Accounts', 43 | route: 'user.accounts', 44 | disable: true 45 | } 46 | ]; 47 | ``` 48 | 49 | NOTE: You can also specify `params` and `options` to pass special parameters or options for the target route to UI Router, Eg: 50 | ```javascript 51 | { 52 | heading: 'Accounts', 53 | route: 'user.accounts', 54 | params: { 55 | accountId: account.id 56 | }, 57 | options: {} 58 | } 59 | ``` 60 | 61 | 1. Declare the following in your the parent HTML view template ``. 62 | 63 | Optional attributes for the `` (which are passed on to the UI Bootstrap component) are: 64 | 65 | * `type: [ 'tabs' | 'pills' ]` 66 | * `vertical: boolean` 67 | * `justified: boolean` 68 | * `class: string` 69 | * `templateUrl: