diff --git a/docs/api/gallery-item.md b/docs/api/gallery-item.md
new file mode 100644
index 00000000000..f05e6303fe3
--- /dev/null
+++ b/docs/api/gallery-item.md
@@ -0,0 +1,46 @@
+---
+title: "ion-gallery-item"
+---
+
+import Props from '@ionic-internal/component-api/v9/gallery-item/props.md';
+import Events from '@ionic-internal/component-api/v9/gallery-item/events.md';
+import Methods from '@ionic-internal/component-api/v9/gallery-item/methods.md';
+import Parts from '@ionic-internal/component-api/v9/gallery-item/parts.md';
+import CustomProps from '@ionic-internal/component-api/v9/gallery-item/custom-props.mdx';
+import Slots from '@ionic-internal/component-api/v9/gallery-item/slots.md';
+
+
+ ion-gallery-item: Gallery Cell for Text, Images, and Cards
+
+
+
+import EncapsulationPill from '@components/page/api/EncapsulationPill';
+
+
+
+Gallery Item is a child component of [Gallery](./gallery.md). It wraps the content for a single cell of the grid. The content can be plain text or any element, including an `img`, a `figure` with a caption, or a [Card](./card.md).
+
+Gallery Items must be placed inside a Gallery, which arranges them and applies layout-specific styling to each item, such as a square aspect ratio in the uniform layout.
+
+Refer to the [Gallery](./gallery.md) documentation for more information.
+
+## Properties
+
+
+## Events
+
+
+## Methods
+
+
+## CSS Shadow Parts
+
+
+## CSS Custom Properties
+
+
+## Slots
+
diff --git a/docs/api/gallery.md b/docs/api/gallery.md
index 63fdebeab15..b22fc7d3035 100644
--- a/docs/api/gallery.md
+++ b/docs/api/gallery.md
@@ -21,7 +21,9 @@ import EncapsulationPill from '@components/page/api/EncapsulationPill';
-The gallery arranges images, cards, and other content in a responsive grid. It supports uniform and masonry layouts, configurable column counts (fixed or breakpoint-based), and multiple masonry ordering modes.
+The Gallery arranges images, cards, and other content in a responsive grid. It supports uniform and masonry layouts, configurable column counts (fixed or breakpoint-based), and multiple masonry ordering modes.
+
+Each [Gallery Item](./gallery-item.md) is a single cell of the grid and can contain plain text or any element, such as an `img`, a `figure` with a caption, or a [Card](./card.md).
## Basic Usage
@@ -41,10 +43,6 @@ import Uniform from '@site/static/usage/v9/gallery/uniform/index.md';
Masonry preserves each item's natural height and stacks items vertically within each column, creating a staggered layout with minimal gaps. Masonry supports two ordering modes: sequential and best fit.
-:::important
-Avoid adding margin to top-level items in a masonry layout, as it can cause incorrect item placement. To add spacing, wrap the content in a child element and apply margin to that wrapper instead.
-:::
-
### Sequential
Sequential is the default masonry ordering mode. Items are placed in DOM order, filling columns from left to right.
@@ -63,10 +61,10 @@ import MasonryBestFit from '@site/static/usage/v9/gallery/masonry-best-fit/index
### Images
-In masonry layouts, top-level `img` elements are given default styles to ensure consistent rendering. These styles make images fill their container while preserving their aspect ratio and keeping them centered.
+An `img` placed directly inside a Gallery Item is given default styles to ensure consistent rendering. These styles make images fill their cell while preserving their aspect ratio and keeping them centered.
:::tip
-Images wrapped in other elements (for example, inside a `figure`) do not inherit these defaults. Apply the same styles to the nested `img` if you want matching behavior, for example:
+Images wrapped in another element (for example, inside a `figure`) do not receive these defaults. Apply the same styles to the nested `img` if you want matching behavior, for example:
```css
figure img {
@@ -88,7 +86,7 @@ import Images from '@site/static/usage/v9/gallery/images/index.md';
Columns can be configured with the `columns` property using either a single number for a fixed column count, or a breakpoint map to change columns across screen sizes.
-If no value is provided, or if an invalid value is used, the gallery falls back to its default responsive column behavior. The default column counts by breakpoint are:
+If no value is provided, or if an invalid value is used, the Gallery falls back to its default responsive column behavior. The default column counts by breakpoint are:
| Breakpoint | Min Width | Default Columns |
| --- | --- | ---|
@@ -112,7 +110,11 @@ Whether provided as a single value or as a value inside a breakpoint map, each g
- A **string** can be any valid CSS [length-percentage](https://developer.mozilla.org/en-US/docs/Web/CSS/length-percentage) (such as `16px`, `1rem`, or `20%`), a math function (such as `calc(1rem + 8px)`), or a CSS variable (such as `var(--app-gallery-gap)`).
- A **number** is treated as a pixel value, so `16` is equivalent to `"16px"`.
-If no value is provided, or if an invalid value is used, the gallery falls back to its default gap value. The default value is `16px`.
+If no value is provided, or if an invalid value is used, the Gallery falls back to its default gap value. The default value is `16px`.
+
+:::tip
+Use the `gap` property to space items apart rather than CSS margins. Margins set on item content are reset so they cannot disrupt the layout calculations, so they will not produce the spacing you expect. Use `gap` for the space _between_ items, and `padding` on your content to inset it _within_ an item.
+:::
import Gap from '@site/static/usage/v9/gallery/gap/index.md';
diff --git a/plugins/docusaurus-plugin-ionic-component-api/index.js b/plugins/docusaurus-plugin-ionic-component-api/index.js
index b9cc29aa34f..416b416e349 100644
--- a/plugins/docusaurus-plugin-ionic-component-api/index.js
+++ b/plugins/docusaurus-plugin-ionic-component-api/index.js
@@ -57,7 +57,7 @@ module.exports = function (context, options) {
// TODO(FW-7097): Replace this with `latest` when v9 is released.
// Dev build based on the `next` branch of `ionic-framework`.
// This must be used to build the docs with the new components.
- let npmTag = '8.8.9-dev.11780493108.1d8e1a89';
+ let npmTag = '8.8.9-dev.11780945313.14080cb4';
if (currentVersion.banner === 'unreleased') {
npmTag = 'next';
} else if (currentVersion.path !== undefined) {
diff --git a/sidebars.js b/sidebars.js
index 93fd41dfb79..32b7f9593c6 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -338,7 +338,7 @@ module.exports = {
type: 'category',
label: 'Grids',
collapsed: false,
- items: ['api/grid', 'api/col', 'api/row', 'api/gallery'],
+ items: ['api/grid', 'api/col', 'api/row', 'api/gallery', 'api/gallery-item'],
},
{
type: 'category',
diff --git a/static/code/stackblitz/v9/angular/package-lock.json b/static/code/stackblitz/v9/angular/package-lock.json
index 335c0192276..c1077674837 100644
--- a/static/code/stackblitz/v9/angular/package-lock.json
+++ b/static/code/stackblitz/v9/angular/package-lock.json
@@ -14,8 +14,8 @@
"@angular/platform-browser": "^20.0.0",
"@angular/platform-browser-dynamic": "^20.0.0",
"@angular/router": "^20.0.0",
- "@ionic/angular": "8.7.11",
- "@ionic/core": "8.7.11",
+ "@ionic/angular": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "8.0.13",
"rxjs": "^7.8.1",
"tslib": "^2.5.0",
@@ -3217,12 +3217,12 @@
}
},
"node_modules/@ionic/angular": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-W2/mmrL/RTwlDrFyOmRukTz6x0DLl905XwVjIIMeGgu/IV3dbHbzHmFj6VwdhdxW13T9kLOrzLqPRri1KQtdCw==",
"license": "MIT",
"dependencies": {
- "@ionic/core": "8.7.11",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "^8.0.13",
"jsonc-parser": "^3.0.0",
"tslib": "^2.3.0"
@@ -3236,8 +3236,8 @@
}
},
"node_modules/@ionic/core": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==",
"license": "MIT",
"dependencies": {
diff --git a/static/code/stackblitz/v9/angular/package.json b/static/code/stackblitz/v9/angular/package.json
index ff788c8514e..a6a3e726715 100644
--- a/static/code/stackblitz/v9/angular/package.json
+++ b/static/code/stackblitz/v9/angular/package.json
@@ -15,8 +15,8 @@
"@angular/platform-browser": "^20.0.0",
"@angular/platform-browser-dynamic": "^20.0.0",
"@angular/router": "^20.0.0",
- "@ionic/angular": "8.7.11",
- "@ionic/core": "8.7.11",
+ "@ionic/angular": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "8.0.13",
"rxjs": "^7.8.1",
"tslib": "^2.5.0",
diff --git a/static/code/stackblitz/v9/html/package-lock.json b/static/code/stackblitz/v9/html/package-lock.json
index d054b91cf01..4c4f6d0afc6 100644
--- a/static/code/stackblitz/v9/html/package-lock.json
+++ b/static/code/stackblitz/v9/html/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "html-starter",
"dependencies": {
- "@ionic/core": "8.7.11",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "8.0.13"
},
"devDependencies": {
@@ -458,8 +458,8 @@
}
},
"node_modules/@ionic/core": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==",
"license": "MIT",
"dependencies": {
diff --git a/static/code/stackblitz/v9/html/package.json b/static/code/stackblitz/v9/html/package.json
index 22a2047e413..a517cb8860f 100644
--- a/static/code/stackblitz/v9/html/package.json
+++ b/static/code/stackblitz/v9/html/package.json
@@ -9,7 +9,7 @@
"start": "vite preview"
},
"dependencies": {
- "@ionic/core": "8.7.11",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "8.0.13"
},
"devDependencies": {
diff --git a/static/code/stackblitz/v9/react/package-lock.json b/static/code/stackblitz/v9/react/package-lock.json
index 5bdf823b03c..61192c2c161 100644
--- a/static/code/stackblitz/v9/react/package-lock.json
+++ b/static/code/stackblitz/v9/react/package-lock.json
@@ -8,8 +8,8 @@
"name": "vite-react-typescript",
"version": "0.1.0",
"dependencies": {
- "@ionic/react": "8.7.11",
- "@ionic/react-router": "8.7.11",
+ "@ionic/react": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/react-router": "8.8.9-dev.11780945313.14080cb4",
"@types/node": "^24.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
@@ -716,8 +716,8 @@
}
},
"node_modules/@ionic/core": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==",
"license": "MIT",
"dependencies": {
@@ -727,12 +727,12 @@
}
},
"node_modules/@ionic/react": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-h4j2SVRMgoxZBdr1bluKGrb0xNYEqEDcjHDuHsok669tKH3RnTMfD276zytfhFh3R8gIKWIqxb76NIsW/hfZcQ==",
"license": "MIT",
"dependencies": {
- "@ionic/core": "8.7.11",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"ionicons": "^8.0.13",
"tslib": "*"
},
@@ -742,12 +742,12 @@
}
},
"node_modules/@ionic/react-router": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-ZpJxx9WjprNngRaVEUvy1k5S22P0/BNfXNKpqqFci/JDJL5uPArLaevwXAuOzdIf+EknpG+34IIW6PBme5cPAQ==",
"license": "MIT",
"dependencies": {
- "@ionic/react": "8.7.11",
+ "@ionic/react": "8.8.9-dev.11780945313.14080cb4",
"tslib": "*"
},
"peerDependencies": {
diff --git a/static/code/stackblitz/v9/react/package.json b/static/code/stackblitz/v9/react/package.json
index 8b0deae5c16..b888a3f46de 100644
--- a/static/code/stackblitz/v9/react/package.json
+++ b/static/code/stackblitz/v9/react/package.json
@@ -3,8 +3,8 @@
"version": "0.1.0",
"private": true,
"dependencies": {
- "@ionic/react": "8.7.11",
- "@ionic/react-router": "8.7.11",
+ "@ionic/react": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/react-router": "8.8.9-dev.11780945313.14080cb4",
"@types/node": "^24.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
diff --git a/static/code/stackblitz/v9/vue/package-lock.json b/static/code/stackblitz/v9/vue/package-lock.json
index ebf2a96fd89..eafa585bac6 100644
--- a/static/code/stackblitz/v9/vue/package-lock.json
+++ b/static/code/stackblitz/v9/vue/package-lock.json
@@ -8,8 +8,8 @@
"name": "vite-vue-starter",
"version": "0.0.0",
"dependencies": {
- "@ionic/vue": "8.7.11",
- "@ionic/vue-router": "8.7.11",
+ "@ionic/vue": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/vue-router": "8.8.9-dev.11780945313.14080cb4",
"vue": "^3.2.25",
"vue-router": "4.6.3"
},
@@ -509,8 +509,8 @@
}
},
"node_modules/@ionic/core": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==",
"license": "MIT",
"dependencies": {
@@ -520,23 +520,23 @@
}
},
"node_modules/@ionic/vue": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-HDEcjhxWfimVQxvXfghrqlAWpXnJvcUDTIVE2Mvq8ul+s7gL/OZCpXTAODJOfFCBAGJ0o9QXyC7OPjyN4UbO8Q==",
"license": "MIT",
"dependencies": {
- "@ionic/core": "8.7.11",
+ "@ionic/core": "8.8.9-dev.11780945313.14080cb4",
"@stencil/vue-output-target": "0.10.7",
"ionicons": "^8.0.13"
}
},
"node_modules/@ionic/vue-router": {
- "version": "8.7.11",
- "resolved": "https://registry.npmjs.org/@ionic/vue-router/-/vue-router-8.7.11.tgz",
+ "version": "8.8.9-dev.11780945313.14080cb4",
+ "resolved": "https://registry.npmjs.org/@ionic/vue-router/-/vue-router-8.8.9-dev.11780945313.14080cb4.tgz",
"integrity": "sha512-6k/bWLORJucLIPYqcrXnSs3KEI69qaWo6V4bGAEOSkt9dISdTy65gafi4gtFFyV+n81LIU00WnajJYLadDG3Cg==",
"license": "MIT",
"dependencies": {
- "@ionic/vue": "8.7.11"
+ "@ionic/vue": "8.8.9-dev.11780945313.14080cb4"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
diff --git a/static/code/stackblitz/v9/vue/package.json b/static/code/stackblitz/v9/vue/package.json
index db6efac6dda..d3ebf4366de 100644
--- a/static/code/stackblitz/v9/vue/package.json
+++ b/static/code/stackblitz/v9/vue/package.json
@@ -8,8 +8,8 @@
"preview": "vite preview"
},
"dependencies": {
- "@ionic/vue": "8.7.11",
- "@ionic/vue-router": "8.7.11",
+ "@ionic/vue": "8.8.9-dev.11780945313.14080cb4",
+ "@ionic/vue-router": "8.8.9-dev.11780945313.14080cb4",
"vue": "^3.2.25",
"vue-router": "4.6.3"
},
diff --git a/static/usage/v9/gallery/basic/angular/example_component_html.md b/static/usage/v9/gallery/basic/angular/example_component_html.md
index 7e51f617d3f..c342f364fd9 100644
--- a/static/usage/v9/gallery/basic/angular/example_component_html.md
+++ b/static/usage/v9/gallery/basic/angular/example_component_html.md
@@ -6,18 +6,42 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
```
diff --git a/static/usage/v9/gallery/basic/angular/example_component_ts.md b/static/usage/v9/gallery/basic/angular/example_component_ts.md
index c73d7da46c8..b2c5a93b91a 100644
--- a/static/usage/v9/gallery/basic/angular/example_component_ts.md
+++ b/static/usage/v9/gallery/basic/angular/example_component_ts.md
@@ -1,12 +1,12 @@
```ts
import { Component } from '@angular/core';
-import { IonContent, IonGallery, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
+import { IonContent, IonGallery, IonGalleryItem, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
@Component({
selector: 'app-example',
templateUrl: 'example.component.html',
styleUrls: ['example.component.css'],
- imports: [IonContent, IonGallery, IonHeader, IonTitle, IonToolbar],
+ imports: [IonContent, IonGallery, IonGalleryItem, IonHeader, IonTitle, IonToolbar],
})
export class ExampleComponent {}
```
diff --git a/static/usage/v9/gallery/basic/demo.html b/static/usage/v9/gallery/basic/demo.html
index b289722cb1d..2ab405fcdda 100644
--- a/static/usage/v9/gallery/basic/demo.html
+++ b/static/usage/v9/gallery/basic/demo.html
@@ -6,8 +6,14 @@
Gallery
-
-
+
+
diff --git a/static/usage/v9/gallery/columns/javascript.md b/static/usage/v9/gallery/columns/javascript.md
index 65e864756fc..a6c109d5d43 100644
--- a/static/usage/v9/gallery/columns/javascript.md
+++ b/static/usage/v9/gallery/columns/javascript.md
@@ -1,17 +1,17 @@
```html
-