fix(item-option): add styling for slots other than icon-only (#17711)

styles the item option properly when icons are slotted. This was not working before at all for `top` and `bottom` slots.

- removes the e2e test from item/sliding in favor of all of them being under item-sliding
- adds more usage examples for all frameworks
- updates the styling for an anchor option so that it displays properly
- updates the standalone e2e test to take screenshots of the start icon, top icon, and anchor options
- updates the interactive e2e test to work locally
- cleaned up the CSS for start/end icons
- verified the styles for ben approval 💪

closes #17737 fixes #17402
This commit is contained in:
Brandy Carney
2019-03-15 13:46:57 -04:00
committed by GitHub
parent 29dbd0770c
commit 14f758ca97
22 changed files with 1332 additions and 535 deletions

View File

@ -19,7 +19,7 @@ export async function testActionSheet(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
const presentBtn = await page.find(selector);
await presentBtn.click();
@ -27,20 +27,20 @@ export async function testActionSheet(
let actionSheet = await page.find('ion-action-sheet');
await actionSheet.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await afterScreenshotHook(page, screenshotName, screenShotCompares, actionSheet);
await afterScreenshotHook(page, screenshotName, screenshotCompares, actionSheet);
await actionSheet.callMethod('dismiss');
await actionSheet.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismissed ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismissed ${screenshotName}`));
actionSheet = await page.find('ion-action-sheet');
expect(actionSheet).toBe(null);
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {
@ -51,7 +51,7 @@ export async function testActionSheet(
export async function testActionSheetBackdrop(
page: any,
screenshotName: string,
screenShotCompares: any,
screenshotCompares: any,
actionSheet: any
) {
try {
@ -59,7 +59,7 @@ export async function testActionSheetBackdrop(
const backdrop = await page.find('ion-backdrop');
await backdrop.click();
screenShotCompares.push(await page.compareScreenshot(`dismissed backdrop ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismissed backdrop ${screenshotName}`));
const isVisible = await actionSheet.isVisible();
expect(isVisible).toBe(true);
@ -71,7 +71,7 @@ export async function testActionSheetBackdrop(
export async function testActionSheetAlert(
page: any,
screenshotName: string,
screenShotCompares: any
screenshotCompares: any
) {
try {
const openAlertBtn = await page.find({ text: 'Open Alert' });
@ -81,7 +81,7 @@ export async function testActionSheetAlert(
await alert.waitForVisible();
await page.waitFor(250);
screenShotCompares.push(await page.compareScreenshot(`alert open ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`alert open ${screenshotName}`));
const alertOkayBtn = await page.find({ contains: 'Okay' });
await alertOkayBtn.click();

View File

@ -18,7 +18,7 @@ export async function testAlert(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
await page.click(selector);
await page.waitForSelector(selector);
@ -28,18 +28,18 @@ export async function testAlert(
expect(alert).not.toBe(null);
await alert.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await alert.callMethod('dismiss');
await alert.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
alert = await page.find('ion-alert');
expect(alert).toBe(null);
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {

View File

@ -35,8 +35,8 @@ export async function testFab(
screenshotCompares.push(await page.compareScreenshot(`${screenshotName} close`));
for (const screenShotCompare of screenshotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {
throw err;
@ -69,8 +69,8 @@ export async function testDisabledFab(
screenshotCompares.push(await page.compareScreenshot(`disabled ${screenshotName} attempt open`));
for (const screenShotCompare of screenshotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {
throw err;

View File

@ -38,6 +38,8 @@
@include text-inherit();
@include padding(0, .7em);
display: inline-block;
position: relative;
width: 100%;
@ -51,13 +53,14 @@
cursor: pointer;
appearance: none;
box-sizing: border-box;
}
.button-inner {
display: flex;
flex-direction: column;
flex-flow: row nowrap;
flex-flow: column nowrap;
flex-shrink: 0;
align-items: center;
justify-content: center;
@ -66,6 +69,29 @@
height: 100%;
}
.horizontal-wrapper {
display: flex;
flex-flow: row nowrap;
flex-shrink: 0;
align-items: center;
justify-content: center;
width: 100%;
}
::slotted(*) {
flex-shrink: 0;
}
::slotted([slot="start"]) {
@include margin(0, 5px, 0, 0);
}
::slotted([slot="end"]) {
@include margin(0, 0, 0, 5px);
}
::slotted([slot="icon-only"]) {
@include padding(0);
@include margin(0, 10px);

View File

@ -80,12 +80,14 @@ export class ItemOption implements ComponentInterface {
href={this.href}
>
<span class="button-inner">
<slot name="top"></slot>
<div class="horizontal-wrapper">
<slot name="start"></slot>
<slot name="top" />
<slot name="icon-only" />
<slot name="icon-only"></slot>
<slot></slot>
<slot name="bottom" />
<slot name="end"></slot>
</div>
<slot name="bottom"></slot>
</span>
{this.mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
</TagType>

View File

@ -319,10 +319,10 @@ export class ItemSliding implements ComponentInterface {
function swipeShouldReset(isResetDirection: boolean, isMovingFast: boolean, isOnResetZone: boolean): boolean {
// The logic required to know when the sliding item should close (openAmount=0)
// depends on three booleans (isCloseDirection, isMovingFast, isOnCloseZone)
// depends on three booleans (isResetDirection, isMovingFast, isOnResetZone)
// and it ended up being too complicated to be written manually without errors
// so the truth table is attached below: (0=false, 1=true)
// isCloseDirection | isMovingFast | isOnCloseZone || shouldClose
// isResetDirection | isMovingFast | isOnResetZone || shouldClose
// 0 | 0 | 0 || 0
// 0 | 0 | 1 || 1
// 0 | 1 | 0 || 0

View File

@ -35,19 +35,145 @@ Options can be expanded to take up the full width of the item if you swipe past
```html
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option (click)="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" (click)="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option (click)="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
```
@ -56,19 +182,145 @@ Options can be expanded to take up the full width of the item if you swipe past
```html
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option onClick="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" onClick="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option onClick="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
```
@ -83,17 +335,143 @@ import { IonList, IonItemSliding, IonItem, IonLabel, IonItemOptions, IonItemOpti
const Example: React.SFC<{}> = () => (
<IonList>
{/* Sliding item with text options on both sides */}
<IonItemSliding>
<IonItemOptions side="start">
<IonItemOption onClick={favorite(item)}>Favorite</IonItemOption>
<IonItemOption color="danger" onClick={share(item)}>Share</IonItemOption>
</IonItemOptions>
<IonItem>
<IonLabel>Item Options</IonLabel>
</IonItem>
<IonItemOptions side="end">
<IonItemOption onClick={unread(item)}>Unread</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with expandable options on both sides */}
<IonItemSliding>
<IonItemOptions side="start">
<IonItemOption color="danger" expandable>
Delete
</IonItemOption>
</IonItemOptions>
<IonItem>
<IonLabel>Item</IonLabel>
<IonLabel>Expandable Options</IonLabel>
</IonItem>
<IonItemOptions side="end">
<IonItemOption color="tertiary" expandable>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Multi-line sliding item with icon options on both sides */}
<IonItemSliding id="item100">
<IonItem href="#">
<IonLabel>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</IonLabel>
<IonNote slot="end">
10:45 AM
</IonNote>
</IonItem>
<IonItemOptions side="start">
<IonItemOption onClick={() => {}}>Favorite</IonItemOption>
<IonItemOption color="danger" onClick={() => {}}>Share</IonItemOption>
<IonItemOption>
<IonIcon slot="icon-only" name="heart"></IonIcon>
</IonItemOption>
</IonItemOptions>
<IonItemOptions side="end">
<IonItemOption onClick={() => {}}>Unread</IonItemOption>
<IonItemOption color="danger">
<IonIcon slot="icon-only" name="trash"></IonIcon>
</IonItemOption>
<IonItemOption>
<IonIcon slot="icon-only" name="star"></IonIcon>
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon start options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Start
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="start" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="start" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon end options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons End
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="end" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="end" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon top options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Top
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="top" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="top" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon bottom options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Bottom
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="bottom" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="bottom" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
</IonList>
@ -109,19 +487,145 @@ export default Example;
```html
<template>
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option @click="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" @click="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option @click="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</template>
```

View File

@ -1,12 +1,14 @@
import { newE2EPage } from '@stencil/core/testing';
import { openItemSliding } from '../test.utils';
test('item-sliding: interactive', async () => {
const page = await newE2EPage({
url: '/src/components/item-sliding/test/interactive?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
const compares = [];
compares.push(await page.compareScreenshot());
const items = await page.$$('ion-item-sliding');
expect(items.length).toEqual(3);
@ -20,30 +22,30 @@ test('item-sliding: interactive', async () => {
const itemsAfterSecondSlide = await page.$$('ion-item-sliding');
expect(itemsAfterSecondSlide.length).toEqual(1);
for (const compare of compares) {
expect(compare).toMatchScreenshot();
}
});
async function slideAndDelete(item: any, page: any) {
try {
// Get the element's ID
const id = await(await item.getProperty('id')).jsonValue();
await openItemSliding(`#${id}`, page);
await deleteItemSliding(item, page, id);
} catch (err) {
throw err;
}
}
// Simulate a drag
const boundingBox = await item.boundingBox();
const centerX = parseFloat(boundingBox.x + boundingBox.width / 2);
const centerY = parseFloat(boundingBox.y + boundingBox.height / 2);
await page.mouse.move(centerX, centerY);
await page.mouse.down();
await page.mouse.move(0, centerY);
await page.mouse.up();
async function deleteItemSliding(item: any, page: any, id: string) {
// Click the "delete" option
const options = await item.$$('ion-item-option');
await options[0].click();
// Wait for element to be removed from DOM
await page.waitForSelector(id, { hidden: true });
} catch (err) {
throw err;
}
await page.waitFor(1000);
}

View File

@ -1,10 +1,31 @@
import { newE2EPage } from '@stencil/core/testing';
import { closeItemSliding, openItemSliding } from '../test.utils';
test('item-sliding: standalone', async () => {
const page = await newE2EPage({
url: '/src/components/item-sliding/test/standalone?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
const compares = [];
compares.push(await page.compareScreenshot());
// Pass sliding item with start icons in option
await openItemSliding('#startItem', page);
compares.push(await page.compareScreenshot(`start icons open`));
await closeItemSliding(page);
// Pass sliding item with top icons in option
await openItemSliding('#topItem', page);
compares.push(await page.compareScreenshot(`top icons open`));
await closeItemSliding(page);
// Pass sliding item with anchor option
await openItemSliding('#anchorItem', page);
compares.push(await page.compareScreenshot(`anchor option`));
await closeItemSliding(page);
for (const compare of compares) {
expect(compare).toMatchScreenshot();
}
});

View File

@ -4,7 +4,8 @@
<head>
<meta charset="UTF-8">
<title>Item Sliding - Standalone</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/core.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
@ -12,38 +13,168 @@
</head>
<body>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option onClick="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" onClick="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option onClick="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
One Line, icon only
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options>
<ion-item-option color="secondary">
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="close"></ion-icon>
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding id="startItem">
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding id="topItem">
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
One Line, icon and text
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon name="more"></ion-icon>
<span class="more-text">More</span>
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with one anchor option -->
<ion-item-sliding id="anchorItem">
<ion-item>
<ion-label>
Sliding Item, Anchor Icon Option
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option href="#" color="primary">
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon name="archive"></ion-icon>
<span class="archive-text">Archive</span>
<ion-icon slot="icon-only" name="archive"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</body>
<style>
body {
margin: 0;
}
</style>
</html>

View File

@ -0,0 +1,31 @@
// Opens a sliding item by simulating a drag event
export async function openItemSliding(id: string, page: any) {
try {
const slidingItem = await page.$(id);
// Simulate a drag
const boundingBox = await slidingItem.boundingBox();
const centerX = parseFloat(boundingBox.x + boundingBox.width / 2);
const centerY = parseFloat(boundingBox.y + boundingBox.height / 2);
await page.mouse.move(centerX, centerY);
await page.mouse.down();
await page.mouse.move(centerX / 2, centerY);
await page.mouse.move(0, centerY);
await page.mouse.up();
// Add a timeout to make sure the item is open
await page.waitFor(2000);
} catch (err) {
throw err;
}
}
// Close a sliding item after taking a screenshot
// to allow other sliding items to open
export async function closeItemSliding(page: any) {
await page.mouse.move(0, 0);
await page.mouse.down();
await page.mouse.up();
await page.waitFor(1000);
}

View File

@ -1,17 +1,143 @@
```html
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option (click)="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" (click)="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option (click)="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
```

View File

@ -1,17 +1,143 @@
```html
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option onClick="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" onClick="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option onClick="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
```

View File

@ -6,17 +6,143 @@ import { IonList, IonItemSliding, IonItem, IonLabel, IonItemOptions, IonItemOpti
const Example: React.SFC<{}> = () => (
<IonList>
{/* Sliding item with text options on both sides */}
<IonItemSliding>
<IonItemOptions side="start">
<IonItemOption onClick={favorite(item)}>Favorite</IonItemOption>
<IonItemOption color="danger" onClick={share(item)}>Share</IonItemOption>
</IonItemOptions>
<IonItem>
<IonLabel>Item</IonLabel>
<IonLabel>Item Options</IonLabel>
</IonItem>
<IonItemOptions side="end">
<IonItemOption onClick={unread(item)}>Unread</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with expandable options on both sides */}
<IonItemSliding>
<IonItemOptions side="start">
<IonItemOption onClick={() => {}}>Favorite</IonItemOption>
<IonItemOption color="danger" onClick={() => {}}>Share</IonItemOption>
<IonItemOption color="danger" expandable>
Delete
</IonItemOption>
</IonItemOptions>
<IonItem>
<IonLabel>Expandable Options</IonLabel>
</IonItem>
<IonItemOptions side="end">
<IonItemOption onClick={() => {}}>Unread</IonItemOption>
<IonItemOption color="tertiary" expandable>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Multi-line sliding item with icon options on both sides */}
<IonItemSliding id="item100">
<IonItem href="#">
<IonLabel>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</IonLabel>
<IonNote slot="end">
10:45 AM
</IonNote>
</IonItem>
<IonItemOptions side="start">
<IonItemOption>
<IonIcon slot="icon-only" name="heart"></IonIcon>
</IonItemOption>
</IonItemOptions>
<IonItemOptions side="end">
<IonItemOption color="danger">
<IonIcon slot="icon-only" name="trash"></IonIcon>
</IonItemOption>
<IonItemOption>
<IonIcon slot="icon-only" name="star"></IonIcon>
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon start options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Start
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="start" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="start" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon end options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons End
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="end" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="end" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon top options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Top
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="top" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="top" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
{/* Sliding item with icon bottom options on end side */}
<IonItemSliding>
<IonItem>
<IonLabel>
Sliding Item, Icons Bottom
</IonLabel>
</IonItem>
<IonItemOptions>
<IonItemOption color="primary">
<IonIcon slot="bottom" name="more"></IonIcon>
More
</IonItemOption>
<IonItemOption color="secondary">
<IonIcon slot="bottom" name="archive"></IonIcon>
Archive
</IonItemOption>
</IonItemOptions>
</IonItemSliding>
</IonList>

View File

@ -1,19 +1,145 @@
```html
<template>
<ion-list>
<!-- Sliding item with text options on both sides -->
<ion-item-sliding>
<ion-item>
<ion-label>Item</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option @click="favorite(item)">Favorite</ion-item-option>
<ion-item-option color="danger" @click="share(item)">Share</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Item Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option @click="unread(item)">Unread</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with expandable options on both sides -->
<ion-item-sliding>
<ion-item-options side="start">
<ion-item-option color="danger" expandable>
Delete
</ion-item-option>
</ion-item-options>
<ion-item>
<ion-label>Expandable Options</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="tertiary" expandable>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Multi-line sliding item with icon options on both sides -->
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option>
<ion-icon slot="icon-only" name="heart"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="danger">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option>
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon start options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Start
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="start" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="start" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon end options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons End
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="end" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="end" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon top options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Top
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="top" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="top" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<!-- Sliding item with icon bottom options on end side -->
<ion-item-sliding>
<ion-item>
<ion-label>
Sliding Item, Icons Bottom
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary">
<ion-icon slot="bottom" name="more"></ion-icon>
More
</ion-item-option>
<ion-item-option color="secondary">
<ion-icon slot="bottom" name="archive"></ion-icon>
Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</template>
```

View File

@ -1,10 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
test('item: sliding', async () => {
const page = await newE2EPage({
url: '/src/components/item/test/sliding?ionic:_testing=true'
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});

View File

@ -1,414 +0,0 @@
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta charset="UTF-8">
<title>Item Sliding - Basic</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script src="../../../../../dist/ionic.js"></script>
</head>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Item Sliding - Basic</ion-title>
<ion-buttons slot="secondary">
<ion-button onclick="changeDynamicText()">Dynamic</ion-button>
</ion-buttons>
<ion-buttons slot="primary">
<ion-button onclick="reload()">Reload</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content id="content">
<div padding>
<ion-button expand="block" onclick="toggleSliding()">Toggle sliding</ion-button>
<ion-button expand="block" onclick="toggleDynamicOptions()">Toggle Dynamic Options</ion-button>
<ion-button expand="block" onclick="closeOpened()">Close Opened Items</ion-button>
</div>
<ion-list id="list">
<div class="nested-div">
<ion-item-sliding>
<ion-item>
<ion-label>
<h2>No Options</h2>
<p>Should not error or swipe without options</p>
</ion-label>
</ion-item>
</ion-item-sliding>
<ion-item-sliding id="item6">
<ion-item>
<ion-label>
One Line, dynamic option and text
</ion-label>
</ion-item>
<ion-item-options class="show-options">
<ion-item-option color="primary">
<ion-icon name="more"></ion-icon>
<span class="more-text"></span>
</ion-item-option>
<ion-item-option color="secondary" onclick="archive('item6')">
<ion-icon name="archive"></ion-icon>
<span class="archive-text"></span>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item6">
<ion-item>
<ion-label>
Two options, one dynamic option and text
</ion-label>
</ion-item>
<ion-item-options side="start">
<ion-item-option color="primary">
<ion-icon slot="icon-only" name="more"></ion-icon>
</ion-item-option>
</ion-item-options>
<ion-item-options side="end" class="show-options">
<ion-item-option color="primary">
<ion-icon name="more"></ion-icon>
<span class="more-text"></span>
</ion-item-option>
<ion-item-option color="secondary" onclick="archive('item6')">
<ion-icon name="archive"></ion-icon>
<span class="archive-text"></span>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item100">
<ion-item href="#">
<ion-label>
<h2>HubStruck Notifications</h2>
<p>A new message from a repo in your network</p>
<p>Oceanic Next has joined your network</p>
</ion-label>
<ion-note slot="end">
10:45 AM
</ion-note>
</ion-item>
<ion-item-options side="start">
<ion-item-option onclick="noclose('item100')">
No close
</ion-item-option>
</ion-item-options>
<ion-item-options side="end">
<ion-item-option color="light" onclick="unread('item100')">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
<ion-item-option onclick="unread('item100')">
<ion-icon slot="icon-only" name="star"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item0">
<ion-item onclick="clickedItem('item0')">
<ion-label text-wrap>
<h2>RIGHT side - no icons</h2>
<p>Hey do you want to go to the game tonight?</p>
</ion-label>
</ion-item>
<ion-item-options class="sliding-enabled">
<ion-item-option color="primary" onclick="archive('item0')">Archive</ion-item-option>
<ion-item-option color="danger" onclick="del('item0')">Delete</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item1">
<ion-item detail href="#" class="activated">
<ion-label text-wrap>
<h2>LEFT side - no icons</h2>
<p>I think I figured out how to get more Mountain Dew</p>
</ion-label>
</ion-item>
<ion-item-options side="start" class="sliding-enabled">
<ion-item-option color="primary" onclick="archive('item1')">Archive</ion-item-option>
<ion-item-option color="danger" onclick="del('item1')">Delete</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item2">
<ion-item detail>
<ion-label text-wrap>
<h2>RIGHT/LEFT side - icons</h2>
<p>I think I figured out how to get more Mountain Dew</p>
</ion-label>
</ion-item>
<ion-item-options side="start" class="sliding-enabled">
<ion-item-option color="secondary" expandable onclick="unread('item2')">
<ion-icon name="ios-checkmark"></ion-icon>Unread
</ion-item-option>
</ion-item-options>
<ion-item-options side="end" class="sliding-enabled">
<ion-item-option color="primary" onclick="archive('item2')">
<ion-icon name="mail"></ion-icon>Archive
</ion-item-option>
<ion-item-option color="danger" onclick="del('item2')" expandable>
<ion-icon name="trash"></ion-icon>Delete
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item3">
<ion-item detail>
<ion-label text-wrap>
<h2>RIGHT/LEFT side - icons (slot="start")</h2>
<p>I think I figured out how to get more Mountain Dew</p>
</ion-label>
</ion-item>
<ion-item-options side="start" icon-start class="sliding-enabled">
<ion-item-option color="secondary" expandable onclick="unread('item3')">
<ion-icon name="ios-checkmark"></ion-icon>Unread
</ion-item-option>
</ion-item-options>
<ion-item-options icon-start>
<ion-item-option color="primary" onclick="archive('item3')">
<ion-icon name="mail"></ion-icon>Archive
</ion-item-option>
<ion-item-option color="danger" onclick="del('item3')" expandable class="sliding-enabled">
<ion-icon name="trash"></ion-icon>Delete
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item4">
<ion-item>
<ion-icon name="mail" slot="start"></ion-icon>
<ion-label>
One Line w/ Icon, div only text
</ion-label>
</ion-item>
<ion-item-options icon-start>
<ion-item-option color="primary" onclick="archive('item4')" expandable class="sliding-enabled">
<ion-icon name="archive"></ion-icon>Archive
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item5" class="sliding-enabled">
<ion-item>
<ion-avatar slot="start">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==">
</ion-avatar>
<ion-label>
One Line w/ Avatar, div only text
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary" expandable>
<ion-icon name="more"></ion-icon>More
</ion-item-option>
<ion-item-option color="secondary" onclick="archive('item5')">
<ion-icon name="archive"></ion-icon>Archive
</ion-item-option>
<ion-item-option color="light" onclick="del('item5')">
<ion-icon name="trash"></ion-icon>Delete
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item7">
<ion-item>
<ion-label>
One Line, dynamic icon-start option
</ion-label>
</ion-item>
<ion-item-options icon-start>
<ion-item-option color="primary">
<ion-icon name="more"></ion-icon>
<span class="more-text"></span>
</ion-item-option>
<ion-item-option color="secondary" onclick="archive('item7')">
<ion-icon name="archive"></ion-icon>
<span class="archive-text"></span>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item8">
<ion-item>
<ion-thumbnail slot="start">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==">
</ion-thumbnail>
<ion-label>
<h2>DOWNLOAD</h2>
<p>Paragraph text.</p>
</ion-label>
</ion-item>
<ion-item-options>
<ion-item-option color="primary" onclick="archive('item8')">
<ion-icon name="archive"></ion-icon>Archive
</ion-item-option>
<ion-item-option color="secondary" expandable onclick="download('item8')">
<ion-icon name="download" class="download-hide"></ion-icon>
<div class="download-hide">Download</div>
<ion-icon class="download-spinner" name="refresh"></ion-icon>
<div class="download-spinner">Loading...</div>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
<ion-item-sliding id="item9">
<ion-item>
<ion-thumbnail slot="start">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAAAAACH5BAAAAAAALAAAAAABAAEAAAICTAEAOw==">
</ion-thumbnail>
<ion-label>
<h2>ion-item-sliding without options (no sliding)</h2>
<p>Paragraph text.</p>
</ion-label>
</ion-item>
</ion-item-sliding>
<ion-item>
<ion-label text-wrap>
<h2>Normal ion-item (no sliding)</h2>
<p>Paragraph text.</p>
</ion-label>
</ion-item>
<ion-item onclick="clickedItem('item9')">
<ion-label text-wrap>
<h2>Normal button (no sliding)</h2>
<p>Hey do you want to go to the game tonight?</p>
</ion-label>
</ion-item>
</div>
</ion-list>
<script>
var dynamicSlidingEnabled = document.getElementsByClassName('sliding-enabled');
// Toggle the dynamic options
var dynamicShowOptions = document.getElementsByClassName('show-options');
toggleDynamicOptions();
function toggleDynamicOptions() {
// TODO the element needs to be removed / added to the DOM
}
// Change the text for the more and archive buttons
var dynamicText = true;
var moreTextSpans = document.getElementsByClassName('more-text');
var archiveTextSpans = document.getElementsByClassName('archive-text');
changeDynamicText();
function changeDynamicText() {
dynamicText = !dynamicText;
for (var i = 0; i < moreTextSpans.length; i++) {
var moreText = dynamicText ? 'Changed More' : 'Dynamic More';
moreTextSpans[i].innerHTML = moreText;
}
for (var i = 0; i < archiveTextSpans.length; i++) {
var archiveText = dynamicText ? 'Changed Archive' : 'Dynamic Archive';
archiveTextSpans[i].innerHTML = archiveText;
}
}
function toggleSliding() {
// this.slidingEnabled = !this.slidingEnabled;
}
function closeOpened() {
var list = document.getElementById('list');
list.closeSlidingItems();
}
function noclose(item) {
var itemEle = document.getElementById(item);
console.log('no close', itemEle);
}
function unread(item) {
closeSlidingItem('UNREAD', item);
}
function archive(item) {
closeSlidingItem('ARCHIVE', item);
}
function del(item) {
closeSlidingItem('DELETE', item);
}
function download(item) {
var itemEle = document.getElementById(item);
console.log(itemEle);
itemEle.classList.add('downloading');
setTimeout(() => {
alert('Item was downloaded!');
itemEle.classList.remove('downloading');
itemEle.close();
}, 1500);
}
function closeSlidingItem(option, item) {
var itemEle = document.getElementById(item);
// TODO open alert instead
if (itemEle) {
itemEle.close();
}
console.log(option, itemEle);
}
function clickedItem(item) {
var itemEle = document.getElementById(item);
console.log('Clicked, ion-item', itemEle);
}
function reload() {
window.location.reload();
}
document.addEventListener('ionSwipe', (ev) => console.log('SWIPE!!', ev.target));
document.addEventListener('ionDrag', (ev) => console.log('DRAG!!', ev.target.getOpenAmount()));
</script>
<style>
.download-spinner {
display: none;
}
svg circle {
stroke: white;
}
.downloading .download-spinner {
display: block;
}
.downloading .download-hide {
display: none;
}
</style>
</ion-content>
</ion-app>
</body>
</html>

View File

@ -18,7 +18,7 @@ export async function testLoading(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
await page.click(selector);
await page.waitForSelector(selector);
@ -28,18 +28,18 @@ export async function testLoading(
await loading.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await loading.callMethod('dismiss');
await loading.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
loading = await page.find('ion-loading');
expect(loading).toBeNull();
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {

View File

@ -18,22 +18,22 @@ export async function testMenu(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
const menu = await page.find(selector);
await menu.callMethod('open');
await page.waitFor(250);
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await menu.callMethod('close');
await page.waitFor(250);
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {
throw err;

View File

@ -18,7 +18,7 @@ export async function testModal(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
await page.click(selector);
await page.waitForSelector(selector);
@ -26,18 +26,18 @@ export async function testModal(
let popover = await page.find('ion-modal');
await popover.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await popover.callMethod('dismiss');
await popover.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
popover = await page.find('ion-modal');
expect(popover).toBeNull();
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {

View File

@ -18,7 +18,7 @@ export async function testPopover(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
await page.click(selector);
await page.waitForSelector(selector);
@ -26,18 +26,18 @@ export async function testPopover(
let popover = await page.find('ion-popover');
await popover.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await popover.callMethod('dismiss');
await popover.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
popover = await page.find('ion-popover');
expect(popover).toBeNull();
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {

View File

@ -18,7 +18,7 @@ export async function testToast(
url: pageUrl
});
const screenShotCompares = [];
const screenshotCompares = [];
const button = await page.find(selector);
await button.click();
@ -26,18 +26,18 @@ export async function testToast(
let toast = await page.find('ion-toast');
await toast.waitForVisible();
screenShotCompares.push(await page.compareScreenshot(screenshotName));
screenshotCompares.push(await page.compareScreenshot(screenshotName));
await toast.callMethod('dismiss');
await toast.waitForNotVisible();
screenShotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
screenshotCompares.push(await page.compareScreenshot(`dismiss ${screenshotName}`));
toast = await page.find('ion-toast');
expect(toast).toBeNull();
for (const screenShotCompare of screenShotCompares) {
expect(screenShotCompare).toMatchScreenshot();
for (const screenshotCompare of screenshotCompares) {
expect(screenshotCompare).toMatchScreenshot();
}
} catch (err) {