アニメーション
これらのジェスチャーとアニメーションのヘルパーは本番利用可能な任意機能です。テーマは使用しなくても動作します。
ion-tab-button / ion-segment-button の Sheet of Glass
ion-tab-bar または ion-segment 要素を登録すると、ボタンに移動する選択エフェクトを追加できます。
registerTabBarEffect は、ページ表示中の変更も含めて prefers-reduced-motion を尊重します。視差効果を減らす設定では、移動するレンズとタブの拡大縮小を無効にし、Ionic 標準の選択動作を維持します。設定を解除すると、登録を破棄するまで任意のエフェクトが復元されます。
registerSegmentEffect は視覚レイヤーだけを追加します。選択、ドラッグ、キーボード操作、イベントは引き続き Ionic が管理します。未選択のセグメントは指を離すとレンズが移動し、選択済みのセグメントは短いタップでもその場で拡大します。動きは iOS 27 のプレゼンテーションレイヤーの計測値に従います。視差効果を減らす設定では省略されます。ネイティブのガラスの屈折は CSS で近似します。
import { registerTabBarEffect, registerSegmentEffect } from '@rdlabo/ionic-theme-ios27';
/**
* 初期化済みの Ionic DOM 要素を登録します。
*/
const tabBar = document.querySelector<HTMLElement>('ion-tab-bar');
const segment = document.querySelector<HTMLElement>('ion-segment');
const registeredTabBarEffect = tabBar ? registerTabBarEffect(tabBar) : undefined;
const registeredSegmentEffect = segment ? registerSegmentEffect(segment) : undefined;
const destroy = () => {
/**
* 登録した DOM 要素が削除された場合(画面遷移など)は、
* ジェスチャーとアニメーションを必ず破棄します。イベントリスナーも削除されます。
* 必要に応じて再登録できます。
*/
registeredTabBarEffect?.destroy();
registeredSegmentEffect?.destroy();
};
検索バーのキャンセルアイコン
Ionic 8 と 9 は Material Design モードでのみ cancelButtonIcon を描画します。検索バーを登録すると iOS モードでも同じプロパティを使えます。この任意のヘルパーを使用しない場合、テーマは Ionic のキャンセル用テキストボタンを維持します。
この描画補助は一時的なもので、対応する Ionic のバージョンが iOS DOM 内で cancelButtonIcon を描画するようになれば削除する予定です。アイコンがすでに存在する場合は挿入しません。キーボード操作、フォーカス、ボタンのアクセシビリティー属性、キャンセル・クリアの動作は変更せず、Ionic が引き続き管理します。CSS のデザインとアニメーションはヘルパーから独立しており、Ionic 自身が描画するアイコンにも適用されます。
import { supportSeachbarCancelButtonIcon } from '@rdlabo/ionic-theme-ios27';
import { closeOutline } from 'ionicons/icons';
const searchbar = document.querySelector<HTMLIonSearchbarElement>('ion-searchbar')!;
searchbar.animated = true;
searchbar.showCancelButton = 'focus'; // 'always' と 'never' も使用できます
searchbar.cancelButtonIcon = closeOutline;
searchbar.clearIcon = closeOutline;
searchbar.cancelButtonText = 'Close search'; // アイコンボタンのアクセシブルな名前
const effect = supportSeachbarCancelButtonIcon(searchbar);
// JavaScript プロパティで cancelButtonIcon を変更したら effect.refresh() を呼びます。
// コンポーネント・ページの破棄時:
// effect.destroy();
登録と対象外の条件
Ionic 要素の初期化後(例: Angular の ngAfterViewInit)に登録してください。
| 条件 | 動作 |
|---|---|
| 対応する iOS モードの検索バー | Ionic のボタンとイベントハンドラーを維持します。destroy() はテキストを復元します。 |
MD モード、searchbar-classic、ios-theme-disabled、ios26-disabled |
ヘルパーを適用しません。 |
animated / prefers-reduced-motion |
CSS アニメーションが設定を尊重します。 |
| CSS のカスタマイズ | --background、--box-shadow、--border-radius、--cancel-button-color を引き続き使用できます。 |
クリアボタンとキャンセルボタン
| ボタン | Ionic の外観設定 | 操作 |
|---|---|---|
| クリア | clearIcon、showClearButton、--clear-button-color |
入力フォーカスを維持してクリアします。 |
| キャンセル | cancelButtonIcon、--cancel-button-color |
検索を終了します。 |
両方のボタンを入力欄の横に同時に表示できます。外観を揃えるには clearIcon と cancelButtonIcon に同じアイコンを指定します。
外側のガラスボタンはいずれも通常時 44px で、押すと拡大します。視差効果を減らす設定では拡大縮小を無効にします。クリアボタンは入力欄の外に表示され、アイコンは Ionic が提供します。
押している間はガラスの背景が不透明になり、アイコンの色を維持したまま不透明度が 0.55 になります。押下時の背景は --background と独立して --background-activated で変更できます。
TabBarSearchable: ion-tab-bar と ion-fab-button による検索
ion-tabs 内で次の構造を使用すると、検索ボタンが検索ツールバーへ変化するアニメーションを適用できます。
<ion-content>...</ion-content>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button aria-label="Search" (click)="present($event)">
<ion-icon name="search"></ion-icon>
</ion-fab-button>
</ion-fab>
<ion-footer [translucent]="true">
<ion-toolbar>
<ion-buttons slot="start">
<!-- ion-icon の name はアニメーションが動的に設定します -->
<ion-button fill="default"><ion-icon slot="icon-only"></ion-icon> </ion-button>
</ion-buttons>
<!-- 利用側で `ionChange` などのイベントを設定します。 -->
<ion-searchbar aria-label="Search" (ionChange)="example($event)"></ion-searchbar>
</ion-toolbar>
</ion-footer>
import { attachTabBarSearchable, TabBarSearchableType } from '@rdlabo/ionic-theme-ios27';
import type { TabBarSearchableFunction } from '@rdlabo/ionic-theme-ios27';
let searchableFun: TabBarSearchableFunction | undefined;
const initialize = () => {
// attachTabBarSearchable は状態を持つため、ページごとに初期化します。
const tabBar = document.querySelector<HTMLElement>('ion-tab-bar');
const fabButton = document.querySelector<HTMLElement>('ion-fab-button');
const footer = document.querySelector<HTMLElement>('ion-footer');
if (!tabBar || !fabButton || !footer) {
return;
}
searchableFun = attachTabBarSearchable(tabBar, fabButton, footer);
};
const present = (event: Event) => {
searchableFun!(event, TabBarSearchableType.Enter);
};
const dismiss = (event: Event) => {
searchableFun!(event, TabBarSearchableType.Leave);
};

