From 07c824db8d465a256c642dcd91d988688f6551f1 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Thu, 20 Mar 2014 14:18:12 -0500 Subject: [PATCH] fix(item): Restructure item editing css for added reusability and organization --- js/ext/angular/src/directive/ionicList.js | 9 +- .../angular/test/directive/ionicList.unit.js | 22 ++-- js/ext/angular/test/list.html | 19 ++- scss/_items.scss | 122 ++++++++++++------ scss/_list.scss | 19 --- scss/_variables.scss | 14 ++ 6 files changed, 122 insertions(+), 83 deletions(-) diff --git a/js/ext/angular/src/directive/ionicList.js b/js/ext/angular/src/directive/ionicList.js index 566ceea7ed..9c83f1e908 100644 --- a/js/ext/angular/src/directive/ionicList.js +++ b/js/ext/angular/src/directive/ionicList.js @@ -63,11 +63,11 @@ angular.module('ionic.ui.list', ['ngAnimate']) }, template: '
\ -
\ +
\ \
\ \ -
\ +
\ \
\
\ @@ -114,12 +114,14 @@ angular.module('ionic.ui.list', ['ngAnimate']) // Set which icons to use for deleting $scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled'; + $element.addClass('item-left-editable'); } } // set the reorder Icon Class only if the item or list set can-reorder="true" if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") { $scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon'; + $element.addClass('item-right-editable'); } // Set the option buttons which can be revealed by swiping to the left @@ -129,6 +131,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) if(typeof $scope.itemOptionButtons === "undefined") { $scope.itemOptionButtons = $parentScope.optionButtons(); } + $element.addClass('item-swipeable'); } } @@ -202,7 +205,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) reorderIcon: '@' }, - template: '
', + template: '
', controller: ['$scope', '$attrs', function($scope, $attrs) { this.scope = $scope; diff --git a/js/ext/angular/test/directive/ionicList.unit.js b/js/ext/angular/test/directive/ionicList.unit.js index d7ea5e95c6..28aae0fcd7 100644 --- a/js/ext/angular/test/directive/ionicList.unit.js +++ b/js/ext/angular/test/directive/ionicList.unit.js @@ -25,8 +25,8 @@ describe('Ionic List', function() { it('Should init', function() { var element = compile('' + - '' + - '' + + '' + + '' + '')(scope); expect(element.children().length).toBe(2); @@ -37,18 +37,18 @@ describe('Ionic List', function() { expect(element.hasClass('my-animation')).toBe(true); }); - it('Should add list-editing class', function() { - expect(listElement.hasClass('list-editing')).toBe(false); + it('Should add list-left-editing class because of showDelete', function() { + expect(listElement.hasClass('list-left-editing')).toBe(false); scope.showDelete = true; scope.$digest(); - expect(listElement.hasClass('list-editing')).toBe(true); + expect(listElement.hasClass('list-left-editing')).toBe(true); }); - it('Should add list-reordering class', function() { - expect(listElement.hasClass('list-reordering')).toBe(false); + it('Should add list-right-editing class because of showReorder', function() { + expect(listElement.hasClass('list-right-editing')).toBe(false); scope.showReorder = true; scope.$digest(); - expect(listElement.hasClass('list-reordering')).toBe(true); + expect(listElement.hasClass('list-right-editing')).toBe(true); }); it('Should add item-options-hide class', function() { @@ -221,7 +221,8 @@ describe('Ionic Item Directive', function () { $rootScope.$digest(); itemScope = itemElement.isolateScope(); expect(itemScope.deleteClick).not.toBe(undefined); - expect(itemElement.find('.item-edit').length).toBe(1); + expect(itemElement.find('.item-left-edit').length).toBe(1); + expect(itemElement.find('.item-delete').length).toBe(1); expect(itemScope.deleteIconClass).toBe("test-icon"); })); @@ -277,7 +278,8 @@ describe('Ionic Item Directive', function () { $rootScope.$digest(); itemScope = itemElement.isolateScope(); expect(itemScope.deleteClick).not.toBe(undefined); - expect(itemElement.find('.item-edit').length).toBe(1); + expect(itemElement.find('.item-left-edit').length).toBe(1); + expect(itemElement.find('.item-delete').length).toBe(1); expect(itemScope.deleteIconClass).toBe("test-icon"); })); diff --git a/js/ext/angular/test/list.html b/js/ext/angular/test/list.html index 857a93d63e..606072cdf8 100644 --- a/js/ext/angular/test/list.html +++ b/js/ext/angular/test/list.html @@ -95,12 +95,6 @@ -
- Hello! - - Hello! -
- - +

{{item.from}}

{{item.text}}

@@ -198,9 +192,14 @@ // Build Mock Data $scope.items = [ - { from: 'Ben', face: 'https://pbs.twimg.com/profile_images/378800000571933189/278e8e1b7871a115b95fc550cd07af40.png', text: 'Did you prepare?' }, - { from: 'Adam', face: 'https://pbs.twimg.com/profile_images/2927292174/25b170ee2e3044fd936ad1319bc4b82d_bigger.jpeg', text: 'Don\'t forget to smile!' }, - { from: 'Tim', face: 'https://pbs.twimg.com/profile_images/378800000290028838/ee3303b02223f25cb0f9b082b55b2eeb.jpeg', text: 'Bring some shirts!', isActive: true } + { from: 'Ben', face: 'https://pbs.twimg.com/profile_images/378800000571933189/278e8e1b7871a115b95fc550cd07af40.png', text: 'Whoa, whoa, whoa. There’s still plenty of meat on that bone. Now you take this home, throw it in a pot, add some broth, a potato. Baby, you\'ve got a stew going.' }, + { from: 'Adam', face: 'https://pbs.twimg.com/profile_images/2927292174/25b170ee2e3044fd936ad1319bc4b82d_bigger.jpeg', text: 'It Ain\'t Easy Being Cheesy' }, + { from: 'Tim', face: 'https://pbs.twimg.com/profile_images/378800000290028838/ee3303b02223f25cb0f9b082b55b2eeb.jpeg', text: 'Baxter! You know I don\'t speak spanish!' }, + { from: 'Brody', face: 'https://pbs.twimg.com/profile_images/378800000138067018/554c103ebf37c2ba3b923b8deea46b0d.jpeg', text: 'Sounds like some sort of marmalade' }, + { from: 'Peter', face: 'https://pbs.twimg.com/profile_images/378800000238071493/08f76337bdc91b1e1e73a9d55c57a451.jpeg', text: 'A cooked goose for everyone!' }, + { from: 'Max', face: 'https://pbs.twimg.com/profile_images/430001754747305984/qa5DFLgU.jpeg', text: 'Yes my dear man, more beans. oooohh' }, + { from: 'Andy', face: 'https://pbs.twimg.com/profile_images/423294834229522433/BSlEOBYt.jpeg', text: 'I did it all for her' }, + { from: 'Melissa', face: 'https://pbs.twimg.com/profile_images/412451928816111616/VZ3_md1N.jpeg', text: 'I think I want my money back' } ]; diff --git a/scss/_items.scss b/scss/_items.scss index a467610615..2891b86203 100644 --- a/scss/_items.scss +++ b/scss/_items.scss @@ -5,7 +5,6 @@ .item { @include item-style($item-default-bg, $item-default-border, $item-default-text); - @include transition(margin-left 0.2s ease-in-out, margin-right 0.2s ease-in-out, left 0.2s ease-in-out); position: relative; z-index: $z-index-item; // Make sure the borders and stuff don't get hidden by children @@ -183,18 +182,10 @@ button.item.item-complex { } .item-complex .item-content, .item-radio .item-content { - /** - * The content area of a complex list item. This area can - * Slide left and right and be dragged to support different - * UI interactions. - */ - @include transition(all 0.1s ease-in-out); position: relative; z-index: $z-index-item; - padding: $item-padding (($item-padding * 3) - 5) $item-padding $item-padding; border: none; - background-color: white; } @@ -554,30 +545,60 @@ button.item-button-right:after, // Item Editing // ------------------------------- -.item-reordering { - position: absolute; - z-index: $z-index-item-reordering; - width: 100%; +.item-left-editable .item-content, +.item-right-editable .item-content { + // setup standard transition settings + @include transition-duration( $item-edit-transition-duration ); + @include transition-timing-function( $item-edit-transition-function ); + @include transition-property( none ); } -.item-placeholder { - opacity: 0.7; +.item-left-editable .item-content { + // set transition property for an item just left editable + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + transition-property: transform; +} + +.item-right-editable .item-content { + // set transition property for an item just right editable + @include transition-property(margin-right); +} + +.item-left-editable.item-right-editable .item-content { + // set transition property for an item that's both left/right editable + -webkit-transition-property: -webkit-transform, margin-right; + -moz-transition-property: -moz-transform, margin-right; + transition-property: transform, margin-right; +} + +.list-left-editing .item-left-editable .item-content, +.item-left-editing.item-left-editable .item-content { + // actively editing the left side of the item + @include translate3d($item-edit-left-open-width, 0, 0); +} + +.list-right-editing .item-right-editable .item-content, +.item-right-editing.item-right-editable .item-content { + // actively editing the right side of the item + margin-right: $item-edit-right-open-width; } -/** - * The left-side edit area of a complex list item. This area shows - * whe the list item is in edit mode. - */ -.item-edit { - @include transition(left 0.2s ease-in-out, opacity 0.2s ease-in-out); +// Item Left Edit Button +// ------------------------------- + +.item-left-edit { + @include transition(all $item-edit-transition-function $item-edit-transition-duration); + @include translate3d( $item-delete-icon-left - $item-edit-left-open-width, 0, 0); position: absolute; top: 0; - left: 8px; + left: 0; z-index: $z-index-item-edit; - width: 48px; + width: $item-edit-left-open-width; height: 100%; line-height: 100%; + opacity: 0; .button { height: 100%; @@ -589,31 +610,48 @@ button.item-button-right:after, top: 0; left: 0; height: 100%; - color: $assertive; - font-size: 24px; } } +} - &.ng-enter { - @include transition(left 0.2s ease-in-out, opacity 0.2s ease-in-out); - left: -48px; - opacity: 0; +.list-left-editing .item-left-edit { + @include translate3d($item-delete-icon-left, 0, 0); + opacity: 1; +} + + +// Item Delete +// ------------------------------- + +.item-delete .button.icon { + color: $item-delete-icon-color; + font-size: $item-delete-icon-size; + + &:hover { + opacity: .7; } - &.ng-enter-active { - left: 8px; - opacity: 1; - } - &.ng-leave { - @include transition(left 0.2s ease-in-out, opacity 0.2s ease-in-out); - left: 0px; - opacity: 1; - } - &.ng-leave-active { - left: -48px; - opacity: 0; +} + + +// Item Reordering +// ------------------------------- + +.list-reordering { + .item-drag { + z-index: 1; } } +.item-reordering { + position: absolute; + z-index: $z-index-item-reordering; + width: 100%; +} + +.item-placeholder { + opacity: 0.7; +} + .item-drag { position: absolute; top: 0; @@ -637,6 +675,8 @@ button.item-button-right:after, } } } + + /** * The hidden right-side buttons that can be exposed under a list item * with dragging. diff --git a/scss/_list.scss b/scss/_list.scss index 08e22952a0..4ff719eb01 100644 --- a/scss/_list.scss +++ b/scss/_list.scss @@ -11,29 +11,10 @@ padding-left: 0; // reset padding because ul and ol margin-bottom: 20px; } -/* If a list is the last item in a container, don't add margin-bottom */ .list:last-child { margin-bottom: 0px; } -/** - * List editing styles. These trigger when the entire list goes into - * "edit mode" or reordering list items - */ -.list-editing { - .item-content { - @include translate3d(50px, 0, 0); - } -} -.list-reordering { - .item-content { - margin-right: 50px; - } - .item-drag { - z-index: 1; - } -} - /** * List Header diff --git a/scss/_variables.scss b/scss/_variables.scss index bab9d661d6..16363d55ab 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -361,6 +361,20 @@ $item-default-active-bg: #D9D9D9 !default; $item-default-active-border: $item-light-active-border !default; +// Item Editing +// ------------------------------- + +$item-edit-transition-duration: 250ms !default; +$item-edit-transition-function: ease-in-out !default; + +$item-edit-right-open-width: 50px !default; +$item-edit-left-open-width: 50px !default; + +$item-delete-icon-left: 8px !default; +$item-delete-icon-size: 24px !default; +$item-delete-icon-color: $assertive !default; + + // Lists // -------------------------------