diff --git a/angular/src/directives/proxies.ts b/angular/src/directives/proxies.ts index 3a2603d2670..c31884b84d2 100644 --- a/angular/src/directives/proxies.ts +++ b/angular/src/directives/proxies.ts @@ -414,7 +414,7 @@ export class IonItemSliding { proxyOutputs(this, this.el, ['ionDrag']); } } -proxyMethods(IonItemSliding, ['getOpenAmount', 'getSlidingRatio', 'close', 'closeOpened']); +proxyMethods(IonItemSliding, ['getOpenAmount', 'getSlidingRatio', 'open', 'close', 'closeOpened']); proxyInputs(IonItemSliding, ['disabled']); export declare interface IonLabel extends StencilComponents<'IonLabel'> {} diff --git a/core/api.txt b/core/api.txt index 00a62c66379..92b526ae3e6 100644 --- a/core/api.txt +++ b/core/api.txt @@ -472,6 +472,7 @@ ion-item-sliding,method,close,close() => Promise ion-item-sliding,method,closeOpened,closeOpened() => Promise ion-item-sliding,method,getOpenAmount,getOpenAmount() => Promise ion-item-sliding,method,getSlidingRatio,getSlidingRatio() => Promise +ion-item-sliding,method,open,open(side: string | undefined) => Promise ion-item-sliding,event,ionDrag,void,true ion-item,shadow diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 228c533ebc6..f9cc3daaaa1 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -1983,6 +1983,10 @@ export namespace Components { * Get the ratio of the open amount of the item compared to the width of the options. If the number returned is positive, then the options on the right side are open. If the number returned is negative, then the options on the left side are open. If the absolute value of the number is greater than 1, the item is open more than the width of the options. */ 'getSlidingRatio': () => Promise; + /** + * Open the sliding item. + */ + 'open': (side: string | undefined) => Promise; } interface IonItemSlidingAttributes extends StencilHTMLAttributes { /** diff --git a/core/src/components/item-sliding/item-sliding.tsx b/core/src/components/item-sliding/item-sliding.tsx index ed348fb2f6c..56d5808df7c 100644 --- a/core/src/components/item-sliding/item-sliding.tsx +++ b/core/src/components/item-sliding/item-sliding.tsx @@ -117,6 +117,52 @@ export class ItemSliding implements ComponentInterface { return Promise.resolve(this.getSlidingRatioSync()); } + /** + * Open the sliding item. + * + * @param side The side of the options to open. If a side is not provided, it will open the first set of options it finds within the item. + */ + // TODO update to work with RTL + @Method() + async open(side: string | undefined) { + if (this.item === null) { return; } + + const optionsToOpen = this.getOptions(side); + if (!optionsToOpen) { return; } + + /** + * If side is not set, we need to infer the side + * so we know which direction to move the options + */ + if (side === undefined) { + side = (optionsToOpen === this.leftOptions) ? 'start' : 'end'; + } + + const isStartOpen = this.openAmount < 0; + const isEndOpen = this.openAmount > 0; + + /** + * If a side is open and a user tries to + * re-open the same side, we should not do anything + */ + if (isStartOpen && optionsToOpen === this.leftOptions) { return; } + if (isEndOpen && optionsToOpen === this.rightOptions) { return; } + + this.closeOpened(); + + this.state = SlidingState.Enabled; + + requestAnimationFrame(() => { + this.calculateOptsWidth(); + + const width = (side === 'end') ? this.optsWidthRightSide : -this.optsWidthLeftSide; + openSlidingItem = this.el; + + this.setOpenAmount(width, false); + this.state = (side === 'end') ? SlidingState.End : SlidingState.Start; + }); + } + /** * Close the sliding item. Items can also be closed from the [List](../../list/List). */ @@ -138,6 +184,22 @@ export class ItemSliding implements ComponentInterface { return false; } + /** + * Given a side, attempt to return the ion-item-options element + * + * @param side This side of the options to get. If a side is not provided it will return the first one available + */ + // TODO update to work with RTL + private getOptions(side?: string): HTMLIonItemOptionsElement | undefined { + if (side === undefined) { + return this.leftOptions || this.rightOptions; + } else if (side === 'start') { + return this.leftOptions; + } else { + return this.rightOptions; + } + } + private async updateOptions() { const options = this.el.querySelectorAll('ion-item-options'); @@ -244,13 +306,18 @@ export class ItemSliding implements ComponentInterface { private calculateOptsWidth() { this.optsWidthRightSide = 0; if (this.rightOptions) { + this.rightOptions.style.display = 'flex'; this.optsWidthRightSide = this.rightOptions.offsetWidth; + this.rightOptions.style.display = ''; } this.optsWidthLeftSide = 0; if (this.leftOptions) { + this.leftOptions.style.display = 'flex'; this.optsWidthLeftSide = this.leftOptions.offsetWidth; + this.leftOptions.style.display = ''; } + this.optsDirty = false; } diff --git a/core/src/components/item-sliding/readme.md b/core/src/components/item-sliding/readme.md index b41c1c5455c..fb4a30d7c83 100644 --- a/core/src/components/item-sliding/readme.md +++ b/core/src/components/item-sliding/readme.md @@ -692,6 +692,22 @@ Type: `Promise` +### `open(side: string | undefined) => Promise` + +Open the sliding item. + +#### Parameters + +| Name | Type | Description | +| ------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `side` | `string \| undefined` | The side of the options to open. If a side is not provided, it will open the first set of options it finds within the item. | + +#### Returns + +Type: `Promise` + + + ---------------------------------------------- diff --git a/core/src/components/item-sliding/test/basic/index.html b/core/src/components/item-sliding/test/basic/index.html index 60f1ba96fd4..1f2a0b76e79 100644 --- a/core/src/components/item-sliding/test/basic/index.html +++ b/core/src/components/item-sliding/test/basic/index.html @@ -38,6 +38,9 @@ Toggle sliding Toggle Dynamic Options Close Opened Items + Open Item Start + Open Item End + Open Item with only one side @@ -405,6 +408,16 @@

Normal button (no sliding)

list.closeSlidingItems(); } + function openItem(side) { + var item = document.getElementById('item2'); + item.open(side); + } + + function openItemOneSide() { + var item = document.getElementById('item1'); + item.open(); + } + function noclose(item) { var itemEle = document.getElementById(item); console.log('no close', itemEle); diff --git a/core/src/components/item-sliding/test/preview/index.html b/core/src/components/item-sliding/test/preview/index.html index a83ebbbf8cf..ff0ec61081c 100644 --- a/core/src/components/item-sliding/test/preview/index.html +++ b/core/src/components/item-sliding/test/preview/index.html @@ -32,6 +32,7 @@ Toggle sliding Toggle Dynamic Options Close Opened Items + Open Item @@ -356,6 +357,11 @@

Normal button (no sliding)

list.closeSlidingItems(); } + function openItem() { + var item = document.getElementById('item0'); + item.open(); + } + function noclose(item) { var itemEle = document.getElementById(item); console.log('no close', itemEle);