mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-14 16:52:26 +08:00
chore(): sync with main
This commit is contained in:
1
.github/dependabot.yml
vendored
1
.github/dependabot.yml
vendored
@ -7,3 +7,4 @@ updates:
|
||||
allow:
|
||||
- dependency-name: "@playwright/test"
|
||||
- dependency-name: "@axe-core/playwright"
|
||||
- dependency-name: "@stencil/core"
|
||||
|
15
CHANGELOG.md
15
CHANGELOG.md
@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.6.2](https://github.com/ionic-team/ionic-framework/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **accordion:** include margins during expand animation ([#26390](https://github.com/ionic-team/ionic-framework/issues/26390)) ([f809918](https://github.com/ionic-team/ionic-framework/commit/f80991813ae8873d8ef6038b0aeb763d727f402e)), closes [#26381](https://github.com/ionic-team/ionic-framework/issues/26381)
|
||||
* **IonicSlides:** remove unnecessary autoplay option ([#26935](https://github.com/ionic-team/ionic-framework/issues/26935)) ([b8f8937](https://github.com/ionic-team/ionic-framework/commit/b8f893731471052df198824b7ece47606ffcc500))
|
||||
* **radio:** checked state is updated when value changes ([#26936](https://github.com/ionic-team/ionic-framework/issues/26936)) ([27a5356](https://github.com/ionic-team/ionic-framework/commit/27a5356fa2b72073d565e9d6f527107869faa3ee))
|
||||
* **react/vue:** properly switch ionicon based on the mode when ios/md is set ([#26924](https://github.com/ionic-team/ionic-framework/issues/26924)) ([1eb9a08](https://github.com/ionic-team/ionic-framework/commit/1eb9a085b2d69dfcfc71ff49b25d33347dd54aae)), closes [#26207](https://github.com/ionic-team/ionic-framework/issues/26207)
|
||||
* **textarea:** inherit tabindex to inner textarea ([#26945](https://github.com/ionic-team/ionic-framework/issues/26945)) ([2c68d01](https://github.com/ionic-team/ionic-framework/commit/2c68d01b898a2f879445b8b64014189afe1255d7)), closes [#26944](https://github.com/ionic-team/ionic-framework/issues/26944)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic-framework/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
|
||||
|
@ -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.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
|
||||
|
@ -3,6 +3,21 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **accordion:** include margins during expand animation ([#26390](https://github.com/ionic-team/ionic/issues/26390)) ([f809918](https://github.com/ionic-team/ionic/commit/f80991813ae8873d8ef6038b0aeb763d727f402e)), closes [#26381](https://github.com/ionic-team/ionic/issues/26381)
|
||||
* **IonicSlides:** remove unnecessary autoplay option ([#26935](https://github.com/ionic-team/ionic/issues/26935)) ([b8f8937](https://github.com/ionic-team/ionic/commit/b8f893731471052df198824b7ece47606ffcc500))
|
||||
* **radio:** checked state is updated when value changes ([#26936](https://github.com/ionic-team/ionic/issues/26936)) ([27a5356](https://github.com/ionic-team/ionic/commit/27a5356fa2b72073d565e9d6f527107869faa3ee))
|
||||
* **react/vue:** properly switch ionicon based on the mode when ios/md is set ([#26924](https://github.com/ionic-team/ionic/issues/26924)) ([1eb9a08](https://github.com/ionic-team/ionic/commit/1eb9a085b2d69dfcfc71ff49b25d33347dd54aae)), closes [#26207](https://github.com/ionic-team/ionic/issues/26207)
|
||||
* **textarea:** inherit tabindex to inner textarea ([#26945](https://github.com/ionic-team/ionic/issues/26945)) ([2c68d01](https://github.com/ionic-team/ionic/commit/2c68d01b898a2f879445b8b64014189afe1255d7)), closes [#26944](https://github.com/ionic-team/ionic/issues/26944)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
|
||||
|
@ -57,6 +57,14 @@
|
||||
max-height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent margins of content-wrapper
|
||||
* from collapsing, breaking the animation.
|
||||
*/
|
||||
:host(.accordion-expanding) #content-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:host(.accordion-disabled) #header,
|
||||
:host(.accordion-readonly) #header,
|
||||
:host(.accordion-disabled) #content,
|
||||
|
@ -77,6 +77,26 @@
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
</div>
|
||||
|
||||
<div class="grid-item">
|
||||
<h2>Margins In Content</h2>
|
||||
|
||||
<ion-accordion-group>
|
||||
<ion-accordion>
|
||||
<ion-item slot="header"> Accordion </ion-item>
|
||||
<ion-card slot="content" style="margin: 100px 16px">
|
||||
<ion-card-header>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Here's a small text description for the card content. Nothing more, nothing less.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</ion-accordion>
|
||||
</ion-accordion-group>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
@ -26,6 +26,9 @@ export interface AlertInput {
|
||||
name?: string;
|
||||
placeholder?: string;
|
||||
value?: any; // TODO(FW-2832): type
|
||||
/**
|
||||
* The label text to display next to the input, if the input type is `radio` or `checkbox`.
|
||||
*/
|
||||
label?: string;
|
||||
checked?: boolean;
|
||||
disabled?: boolean;
|
||||
|
@ -87,6 +87,30 @@
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item>
|
||||
<ion-icon slot="start" ios="star-outline" md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" mode="ios" ios="star-outline" md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<h3>mode: ios</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" mode="md" ios="star-outline" md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<h3>mode: md</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item detail="true">
|
||||
<ion-label>
|
||||
<code> ion-item w/ [detail="true"] attr. text text text text text text </code>
|
||||
|
14
core/src/components/input/test/input.spec.ts
Normal file
14
core/src/components/input/test/input.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
import { Input } from '../input';
|
||||
|
||||
it('should inherit attributes', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Input],
|
||||
html: '<ion-input title="my title" tabindex="-1" data-form-type="password"></ion-input>',
|
||||
});
|
||||
|
||||
const nativeEl = page.body.querySelector('ion-input input');
|
||||
expect(nativeEl.getAttribute('title')).toBe('my title');
|
||||
expect(nativeEl.getAttribute('tabindex')).toBe('-1');
|
||||
expect(nativeEl.getAttribute('data-form-type')).toBe('password');
|
||||
});
|
@ -71,6 +71,16 @@ export class Radio implements ComponentInterface {
|
||||
*/
|
||||
@Prop() value?: any | null;
|
||||
|
||||
@Watch('value')
|
||||
valueChanged() {
|
||||
/**
|
||||
* The new value of the radio may
|
||||
* match the radio group's value,
|
||||
* so we see if it should be checked.
|
||||
*/
|
||||
this.updateState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to place the label relative to the radio.
|
||||
* `"start"`: The label will appear to the left of the radio in LTR and to the right in RTL.
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { Radio } from '../radio.tsx';
|
||||
import { RadioGroup } from '../../radio-group/radio-group.tsx';
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
describe('ion-radio', () => {
|
||||
it('should set a default value', async () => {
|
||||
@ -8,4 +10,24 @@ describe('ion-radio', () => {
|
||||
|
||||
expect(radio.value).toEqual('ion-rb-0');
|
||||
});
|
||||
|
||||
it('should update the checked state when updating the value', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Radio, RadioGroup],
|
||||
html: `
|
||||
<ion-radio-group value="a">
|
||||
<ion-radio value="other-value"></ion-radio>
|
||||
</ion-radio-group>
|
||||
`,
|
||||
});
|
||||
|
||||
const radio = page.root.querySelector('ion-radio');
|
||||
expect(radio.classList.contains('radio-checked')).toBe(false);
|
||||
|
||||
radio.value = 'a';
|
||||
|
||||
await page.waitForChanges();
|
||||
|
||||
expect(radio.classList.contains('radio-checked')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
@ -2,8 +2,12 @@ import { expect } from '@playwright/test';
|
||||
import type { E2EPage } from '@utils/test/playwright';
|
||||
import { test } from '@utils/test/playwright';
|
||||
|
||||
// TODO FW-3081
|
||||
test.describe.skip('ripple-effect: basic', () => {
|
||||
test.describe('ripple-effect: basic', () => {
|
||||
test.beforeEach(async ({ skip }) => {
|
||||
skip.rtl();
|
||||
skip.mode('ios');
|
||||
});
|
||||
|
||||
test('should add .ion-activated when pressed', async ({ page }) => {
|
||||
await verifyRippleEffect(page, '#small-btn');
|
||||
await verifyRippleEffect(page, '#large-btn');
|
||||
@ -14,7 +18,7 @@ test.describe.skip('ripple-effect: basic', () => {
|
||||
|
||||
test.describe('ripple effect with nested ion-button', () => {
|
||||
test('should add .ion-activated when the block is pressed', async ({ page }) => {
|
||||
await page.goto(`/src/components/ripple-effect/test/basic?ionic:_testing=false&ionic:mode=md`);
|
||||
await page.goto('/src/components/ripple-effect/test/basic?ionic:_testing=false');
|
||||
|
||||
const el = page.locator('#ripple-with-button');
|
||||
|
||||
@ -30,9 +34,7 @@ test.describe.skip('ripple-effect: basic', () => {
|
||||
// Waits for the ripple effect to be added
|
||||
await page.waitForSelector('.ion-activated');
|
||||
|
||||
const elHandle = await el.elementHandle();
|
||||
const classes = await elHandle?.evaluate((el) => el.classList.value);
|
||||
expect(classes).toMatch(/ion-activated/);
|
||||
await expect(el).toHaveClass(/ion-activated/);
|
||||
});
|
||||
|
||||
test('should add .ion-activated when the button is pressed', async ({ page }) => {
|
||||
@ -42,7 +44,7 @@ test.describe.skip('ripple-effect: basic', () => {
|
||||
});
|
||||
|
||||
const verifyRippleEffect = async (page: E2EPage, selector: string) => {
|
||||
await page.goto(`/src/components/ripple-effect/test/basic?ionic:_testing=false&ionic:mode=md`);
|
||||
await page.goto('/src/components/ripple-effect/test/basic?ionic:_testing=false');
|
||||
|
||||
const el = page.locator(selector);
|
||||
|
||||
@ -55,10 +57,7 @@ const verifyRippleEffect = async (page: E2EPage, selector: string) => {
|
||||
await page.mouse.down();
|
||||
}
|
||||
|
||||
// Waits for the ripple effect to be added
|
||||
await page.waitForSelector(`${selector}.ion-activated`);
|
||||
await page.waitForSelector('.ion-activated');
|
||||
|
||||
const elHandle = await el.elementHandle();
|
||||
const classes = await elHandle?.evaluate((el) => el.classList.value);
|
||||
expect(classes).toMatch(/ion-activated/);
|
||||
await expect(el).toHaveClass(/ion-activated/);
|
||||
};
|
||||
|
@ -10,7 +10,8 @@ test.describe('segment: a11y', () => {
|
||||
expect(results.violations).toEqual([]);
|
||||
});
|
||||
|
||||
test('segment buttons should be keyboard navigable', async ({ page, browserName, skip }, testInfo) => {
|
||||
// TODO FW-3710
|
||||
test.skip('segment buttons should be keyboard navigable', async ({ page, browserName, skip }, testInfo) => {
|
||||
// TODO (FW-2979)
|
||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||
const tabKey = browserName === 'webkit' ? 'Alt+Tab' : 'Tab';
|
||||
|
@ -16,7 +16,6 @@ export const IonicSlides = (opts: any) => {
|
||||
slidesOffsetBefore: 0,
|
||||
slidesOffsetAfter: 0,
|
||||
touchEventsTarget: 'container',
|
||||
autoplay: false,
|
||||
freeMode: false,
|
||||
freeModeMomentum: true,
|
||||
freeModeMomentumRatio: 1,
|
||||
|
14
core/src/components/textarea/test/textarea.spec.ts
Normal file
14
core/src/components/textarea/test/textarea.spec.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
import { Textarea } from '../textarea';
|
||||
|
||||
it('should inherit attributes', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Textarea],
|
||||
html: '<ion-textarea title="my title" tabindex="-1" data-form-type="password"></ion-textarea>',
|
||||
});
|
||||
|
||||
const nativeEl = page.body.querySelector('ion-textarea textarea');
|
||||
expect(nativeEl.getAttribute('title')).toBe('my title');
|
||||
expect(nativeEl.getAttribute('tabindex')).toBe('-1');
|
||||
expect(nativeEl.getAttribute('data-form-type')).toBe('password');
|
||||
});
|
@ -310,7 +310,7 @@ export class Textarea implements ComponentInterface {
|
||||
componentWillLoad() {
|
||||
this.inheritedAttributes = {
|
||||
...inheritAriaAttributes(this.el),
|
||||
...inheritAttributes(this.el, ['data-form-type', 'title']),
|
||||
...inheritAttributes(this.el, ['data-form-type', 'title', 'tabindex']),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,15 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic-docs/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
## [6.6.2](https://github.com/ionic-team/ionic-docs/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic-docs/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @ionic/docs
|
||||
|
||||
|
@ -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.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @ionic/angular-server
|
||||
|
@ -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.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @ionic/react-router
|
||||
|
1
packages/react-router/package-lock.json
generated
1
packages/react-router/package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ionic/react": "^7.0.0-rc.1",
|
||||
|
||||
"tslib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -3,6 +3,18 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
|
||||
* **react/vue:** properly switch ionicon based on the mode when ios/md is set ([#26924](https://github.com/ionic-team/ionic/issues/26924)) ([1eb9a08](https://github.com/ionic-team/ionic/commit/1eb9a085b2d69dfcfc71ff49b25d33347dd54aae)), closes [#26207](https://github.com/ionic-team/ionic/issues/26207)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { NavContext } from '../contexts/NavContext';
|
||||
|
||||
import type { IonicReactProps } from './IonicReactProps';
|
||||
import { IonIconInner } from './inner-proxies';
|
||||
import { createForwardRef, isPlatform } from './utils';
|
||||
import { createForwardRef, getConfig } from './utils';
|
||||
|
||||
interface IonIconProps {
|
||||
color?: string;
|
||||
@ -34,12 +34,15 @@ class IonIconContainer extends React.PureComponent<InternalProps> {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { icon, ios, md, ...rest } = this.props;
|
||||
const { icon, ios, md, mode, ...rest } = this.props;
|
||||
|
||||
let iconToUse: typeof icon;
|
||||
|
||||
const config = getConfig();
|
||||
const iconMode = mode || config?.get('mode');
|
||||
|
||||
if (ios || md) {
|
||||
if (isPlatform('ios')) {
|
||||
if (iconMode === 'ios') {
|
||||
iconToUse = ios ?? md ?? icon;
|
||||
} else {
|
||||
iconToUse = md ?? ios ?? icon;
|
||||
|
47
packages/react/test-app/README.md
Normal file
47
packages/react/test-app/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# React Test App
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Setup
|
||||
|
||||
Make sure you are using the latest versions of node and npm. If you do not have these, [download the installer](https://nodejs.org/) for the LTS version of Node.js. This is the best way to also [install npm](https://blog.npmjs.org/post/85484771375/how-to-install-npm#_=_).
|
||||
|
||||
### Building Dependencies
|
||||
|
||||
Navigate to the `core`, `packages/react` and `packages/react-router` directories and build each of them:
|
||||
|
||||
```bash
|
||||
npm i
|
||||
npm run build
|
||||
```
|
||||
|
||||
Then, install dependencies from this directory for this test app:
|
||||
|
||||
```
|
||||
npm i
|
||||
```
|
||||
|
||||
### Syncing Changes
|
||||
|
||||
When making changes to the React package, run the following from this directory to sync the changes:
|
||||
|
||||
```bash
|
||||
npm run sync
|
||||
```
|
||||
|
||||
### Previewing App
|
||||
|
||||
To preview this app locally, run the following from this directory:
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
To run the e2e tests, run the following from this directory:
|
||||
|
||||
```
|
||||
npm run build
|
||||
npm run e2e
|
||||
```
|
1
packages/react/test-app/public/assets/logo-android.svg
Normal file
1
packages/react/test-app/public/assets/logo-android.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon md android" viewBox="0 0 512 512"><title>Logo Android</title><path d="M380.91 199l42.47-73.57a8.63 8.63 0 00-3.12-11.76 8.52 8.52 0 00-11.71 3.12l-43 74.52c-32.83-15-69.78-23.35-109.52-23.35s-76.69 8.36-109.52 23.35l-43-74.52a8.6 8.6 0 10-14.88 8.64L131 199C57.8 238.64 8.19 312.77 0 399.55h512c-8.19-86.78-57.8-160.91-131.09-200.55zM138.45 327.65a21.46 21.46 0 1121.46-21.46 21.47 21.47 0 01-21.46 21.46zm235 0A21.46 21.46 0 11395 306.19a21.47 21.47 0 01-21.51 21.46z"/></svg>
|
After Width: | Height: | Size: 533 B |
1
packages/react/test-app/public/assets/logo-apple.svg
Normal file
1
packages/react/test-app/public/assets/logo-apple.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon ios apple" viewBox="0 0 512 512"><title>Logo Apple</title><path d="M349.13 136.86c-40.32 0-57.36 19.24-85.44 19.24-28.79 0-50.75-19.1-85.69-19.1-34.2 0-70.67 20.88-93.83 56.45-32.52 50.16-27 144.63 25.67 225.11 18.84 28.81 44 61.12 77 61.47h.6c28.68 0 37.2-18.78 76.67-19h.6c38.88 0 46.68 18.89 75.24 18.89h.6c33-.35 59.51-36.15 78.35-64.85 13.56-20.64 18.6-31 29-54.35-76.19-28.92-88.43-136.93-13.08-178.34-23-28.8-55.32-45.48-85.79-45.48z"/><path d="M340.25 32c-24 1.63-52 16.91-68.4 36.86-14.88 18.08-27.12 44.9-22.32 70.91h1.92c25.56 0 51.72-15.39 67-35.11 14.72-18.77 25.88-45.37 21.8-72.66z"/></svg>
|
After Width: | Height: | Size: 661 B |
@ -26,6 +26,7 @@ import OverlayHooks from './pages/overlay-hooks/OverlayHooks';
|
||||
import OverlayComponents from './pages/overlay-components/OverlayComponents';
|
||||
import KeepContentsMounted from './pages/overlay-components/KeepContentsMounted';
|
||||
import Tabs from './pages/Tabs';
|
||||
import Icons from './pages/Icons';
|
||||
import NavComponent from './pages/navigation/NavComponent';
|
||||
import IonModalConditionalSibling from './pages/overlay-components/IonModalConditionalSibling';
|
||||
import IonModalConditional from './pages/overlay-components/IonModalConditional';
|
||||
@ -54,6 +55,7 @@ const App: React.FC = () => (
|
||||
<Route path="/keep-contents-mounted" component={KeepContentsMounted} />
|
||||
<Route path="/navigation" component={NavComponent} />
|
||||
<Route path="/tabs" component={Tabs} />
|
||||
<Route path="/icons" component={Icons} />
|
||||
</IonRouterOutlet>
|
||||
</IonReactRouter>
|
||||
</IonApp>
|
||||
|
95
packages/react/test-app/src/pages/Icons.tsx
Normal file
95
packages/react/test-app/src/pages/Icons.tsx
Normal file
@ -0,0 +1,95 @@
|
||||
import React, { useState } from 'react';
|
||||
import { IonBackButton, IonButton, IonButtons, IonContent, IonHeader, IonIcon, IonItem, IonLabel, IonList, IonTitle, IonToolbar } from '@ionic/react';
|
||||
import { heart, heartCircleOutline, logoApple, logoTwitter, personCircleOutline, star, starOutline, trash } from 'ionicons/icons';
|
||||
|
||||
interface IconsProps {}
|
||||
|
||||
const Icons: React.FC<IconsProps> = () => {
|
||||
const [dynamic, setDynamic] = useState(star);
|
||||
const iosCustomSvg = "../assets/logo-apple.svg";
|
||||
const mdCustomSvg = "../assets/logo-android.svg";
|
||||
|
||||
const toggle = () => {
|
||||
setDynamic(dynamic => dynamic === star ? starOutline : star);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<IonHeader translucent={true}>
|
||||
<IonToolbar>
|
||||
<IonButtons>
|
||||
<IonBackButton></IonBackButton>
|
||||
</IonButtons>
|
||||
<IonTitle>Icons</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonContent fullscreen={true}>
|
||||
<IonHeader collapse="condense">
|
||||
<IonToolbar>
|
||||
<IonTitle size="large">Icons</IonTitle>
|
||||
</IonToolbar>
|
||||
</IonHeader>
|
||||
|
||||
<IonList>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" icon={heart}></IonIcon>
|
||||
<IonLabel>Static Icons</IonLabel>
|
||||
<IonIcon slot="end" icon={personCircleOutline} color="dark"></IonIcon>
|
||||
<IonIcon slot="end" icon={trash} color="danger"></IonIcon>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon icon={logoApple} slot="start"></IonIcon>
|
||||
<IonLabel>Logo Icons</IonLabel>
|
||||
<IonIcon icon={logoTwitter} slot="end"></IonIcon>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" icon={dynamic} color="warning"></IonIcon>
|
||||
<IonLabel>Dynamic Icon</IonLabel>
|
||||
<IonButton slot="end" fill="outline" onClick={() => toggle()}>
|
||||
Toggle Icon
|
||||
</IonButton>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" ios={heartCircleOutline} md={personCircleOutline}></IonIcon>
|
||||
<IonLabel>
|
||||
<p>ios: heart circle</p>
|
||||
<p>md: person circle</p>
|
||||
</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" ios={starOutline} md={star}></IonIcon>
|
||||
<IonLabel>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" mode="ios" ios={starOutline} md={star}></IonIcon>
|
||||
<IonLabel>
|
||||
<h3>mode: ios</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon slot="start" mode="md" ios={starOutline} md={star}></IonIcon>
|
||||
<IonLabel>
|
||||
<h3>mode: md</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem>
|
||||
<IonIcon id="customSvg" slot="start" ios={iosCustomSvg} md={mdCustomSvg}></IonIcon>
|
||||
<IonLabel>
|
||||
<p>Custom SVG</p>
|
||||
</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Icons;
|
@ -25,26 +25,21 @@ const Main: React.FC<MainProps> = () => {
|
||||
<IonItem routerLink="/overlay-hooks">
|
||||
<IonLabel>Overlay Hooks</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
<IonList>
|
||||
<IonItem routerLink="/overlay-components">
|
||||
<IonLabel>Overlay Components</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
<IonList>
|
||||
<IonItem routerLink="/keep-contents-mounted">
|
||||
<IonLabel>Keep Contents Mounted Overlay Components</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
<IonList>
|
||||
<IonItem routerLink="/navigation">
|
||||
<IonLabel>Navigation</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
<IonList>
|
||||
<IonItem routerLink="/tabs">
|
||||
<IonLabel>Tabs</IonLabel>
|
||||
</IonItem>
|
||||
<IonItem routerLink="/icons">
|
||||
<IonLabel>Icons</IonLabel>
|
||||
</IonItem>
|
||||
</IonList>
|
||||
</IonContent>
|
||||
</IonPage>
|
||||
|
22
packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts
Normal file
22
packages/react/test-app/tests/e2e/specs/icons/icons.cy.ts
Normal file
@ -0,0 +1,22 @@
|
||||
describe('Icons', () => {
|
||||
it('should use ios svg', () => {
|
||||
cy.visit('/icons?ionic:mode=ios');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'ios');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'apple');
|
||||
});
|
||||
|
||||
it('should use md svg', () => {
|
||||
cy.visit('/icons?ionic:mode=md');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
|
||||
});
|
||||
|
||||
it('should use fallback md svg', () => {
|
||||
cy.visit('/icons');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
|
||||
});
|
||||
})
|
@ -3,6 +3,15 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
**Note:** Version bump only for package @ionic/vue-router
|
||||
|
@ -3,6 +3,17 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [6.6.2](https://github.com/ionic-team/ionic/compare/v6.6.1...v6.6.2) (2023-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **react/vue:** properly switch ionicon based on the mode when ios/md is set ([#26924](https://github.com/ionic-team/ionic/issues/26924)) ([1eb9a08](https://github.com/ionic-team/ionic/commit/1eb9a085b2d69dfcfc71ff49b25d33347dd54aae)), closes [#26207](https://github.com/ionic-team/ionic/issues/26207)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [7.0.0-rc.1](https://github.com/ionic-team/ionic/compare/v7.0.0-rc.0...v7.0.0-rc.1) (2023-03-08)
|
||||
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { isPlatform } from "@ionic/core/components";
|
||||
import { defineCustomElement } from "ionicons/components/ion-icon.js";
|
||||
import { h, defineComponent } from "vue";
|
||||
|
||||
import { getConfig } from "../utils";
|
||||
|
||||
export const IonIcon = /*@__PURE__*/ defineComponent({
|
||||
name: "IonIcon",
|
||||
props: {
|
||||
@ -19,11 +20,15 @@ export const IonIcon = /*@__PURE__*/ defineComponent({
|
||||
setup(props, { slots }) {
|
||||
defineCustomElement();
|
||||
return () => {
|
||||
const { icon, ios, md } = props;
|
||||
const { icon, ios, md, mode } = props;
|
||||
|
||||
let iconToUse: typeof icon;
|
||||
|
||||
const config = getConfig();
|
||||
const iconMode = mode || config?.get("mode");
|
||||
|
||||
if (ios || md) {
|
||||
if (isPlatform("ios")) {
|
||||
if (iconMode === "ios") {
|
||||
iconToUse = ios ?? md ?? icon;
|
||||
} else {
|
||||
iconToUse = md ?? ios ?? icon;
|
||||
|
1
packages/vue/test/base/public/assets/logo-android.svg
Normal file
1
packages/vue/test/base/public/assets/logo-android.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon md android" viewBox="0 0 512 512"><title>Logo Android</title><path d="M380.91 199l42.47-73.57a8.63 8.63 0 00-3.12-11.76 8.52 8.52 0 00-11.71 3.12l-43 74.52c-32.83-15-69.78-23.35-109.52-23.35s-76.69 8.36-109.52 23.35l-43-74.52a8.6 8.6 0 10-14.88 8.64L131 199C57.8 238.64 8.19 312.77 0 399.55h512c-8.19-86.78-57.8-160.91-131.09-200.55zM138.45 327.65a21.46 21.46 0 1121.46-21.46 21.47 21.47 0 01-21.46 21.46zm235 0A21.46 21.46 0 11395 306.19a21.47 21.47 0 01-21.51 21.46z"/></svg>
|
After Width: | Height: | Size: 533 B |
1
packages/vue/test/base/public/assets/logo-apple.svg
Normal file
1
packages/vue/test/base/public/assets/logo-apple.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon ios apple" viewBox="0 0 512 512"><title>Logo Apple</title><path d="M349.13 136.86c-40.32 0-57.36 19.24-85.44 19.24-28.79 0-50.75-19.1-85.69-19.1-34.2 0-70.67 20.88-93.83 56.45-32.52 50.16-27 144.63 25.67 225.11 18.84 28.81 44 61.12 77 61.47h.6c28.68 0 37.2-18.78 76.67-19h.6c38.88 0 46.68 18.89 75.24 18.89h.6c33-.35 59.51-36.15 78.35-64.85 13.56-20.64 18.6-31 29-54.35-76.19-28.92-88.43-136.93-13.08-178.34-23-28.8-55.32-45.48-85.79-45.48z"/><path d="M340.25 32c-24 1.63-52 16.91-68.4 36.86-14.88 18.08-27.12 44.9-22.32 70.91h1.92c25.56 0 51.72-15.39 67-35.11 14.72-18.77 25.88-45.37 21.8-72.66z"/></svg>
|
After Width: | Height: | Size: 661 B |
@ -33,6 +33,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: '/keep-contents-mounted',
|
||||
component: () => import('@/views/OverlaysKeepContentsMounted.vue')
|
||||
},
|
||||
{
|
||||
path: '/icons',
|
||||
component: () => import('@/views/Icons.vue')
|
||||
},
|
||||
{
|
||||
path: '/inputs',
|
||||
component: () => import('@/views/Inputs.vue')
|
||||
|
@ -20,6 +20,9 @@
|
||||
<ion-item button router-link="/overlays">
|
||||
<ion-label>Overlays</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button router-link="/icons">
|
||||
<ion-label>Icons</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button router-link="/inputs">
|
||||
<ion-label>Inputs</ion-label>
|
||||
</ion-item>
|
||||
|
143
packages/vue/test/base/src/views/Icons.vue
Normal file
143
packages/vue/test/base/src/views/Icons.vue
Normal file
@ -0,0 +1,143 @@
|
||||
<template>
|
||||
<ion-page data-pageid="icons">
|
||||
<ion-header :translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-buttons>
|
||||
<ion-back-button></ion-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Icons</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content :fullscreen="true">
|
||||
<ion-header collapse="condense">
|
||||
<ion-toolbar>
|
||||
<ion-title size="large">Icons</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" :icon="heart"></ion-icon>
|
||||
<ion-label>Static Icons</ion-label>
|
||||
<ion-icon slot="end" :icon="personCircleOutline" color="dark"></ion-icon>
|
||||
<ion-icon slot="end" :icon="trash" color="danger"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon :icon="logoApple" slot="start"></ion-icon>
|
||||
<ion-label>Logo Icons</ion-label>
|
||||
<ion-icon :icon="logoTwitter" slot="end"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" :icon="dynamic" color="warning"></ion-icon>
|
||||
<ion-label>Dynamic Icon</ion-label>
|
||||
<ion-button slot="end" fill="outline" @click="toggle">
|
||||
Toggle Icon
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" :ios="heartCircleOutline" :md="personCircleOutline"></ion-icon>
|
||||
<ion-label>
|
||||
<p>ios: heart circle</p>
|
||||
<p>md: person circle</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" :ios="starOutline" :md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" mode="ios" :ios="starOutline" :md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<h3>mode: ios</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon slot="start" mode="md" :ios="starOutline" :md="star"></ion-icon>
|
||||
<ion-label>
|
||||
<h3>mode: md</h3>
|
||||
<p>ios: star outline</p>
|
||||
<p>md: star</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-icon id="customSvg" slot="start" :ios="iosCustomSvg" :md="mdCustomSvg"></ion-icon>
|
||||
<ion-label>
|
||||
<p>Custom SVG</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
IonBackButton,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonIcon,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar
|
||||
} from '@ionic/vue';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { heart, heartCircleOutline, logoApple, logoTwitter, personCircleOutline, star, starOutline, trash } from 'ionicons/icons';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
IonBackButton,
|
||||
IonButton,
|
||||
IonButtons,
|
||||
IonContent,
|
||||
IonHeader,
|
||||
IonIcon,
|
||||
IonItem,
|
||||
IonLabel,
|
||||
IonList,
|
||||
IonPage,
|
||||
IonTitle,
|
||||
IonToolbar
|
||||
},
|
||||
setup() {
|
||||
const iosCustomSvg = "../assets/logo-apple.svg";
|
||||
const mdCustomSvg = "../assets/logo-android.svg";
|
||||
|
||||
const dynamic = ref(star);
|
||||
|
||||
const toggle = () => {
|
||||
const current = dynamic.value;
|
||||
dynamic.value = current === star ? starOutline : star;
|
||||
}
|
||||
|
||||
return {
|
||||
iosCustomSvg,
|
||||
mdCustomSvg,
|
||||
dynamic,
|
||||
|
||||
heart,
|
||||
heartCircleOutline,
|
||||
logoApple,
|
||||
logoTwitter,
|
||||
personCircleOutline,
|
||||
star,
|
||||
starOutline,
|
||||
trash,
|
||||
|
||||
toggle
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
22
packages/vue/test/base/tests/e2e/specs/icons.cy.js
Normal file
22
packages/vue/test/base/tests/e2e/specs/icons.cy.js
Normal file
@ -0,0 +1,22 @@
|
||||
describe('Icons', () => {
|
||||
it('should use ios svg', () => {
|
||||
cy.visit('http://localhost:8080/icons?ionic:mode=ios');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'ios');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'apple');
|
||||
});
|
||||
|
||||
it('should use md svg', () => {
|
||||
cy.visit('http://localhost:8080/icons?ionic:mode=md');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
|
||||
});
|
||||
|
||||
it('should use fallback md svg', () => {
|
||||
cy.visit('http://localhost:8080/icons');
|
||||
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'md');
|
||||
cy.get('#customSvg').shadow().find('svg').should('have.class', 'android');
|
||||
});
|
||||
})
|
Reference in New Issue
Block a user