merge release-6.3.1

Release 6.3.1
This commit is contained in:
Liam DeBeasi
2022-10-12 10:06:50 -05:00
committed by GitHub
81 changed files with 696 additions and 366 deletions

View File

@ -55,6 +55,15 @@ jobs:
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash shell: bash
# Lerna does not automatically bump versions
# of Ionic dependencies that have changed,
# so we do that here.
- name: Bump Package Lock
run: |
lerna exec "npm install --package-lock-only --legacy-peer-deps"
git add .
git commit -m "chore(): update package lock files"
git push
# Purge the JSDeliver CDN cache so # Purge the JSDeliver CDN cache so
# component playgrounds always load # component playgrounds always load
# the latest version of Ionic. # the latest version of Ionic.

View File

@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic-framework/compare/v6.3.0...v6.3.1) (2022-10-12)
### Bug Fixes
* **datetime:** setting date async updates calendar grid ([#26070](https://github.com/ionic-team/ionic-framework/issues/26070)) ([0aee328](https://github.com/ionic-team/ionic-framework/commit/0aee328b4b84d5668752e5ae0792334d0173c2bb)), closes [#25776](https://github.com/ionic-team/ionic-framework/issues/25776)
* **datetime:** setting max/min does not increase number of nodes rendered ([#26065](https://github.com/ionic-team/ionic-framework/issues/26065)) ([a5d178f](https://github.com/ionic-team/ionic-framework/commit/a5d178f4c03a0ad2501095afe1f75914b0462ae1)), closes [#26059](https://github.com/ionic-team/ionic-framework/issues/26059)
* **item, card:** aria-label is reflected to the inner button ([#26028](https://github.com/ionic-team/ionic-framework/issues/26028)) ([3c89ebe](https://github.com/ionic-team/ionic-framework/commit/3c89ebe7216b2a19580a4f1ed23d5d1d4c37919d)), closes [#25885](https://github.com/ionic-team/ionic-framework/issues/25885)
* **toolbar:** MD height only applies to MD segment ([#26042](https://github.com/ionic-team/ionic-framework/issues/26042)) ([ab89679](https://github.com/ionic-team/ionic-framework/commit/ab8967936c6bef5fc0a884cb8bf8f2deb7784c13)), closes [#18617](https://github.com/ionic-team/ionic-framework/issues/18617)
# [6.3.0](https://github.com/ionic-team/ionic-framework/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic-framework/compare/v6.2.9...v6.3.0) (2022-10-05)

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/angular
# [6.3.0 Manganese](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0 Manganese](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)

View File

@ -1,15 +1,15 @@
{ {
"name": "@ionic/angular", "name": "@ionic/angular",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/angular", "name": "@ionic/angular",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"jsonc-parser": "^3.0.0", "jsonc-parser": "^3.0.0",
"tslib": "^2.0.0" "tslib": "^2.0.0"
}, },
@ -1023,9 +1023,9 @@
"dev": true "dev": true
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -7951,9 +7951,9 @@
"dev": true "dev": true
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",

View File

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

View File

@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
### Bug Fixes
* **datetime:** setting date async updates calendar grid ([#26070](https://github.com/ionic-team/ionic/issues/26070)) ([0aee328](https://github.com/ionic-team/ionic/commit/0aee328b4b84d5668752e5ae0792334d0173c2bb)), closes [#25776](https://github.com/ionic-team/ionic/issues/25776)
* **datetime:** setting max/min does not increase number of nodes rendered ([#26065](https://github.com/ionic-team/ionic/issues/26065)) ([a5d178f](https://github.com/ionic-team/ionic/commit/a5d178f4c03a0ad2501095afe1f75914b0462ae1)), closes [#26059](https://github.com/ionic-team/ionic/issues/26059)
* **item, card:** aria-label is reflected to the inner button ([#26028](https://github.com/ionic-team/ionic/issues/26028)) ([3c89ebe](https://github.com/ionic-team/ionic/commit/3c89ebe7216b2a19580a4f1ed23d5d1d4c37919d)), closes [#25885](https://github.com/ionic-team/ionic/issues/25885)
* **toolbar:** MD height only applies to MD segment ([#26042](https://github.com/ionic-team/ionic/issues/26042)) ([ab89679](https://github.com/ionic-team/ionic/commit/ab8967936c6bef5fc0a884cb8bf8f2deb7784c13)), closes [#18617](https://github.com/ionic-team/ionic/issues/18617)
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)

View File

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

View File

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

View File

@ -1,34 +0,0 @@
// Roboto Font
// Google
// Apache License, version 2.0
// http://www.apache.org/licenses/LICENSE-2.0.html
$roboto-font-path: $font-path !default;
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 300;
src: local("Roboto Light"), local("Roboto-Light"), url("#{$roboto-font-path}/roboto-light.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-light.woff") format("woff"), url("#{$roboto-font-path}/roboto-light.ttf") format("truetype");
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
src: local("Roboto"), local("Roboto-Regular"), url("#{$roboto-font-path}/roboto-regular.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-regular.woff") format("woff"), url("#{$roboto-font-path}/roboto-regular.ttf") format("truetype");
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 500;
src: local("Roboto Medium"), local("Roboto-Medium"), url("#{$roboto-font-path}/roboto-medium.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-medium.woff") format("woff"), url("#{$roboto-font-path}/roboto-medium.ttf") format("truetype");
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 700;
src: local("Roboto Bold"), local("Roboto-Bold"), url("#{$roboto-font-path}/roboto-bold.woff2") format("woff2"), url("#{$roboto-font-path}/roboto-bold.woff") format("woff"), url("#{$roboto-font-path}/roboto-bold.ttf") format("truetype");
}

View File

@ -1,9 +1,11 @@
import type { ComponentInterface } from '@stencil/core'; import type { ComponentInterface } from '@stencil/core';
import { Component, Host, Prop, h } from '@stencil/core'; import { Element, Component, Host, Prop, h } from '@stencil/core';
import { getIonMode } from '../../global/ionic-global'; import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, Color, Mode, RouterDirection } from '../../interface'; import type { AnimationBuilder, Color, Mode, RouterDirection } from '../../interface';
import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface'; import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
import type { Attributes } from '../../utils/helpers';
import { inheritAttributes } from '../../utils/helpers';
import { createColorClasses, openURL } from '../../utils/theme'; import { createColorClasses, openURL } from '../../utils/theme';
/** /**
@ -20,6 +22,9 @@ import { createColorClasses, openURL } from '../../utils/theme';
shadow: true, shadow: true,
}) })
export class Card implements ComponentInterface, AnchorInterface, ButtonInterface { export class Card implements ComponentInterface, AnchorInterface, ButtonInterface {
private inheritedAriaAttributes: Attributes = {};
@Element() el!: HTMLElement;
/** /**
* The color to use from your application's color palette. * The color to use from your application's color palette.
* Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. * Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`.
@ -81,6 +86,10 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
*/ */
@Prop() target: string | undefined; @Prop() target: string | undefined;
componentWillLoad() {
this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']);
}
private isClickable(): boolean { private isClickable(): boolean {
return this.href !== undefined || this.button; return this.href !== undefined || this.button;
} }
@ -91,7 +100,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
if (!clickable) { if (!clickable) {
return [<slot></slot>]; return [<slot></slot>];
} }
const { href, routerAnimation, routerDirection } = this; const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this;
const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any); const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any);
const attrs = const attrs =
TagType === 'button' TagType === 'button'
@ -106,6 +115,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
return ( return (
<TagType <TagType
{...attrs} {...attrs}
{...inheritedAriaAttributes}
class="card-native" class="card-native"
part="native" part="native"
disabled={this.disabled} disabled={this.disabled}

View File

@ -0,0 +1,17 @@
import { newSpecPage } from '@stencil/core/testing';
import { Card } from '../card';
describe('card: button', () => {
it('should reflect aria-label to button', async () => {
const page = await newSpecPage({
components: [Card],
html: `<ion-card button="true" aria-label="Test"></ion-card>`,
});
const button = page.body.querySelector('ion-card')!.shadowRoot!.querySelector('button')!;
const ariaLabel = button.getAttribute('aria-label');
expect(ariaLabel).toEqual('Test');
});
});

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<title>Card - Basic</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/ionic.bundle.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-app>
<ion-header>
<ion-toolbar>
<ion-title>Card - Basic</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-card>
<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>
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
in the woods. Wash your spirit clean.
</ion-card-content>
</ion-card>
</ion-content>
</ion-app>
</body>
</html>

View File

@ -19,7 +19,7 @@ import { isRTL } from '../../utils/rtl';
import { createColorClasses } from '../../utils/theme'; import { createColorClasses } from '../../utils/theme';
import type { PickerColumnItem } from '../picker-column-internal/picker-column-internal-interfaces'; import type { PickerColumnItem } from '../picker-column-internal/picker-column-internal-interfaces';
import { isSameDay, warnIfValueOutOfBounds } from './utils/comparison'; import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from './utils/comparison';
import { import {
generateMonths, generateMonths,
getDaysOfMonth, getDaysOfMonth,
@ -32,7 +32,7 @@ import {
getCombinedDateColumnData, getCombinedDateColumnData,
} from './utils/data'; } from './utils/data';
import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from './utils/format'; import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from './utils/format';
import { is24Hour, isLocaleDayPeriodRTL, isMonthFirstLocale } from './utils/helpers'; import { is24Hour, isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth } from './utils/helpers';
import { import {
calculateHourFromAMPM, calculateHourFromAMPM,
convertDataToISO, convertDataToISO,
@ -85,17 +85,6 @@ export class Datetime implements ComponentInterface {
private calendarBodyRef?: HTMLElement; private calendarBodyRef?: HTMLElement;
private popoverRef?: HTMLIonPopoverElement; private popoverRef?: HTMLIonPopoverElement;
private clearFocusVisible?: () => void; private clearFocusVisible?: () => void;
/**
* Whether to highlight the active day with a solid circle (as opposed
* to the outline circle around today). If you don't specify an initial
* value for the datetime, it doesn't automatically init to a default to
* avoid unwanted change events firing. If the solid circle were still
* shown then, it would look like a date had already been selected, which
* is misleading UX.
*/
private highlightActiveParts = false;
private parsedMinuteValues?: number[]; private parsedMinuteValues?: number[];
private parsedHourValues?: number[]; private parsedHourValues?: number[];
private parsedMonthValues?: number[]; private parsedMonthValues?: number[];
@ -115,18 +104,11 @@ export class Datetime implements ComponentInterface {
* Duplicate reference to `activeParts` that does not trigger a re-render of the component. * Duplicate reference to `activeParts` that does not trigger a re-render of the component.
* Allows caching an instance of the `activeParts` in between render cycles. * Allows caching an instance of the `activeParts` in between render cycles.
*/ */
private activePartsClone!: DatetimeParts | DatetimeParts[]; private activePartsClone: DatetimeParts | DatetimeParts[] = [];
@State() showMonthAndYear = false; @State() showMonthAndYear = false;
@State() activeParts: DatetimeParts | DatetimeParts[] = { @State() activeParts: DatetimeParts | DatetimeParts[] = [];
month: 5,
day: 28,
year: 2021,
hour: 13,
minute: 52,
ampm: 'pm',
};
@State() workingParts: DatetimeParts = { @State() workingParts: DatetimeParts = {
month: 5, month: 5,
@ -506,16 +488,12 @@ export class Datetime implements ComponentInterface {
*/ */
@Method() @Method()
async confirm(closeOverlay = false) { async confirm(closeOverlay = false) {
const { highlightActiveParts, isCalendarPicker, activeParts } = this; const { isCalendarPicker, activeParts } = this;
/** /**
* We only update the value if the presentation is not a calendar picker, * We only update the value if the presentation is not a calendar picker.
* or if `highlightActiveParts` is true; indicating that the user
* has selected a date from the calendar picker.
*
* Otherwise "today" would accidentally be set as the value.
*/ */
if (highlightActiveParts || !isCalendarPicker) { if (activeParts !== undefined || !isCalendarPicker) {
const activePartsIsArray = Array.isArray(activeParts); const activePartsIsArray = Array.isArray(activeParts);
if (activePartsIsArray && activeParts.length === 0) { if (activePartsIsArray && activeParts.length === 0) {
this.value = undefined; this.value = undefined;
@ -573,6 +551,23 @@ export class Datetime implements ComponentInterface {
} }
} }
/**
* Returns the DatetimePart interface
* to use when rendering an initial set of
* data. This should be used when rendering an
* interface in an environment where the `value`
* may not be set. This function works
* by returning the first selected date in
* "activePartsClone" and then falling back to
* today's DatetimeParts if no active date is selected.
*/
private getDefaultPart = () => {
const { activePartsClone, todayParts } = this;
const firstPart = Array.isArray(activePartsClone) ? activePartsClone[0] : activePartsClone;
return firstPart ?? todayParts;
};
private closeParentOverlay = () => { private closeParentOverlay = () => {
const popoverOrModal = this.el.closest('ion-modal, ion-popover') as const popoverOrModal = this.el.closest('ion-modal, ion-popover') as
| HTMLIonModalElement | HTMLIonModalElement
@ -590,7 +585,7 @@ export class Datetime implements ComponentInterface {
}; };
private setActiveParts = (parts: DatetimeParts, removeDate = false) => { private setActiveParts = (parts: DatetimeParts, removeDate = false) => {
const { multiple, activePartsClone, highlightActiveParts } = this; const { multiple, activePartsClone } = this;
/** /**
* When setting the active parts, it is possible * When setting the active parts, it is possible
@ -618,15 +613,8 @@ export class Datetime implements ComponentInterface {
const activePartsArray = Array.isArray(activePartsClone) ? activePartsClone : [activePartsClone]; const activePartsArray = Array.isArray(activePartsClone) ? activePartsClone : [activePartsClone];
if (removeDate) { if (removeDate) {
this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts)); this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
} else if (highlightActiveParts) {
this.activeParts = [...activePartsArray, validatedParts];
} else { } else {
/** this.activeParts = [...activePartsArray, validatedParts];
* 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 = [validatedParts];
} }
} else { } else {
this.activeParts = { this.activeParts = {
@ -634,18 +622,6 @@ export class Datetime implements ComponentInterface {
}; };
} }
/**
* Now that the user has interacted somehow to select something, we can
* show the solid highlight. This needs to be done after checking it above,
* but before the confirm call below.
*
* Note that for datetimes with confirm/cancel buttons, the value
* isn't updated until you call confirm(). We need to bring the
* solid circle back on day click for UX reasons, rather than only
* show the circle if `value` is truthy.
*/
this.highlightActiveParts = true;
const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null; const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
if (hasSlottedButtons || this.showDefaultButtons) { if (hasSlottedButtons || this.showDefaultButtons) {
return; return;
@ -1178,7 +1154,7 @@ export class Datetime implements ComponentInterface {
} }
private processValue = (value?: string | string[] | null) => { private processValue = (value?: string | string[] | null) => {
const hasValue = (this.highlightActiveParts = value !== null && value !== undefined); const hasValue = value !== null && value !== undefined;
let valueToProcess = parseDate(value ?? getToday()); let valueToProcess = parseDate(value ?? getToday());
const { minParts, maxParts, multiple } = this; const { minParts, maxParts, multiple } = this;
@ -1219,18 +1195,26 @@ export class Datetime implements ComponentInterface {
ampm, ampm,
}); });
if (Array.isArray(valueToProcess)) { /**
this.activeParts = [...valueToProcess]; * Since `activeParts` indicates a value that
} else { * been explicitly selected either by the
this.activeParts = { * user or the app, only update `activeParts`
month, * if the `value` property is set.
day, */
year, if (hasValue) {
hour, if (Array.isArray(valueToProcess)) {
minute, this.activeParts = [...valueToProcess];
tzOffset, } else {
ampm, this.activeParts = {
}; month,
day,
year,
hour,
minute,
tzOffset,
ampm,
};
}
} }
}; };
@ -1416,23 +1400,24 @@ export class Datetime implements ComponentInterface {
* Previous month, current month, and next month * Previous month, current month, and next month
*/ */
const monthsToRender = generateMonths(workingParts); const monthsToRender = generateMonths(workingParts);
const lastMonth = monthsToRender[monthsToRender.length - 1];
/** /**
* generateMonths returns the day data as well, * Ensure that users can select the entire window of dates.
* but we do not want the day value to act as a max/min
* on the data we are going to generate.
*/ */
for (let i = 0; i <= monthsToRender.length - 1; i++) { monthsToRender[0].day = 1;
monthsToRender[i].day = null; lastMonth.day = getNumDaysInMonth(lastMonth.month, lastMonth.year);
}
/** /**
* If developers have provided their own * Narrow the dates rendered based on min/max dates (if any).
* min/max values, use that instead. Otherwise, * The `min` date is used if the min is after the generated min month.
* fallback to the default range of 3 months. * The `max` date is used if the max is before the generated max month.
* This ensures that the sliding window always stays at 3 months
* but still allows future dates to be lazily rendered based on any min/max
* constraints.
*/ */
const min = minParts || monthsToRender[0]; const min = minParts !== undefined && isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
const max = maxParts || monthsToRender[monthsToRender.length - 1]; const max = maxParts !== undefined && isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
const result = getCombinedDateColumnData( const result = getCombinedDateColumnData(
locale, locale,
@ -1442,6 +1427,7 @@ export class Datetime implements ComponentInterface {
this.parsedDayValues, this.parsedDayValues,
this.parsedMonthValues this.parsedMonthValues
); );
let items = result.items; let items = result.items;
const parts = result.parts; const parts = result.parts;
@ -1747,13 +1733,15 @@ export class Datetime implements ComponentInterface {
} }
private renderHourPickerColumn(hoursData: PickerColumnItem[]) { private renderHourPickerColumn(hoursData: PickerColumnItem[]) {
const { workingParts, activePartsClone } = this; const { workingParts } = this;
if (hoursData.length === 0) return []; if (hoursData.length === 0) return [];
const activePart = this.getDefaultPart();
return ( return (
<ion-picker-column-internal <ion-picker-column-internal
color={this.color} color={this.color}
value={(activePartsClone as DatetimeParts).hour} value={activePart.hour}
items={hoursData} items={hoursData}
numericInput numericInput
onIonChange={(ev: CustomEvent) => { onIonChange={(ev: CustomEvent) => {
@ -1762,9 +1750,9 @@ export class Datetime implements ComponentInterface {
hour: ev.detail.value, hour: ev.detail.value,
}); });
if (!Array.isArray(activePartsClone)) { if (!Array.isArray(activePart)) {
this.setActiveParts({ this.setActiveParts({
...activePartsClone, ...activePart,
hour: ev.detail.value, hour: ev.detail.value,
}); });
} }
@ -1775,13 +1763,15 @@ export class Datetime implements ComponentInterface {
); );
} }
private renderMinutePickerColumn(minutesData: PickerColumnItem[]) { private renderMinutePickerColumn(minutesData: PickerColumnItem[]) {
const { workingParts, activePartsClone } = this; const { workingParts } = this;
if (minutesData.length === 0) return []; if (minutesData.length === 0) return [];
const activePart = this.getDefaultPart();
return ( return (
<ion-picker-column-internal <ion-picker-column-internal
color={this.color} color={this.color}
value={(activePartsClone as DatetimeParts).minute} value={activePart.minute}
items={minutesData} items={minutesData}
numericInput numericInput
onIonChange={(ev: CustomEvent) => { onIonChange={(ev: CustomEvent) => {
@ -1790,9 +1780,9 @@ export class Datetime implements ComponentInterface {
minute: ev.detail.value, minute: ev.detail.value,
}); });
if (!Array.isArray(activePartsClone)) { if (!Array.isArray(activePart)) {
this.setActiveParts({ this.setActiveParts({
...activePartsClone, ...activePart,
minute: ev.detail.value, minute: ev.detail.value,
}); });
} }
@ -1803,18 +1793,19 @@ export class Datetime implements ComponentInterface {
); );
} }
private renderDayPeriodPickerColumn(dayPeriodData: PickerColumnItem[]) { private renderDayPeriodPickerColumn(dayPeriodData: PickerColumnItem[]) {
const { workingParts, activePartsClone } = this; const { workingParts } = this;
if (dayPeriodData.length === 0) { if (dayPeriodData.length === 0) {
return []; return [];
} }
const activePart = this.getDefaultPart();
const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale); const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale);
return ( return (
<ion-picker-column-internal <ion-picker-column-internal
style={isDayPeriodRTL ? { order: '-1' } : {}} style={isDayPeriodRTL ? { order: '-1' } : {}}
color={this.color} color={this.color}
value={(activePartsClone as DatetimeParts).ampm} value={activePart.ampm}
items={dayPeriodData} items={dayPeriodData}
onIonChange={(ev: CustomEvent) => { onIonChange={(ev: CustomEvent) => {
const hour = calculateHourFromAMPM(workingParts, ev.detail.value); const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
@ -1825,9 +1816,9 @@ export class Datetime implements ComponentInterface {
hour, hour,
}); });
if (!Array.isArray(activePartsClone)) { if (!Array.isArray(activePart)) {
this.setActiveParts({ this.setActiveParts({
...activePartsClone, ...activePart,
ampm: ev.detail.value, ampm: ev.detail.value,
hour, hour,
}); });
@ -1901,7 +1892,6 @@ export class Datetime implements ComponentInterface {
); );
} }
private renderMonth(month: number, year: number) { private renderMonth(month: number, year: number) {
const { highlightActiveParts } = this;
const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year); const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month); const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
const isCalMonthDisabled = !yearAllowed || !monthAllowed; const isCalMonthDisabled = !yearAllowed || !monthAllowed;
@ -1979,7 +1969,7 @@ export class Datetime implements ComponentInterface {
class={{ class={{
'calendar-day-padding': day === null, 'calendar-day-padding': day === null,
'calendar-day': true, 'calendar-day': true,
'calendar-day-active': isActive && highlightActiveParts, 'calendar-day-active': isActive,
'calendar-day-today': isToday, 'calendar-day-today': isToday,
}} }}
aria-selected={ariaSelected} aria-selected={ariaSelected}
@ -2004,7 +1994,7 @@ export class Datetime implements ComponentInterface {
day, day,
year, year,
}, },
isActive && highlightActiveParts isActive
); );
} else { } else {
this.setActiveParts({ this.setActiveParts({
@ -2052,6 +2042,8 @@ export class Datetime implements ComponentInterface {
private renderTimeOverlay() { private renderTimeOverlay() {
const use24Hour = is24Hour(this.locale, this.hourCycle); const use24Hour = is24Hour(this.locale, this.hourCycle);
const activePart = this.getDefaultPart();
return [ return [
<div class="time-header">{this.renderTimeLabel()}</div>, <div class="time-header">{this.renderTimeLabel()}</div>,
<button <button
@ -2081,7 +2073,7 @@ export class Datetime implements ComponentInterface {
} }
}} }}
> >
{getLocalizedTime(this.locale, this.activePartsClone as DatetimeParts, use24Hour)} {getLocalizedTime(this.locale, activePart, use24Hour)}
</button>, </button>,
<ion-popover <ion-popover
alignment="center" alignment="center"
@ -2135,7 +2127,7 @@ export class Datetime implements ComponentInterface {
} }
} else { } else {
// for exactly 1 day selected (multiple set or not), show a formatted version of that // for exactly 1 day selected (multiple set or not), show a formatted version of that
headerText = getMonthAndDay(this.locale, isArray ? activeParts[0] : activeParts); headerText = getMonthAndDay(this.locale, this.getDefaultPart());
} }
return ( return (

View File

@ -14,14 +14,37 @@ test.describe('datetime: prefer wheel', () => {
* are rendering quirks on Linux * are rendering quirks on Linux
* if the datetime is too small. * if the datetime is too small.
*/ */
test.describe('datetime: date wheel rendering', () => { test.describe('datetime: wheel rendering', () => {
test('should not have visual regressions', async ({ page }) => { test('should not have visual regressions for date wheel', async ({ page }) => {
await page.setContent(` await page.setContent(`
<ion-datetime size="cover" presentation="date" prefer-wheel="true" value="2019-05-30"></ion-datetime> <ion-datetime size="cover" presentation="date" prefer-wheel="true" value="2019-05-30"></ion-datetime>
`); `);
expect(await page.screenshot()).toMatchSnapshot(`datetime-wheel-date-diff-${page.getSnapshotSettings()}.png`); expect(await page.screenshot()).toMatchSnapshot(`datetime-wheel-date-diff-${page.getSnapshotSettings()}.png`);
}); });
test('should not have visual regressions for date-time wheel', async ({ page }) => {
await page.setContent(`
<ion-datetime size="cover" presentation="date-time" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
`);
expect(await page.screenshot()).toMatchSnapshot(
`datetime-wheel-date-time-diff-${page.getSnapshotSettings()}.png`
);
});
test('should not have visual regressions for time-date wheel', async ({ page }) => {
await page.setContent(`
<ion-datetime size="cover" presentation="time-date" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
`);
expect(await page.screenshot()).toMatchSnapshot(
`datetime-wheel-time-date-diff-${page.getSnapshotSettings()}.png`
);
});
});
test.describe('datetime: date wheel', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
});
test('should respect the min bounds', async ({ page }) => { test('should respect the min bounds', async ({ page }) => {
await page.setContent(` await page.setContent(`
<ion-datetime presentation="date" prefer-wheel="true" min="2019-05-05" max="2023-10-01" value="2019-05-30"></ion-datetime> <ion-datetime presentation="date" prefer-wheel="true" min="2019-05-05" max="2023-10-01" value="2019-05-30"></ion-datetime>
@ -149,15 +172,9 @@ test.describe('datetime: prefer wheel', () => {
}); });
}); });
}); });
test.describe('datetime: date-time wheel rendering', () => { test.describe('datetime: date-time wheel', () => {
test('should not have visual regressions', async ({ page }) => { test.beforeEach(({ skip }) => {
await page.setContent(` skip.rtl();
<ion-datetime size="cover" presentation="date-time" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
`);
expect(await page.screenshot()).toMatchSnapshot(
`datetime-wheel-date-time-diff-${page.getSnapshotSettings()}.png`
);
}); });
test('should respect the min bounds', async ({ page }) => { test('should respect the min bounds', async ({ page }) => {
await page.setContent(` await page.setContent(`
@ -249,20 +266,58 @@ test.describe('datetime: prefer wheel', () => {
await page.waitForSelector('.datetime-ready'); await page.waitForSelector('.datetime-ready');
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)'); const dateColumn = page.locator('.date-column');
const dateValues = dateColumn.locator('.picker-item:not(.picker-item-empty)');
expect(await dateValues.count()).toBe(397); expect(await dateValues.count()).toBe(90);
/**
* Select 1st item to change the dates rendered
*/
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2022-1-1');
await dateColumn.evaluate((el: HTMLElement) => (el.scrollTop = 0));
await page.waitForChanges();
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2021-12-1');
}); });
}); test('should keep sliding window if default window is within min and max constraints', async ({ page }) => {
test.describe('datetime: time-date wheel rendering', () => {
test('should not have visual regressions', async ({ page }) => {
await page.setContent(` await page.setContent(`
<ion-datetime size="cover" presentation="time-date" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime> <ion-datetime
presentation="date-time"
prefer-wheel="true"
value="2022-06-01"
max="2030-01-01"
min="2010-01-01"
></ion-datetime>
`); `);
expect(await page.screenshot()).toMatchSnapshot( await page.waitForSelector('.datetime-ready');
`datetime-wheel-time-date-diff-${page.getSnapshotSettings()}.png`
); const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
expect(await dayValues.count()).toBe(92);
});
test('should narrow sliding window if default window is not within min and max constraints', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="date-time"
prefer-wheel="true"
value="2022-06-01"
max="2022-05-15"
min="2022-05-01"
></ion-datetime>
`);
await page.waitForSelector('.datetime-ready');
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
expect(await dayValues.count()).toBe(15);
});
});
test.describe('datetime: time-date wheel', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
}); });
test('should respect the min bounds', async ({ page }) => { test('should respect the min bounds', async ({ page }) => {
await page.setContent(` await page.setContent(`
@ -354,9 +409,53 @@ test.describe('datetime: prefer wheel', () => {
await page.waitForSelector('.datetime-ready'); await page.waitForSelector('.datetime-ready');
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)'); const dateColumn = page.locator('.date-column');
const dateValues = dateColumn.locator('.picker-item:not(.picker-item-empty)');
expect(await dateValues.count()).toBe(397); expect(await dateValues.count()).toBe(90);
/**
* Select 1st item to change the dates rendered
*/
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2022-1-1');
await dateColumn.evaluate((el: HTMLElement) => (el.scrollTop = 0));
await page.waitForChanges();
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2021-12-1');
});
test('should keep sliding window if default window is within min and max constraints', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="time-date"
prefer-wheel="true"
value="2022-06-01"
max="2030-01-01"
min="2010-01-01"
></ion-datetime>
`);
await page.waitForSelector('.datetime-ready');
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
expect(await dayValues.count()).toBe(92);
});
test('should narrow sliding window if default window is not within min and max constraints', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="time-date"
prefer-wheel="true"
value="2022-06-01"
max="2022-05-15"
min="2022-05-01"
></ion-datetime>
`);
await page.waitForSelector('.datetime-ready');
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
expect(await dayValues.count()).toBe(15);
}); });
}); });
}); });

View File

@ -2,11 +2,13 @@ import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright'; import { test } from '@utils/test/playwright';
test.describe('datetime: set-value', () => { test.describe('datetime: set-value', () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ skip }) => {
skip.rtl();
});
test('should update the active date when value is initially set', async ({ page }) => {
await page.goto('/src/components/datetime/test/set-value'); await page.goto('/src/components/datetime/test/set-value');
await page.waitForSelector('.datetime-ready'); await page.waitForSelector('.datetime-ready');
});
test('should update the active date', async ({ page }) => {
const datetime = page.locator('ion-datetime'); const datetime = page.locator('ion-datetime');
await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-11-25T12:40:00.000Z')); await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-11-25T12:40:00.000Z'));
@ -15,7 +17,10 @@ test.describe('datetime: set-value', () => {
const activeDate = page.locator('ion-datetime .calendar-day-active'); const activeDate = page.locator('ion-datetime .calendar-day-active');
await expect(activeDate).toHaveText('25'); await expect(activeDate).toHaveText('25');
}); });
test('should update the active time', async ({ page }) => { test('should update the active time when value is initially set', async ({ page }) => {
await page.goto('/src/components/datetime/test/set-value');
await page.waitForSelector('.datetime-ready');
const datetime = page.locator('ion-datetime'); const datetime = page.locator('ion-datetime');
await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-11-25T12:40:00.000Z')); await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-11-25T12:40:00.000Z'));
@ -24,4 +29,38 @@ test.describe('datetime: set-value', () => {
const activeDate = page.locator('ion-datetime .time-body'); const activeDate = page.locator('ion-datetime .time-body');
await expect(activeDate).toHaveText('12:40 PM'); await expect(activeDate).toHaveText('12:40 PM');
}); });
test('should update active item when value is not initially set', async ({ page }) => {
await page.setContent(`
<ion-datetime presentation="date" locale="en-US"></ion-datetime>
`);
await page.waitForSelector('.datetime-ready');
const datetime = page.locator('ion-datetime');
const activeDayButton = page.locator('.calendar-day-active');
const monthYearButton = page.locator('.calendar-month-year');
const monthColumn = page.locator('.month-column');
const yearColumn = page.locator('.year-column');
await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-10-05'));
// Open month/year picker
await monthYearButton.click();
await page.waitForChanges();
// Select October 2021
await monthColumn.locator('.picker-item[data-value="10"]').click();
await page.waitForChanges();
await yearColumn.locator('.picker-item[data-value="2021"]').click();
await page.waitForChanges();
// Close month/year picker
await monthYearButton.click();
await page.waitForChanges();
// Check that correct day is highlighted
await expect(activeDayButton).toHaveAttribute('data-day', '5');
await expect(activeDayButton).toHaveAttribute('data-month', '10');
await expect(activeDayButton).toHaveAttribute('data-year', '2021');
});
}); });

View File

@ -115,6 +115,7 @@ export function parseDate(val: string | string[] | undefined | null): DatetimePa
hour: parse[4], hour: parse[4],
minute: parse[5], minute: parse[5],
tzOffset, tzOffset,
ampm: parse[4] < 12 ? 'am' : 'pm',
}; };
} }

View File

@ -1,44 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
import type { E2EPage } from '@stencil/core/testing';
/**
* Scrolls an `ion-content` element to the bottom, triggering the `ionInfinite` event.
* Waits for the custom event to complete.
*/
const scrollIonContentPage = async (page: E2EPage) => {
const content = await page.find('ion-content');
await content.callMethod('scrollToBottom');
await page.waitForChanges();
const ev = await page.spyOnEvent('ionInfiniteComplete', 'document');
await ev.next();
};
describe('infinite-scroll: basic', () => {
it('should match existing visual screenshots', async () => {
const page = await newE2EPage({
url: '/src/components/infinite-scroll/test/basic?ionic:_testing=true',
});
const compare = await page.compareScreenshot();
expect(compare).toMatchScreenshot();
});
describe('when enabled', () => {
it('should load more items when scrolled to the bottom', async () => {
const page = await newE2EPage({
url: '/src/components/infinite-scroll/test/basic?ionic:_testing=true',
});
const initialItems = await page.findAll('ion-item');
expect(initialItems.length).toBe(30);
await scrollIonContentPage(page);
const updatedItems = await page.findAll('ion-item');
expect(updatedItems.length).toBe(60);
});
});
});

View File

@ -47,7 +47,7 @@
infiniteScroll.complete(); infiniteScroll.complete();
appendItems(); appendItems();
// Custom event consumed in the e2e tests // Custom event consumed in the e2e tests
document.dispatchEvent(new CustomEvent('ionInfiniteComplete')); window.dispatchEvent(new CustomEvent('ionInfiniteComplete'));
}); });
function appendItems() { function appendItems() {

View File

@ -0,0 +1,22 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('infinite-scroll: basic', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
skip.mode('ios');
});
test('should load more items when scrolled to the bottom', async ({ page }) => {
await page.goto('/src/components/infinite-scroll/test/basic');
const ionInfiniteComplete = await page.spyOnEvent('ionInfiniteComplete');
const content = page.locator('ion-content');
const items = page.locator('ion-item');
expect(await items.count()).toBe(30);
await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));
await ionInfiniteComplete.next();
expect(await items.count()).toBe(60);
});
});

View File

@ -1,32 +0,0 @@
import { newE2EPage } from '@stencil/core/testing';
import type { E2EPage } from '@stencil/core/testing';
import { scrollToBottom } from '@utils/test';
/**
* Scrolls an `ion-content` element to the bottom, triggering the `ionInfinite` event.
* Waits for the custom event to complete.
*/
async function scrollPage(page: E2EPage) {
await scrollToBottom(page, '#scroll-target');
await page.waitForChanges();
const ev = await page.spyOnEvent('ionInfiniteComplete', 'document');
await ev.next();
}
describe('infinite-scroll: custom scroll target', () => {
it('should load more items when scrolled to the bottom', async () => {
const page = await newE2EPage({
url: '/src/components/infinite-scroll/test/scroll-target?ionic:_testing=true',
});
const initialItems = await page.findAll('ion-item');
expect(initialItems.length).toBe(30);
await scrollPage(page);
const items = await page.findAll('ion-item');
expect(items.length).toBe(60);
});
});

View File

@ -51,7 +51,7 @@
infiniteScroll.complete(); infiniteScroll.complete();
appendItems(); appendItems();
// Custom event consumed in the e2e tests // Custom event consumed in the e2e tests
document.dispatchEvent(new CustomEvent('ionInfiniteComplete')); window.dispatchEvent(new CustomEvent('ionInfiniteComplete'));
}); });
function appendItems() { function appendItems() {

View File

@ -0,0 +1,22 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('infinite-scroll: scroll-target', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
skip.mode('ios');
});
test('should load more items when scroll target is scrolled to the bottom', async ({ page }) => {
await page.goto('/src/components/infinite-scroll/test/scroll-target');
const ionInfiniteComplete = await page.spyOnEvent('ionInfiniteComplete');
const content = page.locator('#scroll-target');
const items = page.locator('ion-item');
expect(await items.count()).toBe(30);
await content.evaluate((el: HTMLElement) => (el.scrollTop = el.scrollHeight));
await ionInfiniteComplete.next();
expect(await items.count()).toBe(60);
});
});

View File

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

View File

@ -47,6 +47,8 @@
await wait(500); await wait(500);
infiniteScroll.complete(); infiniteScroll.complete();
appendItems(); appendItems();
// Custom event consumed in the e2e tests
window.dispatchEvent(new CustomEvent('ionInfiniteComplete'));
console.log('Done'); console.log('Done');
}); });

View File

@ -0,0 +1,22 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('infinite-scroll: top', () => {
test.beforeEach(({ skip }) => {
skip.rtl();
skip.mode('ios');
});
test('should load more items when scrolled to the top', async ({ page }) => {
await page.goto('/src/components/infinite-scroll/test/top');
const ionInfiniteComplete = await page.spyOnEvent('ionInfiniteComplete');
const content = page.locator('ion-content');
const items = page.locator('ion-item');
expect(await items.count()).toBe(30);
await content.evaluate((el: HTMLIonContentElement) => el.scrollToTop(0));
await ionInfiniteComplete.next();
expect(await items.count()).toBe(60);
});
});

View File

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

View File

@ -0,0 +1,14 @@
import { expect } from '@playwright/test';
import { test } from '@utils/test/playwright';
test.describe('item-divider: spec', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/src/components/item-divider/test/spec');
});
test('should not have visual regressions', async ({ page }) => {
await page.setIonViewport();
expect(await page.screenshot()).toMatchSnapshot(`list-item-divider-${page.getSnapshotSettings()}.png`);
});
});

View File

@ -5,7 +5,8 @@ import { chevronForward } from 'ionicons/icons';
import { getIonMode } from '../../global/ionic-global'; import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, Color, CssClassMap, RouterDirection, StyleEventDetail } from '../../interface'; import type { AnimationBuilder, Color, CssClassMap, RouterDirection, StyleEventDetail } from '../../interface';
import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface'; import type { AnchorInterface, ButtonInterface } from '../../utils/element-interface';
import { raf } from '../../utils/helpers'; import type { Attributes } from '../../utils/helpers';
import { inheritAttributes, raf } from '../../utils/helpers';
import { printIonError } from '../../utils/logging'; import { printIonError } from '../../utils/logging';
import { createColorClasses, hostContext, openURL } from '../../utils/theme'; import { createColorClasses, hostContext, openURL } from '../../utils/theme';
import type { InputChangeEventDetail } from '../input/input-interface'; import type { InputChangeEventDetail } from '../input/input-interface';
@ -38,6 +39,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
private labelColorStyles = {}; private labelColorStyles = {};
private itemStyles = new Map<string, CssClassMap>(); private itemStyles = new Map<string, CssClassMap>();
private clickListener?: (ev: Event) => void; private clickListener?: (ev: Event) => void;
private inheritedAriaAttributes: Attributes = {};
@Element() el!: HTMLIonItemElement; @Element() el!: HTMLIonItemElement;
@ -226,6 +228,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
componentDidLoad() { componentDidLoad() {
raf(() => { raf(() => {
this.inheritedAriaAttributes = inheritAttributes(this.el, ['aria-label']);
this.setMultipleInputs(); this.setMultipleInputs();
this.focusable = this.isFocusable(); this.focusable = this.isFocusable();
}); });
@ -359,12 +362,14 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
target, target,
routerAnimation, routerAnimation,
routerDirection, routerDirection,
inheritedAriaAttributes,
} = this; } = this;
const childStyles = {} as any; const childStyles = {} as any;
const mode = getIonMode(this); const mode = getIonMode(this);
const clickable = this.isClickable(); const clickable = this.isClickable();
const canActivate = this.canActivate(); const canActivate = this.canActivate();
const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any); const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any);
const attrs = const attrs =
TagType === 'button' TagType === 'button'
? { type: this.type } ? { type: this.type }
@ -390,6 +395,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null; const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null;
const fillValue = fill || 'none'; const fillValue = fill || 'none';
const inList = hostContext('ion-list', this.el); const inList = hostContext('ion-list', this.el);
return ( return (
<Host <Host
aria-disabled={ariaDisabled} aria-disabled={ariaDisabled}
@ -412,7 +418,14 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
}} }}
role={inList ? 'listitem' : null} role={inList ? 'listitem' : null}
> >
<TagType {...attrs} class="item-native" part="native" disabled={disabled} {...clickFn}> <TagType
{...attrs}
{...inheritedAriaAttributes}
class="item-native"
part="native"
disabled={disabled}
{...clickFn}
>
<slot name="start"></slot> <slot name="start"></slot>
<div class="item-inner"> <div class="item-inner">
<div class="input-wrapper"> <div class="input-wrapper">

View File

@ -4,6 +4,12 @@ import { Component, Element, Event, Host, Listen, Prop, Watch, h } from '@stenci
import { getIonMode } from '../../global/ionic-global'; import { getIonMode } from '../../global/ionic-global';
import type { RadioGroupChangeEventDetail } from '../../interface'; import type { RadioGroupChangeEventDetail } from '../../interface';
/**
* The Radio Group component mandates that only one radio button
* within the group can be selected at any given time. Since `ion-radio`
* is a shadow DOM component, it cannot natively perform this behavior
* using the `name` attribute.
*/
@Component({ @Component({
tag: 'ion-radio-group', tag: 'ion-radio-group',
}) })

View File

@ -8,10 +8,23 @@
--background: transparent; --background: transparent;
} }
// Segment: In Toolbar
// --------------------------------------------------
:host(.in-toolbar) {
/**
* Segment should inherit the
* height of the toolbar.
* Note: --min-height is initially
* set on ion-toolbar, not ion-segment
*/
min-height: var(--min-height);
}
// Segment: Scrollable // Segment: Scrollable
// -------------------------------------------------- // --------------------------------------------------
:host(.segment-scrollable) ::slotted(ion-segment-button) { :host(.segment-scrollable) ::slotted(ion-segment-button) {
min-width: auto; min-width: auto;
} }

View File

@ -38,5 +38,33 @@ test.describe('segment: toolbar', () => {
expect(await header.screenshot()).toMatchSnapshot(`segment-toolbar-color-${page.getSnapshotSettings()}.png`); expect(await header.screenshot()).toMatchSnapshot(`segment-toolbar-color-${page.getSnapshotSettings()}.png`);
}); });
test('should not inherit height when segment is MD and toolbar is iOS', async ({ page, skip }) => {
skip.rtl();
skip.mode('ios', 'We manually set the mode in this test, so the automatic mode switching is not needed');
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/ionic-team/ionic-framework/issues/18617',
});
await page.setContent(`
<ion-header>
<ion-toolbar mode="ios" color="primary">
<ion-segment mode="md" value="a">
<ion-segment-button value="a">First</ion-segment-button>
<ion-segment-button value="b">Second</ion-segment-button>
<ion-segment-button value="c" disabled="true">Third</ion-segment-button>
</ion-segment>
</ion-toolbar>
</ion-header>
`);
const header = page.locator('ion-header');
expect(await header.screenshot()).toMatchSnapshot(
`segment-toolbar-height-inherit-${page.getSnapshotSettings()}.png`
);
});
}); });
}); });

View File

@ -27,15 +27,6 @@
max-width: 100%; max-width: 100%;
} }
// Toolbar: Segment
// --------------------------------------------------
::slotted(ion-segment) {
min-height: var(--min-height);
}
// Material Design Toolbar Buttons // Material Design Toolbar Buttons
// -------------------------------------------------- // --------------------------------------------------

View File

@ -19,9 +19,6 @@ $font-family-base: var(--ion-font-family, inherit) !default;
// Global app direction // Global app direction
$app-direction: null !default; $app-direction: null !default;
// Global font path
$font-path: "/dist/fonts" !default;
// Hairlines width // Hairlines width
$hairlines-width: .55px !default; $hairlines-width: .55px !default;

View File

@ -0,0 +1,42 @@
import { inheritAriaAttributes } from './helpers';
describe('inheritAriaAttributes', () => {
it('should inherit aria attributes', () => {
const parent = document.createElement('div');
parent.setAttribute('aria-label', 'parent');
parent.setAttribute('aria-hidden', 'true');
parent.setAttribute('role', 'button');
const inheritedAriaAttributes = inheritAriaAttributes(parent);
expect(inheritedAriaAttributes).toEqual({
'aria-label': 'parent',
'aria-hidden': 'true',
role: 'button',
});
});
it('should not inherit non-aria attributes', () => {
const parent = document.createElement('button');
parent.setAttribute('type', 'submit');
const inheritedAriaAttributes = inheritAriaAttributes(parent);
expect(inheritedAriaAttributes).toEqual({});
});
it('attributes that are ignored should not be returned', () => {
const parent = document.createElement('div');
parent.setAttribute('aria-label', 'parent');
parent.setAttribute('aria-hidden', 'true');
parent.setAttribute('role', 'button');
const ignoreList = ['aria-hidden'];
const inheritedAriaAttributes = inheritAriaAttributes(parent, ignoreList);
expect(inheritedAriaAttributes).toEqual({
'aria-label': 'parent',
role: 'button',
});
});
});

View File

@ -167,9 +167,15 @@ const ariaAttributes = [
* Returns an array of aria attributes that should be copied from * Returns an array of aria attributes that should be copied from
* the shadow host element to a target within the light DOM. * the shadow host element to a target within the light DOM.
* @param el The element that the attributes should be copied from. * @param el The element that the attributes should be copied from.
* @param ignoreList The list of aria-attributes to ignore reflecting and removing from the host.
* Use this in instances where we manually specify aria attributes on the `<Host>` element.
*/ */
export const inheritAriaAttributes = (el: HTMLElement) => { export const inheritAriaAttributes = (el: HTMLElement, ignoreList?: string[]) => {
return inheritAttributes(el, ariaAttributes); let attributesToInherit = ariaAttributes;
if (ignoreList && ignoreList.length > 0) {
attributesToInherit = attributesToInherit.filter((attr) => !ignoreList.includes(attr));
}
return inheritAttributes(el, attributesToInherit);
}; };
export const addEventListener = (el: any, eventName: string, callback: any, opts?: any) => { export const addEventListener = (el: any, eventName: string, callback: any, opts?: any) => {

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic-docs/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/docs
# [6.3.0](https://github.com/ionic-team/ionic-docs/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic-docs/compare/v6.2.9...v6.3.0) (2022-10-05)
**Note:** Version bump only for package @ionic/docs **Note:** Version bump only for package @ionic/docs

View File

@ -1,12 +1,12 @@
{ {
"name": "@ionic/docs", "name": "@ionic/docs",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/docs", "name": "@ionic/docs",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT" "license": "MIT"
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/docs", "name": "@ionic/docs",
"version": "6.3.0", "version": "6.3.1",
"description": "Pre-packaged API documentation for the Ionic docs.", "description": "Pre-packaged API documentation for the Ionic docs.",
"main": "core.json", "main": "core.json",
"types": "core.d.ts", "types": "core.d.ts",

View File

@ -5,5 +5,5 @@
"angular", "angular",
"packages/*" "packages/*"
], ],
"version": "6.3.0" "version": "6.3.1"
} }

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/angular-server
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
**Note:** Version bump only for package @ionic/angular-server **Note:** Version bump only for package @ionic/angular-server

View File

@ -1,12 +1,12 @@
{ {
"name": "@ionic/angular-server", "name": "@ionic/angular-server",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/angular-server", "name": "@ionic/angular-server",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@angular-eslint/eslint-plugin": "^12.6.1", "@angular-eslint/eslint-plugin": "^12.6.1",
@ -18,7 +18,7 @@
"@angular/platform-browser": "^12.0.0", "@angular/platform-browser": "^12.0.0",
"@angular/platform-browser-dynamic": "^12.2.10", "@angular/platform-browser-dynamic": "^12.2.10",
"@angular/platform-server": "^12.0.0", "@angular/platform-server": "^12.0.0",
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"@ionic/eslint-config": "^0.3.0", "@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0", "@ionic/prettier-config": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^5.2.0", "@typescript-eslint/eslint-plugin": "^5.2.0",
@ -786,9 +786,9 @@
"license": "BSD-3-Clause" "license": "BSD-3-Clause"
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
@ -7116,9 +7116,9 @@
"dev": true "dev": true
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dev": true, "dev": true,
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/angular-server", "name": "@ionic/angular-server",
"version": "6.3.0", "version": "6.3.1",
"description": "Angular SSR Module for Ionic", "description": "Angular SSR Module for Ionic",
"keywords": [ "keywords": [
"ionic", "ionic",
@ -56,7 +56,7 @@
"@angular/platform-browser": "^12.0.0", "@angular/platform-browser": "^12.0.0",
"@angular/platform-browser-dynamic": "^12.2.10", "@angular/platform-browser-dynamic": "^12.2.10",
"@angular/platform-server": "^12.0.0", "@angular/platform-server": "^12.0.0",
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"@ionic/eslint-config": "^0.3.0", "@ionic/eslint-config": "^0.3.0",
"@ionic/prettier-config": "^2.0.0", "@ionic/prettier-config": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^5.2.0", "@typescript-eslint/eslint-plugin": "^5.2.0",

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/react-router
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
**Note:** Version bump only for package @ionic/react-router **Note:** Version bump only for package @ionic/react-router

View File

@ -1,15 +1,15 @@
{ {
"name": "@ionic/react-router", "name": "@ionic/react-router",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/react-router", "name": "@ionic/react-router",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ionic/react": "^6.3.0", "@ionic/react": "^6.3.1",
"tslib": "*" "tslib": "*"
}, },
"devDependencies": { "devDependencies": {
@ -147,9 +147,9 @@
} }
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -157,11 +157,11 @@
} }
}, },
"node_modules/@ionic/react": { "node_modules/@ionic/react": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.3.1.tgz",
"integrity": "sha512-h84M4HnhopKA7+vfnmB6zoOGJbun74LP1XtXluGi15Bi/buXCeBtHdgLunzLW50G/JMI6QvksyyQa/bhgRI+Eg==", "integrity": "sha512-8Omxifn+b6wXjfm/+OH+AzKpFsR7xn0u8dxaAKeT66txh4fA7DBMgzEPBOe5+VvWarWI6B7cElX/7Xq8qJNwbw==",
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2", "ionicons": "^6.0.2",
"tslib": "*" "tslib": "*"
}, },
@ -1157,9 +1157,9 @@
} }
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -1167,11 +1167,11 @@
} }
}, },
"@ionic/react": { "@ionic/react": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/react/-/react-6.3.1.tgz",
"integrity": "sha512-h84M4HnhopKA7+vfnmB6zoOGJbun74LP1XtXluGi15Bi/buXCeBtHdgLunzLW50G/JMI6QvksyyQa/bhgRI+Eg==", "integrity": "sha512-8Omxifn+b6wXjfm/+OH+AzKpFsR7xn0u8dxaAKeT66txh4fA7DBMgzEPBOe5+VvWarWI6B7cElX/7Xq8qJNwbw==",
"requires": { "requires": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2", "ionicons": "^6.0.2",
"tslib": "*" "tslib": "*"
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/react-router", "name": "@ionic/react-router",
"version": "6.3.0", "version": "6.3.1",
"description": "React Router wrapper for @ionic/react", "description": "React Router wrapper for @ionic/react",
"keywords": [ "keywords": [
"ionic", "ionic",
@ -37,7 +37,7 @@
"dist/" "dist/"
], ],
"dependencies": { "dependencies": {
"@ionic/react": "^6.3.0", "@ionic/react": "^6.3.1",
"tslib": "*" "tslib": "*"
}, },
"peerDependencies": { "peerDependencies": {

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/react
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
**Note:** Version bump only for package @ionic/react **Note:** Version bump only for package @ionic/react

View File

@ -1,15 +1,15 @@
{ {
"name": "@ionic/react", "name": "@ionic/react",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/react", "name": "@ionic/react",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2", "ionicons": "^6.0.2",
"tslib": "*" "tslib": "*"
}, },
@ -607,9 +607,9 @@
} }
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -9534,9 +9534,9 @@
} }
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/react", "name": "@ionic/react",
"version": "6.3.0", "version": "6.3.1",
"description": "React specific wrapper for @ionic/core", "description": "React specific wrapper for @ionic/core",
"keywords": [ "keywords": [
"ionic", "ionic",
@ -41,7 +41,7 @@
"css/" "css/"
], ],
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2", "ionicons": "^6.0.2",
"tslib": "*" "tslib": "*"
}, },

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/vue-router
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)
**Note:** Version bump only for package @ionic/vue-router **Note:** Version bump only for package @ionic/vue-router

View File

@ -1,15 +1,15 @@
{ {
"name": "@ionic/vue-router", "name": "@ionic/vue-router",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/vue-router", "name": "@ionic/vue-router",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ionic/vue": "^6.3.0" "@ionic/vue": "^6.3.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^28.1.1", "@types/jest": "^28.1.1",
@ -578,9 +578,9 @@
"dev": true "dev": true
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -588,11 +588,11 @@
} }
}, },
"node_modules/@ionic/vue": { "node_modules/@ionic/vue": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.3.1.tgz",
"integrity": "sha512-9D7bK8xZ/qa6gWShgvBRCFSmwkZBN7RkJF1ItmNQXl1msszRjqi7W/++AsTjjGmqpWbupNkwwxZWP7IzN7vcjA==", "integrity": "sha512-QFPF9Pshg4Ns3UDrbA+vGA1QyadIvW0r1Gct6Rv9S/eAfHMOXfAiaIqUgTy0BrFjcR+VCgiCZzg1atEvU0XvyA==",
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2" "ionicons": "^6.0.2"
} }
}, },
@ -5233,9 +5233,9 @@
"dev": true "dev": true
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -5243,11 +5243,11 @@
} }
}, },
"@ionic/vue": { "@ionic/vue": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-6.3.1.tgz",
"integrity": "sha512-9D7bK8xZ/qa6gWShgvBRCFSmwkZBN7RkJF1ItmNQXl1msszRjqi7W/++AsTjjGmqpWbupNkwwxZWP7IzN7vcjA==", "integrity": "sha512-QFPF9Pshg4Ns3UDrbA+vGA1QyadIvW0r1Gct6Rv9S/eAfHMOXfAiaIqUgTy0BrFjcR+VCgiCZzg1atEvU0XvyA==",
"requires": { "requires": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2" "ionicons": "^6.0.2"
} }
}, },

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/vue-router", "name": "@ionic/vue-router",
"version": "6.3.0", "version": "6.3.1",
"description": "Vue Router integration for @ionic/vue", "description": "Vue Router integration for @ionic/vue",
"scripts": { "scripts": {
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
@ -44,7 +44,7 @@
}, },
"homepage": "https://github.com/ionic-team/ionic#readme", "homepage": "https://github.com/ionic-team/ionic#readme",
"dependencies": { "dependencies": {
"@ionic/vue": "^6.3.0" "@ionic/vue": "^6.3.1"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^28.1.1", "@types/jest": "^28.1.1",

View File

@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.3.1](https://github.com/ionic-team/ionic/compare/v6.3.0...v6.3.1) (2022-10-12)
**Note:** Version bump only for package @ionic/vue
# [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05) # [6.3.0](https://github.com/ionic-team/ionic/compare/v6.2.9...v6.3.0) (2022-10-05)

View File

@ -1,15 +1,15 @@
{ {
"name": "@ionic/vue", "name": "@ionic/vue",
"version": "6.3.0", "version": "6.3.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@ionic/vue", "name": "@ionic/vue",
"version": "6.3.0", "version": "6.3.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2" "ionicons": "^6.0.2"
}, },
"devDependencies": { "devDependencies": {
@ -59,9 +59,9 @@
} }
}, },
"node_modules/@ionic/core": { "node_modules/@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"dependencies": { "dependencies": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",
@ -768,9 +768,9 @@
} }
}, },
"@ionic/core": { "@ionic/core": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.0.tgz", "resolved": "https://registry.npmjs.org/@ionic/core/-/core-6.3.1.tgz",
"integrity": "sha512-6MR0hOdIM6sQyZyXez3/jWAnHScrZKaQxzGT2XiXXIpBrKztNdeAhqDLXoxbDU1PLyDnXXPWBzT6xZ698gG67g==", "integrity": "sha512-OpmGQQ/sGtoXW4PQRvRjYa9mTlAmAWwFMu8g/1rcdAPaTQQAlRnfZ62wYYqmChLSFlVbn6mCleeljzR9FaYrAg==",
"requires": { "requires": {
"@stencil/core": "^2.18.0", "@stencil/core": "^2.18.0",
"ionicons": "^6.0.3", "ionicons": "^6.0.3",

View File

@ -1,6 +1,6 @@
{ {
"name": "@ionic/vue", "name": "@ionic/vue",
"version": "6.3.0", "version": "6.3.1",
"description": "Vue specific wrapper for @ionic/core", "description": "Vue specific wrapper for @ionic/core",
"scripts": { "scripts": {
"prepublishOnly": "npm run build", "prepublishOnly": "npm run build",
@ -61,7 +61,7 @@
"vue-router": "^4.0.16" "vue-router": "^4.0.16"
}, },
"dependencies": { "dependencies": {
"@ionic/core": "^6.3.0", "@ionic/core": "^6.3.1",
"ionicons": "^6.0.2" "ionicons": "^6.0.2"
}, },
"vetur": { "vetur": {