From f4ea0044310bd0eb8baa6c9dce930a9e73d7d902 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 19 May 2026 16:23:07 -0400 Subject: [PATCH 1/7] chore(): use dev build --- .../index.js | 2 +- .../stackblitz/v9/angular/package-lock.json | 14 ++++++------- .../code/stackblitz/v9/angular/package.json | 4 ++-- .../code/stackblitz/v9/html/package-lock.json | 6 +++--- static/code/stackblitz/v9/html/package.json | 2 +- .../stackblitz/v9/react/package-lock.json | 20 +++++++++---------- static/code/stackblitz/v9/react/package.json | 4 ++-- .../code/stackblitz/v9/vue/package-lock.json | 20 +++++++++---------- static/code/stackblitz/v9/vue/package.json | 4 ++-- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/plugins/docusaurus-plugin-ionic-component-api/index.js b/plugins/docusaurus-plugin-ionic-component-api/index.js index 8d9acb8c144..69ae8134989 100644 --- a/plugins/docusaurus-plugin-ionic-component-api/index.js +++ b/plugins/docusaurus-plugin-ionic-component-api/index.js @@ -54,7 +54,7 @@ module.exports = function (context, options) { await generateMarkdownForVersion(version, npmTag, context.i18n.currentLocale, false); } - let npmTag = 'latest'; + let npmTag = '8.8.7-dev.11779221548.1d38f927'; if (currentVersion.banner === 'unreleased') { npmTag = 'next'; } else if (currentVersion.path !== undefined) { diff --git a/static/code/stackblitz/v9/angular/package-lock.json b/static/code/stackblitz/v9/angular/package-lock.json index 335c0192276..6054d38649f 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.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.7-dev.11779221548.1d38f927", "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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.8.7-dev.11779221548.1d38f927.tgz", "integrity": "sha512-W2/mmrL/RTwlDrFyOmRukTz6x0DLl905XwVjIIMeGgu/IV3dbHbzHmFj6VwdhdxW13T9kLOrzLqPRri1KQtdCw==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.8.7-dev.11779221548.1d38f927", "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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.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..de6206d75dc 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.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.7-dev.11779221548.1d38f927", "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..e0efc79a19d 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.7-dev.11779221548.1d38f927", "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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.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..cea9a7d7f70 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.7-dev.11779221548.1d38f927", "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..cd98ea12278 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.7-dev.11779221548.1d38f927", + "@ionic/react-router": "8.8.7-dev.11779221548.1d38f927", "@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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.7-dev.11779221548.1d38f927.tgz", "integrity": "sha512-h4j2SVRMgoxZBdr1bluKGrb0xNYEqEDcjHDuHsok669tKH3RnTMfD276zytfhFh3R8gIKWIqxb76NIsW/hfZcQ==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.8.7-dev.11779221548.1d38f927", "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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.8.7-dev.11779221548.1d38f927.tgz", "integrity": "sha512-ZpJxx9WjprNngRaVEUvy1k5S22P0/BNfXNKpqqFci/JDJL5uPArLaevwXAuOzdIf+EknpG+34IIW6PBme5cPAQ==", "license": "MIT", "dependencies": { - "@ionic/react": "8.7.11", + "@ionic/react": "8.8.7-dev.11779221548.1d38f927", "tslib": "*" }, "peerDependencies": { diff --git a/static/code/stackblitz/v9/react/package.json b/static/code/stackblitz/v9/react/package.json index 8b0deae5c16..358e6f8e985 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.7-dev.11779221548.1d38f927", + "@ionic/react-router": "8.8.7-dev.11779221548.1d38f927", "@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..38add583736 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.7-dev.11779221548.1d38f927", + "@ionic/vue-router": "8.8.7-dev.11779221548.1d38f927", "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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.7-dev.11779221548.1d38f927.tgz", "integrity": "sha512-HDEcjhxWfimVQxvXfghrqlAWpXnJvcUDTIVE2Mvq8ul+s7gL/OZCpXTAODJOfFCBAGJ0o9QXyC7OPjyN4UbO8Q==", "license": "MIT", "dependencies": { - "@ionic/core": "8.7.11", + "@ionic/core": "8.8.7-dev.11779221548.1d38f927", "@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.7-dev.11779221548.1d38f927", + "resolved": "https://registry.npmjs.org/@ionic/vue-router/-/vue-router-8.8.7-dev.11779221548.1d38f927.tgz", "integrity": "sha512-6k/bWLORJucLIPYqcrXnSs3KEI69qaWo6V4bGAEOSkt9dISdTy65gafi4gtFFyV+n81LIU00WnajJYLadDG3Cg==", "license": "MIT", "dependencies": { - "@ionic/vue": "8.7.11" + "@ionic/vue": "8.8.7-dev.11779221548.1d38f927" } }, "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..cfd3214c9e6 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.7-dev.11779221548.1d38f927", + "@ionic/vue-router": "8.8.7-dev.11779221548.1d38f927", "vue": "^3.2.25", "vue-router": "4.6.3" }, From ec02fee4b2082a63cf6ce55e9fa61ff612ecc09d Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 19 May 2026 16:37:11 -0400 Subject: [PATCH 2/7] docs(guide): add ion-select-option to guides mentioning innerHTML --- docs/developing/config.md | 2 +- docs/techniques/security.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/developing/config.md b/docs/developing/config.md index 2fdef3f0e48..bc2db8570fe 100644 --- a/docs/developing/config.md +++ b/docs/developing/config.md @@ -180,7 +180,7 @@ Below are the config options that Ionic uses. | `backButtonDefaultHref` | `string` | Overrides the default value for the `defaultHref` property in all `` components. | | `backButtonIcon` | `string` | Overrides the default icon in all `` components. | | `backButtonText` | `string` | Overrides the default text in all `` components. | -| `innerHTMLTemplatesEnabled` | `boolean` | Relevant Components: `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, `ion-toast`. If `true`, content passed to the relevant components will be parsed as HTML instead of plaintext. Defaults to `false`. | +| `innerHTMLTemplatesEnabled` | `boolean` | Relevant Components: `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, `ion-select-option`, `ion-toast`. If `true`, content passed to the relevant components will be parsed as HTML instead of plaintext. Defaults to `false`. | | `hardwareBackButton` | `boolean` | If `true`, Ionic will respond to the hardware back button in an Android device. | | `infiniteLoadingSpinner` | `SpinnerTypes` | Overrides the default spinner type in all `` components. | | `loadingEnter` | `AnimationBuilder` | Provides a custom enter animation for all `ion-loading`, overriding the default "animation". | diff --git a/docs/techniques/security.md b/docs/techniques/security.md index 03268c4363a..e9886f488f2 100644 --- a/docs/techniques/security.md +++ b/docs/techniques/security.md @@ -61,7 +61,7 @@ To learn more about the security recommendations for binding to directives such ## Enabling Custom HTML Parsing via `innerHTML` -`ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, and `ion-toast` can accept custom HTML as strings for certain properties. These strings are added to the DOM using `innerHTML` and must be properly sanitized by the developer. This behavior is disabled by default which means values passed to the affected components will always be interpreted as plaintext. Developers can enable this custom HTML behavior by setting `innerHTMLTemplatesEnabled: true` in the [IonicConfig](../developing/config#ionicconfig). +`ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, `ion-select-option`, and `ion-toast` can accept custom HTML as strings for certain properties. These strings are added to the DOM using `innerHTML` and must be properly sanitized by the developer. This behavior is disabled by default which means values passed to the affected components will always be interpreted as plaintext. Developers can enable this custom HTML behavior by setting `innerHTMLTemplatesEnabled: true` in the [IonicConfig](../developing/config#ionicconfig). ## Ejecting from the built-in sanitizer From 004228d81da46e5d7cfe24a65f5633efd1fe5f7f Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Tue, 19 May 2026 17:58:15 -0400 Subject: [PATCH 3/7] feat(stackblitz): add support for passing IonicConfig to StackBlitz --- docs/developing/config.md | 2 +- src/components/global/Playground/README.md | 8 +++ src/components/global/Playground/index.tsx | 16 ++++- .../global/Playground/playground.types.ts | 6 ++ .../global/Playground/stackblitz.utils.ts | 69 +++++++++++++++---- 5 files changed, 86 insertions(+), 15 deletions(-) diff --git a/docs/developing/config.md b/docs/developing/config.md index bc2db8570fe..494c55d64cb 100644 --- a/docs/developing/config.md +++ b/docs/developing/config.md @@ -180,7 +180,7 @@ Below are the config options that Ionic uses. | `backButtonDefaultHref` | `string` | Overrides the default value for the `defaultHref` property in all `` components. | | `backButtonIcon` | `string` | Overrides the default icon in all `` components. | | `backButtonText` | `string` | Overrides the default text in all `` components. | -| `innerHTMLTemplatesEnabled` | `boolean` | Relevant Components: `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, `ion-select-option`, `ion-toast`. If `true`, content passed to the relevant components will be parsed as HTML instead of plaintext. Defaults to `false`. | +| `innerHTMLTemplatesEnabled` | `boolean` | Relevant Components: `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, `ion-select-option`, `ion-toast`. If `true`, content passed to the relevant components will be parsed as HTML instead of plaintext. Defaults to `false`. | | `hardwareBackButton` | `boolean` | If `true`, Ionic will respond to the hardware back button in an Android device. | | `infiniteLoadingSpinner` | `SpinnerTypes` | Overrides the default spinner type in all `` components. | | `loadingEnter` | `AnimationBuilder` | Provides a custom enter animation for all `ion-loading`, overriding the default "animation". | diff --git a/src/components/global/Playground/README.md b/src/components/global/Playground/README.md index 22c475fafe8..99aac9d13eb 100644 --- a/src/components/global/Playground/README.md +++ b/src/components/global/Playground/README.md @@ -71,3 +71,11 @@ To opt-out of this behavior, set `includeIonContent={false}` to disable this wra ```tsx ``` + +## Ionic Config + +Pass an [IonicConfig](/docs/developing/config#ionicconfig) object so generated StackBlitz projects bootstrap with the same settings. This is merged with the active preview `mode` when opening the editor. Only string, number, and boolean values are injected into generated code: + +```tsx + +``` diff --git a/src/components/global/Playground/index.tsx b/src/components/global/Playground/index.tsx index 69c1bd2b00e..56b9f12cc0b 100644 --- a/src/components/global/Playground/index.tsx +++ b/src/components/global/Playground/index.tsx @@ -4,7 +4,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl'; import './playground.css'; import { EditorOptions, openAngularEditor, openHtmlEditor, openReactEditor, openVueEditor } from './stackblitz.utils'; import { useColorMode } from '@docusaurus/theme-common'; -import { ConsoleItem, Mode, UsageTarget } from './playground.types'; +import { ConsoleItem, IonicConfig, Mode, UsageTarget } from './playground.types'; import Tippy from '@tippyjs/react'; import 'tippy.js/dist/tippy.css'; @@ -120,8 +120,14 @@ interface UsageTargetOptions { * @param description Optional description of the generated playground example. Specify to customize the StackBlitz description. * @param src The absolute path to the playground demo. For example: `/usage/button/basic/demo.html` * @param size The height of the playground. Supports `xsmall`, `small`, `medium`, `large`, 'xlarge' or any string value. + * @param mode Restricts the playground to a single specified mode. Acceptable values are: `ios` or `md`. * @param devicePreview `true` if the playground example should render in a device frame (iOS/MD). * @param showConsole `true` if the playground should render a console UI that reflects console logs, warnings, and errors. + * @param includeIonContent Whether to include the `ion-app` and `ion-content` elements in the generated StackBlitz example. + * @param ionicConfig Ionic config values to inject into generated StackBlitz examples. + * @param version The major version of Ionic to use in the generated StackBlitz example. + * @param defaultFramework The framework to select by default when no user preference is stored. + * @returns The generated StackBlitz example. */ export default function Playground({ code, @@ -133,6 +139,7 @@ export default function Playground({ devicePreview, showConsole, includeIonContent = true, + ionicConfig, version, defaultFramework, }: { @@ -150,6 +157,12 @@ export default function Playground({ devicePreview?: boolean; showConsole?: boolean; includeIonContent: boolean; + /** + * Ionic config values to inject into generated StackBlitz examples. For + * example: `{ innerHTMLTemplatesEnabled: true }`. Merges with the active + * preview `mode` when opening the editor. + */ + ionicConfig?: IonicConfig; /** * The major version of Ionic to use in the generated StackBlitz examples. * This will also load assets for StackBlitz from the specified version directory. @@ -551,6 +564,7 @@ export default function Playground({ title, description, includeIonContent, + ionicConfig, mode: isIOS ? 'ios' : 'md', version, }; diff --git a/src/components/global/Playground/playground.types.ts b/src/components/global/Playground/playground.types.ts index c6a14b8e585..9e69fb032dd 100644 --- a/src/components/global/Playground/playground.types.ts +++ b/src/components/global/Playground/playground.types.ts @@ -14,3 +14,9 @@ export interface ConsoleItem { type: 'log' | 'warning' | 'error'; message: string; } + +/** + * Ionic app configuration. See [IonicConfig](/docs/developing/config#ionicconfig). + * Playground only injects serializable values (string, number, boolean) into StackBlitz. + */ +export type IonicConfig = Record; diff --git a/src/components/global/Playground/stackblitz.utils.ts b/src/components/global/Playground/stackblitz.utils.ts index d04378f74f7..651714eaded 100644 --- a/src/components/global/Playground/stackblitz.utils.ts +++ b/src/components/global/Playground/stackblitz.utils.ts @@ -1,5 +1,7 @@ import sdk from '@stackblitz/sdk'; +import type { IonicConfig } from './playground.types'; + // The default title to use for StackBlitz examples (when not overwritten) const DEFAULT_EDITOR_TITLE = 'Ionic Docs Example'; // The default description to use for StackBlitz examples (when not overwritten) @@ -38,9 +40,46 @@ export interface EditorOptions { */ mode?: string; + /** + * Ionic config values to inject into the generated StackBlitz bootstrap. + */ + ionicConfig?: IonicConfig; + + /** + * The major version of Ionic to use in the generated StackBlitz example. + * For example: `9` for Ionic 9. + */ version?: string; } +/** + * Formats the Ionic config object for the generated StackBlitz example. + * @param options The editor options. + * @param indent The number of spaces to indent the formatted Ionic config object. + * @returns The formatted Ionic config object. + */ +const getFormattedIonicConfig = (options?: EditorOptions, indent = 0) => { + const config: IonicConfig = { + ...options?.ionicConfig, + ...(options?.mode ? { mode: options.mode } : {}), + }; + + const entries = Object.entries(config).filter( + (entry): entry is [string, boolean | number | string] => + typeof entry[1] === 'boolean' || typeof entry[1] === 'number' || typeof entry[1] === 'string' + ); + + if (entries.length === 0) { + return '{}'; + } + + const pad = ' '.repeat(indent); + const propertyPad = ' '.repeat(indent + 2); + const lines = entries.map(([key, value]) => `${propertyPad}${JSON.stringify(key)}: ${JSON.stringify(value)}`); + + return `{\n${lines.join(',\n')}\n${pad}}`; +}; + const loadSourceFiles = async (files: string[], version: string) => { const versionDir = `v${version}`; const sourceFiles = await Promise.all(files.map((f) => fetch(`/docs/code/stackblitz/${versionDir}/${f}`))); @@ -82,15 +121,15 @@ const openHtmlEditor = async (code: string, options?: EditorOptions) => { ...options?.files, }; + const ionicConfig = getFormattedIonicConfig(options, 6); + files[indexHtml] = defaultFiles[1].replace(/{{ TEMPLATE }}/g, code).replace( '', ` ` @@ -159,13 +198,18 @@ const openAngularEditor = async (code: string, options?: EditorOptions) => { ...options?.files, }; + const ionicConfig = getFormattedIonicConfig(options, 4); + if (options?.version === '6') { files[main] = files[main].replace( 'importProvidersFrom(IonicModule.forRoot({ }))', - `importProvidersFrom(IonicModule.forRoot({ mode: '${options?.mode}' }))` + `importProvidersFrom(IonicModule.forRoot(${ionicConfig}))` ); } else { - files[main] = files[main].replace('provideIonicAngular()', `provideIonicAngular({ mode: '${options?.mode}' })`); + files[main] = files[main].replace( + /provideIonicAngular\(\s*(\{[^}]*\})?\s*\)/s, + `provideIonicAngular(${ionicConfig})` + ); } sdk.openProject({ @@ -221,7 +265,9 @@ const openReactEditor = async (code: string, options?: EditorOptions) => { }`, }; - files[appTsx] = files[appTsx].replace('setupIonicReact()', `setupIonicReact({ mode: '${options?.mode}' })`); + const ionicConfig = getFormattedIonicConfig(options); + + files[appTsx] = files[appTsx].replace(/setupIonicReact\(\s*(\{[^}]*\})?\s*\)/s, `setupIonicReact(${ionicConfig})`); sdk.openProject({ template: 'node', @@ -274,12 +320,9 @@ const openVueEditor = async (code: string, options?: EditorOptions) => { }`, }; - files[mainTs] = files[mainTs].replace( - '.use(IonicVue)', - `.use(IonicVue, { - mode: '${options?.mode}' -})` - ); + const ionicConfig = getFormattedIonicConfig(options); + + files[mainTs] = files[mainTs].replace(/\.use\(IonicVue(?:,\s*\{[^}]*\})?\)/s, `.use(IonicVue, ${ionicConfig})`); /** * We have to use StackBlitz web containers here (node template), due From 6f73533af7fa7a217fadd77dec3133f00a77ffbf Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Wed, 20 May 2026 11:46:47 -0400 Subject: [PATCH 4/7] docs(select): add rich content options playground --- docs/api/select.md | 8 + .../angular/example_component_html.md | 39 +++++ .../angular/example_component_ts.md | 30 ++++ .../angular/global_css.md | 47 ++++++ .../v9/select/rich-content-options/demo.html | 148 ++++++++++++++++++ .../v9/select/rich-content-options/index.md | 42 +++++ .../javascript/index_html.md | 112 +++++++++++++ .../javascript/index_ts.md | 46 ++++++ .../rich-content-options/react/main_css.md | 47 ++++++ .../rich-content-options/react/main_tsx.md | 71 +++++++++ .../v9/select/rich-content-options/vue.md | 104 ++++++++++++ 11 files changed, 694 insertions(+) create mode 100644 static/usage/v9/select/rich-content-options/angular/example_component_html.md create mode 100644 static/usage/v9/select/rich-content-options/angular/example_component_ts.md create mode 100644 static/usage/v9/select/rich-content-options/angular/global_css.md create mode 100644 static/usage/v9/select/rich-content-options/demo.html create mode 100644 static/usage/v9/select/rich-content-options/index.md create mode 100644 static/usage/v9/select/rich-content-options/javascript/index_html.md create mode 100644 static/usage/v9/select/rich-content-options/javascript/index_ts.md create mode 100644 static/usage/v9/select/rich-content-options/react/main_css.md create mode 100644 static/usage/v9/select/rich-content-options/react/main_tsx.md create mode 100644 static/usage/v9/select/rich-content-options/vue.md diff --git a/docs/api/select.md b/docs/api/select.md index ca3ef27b1be..918a33c1eb9 100644 --- a/docs/api/select.md +++ b/docs/api/select.md @@ -201,6 +201,14 @@ import StartEndSlots from '@site/static/usage/v9/select/start-end-slots/index.md +## Rich Content Options + +TODO + +import RichContentOptions from '@site/static/usage/v9/select/rich-content-options/index.md'; + + + ## Customization There are two units that make up the Select component and each need to be styled separately. The `ion-select` element is represented on the view by the selected value(s), or placeholder if there is none, and dropdown icon. The interface, which is defined in the [Interfaces](#interfaces) section above, is the dialog that opens when clicking on the `ion-select`. The interface contains all of the options defined by adding `ion-select-option` elements. The following sections will go over the differences between styling these. diff --git a/static/usage/v9/select/rich-content-options/angular/example_component_html.md b/static/usage/v9/select/rich-content-options/angular/example_component_html.md new file mode 100644 index 00000000000..f8431fb7164 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/angular/example_component_html.md @@ -0,0 +1,39 @@ +```html + + @for (selectInterface of selectInterfaces; track selectInterface) { + + + + + Flight + 2h 15m · Nonstop + $279 + + + + Bus + 6h 40m · 1 transfer + $39 + + + + Rental Car + 5h 10m · Flexible route + $92 + + + + Train + 4h 55m · Direct + $64 + + + + } + +``` diff --git a/static/usage/v9/select/rich-content-options/angular/example_component_ts.md b/static/usage/v9/select/rich-content-options/angular/example_component_ts.md new file mode 100644 index 00000000000..05f1327a5d9 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/angular/example_component_ts.md @@ -0,0 +1,30 @@ +```ts +import { Component } from '@angular/core'; +import { IonBadge, IonIcon, IonItem, IonList, IonSelect, IonSelectOption } from '@ionic/angular/standalone'; +import { addIcons } from 'ionicons'; +import { airplane, bus, car, train } from 'ionicons/icons'; + +@Component({ + selector: 'app-example', + templateUrl: 'example.component.html', + imports: [IonBadge, IonIcon, IonItem, IonList, IonSelect, IonSelectOption], +}) +export class ExampleComponent { + readonly selectInterfaces = ['alert', 'action-sheet', 'modal', 'popover']; + + /* The interfaceOptions property is for demonstration purposes only. */ + /* It is not required for the rich options to work. */ + readonly interfaceOptions = { header: 'Travel mode' }; + + constructor() { + addIcons({ airplane, bus, car, train }); + } + + formatInterfaceLabel(selectInterface: string): string { + return selectInterface + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + } +} +``` diff --git a/static/usage/v9/select/rich-content-options/angular/global_css.md b/static/usage/v9/select/rich-content-options/angular/global_css.md new file mode 100644 index 00000000000..2d733405508 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/angular/global_css.md @@ -0,0 +1,47 @@ +```css +/* These styles are for demonstration purposes only. */ +/* They are not required for the rich options to work. */ + +/* Alert Interface */ +ion-alert.select-alert { + --min-width: 350px; +} + +/* Action Sheet Interface */ +.action-sheet-button-label { + flex: 1 1 auto; + text-align: start; +} + +/* Modal, Popover Interfaces */ +ion-popover.select-popover ion-list ion-radio.in-item::part(label), +ion-modal.select-modal ion-list ion-radio.in-item::part(label) { + margin-top: 10px; + margin-bottom: 10px; +} + +/* All Interfaces */ +.alert-radio-label-text, +.action-sheet-button-label-text, +.select-option-label-text, +.select-option-content { + display: flex; + flex-direction: column; + gap: 2px; +} + +/* Custom Select Option Title */ +.select-option-content .option-title { + font-size: 1rem; + font-weight: 600; + line-height: initial; +} + +/* Custom Select Option Subtitle */ +.select-option-content .option-subtitle { + display: block; + font-size: 0.8125rem; + font-weight: 500; + line-height: initial; +} +``` diff --git a/static/usage/v9/select/rich-content-options/demo.html b/static/usage/v9/select/rich-content-options/demo.html new file mode 100644 index 00000000000..943df6ab16a --- /dev/null +++ b/static/usage/v9/select/rich-content-options/demo.html @@ -0,0 +1,148 @@ + + + + + + Select - Rich Content Option + + + + + + + + + + + + +
+ + + +
+
+
+ + + + diff --git a/static/usage/v9/select/rich-content-options/index.md b/static/usage/v9/select/rich-content-options/index.md new file mode 100644 index 00000000000..b4013a0eb4a --- /dev/null +++ b/static/usage/v9/select/rich-content-options/index.md @@ -0,0 +1,42 @@ +import Playground from '@site/src/components/global/Playground'; + +import javascript_index_html from './javascript/index_html.md'; +import javascript_index_ts from './javascript/index_ts.md'; + +import react_main_tsx from './react/main_tsx.md'; +import react_main_css from './react/main_css.md'; + +import vue from './vue.md'; + +import angular_example_component_html from './angular/example_component_html.md'; +import angular_example_component_ts from './angular/example_component_ts.md'; +import angular_global_css from './angular/global_css.md'; + + diff --git a/static/usage/v9/select/rich-content-options/javascript/index_html.md b/static/usage/v9/select/rich-content-options/javascript/index_html.md new file mode 100644 index 00000000000..3c7431c5fc9 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/javascript/index_html.md @@ -0,0 +1,112 @@ +```html + + + + + + + +``` diff --git a/static/usage/v9/select/rich-content-options/javascript/index_ts.md b/static/usage/v9/select/rich-content-options/javascript/index_ts.md new file mode 100644 index 00000000000..01ce02c278a --- /dev/null +++ b/static/usage/v9/select/rich-content-options/javascript/index_ts.md @@ -0,0 +1,46 @@ +```ts +import { defineCustomElements } from '@ionic/core/loader'; + +import { addIcons } from 'ionicons'; +import { airplane, bus, car, train } from 'ionicons/icons'; + +/* Core CSS required for Ionic components to work properly */ +import '@ionic/core/css/core.css'; + +/* Basic CSS for apps built with Ionic */ +import '@ionic/core/css/normalize.css'; +import '@ionic/core/css/structure.css'; +import '@ionic/core/css/typography.css'; + +/* Optional CSS utils that can be commented out */ +import '@ionic/core/css/padding.css'; +import '@ionic/core/css/float-elements.css'; +import '@ionic/core/css/text-alignment.css'; +import '@ionic/core/css/text-transformation.css'; +import '@ionic/core/css/flex-utils.css'; +import '@ionic/core/css/display.css'; + +/** + * Ionic Dark Palette + * ----------------------------------------------------- + * For more information, please see: + * https://ionicframework.com/docs/theming/dark-mode + */ + +// import '@ionic/core/css/palettes/dark.always.css'; +// import '@ionic/core/css/palettes/dark.class.css'; +import '@ionic/core/css/palettes/dark.system.css'; + +/* Theme variables */ +import './theme/variables.css'; + +/** + * On Ionicons 7.2+ these icons + * get mapped to a kebab-case key. + * Alternatively, developers can do: + * addIcons({ 'airplane': airplane, 'bus': bus, 'car': car, 'train', train }); + */ +addIcons({ airplane, bus, car, train }); + +defineCustomElements(); +``` diff --git a/static/usage/v9/select/rich-content-options/react/main_css.md b/static/usage/v9/select/rich-content-options/react/main_css.md new file mode 100644 index 00000000000..2d733405508 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/react/main_css.md @@ -0,0 +1,47 @@ +```css +/* These styles are for demonstration purposes only. */ +/* They are not required for the rich options to work. */ + +/* Alert Interface */ +ion-alert.select-alert { + --min-width: 350px; +} + +/* Action Sheet Interface */ +.action-sheet-button-label { + flex: 1 1 auto; + text-align: start; +} + +/* Modal, Popover Interfaces */ +ion-popover.select-popover ion-list ion-radio.in-item::part(label), +ion-modal.select-modal ion-list ion-radio.in-item::part(label) { + margin-top: 10px; + margin-bottom: 10px; +} + +/* All Interfaces */ +.alert-radio-label-text, +.action-sheet-button-label-text, +.select-option-label-text, +.select-option-content { + display: flex; + flex-direction: column; + gap: 2px; +} + +/* Custom Select Option Title */ +.select-option-content .option-title { + font-size: 1rem; + font-weight: 600; + line-height: initial; +} + +/* Custom Select Option Subtitle */ +.select-option-content .option-subtitle { + display: block; + font-size: 0.8125rem; + font-weight: 500; + line-height: initial; +} +``` diff --git a/static/usage/v9/select/rich-content-options/react/main_tsx.md b/static/usage/v9/select/rich-content-options/react/main_tsx.md new file mode 100644 index 00000000000..1497ab84dac --- /dev/null +++ b/static/usage/v9/select/rich-content-options/react/main_tsx.md @@ -0,0 +1,71 @@ +```tsx +import React from 'react'; +import { SelectInterface } from '@ionic/core'; +import { IonBadge, IonIcon, IonItem, IonList, IonSelect, IonSelectOption } from '@ionic/react'; +import { airplane, bus, car, train } from 'ionicons/icons'; + +import './main.css'; + +const selectInterfaces: SelectInterface[] = ['alert', 'action-sheet', 'modal', 'popover']; + +/* The interfaceOptions property is for demonstration purposes only. */ +/* It is not required for the rich options to work. */ +const interfaceOptions = { header: 'Travel mode' }; + +const formatInterfaceLabel = (selectInterface: string) => + selectInterface + .split('-') + .map((word) => word.charAt(0).toUpperCase() + word.slice(1)) + .join(' '); + +function Example() { + return ( + + {selectInterfaces.map((selectInterface) => ( + + + + + + + + + + + + + ))} + + ); +} +export default Example; +``` diff --git a/static/usage/v9/select/rich-content-options/vue.md b/static/usage/v9/select/rich-content-options/vue.md new file mode 100644 index 00000000000..4c109a47dd0 --- /dev/null +++ b/static/usage/v9/select/rich-content-options/vue.md @@ -0,0 +1,104 @@ +```vue + + + + + +``` From ca1f07f58429a1a5193abaee3e7e3343ec2a6e0a Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Wed, 20 May 2026 12:20:04 -0400 Subject: [PATCH 5/7] style: add comment on dev build --- plugins/docusaurus-plugin-ionic-component-api/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/docusaurus-plugin-ionic-component-api/index.js b/plugins/docusaurus-plugin-ionic-component-api/index.js index 69ae8134989..dd0d36c45f5 100644 --- a/plugins/docusaurus-plugin-ionic-component-api/index.js +++ b/plugins/docusaurus-plugin-ionic-component-api/index.js @@ -54,6 +54,8 @@ module.exports = function (context, options) { await generateMarkdownForVersion(version, npmTag, context.i18n.currentLocale, false); } + // 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.7-dev.11779221548.1d38f927'; if (currentVersion.banner === 'unreleased') { npmTag = 'next'; From 3396381f4898f9e4d153e9069bce89facae2e845 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Wed, 20 May 2026 14:16:03 -0400 Subject: [PATCH 6/7] docs(select): add section description to Rich Content Options --- docs/api/select.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/api/select.md b/docs/api/select.md index 918a33c1eb9..c71914c22e0 100644 --- a/docs/api/select.md +++ b/docs/api/select.md @@ -203,7 +203,13 @@ import StartEndSlots from '@site/static/usage/v9/select/start-end-slots/index.md ## Rich Content Options -TODO +:::important +Rich content in select options is disabled by default. Set [`innerHTMLTemplatesEnabled`](/docs/developing/config#ionicconfig) to `true` in your [global Ionic config](/docs/developing/config#global-config). Markup inside options is treated as plain text when it is disabled. Refer to [Security](/docs/techniques/security.md) for sanitization guidance when enabling custom HTML. +::: + +In addition to single text labels, [Select Options](./select-option.md) can include HTML rich content in the select interface. Elements added inside of an option without a named slot will go into the default label. The `start` and `end` slots will place elements on either side of the default slot. The `description` attribute can be used for additional supporting text displayed under the label. + +This is separate from [Start and End Slots](#start-and-end-slots) on `ion-select`, which decorate the closed field. The rich content options display in the interface after opening the select. import RichContentOptions from '@site/static/usage/v9/select/rich-content-options/index.md'; From 6848c26cb89cdde32ce89d3d3214afb2c2b320c4 Mon Sep 17 00:00:00 2001 From: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> Date: Fri, 22 May 2026 13:19:44 -0400 Subject: [PATCH 7/7] chore(): use latest dev build --- .../index.js | 2 +- .../stackblitz/v9/angular/package-lock.json | 14 ++++++------- .../code/stackblitz/v9/angular/package.json | 4 ++-- .../code/stackblitz/v9/html/package-lock.json | 6 +++--- static/code/stackblitz/v9/html/package.json | 2 +- .../stackblitz/v9/react/package-lock.json | 20 +++++++++---------- static/code/stackblitz/v9/react/package.json | 4 ++-- .../code/stackblitz/v9/vue/package-lock.json | 20 +++++++++---------- static/code/stackblitz/v9/vue/package.json | 4 ++-- .../v9/select/rich-content-options/demo.html | 4 ++-- 10 files changed, 40 insertions(+), 40 deletions(-) diff --git a/plugins/docusaurus-plugin-ionic-component-api/index.js b/plugins/docusaurus-plugin-ionic-component-api/index.js index 7bfad796faf..703afc8af4f 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.7-dev.11779221548.1d38f927'; + let npmTag = '8.8.9-dev.11779411201.1a483e09'; if (currentVersion.banner === 'unreleased') { npmTag = 'next'; } else if (currentVersion.path !== undefined) { diff --git a/static/code/stackblitz/v9/angular/package-lock.json b/static/code/stackblitz/v9/angular/package-lock.json index 6054d38649f..d6d6e13da71 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.8.7-dev.11779221548.1d38f927", - "@ionic/core": "8.8.7-dev.11779221548.1d38f927", + "@ionic/angular": "8.8.9-dev.11779411201.1a483e09", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "ionicons": "8.0.13", "rxjs": "^7.8.1", "tslib": "^2.5.0", @@ -3217,12 +3217,12 @@ } }, "node_modules/@ionic/angular": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-W2/mmrL/RTwlDrFyOmRukTz6x0DLl905XwVjIIMeGgu/IV3dbHbzHmFj6VwdhdxW13T9kLOrzLqPRri1KQtdCw==", "license": "MIT", "dependencies": { - "@ionic/core": "8.8.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "ionicons": "^8.0.13", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" @@ -3236,8 +3236,8 @@ } }, "node_modules/@ionic/core": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11779411201.1a483e09.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 de6206d75dc..96b73306f96 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.8.7-dev.11779221548.1d38f927", - "@ionic/core": "8.8.7-dev.11779221548.1d38f927", + "@ionic/angular": "8.8.9-dev.11779411201.1a483e09", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "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 e0efc79a19d..12361b63dd9 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.8.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "ionicons": "8.0.13" }, "devDependencies": { @@ -458,8 +458,8 @@ } }, "node_modules/@ionic/core": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11779411201.1a483e09.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 cea9a7d7f70..e8036d28121 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.8.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "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 cd98ea12278..d29d9c8d150 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.8.7-dev.11779221548.1d38f927", - "@ionic/react-router": "8.8.7-dev.11779221548.1d38f927", + "@ionic/react": "8.8.9-dev.11779411201.1a483e09", + "@ionic/react-router": "8.8.9-dev.11779411201.1a483e09", "@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.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", "license": "MIT", "dependencies": { @@ -727,12 +727,12 @@ } }, "node_modules/@ionic/react": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/react/-/react-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-h4j2SVRMgoxZBdr1bluKGrb0xNYEqEDcjHDuHsok669tKH3RnTMfD276zytfhFh3R8gIKWIqxb76NIsW/hfZcQ==", "license": "MIT", "dependencies": { - "@ionic/core": "8.8.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "ionicons": "^8.0.13", "tslib": "*" }, @@ -742,12 +742,12 @@ } }, "node_modules/@ionic/react-router": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/react-router/-/react-router-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-ZpJxx9WjprNngRaVEUvy1k5S22P0/BNfXNKpqqFci/JDJL5uPArLaevwXAuOzdIf+EknpG+34IIW6PBme5cPAQ==", "license": "MIT", "dependencies": { - "@ionic/react": "8.8.7-dev.11779221548.1d38f927", + "@ionic/react": "8.8.9-dev.11779411201.1a483e09", "tslib": "*" }, "peerDependencies": { diff --git a/static/code/stackblitz/v9/react/package.json b/static/code/stackblitz/v9/react/package.json index 358e6f8e985..612064c55a4 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.8.7-dev.11779221548.1d38f927", - "@ionic/react-router": "8.8.7-dev.11779221548.1d38f927", + "@ionic/react": "8.8.9-dev.11779411201.1a483e09", + "@ionic/react-router": "8.8.9-dev.11779411201.1a483e09", "@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 38add583736..1c80916ee9b 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.8.7-dev.11779221548.1d38f927", - "@ionic/vue-router": "8.8.7-dev.11779221548.1d38f927", + "@ionic/vue": "8.8.9-dev.11779411201.1a483e09", + "@ionic/vue-router": "8.8.9-dev.11779411201.1a483e09", "vue": "^3.2.25", "vue-router": "4.6.3" }, @@ -509,8 +509,8 @@ } }, "node_modules/@ionic/core": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-9UX9IeEztWWXymi+xCUMEBnnY+TbaR8crZLOwFnxPUEq4FFWSUCSv5XeHHQBpgZjBO2MJuDGcNv0GCQumIjVcQ==", "license": "MIT", "dependencies": { @@ -520,23 +520,23 @@ } }, "node_modules/@ionic/vue": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/vue/-/vue-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-HDEcjhxWfimVQxvXfghrqlAWpXnJvcUDTIVE2Mvq8ul+s7gL/OZCpXTAODJOfFCBAGJ0o9QXyC7OPjyN4UbO8Q==", "license": "MIT", "dependencies": { - "@ionic/core": "8.8.7-dev.11779221548.1d38f927", + "@ionic/core": "8.8.9-dev.11779411201.1a483e09", "@stencil/vue-output-target": "0.10.7", "ionicons": "^8.0.13" } }, "node_modules/@ionic/vue-router": { - "version": "8.8.7-dev.11779221548.1d38f927", - "resolved": "https://registry.npmjs.org/@ionic/vue-router/-/vue-router-8.8.7-dev.11779221548.1d38f927.tgz", + "version": "8.8.9-dev.11779411201.1a483e09", + "resolved": "https://registry.npmjs.org/@ionic/vue-router/-/vue-router-8.8.9-dev.11779411201.1a483e09.tgz", "integrity": "sha512-6k/bWLORJucLIPYqcrXnSs3KEI69qaWo6V4bGAEOSkt9dISdTy65gafi4gtFFyV+n81LIU00WnajJYLadDG3Cg==", "license": "MIT", "dependencies": { - "@ionic/vue": "8.8.7-dev.11779221548.1d38f927" + "@ionic/vue": "8.8.9-dev.11779411201.1a483e09" } }, "node_modules/@jridgewell/sourcemap-codec": { diff --git a/static/code/stackblitz/v9/vue/package.json b/static/code/stackblitz/v9/vue/package.json index cfd3214c9e6..1554f4ada51 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.8.7-dev.11779221548.1d38f927", - "@ionic/vue-router": "8.8.7-dev.11779221548.1d38f927", + "@ionic/vue": "8.8.9-dev.11779411201.1a483e09", + "@ionic/vue-router": "8.8.9-dev.11779411201.1a483e09", "vue": "^3.2.25", "vue-router": "4.6.3" }, diff --git a/static/usage/v9/select/rich-content-options/demo.html b/static/usage/v9/select/rich-content-options/demo.html index 943df6ab16a..ce4b85da93d 100644 --- a/static/usage/v9/select/rich-content-options/demo.html +++ b/static/usage/v9/select/rich-content-options/demo.html @@ -15,11 +15,11 @@