Compare commits
53 Commits
liamdebeas
...
ROU-4835
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95daa05a49 | ||
|
|
a57be0941d | ||
|
|
9e7c9a5934 | ||
|
|
e93941ffa3 | ||
|
|
2e9fee8ed8 | ||
|
|
6f42c29250 | ||
|
|
0decc7770d | ||
|
|
1674211ce7 | ||
|
|
fb445322c3 | ||
|
|
2220d83d32 | ||
|
|
adf220b681 | ||
|
|
e64015a609 | ||
|
|
3d9871a77f | ||
|
|
e91fee4f2d | ||
|
|
b315b0cb29 | ||
|
|
7b6c330f17 | ||
|
|
b3cd49bf22 | ||
|
|
6c36cef241 | ||
|
|
4d6edee89c | ||
|
|
6945adc3cc | ||
|
|
90a7e70a1c | ||
|
|
0f5d1c02d2 | ||
|
|
4b79bbef7d | ||
|
|
ac7631a324 | ||
|
|
b5cb828861 | ||
|
|
101ad5402f | ||
|
|
de35fa8b94 | ||
|
|
c766528a17 | ||
|
|
9b3cf9fbc2 | ||
|
|
ee5da7a747 | ||
|
|
c4bfc783e0 | ||
|
|
0137e732ce | ||
|
|
88ecb29e39 | ||
|
|
f726c35868 | ||
|
|
4a9d84ecbd | ||
|
|
f08759c2b8 | ||
|
|
2053bc77a6 | ||
|
|
02e05bd7cb | ||
|
|
fa387cb2a2 | ||
|
|
8ab116150c | ||
|
|
8c9182c52f | ||
|
|
c0a8e7a95d | ||
|
|
0c5a2967d8 | ||
|
|
6ebb3c4e38 | ||
|
|
cdcb6decbd | ||
|
|
652ea169b7 | ||
|
|
42c09a7ea1 | ||
|
|
c23be1befd | ||
|
|
a2923aaeb3 | ||
|
|
eeab96de55 | ||
|
|
ca0923812a | ||
|
|
1be956bd18 | ||
|
|
8ad66c03d7 |
66
.github/CODEOWNERS
vendored
@@ -13,73 +13,7 @@
|
||||
|
||||
* @ionic-team/framework
|
||||
|
||||
# Frameworks
|
||||
|
||||
## Angular
|
||||
|
||||
/packages/angular/ @sean-perkins @thetaPC
|
||||
/packages/angular-server @sean-perkins @thetaPC
|
||||
/packages/angular/test @thetaPC
|
||||
|
||||
## React
|
||||
|
||||
/packages/react/ @amandaejohnston
|
||||
/packages/react-router @amandaejohnston
|
||||
/packages/react/test-app/
|
||||
/packages/react-router/test-app/
|
||||
|
||||
## Vue
|
||||
|
||||
/packages/vue/ @liamdebeasi @thetaPC
|
||||
/packages/vue-router/ @liamdebeasi @thetaPC
|
||||
/packages/vue/test/ @thetaPC
|
||||
/packages/vue-router/__tests__ @thetaPC
|
||||
|
||||
# Components
|
||||
|
||||
/core/src/components/accordion/ @liamdebeasi
|
||||
/core/src/components/accordion-group/ @liamdebeasi
|
||||
|
||||
/core/src/components/checkbox/ @amandaejohnston
|
||||
|
||||
/core/src/components/datetime/ @liamdebeasi @amandaejohnston @sean-perkins
|
||||
/core/src/components/datetime-button/ @liamdebeasi
|
||||
|
||||
/core/src/components/item/ @brandyscarney
|
||||
|
||||
/core/src/components/menu/ @amandaejohnston
|
||||
/core/src/components/menu-toggle/ @amandaejohnston
|
||||
|
||||
/core/src/components/nav/ @sean-perkins
|
||||
/core/src/components/nav-link/ @sean-perkins
|
||||
|
||||
/core/src/components/picker/ @liamdebeasi
|
||||
/core/src/components/picker-column/ @liamdebeasi
|
||||
|
||||
/core/src/components/radio/ @amandaejohnston
|
||||
/core/src/components/radio-group/ @amandaejohnston
|
||||
|
||||
/core/src/components/refresher/ @liamdebeasi
|
||||
/core/src/components/refresher-content/ @liamdebeasi
|
||||
|
||||
/core/src/components/searchbar/ @brandyscarney
|
||||
|
||||
/core/src/components/segment/ @brandyscarney
|
||||
/core/src/components/segment-button/ @brandyscarney
|
||||
|
||||
/core/src/components/skeleton-text/ @brandyscarney
|
||||
|
||||
# Utilities
|
||||
|
||||
/core/src/utils/animation/ @liamdebeasi
|
||||
/core/src/utils/content/ @sean-perkins
|
||||
/core/src/utils/gesture/ @liamdebeasi
|
||||
/core/src/utils/input-shims/ @liamdebeasi
|
||||
/core/src/utils/keyboard/ @liamdebeasi
|
||||
/core/src/utils/logging/ @amandaejohnston
|
||||
/core/src/utils/sanitization/ @liamdebeasi
|
||||
/core/src/utils/tap-click/ @liamdebeasi
|
||||
/core/src/utils/transition/ @liamdebeasi
|
||||
|
||||
/core/src/css/ @brandyscarney
|
||||
/core/src/themes/ @brandyscarney
|
||||
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -25,7 +25,7 @@ Issue number: resolves #
|
||||
If this introduces a breaking change:
|
||||
1. Describe the impact and migration path for existing applications below.
|
||||
2. Update the BREAKING.md file with the breaking change.
|
||||
3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#footer for more information.
|
||||
3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information.
|
||||
-->
|
||||
|
||||
|
||||
|
||||
2
.github/workflows/assign-issues.yml
vendored
@@ -13,6 +13,6 @@ jobs:
|
||||
- name: 'Auto-assign issue'
|
||||
uses: pozil/auto-assign-issue@edee9537367a8fbc625d27f9e10aa8bad47b8723 # v1.13.0
|
||||
with:
|
||||
assignees: liamdebeasi, sean-perkins, brandyscarney, amandaejohnston, mapsandapps, thetaPC
|
||||
assignees: liamdebeasi, sean-perkins, brandyscarney, amandaejohnston, thetaPC
|
||||
numOfAssignee: 1
|
||||
allowSelfAssign: false
|
||||
|
||||
8
.github/workflows/release-ionic.yml
vendored
@@ -41,8 +41,8 @@ jobs:
|
||||
uses: ./.github/workflows/actions/upload-archive
|
||||
with:
|
||||
name: ionic-docs
|
||||
output: docs/DocsBuild.zip
|
||||
paths: docs/core.json docs/core.d.ts
|
||||
output: packages/docs/DocsBuild.zip
|
||||
paths: packages/docs/core.json packages/docs/core.d.ts
|
||||
|
||||
release-docs:
|
||||
needs: [release-core]
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
uses: ./.github/workflows/actions/download-archive
|
||||
with:
|
||||
name: ionic-docs
|
||||
path: ./docs
|
||||
path: ./packages/docs
|
||||
filename: DocsBuild.zip
|
||||
- uses: ./.github/workflows/actions/publish-npm
|
||||
with:
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
tag: ${{ inputs.tag }}
|
||||
version: ${{ inputs.version }}
|
||||
preid: ${{ inputs.preid }}
|
||||
working-directory: 'docs'
|
||||
working-directory: 'packages/docs'
|
||||
token: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
release-angular:
|
||||
|
||||
61
CHANGELOG.md
@@ -3,6 +3,67 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
|
||||
## [7.8.3](https://github.com/ionic-team/ionic-framework/compare/v7.8.2...v7.8.3) (2024-04-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **button:** activated outline button in toolbar no longer blends into background on MD dark mode ([#29216](https://github.com/ionic-team/ionic-framework/issues/29216)) ([ee5da7a](https://github.com/ionic-team/ionic-framework/commit/ee5da7a747c0a0b420c5e371a9fe9ec4938d179e))
|
||||
* **popover:** viewport can be scrolled if no content present ([#29215](https://github.com/ionic-team/ionic-framework/issues/29215)) ([f08759c](https://github.com/ionic-team/ionic-framework/commit/f08759c2b8256ff66f8d1901bd8e0be4617db262)), closes [#29211](https://github.com/ionic-team/ionic-framework/issues/29211)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-rc.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.4...v8.0.0-rc.0) (2024-03-27)
|
||||
|
||||
**Note:** Version bump only for package ionic-framework
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-beta.4](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.3...v8.0.0-beta.4) (2024-03-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **angular:** schematics account for new theme files ([#29185](https://github.com/ionic-team/ionic-framework/issues/29185)) ([b0a10df](https://github.com/ionic-team/ionic-framework/commit/b0a10dfa56a65ee3905cc2c3d48d2221a42f222f))
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **haptics:** remove cordova haptics support ([#29186](https://github.com/ionic-team/ionic-framework/issues/29186)) ([9efeb0a](https://github.com/ionic-team/ionic-framework/commit/9efeb0ad31aadee5f5ae542641d928ecf93fe82a))
|
||||
* **searchbar:** autocapitalize defaults to off ([#29107](https://github.com/ionic-team/ionic-framework/issues/29107)) ([6e477b7](https://github.com/ionic-team/ionic-framework/commit/6e477b743e41b2b37627c8208901704f599b762a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **button:** add circular shape as round ([#29161](https://github.com/ionic-team/ionic-framework/issues/29161)) ([44529f0](https://github.com/ionic-team/ionic-framework/commit/44529f0a62f1b1ce42750a20f19e829b2789febd))
|
||||
* **input:** add input-password-toggle component ([#29175](https://github.com/ionic-team/ionic-framework/issues/29175)) ([6c500fd](https://github.com/ionic-team/ionic-framework/commit/6c500fd6b2e2553c11fcddc9d86ac9a29f76e172))
|
||||
* remove css animations support for ionic animations ([#29123](https://github.com/ionic-team/ionic-framework/issues/29123)) ([892594d](https://github.com/ionic-team/ionic-framework/commit/892594de0665e8fc5c8a737d292812842ea03d64))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **searchbar:** The `autocapitalize` property on Searchbar now defaults to `'off'`.
|
||||
* **haptics:** Support for the Cordova Haptics plugin has been removed. Components that integrate with haptics, such as `ion-picker` and `ion-toggle`, will continue to function but will no longer play haptics in Cordova environments. Developers should migrate to Capacitor to continue to have haptics in these components.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.8.2](https://github.com/ionic-team/ionic-framework/compare/v7.8.1...v7.8.2) (2024-03-27)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **searchbar:** autocapitalize is initialized correctly ([#29197](https://github.com/ionic-team/ionic-framework/issues/29197)) ([8ad66c0](https://github.com/ionic-team/ionic-framework/commit/8ad66c03d777edcab19c97cba696b171acc2d2e8)), closes [#29193](https://github.com/ionic-team/ionic-framework/issues/29193)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-beta.3](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.2...v8.0.0-beta.3) (2024-03-20)
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</h1>
|
||||
|
||||
<p align="center">
|
||||
Ionic is an open source app development toolkit for building modern, fast, top-quality cross-platform native and Progressive Web Apps from a single codebase with JavaScript and the Web. test 123
|
||||
Ionic is an open source app development toolkit for building modern, fast, top-quality cross-platform native and Progressive Web Apps from a single codebase with JavaScript and the Web.
|
||||
</p>
|
||||
<p align="center">
|
||||
Ionic is based on <a href="https://www.webcomponents.org/introduction">Web Components</a>, which enables significant performance, usability, and feature improvements alongside support for popular web frameworks like <a href="https://angular.io/">Angular</a>, <a href="https://reactjs.com/">React</a>, and <a href="https://vuejs.org/">Vue</a>.
|
||||
@@ -20,7 +20,7 @@
|
||||
<a href="https://github.com/ionic-team/ionic-framework/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="Ionic Framework is released under the MIT license." />
|
||||
</a>
|
||||
<a href="https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md">
|
||||
<a href="https://github.com/ionic-team/ionic/blob/main/docs/CONTRIBUTING.md">
|
||||
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
|
||||
</a>
|
||||
<a href="https://twitter.com/Ionicframework">
|
||||
@@ -38,7 +38,7 @@
|
||||
Documentation
|
||||
</a>
|
||||
<span> · </span>
|
||||
<a href="https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md">Contribute</a>
|
||||
<a href="https://github.com/ionic-team/ionic/blob/main/docs/CONTRIBUTING.md">Contribute</a>
|
||||
<span> · </span>
|
||||
<a href="https://blog.ionicframework.com/">Blog</a>
|
||||
<br />
|
||||
@@ -88,7 +88,7 @@ The Ionic Conference App is a full featured Ionic app. It is the perfect startin
|
||||
### Contributing
|
||||
|
||||
Thanks for your interest in contributing! Read up on our guidelines for
|
||||
[contributing](https://github.com/ionic-team/ionic/blob/main/.github/CONTRIBUTING.md)
|
||||
[contributing](https://github.com/ionic-team/ionic/blob/main/docs/CONTRIBUTING.md)
|
||||
and then look through our issues with a [help wanted](https://github.com/ionic-team/ionic/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
|
||||
label.
|
||||
|
||||
|
||||
@@ -3,6 +3,63 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
|
||||
## [7.8.3](https://github.com/ionic-team/ionic-framework/compare/v7.8.2...v7.8.3) (2024-04-03)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **button:** activated outline button in toolbar no longer blends into background on MD dark mode ([#29216](https://github.com/ionic-team/ionic-framework/issues/29216)) ([ee5da7a](https://github.com/ionic-team/ionic-framework/commit/ee5da7a747c0a0b420c5e371a9fe9ec4938d179e))
|
||||
* **popover:** viewport can be scrolled if no content present ([#29215](https://github.com/ionic-team/ionic-framework/issues/29215)) ([f08759c](https://github.com/ionic-team/ionic-framework/commit/f08759c2b8256ff66f8d1901bd8e0be4617db262)), closes [#29211](https://github.com/ionic-team/ionic-framework/issues/29211)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-rc.0](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.4...v8.0.0-rc.0) (2024-03-27)
|
||||
|
||||
**Note:** Version bump only for package @ionic/core
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-beta.4](https://github.com/ionic-team/ionic-framework/compare/v8.0.0-beta.3...v8.0.0-beta.4) (2024-03-27)
|
||||
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **haptics:** remove cordova haptics support ([#29186](https://github.com/ionic-team/ionic-framework/issues/29186)) ([9efeb0a](https://github.com/ionic-team/ionic-framework/commit/9efeb0ad31aadee5f5ae542641d928ecf93fe82a))
|
||||
* **searchbar:** autocapitalize defaults to off ([#29107](https://github.com/ionic-team/ionic-framework/issues/29107)) ([6e477b7](https://github.com/ionic-team/ionic-framework/commit/6e477b743e41b2b37627c8208901704f599b762a))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **button:** add circular shape as round ([#29161](https://github.com/ionic-team/ionic-framework/issues/29161)) ([44529f0](https://github.com/ionic-team/ionic-framework/commit/44529f0a62f1b1ce42750a20f19e829b2789febd))
|
||||
* **input:** add input-password-toggle component ([#29175](https://github.com/ionic-team/ionic-framework/issues/29175)) ([6c500fd](https://github.com/ionic-team/ionic-framework/commit/6c500fd6b2e2553c11fcddc9d86ac9a29f76e172))
|
||||
* remove css animations support for ionic animations ([#29123](https://github.com/ionic-team/ionic-framework/issues/29123)) ([892594d](https://github.com/ionic-team/ionic-framework/commit/892594de0665e8fc5c8a737d292812842ea03d64))
|
||||
|
||||
|
||||
### BREAKING CHANGES
|
||||
|
||||
* **searchbar:** The `autocapitalize` property on Searchbar now defaults to `'off'`.
|
||||
* **haptics:** Support for the Cordova Haptics plugin has been removed. Components that integrate with haptics, such as `ion-picker` and `ion-toggle`, will continue to function but will no longer play haptics in Cordova environments. Developers should migrate to Capacitor to continue to have haptics in these components.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [7.8.2](https://github.com/ionic-team/ionic-framework/compare/v7.8.1...v7.8.2) (2024-03-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **searchbar:** autocapitalize is initialized correctly ([#29197](https://github.com/ionic-team/ionic-framework/issues/29197)) ([8ad66c0](https://github.com/ionic-team/ionic-framework/commit/8ad66c03d777edcab19c97cba696b171acc2d2e8)), closes [#29193](https://github.com/ionic-team/ionic-framework/issues/29193)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [8.0.0-beta.3](https://github.com/ionic-team/ionic-framework/compare/v7.8.1...v8.0.0-beta.3) (2024-03-20)
|
||||
|
||||
|
||||
|
||||
@@ -282,6 +282,7 @@ ion-card,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card,prop,rel,string | undefined,undefined,false,false
|
||||
ion-card,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-card,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||
ion-card,prop,shape,"rectangular" | "round" | undefined,undefined,false,true
|
||||
ion-card,prop,target,string | undefined,undefined,false,false
|
||||
ion-card,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
@@ -346,6 +347,7 @@ ion-chip,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "second
|
||||
ion-chip,prop,disabled,boolean,false,false,false
|
||||
ion-chip,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-chip,prop,outline,boolean,false,false,false
|
||||
ion-chip,prop,shape,"rectangular" | "round" | undefined,undefined,false,false
|
||||
ion-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-chip,css-prop,--background
|
||||
ion-chip,css-prop,--color
|
||||
@@ -387,6 +389,7 @@ ion-col,css-prop,--ion-grid-columns
|
||||
|
||||
ion-content,shadow
|
||||
ion-content,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-content,prop,fixedSlotPlacement,"after" | "before",'after',false,false
|
||||
ion-content,prop,forceOverscroll,boolean | undefined,undefined,false,false
|
||||
ion-content,prop,fullscreen,boolean,false,false,false
|
||||
ion-content,prop,mode,"ios" | "md",undefined,false,false
|
||||
@@ -598,6 +601,7 @@ ion-input,prop,autocomplete,"name" | "email" | "tel" | "url" | "on" | "off" | "h
|
||||
ion-input,prop,autocorrect,"off" | "on",'off',false,false
|
||||
ion-input,prop,autofocus,boolean,false,false,false
|
||||
ion-input,prop,clearInput,boolean,false,false,false
|
||||
ion-input,prop,clearInputIcon,string | undefined,undefined,false,false
|
||||
ion-input,prop,clearOnEdit,boolean | undefined,undefined,false,false
|
||||
ion-input,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-input,prop,counter,boolean,false,false,false
|
||||
|
||||
40
core/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "8.0.0-beta.3",
|
||||
"version": "8.0.0-rc.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ionic/core",
|
||||
"version": "8.0.0-beta.3",
|
||||
"version": "8.0.0-rc.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@stencil/core": "^4.12.2",
|
||||
@@ -612,9 +612,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@capacitor/core": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.3.tgz",
|
||||
"integrity": "sha512-xEuQmP+h0tugl2N+qRcdrUavZydvTnnmtvqu/OtCBb/bKZo2PDRFft7MxuQRE2GxXs6kLy3cvwzhDAHB3a+9mw==",
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.4.tgz",
|
||||
"integrity": "sha512-iZBgvx3o4amzKv5ttA+QHB6i7cxK+/mYpCQd1tnSdipg6ZkvfBhg1HkzhEqHk+I7MNur+QwgYDZho9+ycHRwOw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -1832,9 +1832,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/core": {
|
||||
"version": "4.12.6",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg==",
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.14.0.tgz",
|
||||
"integrity": "sha512-+s0u/KsNolXZ7tC2hEMgMA3jaNaqOhZvYKwSzjQbc0Wv+cB481Isxzo7ifgEWRYqsJzNSyqhO6cyu/EJrGGTdg==",
|
||||
"bin": {
|
||||
"stencil": "bin/stencil"
|
||||
},
|
||||
@@ -1866,9 +1866,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@stencil/vue-output-target": {
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.8.7.tgz",
|
||||
"integrity": "sha512-hgOzbKKgLdCFrhLpmaw/qQrPSXl6hZ09K+j3p/iWh3esq6sxnwuW1PJKLniwkT4Z/JlDIk6stGPGQYi+WE5I2Q==",
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.8.8.tgz",
|
||||
"integrity": "sha512-xrpz92lmTuLgwY9CLgl2Q14+zBXfBuXiRS6uXFPfeaFo0pe+do8cZitOOQ8i8tcoCa/tAqgD9B9CD+yQehSIGg==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@stencil/core": ">=2.0.0 || >=3 || >= 4.0.0-beta.0 || >= 4.0.0"
|
||||
@@ -10947,9 +10947,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@capacitor/core": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.3.tgz",
|
||||
"integrity": "sha512-xEuQmP+h0tugl2N+qRcdrUavZydvTnnmtvqu/OtCBb/bKZo2PDRFft7MxuQRE2GxXs6kLy3cvwzhDAHB3a+9mw==",
|
||||
"version": "5.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@capacitor/core/-/core-5.7.4.tgz",
|
||||
"integrity": "sha512-iZBgvx3o4amzKv5ttA+QHB6i7cxK+/mYpCQd1tnSdipg6ZkvfBhg1HkzhEqHk+I7MNur+QwgYDZho9+ycHRwOw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^2.1.0"
|
||||
@@ -11826,9 +11826,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/core": {
|
||||
"version": "4.12.6",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.6.tgz",
|
||||
"integrity": "sha512-15JO2TdaxGVKNdLZb/2TtDa+juj3XGD/V0y/disgdzYYSnajgSh06nwODfdHz9eTUh1Hisz+KIo857I1rCZrfg=="
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.14.0.tgz",
|
||||
"integrity": "sha512-+s0u/KsNolXZ7tC2hEMgMA3jaNaqOhZvYKwSzjQbc0Wv+cB481Isxzo7ifgEWRYqsJzNSyqhO6cyu/EJrGGTdg=="
|
||||
},
|
||||
"@stencil/react-output-target": {
|
||||
"version": "0.5.3",
|
||||
@@ -11845,9 +11845,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@stencil/vue-output-target": {
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.8.7.tgz",
|
||||
"integrity": "sha512-hgOzbKKgLdCFrhLpmaw/qQrPSXl6hZ09K+j3p/iWh3esq6sxnwuW1PJKLniwkT4Z/JlDIk6stGPGQYi+WE5I2Q==",
|
||||
"version": "0.8.8",
|
||||
"resolved": "https://registry.npmjs.org/@stencil/vue-output-target/-/vue-output-target-0.8.8.tgz",
|
||||
"integrity": "sha512-xrpz92lmTuLgwY9CLgl2Q14+zBXfBuXiRS6uXFPfeaFo0pe+do8cZitOOQ8i8tcoCa/tAqgD9B9CD+yQehSIGg==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ionic/core",
|
||||
"version": "8.0.0-beta.3",
|
||||
"version": "8.0.0-rc.0",
|
||||
"description": "Base components for Ionic",
|
||||
"keywords": [
|
||||
"ionic",
|
||||
@@ -79,7 +79,7 @@
|
||||
"build.tokens": "node ./scripts/tokens.js && npm run lint.sass.fix",
|
||||
"clean": "node scripts/clean.js",
|
||||
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
|
||||
"css.sass": "sass --embed-sources src/css:./css",
|
||||
"css.sass": "sass --embed-sources --style compressed src/css:./css",
|
||||
"eslint": "eslint src",
|
||||
"lint": "npm run lint.ts && npm run lint.sass && npm run prettier -- --write --cache",
|
||||
"lint.fix": "npm run lint.ts.fix && npm run lint.sass.fix && npm run prettier -- --write --cache",
|
||||
|
||||
@@ -1,44 +1,4 @@
|
||||
|
||||
## Build
|
||||
# Core Scripts
|
||||
|
||||
### 1. Clone ionic
|
||||
|
||||
git@github.com:ionic-team/ionic.git
|
||||
cd ionic
|
||||
|
||||
### 2. Run `npm install`
|
||||
|
||||
cd core
|
||||
npm install
|
||||
|
||||
|
||||
Notice that `@ionic/core` lives in `core`.
|
||||
|
||||
### 3. Run `npm start`
|
||||
|
||||
Make sure you are inside the `core` directory.
|
||||
|
||||
npm start
|
||||
|
||||
With the `dev` command, Ionic components will be built with [Stencil](https://stenciljs.com/), changes to source files are watched, a local http server will startup, and http://localhost:3333/ will open in a browser.
|
||||
|
||||
### 4. Preview
|
||||
|
||||
Navigate to http://localhost:3333/src/components/. Each component has small e2e apps found in the `test` directory, for example: http://localhost:3333/src/components/button/test/basic
|
||||
|
||||
As changes are made in an editor to source files, the e2e app will live-reload.
|
||||
|
||||
## How to contribute
|
||||
|
||||
1. `npm start` allows you to modify the components and have live reloading, just like another ionic app.
|
||||
|
||||
2. When everything looks good, run `npm run validate` to verify the tests linter and production build passes.
|
||||
|
||||
|
||||
# Deploy
|
||||
|
||||
1. `npm run prepare.deploy`
|
||||
2. Review/update changelog
|
||||
3. Commit updates using the package name and version number as the commit message.
|
||||
4. `npm run deploy`
|
||||
5. :tada:
|
||||
This file has been moved to [/docs/core/testing/preview-changes.md](/docs/core/testing/preview-changes.md).
|
||||
|
||||
32
core/src/components.d.ts
vendored
@@ -618,6 +618,10 @@ export namespace Components {
|
||||
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
||||
*/
|
||||
"routerDirection": RouterDirection;
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
/**
|
||||
* Specifies where to display the linked URL. Only applies when an `href` is provided. Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
|
||||
*/
|
||||
@@ -750,6 +754,10 @@ export namespace Components {
|
||||
* Display an outline style button.
|
||||
*/
|
||||
"outline": boolean;
|
||||
/**
|
||||
* Define the Chip corner shape, when using the Ionic Theme.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
@@ -866,6 +874,10 @@ export namespace Components {
|
||||
* 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).
|
||||
*/
|
||||
"color"?: Color;
|
||||
/**
|
||||
* Controls where the fixed content is placed relative to the main content in the DOM. This can be used to control the order in which fixed elements receive keyboard focus. For example, if a FAB in the fixed slot should receive keyboard focus before the main page content, set this property to `'before'`.
|
||||
*/
|
||||
"fixedSlotPlacement": 'after' | 'before';
|
||||
/**
|
||||
* If `true` and the content does not cause an overflow scroll, the scroll interaction will cause a bounce. If the content exceeds the bounds of ionContent, nothing will change. Note, this does not disable the system bounce on iOS. That is an OS level setting.
|
||||
*/
|
||||
@@ -1342,6 +1354,10 @@ export namespace Components {
|
||||
* If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
|
||||
*/
|
||||
"clearInput": boolean;
|
||||
/**
|
||||
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
|
||||
*/
|
||||
"clearInputIcon"?: string;
|
||||
/**
|
||||
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
|
||||
*/
|
||||
@@ -5834,6 +5850,10 @@ declare namespace LocalJSX {
|
||||
* When using a router, it specifies the transition direction when navigating to another page using `href`.
|
||||
*/
|
||||
"routerDirection"?: RouterDirection;
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
/**
|
||||
* Specifies where to display the linked URL. Only applies when an `href` is provided. Special keywords: `"_blank"`, `"_self"`, `"_parent"`, `"_top"`.
|
||||
*/
|
||||
@@ -5978,6 +5998,10 @@ declare namespace LocalJSX {
|
||||
* Display an outline style button.
|
||||
*/
|
||||
"outline"?: boolean;
|
||||
/**
|
||||
* Define the Chip corner shape, when using the Ionic Theme.
|
||||
*/
|
||||
"shape"?: 'round' | 'rectangular';
|
||||
/**
|
||||
* The theme determines the visual appearance of the component.
|
||||
*/
|
||||
@@ -6094,6 +6118,10 @@ declare namespace LocalJSX {
|
||||
* 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).
|
||||
*/
|
||||
"color"?: Color;
|
||||
/**
|
||||
* Controls where the fixed content is placed relative to the main content in the DOM. This can be used to control the order in which fixed elements receive keyboard focus. For example, if a FAB in the fixed slot should receive keyboard focus before the main page content, set this property to `'before'`.
|
||||
*/
|
||||
"fixedSlotPlacement"?: 'after' | 'before';
|
||||
/**
|
||||
* If `true` and the content does not cause an overflow scroll, the scroll interaction will cause a bounce. If the content exceeds the bounds of ionContent, nothing will change. Note, this does not disable the system bounce on iOS. That is an OS level setting.
|
||||
*/
|
||||
@@ -6578,6 +6606,10 @@ declare namespace LocalJSX {
|
||||
* If `true`, a clear icon will appear in the input when there is a value. Clicking it clears the input.
|
||||
*/
|
||||
"clearInput"?: boolean;
|
||||
/**
|
||||
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
|
||||
*/
|
||||
"clearInputIcon"?: string;
|
||||
/**
|
||||
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
|
||||
*/
|
||||
|
||||
@@ -109,7 +109,18 @@
|
||||
::slotted(ion-icon[slot="start"]),
|
||||
::slotted(ion-icon[slot="end"]),
|
||||
::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1em;
|
||||
font-size: px-to-rem(16);
|
||||
}
|
||||
|
||||
:host(.button-xsmall),
|
||||
:host(.button-small),
|
||||
:host(.button-large),
|
||||
:host(.button-xlarge) {
|
||||
::slotted(ion-icon[slot="start"]),
|
||||
::slotted(ion-icon[slot="end"]),
|
||||
::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Button extra small */
|
||||
|
||||
@@ -149,7 +149,20 @@
|
||||
}
|
||||
|
||||
::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1.125em;
|
||||
/**
|
||||
* The values were provided through a native iOS app.
|
||||
* min font size: 15px, default font size: 18px, max font size: 43px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 16px
|
||||
* (derived from rem), then the base size can use the default font
|
||||
* size of the icon.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(0.84, 18px, 2.39, 1em);
|
||||
}
|
||||
|
||||
:host(.button-small.button-has-icon-only) {
|
||||
@@ -157,11 +170,23 @@
|
||||
min-width: clamp(23px, 2.16em, 54px);
|
||||
// TODO(FW-6053): replace em value with the min-height variable.
|
||||
min-height: clamp(23px, 2.16em, 54px);
|
||||
|
||||
}
|
||||
|
||||
:host(.button-small) ::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1.4em;
|
||||
/**
|
||||
* The values were provided through a native iOS app.
|
||||
* min font size: 12px, default font size: 17px, max font size: 40px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 13px
|
||||
* (derived from rem) and the default font size of the icon is
|
||||
* 17px, then the base size would need to be increased.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(0.58, 20.93px, 1.92, 1em);
|
||||
}
|
||||
|
||||
:host(.button-large.button-has-icon-only) {
|
||||
@@ -172,7 +197,20 @@
|
||||
}
|
||||
|
||||
:host(.button-large) ::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1em;
|
||||
/**
|
||||
* The values were provided through a native iOS app.
|
||||
* min font size: 15px, default font size: 18px, max font size: 43px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 20px
|
||||
* (derived from rem) and the default font size of the icon is
|
||||
* 18px, then the base size would need to be decreased.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(1.05, 14.4px, 2.99, 1em);
|
||||
}
|
||||
|
||||
// iOS Button Focused
|
||||
@@ -247,3 +285,12 @@
|
||||
:host(.button-solid.ion-color.ion-activated) .button-native::after {
|
||||
background: #{current-color(shade)};
|
||||
}
|
||||
|
||||
|
||||
// Activated Button in Toolbar
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
|
||||
background: var(--ion-toolbar-color, var(--color));
|
||||
color: #{var(--ion-toolbar-background, var(--background), ion-color(primary, contrast))};
|
||||
}
|
||||
|
||||
@@ -142,7 +142,21 @@
|
||||
}
|
||||
|
||||
::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1.6em;
|
||||
/**
|
||||
* The values were provided through MD design,
|
||||
* large and small are based on the iOS sizes.
|
||||
* min font size: 15px, default font size: 22.4px, max font size: 43px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 14px
|
||||
* (derived from rem) and the default font size of the icon is
|
||||
* 22.4px, then the base size would need to be increased.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(0.59, 25.6px, 1.68, 1em);
|
||||
}
|
||||
|
||||
:host(.button-small.button-has-icon-only) {
|
||||
@@ -153,7 +167,21 @@
|
||||
}
|
||||
|
||||
:host(.button-small) ::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1.23em;
|
||||
/**
|
||||
* The values were provided through MD design,
|
||||
* large and small are based on the iOS sizes.
|
||||
* min font size: 12px, default font size: 16px, max font size: 40px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 13px
|
||||
* (derived from rem) and the default font size of the icon is
|
||||
* 16px, then the base size would need to be increased.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(0.66, 19.7px, 2.05, 1em);
|
||||
}
|
||||
|
||||
:host(.button-large.button-has-icon-only) {
|
||||
@@ -164,7 +192,21 @@
|
||||
}
|
||||
|
||||
:host(.button-large) ::slotted(ion-icon[slot="icon-only"]) {
|
||||
font-size: 1.4em;
|
||||
/**
|
||||
* The values were provided through MD design,
|
||||
* large and small are based on the iOS sizes.
|
||||
* min font size: 15px, default font size: 28px, max font size: 43px
|
||||
*
|
||||
* Since the `ion-button` uses `rem` for the font size, we can't
|
||||
* just pass the desired icon font size in `em` to the `
|
||||
* dynamic-font-clamp`. Instead, we need to adjust the base size
|
||||
* to account for the ion-button` font size.
|
||||
*
|
||||
* For example, if the default font size of `ion-button` is 20px
|
||||
* (derived from rem) and the default font size of the icon is
|
||||
* 28px, then the base size would need to be increased.
|
||||
*/
|
||||
font-size: dynamic-font-clamp(0.67, 22.4px, 1.92, 1em);
|
||||
}
|
||||
|
||||
// Material Design Button: Hover
|
||||
@@ -196,3 +238,12 @@
|
||||
background: #{current-color(base)};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Activated Button in Toolbar
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
|
||||
background: var(--ion-toolbar-background, var(--color));
|
||||
color: #{var(--ion-toolbar-color, var(--background), ion-color(primary, contrast))};
|
||||
}
|
||||
|
||||
@@ -325,11 +325,3 @@ ion-ripple-effect {
|
||||
background: #{var(--ion-toolbar-color, var(--background))};
|
||||
color: #{var(--ion-toolbar-background, var(--color))};
|
||||
}
|
||||
|
||||
// Activated Button in Toolbar
|
||||
// --------------------------------------------------
|
||||
|
||||
:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native {
|
||||
background: var(--ion-toolbar-color, var(--color));
|
||||
color: #{var(--ion-toolbar-background, var(--background), ion-color(primary, contrast))};
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
28
core/src/components/card/card.ionic.scss
Executable file
@@ -0,0 +1,28 @@
|
||||
@use "../../foundations/ionic.vars.scss" as tokens;
|
||||
@use "../../themes/ionic.mixins" as mixins;
|
||||
|
||||
// Ionic Card
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
--background: #{tokens.$ionic-color-neutral-0};
|
||||
--border-radius: #{tokens.$ionic-border-radius-rounded-small};
|
||||
|
||||
@include mixins.padding(tokens.$ionic-space-base);
|
||||
@include mixins.border-radius(var(--border-radius));
|
||||
|
||||
display: block;
|
||||
|
||||
border: #{tokens.$ionic-border-size-small} solid #{tokens.$ionic-color-neutral-50};
|
||||
|
||||
background: var(--background);
|
||||
color: var(--color);
|
||||
}
|
||||
|
||||
:host(.card-round) {
|
||||
--border-radius: #{tokens.$ionic-border-radius-rounded-large};
|
||||
}
|
||||
|
||||
:host(.card-rectangular) {
|
||||
--border-radius: #{tokens.$ionic-border-radius-square};
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import type { RouterDirection } from '../router/utils/interface';
|
||||
styleUrls: {
|
||||
ios: 'card.ios.scss',
|
||||
md: 'card.md.scss',
|
||||
ionic: 'card.md.scss',
|
||||
ionic: 'card.ionic.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -82,6 +82,11 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
*/
|
||||
@Prop() routerAnimation: AnimationBuilder | undefined;
|
||||
|
||||
/**
|
||||
* Set to `"round"` for a card with more rounded corners, or `"rectangular"` for a card without rounded corners.
|
||||
*/
|
||||
@Prop({ reflect: true }) shape?: 'round' | 'rectangular';
|
||||
|
||||
/**
|
||||
* Specifies where to display the linked URL.
|
||||
* Only applies when an `href` is provided.
|
||||
@@ -131,12 +136,16 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
}
|
||||
|
||||
render() {
|
||||
const { shape } = this;
|
||||
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[theme]: true,
|
||||
// TODO(FW-6119): remove theme === 'ionic' when support for other themes is added
|
||||
[`card-${shape}`]: theme === 'ionic' && shape !== undefined,
|
||||
'card-disabled': this.disabled,
|
||||
'ion-activatable': this.isClickable(),
|
||||
})}
|
||||
|
||||
40
core/src/components/card/test/shape/card.e2e.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
/**
|
||||
* Shape is only available in the Ionic theme.
|
||||
* TODO(FW-6119): add the `ios` and `md` modes when shape support is added.
|
||||
*/
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
test.describe(title('card: shape'), () => {
|
||||
test.describe('default', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/card/test/shape`, config);
|
||||
|
||||
const container = page.locator('#default');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`card-default`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('round', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/card/test/shape`, config);
|
||||
|
||||
const container = page.locator('#round');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`card-round`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('rectangular', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.goto(`/src/components/card/test/shape`, config);
|
||||
|
||||
const container = page.locator('#rectangular');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`card-rectangular`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 12 KiB |
85
core/src/components/card/test/shape/index.html
Normal file
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Card - Shape</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
|
||||
<!-- Styles only for testing purposes to identify the card shape -->
|
||||
<style>
|
||||
:root {
|
||||
--ion-background-color: #dde2ef;
|
||||
}
|
||||
|
||||
#default,
|
||||
#round,
|
||||
#rectangular {
|
||||
padding: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Card - Shape</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding ion-text-center" id="content" no-bounce>
|
||||
<h1>Default</h1>
|
||||
<div id="default" class="ion-margin-top">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
|
||||
in the woods. Wash your spirit clean.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
<h1>Round</h1>
|
||||
<div id="round" class="ion-margin-top">
|
||||
<ion-card shape="round">
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
|
||||
in the woods. Wash your spirit clean.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
|
||||
<h1>Rectangular</h1>
|
||||
<div id="rectangular" class="ion-margin-top">
|
||||
<ion-card shape="rectangular">
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
|
||||
in the woods. Wash your spirit clean.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
</body>
|
||||
</html>
|
||||
78
core/src/components/card/test/theme-ionic/index.html
Normal file
@@ -0,0 +1,78 @@
|
||||
<!-- TODO: FW-6077 This file can be removed once the additional test cases are added -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Card - Theme Ionic</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
|
||||
<style>
|
||||
.ion-margin-top {
|
||||
margin-top: 32px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Card - Ionic</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding ion-text-center" id="content" no-bounce>
|
||||
<h4>Preview options</h4>
|
||||
|
||||
<p>
|
||||
<ion-select id="select-shape" justify="space-between" interface="alert" label="Shape" placeholder="">
|
||||
<ion-select-option value="">default</ion-select-option>
|
||||
<ion-select-option value="round">Round</ion-select-option>
|
||||
<ion-select-option value="rectangular">Rectangular</ion-select-option>
|
||||
</ion-select>
|
||||
</p>
|
||||
|
||||
<div id="screenshot-wrapper" class="ion-margin-top">
|
||||
<ion-card>
|
||||
<ion-card-header>
|
||||
<ion-card-subtitle>Card Subtitle</ion-card-subtitle>
|
||||
<ion-card-title>Card Title</ion-card-title>
|
||||
</ion-card-header>
|
||||
|
||||
<ion-card-content>
|
||||
Keep close to Nature's heart... and break clear away, once in awhile, and climb a mountain or spend a week
|
||||
in the woods. Wash your spirit clean.
|
||||
</ion-card-content>
|
||||
</ion-card>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<script>
|
||||
const listOfCards = Array.from(document.querySelectorAll('ion-card'));
|
||||
|
||||
function updateAttr(el, name, value) {
|
||||
if (value === '' || value === undefined) {
|
||||
el.removeAttribute(name);
|
||||
} else {
|
||||
el.setAttribute(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
const selectShape = document.getElementById('select-shape');
|
||||
selectShape.addEventListener('ionChange', (e) => {
|
||||
for (const el of listOfCards) {
|
||||
updateAttr(el, 'shape', e.detail.value);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
@use "../../themes/ionic.mixins" as mixins;
|
||||
@use "../../foundations/ionic.vars.scss" as tokens;
|
||||
|
||||
// Chip
|
||||
// Ionic Chip
|
||||
// --------------------------------------------------
|
||||
|
||||
// TODO(ROU-4870): there is no token yet for these ones, but it should be created in the future, once UX team has figma tokens done
|
||||
@@ -11,19 +11,21 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
|
||||
:host {
|
||||
--background: #{tokens.$ionic-color-neutral-10};
|
||||
--border-color: transparent;
|
||||
--border-radius: #{tokens.$ionic-border-radius-rounded-small};
|
||||
--color: #{tokens.$ionic-color-neutral-900};
|
||||
--focus-ring-color: #{$ionic-states-focus-primary};
|
||||
--focus-ring-width: #{tokens.$ionic-border-size-medium};
|
||||
|
||||
@include mixins.font-smoothing;
|
||||
@include mixins.padding(tokens.$ionic-space-xs, tokens.$ionic-space-xxs);
|
||||
@include mixins.border-radius(tokens.$ionic-border-radius-rounded-large);
|
||||
@include mixins.border-radius(var(--border-radius));
|
||||
|
||||
display: inline-flex;
|
||||
|
||||
position: relative;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
gap: tokens.$ionic-space-xxxs;
|
||||
|
||||
@@ -39,6 +41,9 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
|
||||
|
||||
font-family: tokens.$ionic-font-family;
|
||||
font-size: tokens.$ionic-font-size-m;
|
||||
font-weight: tokens.$ionic-font-weight-medium;
|
||||
|
||||
line-height: tokens.$ionic-font-line-height-full;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
@@ -82,6 +87,17 @@ $ionic-states-hover: #{rgba(#05080f, 0.16)}; // We should review how to make thi
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Chip Shapes
|
||||
// ---------------------------------------------
|
||||
|
||||
:host(.chip-round) {
|
||||
--border-radius: #{tokens.$ionic-border-radius-rounded-large};
|
||||
}
|
||||
|
||||
:host(.chip-rectangular) {
|
||||
--border-radius: #{tokens.$ionic-border-radius-square};
|
||||
}
|
||||
|
||||
// Chip Icon
|
||||
// ---------------------------------------------
|
||||
::slotted(ion-icon) {
|
||||
|
||||
@@ -36,7 +36,13 @@ export class Chip implements ComponentInterface {
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
/**
|
||||
* Define the Chip corner shape, when using the Ionic Theme.
|
||||
*/
|
||||
@Prop() shape?: 'round' | 'rectangular';
|
||||
|
||||
render() {
|
||||
const { shape } = this;
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
@@ -44,10 +50,12 @@ export class Chip implements ComponentInterface {
|
||||
aria-disabled={this.disabled ? 'true' : null}
|
||||
class={createColorClasses(this.color, {
|
||||
[theme]: true,
|
||||
// TODO(FW-6120): remove the theme==='ionic' when we add support for the `ios` and `md` modes.
|
||||
[`chip-${shape}`]: theme === 'ionic' && shape !== undefined,
|
||||
'chip-outline': this.outline,
|
||||
'chip-disabled': this.disabled,
|
||||
'ion-activatable': true,
|
||||
'ion-focusable': true,
|
||||
'ion-focusable': !this.disabled,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
38
core/src/components/chip/test/shape/chip.e2e.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
/**
|
||||
* This behavior only applies to Ionic Theme.
|
||||
* TODO(FW-6120): add the `ios` and `md` modes when shape support is added.
|
||||
*/
|
||||
test.describe(title('chip: shape'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto(`/src/components/chip/test/shape`, config);
|
||||
});
|
||||
|
||||
test.describe('default', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
const container = page.locator('#default');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`chip-default`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('round', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
const container = page.locator('#round');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`chip-round`));
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('rectangular', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
const container = page.locator('#rectangular');
|
||||
|
||||
await expect(container).toHaveScreenshot(screenshot(`chip-rectangular`));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
56
core/src/components/chip/test/shape/index.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" dir="ltr">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Chip - Shape</title>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
||||
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-content>
|
||||
<h2>Chip - Shape</h2>
|
||||
|
||||
<h3>Shapes</h3>
|
||||
<p>
|
||||
<ion-chip id="default">
|
||||
<ion-label>Default</ion-label>
|
||||
</ion-chip>
|
||||
<ion-chip id="round" shape="round">
|
||||
<ion-label>Round</ion-label>
|
||||
</ion-chip>
|
||||
<ion-chip id="rectangular" shape="rectangular">
|
||||
<ion-label>Rectangular</ion-label>
|
||||
</ion-chip>
|
||||
</p>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
|
||||
<style>
|
||||
ion-content {
|
||||
--background: #222;
|
||||
}
|
||||
h2,
|
||||
h3 {
|
||||
color: #fff;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
ion-chip + ion-chip {
|
||||
margin-inline-start: 16px;
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
@@ -41,3 +41,25 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => {
|
||||
/**
|
||||
* This behavior only applies to Ionic Theme.
|
||||
*/
|
||||
test.describe(title('chip: focus state'), () => {
|
||||
test('should render focus state', async ({ page }) => {
|
||||
await page.setContent(
|
||||
`<div id="container" class="ion-padding">
|
||||
<ion-chip class="ion-focused">
|
||||
<ion-label>Focused</ion-label>
|
||||
</ion-chip>
|
||||
</div>`,
|
||||
config
|
||||
);
|
||||
|
||||
const chip = page.locator('#container');
|
||||
|
||||
await expect(chip).toHaveScreenshot(screenshot(`chip-focused`));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
@@ -51,6 +51,19 @@
|
||||
</ion-chip>
|
||||
</p>
|
||||
|
||||
<h3>Shapes</h3>
|
||||
<p>
|
||||
<ion-chip shape="soft">
|
||||
<ion-label>Soft</ion-label>
|
||||
</ion-chip>
|
||||
<ion-chip shape="round">
|
||||
<ion-label>Round</ion-label>
|
||||
</ion-chip>
|
||||
<ion-chip shape="rectangular">
|
||||
<ion-label>Rectangular</ion-label>
|
||||
</ion-chip>
|
||||
</p>
|
||||
|
||||
<h3>With Icon</h3>
|
||||
<p>
|
||||
<ion-chip>
|
||||
|
||||
@@ -78,6 +78,15 @@ export class Content implements ComponentInterface {
|
||||
*/
|
||||
@Prop() fullscreen = false;
|
||||
|
||||
/**
|
||||
* Controls where the fixed content is placed relative to the main content
|
||||
* in the DOM. This can be used to control the order in which fixed elements
|
||||
* receive keyboard focus.
|
||||
* For example, if a FAB in the fixed slot should receive keyboard focus before
|
||||
* the main page content, set this property to `'before'`.
|
||||
*/
|
||||
@Prop() fixedSlotPlacement: 'after' | 'before' = 'after';
|
||||
|
||||
/**
|
||||
* If `true` and the content does not cause an overflow scroll, the scroll interaction will cause a bounce.
|
||||
* If the content exceeds the bounds of ionContent, nothing will change.
|
||||
@@ -425,7 +434,7 @@ export class Content implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isMainContent, scrollX, scrollY, el } = this;
|
||||
const { fixedSlotPlacement, isMainContent, scrollX, scrollY, el } = this;
|
||||
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
||||
const theme = getIonTheme(this);
|
||||
const mode = getIonMode(this, theme);
|
||||
@@ -449,6 +458,9 @@ export class Content implements ComponentInterface {
|
||||
}}
|
||||
>
|
||||
<div ref={(el) => (this.backgroundContentEl = el)} id="background-content" part="background"></div>
|
||||
|
||||
{fixedSlotPlacement === 'before' ? <slot name="fixed"></slot> : null}
|
||||
|
||||
<div
|
||||
class={{
|
||||
'inner-scroll': true,
|
||||
@@ -470,7 +482,7 @@ export class Content implements ComponentInterface {
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<slot name="fixed"></slot>
|
||||
{fixedSlotPlacement === 'after' ? <slot name="fixed"></slot> : null}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
31
core/src/components/content/test/content.spec.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
|
||||
import { Content } from '../content';
|
||||
|
||||
describe('content: fixed slot placement', () => {
|
||||
it('should should fixed slot after content', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Content],
|
||||
html: '<ion-content></ion-content>',
|
||||
});
|
||||
|
||||
const content = page.body.querySelector('ion-content')!;
|
||||
const fixedSlot = content.shadowRoot!.querySelector('slot[name="fixed"]')!;
|
||||
const scrollEl = content.shadowRoot!.querySelector('[part="scroll"]')!;
|
||||
|
||||
expect(fixedSlot.nextElementSibling).not.toBe(scrollEl);
|
||||
});
|
||||
|
||||
it('should should fixed slot before content', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Content],
|
||||
html: `<ion-content fixed-slot-placement="before"></ion-content>`,
|
||||
});
|
||||
|
||||
const content = page.body.querySelector('ion-content')!;
|
||||
const fixedSlot = content.shadowRoot!.querySelector('slot[name="fixed"]')!;
|
||||
const scrollEl = content.shadowRoot!.querySelector('[part="scroll"]')!;
|
||||
|
||||
expect(fixedSlot.nextElementSibling).toBe(scrollEl);
|
||||
});
|
||||
});
|
||||
@@ -543,7 +543,7 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
|
||||
if (closeOverlay) {
|
||||
this.closeParentOverlay();
|
||||
this.closeParentOverlay(CONFIRM_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ export class Datetime implements ComponentInterface {
|
||||
this.ionCancel.emit();
|
||||
|
||||
if (closeOverlay) {
|
||||
this.closeParentOverlay();
|
||||
this.closeParentOverlay(CANCEL_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,13 +618,13 @@ export class Datetime implements ComponentInterface {
|
||||
return Array.isArray(activeParts) ? activeParts[0] : activeParts;
|
||||
};
|
||||
|
||||
private closeParentOverlay = () => {
|
||||
private closeParentOverlay = (role: string) => {
|
||||
const popoverOrModal = this.el.closest('ion-modal, ion-popover') as
|
||||
| HTMLIonModalElement
|
||||
| HTMLIonPopoverElement
|
||||
| null;
|
||||
if (popoverOrModal) {
|
||||
popoverOrModal.dismiss();
|
||||
popoverOrModal.dismiss(undefined, role);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2647,5 +2647,7 @@ export class Datetime implements ComponentInterface {
|
||||
}
|
||||
|
||||
let datetimeIds = 0;
|
||||
const CANCEL_ROLE = 'datetime-cancel';
|
||||
const CONFIRM_ROLE = 'datetime-confirm';
|
||||
const WHEEL_ITEM_PART = 'wheel-item';
|
||||
const WHEEL_ITEM_ACTIVE_PART = `active`;
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { configs, test } from '@utils/test/playwright';
|
||||
|
||||
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ config, title }) => {
|
||||
test.describe(title('datetime: overlay roles'), () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.setContent(
|
||||
`
|
||||
<ion-modal>
|
||||
<ion-datetime></ion-datetime>
|
||||
</ion-modal>
|
||||
`,
|
||||
config
|
||||
);
|
||||
});
|
||||
test('should pass role to overlay when calling confirm method', async ({ page }) => {
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const modal = page.locator('ion-modal');
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.present());
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.confirm(true));
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-confirm' });
|
||||
});
|
||||
test('should pass role to overlay when calling cancel method', async ({ page }) => {
|
||||
const ionModalDidDismiss = await page.spyOnEvent('ionModalDidDismiss');
|
||||
const modal = page.locator('ion-modal');
|
||||
const datetime = page.locator('ion-datetime');
|
||||
|
||||
await modal.evaluate((el: HTMLIonModalElement) => el.present());
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.cancel(true));
|
||||
|
||||
await ionModalDidDismiss.next();
|
||||
expect(ionModalDidDismiss).toHaveReceivedEventDetail({ data: undefined, role: 'datetime-cancel' });
|
||||
});
|
||||
});
|
||||
});
|
||||
66
core/src/components/datetime/test/overlay-roles/index.html
Normal file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Datetime - Overlay Roles</title>
|
||||
<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="../../../../../scripts/testing/styles.css" rel="stylesheet" />
|
||||
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||
<style>
|
||||
ion-modal.ios,
|
||||
ion-popover.datetime-popover.ios {
|
||||
--width: 350px;
|
||||
--height: 420px;
|
||||
}
|
||||
|
||||
ion-modal.md,
|
||||
ion-popover.datetime-popover.md {
|
||||
--width: 350px;
|
||||
--height: 450px;
|
||||
}
|
||||
|
||||
ion-datetime {
|
||||
width: 350px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ion-app>
|
||||
<ion-header translucent="true">
|
||||
<ion-toolbar>
|
||||
<ion-title>Datetime - Overlay Roles</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button onclick="presentModal()">Present Modal</ion-button>
|
||||
</ion-content>
|
||||
</ion-app>
|
||||
<script>
|
||||
const presentModal = async () => {
|
||||
const modal = await createModal();
|
||||
|
||||
await modal.present();
|
||||
console.log(await modal.onDidDismiss());
|
||||
};
|
||||
|
||||
const createModal = () => {
|
||||
// create component to open
|
||||
const element = document.createElement('div');
|
||||
element.innerHTML = `
|
||||
<ion-datetime show-default-buttons="true"></ion-datetime>
|
||||
`;
|
||||
|
||||
// present the modal
|
||||
const modalElement = Object.assign(document.createElement('ion-modal'), {
|
||||
component: element,
|
||||
});
|
||||
|
||||
const app = document.querySelector('ion-app');
|
||||
app.appendChild(modalElement);
|
||||
return modalElement;
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -94,6 +94,11 @@ export class Input implements ComponentInterface {
|
||||
*/
|
||||
@Prop() clearInput = false;
|
||||
|
||||
/**
|
||||
* The icon to use for the clear button. Only applies when `clearInput` is set to `true`.
|
||||
*/
|
||||
@Prop() clearInputIcon?: string;
|
||||
|
||||
/**
|
||||
* If `true`, the value will be cleared after focus upon edit. Defaults to `true` when `type` is `"password"`, `false` for all other types.
|
||||
*/
|
||||
@@ -683,12 +688,15 @@ export class Input implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus } = this;
|
||||
const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus, clearInputIcon } = this;
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
|
||||
const defaultClearIcon = theme === 'ios' ? closeCircle : closeSharp;
|
||||
const clearIconData = clearInputIcon ?? defaultClearIcon;
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||
|
||||
@@ -786,7 +794,7 @@ export class Input implements ComponentInterface {
|
||||
}}
|
||||
onClick={this.clearTextInput}
|
||||
>
|
||||
<ion-icon aria-hidden="true" icon={theme === 'ios' ? closeCircle : closeSharp}></ion-icon>
|
||||
<ion-icon aria-hidden="true" icon={clearIconData}></ion-icon>
|
||||
</button>
|
||||
)}
|
||||
<slot name="end"></slot>
|
||||
|
||||
@@ -99,3 +99,19 @@ describe('input: label rendering', () => {
|
||||
expect(labelText.textContent).toBe('Label Prop Text');
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/ionic-team/ionic-framework/issues/26974
|
||||
describe('input: clear icon', () => {
|
||||
it('should render custom icon', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [Input],
|
||||
html: `
|
||||
<ion-input clear-input-icon="foo" clear-input="true"></ion-input>
|
||||
`,
|
||||
});
|
||||
|
||||
const icon = page.body.querySelector<HTMLIonIconElement>('ion-input ion-icon')!;
|
||||
|
||||
expect(icon.getAttribute('icon')).toBe('foo');
|
||||
});
|
||||
});
|
||||
|
||||
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 84 KiB |
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |