chore(): sync feature-7.0 with main

chore(): sync feature-7.0 with main
This commit is contained in:
Liam DeBeasi
2022-09-23 17:01:55 -05:00
committed by GitHub
169 changed files with 679 additions and 1135 deletions

2
.github/CODEOWNERS vendored
View File

@@ -12,4 +12,4 @@
# This should make it easy to add new rules without breaking existing ones.
# Global owners
* @ionic-team/framework-core
* @ionic-team/framework

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.2.8](https://github.com/ionic-team/ionic-framework/compare/v6.2.7...v6.2.8) (2022-09-21)
### Bug Fixes
* **datetime:** account for 12AM with min times and 12 hour format ([#25952](https://github.com/ionic-team/ionic-framework/issues/25952)) ([55ebd6c](https://github.com/ionic-team/ionic-framework/commit/55ebd6cdf39c01b401e876b76e755bfa04db8f65)), closes [#25183](https://github.com/ionic-team/ionic-framework/issues/25183)
* **item:** show the highlight on iOS when --highlight-height is set ([#25905](https://github.com/ionic-team/ionic-framework/issues/25905)) ([d7db133](https://github.com/ionic-team/ionic-framework/commit/d7db1333f13834ecb447b4b1da62cfffed9fb333))
* **overlays:** focus trapping no longer includes disabled elements ([#25949](https://github.com/ionic-team/ionic-framework/issues/25949)) ([6cb5827](https://github.com/ionic-team/ionic-framework/commit/6cb5827d069c255ab0a9a8c319aba9994a4c5196))
* **overlays:** focus trapping no longer includes hidden elements ([#25948](https://github.com/ionic-team/ionic-framework/issues/25948)) ([5c10f98](https://github.com/ionic-team/ionic-framework/commit/5c10f98ceb3ae42d3363b38ba786b9122676a59c))
### Performance Improvements
* **card:** avoid force compositing on ios ([#25942](https://github.com/ionic-team/ionic-framework/issues/25942)) ([174c3b3](https://github.com/ionic-team/ionic-framework/commit/174c3b30a0bce7e7ab13e5605348ec107af69dd6))
## [6.2.7](https://github.com/ionic-team/ionic-framework/compare/v6.2.6...v6.2.7) (2022-09-14)

View File

@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.2.8](https://github.com/ionic-team/ionic/compare/v6.2.7...v6.2.8) (2022-09-21)
**Note:** Version bump only for package @ionic/angular
## [6.2.7](https://github.com/ionic-team/ionic/compare/v6.2.6...v6.2.7) (2022-09-14)

View File

@@ -1,15 +1,15 @@
{
"name": "@ionic/angular",
"version": "6.2.7",
"version": "6.2.8",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/angular",
"version": "6.2.7",
"version": "6.2.8",
"license": "MIT",
"dependencies": {
"@ionic/core": "^6.2.7",
"@ionic/core": "^6.2.8",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},
@@ -1023,9 +1023,9 @@
"dev": true
},
"node_modules/@ionic/core": {
"version": "6.2.7",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.7.tgz",
"integrity": "sha512-pQWcIqr5zfCX5De/MQ9kFs+nhaPCr8HIh5QjmydxvmlLv6WU4vlny/Mg0y1+JwLE0qxPD0T9sMykawWH9e3y5Q==",
"version": "6.2.8",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.8.tgz",
"integrity": "sha512-tUUdvCPo9Z4RQXjvxNXBXQsVTFDAH2ju/HAhzZiAvdfwpHfpA39DWkXwAQeoV9gfFFblaOmCmeSq/8JP/FRn4A==",
"dependencies": {
"@stencil/core": "^2.17.4",
"ionicons": "^6.0.3",
@@ -7951,9 +7951,9 @@
"dev": true
},
"@ionic/core": {
"version": "6.2.7",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.7.tgz",
"integrity": "sha512-pQWcIqr5zfCX5De/MQ9kFs+nhaPCr8HIh5QjmydxvmlLv6WU4vlny/Mg0y1+JwLE0qxPD0T9sMykawWH9e3y5Q==",
"version": "6.2.8",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.2.8.tgz",
"integrity": "sha512-tUUdvCPo9Z4RQXjvxNXBXQsVTFDAH2ju/HAhzZiAvdfwpHfpA39DWkXwAQeoV9gfFFblaOmCmeSq/8JP/FRn4A==",
"requires": {
"@stencil/core": "^2.17.4",
"ionicons": "^6.0.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/angular",
"version": "6.2.7",
"version": "6.2.8",
"description": "Angular specific wrappers for @ionic/core",
"keywords": [
"ionic",
@@ -44,7 +44,7 @@
"validate": "npm i && npm run lint && npm run test && npm run build"
},
"dependencies": {
"@ionic/core": "^6.2.7",
"@ionic/core": "^6.2.8",
"jsonc-parser": "^3.0.0",
"tslib": "^2.0.0"
},

View File

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.2.8](https://github.com/ionic-team/ionic/compare/v6.2.7...v6.2.8) (2022-09-21)
### Bug Fixes
* **datetime:** account for 12AM with min times and 12 hour format ([#25952](https://github.com/ionic-team/ionic/issues/25952)) ([55ebd6c](https://github.com/ionic-team/ionic/commit/55ebd6cdf39c01b401e876b76e755bfa04db8f65)), closes [#25183](https://github.com/ionic-team/ionic/issues/25183)
* **item:** show the highlight on iOS when --highlight-height is set ([#25905](https://github.com/ionic-team/ionic/issues/25905)) ([d7db133](https://github.com/ionic-team/ionic/commit/d7db1333f13834ecb447b4b1da62cfffed9fb333))
* **overlays:** focus trapping no longer includes disabled elements ([#25949](https://github.com/ionic-team/ionic/issues/25949)) ([6cb5827](https://github.com/ionic-team/ionic/commit/6cb5827d069c255ab0a9a8c319aba9994a4c5196))
* **overlays:** focus trapping no longer includes hidden elements ([#25948](https://github.com/ionic-team/ionic/issues/25948)) ([5c10f98](https://github.com/ionic-team/ionic/commit/5c10f98ceb3ae42d3363b38ba786b9122676a59c))
### Performance Improvements
* **card:** avoid force compositing on ios ([#25942](https://github.com/ionic-team/ionic/issues/25942)) ([174c3b3](https://github.com/ionic-team/ionic/commit/174c3b30a0bce7e7ab13e5605348ec107af69dd6))
## [6.2.7](https://github.com/ionic-team/ionic/compare/v6.2.6...v6.2.7) (2022-09-14)

View File

@@ -1,12 +1,12 @@
{
"name": "@ionic/core",
"version": "6.2.7",
"version": "6.2.8",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@ionic/core",
"version": "6.2.7",
"version": "6.2.8",
"license": "MIT",
"dependencies": {
"@stencil/core": "^2.17.4",

View File

@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "6.2.7",
"version": "6.2.8",
"description": "Base components for Ionic",
"keywords": [
"ionic",

View File

@@ -0,0 +1,12 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('card-header: basic', () => {
test('should not have visual regressions', async ({ page }) => {
await page.goto(`/src/components/card-header/test/basic`);
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`card-header-diff-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View File

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

View File

@@ -47,14 +47,6 @@
</ion-card-header>
<ion-card-content> Custom background, color=secondary on ion-card-header </ion-card-content>
</ion-card>
<ion-card color="danger">
<ion-card-header>
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
<ion-card-title>Card Title</ion-card-title>
</ion-card-header>
<ion-card-content> color=danger on ion-card-header </ion-card-content>
</ion-card>
</ion-content>
</ion-app>
<style>

View File

@@ -0,0 +1,15 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('content: basic', () => {
test('should not have visual regressions', async ({ page, skip }) => {
skip.rtl();
skip.mode('ios', 'ion-content does not have mode-specific styling');
await page.goto(`/src/components/content/test/basic`);
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`content-diff-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

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

View File

@@ -29,7 +29,6 @@
<ion-content class="ion-padding" style="text-align: center; flex: 2" id="content">
<ion-content id="content-part">
<f style="height: 50%"></f>
<ion-button onclick="toggleFullscreen()">Toggle content.fullscreen</ion-button>
<p>
<ion-button onclick="toggleDisplay('header')" color="secondary">Toggle header</ion-button>
<ion-button onclick="toggleDisplay('footer')" color="secondary">Toggle footer</ion-button>
@@ -45,11 +44,6 @@
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
<f></f>
</ion-content>
</ion-content>
<ion-content class="ion-padding" style="display: none" id="content3">
@@ -79,16 +73,7 @@
<script>
const content = document.getElementById('content');
content.scrollEvents = true;
content.addEventListener('ionScrollStart', () => console.log('scroll start'));
content.addEventListener('ionScroll', (ev) => console.log('scroll', ev.detail));
content.addEventListener('ionScrollEnd', () => console.log('scroll end'));
function toggleFullscreen() {
const content = document.getElementById('content');
content.fullscreen = !content.fullscreen;
console.log('content.fullscren =', content.fullscreen);
}
function toggleDisplay(id) {
const el = document.getElementById(id);
el.style.display = !el.style.display ? 'none' : null;

View File

@@ -0,0 +1,14 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('content: fixed', () => {
test('should not have visual regressions', async ({ page, skip }) => {
skip.mode('ios', 'ion-content does not have mode-specific styling');
await page.goto(`/src/components/content/test/fixed`);
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`content-fixed-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

View File

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

View File

@@ -27,7 +27,7 @@
<div slot="fixed">
<h1>Fixed content</h1>
<p>Fixed paragraph</p>
<ion-button>Button</ion-button>
<ion-button>Fixed button</ion-button>
</div>
<ion-fab vertical="top" horizontal="end" slot="fixed">
<ion-fab-button>

View File

@@ -0,0 +1,15 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('content: fullscreen', () => {
test('should not have visual regressions', async ({ page, skip }) => {
skip.rtl();
skip.mode('ios', 'ion-content does not have mode-specific styling');
await page.goto(`/src/components/content/test/fullscreen`);
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`content-fullscreen-${page.getSnapshotSettings()}.png`);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 920 KiB

View File

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

View File

@@ -49,18 +49,6 @@
Integer luctus faucibus nunc, non mattis nisl consectetur at. Interdum et malesuada fames ac ante ipsum primis
in faucibus.
</p>
<p>
Suspendisse et arcu nec odio lobortis lacinia a congue ligula. Duis libero lacus, blandit ac lectus et,
laoreet condimentum est. Suspendisse potenti. Praesent ligula dui, laoreet sed pellentesque vitae, congue at
leo. Mauris pharetra, tellus vel viverra viverra, tellus felis mollis magna, volutpat pharetra augue nunc a
dolor. Donec ex turpis, iaculis id consectetur quis, posuere a purus. Morbi eu massa sed erat tristique
hendrerit. Morbi eleifend, nisi eleifend condimentum euismod, lacus erat porta arcu, consequat rutrum ipsum
arcu at metus. Sed tellus nulla, pellentesque sit amet justo at, venenatis imperdiet dui. Aenean odio eros,
posuere at dui pharetra, laoreet posuere nulla. Vestibulum interdum odio eu odio ornare, quis maximus lacus
semper. Quisque purus dolor, ullamcorper mollis lorem at, sodales aliquet velit. Interdum et malesuada fames
ac ante ipsum primis in faucibus. Vivamus purus felis, elementum ut est ut, finibus sagittis tellus. Etiam
neque mauris, lobortis sed orci in, dictum eleifend turpis. Morbi eu odio quis mauris gravida tristique.
</p>
<p>
Vestibulum blandit quam a odio lobortis dictum. Nulla pellentesque mauris ornare neque ultricies sagittis.
Aenean molestie placerat fermentum. Morbi ac tortor vel felis imperdiet suscipit. Ut id pellentesque nulla.

View File

@@ -0,0 +1,15 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('content: standalone', () => {
test('should not have visual regressions', async ({ page, skip }) => {
skip.rtl();
skip.mode('ios', 'ion-content does not have mode-specific styling');
await page.goto(`/src/components/content/test/standalone`);
expect(await page.screenshot({ fullPage: true })).toMatchSnapshot(
`content-standalone-${page.getSnapshotSettings()}.png`
);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

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

View File

@@ -53,46 +53,11 @@
</ion-content>
</div>
<div class="content-height">
<ion-content class="ion-padding outer-content">
<h1>Heading</h1>
<h2>Heading</h2>
<h3>Heading</h3>
<hr />
<h4>Heading</h4>
<h5>Heading</h5>
<h6>Heading</h6>
<p>Paragraph</p>
</ion-content>
</div>
<div class="content-height">
<ion-content class="ion-padding outer-content">
<h1>Heading</h1>
<h2>Heading</h2>
<h3>Heading</h3>
<hr />
<h4>Heading</h4>
<h5>Heading</h5>
<h6>Heading</h6>
<p>Paragraph</p>
</ion-content>
</div>
<style>
.content-height {
height: 200px;
}
/* TODO should this be in content? */
ion-content {
height: 100%;
}
.outer-content {
--background: #f2f2f2;
}
.custom-color {
--background: blue;
--color: white;

View File

@@ -45,6 +45,7 @@ import {
getPreviousWeek,
getPreviousYear,
getStartOfWeek,
validateParts,
} from './utils/manipulation';
import {
clampDate,
@@ -583,6 +584,19 @@ export class Datetime implements ComponentInterface {
private setActiveParts = (parts: DatetimeParts, removeDate = false) => {
const { multiple, activePartsClone, highlightActiveParts } = this;
/**
* When setting the active parts, it is possible
* to set invalid data. For example,
* when updating January 31 to February,
* February 31 does not exist. As a result
* we need to validate the active parts and
* ensure that we are only setting valid dates.
* Additionally, we need to update the working parts
* too in the event that the validated parts are different.
*/
const validatedParts = validateParts(parts);
this.setWorkingParts(validatedParts);
if (multiple) {
/**
* We read from activePartsClone here because valueChanged() only updates that,
@@ -595,20 +609,20 @@ export class Datetime implements ComponentInterface {
*/
const activePartsArray = Array.isArray(activePartsClone) ? activePartsClone : [activePartsClone];
if (removeDate) {
this.activeParts = activePartsArray.filter((p) => !isSameDay(p, parts));
this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
} else if (highlightActiveParts) {
this.activeParts = [...activePartsArray, parts];
this.activeParts = [...activePartsArray, validatedParts];
} else {
/**
* If highlightActiveParts is false, that means we just have a
* default value of today in activeParts; we need to replace that
* rather than adding to it since it's just a placeholder.
*/
this.activeParts = [parts];
this.activeParts = [validatedParts];
}
} else {
this.activeParts = {
...parts,
...validatedParts,
};
}

View File

@@ -63,7 +63,7 @@ describe('generateTime()', () => {
};
const { hours, minutes } = generateTime(today, 'h12', min);
expect(hours.length).toEqual(11);
expect(hours.length).toEqual(10);
expect(minutes.length).toEqual(60);
});
it('should not filter according to min if not on reference day', () => {
@@ -103,7 +103,7 @@ describe('generateTime()', () => {
};
const { hours, minutes } = generateTime(today, 'h12', undefined, max);
expect(hours.length).toEqual(7);
expect(hours.length).toEqual(8);
expect(minutes.length).toEqual(45);
});
it('should not filter according to min if not on reference day', () => {

View File

@@ -0,0 +1,48 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('datetime: switching months with different number of days', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl();
skip.mode('ios');
await page.setContent(`
<ion-datetime locale="en-US" presentation="date" value="2022-01-31"></ion-datetime>
`);
await page.waitForSelector('.datetime-ready');
});
test('should switch the calendar header when moving to a month with a different number of days', async ({ page }) => {
const monthYearToggle = page.locator('ion-datetime .calendar-month-year');
const monthColumnItems = page.locator('ion-datetime .month-column .picker-item:not(.picker-item-empty)');
await expect(monthYearToggle).toContainText('January 2022');
await monthYearToggle.click();
await page.waitForChanges();
// February
await monthColumnItems.nth(1).click();
await page.waitForChanges();
await expect(monthYearToggle).toContainText('February 2022');
});
test('should adjust the selected day when moving to a month with a different number of days', async ({ page }) => {
const monthYearToggle = page.locator('ion-datetime .calendar-month-year');
const monthColumnItems = page.locator('ion-datetime .month-column .picker-item:not(.picker-item-empty)');
const datetime = page.locator('ion-datetime');
const ionChange = await page.spyOnEvent('ionChange');
await monthYearToggle.click();
await page.waitForChanges();
// February
await monthColumnItems.nth(1).click();
await ionChange.next();
await expect(ionChange).toHaveReceivedEventTimes(1);
await expect(datetime).toHaveJSProperty('value', '2022-02-28');
});
});

View File

@@ -57,7 +57,7 @@ describe('getMonthAndDay()', () => {
describe('getFormattedHour()', () => {
it('should only add padding if using 24 hour time', () => {
expect(getFormattedHour(0, true)).toEqual('00');
expect(getFormattedHour(0, false)).toEqual('0');
expect(getFormattedHour(0, false)).toEqual('12');
expect(getFormattedHour(10, true)).toEqual('10');
expect(getFormattedHour(10, false)).toEqual('10');

View File

@@ -188,4 +188,50 @@ test.describe('datetime: minmax', () => {
await expect(datetimeMonthDidChange).toHaveReceivedEventTimes(1);
});
test('should not include 12AM when minimum is greater than 12AM', async ({ page, skip }) => {
skip.rtl();
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/25183',
});
await page.setContent(`
<ion-datetime
presentation="time"
min="2022-04-25T08:30:00"
max="2022-04-25T21:30:00"
value="2022-04-25T08:30:00"
></ion-datetime>
`);
const hourPickerItems = page.locator(
'ion-datetime ion-picker-column-internal:first-of-type .picker-item:not(.picker-item-empty)'
);
await expect(hourPickerItems).toHaveText(['8', '9', '10', '11']);
});
test('should include 12PM when minimum is greater than 12', async ({ page, skip }) => {
skip.rtl();
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/25183',
});
await page.setContent(`
<ion-datetime
locale="en-US"
presentation="time"
min="2022-07-29T08:00:00"
value="2022-07-29T12:00:00"
></ion-datetime>
`);
const hourPickerItems = page.locator(
'ion-datetime ion-picker-column-internal:first-of-type .picker-item:not(.picker-item-empty)'
);
await expect(hourPickerItems).toHaveText(['12', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11']);
});
});

View File

@@ -44,7 +44,7 @@ const minutes = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
];
const hour12 = [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
const hour12 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
const hour23 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
/**

View File

@@ -49,16 +49,26 @@ export const addTimePadding = (value: number): string => {
};
/**
* Formats the hour value so that it
* is always 2 digits. Only applies
* if using 12 hour format.
* Formats 24 hour times so that
* it always has 2 digits. For
* 12 hour times it ensures that
* hour 0 is formatted as '12'.
*/
export const getFormattedHour = (hour: number, use24Hour: boolean): string => {
if (!use24Hour) {
return hour.toString();
if (use24Hour) {
return addTimePadding(hour);
}
return addTimePadding(hour);
/**
* If using 12 hour
* format, make sure hour
* 0 is formatted as '12'.
*/
if (hour === 0) {
return '12';
}
return hour.toString();
};
/**

View File

@@ -339,3 +339,27 @@ export const calculateHourFromAMPM = (currentParts: DatetimeParts, newAMPM: 'am'
return newHour;
};
/**
* Updates parts to ensure that month and day
* values are valid. For days that do not exist,
* the closest valid day is used.
*/
export const validateParts = (parts: DatetimeParts): DatetimeParts => {
const { month, day, year } = parts;
const partsCopy = { ...parts };
const numDays = getNumDaysInMonth(month, year);
/**
* If the max number of days
* is greater than the day we want
* to set, update the DatetimeParts
* day field to be the max days.
*/
if (day !== null && numDays < day) {
partsCopy.day = numDays;
}
return partsCopy;
};

View File

@@ -0,0 +1,16 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('fab-button: aria attributes', () => {
test('should inherit aria attributes to inner button', async ({ page, skip }) => {
skip.rtl();
skip.mode('ios');
await page.setContent(`
<ion-fab-button aria-label="Hello World">My Button</ion-fab-button>
`);
const nativeButton = page.locator('ion-fab-button button');
await expect(nativeButton).toHaveAttribute('aria-label', 'Hello World');
});
});

View File

@@ -1,19 +0,0 @@
import { newSpecPage } from '@stencil/core/testing';
import { FabButton } from '../fab-button';
describe('fab-button: aria attributes', () => {
it('should inherit aria attributes to inner <button>', async () => {
const page = await newSpecPage({
components: [FabButton],
html: `
<ion-fab-button aria-label="Hello World">My Button</ion-fab-button>
`,
});
const fabButton = page.body.querySelector('ion-fab-button');
const root = fabButton.shadowRoot;
const nativeButton = root.querySelector('button');
expect(nativeButton.getAttribute('aria-label')).toEqual('Hello World');
});
});

View File

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

View File

@@ -1,142 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Floating Action Button - Standalone</title>
<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>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<h3>Default</h3>
<p>
<ion-fab-button>Default</ion-fab-button>
<ion-fab-button><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button size="small">Mini</ion-fab-button>
<ion-fab-button size="small"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button class="fab-button-in-list">In List</ion-fab-button>
<ion-fab-button class="fab-button-in-list"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button size="small" class="fab-button-in-list"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button class="fab-button-in-list ion-activated"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button size="small" class="fab-button-in-list ion-activated"
><ion-icon name="star"></ion-icon
></ion-fab-button>
</p>
<h3>Colors</h3>
<p>
<ion-fab-button color="primary"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="secondary"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="tertiary"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="success"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="warning"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="danger"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="light"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="medium"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button color="dark"><ion-icon name="heart"></ion-icon></ion-fab-button>
</p>
<p>
<ion-fab-button color="primary" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="secondary" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="tertiary" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="success" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="warning" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="danger" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="light" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="medium" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="dark" class="ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
</p>
<h3>Custom</h3>
<!-- Custom Font -->
<ion-fab-button class="large">large</ion-fab-button>
<!-- Custom Colors -->
<ion-fab-button class="custom"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button class="custom ion-activated"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button color="secondary" class="custom"><ion-icon name="heart"></ion-icon></ion-fab-button>
<!-- Custom Colors Fab In List -->
<ion-fab-button class="fab-button-in-list custom-white">White</ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-white ion-activated">White</ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-white"><ion-icon name="heart"></ion-icon></ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-white ion-activated"
><ion-icon name="heart"></ion-icon
></ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-blue"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-blue ion-activated"
><ion-icon name="star"></ion-icon
></ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-border">Border</ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-border ion-activated">Border</ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-border"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-button class="fab-button-in-list custom-border ion-activated"
><ion-icon name="star"></ion-icon
></ion-fab-button>
<ion-fab slot="fixed" horizontal="center" vertical="bottom">
<ion-fab-button class="custom-close"><ion-icon name="star"></ion-icon></ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button>
<ion-icon name="heart"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="square"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="triangle"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<style>
ion-fab-button {
display: inline-block;
margin-bottom: 5px;
}
.large {
font-size: 24px;
}
.custom {
--background: lightpink;
--background-activated: green;
--color: blue;
--color-activated: white;
}
.custom-white {
--background: white;
--background-activated: #f6f6f6;
}
.custom-blue {
--background: #add8e6;
--background-activated: #7cb2c4;
}
.custom-border {
--border-radius: 10px;
--border-width: 2px;
--border-style: dashed;
--border-color: red;
}
.custom-close::part(close-icon) {
color: red;
font-size: 44px;
}
</style>
</body>
</html>

View File

@@ -1,17 +0,0 @@
import { testDisabledFab, testFab } from '../test.utils';
test('fab: basic', async () => {
await testFab('basic', '#fab1');
});
test('fab:rtl: basic', async () => {
await testFab('basic', '#fab1', true);
});
test('fab: disabled', async () => {
await testDisabledFab('basic', '#fab2');
});
test('fab:rtl: disabled', async () => {
await testDisabledFab('basic', '#fab2', true);
});

View File

@@ -0,0 +1,72 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('fab: basic (visual checks)', () => {
test.beforeEach(async ({ page }) => {
await page.goto(`/src/components/fab/test/basic`);
});
test('should not have visual regressions', async ({ page }) => {
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`fab-basic-${page.getSnapshotSettings()}.png`);
});
test('should not have visual regressions when open', async ({ page }) => {
// this fab has multiple buttons on each side, so it covers all the bases
const fab = page.locator('#fab5');
await fab.click();
await page.waitForChanges();
/**
* fab.screenshot doesn't work since ion-fab's bounding box only covers the
* central button. This viewport size crops extra white space while also
* containing all the buttons in the open fab.
*/
await page.setViewportSize({
width: 320,
height: 415,
});
expect(await page.screenshot()).toMatchSnapshot(`fab-open-${page.getSnapshotSettings()}.png`);
});
});
test.describe('fab: basic (functionality checks)', () => {
test.beforeEach(async ({ page, skip }) => {
skip.rtl();
skip.mode('ios');
await page.goto(`/src/components/fab/test/basic`);
});
test('should toggle active state when clicked', async ({ page }) => {
const fab = page.locator('#fab1');
const fabList = fab.locator('ion-fab-list');
expect(fabList).not.toHaveClass(/fab-list-active/);
// open fab
await fab.click();
await page.waitForChanges();
expect(fabList).toHaveClass(/fab-list-active/);
// close fab
await fab.click();
await page.waitForChanges();
expect(fabList).not.toHaveClass(/fab-list-active/);
});
test('should not open when disabled', async ({ page }) => {
const fab = page.locator('#fab2');
const fabList = fab.locator('ion-fab-list');
expect(fabList).not.toHaveClass(/fab-list-active/);
// attempt to open fab
await fab.click();
await page.waitForChanges();
expect(fabList).not.toHaveClass(/fab-list-active/);
});
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 151 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

View File

@@ -26,117 +26,108 @@
<f></f>
<f></f>
<pre id="log" style="right: 10px; bottom: 50px; text-shadow: 0 0 2px rgba(0, 0, 0, 0.24)" slot="fixed">log</pre>
<ion-button>Test</ion-button>
<ion-fab-button disabled href="#path" onclick="throw 'no clickable'">FAB</ion-fab-button>
<ion-fab vertical="top" horizontal="end" edge id="fab1" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab1')" size="small" class="e2eFabTopRight">
<ion-fab-button size="small" class="e2eFabTopRight">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
<ion-fab-list>
<ion-fab-button onclick="openSocial('facebook', 'fab1')">
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('twitter', 'fab1')">
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('vimeo', 'fab1')">
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('instagram', 'fab1')">
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<ion-fab vertical="bottom" horizontal="end" edge id="fab2" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab2')" color="dark" class="e2eFabBottomRight" disabled>
<ion-icon name="arrow-back-circle"></ion-icon>
<ion-fab vertical="bottom" horizontal="start" edge id="fab2" slot="fixed">
<ion-fab-button color="dark" class="e2eFabBottomRight" disabled>
<ion-icon name="arrow-up-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="start">
<ion-fab-button onclick="openSocial('facebook', 'fab2')">
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('twitter', 'fab2')">
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('vimeo', 'fab2')">
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('instagram', 'fab2')">
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<ion-fab vertical="top" horizontal="start" id="fab3" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab3')" color="secondary" class="e2eFabTopLeft">
<ion-fab-button color="secondary" class="e2eFabTopLeft">
<ion-icon name="arrow-forward-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="end">
<ion-fab-button onclick="openSocial('facebook', 'fab3')">
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('twitter', 'fab3')">
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('vimeo', 'fab3')">
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('instagram', 'fab3')">
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<ion-fab vertical="bottom" horizontal="start" id="fab4" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab4')" color="light" class="e2eFabBottomLeft">
<ion-icon name="arrow-up-circle"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('facebook', 'fab4')">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('twitter', 'fab4')">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('vimeo', 'fab4')">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button onclick="openSocial('instagram', 'fab4')">
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<ion-fab vertical="center" horizontal="center" id="fab5" slot="fixed">
<ion-fab-button onclick="clickMainFAB('fab5')" class="e2eFabCenter">
<ion-fab-button class="e2eFabCenter">
<ion-icon name="share"></ion-icon>
</ion-fab-button>
<ion-fab-list side="top">
<ion-fab-button onclick="openSocial('vimeo', 'fab5')" color="primary">
<ion-fab-button color="primary">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="bottom">
<ion-fab-button onclick="openSocial('facebook', 'fab5')" color="secondary">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="start">
<ion-fab-button onclick="openSocial('instagram', 'fab5')" color="light">
<ion-fab-button color="light">
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="end">
<ion-fab-button onclick="openSocial('twitter', 'fab5')" color="dark">
<ion-fab-list side="bottom">
<ion-fab-button color="secondary">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
<ion-fab-button color="dark">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="start">
<ion-fab-button color="light">
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
<ion-fab-button color="primary">
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
</ion-fab-list>
<ion-fab-list side="end">
<ion-fab-button color="dark">
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button color="secondary">
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<ion-fab horizontal="end" vertical="center" slot="fixed">
<ion-fab horizontal="end" vertical="bottom" slot="fixed">
<ion-fab-button color="danger" onclick="add()">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
@@ -157,28 +148,10 @@
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}
function insertLog(message) {
console.log(message);
var el = document.querySelector('#log');
const oldHTML = el.innerHTML;
el.innerHTML = oldHTML + '\n' + message;
}
function add() {
var newEle = document.createElement('f');
var ref = document.querySelector('f');
insertAfter(newEle, ref);
insertLog('add');
}
function clickMainFAB(container) {
let message = 'Clicked open social menu';
insertLog(message);
}
function openSocial(network, container) {
let message = 'Share in ' + network;
insertLog(message);
}
function closeLists() {

View File

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

View File

@@ -1,78 +0,0 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Floating Action Button - Standalone</title>
<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>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<body>
<ion-fab-button href="https://ionicframework.com">
<ion-icon name="logo-ionitron"></ion-icon>
</ion-fab-button>
<ion-fab-button href="https://ionicframework.com" target="_blank">
<ion-icon name="logo-ionitron"></ion-icon>
</ion-fab-button>
<ion-button href="https://ionicframework.com" target="_blank">
<ion-icon name="logo-ionitron"></ion-icon>
</ion-button>
<script>
function insertAfter(el, referenceNode) {
referenceNode.parentNode.insertBefore(el, referenceNode.nextSibling);
}
function add() {
var newEle = document.createElement('f');
var ref = document.querySelector('f');
insertAfter(newEle, ref);
console.log('add');
}
function clickMainFAB(container) {
let message = 'Clicked open social menu';
console.log(message);
openLists(container);
}
function openSocial(network, container) {
let message = 'Share in ' + network;
console.log(message);
openLists(container);
}
function openLists(container) {
var fabLists = document.getElementById(container).querySelectorAll('ion-fab-list');
for (var i = 0; i < fabLists.length; i++) {
fabLists[i].activated = true;
}
}
</script>
<style>
f {
display: block;
margin: 15px auto;
max-width: 150px;
height: 150px;
background: blue;
}
f:last-of-type {
background: yellow;
}
</style>
</body>
</html>

View File

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

View File

@@ -0,0 +1,11 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test('should not have visual regressions', async ({ page, skip }) => {
skip.rtl();
await page.goto(`/src/components/fab/test/states`);
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`fab-states-${page.getSnapshotSettings()}.png`);
});

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 KiB

View File

@@ -17,26 +17,6 @@
<body>
<ion-app>
<ion-content>
<ion-fab slot="fixed" horizontal="end">
<ion-fab-button>
<ion-icon name="share-social"></ion-icon>
</ion-fab-button>
<ion-fab-list side="bottom">
<ion-fab-button>
<ion-icon name="logo-vimeo"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-instagram"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-twitter"></ion-icon>
</ion-fab-button>
<ion-fab-button>
<ion-icon name="logo-facebook"></ion-icon>
</ion-fab-button>
</ion-fab-list>
</ion-fab>
<h3>Default</h3>
<p>
<ion-fab-button>
@@ -169,18 +149,6 @@
</ion-content>
</ion-app>
<script>
var buttons = document.querySelectorAll('ion-fab-button');
for (var i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', (event) => onClick(event));
}
function onClick(ev) {
console.log('clicked the button', ev.target.innerText);
}
</script>
<style>
h3 {
padding-left: 16px;

Some files were not shown because too many files have changed in this diff Show More