Skip to content

Commit ab0df5b

Browse files
committed
Merge commit '005d32eb4464ba00c5d578874b12cdea601626d6'
# Conflicts: # cspell-wordlist.txt # docs/api/modal.md # docs/api/refresher.md
2 parents ce29bff + 005d32e commit ab0df5b

File tree

103 files changed

+6502
-3738
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+6502
-3738
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ yarn-debug.log*
2424
yarn-error.log*
2525

2626
static/**/node_modules/
27+
.idea

cspell-wordlist.txt

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Udemy
1313
Vetur
1414
Wistia
1515
WCAG
16+
CDK
1617

1718
actionsheet
1819
fabs
@@ -82,9 +83,3 @@ msallowfullscreen
8283
oallowfullscreen
8384
webkitallowfullscreen
8485
webnative
85-
86-
browserslistrc
87-
ionicframework
88-
tappable
89-
Overscroll
90-
expressjs

docs/angular/overlays.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
---
2+
title: Overlay Components
3+
sidebar_label: Overlays
4+
---
5+
6+
<head>
7+
<title>Angular Overlay Components: Modals, Popovers with Custom Injectors</title>
8+
<meta
9+
name="description"
10+
content="Learn how to use overlay components like modals and popovers in Ionic Angular, including passing custom injectors for dependency injection."
11+
/>
12+
</head>
13+
14+
Ionic provides overlay components such as modals and popovers that display content on top of your application. In Angular, these overlays can be created using controllers like `ModalController` and `PopoverController`.
15+
16+
## Creating Overlays
17+
18+
Overlays can be created programmatically using their respective controllers:
19+
20+
```typescript
21+
import { Component } from '@angular/core';
22+
import { ModalController } from '@ionic/angular/standalone';
23+
import { MyModalComponent } from './my-modal.component';
24+
25+
@Component({
26+
selector: 'app-home',
27+
templateUrl: './home.component.html',
28+
})
29+
export class HomeComponent {
30+
constructor(private modalController: ModalController) {}
31+
32+
async openModal() {
33+
const modal = await this.modalController.create({
34+
component: MyModalComponent,
35+
componentProps: {
36+
title: 'My Modal',
37+
},
38+
});
39+
await modal.present();
40+
}
41+
}
42+
```
43+
44+
## Custom Injectors
45+
46+
By default, overlay components use the root injector for dependency injection. This means that services or tokens provided at the route level or within a specific component tree are not accessible inside the overlay.
47+
48+
The `injector` option allows you to pass a custom Angular `Injector` when creating a modal or popover. This enables overlay components to access services and tokens that are not available in the root injector.
49+
50+
### Use Cases
51+
52+
Custom injectors are useful when you need to:
53+
54+
- Access route-scoped services from within an overlay
55+
- Use Angular CDK's `Dir` directive for bidirectional text support
56+
- Access any providers that are not registered at the root level
57+
58+
### Usage
59+
60+
To use a custom injector, pass it to the `create()` method:
61+
62+
```typescript
63+
import { Component, Injector } from '@angular/core';
64+
import { ModalController } from '@ionic/angular/standalone';
65+
import { MyModalComponent } from './my-modal.component';
66+
import { MyRouteService } from './my-route.service';
67+
68+
@Component({
69+
selector: 'app-feature',
70+
templateUrl: './feature.component.html',
71+
providers: [MyRouteService], // Service provided at route level
72+
})
73+
export class FeatureComponent {
74+
constructor(private modalController: ModalController, private injector: Injector) {}
75+
76+
async openModal() {
77+
const modal = await this.modalController.create({
78+
component: MyModalComponent,
79+
injector: this.injector, // Pass the component's injector
80+
});
81+
await modal.present();
82+
}
83+
}
84+
```
85+
86+
The modal component can now inject `MyRouteService`:
87+
88+
```typescript
89+
import { Component, inject } from '@angular/core';
90+
import { MyRouteService } from '../my-route.service';
91+
92+
@Component({
93+
selector: 'app-my-modal',
94+
templateUrl: './my-modal.component.html',
95+
})
96+
export class MyModalComponent {
97+
private myRouteService = inject(MyRouteService);
98+
}
99+
```
100+
101+
### Creating a Custom Injector
102+
103+
You can also create a custom injector with specific providers:
104+
105+
```typescript
106+
import { Component, Injector } from '@angular/core';
107+
import { ModalController } from '@ionic/angular/standalone';
108+
import { MyModalComponent } from './my-modal.component';
109+
import { MyService } from './my.service';
110+
111+
@Component({
112+
selector: 'app-feature',
113+
templateUrl: './feature.component.html',
114+
})
115+
export class FeatureComponent {
116+
constructor(private modalController: ModalController, private injector: Injector) {}
117+
118+
async openModal() {
119+
const myService = new MyService();
120+
myService.configure({ someOption: true });
121+
122+
const customInjector = Injector.create({
123+
providers: [{ provide: MyService, useValue: myService }],
124+
parent: this.injector,
125+
});
126+
127+
const modal = await this.modalController.create({
128+
component: MyModalComponent,
129+
injector: customInjector,
130+
});
131+
await modal.present();
132+
}
133+
}
134+
```
135+
136+
### Using with Angular CDK Directionality
137+
138+
A common use case is providing the Angular CDK `Dir` directive to overlays for bidirectional text support:
139+
140+
```typescript
141+
import { Component, Injector } from '@angular/core';
142+
import { Dir } from '@angular/cdk/bidi';
143+
import { ModalController } from '@ionic/angular/standalone';
144+
import { MyModalComponent } from './my-modal.component';
145+
146+
@Component({
147+
selector: 'app-feature',
148+
templateUrl: './feature.component.html',
149+
})
150+
export class FeatureComponent {
151+
constructor(private modalController: ModalController, private injector: Injector) {}
152+
153+
async openModal() {
154+
const modal = await this.modalController.create({
155+
component: MyModalComponent,
156+
injector: this.injector, // Includes Dir from component tree
157+
});
158+
await modal.present();
159+
}
160+
}
161+
```
162+
163+
### Popover Controller
164+
165+
The `PopoverController` supports the same `injector` option:
166+
167+
```typescript
168+
import { Component, Injector } from '@angular/core';
169+
import { PopoverController } from '@ionic/angular/standalone';
170+
import { MyPopoverComponent } from './my-popover.component';
171+
172+
@Component({
173+
selector: 'app-feature',
174+
templateUrl: './feature.component.html',
175+
})
176+
export class FeatureComponent {
177+
constructor(private popoverController: PopoverController, private injector: Injector) {}
178+
179+
async openPopover(event: Event) {
180+
const popover = await this.popoverController.create({
181+
component: MyPopoverComponent,
182+
event: event,
183+
injector: this.injector,
184+
});
185+
await popover.present();
186+
}
187+
}
188+
```
189+
190+
## Angular Options Types
191+
192+
Ionic Angular exports its own `ModalOptions` and `PopoverOptions` types that extend the core options with Angular-specific properties like `injector`:
193+
194+
- `ModalOptions` - Extends core `ModalOptions` with the `injector` property
195+
- `PopoverOptions` - Extends core `PopoverOptions` with the `injector` property
196+
197+
These types are exported from `@ionic/angular` and `@ionic/angular/standalone`:
198+
199+
```typescript
200+
import type { ModalOptions, PopoverOptions } from '@ionic/angular/standalone';
201+
```
202+
203+
## Docs for Overlays in Ionic
204+
205+
For full docs and to see usage examples, visit the docs page for each of the overlays in Ionic:
206+
207+
- [Action Sheet](https://ionicframework.com/docs/api/action-sheet)
208+
- [Alert](https://ionicframework.com/docs/api/alert)
209+
- [Loading](https://ionicframework.com/docs/api/loading)
210+
- [Modal](https://ionicframework.com/docs/api/modal)
211+
- [Picker](https://ionicframework.com/docs/api/picker)
212+
- [Popover](https://ionicframework.com/docs/api/popover)
213+
- [Toast](https://ionicframework.com/docs/api/toast)

docs/api/datetime.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ import ShowAdjacentDays from '@site/static/usage/v8/datetime/show-adjacent-days/
4141
import MultipleDateSelection from '@site/static/usage/v8/datetime/multiple/index.md';
4242

4343
import GlobalTheming from '@site/static/usage/v8/datetime/styling/global-theming/index.md';
44+
import CalendarHeaderStyling from '@site/static/usage/v8/datetime/styling/calendar-header/index.md';
4445
import CalendarDaysStyling from '@site/static/usage/v8/datetime/styling/calendar-days/index.md';
46+
import DatetimeHeaderStyling from '@site/static/usage/v8/datetime/styling/datetime-header/index.md';
4547
import WheelStyling from '@site/static/usage/v8/datetime/styling/wheel-styling/index.md';
4648

4749
<head>
@@ -352,6 +354,24 @@ Ionicの強力なテーマシステムを使用すると、特定のテーマに
352354

353355
<GlobalTheming />
354356

357+
### Datetime Header
358+
359+
The datetime header manages the content for the `title` slot and the selected date.
360+
361+
:::note
362+
The selected date will not render if `preferWheel` is set to `true`.
363+
:::
364+
365+
<DatetimeHeaderStyling />
366+
367+
### Calender Header
368+
369+
The calendar header manages the date navigation controls (month/year picker and prev/next buttons) and the days of the week when using a grid style layout.
370+
371+
The header can be styled using CSS shadow parts.
372+
373+
<CalendarHeaderStyling />
374+
355375
### Calendar Days
356376

357377
The calendar days in a grid-style `ion-datetime` can be styled using CSS shadow parts.

docs/api/modal.md

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,26 @@ import CustomDialogs from '@site/static/usage/v8/modal/custom-dialogs/index.md';
212212
* `ion-content` は、フルページモダル、カード、シートで使用することを意図しています。カスタムダイアログのサイズが動的であったり、不明であったりする場合は、 `ion-content` を使用するべきではありません。
213213
* カスタムダイアログを作成することは、デフォルトのモーダルエクスペリエンスから逃れる方法を提供します。そのため、カスタムダイアログは、カードやシートのモーダルでは使用しないでください。
214214

215+
## Event Handling
216+
217+
### Using `ionDragStart` and `ionDragEnd`
218+
219+
The `ionDragStart` event is emitted as soon as the user begins a dragging gesture on the modal. This event fires at the moment the user initiates contact with the handle or modal surface, before any actual displacement occurs. It is particularly useful for preparing the interface for a transition, such as hiding certain interactive elements (like headers or buttons) to ensure a smooth dragging experience.
220+
221+
The `ionDragEnd` event is emitted when the user completes the dragging gesture by releasing the modal. Like the move event, it includes the final [`ModalDragEventDetail`](#modaldrageventdetail) object. This event is commonly used to finalize state changes once the modal has come to a rest.
222+
223+
import DragStartEndEvents from '@site/static/usage/v8/modal/drag-start-end-events/index.md';
224+
225+
<DragStartEndEvents />
226+
227+
### Using `ionDragMove`
228+
229+
The `ionDragMove` event is emitted continuously while the user is actively dragging the modal. This event provides a [`ModalDragEventDetail`](#modaldrageventdetail) object containing real-time data, essential for creating highly responsive UI updates that react instantly to the user's touch. For example, the `progress` value can be used to dynamically darken a header's opacity as the modal is dragged upward.
230+
231+
import DragMoveEvent from '@site/static/usage/v8/modal/drag-move-event/index.md';
232+
233+
<DragMoveEvent />
234+
215235
## Interfaces
216236

217237
### ModalOptions
@@ -253,7 +273,60 @@ interface ModalCustomEvent extends CustomEvent {
253273
}
254274
```
255275

256-
## アクセシビリティ
276+
### ModalDragEventDetail
277+
278+
When using the `ionDragMove` and `ionDragEnd` events, the event detail contains the following properties:
279+
280+
```typescript
281+
interface ModalDragEventDetail {
282+
/**
283+
* The current Y position of the modal.
284+
*
285+
* This can be used to determine how far the modal has been dragged.
286+
*/
287+
currentY: number;
288+
/**
289+
* The change in Y position since the gesture started.
290+
*
291+
* This can be used to determine the direction of the drag.
292+
*/
293+
deltaY: number;
294+
/**
295+
* The velocity of the drag in the Y direction.
296+
*
297+
* This can be used to determine how fast the modal is being dragged.
298+
*/
299+
velocityY: number;
300+
/**
301+
* A number between 0 and 1.
302+
*
303+
* In a sheet modal, progress represents the relative position between
304+
* the lowest and highest defined breakpoints.
305+
*
306+
* In a card modal, it measures the relative position between the
307+
* bottom of the screen and the top of the modal when it is fully
308+
* open.
309+
*
310+
* This can be used to style content based on how far the modal has
311+
* been dragged.
312+
*/
313+
progress: number;
314+
/**
315+
* If the modal is a sheet modal, this will be the breakpoint that
316+
* the modal will snap to if the user lets go of the modal at the
317+
* current moment.
318+
*
319+
* If it's a card modal, this property will not be included in the
320+
* event payload.
321+
*
322+
* This can be used to style content based on where the modal will
323+
* snap to upon release.
324+
*/
325+
snapBreakpoint?: number;
326+
}
327+
```
328+
329+
## Accessibility
257330

258331
### Keyboard Interactions
259332

docs/api/range.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ import CSSProps from '@site/static/usage/v8/range/theming/css-properties/index.m
124124

125125
Rangeには [CSS Shadow Parts](#css-shadow-parts) があり、Rangeコンポーネント内の特定の要素ノードを完全にカスタマイズすることができます。CSS Shadow Partsは最も多くのカスタマイズ機能を提供し、Rangeコンポーネントで高度なスタイリングが必要な場合に推奨されるアプローチです。
126126

127+
When `dualKnobs` is enabled, additional Shadow Parts are exposed to allow each knob to be styled independently. These are available in two forms: **static identity parts** (`A` and `B`) and **dynamic position parts** (`lower` and `upper`). The A and B parts always refer to the same physical knobs, even if the knobs cross. In contrast, the lower and upper parts reflect the current value position and automatically swap if the knobs cross. This allows styling by consistent identity or by relative value within the range.
128+
127129
import CSSParts from '@site/static/usage/v8/range/theming/css-shadow-parts/index.md';
128130

129131
<CSSParts />

0 commit comments

Comments
 (0)