├── .gitignore ├── .npmignore ├── tests ├── fixtures │ ├── pinny.html │ ├── fullPinny.html │ └── sandbox.html ├── runner │ ├── index.html │ ├── test-main.js │ ├── test-config.js │ ├── sandbox-main.js │ └── sandbox-config.js ├── utils │ └── test-sandbox.js └── unit │ ├── constructor.js │ ├── sheets.js │ ├── events.js │ ├── options.js │ └── plugin.js ├── examples ├── assets │ ├── i │ │ └── pinny.gif │ ├── css │ │ └── examples.css │ └── js │ │ ├── config.js │ │ └── main.js ├── examples.css └── index.html ├── tasks ├── jslinting.js ├── config │ ├── watch.js │ ├── concurrent.js │ ├── mocha_phantomjs.js │ ├── sasslint.js │ ├── open.js │ ├── autoprefixer.js │ ├── copy.js │ ├── version.js │ ├── eslint.js │ ├── connect.js │ ├── uglify.js │ └── sass.js ├── version │ └── tasks.js └── eslint │ └── tasks.js ├── circle.yml ├── dist ├── pinny.min.css ├── effect │ ├── sheet-bottom.min.js │ ├── sheet-left.min.js │ ├── sheet-right.min.js │ ├── sheet-top.min.js │ ├── modal-center.min.js │ ├── sheet-bottom.js │ ├── sheet-top.js │ ├── sheet-left.js │ ├── sheet-right.js │ └── modal-center.js ├── pinny.css ├── pinny-theme.min.css ├── pinny-theme.css ├── utils │ └── event-polyfill.js ├── pinny.min.js └── pinny.js ├── PULL-REQUEST-TEMPLATE.md ├── RELEASE.md ├── LICENSE ├── package.json ├── src ├── js │ ├── effect │ │ ├── sheet-bottom.js │ │ ├── sheet-top.js │ │ ├── sheet-left.js │ │ ├── sheet-right.js │ │ └── modal-center.js │ ├── utils │ │ └── event-polyfill.js │ └── pinny.js └── style │ ├── pinny-theme.scss │ └── pinny.scss ├── gruntfile.js ├── CONTRIBUTING.md ├── CHANGELOG └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .DS_Store 3 | /.sass-cache/ 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | circle* 3 | tests 4 | examples 5 | -------------------------------------------------------------------------------- /tests/fixtures/pinny.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /examples/assets/i/pinny.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mobify/pinny/HEAD/examples/assets/i/pinny.gif -------------------------------------------------------------------------------- /tasks/jslinting.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | targets: [ 3 | 'src/js/**/*.js' 4 | ] 5 | }; 6 | -------------------------------------------------------------------------------- /tasks/config/watch.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | files: ["src/**/*"], 4 | tasks: ['build'] 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /tasks/config/concurrent.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(grunt) { 3 | return { 4 | tests: ['connect:test:keepalive', 'open:tests'] 5 | }; 6 | }; -------------------------------------------------------------------------------- /tasks/version/tasks.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | grunt.registerTask('version:all', ['version:dist', 'version:bower']); 3 | grunt.registerTask('version', ['version:all']); 4 | }; -------------------------------------------------------------------------------- /tests/fixtures/fullPinny.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | Pinny 4 | 5 |
6 |
7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /tasks/config/mocha_phantomjs.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | all: { 4 | options: { 5 | urls: ['http://localhost:' + (grunt.option('p') || 8888) + '/tests/runner/'] 6 | } 7 | } 8 | }; 9 | }; -------------------------------------------------------------------------------- /tasks/eslint/tasks.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function(grunt) { 3 | grunt.loadNpmTasks('grunt-eslint'); 4 | 5 | grunt.registerTask('lint:dev', ['eslint:dev']); 6 | grunt.registerTask('lint:prod', ['eslint:prod']); 7 | grunt.registerTask('lint', ['lint:dev']); 8 | }; 9 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 4.3.1 4 | 5 | dependencies: 6 | override: 7 | - npm install 8 | - npm install -g grunt-cli 9 | 10 | test: 11 | override: 12 | - grunt sasslint 13 | - grunt lint:prod 14 | - grunt test 15 | -------------------------------------------------------------------------------- /examples/assets/css/examples.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html { 6 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 7 | -webkit-text-size-adjust: 100%; 8 | } 9 | 10 | .pinny p { 11 | margin: 0; 12 | } 13 | 14 | p + p { 15 | margin-bottom: 10px; 16 | } -------------------------------------------------------------------------------- /tasks/config/sasslint.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | var targets = [ 3 | 'src/**/*.scss' 4 | ]; 5 | 6 | return { 7 | options: { 8 | configFile: require.resolve('mobify-code-style/css/.sass-lint.yml') 9 | }, 10 | target: targets 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /tasks/config/open.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | examples: { 4 | path: 'http://localhost:3000/examples', 5 | app: 'Google Chrome' 6 | }, 7 | tests: { 8 | path: 'http://localhost:8888/tests/runner', 9 | app: 'Google Chrome' 10 | } 11 | } 12 | }; -------------------------------------------------------------------------------- /tasks/config/autoprefixer.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | options: { 4 | browsers: ['last 4 versions', 'ie 8', 'ie 9', 'iOS >= 6.0', 'Android >= 2.3', 'last 4 ChromeAndroid versions'] 5 | }, 6 | multiple_files: { 7 | flatten: true, 8 | src: 'dist/*.css' 9 | } 10 | }; 11 | }; -------------------------------------------------------------------------------- /examples/examples.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | } 4 | 5 | html { 6 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 7 | -webkit-text-size-adjust: 100%; 8 | } 9 | 10 | body { 11 | margin: 10px; 12 | } 13 | 14 | .button-section { 15 | text-align: center; 16 | padding: 10px 0; 17 | } 18 | 19 | input { 20 | font-size: 16px; 21 | } 22 | -------------------------------------------------------------------------------- /tasks/config/copy.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | main: { 4 | files: [ 5 | { 6 | expand: true, 7 | cwd: 'src/js', 8 | src: ['**/*.js'], 9 | dest: 'dist/', 10 | filter: 'isFile' 11 | } 12 | ] 13 | } 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /tasks/config/version.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | dist: { 4 | options: { 5 | prefix: 'VERSION\\s*=\\s*[\\\'|"]' 6 | }, 7 | src: ['dist/pinny.js', 'dist/pinny.min.js'] 8 | }, 9 | bower: { 10 | options: { 11 | prefix: '"version":\\s*"' 12 | }, 13 | src: ['bower.json'] 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /tests/fixtures/sandbox.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pinny Tests 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/runner/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pinny Tests 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/runner/test-main.js: -------------------------------------------------------------------------------- 1 | require(['test-config'], function() { 2 | require([ 3 | 'require', 4 | 'chai', 5 | 'mocha' 6 | ], 7 | function(require, chai, mocha) { 8 | require(['glob!tests/unit/*.js'], function() { 9 | window.expect = chai.expect; 10 | 11 | if (window.mochaPhantomJS) { 12 | return window.mochaPhantomJS.run(); 13 | } 14 | mocha.run(); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /dist/pinny.min.css: -------------------------------------------------------------------------------- 1 | .pinny{position:fixed;display:none;background:white;outline:none;-webkit-tap-highlight-color:transparent}.pinny__wrapper{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow:hidden;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%}.pinny__header,.pinny__footer{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.pinny__content{overflow:auto;-webkit-box-flex:1;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-overflow-scrolling:touch}[hidden]{display:none !important} 2 | -------------------------------------------------------------------------------- /tasks/config/eslint.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | var lint = require('../jslinting'); 3 | 4 | return { 5 | prod: { 6 | src: lint.targets, 7 | options: { 8 | reset: true, 9 | config: require.resolve('mobify-code-style/javascript/.eslintrc-prod') 10 | } 11 | }, 12 | dev: { 13 | src: lint.targets, 14 | options: { 15 | reset: true, 16 | config: require.resolve('mobify-code-style/javascript/.eslintrc') 17 | } 18 | } 19 | }; 20 | }; 21 | -------------------------------------------------------------------------------- /tasks/config/connect.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | var addRequireJSGlob = function(connect, options, middlewares) { 3 | middlewares.unshift(require('requirejs-glob')()); 4 | return middlewares; 5 | }; 6 | 7 | return { 8 | server: { 9 | options: { 10 | hostname: '0.0.0.0', 11 | port: 3000, 12 | base: '.' 13 | } 14 | }, 15 | test: { 16 | options: { 17 | hostname: '0.0.0.0', 18 | port: 8888, 19 | base: '.', 20 | middleware: addRequireJSGlob 21 | } 22 | } 23 | }; 24 | }; -------------------------------------------------------------------------------- /dist/effect/sheet-bottom.min.js: -------------------------------------------------------------------------------- 1 | /*! pinny 3.0.1 (https://github.com/mobify/pinny.git) */ 2 | !function(a){if("function"==typeof define&&define.amd)define(["$","velocity"],a);else{var b=window.jQuery;a(b,b.Velocity)}}(function(a,b){return function(){var a=this,c=this._coverage();return this.$pinny.css({bottom:0,left:0,right:0,top:c?c:"auto",height:c?"auto":this.options.coverage,width:"auto"}),{open:function(){b.animate(a.$pinny,{translateY:[0,"100%"]},{easing:a.options.easing,duration:a.options.duration,display:"block",complete:a.animation.openComplete.bind(a)})},close:function(){b.animate(a.$pinny,"reverse",{easing:a.options.easing,duration:a.options.duration,display:"none",complete:a.animation.closeComplete.bind(a)})}}}}); -------------------------------------------------------------------------------- /dist/effect/sheet-left.min.js: -------------------------------------------------------------------------------- 1 | /*! pinny 3.0.1 (https://github.com/mobify/pinny.git) */ 2 | !function(a){if("function"==typeof define&&define.amd)define(["$","velocity"],a);else{var b=window.jQuery;a(b,b.Velocity)}}(function(a,b){return function(){var a=this,c=this._coverage();return this.$pinny.css({top:0,bottom:0,left:0,right:c?c:"auto",width:c?"auto":this.options.coverage,height:"auto"}),{open:function(){b.animate(a.$pinny,{translateX:[0,"-100%"]},{easing:a.options.easing,duration:a.options.duration,display:"block",complete:a.animation.openComplete.bind(a)})},close:function(){b.animate(a.$pinny,"reverse",{easing:a.options.easing,duration:a.options.duration,display:"none",complete:a.animation.closeComplete.bind(a)})}}}}); -------------------------------------------------------------------------------- /dist/effect/sheet-right.min.js: -------------------------------------------------------------------------------- 1 | /*! pinny 3.0.1 (https://github.com/mobify/pinny.git) */ 2 | !function(a){if("function"==typeof define&&define.amd)define(["$","velocity"],a);else{var b=window.jQuery;a(b,b.Velocity)}}(function(a,b){return function(){var a=this,c=this._coverage();return this.$pinny.css({top:0,bottom:0,right:0,left:c?c:"auto",width:c?"auto":this.options.coverage,height:"auto"}),{open:function(){b.animate(a.$pinny,{translateX:[0,"100%"]},{easing:a.options.easing,duration:a.options.duration,display:"block",complete:a.animation.openComplete.bind(a)})},close:function(){b.animate(a.$pinny,"reverse",{easing:a.options.easing,duration:a.options.duration,display:"none",complete:a.animation.closeComplete.bind(a)})}}}}); -------------------------------------------------------------------------------- /dist/effect/sheet-top.min.js: -------------------------------------------------------------------------------- 1 | /*! pinny 3.0.1 (https://github.com/mobify/pinny.git) */ 2 | !function(a){if("function"==typeof define&&define.amd)define(["$","velocity"],a);else{var b=window.jQuery;a(b,b.Velocity)}}(function(a,b){return function(){var a=this,c=this._coverage();return this.$pinny.css({top:0,left:0,right:0,bottom:c?c:"auto",height:c?"auto":this.options.coverage,width:"auto"}),{open:function(){b.animate(a.$pinny,{translateY:[0,"-100%"]},{easing:a.options.easing,duration:a.options.duration,display:"block",complete:a.animation.openComplete.bind(a)})},close:function(){b.animate(a.$pinny,"reverse",{easing:a.options.easing,duration:a.options.duration,display:"none",complete:a.animation.closeComplete.bind(a)})}}}}); -------------------------------------------------------------------------------- /tasks/config/uglify.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | return { 3 | options: { 4 | banner: '/*! <%= pkg.name %> <%= pkg.version %> (<%= pkg.repository.url%>) */\n' 5 | }, 6 | build: { 7 | files: { 8 | 'dist/pinny.min.js': 'src/js/pinny.js', 9 | 'dist/effect/modal-center.min.js': 'src/js/effect/modal-center.js', 10 | 'dist/effect/sheet-top.min.js': 'src/js/effect/sheet-top.js', 11 | 'dist/effect/sheet-bottom.min.js': 'src/js/effect/sheet-bottom.js', 12 | 'dist/effect/sheet-left.min.js': 'src/js/effect/sheet-left.js', 13 | 'dist/effect/sheet-right.min.js': 'src/js/effect/sheet-right.js' 14 | } 15 | } 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /tests/runner/test-config.js: -------------------------------------------------------------------------------- 1 | require.config({ 2 | baseUrl: '../../', 3 | paths: { 4 | 'text': 'node_modules/text/text', 5 | 'glob': 'node_modules/requirejs-glob/lib/glob', 6 | 'fixtures': 'tests/fixtures', 7 | '$': 'node_modules/jquery/dist/jquery.min', 8 | 'chai': 'node_modules/chai/chai', 9 | 'mocha': 'node_modules/mocha/mocha', 10 | 'test-sandbox': 'tests/utils/test-sandbox' 11 | }, 12 | 'shim': { 13 | 'mocha': { 14 | init: function() { 15 | this.mocha.setup('bdd'); 16 | return this.mocha; 17 | } 18 | }, 19 | '$': { 20 | exports: '$' 21 | } 22 | }, 23 | glob: { 24 | middlewarePathPrefix: '/' 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /PULL-REQUEST-TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # (brief description / PR title) 2 | 3 | Status: **Don't forget to label this PR as either: Open for visibility or Ready for review!** 4 | 5 | JIRA: **(link to JIRA ticket)** 6 | Linked PRs: **(links to corresponding PRs, optional)** 7 | 8 | ## Changes 9 | - (change1) 10 | 11 | ## How to test-drive this PR 12 | - (necessary config changes) 13 | - (necessary corresponding PRs) 14 | - (how to access the new / changed functionality -- fixtures, URLs) 15 | 16 | ## Research resources 17 | - (link1) 18 | 19 | ## TODOS: 20 | - [ ] Changes tested and working in supported browsers (see [README](https://github.com/mobify/pinny#browser-compatibility) for supported browsers) 21 | - [ ] Tests added 22 | - [ ] Tests passed 23 | - [ ] Build generated 24 | - [ ] README.md updated 25 | - [ ] CHANGELOG.md updated 26 | -------------------------------------------------------------------------------- /dist/effect/modal-center.min.js: -------------------------------------------------------------------------------- 1 | /*! pinny 3.0.1 (https://github.com/mobify/pinny.git) */ 2 | !function(a){if("function"==typeof define&&define.amd)define(["$","velocity"],a);else{var b=window.jQuery;a(b,b.Velocity)}}(function(a,b){return function(){var c=this,d=a(window),e=this._coverage(2);return this.$pinny.css({width:e?"auto":this.options.coverage,height:e?"auto":this.options.coverage}),{open:function(){var a={},f=function(b){return a[b]||(a[b]=d[b]()-c.$pinny[b]()/2),a[b]},g=f("height"),h=f("width");c.$pinny.css({top:e?e:g,bottom:e?e:g,right:e?e:h,left:e?e:h}),b.animate(c.$pinny,{scale:[1,2],opacity:[1,0]},{easing:c.options.easing,duration:c.options.duration,display:"block",complete:c.animation.openComplete.bind(c)})},close:function(){b.animate(c.$pinny,{scale:.5,opacity:0},{easing:c.options.easing,duration:c.options.duration,display:"none",complete:c.animation.closeComplete.bind(c)})}}}}); -------------------------------------------------------------------------------- /dist/pinny.css: -------------------------------------------------------------------------------- 1 | .pinny { 2 | position: fixed; 3 | display: none; 4 | background: white; 5 | outline: none; 6 | -webkit-tap-highlight-color: transparent; 7 | } 8 | 9 | .pinny__wrapper { 10 | display: -webkit-box; 11 | display: -webkit-flex; 12 | display: -ms-flexbox; 13 | display: flex; 14 | overflow: hidden; 15 | -webkit-box-orient: vertical; 16 | -webkit-box-direction: normal; 17 | -webkit-flex-direction: column; 18 | -ms-flex-direction: column; 19 | flex-direction: column; 20 | height: 100%; 21 | } 22 | 23 | .pinny__header, 24 | .pinny__footer { 25 | -webkit-flex-shrink: 0; 26 | -ms-flex-negative: 0; 27 | flex-shrink: 0; 28 | } 29 | 30 | .pinny__content { 31 | overflow: auto; 32 | -webkit-box-flex: 1; 33 | -webkit-flex: 1; 34 | -ms-flex: 1; 35 | flex: 1; 36 | -webkit-overflow-scrolling: touch; 37 | } 38 | 39 | [hidden] { 40 | display: none !important; 41 | } 42 | -------------------------------------------------------------------------------- /tests/utils/test-sandbox.js: -------------------------------------------------------------------------------- 1 | define([ 2 | '$' 3 | ], function($) { 4 | 5 | var $body = $(document.body); 6 | 7 | var setUp = function(fixture, setUpComplete) { 8 | var $frame = $('