From 3f89bca290d8196dcc27664ea9ca91def0a14436 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Tue, 12 Nov 2013 23:25:57 -0600 Subject: [PATCH] Lots of action sheet work --- dist/css/ionic.css | 58 ++++++++++++- dist/js/ionic-angular.js | 81 ++++++++++++------- .../angular/src/directive/ionicActionSheet.js | 31 ++++--- .../angular/src/service/ionicActionSheet.js | 50 +++++++----- js/ext/angular/test/actionSheet.html | 47 +++++++++++ scss/_action-sheet.scss | 53 +++++++++++- scss/_variables.scss | 6 +- 7 files changed, 261 insertions(+), 65 deletions(-) create mode 100644 js/ext/angular/test/actionSheet.html diff --git a/dist/css/ionic.css b/dist/css/ionic.css index fad7a9564a..5f3935fa9d 100644 --- a/dist/css/ionic.css +++ b/dist/css/ionic.css @@ -2484,6 +2484,50 @@ a.subdued‎ { * Action Sheets * -------------------------------------------------- */ +@-webkit-keyframes fadeInHalf { + from { + background-color: rgba(0, 0, 0, 0); } + + to { + background-color: rgba(0, 0, 0, 0.5); } } + +@keyframes fadeInHalf { + from { + background-color: rgba(0, 0, 0, 0); } + + to { + background-color: rgba(0, 0, 0, 0.5); } } + +@-webkit-keyframes fadeOutHalf { + from { + background-color: rgba(0, 0, 0, 0.5); } + + to { + background-color: rgba(0, 0, 0, 0); } } + +@keyframes fadeOutHalf { + from { + background-color: rgba(0, 0, 0, 0.5); } + + to { + background-color: rgba(0, 0, 0, 0); } } + +.action-sheet-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0); } + .action-sheet-backdrop.active { + -webkit-animation: fadeInHalf 0.2s; + animation: fadeInHalf 0.2s; + -webkit-animation-fill-mode: forwards; } + .action-sheet-backdrop.active-remove { + -webkit-animation: fadeOutHalf 0.2s; + animation: fadeOutHalf 0.2s; + -webkit-animation-fill-mode: forwards; } + .action-sheet { -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); @@ -2495,7 +2539,7 @@ a.subdued‎ { width: calc(100% - 30px); } .action-sheet .button { display: block; - padding: 10px; + padding: 6px; width: 100%; border-radius: none; background-color: transparent; @@ -2507,12 +2551,18 @@ a.subdued‎ { .action-sheet-title { padding: 10px; text-align: center; - font-size: 12px; } + font-size: 12px; + color: #666666; } .action-sheet-group { + background-color: #fff; margin-bottom: 10px; - border-radius: 3px; - background-color: rgba(255, 255, 255, 0.95); } + border-radius: 3px 3px 3px 3px; } + .action-sheet-group .button { + border-radius: 0; + border-width: 1px 0px 0px 0px; } + .action-sheet-group .button:first-child:last-child { + border-width: 0; } /** * Bar (Headers and Footers) diff --git a/dist/js/ionic-angular.js b/dist/js/ionic-angular.js index 0d30899581..4c3d0c6c9f 100644 --- a/dist/js/ionic-angular.js +++ b/dist/js/ionic-angular.js @@ -29,9 +29,11 @@ angular.module('ionic', [ 'ionic.ui', ]); ; -angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.ui.actionSheet']) +angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.ui.actionSheet', 'ngAnimate']) + +.factory('ActionSheet', ['$rootScope', '$document', '$compile', '$animate', 'TemplateLoader', + function($rootScope, $document, $compile, $animate, TemplateLoader) { -.factory('ActionSheet', ['$rootScope', '$document', '$compile', 'TemplateLoader', function($rootScope, $document, $compile, TemplateLoader) { return { /** * Load an action sheet with the given template string. @@ -41,23 +43,38 @@ angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ioni * * @param {object} opts the options for this ActionSheet (see docs) */ - show: function(opts, $scope) { - var scope = $scope && $scope.$new() || $rootScope.$new(true); + show: function(opts) { + var scope = $rootScope.$new(true); angular.extend(scope, opts); + + // Compile the template + var element = $compile('')(scope); + + // Grab the sheet element for animation + var sheetEl = angular.element(element[0].querySelector('.action-sheet')); + + var hideSheet = function(didCancel) { + $animate.leave(sheetEl, function() { + if(didCancel) { + opts.cancel(); + } + }); + $animate.removeClass(element, 'active', function() { + scope.$destroy(); + }); + }; + scope.cancel = function() { - scope.sheet.hide(); - //scope.$destroy(); - opts.cancel(); + hideSheet(true); }; scope.buttonClicked = function(index) { // Check if the button click event returned true, which means // we can close the action sheet if((opts.buttonClicked && opts.buttonClicked(index)) === true) { - scope.sheet.hide(); - //scope.$destroy(); + hideSheet(false); } }; @@ -65,26 +82,23 @@ angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ioni // Check if the destructive button click event returned true, which means // we can close the action sheet if((opts.destructiveButtonClicked && opts.destructiveButtonClicked()) === true) { - scope.sheet.hide(); - //scope.$destroy(); + hideSheet(false); } }; - // Compile the template - var element = $compile('')(scope); - - var s = element.scope(); - $document[0].body.appendChild(element[0]); var sheet = new ionic.views.ActionSheet({el: element[0] }); - s.sheet = sheet; + scope.sheet = sheet; - sheet.show(); + $animate.addClass(element, 'active'); + $animate.enter(sheetEl, element, function() { + }); return sheet; } }; + }]); ; angular.module('ionic.service.gesture', []) @@ -399,7 +413,7 @@ angular.module('ionic.service.templateLoad', []) angular.module('ionic.ui.actionSheet', []) -.directive('actionSheet', function() { +.directive('actionSheet', function($document) { return { restrict: 'E', scope: true, @@ -408,17 +422,26 @@ angular.module('ionic.ui.actionSheet', []) $scope.$on('$destroy', function() { $element.remove(); }); + + $document.bind('keyup', function(e) { + if(e.which == 27) { + $scope.cancel(); + $scope.$apply(); + } + }); }, - template: '
' + - '
' + - '
{{titleText}}
' + - '' + - '
' + - '
' + - '' + - '
' + - '
' + - '' + + template: '
' + + '
' + + '
' + + '
{{titleText}}
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + '
' + '
' }; diff --git a/js/ext/angular/src/directive/ionicActionSheet.js b/js/ext/angular/src/directive/ionicActionSheet.js index 756a05dfcb..fff929c4f9 100644 --- a/js/ext/angular/src/directive/ionicActionSheet.js +++ b/js/ext/angular/src/directive/ionicActionSheet.js @@ -3,7 +3,7 @@ angular.module('ionic.ui.actionSheet', []) -.directive('actionSheet', function() { +.directive('actionSheet', function($document) { return { restrict: 'E', scope: true, @@ -12,17 +12,26 @@ angular.module('ionic.ui.actionSheet', []) $scope.$on('$destroy', function() { $element.remove(); }); + + $document.bind('keyup', function(e) { + if(e.which == 27) { + $scope.cancel(); + $scope.$apply(); + } + }); }, - template: '
' + - '
' + - '
{{titleText}}
' + - '' + - '
' + - '
' + - '' + - '
' + - '
' + - '' + + template: '
' + + '
' + + '
' + + '
{{titleText}}
' + + '' + + '
' + + '
' + + '' + + '
' + + '
' + + '' + + '
' + '
' + '
' }; diff --git a/js/ext/angular/src/service/ionicActionSheet.js b/js/ext/angular/src/service/ionicActionSheet.js index 1c9db95766..73ba6542df 100644 --- a/js/ext/angular/src/service/ionicActionSheet.js +++ b/js/ext/angular/src/service/ionicActionSheet.js @@ -1,6 +1,8 @@ -angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.ui.actionSheet']) +angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.ui.actionSheet', 'ngAnimate']) + +.factory('ActionSheet', ['$rootScope', '$document', '$compile', '$animate', 'TemplateLoader', + function($rootScope, $document, $compile, $animate, TemplateLoader) { -.factory('ActionSheet', ['$rootScope', '$document', '$compile', 'TemplateLoader', function($rootScope, $document, $compile, TemplateLoader) { return { /** * Load an action sheet with the given template string. @@ -10,23 +12,38 @@ angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ioni * * @param {object} opts the options for this ActionSheet (see docs) */ - show: function(opts, $scope) { - var scope = $scope && $scope.$new() || $rootScope.$new(true); + show: function(opts) { + var scope = $rootScope.$new(true); angular.extend(scope, opts); + + // Compile the template + var element = $compile('')(scope); + + // Grab the sheet element for animation + var sheetEl = angular.element(element[0].querySelector('.action-sheet')); + + var hideSheet = function(didCancel) { + $animate.leave(sheetEl, function() { + if(didCancel) { + opts.cancel(); + } + }); + $animate.removeClass(element, 'active', function() { + scope.$destroy(); + }); + }; + scope.cancel = function() { - scope.sheet.hide(); - //scope.$destroy(); - opts.cancel(); + hideSheet(true); }; scope.buttonClicked = function(index) { // Check if the button click event returned true, which means // we can close the action sheet if((opts.buttonClicked && opts.buttonClicked(index)) === true) { - scope.sheet.hide(); - //scope.$destroy(); + hideSheet(false); } }; @@ -34,24 +51,21 @@ angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ioni // Check if the destructive button click event returned true, which means // we can close the action sheet if((opts.destructiveButtonClicked && opts.destructiveButtonClicked()) === true) { - scope.sheet.hide(); - //scope.$destroy(); + hideSheet(false); } }; - // Compile the template - var element = $compile('')(scope); - - var s = element.scope(); - $document[0].body.appendChild(element[0]); var sheet = new ionic.views.ActionSheet({el: element[0] }); - s.sheet = sheet; + scope.sheet = sheet; - sheet.show(); + $animate.addClass(element, 'active'); + $animate.enter(sheetEl, element, function() { + }); return sheet; } }; + }]); diff --git a/js/ext/angular/test/actionSheet.html b/js/ext/angular/test/actionSheet.html new file mode 100644 index 0000000000..b72f9edbc1 --- /dev/null +++ b/js/ext/angular/test/actionSheet.html @@ -0,0 +1,47 @@ + + + + Action Sheet + + + + + + + + + + + + + + + diff --git a/scss/_action-sheet.scss b/scss/_action-sheet.scss index e388a226b8..63ceab3a4c 100644 --- a/scss/_action-sheet.scss +++ b/scss/_action-sheet.scss @@ -4,6 +4,46 @@ * -------------------------------------------------- */ +@-webkit-keyframes fadeInHalf { + from { background-color: rgba(0,0,0,0); } + to { background-color: rgba(0,0,0,0.5); } +} +@keyframes fadeInHalf { + from { background-color: rgba(0,0,0,0); } + to { background-color: rgba(0,0,0,0.5); } +} +@-webkit-keyframes fadeOutHalf { + from { background-color: rgba(0,0,0,0.5); } + to { background-color: rgba(0,0,0,0); } +} +@keyframes fadeOutHalf { + from { background-color: rgba(0,0,0,0.5); } + to { background-color: rgba(0,0,0,0); } +} + +.action-sheet-backdrop { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0,0,0,0); + + &.active { + -webkit-animation: fadeInHalf 0.2s; + animation: fadeInHalf 0.2s; + + -webkit-animation-fill-mode: forwards; + } + + &.active-remove { + -webkit-animation: fadeOutHalf 0.2s; + animation: fadeOutHalf 0.2s; + + -webkit-animation-fill-mode: forwards; + } +} + .action-sheet { @include translate3d(0, 100%, 0); @@ -16,9 +56,10 @@ .button { display: block; - padding: 10px; + padding: 6px; width: 100%; border-radius: none; + background-color: transparent; color: $primary; @@ -34,10 +75,18 @@ padding: 10px; text-align: center; font-size: 12px; + color: lighten($base-color, 40%); } .action-sheet-group { + background-color: #fff; margin-bottom: 10px; border-radius: $sheet-border-radius; - background-color: rgba($sheet-bg-color, $sheet-opacity); + .button { + border-radius: 0; + border-width: 1px 0px 0px 0px; + } + .button:first-child:last-child { + border-width: 0; + } } diff --git a/scss/_variables.scss b/scss/_variables.scss index 9bdf1a6129..ed58740972 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -487,7 +487,11 @@ $grid-padding-width: 10px !default; $sheet-bg-color: rgba(255, 255, 255, 0.6) !default; $sheet-opacity: 0.95 !default; -$sheet-border-radius: 3px !default; + +// Border radii for the action sheet button groups +$sheet-border-radius: 3px 3px 3px 3px !default; +$sheet-border-radius-top: 3px 3px 0px 0px !default; +$sheet-border-radius-bottom: 0px 0px 3px 3px !default; // Badges