From f6bf07987800a30f18c4634d1cd08f9e4dd4d3ca Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Thu, 5 Nov 2015 14:15:09 -0500 Subject: [PATCH 01/27] refactor(list): removed absolutely positioned borders, changed to an inner div references #437 --- ionic/components/item/item.scss | 9 +- ionic/components/item/item.ts | 10 +- ionic/components/item/modes/ios.scss | 114 +++++++++--------- ionic/components/list/modes/ios.scss | 38 +++--- ionic/components/list/test/no-lines/main.html | 90 ++++++++++++++ 5 files changed, 174 insertions(+), 87 deletions(-) diff --git a/ionic/components/item/item.scss b/ionic/components/item/item.scss index e69e9b070e..a047c5bccd 100644 --- a/ionic/components/item/item.scss +++ b/ionic/components/item/item.scss @@ -5,7 +5,6 @@ .item { - position: relative; display: flex; justify-content: space-between; align-items: center; @@ -31,7 +30,7 @@ font-weight: 500; width: 100%; z-index: 1000; - + &.sticky { position: -webkit-sticky; position: sticky; @@ -56,6 +55,12 @@ button.item.item { will-change: initial; } +.item-inner { + height: 100%; + width: 100%; + display: flex; +} + ion-item-content { margin: 0; flex: 1; diff --git a/ionic/components/item/item.ts b/ionic/components/item/item.ts index 5b2aa45f2c..82f0f693cf 100644 --- a/ionic/components/item/item.ts +++ b/ionic/components/item/item.ts @@ -21,10 +21,12 @@ import {Component} from 'angular2/angular2'; selector: 'ion-item,[ion-item]', template: '' + - '' + - '' + - ''+ - '', + '
' + + '' + + '' + + ''+ + '' + + '
', host: { '[class.item]': 'isItem' } diff --git a/ionic/components/item/modes/ios.scss b/ionic/components/item/modes/ios.scss index 725333ec5f..1de425d967 100644 --- a/ionic/components/item/modes/ios.scss +++ b/ionic/components/item/modes/ios.scss @@ -40,68 +40,69 @@ ion-note { color: $item-ios-note-color; } -.list { +.item-group { + ion-item-group-title { + border-bottom: 1px solid $item-ios-border-color; + } - .item-group { - // Make sure the first and last items don't have borders - > .item:first-of-type:before { - border-top: none !important; - } - > .item:last-of-type:after { - border-top: none !important; + .item:first-child { + .item-inner { + border-top-width: 0; } } +} + +.list { .item { margin-top: -1px; - padding-right: ($item-ios-padding-right / 2); - padding-left: ($item-ios-padding-left / 2); + padding-left: $item-ios-padding-left; font-size: $item-ios-font-size; - &:before { - position: absolute; - top: 0; - right: 0; - left: $item-ios-padding-left; + &:first-child { border-top: 1px solid $item-ios-border-color; - content: ''; - pointer-events: none; + + .item-inner { + border-top-width: 0; + } } - &:after { - position: absolute; - right: 0; - bottom: 0; - left: $item-ios-padding-left; + &:last-child { + border-bottom: 1px solid $item-ios-border-color; + } + + .item-inner { + padding-right: ($item-ios-padding-right / 2); border-top: 1px solid $item-ios-border-color; - content: ''; - pointer-events: none; } - &:first-child:before, - &:last-child:after { - left: 0; + ion-item-content { + margin: $item-ios-padding-top ($item-ios-padding-right / 2) $item-ios-padding-bottom 0; } } - ion-header + .item:first-of-type:before { - left: 0; - } + // If the item has the no-lines attribute we want to remove the border from it + // and the border from the next item if there is one + .item[no-lines] { + border-width: 0; - &[inset] .item { - &:before, - &:after { - left: 0; + .item-inner { + border-width: 0; + } + + + .item { + .item-inner { + border-width: 0; + } } } - ion-item-content { - margin: $item-ios-padding-top ($item-ios-padding-right / 2) $item-ios-padding-bottom ($item-ios-padding-left / 2); + [item-left] { + margin: $item-ios-padding-media-top $item-ios-padding-right $item-ios-padding-media-bottom 0; } - [item-left], [item-right] { - margin: $item-ios-padding-media-top ($item-ios-padding-right / 2) $item-ios-padding-media-bottom ($item-ios-padding-left / 2); + margin: $item-ios-padding-top ($item-ios-padding-right / 2) $item-ios-padding-bottom ($item-ios-padding-left / 2); } icon[item-left], @@ -224,7 +225,7 @@ ion-card { background-repeat: no-repeat; background-position: right ($item-ios-padding-right - 2) center; background-size: 14px 14px; - padding-right: 32px; + margin-right: 32px; } ion-item-sliding[detail-push] { @@ -234,11 +235,12 @@ ion-card { background-repeat: no-repeat; background-position: right ($item-ios-padding-right - 2) center; background-size: 14px 14px; - padding-right: 32px; + margin-right: 32px; } } } +// Hairlines for iOS need to be set at 0.55px to show on iPhone 6 and 6 Plus &.hairlines .list { ion-item-options { @@ -255,28 +257,26 @@ ion-card { margin-bottom: 0.55px; } + ion-header + .item { + border-top-width: 0.55px; + + .item-inner { + border-width: 0; + } + } + .item { margin-top: -0.55px; + border-width: 0.55px; - &:last-child { - margin-bottom: -0.55px; + .item-inner { + border-width: 0.55px; } - &:before, - &:after { - border-top-width: 0.55px; + &:first-child { + .item-inner { + border-top-width: 0px; + } } } - -} - -.item[no-lines] { - &:before, - &:after { - border-width: 0; - } - - + .item:before { - border-width: 0; - } } diff --git a/ionic/components/list/modes/ios.scss b/ionic/components/list/modes/ios.scss index e50f11b194..b26ef57fb9 100644 --- a/ionic/components/list/modes/ios.scss +++ b/ionic/components/list/modes/ios.scss @@ -31,25 +31,18 @@ $list-ios-header-color: #333 !default; letter-spacing: $list-ios-header-letter-spacing; text-transform: uppercase; color: $list-ios-header-color; + } - &:after { - position: absolute; - z-index: 1; - right: 0; - bottom: 0; - left: 0; - border-top: 1px solid $item-ios-border-color; - content: ''; - pointer-events: none; + ion-header + .item { + border-top: 1px solid $item-ios-border-color; + + .item-inner { + border-top-width: 0; } } } -&.hairlines .list ion-header:after { - border-top-width: 0.55px; -} - .list + .list { margin-top: $list-ios-margin-top + $list-ios-margin-bottom; } @@ -63,24 +56,22 @@ $list-ios-header-color: #333 !default; margin: $list-inset-ios-margin-top $list-inset-ios-margin-right $list-inset-ios-margin-bottom $list-inset-ios-margin-left; border-radius: $list-inset-ios-border-radius; + ion-header { + border-radius: inherit; + } + .item:first-child { margin-top: 0; border-top-right-radius: $list-inset-ios-border-radius; border-top-left-radius: $list-inset-ios-border-radius; - - &:before { - border-top: none; - } + border-top: none; } .item:last-child { margin-bottom: 0; border-bottom-right-radius: $list-inset-ios-border-radius; border-bottom-left-radius: $list-inset-ios-border-radius; - - &:after { - border-top: none; - } + border-bottom: none; } } @@ -90,9 +81,8 @@ $list-ios-header-color: #333 !default; &.hairlines .list[no-lines], .list[no-lines] { - ion-header:after, - .item:before, - .item:after { + .item, + .item .item-inner { border-width: 0; } } diff --git a/ionic/components/list/test/no-lines/main.html b/ionic/components/list/test/no-lines/main.html index 3f53208344..b555792be1 100644 --- a/ionic/components/list/test/no-lines/main.html +++ b/ionic/components/list/test/no-lines/main.html @@ -27,4 +27,94 @@ + + + + List With No Lines First Item + + + + + Pizza + + Always + + + + + + Beer + + Yes Plz + + + + + + Wine + + All the time + + + + + + + List With No Lines Middle Item + + + + + Pizza + + Always + + + + + + Beer + + Yes Plz + + + + + + Wine + + All the time + + + + + + + List With No Lines Last Item + + + + + Pizza + + Always + + + + + + Beer + + Yes Plz + + + + + + Wine + + All the time + + + From d5c5ffad4d094cfd97b5be71372623293dd5fbe3 Mon Sep 17 00:00:00 2001 From: Brandy Carney Date: Thu, 5 Nov 2015 15:17:27 -0500 Subject: [PATCH 02/27] refactor(list): fixing inset borders and adding wrapper for checkbox and radio references #437 --- ionic/components/checkbox/checkbox.ts | 14 ++++++++------ ionic/components/list/modes/ios.scss | 17 ++++++++++++++--- ionic/components/switch/switch.ts | 14 ++++++++------ 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/ionic/components/checkbox/checkbox.ts b/ionic/components/checkbox/checkbox.ts index 16d61c7716..2de01fbd2e 100644 --- a/ionic/components/checkbox/checkbox.ts +++ b/ionic/components/checkbox/checkbox.ts @@ -33,12 +33,14 @@ import {Form} from '../../util/form'; '(click)': 'click($event)' }, template: - '' + - '' + - '' + - '' + - '' + - '' + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + '
' }) export class Checkbox { diff --git a/ionic/components/list/modes/ios.scss b/ionic/components/list/modes/ios.scss index b26ef57fb9..df6fecd18d 100644 --- a/ionic/components/list/modes/ios.scss +++ b/ionic/components/list/modes/ios.scss @@ -56,11 +56,16 @@ $list-ios-header-color: #333 !default; margin: $list-inset-ios-margin-top $list-inset-ios-margin-right $list-inset-ios-margin-bottom $list-inset-ios-margin-left; border-radius: $list-inset-ios-border-radius; - ion-header { - border-radius: inherit; + .item { + margin-top: 0; + border-top: 1px solid $item-ios-border-color; + + .item-inner { + border-top: none; + } } - .item:first-child { + .item:first-child, ion-header { margin-top: 0; border-top-right-radius: $list-inset-ios-border-radius; border-top-left-radius: $list-inset-ios-border-radius; @@ -86,3 +91,9 @@ $list-ios-header-color: #333 !default; border-width: 0; } } + +&.hairlines .list[inset] { + .item { + border-width: 0.55px; + } +} diff --git a/ionic/components/switch/switch.ts b/ionic/components/switch/switch.ts index 7db592ed57..36ed79f25f 100644 --- a/ionic/components/switch/switch.ts +++ b/ionic/components/switch/switch.ts @@ -87,12 +87,14 @@ class MediaSwitch { }, template: '' + - '' + - '' + - '' + - '' + - '' + - '', + '
' + + '' + + '' + + '' + + '' + + '' + + '' + + `
`, directives: [MediaSwitch] }) export class Switch { From b1438d9cf4059339863b69a208e56dea4650ed45 Mon Sep 17 00:00:00 2001 From: Adam Bradley Date: Thu, 5 Nov 2015 15:03:53 -0600 Subject: [PATCH 03/27] refactor(item-sliding) --- ionic/components/item/item-sliding-gesture.ts | 187 ++++++++++++ ionic/components/item/item-sliding.scss | 36 +++ ionic/components/item/item-sliding.ts | 265 ++---------------- ionic/components/item/item.scss | 18 -- ionic/components/item/modes/ios.scss | 42 +-- ionic/components/item/modes/md.scss | 26 +- ionic/components/item/test/sliding/index.ts | 24 +- ionic/components/item/test/sliding/main.html | 150 +++++----- ionic/components/list/list.ts | 51 ++-- ionic/components/tabs/test/basic/index.ts | 45 ++- ionic/components/tap-click/activator.ts | 2 + ionic/components/tap-click/ripple.scss | 4 - ionic/components/tap-click/tap-click.ts | 19 +- ionic/config/directives.ts | 3 +- ionic/gestures/drag-gesture.ts | 8 +- ionic/ionic.core.scss | 1 + ionic/util/dom.ts | 38 +-- 17 files changed, 453 insertions(+), 466 deletions(-) create mode 100644 ionic/components/item/item-sliding-gesture.ts create mode 100644 ionic/components/item/item-sliding.scss diff --git a/ionic/components/item/item-sliding-gesture.ts b/ionic/components/item/item-sliding-gesture.ts new file mode 100644 index 0000000000..ab0128a1b5 --- /dev/null +++ b/ionic/components/item/item-sliding-gesture.ts @@ -0,0 +1,187 @@ +import {Hammer} from 'ionic/gestures/hammer'; +import {DragGesture} from 'ionic/gestures/drag-gesture'; +import {List} from '../list/list'; + +import * as util from 'ionic/util'; +import {CSS, raf, closest} from 'ionic/util/dom'; + + +export class ItemSlidingGesture extends DragGesture { + constructor(list: List, listEle) { + super(listEle, { + direction: 'x', + threshold: list.width() + }); + + this.data = {}; + this.openItems = 0; + + this.list = list; + this.listEle = listEle; + this.canDrag = true; + this.listen(); + + this.on('tap', ev => { + if (!isFromOptionButtons(ev.target)) { + let didClose = this.closeOpened(); + if (didClose) { + ev.preventDefault(); + } + } + }); + } + + onDragStart(ev) { + let itemContainerEle = getItemConatiner(ev.target); + if (!itemContainerEle) return; + + this.closeOpened(ev, itemContainerEle); + + let openAmout = this.getOpenAmount(itemContainerEle); + let itemData = this.getData(itemContainerEle); + + if (openAmout) { + return ev.preventDefault(); + } + + itemContainerEle.classList.add('active-slide'); + + this.setData(itemContainerEle, 'offsetX', openAmout); + this.setData(itemContainerEle, 'startX', ev.center[this.direction]); + } + + onDrag(ev) { + let itemContainerEle = getItemConatiner(ev.target); + if (!itemContainerEle || !isActive(itemContainerEle)) return; + + let itemData = this.getData(itemContainerEle); + + if (!itemData.optsWidth) { + itemData.optsWidth = getOptionsWidth(itemContainerEle); + if (!itemData.optsWidth) return; + } + + let x = ev.center[this.direction]; + let delta = x - itemData.startX; + + let newX = Math.max(0, itemData.offsetX - delta); + + if (newX > itemData.optsWidth) { + // Calculate the new X position, capped at the top of the buttons + newX = -Math.min(-itemData.optsWidth, -itemData.optsWidth + (((delta + itemData.optsWidth) * 0.4))); + } + + this.open(itemContainerEle, newX, false); + } + + onDragEnd(ev) { + let itemContainerEle = getItemConatiner(ev.target); + if (!itemContainerEle || !isActive(itemContainerEle)) return; + + // If we are currently dragging, we want to snap back into place + // The final resting point X will be the width of the exposed buttons + let itemData = this.getData(itemContainerEle); + + var restingPoint = itemData.optsWidth; + + // Check if the drag didn't clear the buttons mid-point + // and we aren't moving fast enough to swipe open + + if (this.getOpenAmount(itemContainerEle) < (restingPoint / 2)) { + + // If we are going left but too slow, or going right, go back to resting + if (ev.direction & Hammer.DIRECTION_RIGHT) { + // Left + restingPoint = 0; + + } else if (Math.abs(ev.velocityX) < 0.3) { + // Right + restingPoint = 0; + } + } + + this.setData(itemContainerEle, 'opened', restingPoint > 0); + + raf(() => { + this.open(itemContainerEle, restingPoint, true); + }); + } + + closeOpened(ev, doNotCloseEle) { + let didClose = false; + if (this.openItems) { + let openItemElements = this.listEle.querySelectorAll('.active-slide'); + for (let i = 0; i < openItemElements.length; i++) { + if (openItemElements[i] !== doNotCloseEle) { + this.open(openItemElements[i], 0, true); + didClose = true; + } + } + } + return didClose; + } + + open(itemContainerEle, openAmount, animate) { + let slidingEle = itemContainerEle.querySelector('ion-item'); + if (!slidingEle) return; + + this.setData(itemContainerEle, 'openAmount', openAmount); + + clearTimeout(this.getData(itemContainerEle).timerId); + + if (openAmount > 0) { + this.openItems++; + + } else { + let timerId = setTimeout(() => { + if (slidingEle.style[CSS.transform] === '') { + itemContainerEle.classList.remove('active-slide'); + this.openItems--; + } + }, 400); + this.setData(itemContainerEle, 'timerId', timerId); + } + + slidingEle.style[CSS.transform] = (openAmount === 0 ? '' : 'translate3d(' + -openAmount + 'px,0,0)'); + slidingEle.style[CSS.transition] = (animate ? '' : 'none'); + } + + getOpenAmount(itemContainerEle) { + return this.getData(itemContainerEle).openAmount || 0; + } + + getData(itemContainerEle) { + return this.data[itemContainerEle && itemContainerEle.$ionSlide] || {}; + } + + setData(itemContainerEle, key, value) { + if (!this.data[itemContainerEle.$ionSlide]) { + this.data[itemContainerEle.$ionSlide] = {}; + } + this.data[itemContainerEle.$ionSlide][key] = value; + } + + unlisten() { + super.unlisten(); + this.listEle = null; + } +} + +function getItemConatiner(ele) { + return closest(ele, 'ion-item-sliding', true); +} + +function isFromOptionButtons(ele) { + return !!closest(ele, 'ion-item-options', true); +} + +function getOptionsWidth(itemContainerEle) { + let optsEle = itemContainerEle.querySelector('ion-item-options'); + if (optsEle) { + return optsEle.offsetWidth; + } +} + +function isActive(itemContainerEle) { + return itemContainerEle.classList.contains('active-slide'); +} diff --git a/ionic/components/item/item-sliding.scss b/ionic/components/item/item-sliding.scss new file mode 100644 index 0000000000..f27705b017 --- /dev/null +++ b/ionic/components/item/item-sliding.scss @@ -0,0 +1,36 @@ + +/** + * The hidden right-side buttons that can be exposed under a list item + * with dragging. + */ + +ion-item-sliding { + display: block; + position: relative; + overflow: hidden; + + .item { + position: static; + } +} + +ion-item-options { + display: none; + position: absolute; + top: 0; + right: 0; + z-index: $z-index-item-options; + height: 100%; +} + +ion-item-sliding.active-slide { + + .item { + position: relative; + z-index: $z-index-item-options + 1; + } + + ion-item-options { + display: flex; + } +} diff --git a/ionic/components/item/item-sliding.ts b/ionic/components/item/item-sliding.ts index ea04bacbfd..4e7fcdae43 100644 --- a/ionic/components/item/item-sliding.ts +++ b/ionic/components/item/item-sliding.ts @@ -1,31 +1,7 @@ -import {Component, Directive, ElementRef, NgIf, Host, Optional, Renderer, NgZone} from 'angular2/angular2'; +import {Component, ElementRef, Optional} from 'angular2/angular2'; -import {Gesture} from 'ionic/gestures/gesture'; -import {DragGesture} from 'ionic/gestures/drag-gesture'; -import {Hammer} from 'ionic/gestures/hammer'; -import {List} from 'ionic/components/list/list'; +import {List} from '../list/list'; -import * as util from 'ionic/util'; - -import {CSS, raf} from 'ionic/util/dom'; - - - -@Directive({ - selector: 'ion-item-options > button,ion-item-options > [button]', - host: { - '(click)': 'clicked($event)' - } -}) -export class ItemSlidingOptionButton { - constructor(elementRef: ElementRef) { - } - clicked(event) { - // Don't allow the click to propagate - event.preventDefault(); - event.stopPropagation(); - } -} /** * @name ionItem @@ -36,238 +12,35 @@ export class ItemSlidingOptionButton { * @usage * ```html * - * - * {{item.title}} - *
- * {{item.note}} - *
+ * + * + * {{item.title}} + * + * + * + * + * * *
- * ``` + * ``` */ @Component({ selector: 'ion-item-sliding', - inputs: [ - 'sliding' - ], template: - '' + - '' + - '' + - '' + - '' + - ''+ - '' + - '' + '' + + '' }) export class ItemSliding { - /** - * TODO - * @param {ElementRef} elementRef A reference to the component's DOM element. - */ - constructor(elementRef: ElementRef, renderer: Renderer, @Optional() @Host() list: List, zone: NgZone) { - this._zone = zone; - renderer.setElementClass(elementRef, 'item', true); - renderer.setElementAttribute(elementRef, 'tappable', ''); - this._isOpen = false; - this._isSlideActive = false; - this._isTransitioning = false; - this._transform = ''; - - this.list = list; - - this.elementRef = elementRef; - this.swipeButtons = {}; - this.optionButtons = {}; + constructor(@Optional() private list: List, elementRef: ElementRef) { + list.enableSlidingItems(true); + elementRef.nativeElement.$ionSlide = ++slideIds; } - onInit() { - let ele = this.elementRef.nativeElement; - this.itemSlidingContent = ele.querySelector('ion-item-sliding-content'); - this.itemOptions = ele.querySelector('ion-item-options'); - this.openAmount = 0; - this._zone.runOutsideAngular(() => { - this.gesture = new ItemSlideGesture(this, this.itemSlidingContent, this._zone); - }); + close() { + this.list.closeSlidingItems(); } - onDestroy() { - this.gesture && this.gesture.unlisten(); - this.itemSlidingContent = this.itemOptionsContent = null; - } - - close(andStopDrag) { - this.openAmount = 0; - - // Enable it once, it'll get disabled on the next drag - raf(() => { - this.enableAnimation(); - if (this.itemSlidingContent) { - this.itemSlidingContent.style[CSS.transform] = 'translateX(0)'; - } - }); - } - - open(amt) { - let el = this.itemSlidingContent; - this.openAmount = amt || 0; - - if (this.list) { - this.list.setOpenItem(this); - } - - if (amt === '') { - el.style[CSS.transform] = ''; - } else { - el.style[CSS.transform] = 'translateX(' + -amt + 'px)'; - } - } - - isOpen() { - return this.openAmount > 0; - } - - getOpenAmt() { - return this.openAmount; - } - - disableAnimation() { - this.itemSlidingContent.style[CSS.transition] = 'none'; - } - - enableAnimation() { - // Clear the explicit transition, allow for CSS one to take over - this.itemSlidingContent.style[CSS.transition] = ''; - } - - /** - * User did a touchstart - */ - didTouch() { - if (this.isOpen()) { - this.close(); - this.didClose = true; - - } else { - let openItem = this.list.getOpenItem(); - if (openItem && openItem !== this) { - this.didClose = true; - } - if (this.list) { - this.list.closeOpenItem(); - } - } - } } -class ItemSlideGesture extends DragGesture { - constructor(item: ItemSliding, el: Element, zone) { - super(el, { - direction: 'x', - threshold: el.offsetWidth - }); - this.item = item; - this.canDrag = true; - this.listen(); - - zone.runOutsideAngular(() => { - let touchStart = (e) => { - this.item.didTouch(); - raf(() => { - this.item.itemOptionsWidth = this.item.itemOptions && this.item.itemOptions.offsetWidth || 0; - }) - }; - el.addEventListener('touchstart', touchStart); - el.addEventListener('mousedown', touchStart); - - let touchEnd = (e) => { - // If we have a touch end and the item is closing, - // prevent default to stop a click from triggering - if(this.item.didClose) { - e.preventDefault(); - } - this.item.didClose = false; - }; - el.addEventListener('touchend', touchEnd); - el.addEventListener('mouseup', touchEnd); - el.addEventListener('mouseout', touchEnd); - el.addEventListener('mouseleave', touchEnd); - el.addEventListener('touchcancel', touchEnd); - }); - } - - onDragStart(ev) { - if (this.item.didClose) { return; } - - if (!this.item.itemOptionsWidth) { return; } - - this.slide = {}; - - this.slide.offsetX = this.item.getOpenAmt(); - this.slide.startX = ev.center[this.direction]; - this.slide.started = true; - - this.item.disableAnimation(); - } - - onDrag(ev) { - if (!this.slide || !this.slide.started) return; - - this.slide.x = ev.center[this.direction]; - this.slide.delta = this.slide.x - this.slide.startX; - - let newX = Math.max(0, this.slide.offsetX - this.slide.delta); - - let buttonsWidth = this.item.itemOptionsWidth; - - if (newX > this.item.itemOptionsWidth) { - // Calculate the new X position, capped at the top of the buttons - newX = -Math.min(-buttonsWidth, -buttonsWidth + (((this.slide.delta + buttonsWidth) * 0.4))); - } - - this.item.open(newX); - } - - onDragEnd(ev) { - if (!this.slide || !this.slide.started) return; - - let buttonsWidth = this.item.itemOptionsWidth; - - // If we are currently dragging, we want to snap back into place - // The final resting point X will be the width of the exposed buttons - var restingPoint = this.item.itemOptionsWidth; - - // Check if the drag didn't clear the buttons mid-point - // and we aren't moving fast enough to swipe open - if (this.item.openAmount < (buttonsWidth / 2)) { - - // If we are going left but too slow, or going right, go back to resting - if (ev.direction & Hammer.DIRECTION_RIGHT) { - // Left - restingPoint = 0; - } else if (Math.abs(ev.velocityX) < 0.3) { - // Right - restingPoint = 0; - } - } - - raf(() => { - if (restingPoint === 0) { - // Reset to zero - this.item.open(''); - var buttons = this.item.itemOptions; - clearTimeout(this.hideButtonsTimeout); - this.hideButtonsTimeout = setTimeout(() => { - buttons && buttons.classList.add('invisible'); - }, 250); - - } else { - this.item.open(restingPoint); - } - this.item.enableAnimation(); - - this.slide = null; - }); - } -} +let slideIds = 0; diff --git a/ionic/components/item/item.scss b/ionic/components/item/item.scss index a047c5bccd..61ffdc307f 100644 --- a/ionic/components/item/item.scss +++ b/ionic/components/item/item.scss @@ -134,24 +134,6 @@ ion-input.item { align-items: flex-start; } -/** - * The hidden right-side buttons that can be exposed under a list item - * with dragging. - */ -ion-item-sliding-content { - display: block; - z-index: $z-index-item-options + 1; - flex: 1; -} -ion-item-options { - display: flex; - position: absolute; - top: 0; - right: 0; - z-index: $z-index-item-options; - height: 100%; -} - // TEMP hack for https://github.com/angular/angular/issues/4582 [item-right] { diff --git a/ionic/components/item/modes/ios.scss b/ionic/components/item/modes/ios.scss index 1de425d967..6215e46607 100644 --- a/ionic/components/item/modes/ios.scss +++ b/ionic/components/item/modes/ios.scss @@ -163,26 +163,6 @@ ion-note { } } - - ion-item-sliding.item { - padding-left: 0; - padding-right: 0; - } - - ion-item-sliding-content { - background-color: $item-ios-sliding-content-bg; - padding-right: ($item-ios-padding-right / 2); - padding-left: ($item-ios-padding-left / 2); - display: flex; - min-height: 42px; - justify-content: center; - - transition: $item-ios-sliding-transition; - - // To allow the hairlines through - margin-top: 1px; - margin-bottom: 1px; - } ion-item-options { button, [button] { min-height: calc(100% - 2px); @@ -204,8 +184,7 @@ ion-note { .item.activated, a.item.activated, -button.item.activated, -.item.activated ion-item-sliding-content { +button.item.activated { background-color: $item-ios-activated-background-color; transition-duration: 0ms; } @@ -219,25 +198,13 @@ button.item { .list, ion-card { button[ion-item]:not([detail-none]), - a[ion-item]:not([detail-none]), - [detail-push]:not(ion-item-sliding) { + a[ion-item]:not([detail-none]) { @include ios-detail-push-icon($item-ios-detail-push-color); background-repeat: no-repeat; background-position: right ($item-ios-padding-right - 2) center; background-size: 14px 14px; margin-right: 32px; } - - ion-item-sliding[detail-push] { - - ion-item-sliding-content { - @include ios-detail-push-icon($item-ios-detail-push-color); - background-repeat: no-repeat; - background-position: right ($item-ios-padding-right - 2) center; - background-size: 14px 14px; - margin-right: 32px; - } - } } // Hairlines for iOS need to be set at 0.55px to show on iPhone 6 and 6 Plus @@ -252,11 +219,6 @@ ion-card { } } - ion-item-sliding-content { - margin-top: 0.55px; - margin-bottom: 0.55px; - } - ion-header + .item { border-top-width: 0.55px; diff --git a/ionic/components/item/modes/md.scss b/ionic/components/item/modes/md.scss index 4afc28a385..9f38858d62 100644 --- a/ionic/components/item/modes/md.scss +++ b/ionic/components/item/modes/md.scss @@ -207,24 +207,6 @@ ion-note { box-shadow: none; } - ion-item-sliding.item { - padding-left: 0; - padding-right: 0; - } - ion-item-sliding-content { - background-color: $item-md-sliding-content-bg; - padding-right: ($item-md-padding-right / 2); - padding-left: ($item-md-padding-left / 2); - display: flex; - min-height: 42px; - justify-content: center; - - transition: $item-md-sliding-transition; - - // To allow the hairlines through - margin-top: 1px; - margin-bottom: 1px; - } ion-item-options { button, [button] { height: calc(100% - 2px); @@ -246,15 +228,13 @@ ion-note { .item, a.item, -button.item, -.item ion-item-sliding-content { - transition: background-color $button-md-transition-duration $button-md-animation-curve; +button.item { + transition: background-color $button-md-transition-duration $button-md-animation-curve, transform 300ms; } .item.activated, a.item.activated, -button.item.activated, -.item.activated ion-item-sliding-content { +button.item.activated { background-color: $item-md-activated-background-color; box-shadow: none; } diff --git a/ionic/components/item/test/sliding/index.ts b/ionic/components/item/test/sliding/index.ts index edf8bf5718..96d33e8aca 100644 --- a/ionic/components/item/test/sliding/index.ts +++ b/ionic/components/item/test/sliding/index.ts @@ -1,29 +1,35 @@ -import {App} from 'ionic/ionic'; +import {App, IonicApp} from 'ionic/ionic'; @App({ templateUrl: 'main.html' }) class E2EApp { - constructor() { + constructor(private app: IonicApp) { setTimeout(() => { this.shouldShow = true; }, 10); } + closeOpened() { + this.app.getComponent('myList').closeSlidingItems(); + } + getItems() { - console.log('getItems'); return [0,1]; } - didClick(e) { - console.log('CLICK', e.defaultPrevented, e) + didClick(ev, item) { + console.log('CLICK', ev.defaultPrevented, ev) } - archive(e) { - console.log('Accept', e); + archive(ev, item) { + console.log('Archive', ev, item); + item.close(); } - del(e) { - console.log('Delete', e); + + del(ev, item) { + console.log('Delete', ev, item); + item.close(); } } diff --git a/ionic/components/item/test/sliding/main.html b/ionic/components/item/test/sliding/main.html index 5f13ed5840..7b3fd83541 100644 --- a/ionic/components/item/test/sliding/main.html +++ b/ionic/components/item/test/sliding/main.html @@ -1,77 +1,99 @@ Sliding Items - + + + - -

Max Lynch

-

- Hey do you want to go to the game tonight? -

- - - - -
+ + +

Max Lynch

+

+ Hey do you want to go to the game tonight? +

+
+ + + + +
- -

Adam Bradley

-

- I think I figured out how to get more Mountain Dew -

- - - - -
+ + +

Adam Bradley

+

+ I think I figured out how to get more Mountain Dew +

+
+ + + + +
- -

Ben Sperry

-

- I like paper -

- - - - -
+ + +

Ben Sperry

+

+ I like paper +

+
+ + + + +
- - - One Line w/ Icon, div only text - - - - + + + + One Line w/ Icon, div only text + + + + + - - - - - One Line w/ Avatar, div only text - - - - + + + + + + One Line w/ Avatar, div only text + + + + + - - - - -

Two Lines w/ Thumbnail, H2 Header

-

Paragraph text.

- - - -
+ + + + + +

Two Lines w/ Thumbnail, H2 Header

+

Paragraph text.

+
+ + + +
- -

ng-for {{item}}

- - - -
+ + +

ng-for {{item}}

+
+ + + +
-
+
+ +

+ +

+ +