Merge branch 'next' into chore-rou-4848-next
@ -29,7 +29,7 @@ runs:
|
|||||||
shell: bash
|
shell: bash
|
||||||
working-directory: ./packages/angular/test
|
working-directory: ./packages/angular/test
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: npm install
|
run: npm install --legacy-peer-deps # TODO(FW-6227): Remove legacy-peer-deps flag
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: ./packages/angular/test/build/${{ inputs.app }}
|
working-directory: ./packages/angular/test/build/${{ inputs.app }}
|
||||||
- name: Sync Built Changes
|
- name: Sync Built Changes
|
||||||
|
2
.github/workflows/assign-issues.yml
vendored
@ -13,6 +13,6 @@ jobs:
|
|||||||
- name: 'Auto-assign issue'
|
- name: 'Auto-assign issue'
|
||||||
uses: pozil/auto-assign-issue@65947009a243e6b3993edeef4e64df3ca85d760c # v1.14.0
|
uses: pozil/auto-assign-issue@65947009a243e6b3993edeef4e64df3ca85d760c # v1.14.0
|
||||||
with:
|
with:
|
||||||
assignees: sean-perkins, brandyscarney, thetaPC
|
assignees: brandyscarney, thetaPC
|
||||||
numOfAssignee: 1
|
numOfAssignee: 1
|
||||||
allowSelfAssign: false
|
allowSelfAssign: false
|
||||||
|
2
.github/workflows/build.yml
vendored
@ -140,7 +140,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
apps: [ng16, ng17]
|
apps: [ng16, ng17, ng18]
|
||||||
needs: [build-angular, build-angular-server]
|
needs: [build-angular, build-angular-server]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
6
.github/workflows/conventional-commit.yml
vendored
@ -24,3 +24,9 @@ jobs:
|
|||||||
# within the message.
|
# within the message.
|
||||||
subjectPatternError: |
|
subjectPatternError: |
|
||||||
The subject "{subject}" found in the pull request title "{title}" didn't match the configured pattern. Please ensure that the subject doesn't start with an uppercase character.
|
The subject "{subject}" found in the pull request title "{title}" didn't match the configured pattern. Please ensure that the subject doesn't start with an uppercase character.
|
||||||
|
# If the PR contains one of these newline-delimited labels, the
|
||||||
|
# validation is skipped. If you want to rerun the validation when
|
||||||
|
# labels change, you might want to use the `labeled` and `unlabeled`
|
||||||
|
# event triggers in your workflow.
|
||||||
|
ignoreLabels: |
|
||||||
|
release
|
||||||
|
2
.github/workflows/stencil-nightly.yml
vendored
@ -150,7 +150,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
apps: [ng16, ng17]
|
apps: [ng16, ng17, ng18]
|
||||||
needs: [build-angular, build-angular-server]
|
needs: [build-angular, build-angular-server]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
14
CHANGELOG.md
@ -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.
|
||||||
|
|
||||||
|
## [8.1.1](https://github.com/ionic-team/ionic-framework/compare/v8.1.0...v8.1.1) (2024-05-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **angular:** add formatOptions property to standalone datetime ([#29468](https://github.com/ionic-team/ionic-framework/issues/29468)) ([bb1db52](https://github.com/ionic-team/ionic-framework/commit/bb1db52567e0884a896f9ccd76c27540b52f5e48)), closes [#29464](https://github.com/ionic-team/ionic-framework/issues/29464)
|
||||||
|
* **angular:** persist select disabled state in item ([#29448](https://github.com/ionic-team/ionic-framework/issues/29448)) ([dfb72d7](https://github.com/ionic-team/ionic-framework/commit/dfb72d7ea06e28d76069b23eb90c3426181b7c4c)), closes [#29234](https://github.com/ionic-team/ionic-framework/issues/29234)
|
||||||
|
* **angular:** set active segment button when dynamically changing items ([#29418](https://github.com/ionic-team/ionic-framework/issues/29418)) ([ee83388](https://github.com/ionic-team/ionic-framework/commit/ee833881da3ecaa0a9153397f0c7e62c1923f19c)), closes [#29414](https://github.com/ionic-team/ionic-framework/issues/29414)
|
||||||
|
* **radio:** persist checked state when items are updated in radio-group ([#29457](https://github.com/ionic-team/ionic-framework/issues/29457)) ([7ea14ae](https://github.com/ionic-team/ionic-framework/commit/7ea14ae41eb27f2a58952bd27d91ef4c77bb6a0c)), closes [#29442](https://github.com/ionic-team/ionic-framework/issues/29442)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,19 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [8.1.1](https://github.com/ionic-team/ionic-framework/compare/v8.1.0...v8.1.1) (2024-05-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **angular:** persist select disabled state in item ([#29448](https://github.com/ionic-team/ionic-framework/issues/29448)) ([dfb72d7](https://github.com/ionic-team/ionic-framework/commit/dfb72d7ea06e28d76069b23eb90c3426181b7c4c)), closes [#29234](https://github.com/ionic-team/ionic-framework/issues/29234)
|
||||||
|
* **angular:** set active segment button when dynamically changing items ([#29418](https://github.com/ionic-team/ionic-framework/issues/29418)) ([ee83388](https://github.com/ionic-team/ionic-framework/commit/ee833881da3ecaa0a9153397f0c7e62c1923f19c)), closes [#29414](https://github.com/ionic-team/ionic-framework/issues/29414)
|
||||||
|
* **radio:** persist checked state when items are updated in radio-group ([#29457](https://github.com/ionic-team/ionic-framework/issues/29457)) ([7ea14ae](https://github.com/ionic-team/ionic-framework/commit/7ea14ae41eb27f2a58952bd27d91ef4c77bb6a0c)), closes [#29442](https://github.com/ionic-team/ionic-framework/issues/29442)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ ion-accordion,prop,disabled,boolean,false,false,false
|
|||||||
ion-accordion,prop,mode,"ios" | "md",undefined,false,false
|
ion-accordion,prop,mode,"ios" | "md",undefined,false,false
|
||||||
ion-accordion,prop,readonly,boolean,false,false,false
|
ion-accordion,prop,readonly,boolean,false,false,false
|
||||||
ion-accordion,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
ion-accordion,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||||
ion-accordion,prop,toggleIcon,string,chevronDown,false,false
|
ion-accordion,prop,toggleIcon,string | undefined,undefined,false,false
|
||||||
ion-accordion,prop,toggleIconSlot,"end" | "start",'end',false,false
|
ion-accordion,prop,toggleIconSlot,"end" | "start",'end',false,false
|
||||||
ion-accordion,prop,value,string,`ion-accordion-${accordionIds++}`,false,false
|
ion-accordion,prop,value,string,`ion-accordion-${accordionIds++}`,false,false
|
||||||
ion-accordion,part,content
|
ion-accordion,part,content
|
||||||
@ -494,7 +494,7 @@ ion-fab,method,close,close() => Promise<void>
|
|||||||
|
|
||||||
ion-fab-button,shadow
|
ion-fab-button,shadow
|
||||||
ion-fab-button,prop,activated,boolean,false,false,false
|
ion-fab-button,prop,activated,boolean,false,false,false
|
||||||
ion-fab-button,prop,closeIcon,string,close,false,false
|
ion-fab-button,prop,closeIcon,string | undefined,undefined,false,false
|
||||||
ion-fab-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
ion-fab-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||||
ion-fab-button,prop,disabled,boolean,false,false,false
|
ion-fab-button,prop,disabled,boolean,false,false,false
|
||||||
ion-fab-button,prop,download,string | undefined,undefined,false,false
|
ion-fab-button,prop,download,string | undefined,undefined,false,false
|
||||||
@ -671,7 +671,7 @@ ion-item,shadow
|
|||||||
ion-item,prop,button,boolean,false,false,false
|
ion-item,prop,button,boolean,false,false,false
|
||||||
ion-item,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
ion-item,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||||
ion-item,prop,detail,boolean | undefined,undefined,false,false
|
ion-item,prop,detail,boolean | undefined,undefined,false,false
|
||||||
ion-item,prop,detailIcon,string,chevronForward,false,false
|
ion-item,prop,detailIcon,string | undefined,undefined,false,false
|
||||||
ion-item,prop,disabled,boolean,false,false,false
|
ion-item,prop,disabled,boolean,false,false,false
|
||||||
ion-item,prop,download,string | undefined,undefined,false,false
|
ion-item,prop,download,string | undefined,undefined,false,false
|
||||||
ion-item,prop,href,string | undefined,undefined,false,false
|
ion-item,prop,href,string | undefined,undefined,false,false
|
||||||
@ -1284,7 +1284,7 @@ ion-searchbar,prop,animated,boolean,false,false,false
|
|||||||
ion-searchbar,prop,autocapitalize,string,'off',false,false
|
ion-searchbar,prop,autocapitalize,string,'off',false,false
|
||||||
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
|
ion-searchbar,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "honorific-prefix" | "given-name" | "additional-name" | "family-name" | "honorific-suffix" | "nickname" | "username" | "new-password" | "current-password" | "one-time-code" | "organization-title" | "organization" | "street-address" | "address-line1" | "address-line2" | "address-line3" | "address-level4" | "address-level3" | "address-level2" | "address-level1" | "country" | "country-name" | "postal-code" | "cc-name" | "cc-given-name" | "cc-additional-name" | "cc-family-name" | "cc-number" | "cc-exp" | "cc-exp-month" | "cc-exp-year" | "cc-csc" | "cc-type" | "transaction-currency" | "transaction-amount" | "language" | "bday" | "bday-day" | "bday-month" | "bday-year" | "sex" | "tel-country-code" | "tel-national" | "tel-area-code" | "tel-local" | "tel-extension" | "impp" | "photo",'off',false,false
|
||||||
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
ion-searchbar,prop,autocorrect,"off" | "on",'off',false,false
|
||||||
ion-searchbar,prop,cancelButtonIcon,string,config.get('backButtonIcon', arrowBackSharp) as string,false,false
|
ion-searchbar,prop,cancelButtonIcon,string | undefined,undefined,false,false
|
||||||
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false
|
ion-searchbar,prop,cancelButtonText,string,'Cancel',false,false
|
||||||
ion-searchbar,prop,clearIcon,string | undefined,undefined,false,false
|
ion-searchbar,prop,clearIcon,string | undefined,undefined,false,false
|
||||||
ion-searchbar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
ion-searchbar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||||
|
4
core/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/core",
|
"name": "@ionic/core",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@ionic/core",
|
"name": "@ionic/core",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stencil/core": "^4.17.2",
|
"@stencil/core": "^4.17.2",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/core",
|
"name": "@ionic/core",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"description": "Base components for Ionic",
|
"description": "Base components for Ionic",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ionic",
|
"ionic",
|
||||||
|
@ -53,4 +53,7 @@ if (requestHeaded && !hasHeadedConfigFiles) {
|
|||||||
console.warn(chalk.yellow.bold('\n⚠️ You are running tests in headed mode, but one or more of your headed config files was not found.\nPlease ensure that both docker-display.txt and docker-display-volume.txt have been created in the correct location.\n'));
|
console.warn(chalk.yellow.bold('\n⚠️ You are running tests in headed mode, but one or more of your headed config files was not found.\nPlease ensure that both docker-display.txt and docker-display-volume.txt have been created in the correct location.\n'));
|
||||||
}
|
}
|
||||||
|
|
||||||
execa('docker', args, { shell: true, stdio: 'inherit' });
|
const res = await execa('docker', args, { shell: true, stdio: 'inherit' });
|
||||||
|
|
||||||
|
// If underlying scripts failed this whole process should fail too
|
||||||
|
process.exit(res.exitCode);
|
||||||
|
8
core/src/components.d.ts
vendored
@ -96,7 +96,7 @@ export namespace Components {
|
|||||||
/**
|
/**
|
||||||
* The toggle icon to use. This icon will be rotated when the accordion is expanded or collapsed.
|
* The toggle icon to use. This icon will be rotated when the accordion is expanded or collapsed.
|
||||||
*/
|
*/
|
||||||
"toggleIcon": string;
|
"toggleIcon"?: string;
|
||||||
/**
|
/**
|
||||||
* The slot inside of `ion-item` to place the toggle icon. Defaults to `"end"`.
|
* The slot inside of `ion-item` to place the toggle icon. Defaults to `"end"`.
|
||||||
*/
|
*/
|
||||||
@ -1153,7 +1153,7 @@ export namespace Components {
|
|||||||
/**
|
/**
|
||||||
* The icon name to use for the close icon. This will appear when the fab button is pressed. Only applies if it is the main button inside of a fab containing a fab list.
|
* The icon name to use for the close icon. This will appear when the fab button is pressed. Only applies if it is the main button inside of a fab containing a fab list.
|
||||||
*/
|
*/
|
||||||
"closeIcon": string;
|
"closeIcon"?: string;
|
||||||
/**
|
/**
|
||||||
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
|
* The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics).
|
||||||
*/
|
*/
|
||||||
@ -1534,7 +1534,7 @@ export namespace Components {
|
|||||||
/**
|
/**
|
||||||
* The icon to use when `detail` is set to `true`.
|
* The icon to use when `detail` is set to `true`.
|
||||||
*/
|
*/
|
||||||
"detailIcon": string;
|
"detailIcon"?: string;
|
||||||
/**
|
/**
|
||||||
* If `true`, the user cannot interact with the item.
|
* If `true`, the user cannot interact with the item.
|
||||||
*/
|
*/
|
||||||
@ -2993,7 +2993,7 @@ export namespace Components {
|
|||||||
/**
|
/**
|
||||||
* Set the cancel button icon. Only available when the theme is `"md"`. Defaults to `"arrow-back-sharp"`.
|
* Set the cancel button icon. Only available when the theme is `"md"`. Defaults to `"arrow-back-sharp"`.
|
||||||
*/
|
*/
|
||||||
"cancelButtonIcon": string;
|
"cancelButtonIcon"?: string;
|
||||||
/**
|
/**
|
||||||
* Set the the cancel button text. Only available when the theme is `"ios"`.
|
* Set the the cancel button text. Only available when the theme is `"ios"`.
|
||||||
*/
|
*/
|
||||||
|
@ -79,7 +79,7 @@ export class Accordion implements ComponentInterface {
|
|||||||
* rotated when the accordion is expanded
|
* rotated when the accordion is expanded
|
||||||
* or collapsed.
|
* or collapsed.
|
||||||
*/
|
*/
|
||||||
@Prop() toggleIcon = chevronDown;
|
@Prop() toggleIcon?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The slot inside of `ion-item` to
|
* The slot inside of `ion-item` to
|
||||||
@ -193,7 +193,8 @@ export class Accordion implements ComponentInterface {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { toggleIconSlot, toggleIcon } = this;
|
const { toggleIconSlot } = this;
|
||||||
|
const accordionToggleIcon = this.toggleIcon ?? config.get('accordionToggleIcon', chevronDown);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there already is a toggle icon.
|
* Check if there already is a toggle icon.
|
||||||
@ -208,7 +209,7 @@ export class Accordion implements ComponentInterface {
|
|||||||
iconEl.slot = toggleIconSlot;
|
iconEl.slot = toggleIconSlot;
|
||||||
iconEl.lazy = false;
|
iconEl.lazy = false;
|
||||||
iconEl.classList.add('ion-accordion-toggle-icon');
|
iconEl.classList.add('ion-accordion-toggle-icon');
|
||||||
iconEl.icon = toggleIcon;
|
iconEl.icon = accordionToggleIcon;
|
||||||
iconEl.setAttribute('aria-hidden', 'true');
|
iconEl.setAttribute('aria-hidden', 'true');
|
||||||
|
|
||||||
ionItem.appendChild(iconEl);
|
ionItem.appendChild(iconEl);
|
||||||
|
@ -3,10 +3,11 @@ import { configs, test } from '@utils/test/playwright';
|
|||||||
|
|
||||||
configs().forEach(({ config, title }) => {
|
configs().forEach(({ config, title }) => {
|
||||||
test.describe(title('accordion: a11y'), () => {
|
test.describe(title('accordion: a11y'), () => {
|
||||||
test('accordions should be keyboard navigable', async ({ page, skip, browserName }) => {
|
// TODO(ROU-8157): remove skip once the keyboard navigation is working again
|
||||||
// TODO(FW-1764): remove skip once issue is resolved
|
test.skip('accordions should be keyboard navigable', async ({ page, skip, browserName }) => {
|
||||||
|
// TODO(ROU-5358): remove skip once issue is resolved
|
||||||
skip.browser('firefox', 'https://github.com/ionic-team/ionic-framework/issues/25070');
|
skip.browser('firefox', 'https://github.com/ionic-team/ionic-framework/issues/25070');
|
||||||
// TODO (FW-2979)
|
// TODO (ROU-5437)
|
||||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||||
|
|
||||||
await page.goto(`/src/components/accordion/test/a11y`, config);
|
await page.goto(`/src/components/accordion/test/a11y`, config);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en" dir="ltr">
|
<html lang="en" dir="ltr">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>Accordion - Basic</title>
|
<title>Accordion - Standalone</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0" />
|
||||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||||
@ -119,6 +119,7 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 20px 16px;
|
padding: 20px 16px;
|
||||||
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.custom-accordion-content {
|
.custom-accordion-content {
|
||||||
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
@ -82,7 +82,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
|||||||
get backButtonIcon() {
|
get backButtonIcon() {
|
||||||
const icon = this.icon;
|
const icon = this.icon;
|
||||||
if (icon != null) {
|
if (icon != null) {
|
||||||
// icon is set on the component or by the config
|
// Icon is set on the component or by the config.
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import { inheritAriaAttributes } from '@utils/helpers';
|
|||||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||||
import { chevronForwardOutline, ellipsisHorizontal } from 'ionicons/icons';
|
import { chevronForwardOutline, ellipsisHorizontal } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type { AnimationBuilder, Color } from '../../interface';
|
import type { AnimationBuilder, Color } from '../../interface';
|
||||||
import type { RouterDirection } from '../router/utils/interface';
|
import type { RouterDirection } from '../router/utils/interface';
|
||||||
@ -167,6 +168,9 @@ export class Breadcrumb implements ComponentInterface {
|
|||||||
const clickable = this.isClickable();
|
const clickable = this.isClickable();
|
||||||
const TagType = this.href === undefined ? 'span' : ('a' as any);
|
const TagType = this.href === undefined ? 'span' : ('a' as any);
|
||||||
|
|
||||||
|
const breadcrumbSeparatorIcon = config.get('breadcrumbSeparatorIcon', chevronForwardOutline);
|
||||||
|
const breadcrumbCollapsedIcon = config.get('breadcrumbCollapsedIcon', ellipsisHorizontal);
|
||||||
|
|
||||||
// Links can still be tabbed to when set to disabled if they have an href
|
// Links can still be tabbed to when set to disabled if they have an href
|
||||||
// in order to truly disable them we can keep it as an anchor but remove the href
|
// in order to truly disable them we can keep it as an anchor but remove the href
|
||||||
const href = disabled ? undefined : this.href;
|
const href = disabled ? undefined : this.href;
|
||||||
@ -224,7 +228,7 @@ export class Breadcrumb implements ComponentInterface {
|
|||||||
'breadcrumbs-collapsed-indicator': true,
|
'breadcrumbs-collapsed-indicator': true,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ion-icon aria-hidden="true" icon={ellipsisHorizontal} lazy={false}></ion-icon>
|
<ion-icon aria-hidden="true" icon={breadcrumbCollapsedIcon} lazy={false}></ion-icon>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
{showSeparator && (
|
{showSeparator && (
|
||||||
@ -236,7 +240,7 @@ export class Breadcrumb implements ComponentInterface {
|
|||||||
<span class="breadcrumb-separator" part="separator" aria-hidden="true">
|
<span class="breadcrumb-separator" part="separator" aria-hidden="true">
|
||||||
<slot name="separator">
|
<slot name="separator">
|
||||||
{theme === 'ios' ? (
|
{theme === 'ios' ? (
|
||||||
<ion-icon icon={chevronForwardOutline} lazy={false} flip-rtl></ion-icon>
|
<ion-icon icon={breadcrumbSeparatorIcon} lazy={false} flip-rtl></ion-icon>
|
||||||
) : (
|
) : (
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
)}
|
)}
|
||||||
|
@ -11,7 +11,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ config, screenshot, t
|
|||||||
test('should update the active item', async ({ page }) => {
|
test('should update the active item', async ({ page }) => {
|
||||||
const breadcrumbItems = page.locator('ion-breadcrumb');
|
const breadcrumbItems = page.locator('ion-breadcrumb');
|
||||||
|
|
||||||
const addItemButton = page.locator('ion-button#add-btn');
|
const addItemButton = page.locator('#add-btn');
|
||||||
|
|
||||||
await expect(breadcrumbItems).toHaveCount(4);
|
await expect(breadcrumbItems).toHaveCount(4);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import { isRTL } from '@utils/rtl';
|
|||||||
import { createColorClasses } from '@utils/theme';
|
import { createColorClasses } from '@utils/theme';
|
||||||
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
|
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||||
import type { Color, StyleEventDetail, Theme } from '../../interface';
|
import type { Color, StyleEventDetail, Theme } from '../../interface';
|
||||||
|
|
||||||
@ -2115,9 +2116,10 @@ export class Datetime implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private renderCalendarHeader(theme: Theme) {
|
private renderCalendarHeader(theme: Theme) {
|
||||||
const { disabled } = this;
|
const { disabled, datetimeShowMonthYearIcon, datetimeHideMonthYearIcon } = this;
|
||||||
const expandedIcon = theme === 'ios' ? chevronDown : caretUpSharp;
|
|
||||||
const collapsedIcon = theme === 'ios' ? chevronForward : caretDownSharp;
|
const datetimeNextIcon = config.get('datetimeNextIcon', chevronForward);
|
||||||
|
const datetimePrevIcon = config.get('datetimePreviousIcon', chevronBack);
|
||||||
|
|
||||||
const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
|
const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
|
||||||
const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
|
const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
|
||||||
@ -2144,7 +2146,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
{getMonthAndYear(this.locale, this.workingParts)}
|
{getMonthAndYear(this.locale, this.workingParts)}
|
||||||
<ion-icon
|
<ion-icon
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
icon={this.showMonthAndYear ? expandedIcon : collapsedIcon}
|
icon={this.showMonthAndYear ? datetimeShowMonthYearIcon : datetimeHideMonthYearIcon}
|
||||||
lazy={false}
|
lazy={false}
|
||||||
flipRtl={true}
|
flipRtl={true}
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -2160,7 +2162,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
dir={hostDir}
|
dir={hostDir}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
slot="icon-only"
|
slot="icon-only"
|
||||||
icon={chevronBack}
|
icon={datetimePrevIcon}
|
||||||
lazy={false}
|
lazy={false}
|
||||||
flipRtl
|
flipRtl
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -2170,7 +2172,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
dir={hostDir}
|
dir={hostDir}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
slot="icon-only"
|
slot="icon-only"
|
||||||
icon={chevronForward}
|
icon={datetimeNextIcon}
|
||||||
lazy={false}
|
lazy={false}
|
||||||
flipRtl
|
flipRtl
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
@ -2593,6 +2595,34 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the show month and year icon.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the show month and year icon.
|
||||||
|
*/
|
||||||
|
get datetimeShowMonthYearIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const expandedIcon = theme === 'ios' ? chevronDown : caretUpSharp;
|
||||||
|
|
||||||
|
return config.get('datetimeShowMonthYearIcon', expandedIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the hide month and year icon.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the hide month and year icon.
|
||||||
|
*/
|
||||||
|
get datetimeHideMonthYearIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const collapsedIcon = theme === 'ios' ? chevronForward : caretDownSharp;
|
||||||
|
|
||||||
|
return config.get('datetimeHideMonthYearIcon', collapsedIcon);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
|
@ -7,7 +7,7 @@ configs().forEach(({ title, screenshot, config }) => {
|
|||||||
await page.goto('/src/components/datetime/test/position', config);
|
await page.goto('/src/components/datetime/test/position', config);
|
||||||
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
||||||
|
|
||||||
const openDateTimeBtn = page.locator('ion-button#open-datetime');
|
const openDateTimeBtn = page.locator('#open-datetime');
|
||||||
await openDateTimeBtn.click();
|
await openDateTimeBtn.click();
|
||||||
|
|
||||||
await ionPopoverDidPresent.next();
|
await ionPopoverDidPresent.next();
|
||||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@ -6,6 +6,7 @@ import type { Attributes } from '@utils/helpers';
|
|||||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||||
import { close } from 'ionicons/icons';
|
import { close } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type { AnimationBuilder, Color } from '../../interface';
|
import type { AnimationBuilder, Color } from '../../interface';
|
||||||
import type { RouterDirection } from '../router/utils/interface';
|
import type { RouterDirection } from '../router/utils/interface';
|
||||||
@ -115,7 +116,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
|||||||
* is pressed. Only applies if it is the main button inside of a fab containing a
|
* is pressed. Only applies if it is the main button inside of a fab containing a
|
||||||
* fab list.
|
* fab list.
|
||||||
*/
|
*/
|
||||||
@Prop() closeIcon = close;
|
@Prop() closeIcon?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Emitted when the button has focus.
|
* Emitted when the button has focus.
|
||||||
@ -166,6 +167,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
|||||||
rel: this.rel,
|
rel: this.rel,
|
||||||
target: this.target,
|
target: this.target,
|
||||||
};
|
};
|
||||||
|
const fabButtonCloseIcon = this.closeIcon ?? config.get('fabButtonCloseIcon', close);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Host
|
<Host
|
||||||
@ -196,7 +198,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
|||||||
>
|
>
|
||||||
<ion-icon
|
<ion-icon
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
icon={this.closeIcon}
|
icon={fabButtonCloseIcon}
|
||||||
part="close-icon"
|
part="close-icon"
|
||||||
class="close-icon"
|
class="close-icon"
|
||||||
lazy={false}
|
lazy={false}
|
||||||
|
@ -4,6 +4,7 @@ import { printIonWarning } from '@utils/logging';
|
|||||||
import { createColorClasses } from '@utils/theme';
|
import { createColorClasses } from '@utils/theme';
|
||||||
import { eyeOff, eye } from 'ionicons/icons';
|
import { eyeOff, eye } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonMode } from '../../global/ionic-global';
|
import { getIonMode } from '../../global/ionic-global';
|
||||||
import type { Color, TextFieldTypes } from '../../interface';
|
import type { Color, TextFieldTypes } from '../../interface';
|
||||||
|
|
||||||
@ -110,10 +111,9 @@ export class InputPasswordToggle implements ComponentInterface {
|
|||||||
|
|
||||||
const mode = getIonMode(this);
|
const mode = getIonMode(this);
|
||||||
|
|
||||||
const showPasswordIcon = this.showIcon ?? eye;
|
|
||||||
const hidePasswordIcon = this.hideIcon ?? eyeOff;
|
|
||||||
|
|
||||||
const isPasswordVisible = type === 'text';
|
const isPasswordVisible = type === 'text';
|
||||||
|
const inputPasswordShowIcon = this.showIcon ?? config.get('inputPasswordShowIcon', eye);
|
||||||
|
const inputPasswordHideIcon = this.hideIcon ?? config.get('inputPasswordHideIcon', eyeOff);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Host
|
<Host
|
||||||
@ -143,7 +143,7 @@ export class InputPasswordToggle implements ComponentInterface {
|
|||||||
<ion-icon
|
<ion-icon
|
||||||
slot="icon-only"
|
slot="icon-only"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
icon={isPasswordVisible ? hidePasswordIcon : showPasswordIcon}
|
icon={isPasswordVisible ? inputPasswordHideIcon : inputPasswordShowIcon}
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</Host>
|
</Host>
|
||||||
|
@ -10,6 +10,7 @@ import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
|||||||
import { createColorClasses, hostContext } from '@utils/theme';
|
import { createColorClasses, hostContext } from '@utils/theme';
|
||||||
import { closeCircle, closeSharp } from 'ionicons/icons';
|
import { closeCircle, closeSharp } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type { AutocompleteTypes, Color, TextFieldTypes } from '../../interface';
|
import type { AutocompleteTypes, Color, TextFieldTypes } from '../../interface';
|
||||||
|
|
||||||
@ -758,8 +759,30 @@ export class Input implements ComponentInterface {
|
|||||||
return this.renderLabel();
|
return this.renderLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the clear icon.
|
||||||
|
* If an icon is set on the component, use that.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
* @returns {string} The icon to use for the clear icon.
|
||||||
|
*/
|
||||||
|
get inputClearIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const defaultClearIcon = theme === 'ios' ? closeCircle : closeSharp;
|
||||||
|
const icon = this.clearInputIcon;
|
||||||
|
|
||||||
|
if (icon !== undefined) {
|
||||||
|
// Icon is set on the component.
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.get('inputClearIcon', defaultClearIcon);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { disabled, fill, readonly, inputId, el, hasFocus, clearInput, clearInputIcon } = this;
|
const { disabled, fill, readonly, inputId, el, hasFocus, clearInput, inputClearIcon } = this;
|
||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const value = this.getValue();
|
const value = this.getValue();
|
||||||
const size = this.getSize();
|
const size = this.getSize();
|
||||||
@ -768,9 +791,6 @@ export class Input implements ComponentInterface {
|
|||||||
const shouldRenderHighlight = (theme === 'md' || theme === 'ionic') && fill !== 'outline' && !inItem;
|
const shouldRenderHighlight = (theme === 'md' || theme === 'ionic') && fill !== 'outline' && !inItem;
|
||||||
const labelPlacement = this.getLabelPlacement();
|
const labelPlacement = this.getLabelPlacement();
|
||||||
|
|
||||||
const defaultClearIcon = theme === 'ios' ? closeCircle : closeSharp;
|
|
||||||
const clearIconData = clearInputIcon ?? defaultClearIcon;
|
|
||||||
|
|
||||||
const hasValue = this.hasValue();
|
const hasValue = this.hasValue();
|
||||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||||
|
|
||||||
@ -891,7 +911,7 @@ export class Input implements ComponentInterface {
|
|||||||
}}
|
}}
|
||||||
onClick={this.clearTextInput}
|
onClick={this.clearTextInput}
|
||||||
>
|
>
|
||||||
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
|
<ion-icon aria-hidden="true" icon={inputClearIcon}></ion-icon>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<slot name="end"></slot>
|
<slot name="end"></slot>
|
||||||
|
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 48 KiB |
@ -6,6 +6,7 @@ import { inheritAttributes, raf } from '@utils/helpers';
|
|||||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||||
import { chevronForward } from 'ionicons/icons';
|
import { chevronForward } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type { AnimationBuilder, Color, CssClassMap, StyleEventDetail } from '../../interface';
|
import type { AnimationBuilder, Color, CssClassMap, StyleEventDetail } from '../../interface';
|
||||||
import type { RouterDirection } from '../router/utils/interface';
|
import type { RouterDirection } from '../router/utils/interface';
|
||||||
@ -61,7 +62,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
/**
|
/**
|
||||||
* The icon to use when `detail` is set to `true`.
|
* The icon to use when `detail` is set to `true`.
|
||||||
*/
|
*/
|
||||||
@Prop() detailIcon = chevronForward;
|
@Prop() detailIcon?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If `true`, the user cannot interact with the item.
|
* If `true`, the user cannot interact with the item.
|
||||||
@ -244,7 +245,6 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
detail,
|
detail,
|
||||||
detailIcon,
|
|
||||||
download,
|
download,
|
||||||
labelColorStyles,
|
labelColorStyles,
|
||||||
lines,
|
lines,
|
||||||
@ -262,6 +262,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
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 itemDetailIcon = this.detailIcon ?? config.get('itemDetailIcon', chevronForward);
|
||||||
|
|
||||||
const attrs =
|
const attrs =
|
||||||
TagType === 'button'
|
TagType === 'button'
|
||||||
@ -368,12 +369,12 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
|||||||
<slot name="end"></slot>
|
<slot name="end"></slot>
|
||||||
{showDetail && (
|
{showDetail && (
|
||||||
<ion-icon
|
<ion-icon
|
||||||
icon={detailIcon}
|
icon={itemDetailIcon}
|
||||||
lazy={false}
|
lazy={false}
|
||||||
class="item-detail-icon"
|
class="item-detail-icon"
|
||||||
part="detail-icon"
|
part="detail-icon"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
flip-rtl={detailIcon === chevronForward}
|
flip-rtl={itemDetailIcon === chevronForward}
|
||||||
></ion-icon>
|
></ion-icon>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -74,7 +74,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c
|
|||||||
|
|
||||||
await ionLoadingDidPresent.next();
|
await ionLoadingDidPresent.next();
|
||||||
|
|
||||||
const button = page.locator('ion-loading ion-button');
|
const button = page.locator('ion-loading button');
|
||||||
|
|
||||||
if (browserName === 'webkit') {
|
if (browserName === 'webkit') {
|
||||||
await page.keyboard.down('Alt');
|
await page.keyboard.down('Alt');
|
||||||
|
@ -29,7 +29,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
|
|
||||||
test('should trap focus', async ({ page, skip, browserName }) => {
|
test('should trap focus', async ({ page, skip, browserName }) => {
|
||||||
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
skip.browser('firefox', 'Firefox incorrectly allows keyboard focus to move to ion-content');
|
||||||
// TODO (FW-2979)
|
// TODO (ROU-5437)
|
||||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||||
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
const ionDidOpen = await page.spyOnEvent('ionDidOpen');
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|||||||
|
|
||||||
await modal.evaluate((modal: HTMLIonModalElement) => {
|
await modal.evaluate((modal: HTMLIonModalElement) => {
|
||||||
modal.remove();
|
modal.remove();
|
||||||
document.querySelector('ion-button')?.insertAdjacentElement('afterend', modal);
|
document.querySelector('button')?.insertAdjacentElement('afterend', modal);
|
||||||
});
|
});
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
|
|
||||||
test.describe('pushing a new page', () => {
|
test.describe('pushing a new page', () => {
|
||||||
test('should render the pushed component', async ({ page }) => {
|
test('should render the pushed component', async ({ page }) => {
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
const pageOne = page.locator('page-one');
|
const pageOne = page.locator('page-one');
|
||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should render the back button', async ({ page }) => {
|
test('should render the back button', async ({ page }) => {
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
const pageTwoBackButton = page.locator('page-two ion-back-button');
|
const pageTwoBackButton = page.locator('page-two ion-back-button');
|
||||||
|
|
||||||
await pageTwoButton.click();
|
await pageTwoButton.click();
|
||||||
@ -45,7 +45,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
test('back button should pop to the previous page', async ({ page }) => {
|
test('back button should pop to the previous page', async ({ page }) => {
|
||||||
const pageOne = page.locator('page-one');
|
const pageOne = page.locator('page-one');
|
||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
const pageTwoBackButton = page.locator('page-two ion-back-button');
|
const pageTwoBackButton = page.locator('page-two ion-back-button');
|
||||||
|
|
||||||
await pageTwoButton.click();
|
await pageTwoButton.click();
|
||||||
@ -65,8 +65,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
const pageThree = page.locator('page-three');
|
const pageThree = page.locator('page-three');
|
||||||
|
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
const pageThreeButton = page.locator('ion-button:has-text("Go to Page Three")');
|
const pageThreeButton = page.locator('button:has-text("Go to Page Three")');
|
||||||
|
|
||||||
await pageTwoButton.click();
|
await pageTwoButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
@ -16,8 +16,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
const pageOne = page.locator('page-one');
|
const pageOne = page.locator('page-one');
|
||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
|
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page 2")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page 2")');
|
||||||
const pageTwoTwoButton = page.locator('ion-button:has-text("Go to Page 2.2")');
|
const pageTwoTwoButton = page.locator('button:has-text("Go to Page 2.2")');
|
||||||
|
|
||||||
await pageTwoButton.click();
|
await pageTwoButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
@ -35,7 +35,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
await expect(pageTwoOne).toHaveCount(1);
|
await expect(pageTwoOne).toHaveCount(1);
|
||||||
await expect(pageTwoTwo).toBeVisible();
|
await expect(pageTwoTwo).toBeVisible();
|
||||||
|
|
||||||
const pageThreeButton = page.locator('ion-button:has-text("Go to Page 3")');
|
const pageThreeButton = page.locator('button:has-text("Go to Page 3")');
|
||||||
|
|
||||||
await pageThreeButton.click();
|
await pageThreeButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
@ -49,8 +49,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
|
|
||||||
test.describe('back button', () => {
|
test.describe('back button', () => {
|
||||||
test('should work with nested ion-nav', async ({ page }) => {
|
test('should work with nested ion-nav', async ({ page }) => {
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page 2")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page 2")');
|
||||||
const pageTwoTwoButton = page.locator('ion-button:has-text("Go to Page 2.2")');
|
const pageTwoTwoButton = page.locator('button:has-text("Go to Page 2.2")');
|
||||||
|
|
||||||
await pageTwoButton.click();
|
await pageTwoButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
@ -61,7 +61,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
await pageTwoTwoButton.click();
|
await pageTwoTwoButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
const pageThreeButton = page.locator('ion-button:has-text("Go to Page 3")');
|
const pageThreeButton = page.locator('button:has-text("Go to Page 3")');
|
||||||
const pageThreeBackButton = page.locator('page-three ion-back-button');
|
const pageThreeBackButton = page.locator('page-three ion-back-button');
|
||||||
|
|
||||||
await pageThreeButton.click();
|
await pageThreeButton.click();
|
||||||
|
@ -24,8 +24,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
const pageOne = page.locator('page-one');
|
const pageOne = page.locator('page-one');
|
||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
|
|
||||||
const pageOneButton = page.locator('ion-button:has-text("Go to Page One")');
|
const pageOneButton = page.locator('button:has-text("Go to Page One")');
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
|
|
||||||
await pageOneButton.click();
|
await pageOneButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
@ -45,7 +45,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should render the back button', async ({ page }) => {
|
test('should render the back button', async ({ page }) => {
|
||||||
const pageOneButton = page.locator('ion-button:has-text("Go to Page One")');
|
const pageOneButton = page.locator('button:has-text("Go to Page One")');
|
||||||
const pageOneBackButton = page.locator('page-one ion-back-button');
|
const pageOneBackButton = page.locator('page-one ion-back-button');
|
||||||
|
|
||||||
await pageOneButton.click();
|
await pageOneButton.click();
|
||||||
@ -59,7 +59,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
const pageRoot = page.locator('page-root');
|
const pageRoot = page.locator('page-root');
|
||||||
const pageOne = page.locator('page-one');
|
const pageOne = page.locator('page-one');
|
||||||
|
|
||||||
const pageOneButton = page.locator('ion-button:has-text("Go to Page One")');
|
const pageOneButton = page.locator('button:has-text("Go to Page One")');
|
||||||
const pageOneBackButton = page.locator('page-one ion-back-button');
|
const pageOneBackButton = page.locator('page-one ion-back-button');
|
||||||
|
|
||||||
await pageOneButton.click();
|
await pageOneButton.click();
|
||||||
@ -80,9 +80,9 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
const pageTwo = page.locator('page-two');
|
const pageTwo = page.locator('page-two');
|
||||||
const pageThree = page.locator('page-three');
|
const pageThree = page.locator('page-three');
|
||||||
|
|
||||||
const pageOneButton = page.locator('ion-button:has-text("Go to Page One")');
|
const pageOneButton = page.locator('button:has-text("Go to Page One")');
|
||||||
const pageTwoButton = page.locator('ion-button:has-text("Go to Page Two")');
|
const pageTwoButton = page.locator('button:has-text("Go to Page Two")');
|
||||||
const pageThreeButton = page.locator('ion-button:has-text("Go to Page Three")');
|
const pageThreeButton = page.locator('button:has-text("Go to Page Three")');
|
||||||
|
|
||||||
await pageOneButton.click();
|
await pageOneButton.click();
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
@ -105,7 +105,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('tabbing should correctly move focus between columns', async ({ page }) => {
|
// TODO(FW-6232): remove this skip when tabbing is working properly
|
||||||
|
test.skip('tabbing should correctly move focus between columns', async ({ page }) => {
|
||||||
const firstColumn = page.locator('ion-picker-column#first');
|
const firstColumn = page.locator('ion-picker-column#first');
|
||||||
const secondColumn = page.locator('ion-picker-column#second');
|
const secondColumn = page.locator('ion-picker-column#second');
|
||||||
|
|
||||||
@ -120,7 +121,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
await expect(secondColumn).toBeFocused();
|
await expect(secondColumn).toBeFocused();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('tabbing should correctly move focus back', async ({ page }) => {
|
// TODO(FW-6232): remove this skip when tabbing is working properly
|
||||||
|
test.skip('tabbing should correctly move focus back', async ({ page }) => {
|
||||||
const firstColumn = page.locator('ion-picker-column#first');
|
const firstColumn = page.locator('ion-picker-column#first');
|
||||||
const secondColumn = page.locator('ion-picker-column#second');
|
const secondColumn = page.locator('ion-picker-column#second');
|
||||||
|
|
||||||
|
@ -7,7 +7,8 @@ import type { E2ELocator } from '@utils/test/playwright/page/utils/locator';
|
|||||||
*/
|
*/
|
||||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||||
test.describe(title('picker: keyboard entry'), () => {
|
test.describe(title('picker: keyboard entry'), () => {
|
||||||
test('should scroll to and update the value prop for a single column', async ({ page }) => {
|
// TODO(FW-6232): remove this skip when keyboard entry is working properly
|
||||||
|
test.skip('should scroll to and update the value prop for a single column', async ({ page }) => {
|
||||||
await page.setContent(
|
await page.setContent(
|
||||||
`
|
`
|
||||||
<ion-picker>
|
<ion-picker>
|
||||||
@ -122,7 +123,8 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
await expect(secondColumn).toHaveJSProperty('value', 24);
|
await expect(secondColumn).toHaveJSProperty('value', 24);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should select 00', async ({ page }) => {
|
// TODO(FW-6232): remove this skip when keyboard entry is working properly
|
||||||
|
test.skip('should select 00', async ({ page }) => {
|
||||||
await page.setContent(
|
await page.setContent(
|
||||||
`
|
`
|
||||||
<ion-picker>
|
<ion-picker>
|
||||||
|
@ -40,7 +40,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|||||||
|
|
||||||
await popover.evaluate((popover: HTMLIonPopoverElement) => {
|
await popover.evaluate((popover: HTMLIonPopoverElement) => {
|
||||||
popover.remove();
|
popover.remove();
|
||||||
document.querySelector('ion-button')?.insertAdjacentElement('afterend', popover);
|
document.querySelector('button')?.insertAdjacentElement('afterend', popover);
|
||||||
});
|
});
|
||||||
await page.waitForChanges();
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
@ -112,6 +112,18 @@ export class Radio implements ComponentInterface {
|
|||||||
*/
|
*/
|
||||||
@Event() ionBlur!: EventEmitter<void>;
|
@Event() ionBlur!: EventEmitter<void>;
|
||||||
|
|
||||||
|
componentDidLoad() {
|
||||||
|
/**
|
||||||
|
* The value may be `undefined` if it
|
||||||
|
* gets set before the radio is
|
||||||
|
* rendered. This ensures that the radio
|
||||||
|
* is checked if the value matches. This
|
||||||
|
* happens most often when Angular is
|
||||||
|
* rendering the radio.
|
||||||
|
*/
|
||||||
|
this.updateState();
|
||||||
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
@Method()
|
@Method()
|
||||||
async setFocus(ev: globalThis.Event) {
|
async setFocus(ev: globalThis.Event) {
|
||||||
|
Before Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 58 KiB |
@ -2,6 +2,7 @@ import type { ComponentInterface } from '@stencil/core';
|
|||||||
import { Component, Element, Host, Listen, h } from '@stencil/core';
|
import { Component, Element, Host, Listen, h } from '@stencil/core';
|
||||||
import { reorderThreeOutline, reorderTwoSharp } from 'ionicons/icons';
|
import { reorderThreeOutline, reorderTwoSharp } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,9 +36,24 @@ export class Reorder implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
/**
|
||||||
|
* Get the icon to use for the handle icon.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the handle icon.
|
||||||
|
*/
|
||||||
|
get reorderHandleIcon(): string {
|
||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const reorderIcon = theme === 'ios' ? reorderThreeOutline : reorderTwoSharp;
|
const reorderIcon = theme === 'ios' ? reorderThreeOutline : reorderTwoSharp;
|
||||||
|
|
||||||
|
return config.get('reorderHandleIcon', reorderIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { reorderHandleIcon } = this;
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Host
|
<Host
|
||||||
class={{
|
class={{
|
||||||
@ -45,7 +61,7 @@ export class Reorder implements ComponentInterface {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
<ion-icon icon={reorderIcon} lazy={false} class="reorder-icon" part="icon" aria-hidden="true" />
|
<ion-icon icon={reorderHandleIcon} lazy={false} class="reorder-icon" part="icon" aria-hidden="true" />
|
||||||
</slot>
|
</slot>
|
||||||
</Host>
|
</Host>
|
||||||
);
|
);
|
||||||
|
@ -100,7 +100,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
* Set the cancel button icon. Only available when the theme is `"md"`.
|
* Set the cancel button icon. Only available when the theme is `"md"`.
|
||||||
* Defaults to `"arrow-back-sharp"`.
|
* Defaults to `"arrow-back-sharp"`.
|
||||||
*/
|
*/
|
||||||
@Prop() cancelButtonIcon = config.get('backButtonIcon', arrowBackSharp) as string;
|
@Prop() cancelButtonIcon?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the the cancel button text. Only available when the theme is `"ios"`.
|
* Set the the cancel button text. Only available when the theme is `"ios"`.
|
||||||
@ -609,13 +609,61 @@ export class Searchbar implements ComponentInterface {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the clear icon.
|
||||||
|
* If an icon is set on the component, use that.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the clear icon.
|
||||||
|
*/
|
||||||
|
get searchbarClearIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const icon = this.clearIcon;
|
||||||
|
const defaultIcon = theme === 'ios' ? closeCircle : closeSharp;
|
||||||
|
|
||||||
|
if (icon !== undefined) {
|
||||||
|
// Icon is set on the component.
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.get('searchbarClearIcon', defaultIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the search icon.
|
||||||
|
* If an icon is set on the component, use that.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the search icon.
|
||||||
|
*/
|
||||||
|
get searchbarSearchIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const icon = this.searchIcon;
|
||||||
|
const defaultIcon = theme === 'ios' ? searchOutline : searchSharp;
|
||||||
|
|
||||||
|
if (icon !== undefined) {
|
||||||
|
// Icon is set on the component.
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.get('searchbarSearchIcon', defaultIcon);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { cancelButtonText, autocapitalize } = this;
|
const { cancelButtonText, autocapitalize, searchbarClearIcon, searchbarSearchIcon } = this;
|
||||||
const animated = this.animated && config.getBoolean('animated', true);
|
const animated = this.animated && config.getBoolean('animated', true);
|
||||||
const theme = getIonTheme(this);
|
const theme = getIonTheme(this);
|
||||||
const clearIcon = this.clearIcon || (theme === 'ios' ? closeCircle : closeSharp);
|
|
||||||
const searchIcon = this.searchIcon || (theme === 'ios' ? searchOutline : searchSharp);
|
|
||||||
const shouldShowCancelButton = this.shouldShowCancelButton();
|
const shouldShowCancelButton = this.shouldShowCancelButton();
|
||||||
|
/**
|
||||||
|
* The `backButtonIcon` config will be used as a fallback if the
|
||||||
|
* `searchbarCancelIcon` config is not set. This ensures apps
|
||||||
|
* have a way to keep the back button icon and searchbar cancel
|
||||||
|
* icon in sync.
|
||||||
|
*/
|
||||||
|
const searchbarCancelIcon =
|
||||||
|
this.cancelButtonIcon ?? config.get('searchbarCancelIcon', config.get('backButtonIcon', arrowBackSharp));
|
||||||
|
|
||||||
const cancelButton = this.showCancelButton !== 'never' && (
|
const cancelButton = this.showCancelButton !== 'never' && (
|
||||||
<button
|
<button
|
||||||
@ -630,7 +678,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
>
|
>
|
||||||
<div aria-hidden="true">
|
<div aria-hidden="true">
|
||||||
{theme === 'md' ? (
|
{theme === 'md' ? (
|
||||||
<ion-icon aria-hidden="true" icon={this.cancelButtonIcon} lazy={false}></ion-icon>
|
<ion-icon aria-hidden="true" icon={searchbarCancelIcon} lazy={false}></ion-icon>
|
||||||
) : (
|
) : (
|
||||||
cancelButtonText
|
cancelButtonText
|
||||||
)}
|
)}
|
||||||
@ -681,7 +729,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
|
|
||||||
{theme === 'md' && cancelButton}
|
{theme === 'md' && cancelButton}
|
||||||
|
|
||||||
<ion-icon aria-hidden="true" icon={searchIcon} lazy={false} class="searchbar-search-icon"></ion-icon>
|
<ion-icon aria-hidden="true" icon={searchbarSearchIcon} lazy={false} class="searchbar-search-icon"></ion-icon>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
aria-label="reset"
|
aria-label="reset"
|
||||||
@ -698,7 +746,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
}}
|
}}
|
||||||
onClick={() => this.onClearInput(true)}
|
onClick={() => this.onClearInput(true)}
|
||||||
>
|
>
|
||||||
<ion-icon aria-hidden="true" icon={clearIcon} lazy={false} class="searchbar-clear-icon"></ion-icon>
|
<ion-icon aria-hidden="true" icon={searchbarClearIcon} lazy={false} class="searchbar-clear-icon"></ion-icon>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{theme === 'ios' && cancelButton}
|
{theme === 'ios' && cancelButton}
|
||||||
|
@ -20,7 +20,7 @@ const checkedOptions: SelectPopoverOption[] = [
|
|||||||
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||||
test.describe(title('select-popover: basic'), () => {
|
test.describe(title('select-popover: basic'), () => {
|
||||||
test.beforeEach(({ browserName }) => {
|
test.beforeEach(({ browserName }) => {
|
||||||
test.skip(browserName === 'webkit', 'https://ionic-cloud.atlassian.net/browse/FW-2979');
|
test.skip(browserName === 'webkit', 'ROU-5437');
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('single selection', () => {
|
test.describe('single selection', () => {
|
||||||
@ -55,7 +55,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('pressing Space on a selected option should dismiss the popover', async ({ browserName }) => {
|
test('pressing Space on a selected option should dismiss the popover', async ({ browserName }) => {
|
||||||
test.skip(browserName === 'firefox', 'Same behavior as https://ionic-cloud.atlassian.net/browse/FW-2979');
|
test.skip(browserName === 'firefox', 'Same behavior as ROU-5437');
|
||||||
|
|
||||||
await selectPopoverPage.setup(config, checkedOptions, false);
|
await selectPopoverPage.setup(config, checkedOptions, false);
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import { createColorClasses, hostContext } from '@utils/theme';
|
|||||||
import { watchForOptions } from '@utils/watch-options';
|
import { watchForOptions } from '@utils/watch-options';
|
||||||
import { caretDownSharp, chevronExpand } from 'ionicons/icons';
|
import { caretDownSharp, chevronExpand } from 'ionicons/icons';
|
||||||
|
|
||||||
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type {
|
import type {
|
||||||
ActionSheetOptions,
|
ActionSheetOptions,
|
||||||
@ -243,10 +244,6 @@ export class Select implements ComponentInterface {
|
|||||||
this.ionChange.emit({ value });
|
this.ionChange.emit({ value });
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillLoad() {
|
|
||||||
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
|
||||||
}
|
|
||||||
|
|
||||||
async connectedCallback() {
|
async connectedCallback() {
|
||||||
const { el } = this;
|
const { el } = this;
|
||||||
|
|
||||||
@ -272,6 +269,24 @@ export class Select implements ComponentInterface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillLoad() {
|
||||||
|
this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidLoad() {
|
||||||
|
/**
|
||||||
|
* If any of the conditions that trigger the styleChanged callback
|
||||||
|
* are met on component load, it is possible the event emitted
|
||||||
|
* prior to a parent web component registering an event listener.
|
||||||
|
*
|
||||||
|
* To ensure the parent web component receives the event, we
|
||||||
|
* emit the style event again after the component has loaded.
|
||||||
|
*
|
||||||
|
* This is often seen in Angular with the `dist` output target.
|
||||||
|
*/
|
||||||
|
this.emitStyle();
|
||||||
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if (this.mutationO) {
|
if (this.mutationO) {
|
||||||
this.mutationO.disconnect();
|
this.mutationO.disconnect();
|
||||||
@ -863,15 +878,11 @@ export class Select implements ComponentInterface {
|
|||||||
* next to the select text.
|
* next to the select text.
|
||||||
*/
|
*/
|
||||||
private renderSelectIcon() {
|
private renderSelectIcon() {
|
||||||
const theme = getIonTheme(this);
|
const { isExpanded, selectExpandIcon, selectCollapsedIcon } = this;
|
||||||
const { isExpanded, toggleIcon, expandedIcon } = this;
|
let icon = selectCollapsedIcon;
|
||||||
let icon: string;
|
|
||||||
|
|
||||||
if (isExpanded && expandedIcon !== undefined) {
|
if (isExpanded) {
|
||||||
icon = expandedIcon;
|
icon = selectExpandIcon;
|
||||||
} else {
|
|
||||||
const defaultIcon = theme === 'ios' ? chevronExpand : caretDownSharp;
|
|
||||||
icon = toggleIcon ?? defaultIcon;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <ion-icon class="select-icon" part="icon" aria-hidden="true" icon={icon}></ion-icon>;
|
return <ion-icon class="select-icon" part="icon" aria-hidden="true" icon={icon}></ion-icon>;
|
||||||
@ -925,6 +936,53 @@ export class Select implements ComponentInterface {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the expand icon.
|
||||||
|
* If an icon is set on the component, use that.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the expand icon.
|
||||||
|
*/
|
||||||
|
get selectExpandIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const icon = this.expandedIcon;
|
||||||
|
let defaultExpandIcon = theme === 'ios' ? chevronExpand : caretDownSharp;
|
||||||
|
|
||||||
|
if (icon !== undefined) {
|
||||||
|
// Icon is set on the component.
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.toggleIcon) {
|
||||||
|
// If the toggleIcon is set, use that as the default expand icon.
|
||||||
|
defaultExpandIcon = this.toggleIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.get('selectExpandIcon', defaultExpandIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the collapsed icon.
|
||||||
|
* If an icon is set on the component, use that.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the collapsed icon.
|
||||||
|
*/
|
||||||
|
get selectCollapsedIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const icon = this.toggleIcon;
|
||||||
|
const defaultIcon = theme === 'ios' ? chevronExpand : caretDownSharp;
|
||||||
|
|
||||||
|
if (icon !== undefined) {
|
||||||
|
// Icon is set on the component.
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
return config.get('selectCollapsedIcon', defaultIcon);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value } =
|
const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value } =
|
||||||
this;
|
this;
|
||||||
|
@ -40,7 +40,7 @@ configs({ directions: ['ltr'] }).forEach(({ title, config }) => {
|
|||||||
|
|
||||||
test.describe('select: popover', () => {
|
test.describe('select: popover', () => {
|
||||||
test('it should open a popover select', async ({ page, skip }) => {
|
test('it should open a popover select', async ({ page, skip }) => {
|
||||||
// TODO (FW-2979)
|
// TODO (ROU-5437)
|
||||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||||
|
|
||||||
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
const ionPopoverDidPresent = await page.spyOnEvent('ionPopoverDidPresent');
|
||||||
|
@ -4,7 +4,7 @@ import { configs, test } from '@utils/test/playwright';
|
|||||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
||||||
test.describe(title('select: disabled options'), () => {
|
test.describe(title('select: disabled options'), () => {
|
||||||
test('should not focus a disabled option when no value is set', async ({ page, skip }) => {
|
test('should not focus a disabled option when no value is set', async ({ page, skip }) => {
|
||||||
// TODO (FW-2979)
|
// TODO (ROU-5437)
|
||||||
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
skip.browser('webkit', 'Safari 16 only allows text fields and pop-up menus to be focused.');
|
||||||
|
|
||||||
test.info().annotations.push({
|
test.info().annotations.push({
|
||||||
|
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 46 KiB |
@ -108,7 +108,9 @@
|
|||||||
|
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-switch-icon-checked-default {
|
||||||
transform: translateY(-50%) rotate(90deg);
|
transform: translateY(-50%) rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import { checkmarkOutline, removeOutline, ellipseOutline } from 'ionicons/icons'
|
|||||||
|
|
||||||
import { config } from '../../global/config';
|
import { config } from '../../global/config';
|
||||||
import { getIonTheme } from '../../global/ionic-global';
|
import { getIonTheme } from '../../global/ionic-global';
|
||||||
import type { Color, Gesture, GestureDetail, Theme } from '../../interface';
|
import type { Color, Gesture, GestureDetail } from '../../interface';
|
||||||
|
|
||||||
import type { ToggleChangeEventDetail } from './toggle-interface';
|
import type { ToggleChangeEventDetail } from './toggle-interface';
|
||||||
|
|
||||||
@ -243,21 +243,59 @@ export class Toggle implements ComponentInterface {
|
|||||||
this.ionBlur.emit();
|
this.ionBlur.emit();
|
||||||
};
|
};
|
||||||
|
|
||||||
private getSwitchLabelIcon = (theme: Theme, checked: boolean) => {
|
private getSwitchLabelIcon = (checked: boolean) => {
|
||||||
if (theme === 'md') {
|
return checked ? this.toggleCheckedIcon : this.toggleUncheckedIcon;
|
||||||
return checked ? checkmarkOutline : removeOutline;
|
|
||||||
}
|
|
||||||
return checked ? removeOutline : ellipseOutline;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderOnOffSwitchLabels(theme: Theme, checked: boolean) {
|
get toggleDefaultCheckedIcon(): string {
|
||||||
const icon = this.getSwitchLabelIcon(theme, checked);
|
const theme = getIonTheme(this);
|
||||||
|
return theme === 'md' ? checkmarkOutline : removeOutline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the checked icon.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the checked icon.
|
||||||
|
*/
|
||||||
|
get toggleCheckedIcon(): string {
|
||||||
|
return config.get('toggleCheckedIcon', this.toggleDefaultCheckedIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the icon to use for the unchecked icon.
|
||||||
|
* Otherwise, use the icon set in the config.
|
||||||
|
* If no icon is set in the config, use the default icon.
|
||||||
|
*
|
||||||
|
* @returns {string} The icon to use for the unchecked icon.
|
||||||
|
*/
|
||||||
|
get toggleUncheckedIcon(): string {
|
||||||
|
const theme = getIonTheme(this);
|
||||||
|
const defaultIcon = theme === 'md' ? removeOutline : ellipseOutline;
|
||||||
|
|
||||||
|
return config.get('toggleUncheckedIcon', defaultIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderOnOffSwitchLabels(checked: boolean) {
|
||||||
|
const icon = this.getSwitchLabelIcon(checked);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ion-icon
|
<ion-icon
|
||||||
class={{
|
class={{
|
||||||
'toggle-switch-icon': true,
|
'toggle-switch-icon': true,
|
||||||
'toggle-switch-icon-checked': checked,
|
'toggle-switch-icon-checked': checked,
|
||||||
|
/**
|
||||||
|
* The default checked icon is being modified with
|
||||||
|
* styling that causes it to rotate by 90 degrees
|
||||||
|
* when the theme is `ios`.
|
||||||
|
*
|
||||||
|
* To prevent any rotation on a custom icon that is
|
||||||
|
* set through the config, we need to apply a class
|
||||||
|
* that handles the styling only when the default
|
||||||
|
* checked icon is being used.
|
||||||
|
*/
|
||||||
|
'toggle-switch-icon-checked-default': checked && icon === this.toggleDefaultCheckedIcon,
|
||||||
}}
|
}}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
@ -275,10 +313,10 @@ export class Toggle implements ComponentInterface {
|
|||||||
since the wrapper is translated when the handle is interacted with and
|
since the wrapper is translated when the handle is interacted with and
|
||||||
this would move the on/off labels outside of the view box */}
|
this would move the on/off labels outside of the view box */}
|
||||||
{enableOnOffLabels &&
|
{enableOnOffLabels &&
|
||||||
theme === 'ios' && [this.renderOnOffSwitchLabels(theme, true), this.renderOnOffSwitchLabels(theme, false)]}
|
theme === 'ios' && [this.renderOnOffSwitchLabels(true), this.renderOnOffSwitchLabels(false)]}
|
||||||
<div class="toggle-icon-wrapper">
|
<div class="toggle-icon-wrapper">
|
||||||
<div class="toggle-inner" part="handle">
|
<div class="toggle-inner" part="handle">
|
||||||
{enableOnOffLabels && theme === 'md' && this.renderOnOffSwitchLabels(theme, checked)}
|
{enableOnOffLabels && theme === 'md' && this.renderOnOffSwitchLabels(checked)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -124,6 +124,108 @@ export interface IonicConfig {
|
|||||||
*/
|
*/
|
||||||
toastDuration?: number;
|
toastDuration?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the toggle icon for all `ion-accordion` components.
|
||||||
|
*/
|
||||||
|
accordionToggleIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the separator icon for all `ion-breadcrumb` components,
|
||||||
|
* only when mode is set to `ios`.
|
||||||
|
*/
|
||||||
|
breadcrumbSeparatorIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the collapsed icon for all `ion-breadcrumb` components.
|
||||||
|
*/
|
||||||
|
breadcrumbCollapsedIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the next icon for all `ion-datetime` components.
|
||||||
|
*/
|
||||||
|
datetimeNextIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the previous icon for all `ion-datetime` components.
|
||||||
|
*/
|
||||||
|
datetimePreviousIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the show month and year icon for all `ion-datetime` components.
|
||||||
|
*/
|
||||||
|
datetimeShowMonthYearIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the hide month and year icon for all `ion-datetime` components.
|
||||||
|
*/
|
||||||
|
datetimeHideMonthYearIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the close icon for all `ion-fab-button` components.
|
||||||
|
*/
|
||||||
|
fabButtonCloseIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the clear icon for all `ion-input` components.
|
||||||
|
*/
|
||||||
|
inputClearIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the show icon for all `ion-input-password` components.
|
||||||
|
*/
|
||||||
|
inputPasswordShowIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the hide icon for all `ion-input-password` components.
|
||||||
|
*/
|
||||||
|
inputPasswordHideIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the detail icon for all `ion-item` components.
|
||||||
|
*/
|
||||||
|
itemDetailIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the handle icon for all `ion-reorder` components.
|
||||||
|
*/
|
||||||
|
reorderHandleIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the cancel icon for all `ion-searchbar` components,
|
||||||
|
* only when mode is set to `md`.
|
||||||
|
*/
|
||||||
|
searchbarCancelIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the clear icon for all `ion-searchbar` components.
|
||||||
|
*/
|
||||||
|
searchbarClearIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the search icon for all `ion-searchbar` components.
|
||||||
|
*/
|
||||||
|
searchbarSearchIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the expand icon for all `ion-select` components.
|
||||||
|
*/
|
||||||
|
selectExpandIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the collapsed icon for all `ion-select` components.
|
||||||
|
*/
|
||||||
|
selectCollapsedIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the checked icon for all `ion-toggle` components.
|
||||||
|
*/
|
||||||
|
toggleCheckedIcon?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides the unchecked icon for all `ion-toggle` components.
|
||||||
|
*/
|
||||||
|
toggleUncheckedIcon?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the default "animation" of all `ion-nav` and `ion-router-outlet` across the whole application.
|
* Overrides the default "animation" of all `ion-nav` and `ion-router-outlet` across the whole application.
|
||||||
* This prop allows to replace the default transition and provide a custom one that applies to all navigation outlets.
|
* This prop allows to replace the default transition and provide a custom one that applies to all navigation outlets.
|
||||||
|
@ -39,10 +39,10 @@ Due to this, Ionic Framework documented the Sass variables as part of the public
|
|||||||
// alert.ios.scss
|
// alert.ios.scss
|
||||||
|
|
||||||
/// @prop - Max width of the alert
|
/// @prop - Max width of the alert
|
||||||
$alert-ios-max-width: 270px !default;
|
$alert-ios-max-width: 270px !default;
|
||||||
|
|
||||||
/// @prop - Border radius of the alert
|
/// @prop - Border radius of the alert
|
||||||
$alert-ios-border-radius: 13px !default;
|
$alert-ios-border-radius: 13px !default;
|
||||||
```
|
```
|
||||||
|
|
||||||
If a Sass variable was deprecated or hidden from the public API, the `@prop` comment would be removed, or it would never be added, as seen in [v3.9.2](https://github.com/ionic-team/ionic-framework/blob/v3.9.2/src/components/alert/alert.ios.scss#L18-L19):
|
If a Sass variable was deprecated or hidden from the public API, the `@prop` comment would be removed, or it would never be added, as seen in [v3.9.2](https://github.com/ionic-team/ionic-framework/blob/v3.9.2/src/components/alert/alert.ios.scss#L18-L19):
|
||||||
@ -51,7 +51,7 @@ If a Sass variable was deprecated or hidden from the public API, the `@prop` com
|
|||||||
// alert.ios.scss
|
// alert.ios.scss
|
||||||
|
|
||||||
// deprecated
|
// deprecated
|
||||||
$alert-ios-head-padding: null !default;
|
$alert-ios-head-padding: null !default;
|
||||||
```
|
```
|
||||||
|
|
||||||
To ensure proper documentation of variables for customizing Ionic Framework, Sass variables were added for components even if they were not used multiple times within the same component or elsewhere:
|
To ensure proper documentation of variables for customizing Ionic Framework, Sass variables were added for components even if they were not used multiple times within the same component or elsewhere:
|
||||||
@ -60,7 +60,7 @@ To ensure proper documentation of variables for customizing Ionic Framework, Sas
|
|||||||
// alert.ios.scss
|
// alert.ios.scss
|
||||||
|
|
||||||
/// @prop - Text color of the label for the checked radio alert
|
/// @prop - Text color of the label for the checked radio alert
|
||||||
$alert-ios-radio-label-text-color-checked: $alert-ios-button-text-color !default;
|
$alert-ios-radio-label-text-color-checked: $alert-ios-button-text-color !default;
|
||||||
|
|
||||||
.alert-ios [aria-checked="true"] .alert-radio-label {
|
.alert-ios [aria-checked="true"] .alert-radio-label {
|
||||||
color: $alert-ios-radio-label-text-color-checked;
|
color: $alert-ios-radio-label-text-color-checked;
|
||||||
@ -71,16 +71,16 @@ $alert-ios-radio-label-text-color-checked: $alert-ios-button-text-color !default
|
|||||||
|
|
||||||
The abundance of Sass variables currently in Ionic Framework is a result of their historical usage, being used to rebuild the CSS and customize Ionic Framework components.
|
The abundance of Sass variables currently in Ionic Framework is a result of their historical usage, being used to rebuild the CSS and customize Ionic Framework components.
|
||||||
|
|
||||||
The comments for Sass variables are also still visible today in [v7.7.0](https://github.com/ionic-team/ionic-framework/blob/v7.7.0/core/src/components/alert/alert.ios.vars.scss), even though they are no longer used by any documentation generators:
|
The comments for Sass variables are also still visible today in [v8.1.0](https://github.com/ionic-team/ionic-framework/blob/v8.1.0/core/src/components/alert/alert.ios.vars.scss), even though they are no longer used by any documentation generators:
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
// alert.ios.vars.scss
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Max width of the alert
|
/// @prop - Max width of the alert
|
||||||
$alert-ios-max-width: dynamic-font-clamp(1, 270px, 1.2) !default;
|
$alert-ios-max-width: dynamic-font-clamp(1, 270px, 1.2);
|
||||||
|
|
||||||
/// @prop - Border radius of the alert
|
/// @prop - Border radius of the alert
|
||||||
$alert-ios-border-radius: 13px !default;
|
$alert-ios-border-radius: 13px;
|
||||||
```
|
```
|
||||||
|
|
||||||
These comments aren't necessary when the naming describes its use thoroughly. The comments for the variables above do not need to be there, as it is fairly obvious what they are used for.
|
These comments aren't necessary when the naming describes its use thoroughly. The comments for the variables above do not need to be there, as it is fairly obvious what they are used for.
|
||||||
@ -91,7 +91,7 @@ However, the comment for the following variable might be helpful in explaining w
|
|||||||
// action-sheet.ios.vars.scss
|
// action-sheet.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Font weight of the action sheet title when it has a sub title
|
/// @prop - Font weight of the action sheet title when it has a sub title
|
||||||
$action-sheet-ios-title-with-sub-title-font-weight: 600 !default;
|
$action-sheet-ios-title-with-sub-title-font-weight: 600;
|
||||||
```
|
```
|
||||||
|
|
||||||
It could be argued though that the comment doesn't really help, as seeing the variable in use will explain its purpose the best. Additionally, this is an example of a variable that isn't necessary, given it is only used in one place, which is why it is so specific in the first place.
|
It could be argued though that the comment doesn't really help, as seeing the variable in use will explain its purpose the best. Additionally, this is an example of a variable that isn't necessary, given it is only used in one place, which is why it is so specific in the first place.
|
||||||
@ -105,38 +105,36 @@ There are two things that need to be outlined here: when we should use comments
|
|||||||
We should update the comments for Sass variables in one of the following ways:
|
We should update the comments for Sass variables in one of the following ways:
|
||||||
|
|
||||||
1. If we don't intend to ever publicly document the Sass variables again, we should update the comments to remove the syntax that was added for documentation generation:
|
1. If we don't intend to ever publicly document the Sass variables again, we should update the comments to remove the syntax that was added for documentation generation:
|
||||||
|
```diff
|
||||||
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
```diff
|
-/// @prop - Border radius of the alert
|
||||||
// alert.ios.vars.scss
|
+// Border radius of the alert
|
||||||
|
$alert-ios-border-radius: 13px;
|
||||||
-/// @prop - Border radius of the alert
|
```
|
||||||
+// Border radius of the alert
|
|
||||||
$alert-ios-border-radius: 13px !default;
|
|
||||||
```
|
|
||||||
|
|
||||||
2. If we don't find the comments to be helpful, and want to stick with keeping the variable names specific, we should remove the comments entirely:
|
2. If we don't find the comments to be helpful, and want to stick with keeping the variable names specific, we should remove the comments entirely:
|
||||||
|
```diff
|
||||||
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
```diff
|
-/// @prop - Border radius of the alert
|
||||||
// alert.ios.vars.scss
|
$alert-ios-border-radius: 13px;
|
||||||
|
```
|
||||||
-/// @prop - Border radius of the alert
|
|
||||||
$alert-ios-border-radius: 13px !default;
|
|
||||||
```
|
|
||||||
|
|
||||||
3. If we find the comments to be helpful for certain variables or situations, like when there are math calculations involved, we should keep only the comments that are necessary to explain what is going on:
|
3. If we find the comments to be helpful for certain variables or situations, like when there are math calculations involved, we should keep only the comments that are necessary to explain what is going on:
|
||||||
```diff
|
```diff
|
||||||
-/// @prop - Height of the alert button
|
-/// @prop - Height of the alert button
|
||||||
/**
|
/**
|
||||||
* We want the height of the button to
|
* We want the height of the button to
|
||||||
* scale with the text so the next never runs
|
* scale with the text so the next never runs
|
||||||
* into the edge of the button. We change the height
|
* into the edge of the button. We change the height
|
||||||
* instead of adding padding because we would need to offset
|
* instead of adding padding because we would need to offset
|
||||||
* the height the padding and the border. Since the border uses
|
* the height the padding and the border. Since the border uses
|
||||||
* a hairline (<1px) width, this will cause subpixel rendering
|
* a hairline (<1px) width, this will cause subpixel rendering
|
||||||
* differences across browsers.
|
* differences across browsers.
|
||||||
*/
|
*/
|
||||||
$alert-ios-button-height: dynamic-font-min(1, 44px) !default;
|
$alert-ios-button-height: dynamic-font-min(1, 44px);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Variables
|
### Variables
|
||||||
|
|
||||||
@ -163,11 +161,11 @@ Example of global variables:
|
|||||||
```scss
|
```scss
|
||||||
// ionic.globals.scss
|
// ionic.globals.scss
|
||||||
|
|
||||||
$font-family-base: var(--ion-font-family, inherit) !default;
|
$font-family-base: var(--ion-font-family, inherit);
|
||||||
|
|
||||||
$hairlines-width: 0.55px !default;
|
$hairlines-width: 0.55px;
|
||||||
|
|
||||||
$placeholder-opacity: 0.6 !default;
|
$placeholder-opacity: 0.6;
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ✅ Theming
|
#### ✅ Theming
|
||||||
@ -179,32 +177,32 @@ Example of theme variables:
|
|||||||
```scss
|
```scss
|
||||||
// ionic.theme.default.scss
|
// ionic.theme.default.scss
|
||||||
|
|
||||||
$background-color-value: #fff !default;
|
$background-color-value: #fff;
|
||||||
$background-color-rgb-value: 255, 255, 255 !default;
|
$background-color-rgb-value: 255, 255, 255;
|
||||||
|
|
||||||
$text-color-value: #000 !default;
|
$text-color-value: #000;
|
||||||
$text-color-rgb-value: 0, 0, 0 !default;
|
$text-color-rgb-value: 0, 0, 0;
|
||||||
|
|
||||||
$background-color: var(
|
$background-color: var(
|
||||||
--ion-background-color,
|
--ion-background-color,
|
||||||
$background-color-value
|
$background-color-value
|
||||||
) !default;
|
);
|
||||||
$background-color-rgb: var(
|
$background-color-rgb: var(
|
||||||
--ion-background-color-rgb,
|
--ion-background-color-rgb,
|
||||||
$background-color-rgb-value
|
$background-color-rgb-value
|
||||||
) !default;
|
);
|
||||||
$text-color: var(--ion-text-color, $text-color-value) !default;
|
$text-color: var(--ion-text-color, $text-color-value);
|
||||||
$text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-value) !default;
|
$text-color-rgb: var(--ion-text-color-rgb, $text-color-rgb-value);
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
// ionic.theme.default.ios.scss
|
// ionic.theme.default.ios.scss
|
||||||
|
|
||||||
$backdrop-ios-color: var(--ion-backdrop-color, #000) !default;
|
$backdrop-ios-color: var(--ion-backdrop-color, #000);
|
||||||
$overlay-ios-background-color: var(
|
$overlay-ios-background-color: var(
|
||||||
--ion-overlay-background-color,
|
--ion-overlay-background-color,
|
||||||
var(--ion-color-step-100, #f9f9f9)
|
var(--ion-color-step-100, #f9f9f9)
|
||||||
) !default;
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ✅ Reusable values
|
#### ✅ Reusable values
|
||||||
@ -227,10 +225,10 @@ Example of reusable values:
|
|||||||
// alert.ios.vars.scss
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Padding end of the alert head
|
/// @prop - Padding end of the alert head
|
||||||
$alert-ios-head-padding-end: 16px !default;
|
$alert-ios-head-padding-end: 16px;
|
||||||
|
|
||||||
/// @prop - Padding start of the alert head
|
/// @prop - Padding start of the alert head
|
||||||
$alert-ios-head-padding-start: $alert-ios-head-padding-end !default;
|
$alert-ios-head-padding-start: $alert-ios-head-padding-end;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -259,10 +257,10 @@ $alert-ios-head-padding-start: $alert-ios-head-padding-end !default;
|
|||||||
// alert.ios.vars.scss
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Padding top of the alert head
|
/// @prop - Padding top of the alert head
|
||||||
$alert-ios-head-padding-top: 12px !default;
|
$alert-ios-head-padding-top: 12px;
|
||||||
|
|
||||||
/// @prop - Padding bottom of the alert head
|
/// @prop - Padding bottom of the alert head
|
||||||
$alert-ios-head-padding-bottom: 7px !default;
|
$alert-ios-head-padding-bottom: 7px;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -303,10 +301,10 @@ $global-md-item-padding-start: $global-md-item-padding-end;
|
|||||||
@import "../../themes/native/native.globals.md";
|
@import "../../themes/native/native.globals.md";
|
||||||
|
|
||||||
/// @prop - Padding end for the item content
|
/// @prop - Padding end for the item content
|
||||||
$item-md-padding-end: $global-md-item-padding-end !default;
|
$item-md-padding-end: $global-md-item-padding-end;
|
||||||
|
|
||||||
/// @prop - Padding start for the item content
|
/// @prop - Padding start for the item content
|
||||||
$item-md-padding-start: $global-md-item-padding-start !default;
|
$item-md-padding-start: $global-md-item-padding-start;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -315,10 +313,10 @@ $item-md-padding-start: $global-md-item-padding-start !default;
|
|||||||
@import "../../themes/native/native.globals.md";
|
@import "../../themes/native/native.globals.md";
|
||||||
|
|
||||||
/// @prop - Padding start for the divider
|
/// @prop - Padding start for the divider
|
||||||
$item-divider-md-padding-start: $global-md-item-padding-start !default;
|
$item-divider-md-padding-start: $global-md-item-padding-start;
|
||||||
|
|
||||||
/// @prop - Padding end for the divider
|
/// @prop - Padding end for the divider
|
||||||
$item-divider-md-padding-end: $global-md-item-padding-end !default;
|
$item-divider-md-padding-end: $global-md-item-padding-end;
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@ -338,10 +336,10 @@ $item-divider-md-padding-end: $global-md-item-padding-end !default;
|
|||||||
@import "../../themes/native/native.globals.md";
|
@import "../../themes/native/native.globals.md";
|
||||||
|
|
||||||
/// @prop - Padding end for the item content
|
/// @prop - Padding end for the item content
|
||||||
$item-md-padding-end: 16px !default;
|
$item-md-padding-end: 16px;
|
||||||
|
|
||||||
/// @prop - Padding start for the item content
|
/// @prop - Padding start for the item content
|
||||||
$item-md-padding-start: 16px !default;
|
$item-md-padding-start: 16px;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -351,10 +349,10 @@ $item-md-padding-start: 16px !default;
|
|||||||
@import "../item/item.md.vars";
|
@import "../item/item.md.vars";
|
||||||
|
|
||||||
/// @prop - Padding start for the divider
|
/// @prop - Padding start for the divider
|
||||||
$item-divider-md-padding-start: $item-md-padding-start !default;
|
$item-divider-md-padding-start: $item-md-padding-start;
|
||||||
|
|
||||||
/// @prop - Padding end for the divider
|
/// @prop - Padding end for the divider
|
||||||
$item-divider-md-padding-end: $item-md-padding-end !default;
|
$item-divider-md-padding-end: $item-md-padding-end;
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@ -380,8 +378,8 @@ $screen-breakpoints: (
|
|||||||
sm: 576px,
|
sm: 576px,
|
||||||
md: 768px,
|
md: 768px,
|
||||||
lg: 992px,
|
lg: 992px,
|
||||||
xl: 1200px,
|
xl: 1200px
|
||||||
) !default;
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### ✅ Dynamic calculations
|
#### ✅ Dynamic calculations
|
||||||
@ -429,7 +427,7 @@ $chip-avatar-size: math.div(24em, $chip-base-font-size);
|
|||||||
// alert.vars.scss
|
// alert.vars.scss
|
||||||
|
|
||||||
/// @prop - Font size of the alert button
|
/// @prop - Font size of the alert button
|
||||||
$alert-button-font-size: dynamic-font(14px) !default;
|
$alert-button-font-size: dynamic-font(14px);
|
||||||
```
|
```
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
@ -456,7 +454,7 @@ For example, the color of the label changes when focused in `md` mode. However,
|
|||||||
// label.md.vars.scss
|
// label.md.vars.scss
|
||||||
|
|
||||||
/// @prop - Text color of the stacked/floating label when it is focused
|
/// @prop - Text color of the stacked/floating label when it is focused
|
||||||
$label-md-text-color-focused: ion-color(primary, base) !default;
|
$label-md-text-color-focused: ion-color(primary, base);
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -485,7 +483,7 @@ $label-md-text-color-focused: ion-color(primary, base) !default;
|
|||||||
// label.ios.vars.scss
|
// label.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Text color of the stacked/floating label when it is focused
|
/// @prop - Text color of the stacked/floating label when it is focused
|
||||||
$label-ios-text-color-focused: null !default;
|
$label-ios-text-color-focused: null;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -537,7 +535,7 @@ A text alignment property should not be stored in a Sass variable, even if it is
|
|||||||
// action-sheet.ios.vars.scss
|
// action-sheet.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Text align of the action sheet
|
/// @prop - Text align of the action sheet
|
||||||
$action-sheet-ios-text-align: center !default;
|
$action-sheet-ios-text-align: center;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -597,10 +595,10 @@ Variables should not be used when they are structural changes of an element. Thi
|
|||||||
// alert.ios.vars.scss
|
// alert.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Flex wrap of the alert button group
|
/// @prop - Flex wrap of the alert button group
|
||||||
$alert-ios-button-group-flex-wrap: wrap !default;
|
$alert-ios-button-group-flex-wrap: wrap;
|
||||||
|
|
||||||
/// @prop - Flex of the alert button
|
/// @prop - Flex of the alert button
|
||||||
$alert-ios-button-flex: 1 1 auto !default;
|
$alert-ios-button-flex: 1 1 auto;
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
@ -662,13 +660,13 @@ We shouldn't use variables for changing things such as `font-size` or `font-weig
|
|||||||
// action-sheet.ios.vars.scss
|
// action-sheet.ios.vars.scss
|
||||||
|
|
||||||
/// @prop - Font size of the action sheet title
|
/// @prop - Font size of the action sheet title
|
||||||
$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px) !default;
|
$action-sheet-ios-title-font-size: dynamic-font-min(1, 13px);
|
||||||
|
|
||||||
/// @prop - Font weight of the action sheet title
|
/// @prop - Font weight of the action sheet title
|
||||||
$action-sheet-ios-title-font-weight: 400 !default;
|
$action-sheet-ios-title-font-weight: 400;
|
||||||
|
|
||||||
/// @prop - Font size of the action sheet sub title
|
/// @prop - Font size of the action sheet sub title
|
||||||
$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px) !default;
|
$action-sheet-ios-sub-title-font-size: dynamic-font-min(1, 13px);
|
||||||
```
|
```
|
||||||
|
|
||||||
```scss
|
```scss
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
"core",
|
"core",
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"version": "8.1.0"
|
"version": "8.1.1"
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
## [8.1.1](https://github.com/ionic-team/ionic-framework/compare/v8.1.0...v8.1.1) (2024-05-08)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ionic/angular-server
|
**Note:** Version bump only for package @ionic/angular-server
|
||||||
|
18
packages/angular-server/package-lock.json
generated
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/angular-server",
|
"name": "@ionic/angular-server",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@ionic/angular-server",
|
"name": "@ionic/angular-server",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ionic/core": "^8.1.0"
|
"@ionic/core": "^8.1.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-eslint/eslint-plugin": "^16.0.0",
|
"@angular-eslint/eslint-plugin": "^16.0.0",
|
||||||
@ -1119,9 +1119,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@ionic/core": {
|
"node_modules/@ionic/core": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.1.tgz",
|
||||||
"integrity": "sha512-CTa0JZA7T0Je7HiAinj/kjpxChQYDvitFBqMtNv88nOJn1KerbUKmV2JfQ0quNFneN8z/bBdNOaKc8T++cyDyg==",
|
"integrity": "sha512-ooB8gZtBuLeoHlE1wUvrXI0nyt26f46rPuyNh2Q062QniR4Ur5kqBXqWjUtdVUZqZvaElCbZJk3up+MQavoIMA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stencil/core": "^4.17.2",
|
"@stencil/core": "^4.17.2",
|
||||||
"ionicons": "^7.2.2",
|
"ionicons": "^7.2.2",
|
||||||
@ -7011,9 +7011,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@ionic/core": {
|
"@ionic/core": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.1.tgz",
|
||||||
"integrity": "sha512-CTa0JZA7T0Je7HiAinj/kjpxChQYDvitFBqMtNv88nOJn1KerbUKmV2JfQ0quNFneN8z/bBdNOaKc8T++cyDyg==",
|
"integrity": "sha512-ooB8gZtBuLeoHlE1wUvrXI0nyt26f46rPuyNh2Q062QniR4Ur5kqBXqWjUtdVUZqZvaElCbZJk3up+MQavoIMA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@stencil/core": "^4.17.2",
|
"@stencil/core": "^4.17.2",
|
||||||
"ionicons": "^7.2.2",
|
"ionicons": "^7.2.2",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/angular-server",
|
"name": "@ionic/angular-server",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"description": "Angular SSR Module for Ionic",
|
"description": "Angular SSR Module for Ionic",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ionic",
|
"ionic",
|
||||||
@ -62,6 +62,6 @@
|
|||||||
},
|
},
|
||||||
"prettier": "@ionic/prettier-config",
|
"prettier": "@ionic/prettier-config",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ionic/core": "^8.1.0"
|
"@ionic/core": "^8.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,17 @@
|
|||||||
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.
|
||||||
|
|
||||||
|
## [8.1.1](https://github.com/ionic-team/ionic-framework/compare/v8.1.0...v8.1.1) (2024-05-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **angular:** add formatOptions property to standalone datetime ([#29468](https://github.com/ionic-team/ionic-framework/issues/29468)) ([bb1db52](https://github.com/ionic-team/ionic-framework/commit/bb1db52567e0884a896f9ccd76c27540b52f5e48)), closes [#29464](https://github.com/ionic-team/ionic-framework/issues/29464)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
# [8.1.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.2...v8.1.0) (2024-05-01)
|
||||||
|
|
||||||
|
|
||||||
|
18
packages/angular/package-lock.json
generated
@ -1,15 +1,15 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/angular",
|
"name": "@ionic/angular",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@ionic/angular",
|
"name": "@ionic/angular",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ionic/core": "^8.1.0",
|
"@ionic/core": "^8.1.1",
|
||||||
"ionicons": "^7.0.0",
|
"ionicons": "^7.0.0",
|
||||||
"jsonc-parser": "^3.0.0",
|
"jsonc-parser": "^3.0.0",
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
@ -1398,9 +1398,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@ionic/core": {
|
"node_modules/@ionic/core": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.1.tgz",
|
||||||
"integrity": "sha512-CTa0JZA7T0Je7HiAinj/kjpxChQYDvitFBqMtNv88nOJn1KerbUKmV2JfQ0quNFneN8z/bBdNOaKc8T++cyDyg==",
|
"integrity": "sha512-ooB8gZtBuLeoHlE1wUvrXI0nyt26f46rPuyNh2Q062QniR4Ur5kqBXqWjUtdVUZqZvaElCbZJk3up+MQavoIMA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stencil/core": "^4.17.2",
|
"@stencil/core": "^4.17.2",
|
||||||
"ionicons": "^7.2.2",
|
"ionicons": "^7.2.2",
|
||||||
@ -9820,9 +9820,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@ionic/core": {
|
"@ionic/core": {
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.1.1.tgz",
|
||||||
"integrity": "sha512-CTa0JZA7T0Je7HiAinj/kjpxChQYDvitFBqMtNv88nOJn1KerbUKmV2JfQ0quNFneN8z/bBdNOaKc8T++cyDyg==",
|
"integrity": "sha512-ooB8gZtBuLeoHlE1wUvrXI0nyt26f46rPuyNh2Q062QniR4Ur5kqBXqWjUtdVUZqZvaElCbZJk3up+MQavoIMA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@stencil/core": "^4.17.2",
|
"@stencil/core": "^4.17.2",
|
||||||
"ionicons": "^7.2.2",
|
"ionicons": "^7.2.2",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ionic/angular",
|
"name": "@ionic/angular",
|
||||||
"version": "8.1.0",
|
"version": "8.1.1",
|
||||||
"description": "Angular specific wrappers for @ionic/core",
|
"description": "Angular specific wrappers for @ionic/core",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"ionic",
|
"ionic",
|
||||||
@ -47,7 +47,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ionic/core": "^8.1.0",
|
"@ionic/core": "^8.1.1",
|
||||||
"ionicons": "^7.0.0",
|
"ionicons": "^7.0.0",
|
||||||
"jsonc-parser": "^3.0.0",
|
"jsonc-parser": "^3.0.0",
|
||||||
"tslib": "^2.3.0"
|
"tslib": "^2.3.0"
|
||||||
|
@ -24,6 +24,7 @@ const DATETIME_INPUTS = [
|
|||||||
'disabled',
|
'disabled',
|
||||||
'doneText',
|
'doneText',
|
||||||
'firstDayOfWeek',
|
'firstDayOfWeek',
|
||||||
|
'formatOptions',
|
||||||
'highlightedDates',
|
'highlightedDates',
|
||||||
'hourCycle',
|
'hourCycle',
|
||||||
'hourValues',
|
'hourValues',
|
||||||
|
156
packages/angular/test/apps/ng18/angular.json
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"test-app": {
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"projectType": "application",
|
||||||
|
"prefix": "app",
|
||||||
|
"schematics": {},
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/test-app/browser",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
{
|
||||||
|
"glob": "**/*",
|
||||||
|
"input": "src/assets",
|
||||||
|
"output": "assets"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"glob": "**/*.svg",
|
||||||
|
"input": "node_modules/ionicons/dist/ionicons/svg",
|
||||||
|
"output": "./svg"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"styles": ["src/styles.css"],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"optimization": true,
|
||||||
|
"outputHashing": "all",
|
||||||
|
"sourceMap": false,
|
||||||
|
"namedChunks": false,
|
||||||
|
"aot": true,
|
||||||
|
"progress": false,
|
||||||
|
"extractLicenses": true,
|
||||||
|
"vendorChunk": false,
|
||||||
|
"buildOptimizer": true,
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "2mb",
|
||||||
|
"maximumError": "5mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "6kb"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildOptimizer": false,
|
||||||
|
"optimization": false,
|
||||||
|
"vendorChunk": true,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"namedChunks": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"options": {
|
||||||
|
"buildTarget": "test-app:build"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"buildTarget": "test-app:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildTarget": "test-app:build:development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"buildTarget": "test-app:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"builder": "@angular-eslint/builder:lint",
|
||||||
|
"options": {
|
||||||
|
"lintFilePatterns": ["src/**/*.ts", "src/**/*.html"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"server": {
|
||||||
|
"builder": "@angular-devkit/build-angular:server",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/test-app/server",
|
||||||
|
"main": "server.ts",
|
||||||
|
"tsConfig": "tsconfig.server.json"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"outputHashing": "media",
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sourceMap": false,
|
||||||
|
"optimization": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve-ssr": {
|
||||||
|
"builder": "@angular-devkit/build-angular:ssr-dev-server",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "test-app:build",
|
||||||
|
"serverTarget": "test-app:server"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "test-app:build:production",
|
||||||
|
"serverTarget": "test-app:server:production"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prerender": {
|
||||||
|
"builder": "@angular-devkit/build-angular:prerender",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "test-app:build:production",
|
||||||
|
"serverTarget": "test-app:server:production",
|
||||||
|
"routes": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cli": {
|
||||||
|
"schematicCollections": ["@angular-eslint/schematics"],
|
||||||
|
"cache": {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|