diff --git a/demo/src/app/docs/docs-content.generated.ts b/demo/src/app/docs/docs-content.generated.ts
index e332be5c..c314d784 100644
--- a/demo/src/app/docs/docs-content.generated.ts
+++ b/demo/src/app/docs/docs-content.generated.ts
@@ -1,3 +1,3 @@
// Generated from docs/special-markup.md. Do not edit directly.
export const docsContentHtml =
- '
Special markup and classes \nMost Ionic markup works without changes. The combinations below are explicit opt-ins provided by the theme.
\nPrimary submit buttons \nSolid primary submit buttons use --ion-color-primary-brightness for their foreground and border treatment. Define a value with sufficient contrast for your primary color.
\n:root { \n --ion-color-primary-brightness : #96feff ; \n} \n\n< ion-button type = "submit" color = "primary" >Submit</ ion-button > \n< ion-button class = "button-submit" fill = "solid" color = "primary" >Continue</ ion-button > \n\n\nPreview \nSubmit \nContinue \n \n\nUse .button-submit when the button needs the same treatment but cannot use type="submit".
\nTwo-line inset list items \nPlace an unslotted ion-label immediately alongside an unslotted ion-note to render a two-line item. When using the iOS-style inset-list background, wrap the items in ion-item-group; keep ion-list-header outside the group.
\n< ion-list inset = "true" > \n < ion-list-header > \n < ion-label >Connections</ ion-label > \n </ ion-list-header > \n < ion-item-group > \n < ion-item > \n < ion-label >Network & internet</ ion-label > \n < ion-note >Mobile, Wi-Fi, hotspot</ ion-note > \n </ ion-item > \n </ ion-item-group > \n</ ion-list > \n\n\nPreview \n\n \n Connections \n \n \n \n Network & internet \n Mobile, Wi-Fi, hotspot \n \n \n \n \n\nUse slot="end" on ion-note when you want the standard trailing-note layout instead.
\nInset-list section headers \nAdd .item-group-header to an ion-item-group to create the centered icon, title, and description used at the top of the component demo pages.
\nThis is an introductory group. Place regular list items in a separate ion-item-group that follows it.
\n< ion-list inset = "true" > \n < ion-item-group class = "item-group-header" > \n < ion-item > \n < ion-label > \n < ion-icon name = "list" style = "background: var(--ion-color-primary)" ></ ion-icon > \n < h2 >Lists</ h2 > \n < ion-text >Inset-list examples</ ion-text > \n </ ion-label > \n </ ion-item > \n </ ion-item-group > \n < ion-item-group > \n < ion-item >< ion-label >First item</ ion-label ></ ion-item > \n </ ion-item-group > \n</ ion-list > \n\n\nPreview \n\n \n \n First item \n \n \n \n\nFull-width segments \nAdd .segment-expand when segment buttons should divide the available width evenly. The class also changes the Liquid Glass effect sizing when registerSegmentEffect is used.
\n< ion-segment class = "segment-expand" value = "new" > \n < ion-segment-button value = "new" >< ion-label >New</ ion-label ></ ion-segment-button > \n < ion-segment-button value = "replied" >< ion-label >Replied</ ion-label ></ ion-segment-button > \n</ ion-segment > \n\n\nPreview \n\n New \n Replied \n \n \n\nClassic search bar in a condense header \nThe theme gives iOS search bars the iOS 26 appearance by default. Add .searchbar-classic to the search field shown beneath a large title in an ion-header with collapse="condense". It uses the conventional filled iOS appearance and collapses with the large title instead of remaining in the fixed header.
\nPlace it in a toolbar with a color, such as color="light"; the classic background is derived from that color's contrast value.
\nThe example uses Ionic's standard collapsible large-title structure. Scroll the preview to collapse the large title and reveal the fixed header.
\n< div class = "ion-page" > \n < ion-header translucent = "true" > \n < ion-toolbar color = "light" > \n < ion-title >Search</ ion-title > \n </ ion-toolbar > \n </ ion-header > \n < ion-content color = "light" fullscreen = "true" > \n < ion-header collapse = "condense" > \n < ion-toolbar color = "light" > \n < ion-title size = "large" >Search</ ion-title > \n </ ion-toolbar > \n < ion-toolbar color = "light" > \n < ion-searchbar class = "searchbar-classic" placeholder = "Filter results" ></ ion-searchbar > \n </ ion-toolbar > \n </ ion-header > \n < ion-list inset = "true" > \n < ion-item-group > \n < ion-item >< ion-label >Recent item 1</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 2</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 3</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 4</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 5</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 6</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 7</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 8</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 9</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 10</ ion-label ></ ion-item > \n </ ion-item-group > \n </ ion-list > \n </ ion-content > \n</ div > \n\n\nPreview \n\n \n \n Search \n \n \n \n \n \n Search \n \n \n \n \n \n \n \n Recent item 1 \n Recent item 2 \n Recent item 3 \n Recent item 4 \n Recent item 5 \n Recent item 6 \n Recent item 7 \n Recent item 8 \n Recent item 9 \n Recent item 10 \n \n \n \n
\n \n\nThe .ion-page wrapper makes this embedded preview behave like a complete routed page. An application using ion-router-outlet normally receives that page container automatically. The inset list and its items only provide enough content to demonstrate scrolling; they are not required by .searchbar-classic.
\nSearch-bar toolbars \nAdd .toolbar-searchbar when an ion-toolbar combines a search bar with start or end buttons. The class centers the slotted controls and adjusts the spacing around the search field.
\n< ion-toolbar class = "toolbar-searchbar" > \n < ion-buttons slot = "start" > \n < ion-button >Cancel</ ion-button > \n </ ion-buttons > \n < ion-searchbar ></ ion-searchbar > \n</ ion-toolbar > \n\n\nPreview \n\n \n Cancel \n \n \n \n \n\nOpting out \nAdd .ios26-disabled to an individual Ionic component when it must retain Ionic's standard iOS styling.
\n< ion-button >iOS 26 theme</ ion-button > < ion-button class = "ios26-disabled" >Standard Ionic button</ ion-button > \n\n\nPreview \niOS 26 theme Standard Ionic button \n \n\nFor the background model behind inset lists, see Using ion-item-group .
\n';
+ 'Special markup and classes \nMost Ionic markup works without changes. The combinations below are explicit opt-ins provided by the theme.
\nPrimary submit buttons \nSolid primary submit buttons use --ion-color-primary-brightness for their foreground and border treatment. Define a value with sufficient contrast for your primary color.
\n:root { \n --ion-color-primary-brightness : #96feff ; \n} \n\n< ion-button type = "submit" color = "primary" >Submit</ ion-button > \n< ion-button class = "button-submit" fill = "solid" color = "primary" >Continue</ ion-button > \n\n\nPreview \nSubmit \nContinue \n \n\nUse .button-submit when the button needs the same treatment but cannot use type="submit".
\nTwo-line inset list items \nPlace an unslotted ion-label immediately alongside an unslotted ion-note to render a two-line item. When using the iOS-style inset-list background, wrap the items in ion-item-group; keep ion-list-header outside the group.
\n< ion-list inset = "true" > \n < ion-list-header > \n < ion-label >Connections</ ion-label > \n </ ion-list-header > \n < ion-item-group > \n < ion-item > \n < ion-label >Network & internet</ ion-label > \n < ion-note >Mobile, Wi-Fi, hotspot</ ion-note > \n </ ion-item > \n </ ion-item-group > \n</ ion-list > \n\n\nPreview \n\n \n Connections \n \n \n \n Network & internet \n Mobile, Wi-Fi, hotspot \n \n \n \n \n\nUse slot="end" on ion-note when you want the standard trailing-note layout instead.
\nInset-list section headers \nAdd .item-group-header to an ion-item-group to create the centered icon, title, and description used at the top of the component demo pages.
\nThis is an introductory group. Place regular list items in a separate ion-item-group that follows it.
\n< ion-list inset = "true" > \n < ion-item-group class = "item-group-header" > \n < ion-item > \n < ion-label > \n < ion-icon name = "list" style = "background: var(--ion-color-primary)" ></ ion-icon > \n < h2 >Lists</ h2 > \n < ion-text >Inset-list examples</ ion-text > \n </ ion-label > \n </ ion-item > \n </ ion-item-group > \n < ion-item-group > \n < ion-item >< ion-label >First item</ ion-label ></ ion-item > \n </ ion-item-group > \n</ ion-list > \n\n\nPreview \n\n \n \n First item \n \n \n \n\nFull-width segments \nAdd .segment-expand when segment buttons should divide the available width evenly. The class also changes the Liquid Glass effect sizing when registerSegmentEffect is used.
\n< ion-segment class = "segment-expand" value = "new" > \n < ion-segment-button value = "new" >< ion-label >New</ ion-label ></ ion-segment-button > \n < ion-segment-button value = "replied" >< ion-label >Replied</ ion-label ></ ion-segment-button > \n</ ion-segment > \n\n\nPreview \n\n New \n Replied \n \n \n\nClassic search bar in a condense header \nThe theme gives iOS search bars the iOS 26 appearance by default. Add .searchbar-classic to the search field shown beneath a large title in an ion-header with collapse="condense". It uses the conventional filled iOS appearance and collapses with the large title instead of remaining in the fixed header.
\nPlace it in a toolbar with a color, such as color="light"; the classic background is derived from that color's contrast value.
\nThe example uses Ionic's standard collapsible large-title structure. Scroll the preview to collapse the large title and reveal the fixed header.
\n< div class = "ion-page" > \n < ion-header translucent = "true" > \n < ion-toolbar color = "light" > \n < ion-title >Search</ ion-title > \n </ ion-toolbar > \n </ ion-header > \n < ion-content color = "light" fullscreen = "true" > \n < ion-header collapse = "condense" > \n < ion-toolbar color = "light" > \n < ion-title size = "large" >Search</ ion-title > \n </ ion-toolbar > \n < ion-toolbar color = "light" > \n < ion-searchbar class = "searchbar-classic" placeholder = "Filter results" ></ ion-searchbar > \n </ ion-toolbar > \n </ ion-header > \n < ion-list inset = "true" > \n < ion-item-group > \n < ion-item >< ion-label >Recent item 1</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 2</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 3</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 4</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 5</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 6</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 7</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 8</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 9</ ion-label ></ ion-item > \n < ion-item >< ion-label >Recent item 10</ ion-label ></ ion-item > \n </ ion-item-group > \n </ ion-list > \n </ ion-content > \n</ div > \n\n\nPreview \n\n \n \n Search \n \n \n \n \n \n Search \n \n \n \n \n \n \n \n Recent item 1 \n Recent item 2 \n Recent item 3 \n Recent item 4 \n Recent item 5 \n Recent item 6 \n Recent item 7 \n Recent item 8 \n Recent item 9 \n Recent item 10 \n \n \n \n
\n \n\nThe .ion-page wrapper makes this embedded preview behave like a complete routed page. An application using ion-router-outlet normally receives that page container automatically. The inset list and its items only provide enough content to demonstrate scrolling; they are not required by .searchbar-classic.
\nSearch-bar toolbars \nAdd .toolbar-searchbar when an ion-toolbar combines a search bar with start or end buttons. The class centers the slotted controls and adjusts the spacing around the search field.
\n< ion-toolbar class = "toolbar-searchbar" > \n < ion-buttons slot = "start" > \n < ion-button >Cancel</ ion-button > \n </ ion-buttons > \n < ion-searchbar ></ ion-searchbar > \n</ ion-toolbar > \n\n\nPreview \n\n \n Cancel \n \n \n \n \n\nOpting out \nAdd .ios-theme-disabled to an individual Ionic component when it must retain Ionic's standard iOS styling.
\n< ion-button >iOS 26 theme</ ion-button > < ion-button class = "ios-theme-disabled" >Standard Ionic button</ ion-button > \n\n\nPreview \niOS 26 theme Standard Ionic button \n \n\nFor the background model behind inset lists, see Using ion-item-group .
\nios26-disabled remains supported as a deprecated alias for ios-theme-disabled.
\n';
diff --git a/docs/migration.md b/docs/migration.md
index e0e32f2b..f4ad0424 100644
--- a/docs/migration.md
+++ b/docs/migration.md
@@ -8,6 +8,32 @@ Review every section newer than the version currently installed, in ascending or
Each section lists only the changes that require application code or configuration updates.
+## Migrating to 9.2.0
+
+### Version-independent theme names
+
+The theme opt-out class and CSS variables have been renamed to remove the OS version from their public names. The old names are deprecated; use the new names in new code and migrate existing customizations when convenient.
+
+| Deprecated name | New name |
+| --- | --- |
+| `ios26-disabled` | `ios-theme-disabled` |
+| `--ios26-content-box-shadow-rgb` | `--ios-theme-content-box-shadow-rgb` |
+| `--ios26-*` (other theme variables) | `--ios-theme-*` (same suffix) |
+
+```diff
+- Standard Ionic button
++ Standard Ionic button
+```
+
+```diff
+ion-content {
+- --ios26-content-box-shadow-rgb: 255, 255, 255;
++ --ios-theme-content-box-shadow-rgb: 255, 255, 255;
+}
+```
+
+`ios26-disabled` remains supported as an alias. Old CSS variables remain supported as fallbacks, and the new variable takes precedence when both are set. Existing applications can therefore keep using the deprecated names during migration. Package names and stylesheet paths are unchanged.
+
## Migrating to 9.0.0
Version 9 aligns the theme's major version with Ionic Framework 9. It does not introduce additional breaking changes beyond those documented in the earlier migration sections.
diff --git a/docs/special-markup.md b/docs/special-markup.md
index 3d146c03..c452f0dc 100644
--- a/docs/special-markup.md
+++ b/docs/special-markup.md
@@ -136,10 +136,12 @@ Add `.toolbar-searchbar` when an `ion-toolbar` combines a search bar with start
## Opting out
-Add `.ios26-disabled` to an individual Ionic component when it must retain Ionic's standard iOS styling.
+Add `.ios-theme-disabled` to an individual Ionic component when it must retain Ionic's standard iOS styling.
```html preview
-iOS 26 theme Standard Ionic button
+iOS 26 theme Standard Ionic button
```
For the background model behind inset lists, see [Using `ion-item-group`](./using-ion-item-group.md).
+
+`ios26-disabled` remains supported as a deprecated alias for `ios-theme-disabled`.
diff --git a/package.json b/package.json
index a1aeb7b6..0208e0fa 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"build:demo": "npm run build && cd demo && npm install && npm run build -- --configuration=production",
"lint": "prettier --check \"./**/*.{scss,ts}\" && prettier --parser angular --check \"./**/*.html\"",
"fmt": "prettier --write \"./**/*.{scss,ts}\" && prettier --parser angular --write \"./**/*.html\"",
- "release": "np --no-tests --no-publish",
+ "release": "np --branch ios26 --no-tests --no-publish",
"prepublishOnly": "npm run build"
},
"repository": {
diff --git a/src/popover/animations/ios.enter.ts b/src/popover/animations/ios.enter.ts
index 18721b5e..e1965d36 100644
--- a/src/popover/animations/ios.enter.ts
+++ b/src/popover/animations/ios.enter.ts
@@ -27,7 +27,7 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
if (!['ion-button', 'ion-buttons'].includes(referenceSizeEl.localName)) {
return false;
}
- if (referenceSizeEl.classList.contains('ios26-disabled')) {
+ if (referenceSizeEl.matches('.ios-theme-disabled, .ios26-disabled')) {
return false;
}
return true;
diff --git a/src/styles/components/ion-action-sheet.scss b/src/styles/components/ion-action-sheet.scss
index e0ed4629..b4e8510a 100644
--- a/src/styles/components/ion-action-sheet.scss
+++ b/src/styles/components/ion-action-sheet.scss
@@ -1,12 +1,12 @@
@use '../utils/api';
-ion-action-sheet.ios:not(.ios26-disabled) {
+ion-action-sheet.ios:not(.ios-theme-disabled, .ios26-disabled) {
--backdrop-opacity: 0.2;
--color: var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));
.action-sheet-wrapper {
padding-bottom: 0;
- bottom: var(--ios26-floating-safe-area-bottom);
+ bottom: var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom));
}
.action-sheet-container {
@@ -74,7 +74,7 @@ ion-action-sheet.ios:not(.ios26-disabled) {
* ios26, action-sheet should not has 'cancel'.
* It is recommend to use Popover.
*/
-ion-action-sheet.ios.select-action-sheet:not(.ios26-disabled) {
+ion-action-sheet.ios.select-action-sheet:not(.ios-theme-disabled, .ios26-disabled) {
.action-sheet-container {
.action-sheet-group {
button.action-sheet-cancel {
diff --git a/src/styles/components/ion-alert.scss b/src/styles/components/ion-alert.scss
index 07d23683..1fc4cddc 100644
--- a/src/styles/components/ion-alert.scss
+++ b/src/styles/components/ion-alert.scss
@@ -1,6 +1,6 @@
@use '../utils/api';
-ion-alert.ios:not(.ios26-disabled) {
+ion-alert.ios:not(.ios-theme-disabled, .ios26-disabled) {
--min-width: 280px;
--backdrop-opacity: 0.2;
diff --git a/src/styles/components/ion-button.scss b/src/styles/components/ion-button.scss
index 753e0c9b..e69e07c1 100644
--- a/src/styles/components/ion-button.scss
+++ b/src/styles/components/ion-button.scss
@@ -23,7 +23,7 @@ $scaleup-large-icon-only: 1.22;
/**
* compare .header-collapse-main ion-toolbar.in-toolbar ion-title, .header-collapse-main ion-toolbar.in-toolbar ion-buttons
*/
- transition: transform var(--ios26-activated-transition-duration) ease-out;
+ transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
z-index: 0;
@@ -59,11 +59,11 @@ $scaleup-large-icon-only: 1.22;
}
}
- &:has(ion-button:not(.ios26-disabled).button-clear.button-large) {
+ &:has(ion-button:not(.ios-theme-disabled, .ios26-disabled).button-clear.button-large) {
border-radius: 30px;
}
- ion-button:not(.ios26-disabled).button-clear {
+ ion-button:not(.ios-theme-disabled, .ios26-disabled).button-clear {
--background: transparent;
--border-style: none;
--border-width: 0;
@@ -121,11 +121,11 @@ $scaleup-large-icon-only: 1.22;
}
}
- ion-button:not(.ios26-disabled) {
+ ion-button:not(.ios-theme-disabled, .ios26-disabled) {
margin: 0;
}
- ion-menu-button:not(.ios26-disabled) {
+ ion-menu-button:not(.ios-theme-disabled, .ios26-disabled) {
width: 44px;
height: 44px;
padding: 2px;
@@ -140,7 +140,7 @@ $scaleup-large-icon-only: 1.22;
}
transition:
- transform var(--ios26-activated-transition-duration) ease-out,
+ transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out,
color 50ms ease;
&.in-toolbar:not(.ion-color):not(.in-toolbar-color) {
@@ -153,13 +153,13 @@ $scaleup-large-icon-only: 1.22;
}
// will-change is optimized to only apply when needed for performance
- &:not(.ios26-disabled):hover,
- &:not(.ios26-disabled):active,
- &:not(.ios26-disabled).ion-activated {
+ &:not(.ios-theme-disabled, .ios26-disabled):hover,
+ &:not(.ios-theme-disabled, .ios26-disabled):active,
+ &:not(.ios-theme-disabled, .ios26-disabled).ion-activated {
will-change: transform;
}
- &:not(.ios26-disabled):not(:hover):not(:active):not(.ion-activated) {
+ &:not(.ios-theme-disabled, .ios26-disabled):not(:hover):not(:active):not(.ion-activated) {
will-change: auto;
}
@@ -248,8 +248,8 @@ $scaleup-large-icon-only: 1.22;
}
} @else {
--box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2),
- 0 0 8px -4px rgba(var(--ios26-glass-box-shadow-color-rgb), 0.92);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 8px -4px rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.92);
}
&::part(native)::before {
content: '';
@@ -313,12 +313,13 @@ $scaleup-large-icon-only: 1.22;
// fill:default only
&:not(.button-solid):not(.button-outline):not(.button-clear) {
- --background: rgba(var(--ios26-glass-background-rgb), 0.72);
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
--background-hover: transparent;
--background-activated: transparent;
@if not $is-back-button {
--box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2), 0 0 10px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.82);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
}
&:not(.button-has-icon-only):not(.back-button-has-icon-only) {
@@ -404,18 +405,22 @@ $scaleup-large-icon-only: 1.22;
}
}
-ion-buttons.ios:not(.ios26-disabled):not(:has(ion-back-button, ion-button:not(.button-clear), ion-menu-button.menu-button-hidden)) {
+ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(
+ :has(ion-back-button, ion-button:not(.button-clear), ion-menu-button.menu-button-hidden)
+ ) {
@include theme-buttons;
}
// Ionic's collapsing-header transition has a more specific contextual selector.
.header-collapse-main
:where(ion-toolbar.in-toolbar)
- ion-buttons.ios:not(.ios26-disabled):not(:has(ion-back-button, ion-button:not(.button-clear), ion-menu-button.menu-button-hidden)) {
- transition: transform var(--ios26-activated-transition-duration) ease-out;
+ ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(
+ :has(ion-back-button, ion-button:not(.button-clear), ion-menu-button.menu-button-hidden)
+ ) {
+ transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
}
-ion-buttons.ios:not(.ios26-disabled):not(:has(ion-back-button, ion-button.button-clear)) {
+ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(:has(ion-back-button, ion-button.button-clear)) {
ion-button {
margin: 0 6px;
&:first-child {
@@ -430,9 +435,9 @@ ion-buttons.ios:not(.ios26-disabled):not(:has(ion-back-button, ion-button.button
}
}
-ion-button.ios:not(.ios26-disabled) {
+ion-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include theme-button;
}
-ion-back-button.ios:not(.ios26-disabled) {
+ion-back-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include theme-button($is-back-button: true);
}
diff --git a/src/styles/components/ion-card.scss b/src/styles/components/ion-card.scss
index e6510259..ee549c5c 100644
--- a/src/styles/components/ion-card.scss
+++ b/src/styles/components/ion-card.scss
@@ -1,4 +1,4 @@
-ion-card.ios:not(.ios26-disabled) {
+ion-card.ios:not(.ios-theme-disabled, .ios26-disabled) {
border-radius: 24px;
ion-list ion-item {
diff --git a/src/styles/components/ion-content.scss b/src/styles/components/ion-content.scss
index f5ea5d14..d107dbb4 100644
--- a/src/styles/components/ion-content.scss
+++ b/src/styles/components/ion-content.scss
@@ -3,8 +3,8 @@
* so we adjust the margin and padding of the content.
* Also supports virtual scrolling using .ion-content-scroll-host.
*/
-.ion-page.ios:not(.ios26-disabled):has(ion-header.header-translucent)
- ion-content.ios:not(.ios26-disabled).content-fullscreen:has(.ion-content-scroll-host) {
+.ion-page.ios:not(.ios-theme-disabled, .ios26-disabled):has(ion-header.header-translucent)
+ ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen:has(.ion-content-scroll-host) {
--padding-top: calc(var(--offset-top) * -1);
> *:not(.ion-content-scroll-host, ion-fab) {
transform: translateY(var(--offset-top));
@@ -13,10 +13,12 @@
padding-top: var(--offset-top);
}
}
-.ion-page.ios:not(.ios26-disabled):not(:has(ion-footer)) ion-content.ios:not(.ios26-disabled).content-fullscreen .ion-content-scroll-host {
- margin-bottom: calc(calc(60px + var(--ios26-floating-safe-area-bottom)) * -1);
- padding-bottom: calc(60px + var(--ios26-floating-safe-area-bottom));
+.ion-page.ios:not(.ios-theme-disabled, .ios26-disabled):not(:has(ion-footer))
+ ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen
+ .ion-content-scroll-host {
+ margin-bottom: calc(calc(60px + var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom))) * -1);
+ padding-bottom: calc(60px + var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom)));
}
-ion-content.ios:not(.ios26-disabled).content-fullscreen:not(:has(.ion-content-scroll-host)) {
- --padding-bottom: calc(60px + var(--ios26-floating-safe-area-bottom));
+ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen:not(:has(.ion-content-scroll-host)) {
+ --padding-bottom: calc(60px + var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom)));
}
diff --git a/src/styles/components/ion-datetime.scss b/src/styles/components/ion-datetime.scss
index 069a16a1..2ede64da 100644
--- a/src/styles/components/ion-datetime.scss
+++ b/src/styles/components/ion-datetime.scss
@@ -1,6 +1,6 @@
@use '../utils/api';
-ion-datetime.ios:not(.ios26-disabled) {
+ion-datetime.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include api.glass-background-overlay;
border-radius: 24px;
diff --git a/src/styles/components/ion-fab.scss b/src/styles/components/ion-fab.scss
index b328a7da..43cfc38f 100644
--- a/src/styles/components/ion-fab.scss
+++ b/src/styles/components/ion-fab.scss
@@ -4,19 +4,21 @@ $scaleup-small-icon-only: 1.18;
$scaleup-default-icon-only: 1.2;
$scaleup-large-icon-only: 1.12;
-ion-fab.ios:not(.ios26-disabled) {
+ion-fab.ios:not(.ios-theme-disabled, .ios26-disabled) {
--transform-value: 2.5px;
&:has(> ion-fab-button.fab-button-small) {
--transform-value: 4px;
}
ion-fab-button {
- --background: rgba(var(--ios26-glass-background-rgb), 0.72);
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
--box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2), 0 0 10px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.82);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
--transition:
- var(--ios26-activated-transition-duration) transform cubic-bezier(0.25, 1.11, 0.78, 1.59),
- var(--ios26-activated-transition-duration) color ease;
+ var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) transform
+ cubic-bezier(0.25, 1.11, 0.78, 1.59),
+ var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) color ease;
--background-activated-opacity: 0;
--background-focused-opacity: 0;
--background-hover-opacity: 0;
@@ -78,15 +80,15 @@ ion-fab.ios:not(.ios26-disabled) {
}
&.fab-vertical-top {
- top: var(--ios26-floating-safe-area-top);
+ top: var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top));
}
&.fab-vertical-bottom {
- bottom: var(--ios26-floating-safe-area-bottom);
+ bottom: var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom));
}
&.fab-horizontal-start {
- left: calc(16px + var(--ios26-menu-width, var(--ion-safe-area-left), 0px));
+ left: calc(16px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ion-safe-area-left), 0px)));
}
&.fab-horizontal-end {
@@ -95,7 +97,7 @@ ion-fab.ios:not(.ios26-disabled) {
&:has(.fab-button-small) {
&.fab-horizontal-start {
- left: calc(10px + var(--ios26-menu-width, var(--ion-safe-area-left), 0px));
+ left: calc(10px + var(--ios-theme-menu-width, var(--ios26-menu-width, var(--ion-safe-area-left), 0px)));
}
&.fab-horizontal-end {
diff --git a/src/styles/components/ion-inputs.scss b/src/styles/components/ion-inputs.scss
index 06f8e6cb..a01b75db 100644
--- a/src/styles/components/ion-inputs.scss
+++ b/src/styles/components/ion-inputs.scss
@@ -54,7 +54,7 @@
}
}
-ion-input.ios:not(.ios26-disabled) {
+ion-input.ios:not(.ios-theme-disabled, .ios26-disabled) {
&.input-fill-outline {
@include outline-field('input');
@@ -65,7 +65,7 @@ ion-input.ios:not(.ios26-disabled) {
}
}
-ion-textarea.ios:not(.ios26-disabled) {
+ion-textarea.ios:not(.ios-theme-disabled, .ios26-disabled) {
&.textarea-fill-outline {
@include outline-field('textarea');
diff --git a/src/styles/components/ion-list.scss b/src/styles/components/ion-list.scss
index f71def38..2b457e81 100644
--- a/src/styles/components/ion-list.scss
+++ b/src/styles/components/ion-list.scss
@@ -1,6 +1,6 @@
@use '../utils/structured-list';
-ion-list.ios:not(.ios26-disabled) {
+ion-list.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include structured-list.support-text;
ion-item {
--background-hover-opacity: 0;
@@ -8,7 +8,7 @@ ion-list.ios:not(.ios26-disabled) {
}
}
-ion-list.list-inset.ios:not(.ios26-disabled) {
+ion-list.list-inset.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include structured-list.layout(20px, 24px);
ion-radio-group,
diff --git a/src/styles/components/ion-loading.scss b/src/styles/components/ion-loading.scss
index c7e907a2..f0adbccd 100644
--- a/src/styles/components/ion-loading.scss
+++ b/src/styles/components/ion-loading.scss
@@ -1,6 +1,6 @@
@use '../utils/api';
-ion-loading.ios:not(.ios26-disabled) {
+ion-loading.ios:not(.ios-theme-disabled, .ios26-disabled) {
--backdrop-opacity: 0.2;
.loading-wrapper {
@include api.glass-background;
diff --git a/src/styles/components/ion-menu.scss b/src/styles/components/ion-menu.scss
index 5fe03eec..aa4683b0 100644
--- a/src/styles/components/ion-menu.scss
+++ b/src/styles/components/ion-menu.scss
@@ -1,20 +1,23 @@
@use '../utils/api';
-ion-split-pane.ios:not(.ios26-disabled) {
- --side-max-width: var(--ios26-menu-width);
+ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled) {
+ --side-max-width: var(--ios-theme-menu-width, var(--ios26-menu-width));
}
-ion-split-pane.ios:not(.ios26-disabled).split-pane-visible:has(ion-menu.menu-pane-visible) {
+ion-split-pane.ios:not(.ios-theme-disabled, .ios26-disabled).split-pane-visible:has(ion-menu.menu-pane-visible) {
.split-pane-main {
- ion-tab-bar.ios:not(.ios26-disabled) {
+ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
width: calc(
100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-left, 0px)) - 60px -
- 12px - var(--ios26-menu-width)
+ 12px - var(--ios-theme-menu-width, var(--ios26-menu-width))
);
&:has(:nth-child(5)) {
width: calc(
- 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-left, 0px)) - var(--ios26-menu-width)
+ 100% - calc(18px + var(--ion-safe-area-left, 0px)) - calc(18px + var(--ion-safe-area-left, 0px)) - var(
+ --ios-theme-menu-width,
+ var(--ios26-menu-width)
+ )
);
}
}
@@ -25,62 +28,62 @@ ion-split-pane.ios:not(.ios26-disabled).split-pane-visible:has(ion-menu.menu-pan
/*
* 4px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/toolbar/toolbar.ios.vars.scss#L28-L32
*/
- --padding-start: calc(var(--ios26-menu-width) + 4px);
+ --padding-start: calc(var(--ios-theme-menu-width, var(--ios26-menu-width)) + 4px);
ion-title.title-default {
/*
* 90px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/title/title.ios.scss#L8
*/
- padding-left: calc(90px + var(--ios26-menu-width));
+ padding-left: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
}
}
ion-content {
- --padding-start: var(--ios26-menu-width);
+ --padding-start: var(--ios-theme-menu-width, var(--ios26-menu-width));
ion-header ion-toolbar {
--padding-start: 4px;
}
}
ion-footer ion-toolbar {
- --padding-start: var(--ios26-menu-width);
+ --padding-start: var(--ios-theme-menu-width, var(--ios26-menu-width));
}
- ion-tab-bar.ios:not(.ios26-disabled) {
+ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
&[slot='bottom'] {
- left: calc(16px + var(--ion-safe-area-left, 0px) + var(--ios26-menu-width));
+ left: calc(16px + var(--ion-safe-area-left, 0px) + var(--ios-theme-menu-width, var(--ios26-menu-width)));
}
}
}
}
- &:has(ion-menu.ios:not(.ios26-disabled).menu-side-end) {
+ &:has(ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled).menu-side-end) {
.split-pane-main {
ion-header ion-toolbar {
/*
* 4px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/toolbar/toolbar.ios.vars.scss#L28-L32
*/
- --padding-end: calc(var(--ios26-menu-width) + 4px);
+ --padding-end: calc(var(--ios-theme-menu-width, var(--ios26-menu-width)) + 4px);
ion-title.title-default {
/*
* 90px: https://github.com/ionic-team/ionic-framework/blob/main/core/src/components/title/title.ios.scss#L8
*/
- padding-right: calc(90px + var(--ios26-menu-width));
+ padding-right: calc(90px + var(--ios-theme-menu-width, var(--ios26-menu-width)));
}
}
ion-content {
- --padding-end: var(--ios26-menu-width);
+ --padding-end: var(--ios-theme-menu-width, var(--ios26-menu-width));
ion-header ion-toolbar {
--padding-start: 4px;
}
}
ion-footer ion-toolbar {
- --padding-end: var(--ios26-menu-width);
+ --padding-end: var(--ios-theme-menu-width, var(--ios26-menu-width));
}
}
}
}
-ion-menu.ios:not(.ios26-disabled) {
+ion-menu.ios:not(.ios-theme-disabled, .ios26-disabled) {
--border: none;
--background: transparent;
- --max-width: var(--ios26-menu-width);
+ --max-width: var(--ios-theme-menu-width, var(--ios26-menu-width));
position: absolute;
top: 0;
z-index: 999;
@@ -89,7 +92,7 @@ ion-menu.ios:not(.ios26-disabled) {
left: 0;
}
&.menu-side-end {
- left: calc(100vw - var(--ios26-menu-width));
+ left: calc(100vw - var(--ios-theme-menu-width, var(--ios26-menu-width)));
}
&::part(backdrop) {
@@ -99,10 +102,12 @@ ion-menu.ios:not(.ios26-disabled) {
ion-content {
--background: transparent;
--ios26-content-box-shadow-rgb: transparent;
+ --ios-theme-content-box-shadow-rgb: var(--ios26-content-box-shadow-rgb);
&::part(scroll) {
@include api.glass-background;
- margin: calc(var(--ios26-floating-safe-area-top) + 6px) calc(16px + var(--ion-safe-area-right)) var(--ios26-floating-safe-area-bottom)
+ margin: calc(var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top)) + 6px)
+ calc(16px + var(--ion-safe-area-right)) var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom))
calc(12px + var(--ion-safe-area-left));
border-radius: 24px;
}
diff --git a/src/styles/components/ion-modal.scss b/src/styles/components/ion-modal.scss
index e4519b25..91d0ea58 100644
--- a/src/styles/components/ion-modal.scss
+++ b/src/styles/components/ion-modal.scss
@@ -1,6 +1,6 @@
@use '../utils/api';
-ion-modal.ios:not(.ios26-disabled) {
+ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled) {
--backdrop-opacity: 0.2;
&::part(handle) {
@@ -34,7 +34,7 @@ ion-modal.ios:not(.ios26-disabled) {
&.modal-sheet {
--border-radius: 30px;
- --background: rgba(var(--ios26-glass-background-rgb), 1);
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 1);
&::part(content) {
@include api.glass-background($opacity: 1, $include-background: false);
}
diff --git a/src/styles/components/ion-picker.scss b/src/styles/components/ion-picker.scss
index 70d07925..60b5f614 100644
--- a/src/styles/components/ion-picker.scss
+++ b/src/styles/components/ion-picker.scss
@@ -1,4 +1,4 @@
@use '../utils/api';
-ion-picker.ios:not(.ios26-disabled) {
+ion-picker.ios:not(.ios-theme-disabled, .ios26-disabled) {
}
diff --git a/src/styles/components/ion-popover.scss b/src/styles/components/ion-popover.scss
index 2c36974b..ff287872 100644
--- a/src/styles/components/ion-popover.scss
+++ b/src/styles/components/ion-popover.scss
@@ -1,10 +1,11 @@
@use '../utils/api';
-ion-popover.ios:not(.ios26-disabled) {
+ion-popover.ios:not(.ios-theme-disabled, .ios26-disabled) {
--backdrop-opacity: 0.2;
- --background: rgba(var(--ios26-glass-background-rgb), 0.72);
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
--box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2), 0 0 10px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.82);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
&::part(arrow) {
display: none;
::after {
diff --git a/src/styles/components/ion-range.scss b/src/styles/components/ion-range.scss
index 43658cdc..823ea48f 100644
--- a/src/styles/components/ion-range.scss
+++ b/src/styles/components/ion-range.scss
@@ -5,7 +5,7 @@
-webkit-transform: scale(1.56, 1.47) translateX(calc(#{$translate-x} * -0.1)) translateZ(0);
}
-ion-range.ios:not(.ios26-disabled) {
+ion-range.ios:not(.ios-theme-disabled, .ios26-disabled) {
--knob-size: 20px;
--knob-width: 38px;
--knob-border-radius: 24px;
@@ -36,7 +36,7 @@ ion-range.ios:not(.ios26-disabled) {
}
&:not(.range-dual-knobs).range-pressed {
- --knob-background: rgba(var(--ios26-glass-background-rgb), 0.1);
+ --knob-background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.1);
--knob-box-shadow: 0 0.5px 4px rgba(0, 0, 0, 0.12), 0 6px 4px rgba(0, 0, 0, 0.05), inset 0.4px 0.4px 1px 0 var(--bar-background-active);
&::part(knob) {
diff --git a/src/styles/components/ion-searchbar.scss b/src/styles/components/ion-searchbar.scss
index f53c7a6e..b97a83c9 100644
--- a/src/styles/components/ion-searchbar.scss
+++ b/src/styles/components/ion-searchbar.scss
@@ -1,7 +1,7 @@
@use '../utils/api';
ion-modal.ios {
- ion-searchbar:not(.ios26-disabled) {
+ ion-searchbar:not(.ios-theme-disabled, .ios26-disabled) {
.searchbar-input-container {
input.searchbar-input {
// Modal表示でのアイコン非表示の不具合の対応
@@ -11,7 +11,7 @@ ion-modal.ios {
}
}
-ion-searchbar.ios:not(.ios26-disabled):not(.searchbar-classic) {
+ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled):not(.searchbar-classic) {
min-height: 60px;
padding: 0;
@@ -44,10 +44,12 @@ ion-searchbar.ios:not(.ios26-disabled):not(.searchbar-classic) {
/**
* add searchbar-classic
*/
-ion-toolbar.ios:not(.ios26-disabled):has(ion-searchbar.searchbar-classic.ios:not(.ios26-disabled)) {
+ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):has(
+ ion-searchbar.searchbar-classic.ios:not(.ios-theme-disabled, .ios26-disabled)
+ ) {
--min-height: auto;
}
-ion-searchbar.ios:not(.ios26-disabled).searchbar-classic {
+ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled).searchbar-classic {
padding-bottom: 12px;
min-height: auto;
.searchbar-input-container input.searchbar-input {
diff --git a/src/styles/components/ion-segment.scss b/src/styles/components/ion-segment.scss
index 6e0b8e9a..cea204bc 100644
--- a/src/styles/components/ion-segment.scss
+++ b/src/styles/components/ion-segment.scss
@@ -1,11 +1,11 @@
@use '../utils/api';
-ion-segment.ios:not(.ios26-disabled) {
+ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include api.glass-background;
min-height: 48px;
border-radius: 25px;
- transition: transform var(--ios26-activated-transition-duration) ease-out;
+ transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
// will-change is optimized to only apply when needed for performance
&.segment-activated,
@@ -114,7 +114,7 @@ ion-segment.ios:not(.ios26-disabled) {
}
}
-ion-segment-button.ios:not(.ios26-disabled) {
+ion-segment-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
--border-width: 0;
--indicator-box-shadow: none;
--indicator-color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.06);
diff --git a/src/styles/components/ion-tabs.scss b/src/styles/components/ion-tabs.scss
index 5b24d814..53b37eed 100644
--- a/src/styles/components/ion-tabs.scss
+++ b/src/styles/components/ion-tabs.scss
@@ -1,6 +1,6 @@
@use '../utils/api';
-ion-tab-bar.ios:not(.ios26-disabled) {
+ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
@include api.glass-background;
z-index: 2;
@@ -9,13 +9,13 @@ ion-tab-bar.ios:not(.ios26-disabled) {
&[slot='top'] {
position: absolute;
- top: var(--ios26-floating-safe-area-top);
+ top: var(--ios-theme-floating-safe-area-top, var(--ios26-floating-safe-area-top));
right: calc(16px + var(--ion-safe-area-right, 0px));
}
&[slot='bottom'] {
position: absolute;
- bottom: var(--ios26-floating-safe-area-bottom);
+ bottom: var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom));
left: calc(16px + var(--ion-safe-area-left, 0px));
}
@@ -31,7 +31,7 @@ ion-tab-bar.ios:not(.ios26-disabled) {
}
padding: 2px 2px;
- transition: transform var(--ios26-activated-transition-duration) ease-out;
+ transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease-out;
// will-change is optimized to only apply when needed for performance
&:has(ion-tab-button.ion-activated) {
@@ -55,7 +55,7 @@ ion-tab-bar.ios:not(.ios26-disabled) {
*/
&.ios26-enable-gesture.ios26-animated {
ion-tab-button.tab-selected::part(native) {
- background: rgba(var(--ios26-button-color-selected-rgb), 0);
+ background: rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0);
}
ion-tab-button.ion-activated {
ion-label,
@@ -66,19 +66,19 @@ ion-tab-bar.ios:not(.ios26-disabled) {
}
}
-ion-tab-button.ios:not(.ios26-disabled) {
+ion-tab-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
ion-icon {
font-size: 26px;
}
ion-label,
ion-icon {
transition:
- filter var(--ios26-activated-transition-duration) ease,
- color var(--ios26-activated-transition-duration) ease;
+ filter var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease,
+ color var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease;
}
- background: rgba(var(--ios26-glass-background-rgb), 0);
+ background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0);
height: auto;
- transition: transform var(--ios26-activated-transition-duration) ease;
+ transition: transform var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease;
&::part(native) {
overflow: visible;
min-height: 56px;
@@ -97,8 +97,8 @@ ion-tab-button.ios:not(.ios26-disabled) {
&.tab-selected {
&::part(native) {
- background: rgba(var(--ios26-button-color-selected-rgb), 0.095);
- transition: background var(--ios26-activated-transition-duration) ease;
+ background: rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.095);
+ transition: background var(--ios-theme-activated-transition-duration, var(--ios26-activated-transition-duration)) ease;
}
}
diff --git a/src/styles/components/ion-toast.scss b/src/styles/components/ion-toast.scss
index e78ab596..ba23f95b 100644
--- a/src/styles/components/ion-toast.scss
+++ b/src/styles/components/ion-toast.scss
@@ -1,21 +1,22 @@
@use '../utils/api';
-ion-toast.ios:not(.ios26-disabled) {
- --background: rgba(var(--ios26-glass-background-rgb), 0.72);
+ion-toast.ios:not(.ios-theme-disabled, .ios26-disabled) {
+ --background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.72);
--border-radius: 24px;
--border-style: solid;
--border-width: 0.5px;
--box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2), 0 0 10px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.82);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
--start: 16px;
--end: 16px;
&::part(wrapper) {
@include api.glass-background($include-background: false, $include-box-shadow: false, $include-border: false);
- border-top-color: rgba(var(--ios26-glass-border-color-rgb), 1);
- border-right-color: rgba(var(--ios26-glass-border-color-rgb), 0.8);
- border-bottom-color: rgba(var(--ios26-glass-border-color-rgb), 1);
- border-left-color: rgba(var(--ios26-glass-border-color-rgb), 0.6);
+ border-top-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);
+ border-right-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.8);
+ border-bottom-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 1);
+ border-left-color: rgba(var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)), 0.6);
}
&.ion-color {
diff --git a/src/styles/components/ion-toggle.scss b/src/styles/components/ion-toggle.scss
index 6868450f..a6edd60a 100644
--- a/src/styles/components/ion-toggle.scss
+++ b/src/styles/components/ion-toggle.scss
@@ -4,7 +4,7 @@
* Adjustments have been made to prevent the right edge from being cut off within the ion-item.
* When the native-inner part be added to the ion-item, it will be removed.
*/
-ion-item.ios:not(.ios26-disabled) ion-toggle.ios:not(.ios26-disabled) {
+ion-item.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toggle.ios:not(.ios-theme-disabled, .ios26-disabled) {
&.toggle-checked.toggle-activated::part(track) {
transform-origin: left;
transform: scaleX(0.894) translateZ(0);
@@ -16,7 +16,7 @@ ion-item.ios:not(.ios26-disabled) ion-toggle.ios:not(.ios26-disabled) {
}
}
-ion-toggle.ios:not(.ios26-disabled) {
+ion-toggle.ios:not(.ios-theme-disabled, .ios26-disabled) {
--handle-width: 38px;
--handle-height: 24px;
--handle-max-width: none;
@@ -47,8 +47,8 @@ ion-toggle.ios:not(.ios26-disabled) {
@include api.glass-background($opacity: 0.1, $blur: 0.5px, $saturate: 120%, $include-background: false, $include-box-shadow: false);
}
&.toggle-activated {
- --handle-background: rgba(var(--ios26-glass-background-rgb), 0.1);
- --handle-background-checked: rgba(var(--ios26-glass-background-rgb), 0.1);
+ --handle-background: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.1);
+ --handle-background-checked: rgba(var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)), 0.1);
--handle-box-shadow: inset 0 0 8px 0 var(--track-background);
}
&.ion-color.toggle-checked.toggle-activated {
diff --git a/src/styles/components/ion-toolbar.scss b/src/styles/components/ion-toolbar.scss
index fe358c8c..df774a46 100644
--- a/src/styles/components/ion-toolbar.scss
+++ b/src/styles/components/ion-toolbar.scss
@@ -6,26 +6,27 @@
* padding-top: var(--ion-safe-area-top, 0);
* }
*/
-ion-header.ios:not(.ios26-disabled) ion-toolbar:not(.ios26-disabled):first-of-type {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
padding-top: max(calc(var(--ion-safe-area-top) - 12px), 4px);
}
-ion-modal.ios:not(.ios26-disabled).modal-card,
-ion-modal.ios:not(.ios26-disabled).modal-sheet {
- ion-header.ios:not(.ios26-disabled) ion-toolbar.ios:not(.ios26-disabled):first-of-type {
+ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled).modal-card,
+ion-modal.ios:not(.ios-theme-disabled, .ios26-disabled).modal-sheet {
+ ion-header.ios:not(.ios-theme-disabled, .ios26-disabled) ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
padding-top: 6px;
}
}
-ion-header.ios.header-collapse-condense:not(.ios26-disabled) ion-toolbar:not(.ios26-disabled):first-of-type {
+ion-header.ios.header-collapse-condense:not(.ios-theme-disabled, .ios26-disabled)
+ ion-toolbar:not(.ios-theme-disabled, .ios26-disabled):first-of-type {
padding-top: 0;
}
-ion-toolbar.ios:not(.toolbar-title-large):not(.ios26-disabled):not(:has(ion-segment.segment-expand)) {
+ion-toolbar.ios:not(.toolbar-title-large):not(.ios-theme-disabled, .ios26-disabled):not(:has(ion-segment.segment-expand)) {
--min-height: 68px;
}
-ion-toolbar.ios:not(.ios26-disabled).toolbar-searchbar {
+ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled).toolbar-searchbar {
*[slot='start'],
*[slot='end'] {
align-self: center;
@@ -34,7 +35,7 @@ ion-toolbar.ios:not(.ios26-disabled).toolbar-searchbar {
ion-buttons[slot='start'] {
margin-right: 6px;
}
- ion-searchbar.ios:not(.ios26-disabled) {
+ ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
.searchbar-input-container {
margin: 0 12px 0 6px;
}
@@ -44,7 +45,7 @@ ion-toolbar.ios:not(.ios26-disabled).toolbar-searchbar {
ion-buttons[slot='end'] {
margin-left: 6px;
}
- ion-searchbar.ios:not(.ios26-disabled) {
+ ion-searchbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
.searchbar-input-container {
margin: 0 6px 0 12px;
}
@@ -52,7 +53,7 @@ ion-toolbar.ios:not(.ios26-disabled).toolbar-searchbar {
}
}
-ion-toolbar.ios:not(.ios26-disabled) {
+ion-toolbar.ios:not(.ios-theme-disabled, .ios26-disabled) {
ion-buttons {
margin-left: 12px;
margin-right: 12px;
diff --git a/src/styles/default-variables.scss b/src/styles/default-variables.scss
index eccfd2d3..c24bc48b 100644
--- a/src/styles/default-variables.scss
+++ b/src/styles/default-variables.scss
@@ -1,12 +1,13 @@
/**
* @naming
- * prefix: ios26
+ * prefix: ios-theme
* target-element: tab-button
* target css property: color
* status: selected
* additional information: rgb
*/
+// Deprecated --ios26-* defaults back the --ios-theme-* fallbacks.
:root {
--ios26-floating-safe-area-top: max(10px, var(--ion-safe-area-top, 0px));
--ios26-floating-safe-area-bottom: max(10px, calc(var(--ion-safe-area-bottom, 0px) - 12px));
diff --git a/src/styles/md-remove-ios-class-effect.scss b/src/styles/md-remove-ios-class-effect.scss
index 0180a5ff..2b6533e8 100644
--- a/src/styles/md-remove-ios-class-effect.scss
+++ b/src/styles/md-remove-ios-class-effect.scss
@@ -3,7 +3,7 @@ ion-buttons.md {
* ion-buttons.ios26-disabled > ion-button.button-default is for ios26 structure.
* for .md, remove button-default styles. Will be button-clear.
*/
- ion-button.md:not(.ios26-disabled).button-default {
+ ion-button.md:not(.ios-theme-disabled, .ios26-disabled).button-default {
// copy .button-clear
--color: initial;
--background: transparent;
diff --git a/src/styles/utils/api.scss b/src/styles/utils/api.scss
index 71a3820a..e38f88a3 100644
--- a/src/styles/utils/api.scss
+++ b/src/styles/utils/api.scss
@@ -2,8 +2,8 @@
$opacity: 0.72,
$blur: 2px,
$saturate: 360%,
- $background-rgb: var(--ios26-glass-background-rgb),
- $border-color-rgb: var(--ios26-glass-border-color-rgb),
+ $background-rgb: var(--ios-theme-glass-background-rgb, var(--ios26-glass-background-rgb)),
+ $border-color-rgb: var(--ios-theme-glass-border-color-rgb, var(--ios26-glass-border-color-rgb)),
$include-background: true,
$include-box-shadow: true,
$include-border: true
@@ -14,8 +14,8 @@
backdrop-filter: blur($blur) saturate($saturate);
@if $include-box-shadow {
box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2),
- 0 0 10px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.82);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 10px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.82);
}
@if $include-border {
border-top: 0.5px solid rgba($border-color-rgb, 1);
@@ -33,8 +33,8 @@
@mixin glass-background-button-activated {
box-shadow:
- inset 0 0 8px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.2),
- 0 0 8px -4px rgba(var(--ios26-glass-box-shadow-color-rgb), 0.92);
+ inset 0 0 8px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.2),
+ 0 0 8px -4px rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.92);
}
@mixin glass-background-button-activated-dark(
@@ -45,16 +45,16 @@
$include-box-shadow: true
) {
@if $include-background {
- background: rgba(var(--ios26-button-color-selected-rgb), $opacity);
+ background: rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), $opacity);
}
backdrop-filter: blur($blur) saturate($saturate);
@if $include-box-shadow {
- box-shadow: inset 0 0 16px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.55);
+ box-shadow: inset 0 0 16px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.55);
}
- border-top: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.8);
- border-right: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.4);
- border-bottom: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.8);
- border-left: 0.8px solid rgba(var(--ios26-button-color-selected-rgb), 0.6);
+ border-top: 0.8px solid rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.8);
+ border-right: 0.8px solid rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.4);
+ border-bottom: 0.8px solid rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.8);
+ border-left: 0.8px solid rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.6);
// Hardware acceleration optimization for glass effects
transform: translateZ(0);
diff --git a/src/styles/utils/dark/ion-button.scss b/src/styles/utils/dark/ion-button.scss
index c64e7046..0b93d994 100644
--- a/src/styles/utils/dark/ion-button.scss
+++ b/src/styles/utils/dark/ion-button.scss
@@ -5,7 +5,7 @@
@include api.glass-background-button-activated-dark;
}
- ion-button:not(.ios26-disabled).button-clear {
+ ion-button:not(.ios-theme-disabled, .ios26-disabled).button-clear {
&.ion-activated {
color: rgb(var(--ion-text-color-rgb, 0, 0, 0));
&.ion-color {
@@ -14,8 +14,8 @@
}
}
- ion-button:not(.ios26-disabled),
- ion-back-button:not(.ios26-disabled) {
+ ion-button:not(.ios-theme-disabled, .ios26-disabled),
+ ion-back-button:not(.ios-theme-disabled, .ios26-disabled) {
&.ion-activated {
--color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 1);
@@ -28,10 +28,10 @@
@mixin theme-dark-button($is-back-button: false) {
&.ion-activated:not(.button-solid):not(.button-outline):not(.button-clear) {
- --background: rgba(var(--ios26-button-color-selected-rgb), 0.56);
+ --background: rgba(var(--ios-theme-button-color-selected-rgb, var(--ios26-button-color-selected-rgb)), 0.56);
--color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 1);
@if not $is-back-button {
- --box-shadow: inset 0 0 16px 0 rgba(var(--ios26-glass-box-shadow-color-rgb), 0.55);
+ --box-shadow: inset 0 0 16px 0 rgba(var(--ios-theme-glass-box-shadow-color-rgb, var(--ios26-glass-box-shadow-color-rgb)), 0.55);
}
&.ion-color {
--color: rgba(var(--ion-color-base-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 1);
@@ -46,13 +46,13 @@
}
@mixin ion-button {
- ion-buttons.ios:not(.ios26-disabled):not(:has(ion-back-button, ion-button:not(.button-clear))) {
+ ion-buttons.ios:not(.ios-theme-disabled, .ios26-disabled):not(:has(ion-back-button, ion-button:not(.button-clear))) {
@include theme-dark-buttons;
}
- ion-button:not(.ios26-disabled) {
+ ion-button:not(.ios-theme-disabled, .ios26-disabled) {
@include theme-dark-button;
}
- ion-back-button:not(.ios26-disabled) {
+ ion-back-button:not(.ios-theme-disabled, .ios26-disabled) {
@include theme-dark-button($is-back-button: true);
}
}
diff --git a/src/styles/utils/dark/ion-fab.scss b/src/styles/utils/dark/ion-fab.scss
index fc36a997..ad7607ad 100644
--- a/src/styles/utils/dark/ion-fab.scss
+++ b/src/styles/utils/dark/ion-fab.scss
@@ -1,7 +1,7 @@
@use '../api';
@mixin ion-fab {
- ion-fab.ios:not(.ios26-disabled) {
+ ion-fab.ios:not(.ios-theme-disabled, .ios26-disabled) {
ion-fab-button {
&.ion-activated {
--color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 1);
diff --git a/src/styles/utils/dark/ion-segment.scss b/src/styles/utils/dark/ion-segment.scss
index 535ba659..3887001c 100644
--- a/src/styles/utils/dark/ion-segment.scss
+++ b/src/styles/utils/dark/ion-segment.scss
@@ -1,10 +1,11 @@
@mixin ion-segment {
- ion-segment.ios:not(.ios26-disabled) {
+ ion-segment.ios:not(.ios-theme-disabled, .ios26-disabled) {
}
- ion-segment-button.ios:not(.ios26-disabled) {
+ ion-segment-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
&.ion-cloned-element {
&::part(native) {
--ios26-glass-border-color-rgb: 120, 120, 120;
+ --ios-theme-glass-border-color-rgb: var(--ios26-glass-border-color-rgb);
box-shadow: inset 0 0 8px 0 rgba(255, 255, 255, 0.2);
}
}
diff --git a/src/styles/utils/dark/ion-tabs.scss b/src/styles/utils/dark/ion-tabs.scss
index 1d9bf51d..0022c3b2 100644
--- a/src/styles/utils/dark/ion-tabs.scss
+++ b/src/styles/utils/dark/ion-tabs.scss
@@ -1,9 +1,9 @@
@use '../api';
@mixin ion-tabs {
- ion-tab-bar.ios:not(.ios26-disabled) {
+ ion-tab-bar.ios:not(.ios-theme-disabled, .ios26-disabled) {
}
- ion-tab-button.ios:not(.ios26-disabled) {
+ ion-tab-button.ios:not(.ios-theme-disabled, .ios26-disabled) {
&.ion-activated {
ion-label,
ion-icon {
@@ -14,6 +14,7 @@
&.ion-cloned-element {
&::part(native) {
--ios26-glass-border-color-rgb: 120, 120, 120;
+ --ios-theme-glass-border-color-rgb: var(--ios26-glass-border-color-rgb);
box-shadow: inset 0 0 8px 0 rgba(255, 255, 255, 0.2);
}
}
diff --git a/src/styles/utils/translucent.scss b/src/styles/utils/translucent.scss
index 764347b1..f5ee3682 100644
--- a/src/styles/utils/translucent.scss
+++ b/src/styles/utils/translucent.scss
@@ -1,7 +1,7 @@
@use 'api';
-ion-header.ios:not(.ios26-disabled).header-translucent,
-ion-footer.ios:not(.ios26-disabled).footer-translucent {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent,
+ion-footer.ios:not(.ios-theme-disabled, .ios26-disabled).footer-translucent {
.header-background,
.footer-background {
backdrop-filter: none;
@@ -21,22 +21,24 @@ ion-footer.ios:not(.ios26-disabled).footer-translucent {
}
}
-ion-header.ios:not(.ios26-disabled).header-collapse-main ion-toolbar.in-toolbar ion-title {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-collapse-main ion-toolbar.in-toolbar ion-title {
transition: all 0.5s ease-in-out;
}
-ion-header.ios:not(.ios26-disabled).header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,
-ion-header.ios:not(.ios26-disabled).header-collapse-condense-inactive:not(.header-collapse-condense)
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-collapse-condense-inactive:not(.header-collapse-condense)
+ ion-toolbar.in-toolbar
+ ion-title,
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-collapse-condense-inactive:not(.header-collapse-condense)
ion-toolbar.in-toolbar
ion-buttons.buttons-collapse {
filter: blur(2px);
transform: translateY(8px);
}
-ion-header.ios:not(.ios26-disabled):not(.header-transitioning).header-translucent::before,
-ion-header.ios:not(.ios26-disabled):not(.header-transitioning).header-translucent::after,
-ion-content.ios:not(.ios26-disabled).content-fullscreen::part(background)::before,
-ion-content.ios:not(.ios26-disabled).content-fullscreen::part(background)::after {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled):not(.header-transitioning).header-translucent::before,
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled):not(.header-transitioning).header-translucent::after,
+ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen::part(background)::before,
+ion-content.ios:not(.ios-theme-disabled, .ios26-disabled).content-fullscreen::part(background)::after {
content: '';
position: absolute;
width: 100%;
@@ -44,7 +46,7 @@ ion-content.ios:not(.ios26-disabled).content-fullscreen::part(background)::after
z-index: 1;
}
-ion-header.ios:not(.ios26-disabled).header-translucent::before {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent::before {
/**
* With safe-area effect, this is need.
*/
@@ -53,7 +55,7 @@ ion-header.ios:not(.ios26-disabled).header-translucent::before {
height: var(--ion-safe-area-top);
}
-ion-header.ios:not(.ios26-disabled).header-translucent::after {
+ion-header.ios:not(.ios-theme-disabled, .ios26-disabled).header-translucent::after {
z-index: 2;
top: 0;
height: 100%;
@@ -71,21 +73,22 @@ ion-header.ios:not(.ios26-disabled).header-translucent::after {
height: var(--offset-top, 0px);
background: linear-gradient(
in oklab,
- rgba(var(--ios26-content-box-shadow-rgb), 0.5) 20%,
- rgba(var(--ios26-content-box-shadow-rgb), 0) 100%
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0.5) 20%,
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0) 100%
);
- box-shadow: inset 0 var(--offset-top, 0px) 16px -32px rgba(var(--ios26-content-box-shadow-rgb), 0.6);
+ box-shadow: inset 0 var(--offset-top, 0px) 16px -32px
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0.6);
}
ion-content.content-fullscreen::part(background)::after {
z-index: 2;
bottom: 0;
- height: calc(60px + var(--ios26-floating-safe-area-bottom));
+ height: calc(60px + var(--ios-theme-floating-safe-area-bottom, var(--ios26-floating-safe-area-bottom)));
background: linear-gradient(
in oklab,
- rgba(var(--ios26-content-box-shadow-rgb), 0) 0%,
- rgba(var(--ios26-content-box-shadow-rgb), 0.8) 50%,
- rgba(var(--ios26-content-box-shadow-rgb), 0.8) 100%
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0) 0%,
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0.8) 50%,
+ rgba(var(--ios-theme-content-box-shadow-rgb, var(--ios26-content-box-shadow-rgb)), 0.8) 100%
);
}