mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(list): make reorder/delete button animation work well on all devices
This commit is contained in:
4
js/angular/directive/itemDeleteButton.js
vendored
4
js/angular/directive/itemDeleteButton.js
vendored
@@ -1,5 +1,5 @@
|
||||
var ITEM_TPL_DELETE_BUTTON =
|
||||
'<div class="item-left-edit item-delete ng-hide enable-pointer-events">' +
|
||||
'<div class="item-left-edit item-delete enable-pointer-events">' +
|
||||
'</div>';
|
||||
/**
|
||||
* @ngdoc directive
|
||||
@@ -49,7 +49,7 @@ IonicModule
|
||||
itemCtrl.$element.append(container).addClass('item-left-editable');
|
||||
|
||||
if (listCtrl && listCtrl.showDelete()) {
|
||||
$animate.removeClass(container, 'ng-hide');
|
||||
container.addClass('visible active');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
4
js/angular/directive/itemReorderButton.js
vendored
4
js/angular/directive/itemReorderButton.js
vendored
@@ -1,5 +1,5 @@
|
||||
var ITEM_TPL_REORDER_BUTTON =
|
||||
'<div data-prevent-scroll="true" class="item-right-edit item-reorder ng-hide enable-pointer-events">' +
|
||||
'<div data-prevent-scroll="true" class="item-right-edit item-reorder enable-pointer-events">' +
|
||||
'</div>';
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ IonicModule
|
||||
itemCtrl.$element.append(container).addClass('item-right-editable');
|
||||
|
||||
if (listCtrl && listCtrl.showReorder()) {
|
||||
$animate.removeClass(container, 'ng-hide');
|
||||
container.addClass('visible active');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
26
js/angular/directive/list.js
vendored
26
js/angular/directive/list.js
vendored
@@ -140,13 +140,13 @@ function($animate, $timeout) {
|
||||
if (isShown) listCtrl.closeOptionButtons();
|
||||
listCtrl.canSwipeItems(!isShown);
|
||||
|
||||
var deleteButton = jqLite($element[0].getElementsByClassName('item-delete'));
|
||||
|
||||
$element.children().toggleClass('list-left-editing', isShown);
|
||||
toggleNgHide(deleteButton, isShown);
|
||||
$element.toggleClass('disable-pointer-events left-editing', isShown);
|
||||
|
||||
$element.toggleClass('disable-pointer-events', isShown);
|
||||
var deleteButton = jqLite($element[0].getElementsByClassName('item-delete'));
|
||||
setButtonShown(deleteButton, listCtrl.showDelete);
|
||||
});
|
||||
|
||||
$scope.$watch(function() {
|
||||
return listCtrl.showReorder();
|
||||
}, function(isShown, wasShown) {
|
||||
@@ -156,21 +156,17 @@ function($animate, $timeout) {
|
||||
if (isShown) listCtrl.closeOptionButtons();
|
||||
listCtrl.canSwipeItems(!isShown);
|
||||
|
||||
var reorderButton = jqLite($element[0].getElementsByClassName('item-reorder'));
|
||||
|
||||
$element.children().toggleClass('list-right-editing', isShown);
|
||||
toggleNgHide(reorderButton, isShown);
|
||||
$element.toggleClass('disable-pointer-events right-editing', isShown);
|
||||
|
||||
$element.toggleClass('disable-pointer-events', isShown);
|
||||
var reorderButton = jqLite($element[0].getElementsByClassName('item-reorder'));
|
||||
setButtonShown(reorderButton, listCtrl.showReorder);
|
||||
});
|
||||
|
||||
function toggleNgHide(element, shouldShow) {
|
||||
forEach(element, function(node) {
|
||||
if (shouldShow) {
|
||||
$animate.removeClass(jqLite(node), 'ng-hide');
|
||||
} else {
|
||||
$animate.addClass(jqLite(node), 'ng-hide');
|
||||
}
|
||||
function setButtonShown(el, shown) {
|
||||
shown() && el.addClass('visible') || el.removeClass('active');
|
||||
ionic.requestAnimationFrame(function() {
|
||||
shown() && el.addClass('active') || el.removeClass('invisible');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@
|
||||
|
||||
if(!lastDrag) return;
|
||||
|
||||
lastDrag.content.style[ionic.CSS.TRANSITION] = '';
|
||||
lastDrag.content.style[ionic.CSS.TRANSFORM] = '';
|
||||
ionic.requestAnimationFrame(function() {
|
||||
lastDrag.content.style[ionic.CSS.TRANSITION] = '';
|
||||
lastDrag.content.style[ionic.CSS.TRANSFORM] = '';
|
||||
setTimeout(function() {
|
||||
lastDrag.buttons && lastDrag.buttons.classList.add('invisible');
|
||||
}, 250);
|
||||
|
||||
@@ -595,28 +595,11 @@ button.item.item-button-right {
|
||||
// setup standard transition settings
|
||||
@include transition-duration( $item-edit-transition-duration );
|
||||
@include transition-timing-function( $item-edit-transition-function );
|
||||
@include transition-property( none );
|
||||
}
|
||||
|
||||
.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
|
||||
@@ -625,8 +608,8 @@ button.item.item-button-right {
|
||||
|
||||
.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-right-edit-open-width;
|
||||
// actively editing the left side of the item
|
||||
@include translate3d(-$item-right-edit-open-width, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -634,8 +617,7 @@ button.item.item-button-right {
|
||||
// -------------------------------
|
||||
|
||||
.item-left-edit {
|
||||
@include transition(all $item-edit-transition-function $item-edit-transition-duration);
|
||||
@include translate3d( $item-left-edit-left - $item-left-edit-open-width, 0, 0);
|
||||
@include transition(all $item-edit-transition-function $item-edit-transition-duration / 2);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -655,13 +637,21 @@ button.item.item-button-right {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-left-editing .item-left-edit,
|
||||
.item-left-editing .item-left-edit {
|
||||
@include translate3d($item-left-edit-left, 0, 0);
|
||||
display: none;
|
||||
opacity: 0;
|
||||
@include translate3d( ($item-left-edit-left - $item-left-edit-open-width) / 2, 0, 0);
|
||||
&.visible {
|
||||
display: block;
|
||||
&.active {
|
||||
opacity: 1;
|
||||
@include translate3d($item-left-edit-left, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-left-editing .item-left-edit {
|
||||
@include transition-delay($item-edit-transition-duration / 2);
|
||||
}
|
||||
|
||||
|
||||
// Item Delete (Left side edit button)
|
||||
// -------------------------------
|
||||
@@ -680,12 +670,12 @@ button.item.item-button-right {
|
||||
// -------------------------------
|
||||
|
||||
.item-right-edit {
|
||||
@include transition(all $item-edit-transition-function $item-edit-transition-duration);
|
||||
@include transition(all $item-edit-transition-function $item-edit-transition-duration / 2);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 0;
|
||||
width: $item-right-edit-open-width;
|
||||
width: $item-right-edit-open-width * 1.5;
|
||||
height: 100%;
|
||||
background: inherit;
|
||||
|
||||
@@ -702,6 +692,20 @@ button.item.item-button-right {
|
||||
font-size: $item-reorder-icon-size;
|
||||
}
|
||||
}
|
||||
|
||||
display: none;
|
||||
opacity: 0;
|
||||
@include translate3d($item-right-edit-open-width / 2, 0, 0);
|
||||
&.visible {
|
||||
display: block;
|
||||
&.active {
|
||||
opacity: 1;
|
||||
@include translate3d(0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
.list-right-editing .item-right-edit {
|
||||
@include transition-delay($item-edit-transition-duration / 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -732,18 +736,6 @@ button.item.item-button-right {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.item-left-edit.item-delete,
|
||||
.item-right-edit.item-reorder {
|
||||
opacity: 1;
|
||||
&.ng-hide {
|
||||
opacity: 0;
|
||||
}
|
||||
&.ng-hide-add,
|
||||
&.ng-hide-remove {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The hidden right-side buttons that can be exposed under a list item
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>Ionic List Directive</title>
|
||||
|
||||
<link href="../../dist/css/ionic.css" rel="stylesheet">
|
||||
<script src="../../dist/js/ionic.bundle.js"></script>
|
||||
<link href="../../dist/css/ionic.min.css" rel="stylesheet">
|
||||
<script src="../../dist/js/ionic.bundle.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body ng-controller="MyCtrl">
|
||||
@@ -117,7 +117,7 @@ angular.module('ionicApp', ['ionic'])
|
||||
};
|
||||
|
||||
$scope.items = [];
|
||||
for (var i=0; i<100; i++) {
|
||||
for (var i=0; i<15; i++) {
|
||||
$scope.items.push({id:i});
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ describe('ionDeleteButton directive', function() {
|
||||
$compile(el)($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
|
||||
var deleteContainer = angular.element(el[0].querySelector('.item-left-edit.item-delete.ng-hide'));
|
||||
var deleteContainer = angular.element(el[0].querySelector('.item-left-edit.item-delete'));
|
||||
expect(deleteContainer.length).toBe(1);
|
||||
expect(deleteContainer.children().hasClass('button icon button-icon')).toBe(true);
|
||||
}));
|
||||
@@ -79,7 +79,8 @@ describe('ionDeleteButton directive', function() {
|
||||
|
||||
var deleteContainer = angular.element(el[0].querySelector('.item-left-edit.item-delete'));
|
||||
expect(deleteContainer.length).toBe(1);
|
||||
expect(deleteContainer.hasClass('ng-hide')).toBe(false);
|
||||
expect(deleteContainer.hasClass('visible')).toBe(true);
|
||||
expect(deleteContainer.hasClass('active')).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
@@ -94,13 +95,13 @@ describe('ionReorderButton directive', function() {
|
||||
$compile(el)($rootScope.$new());
|
||||
$rootScope.$apply();
|
||||
|
||||
var reorderContainer = angular.element(el[0].querySelector('.item-right-edit.item-reorder.ng-hide'));
|
||||
var reorderContainer = angular.element(el[0].querySelector('.item-right-edit.item-reorder'));
|
||||
expect(reorderContainer.length).toBe(1);
|
||||
expect(reorderContainer.children().hasClass('button icon button-icon')).toBe(true);
|
||||
expect(reorderContainer.attr('data-prevent-scroll')).toBe('true');
|
||||
expect(reorderContainer.children().attr('data-prevent-scroll')).toBe('true');
|
||||
}));
|
||||
it('should remove ng-hide if reorder is already active', inject(function($compile, $rootScope) {
|
||||
it('should show if reorder is already active', inject(function($compile, $rootScope) {
|
||||
var setSpy = jasmine.createSpy('setReorderButton');
|
||||
var el = angular.element('<ion-item><ion-reorder-button></ion-reorder-button></ion-item>');
|
||||
el.data('$ionListController', {
|
||||
@@ -110,7 +111,8 @@ describe('ionReorderButton directive', function() {
|
||||
$rootScope.$apply();
|
||||
var reorderContainer = angular.element(el[0].querySelector('.item-right-edit.item-reorder'));
|
||||
expect(reorderContainer.length).toBe(1);
|
||||
expect(reorderContainer.hasClass('ng-hide')).toBe(false);
|
||||
expect(reorderContainer.hasClass('visible')).toBe(true);
|
||||
expect(reorderContainer.hasClass('active')).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
@@ -92,7 +92,6 @@ describe('ionList directive', function() {
|
||||
expect(el.controller('ionList').closeOptionButtons).toHaveBeenCalled();
|
||||
var deleteButtons = angular.element(el[0].querySelectorAll('.item-delete.item-left-edit'));
|
||||
expect(deleteButtons.length).not.toBe(0);
|
||||
expect(deleteButtons.hasClass('ng-hide')).toBe(false);
|
||||
expect(el.children().hasClass('list-left-editing')).toBe(true);
|
||||
var content = angular.element(el[0].querySelectorAll('.item-content'));
|
||||
}));
|
||||
@@ -111,7 +110,6 @@ describe('ionList directive', function() {
|
||||
expect(el.controller('ionList').canSwipeItems()).toBe(true);
|
||||
expect(el.controller('ionList').closeOptionButtons.callCount).toBe(1);
|
||||
var deleteButtons = angular.element(el[0].querySelectorAll('.item-delete.item-left-edit'));
|
||||
expect(deleteButtons.hasClass('ng-hide')).toBe(true);
|
||||
expect(deleteButtons.length).not.toBe(0);
|
||||
expect(el.children().hasClass('list-left-editing')).toBe(false);
|
||||
var content = angular.element(el[0].querySelectorAll('.item-content'));
|
||||
@@ -131,7 +129,6 @@ describe('ionList directive', function() {
|
||||
expect(el.controller('ionList').canSwipeItems()).toBe(false);
|
||||
var reorderButtons = angular.element(el[0].querySelectorAll('.item-reorder.item-right-edit'));
|
||||
expect(reorderButtons.length).not.toBe(0);
|
||||
expect(reorderButtons.hasClass('ng-hide')).toBe(false);
|
||||
expect(el.children().hasClass('list-right-editing')).toBe(true);
|
||||
var content = angular.element(el[0].querySelectorAll('.item-content'));
|
||||
}));
|
||||
@@ -151,7 +148,6 @@ describe('ionList directive', function() {
|
||||
expect(el.controller('ionList').closeOptionButtons.callCount).toBe(1);
|
||||
var reorderButtons = angular.element(el[0].querySelectorAll('.item-reorder.item-right-edit'));
|
||||
expect(reorderButtons.length).not.toBe(0);
|
||||
expect(reorderButtons.hasClass('ng-hide')).toBe(true);
|
||||
expect(el.children().hasClass('list-right-editing')).toBe(false);
|
||||
var content = angular.element(el[0].querySelectorAll('.item-content'));
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user