@ionic/core 8.8.9-dev.11779403760.13ea2a08 → 8.8.9-dev.11779411201.1a483e09

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/components/index.js +1 -1
  2. package/components/ion-alert.js +1 -1
  3. package/components/ion-infinite-scroll-content.js +1 -1
  4. package/components/ion-loading.js +1 -1
  5. package/components/ion-refresher-content.js +1 -1
  6. package/components/ion-select.js +1 -1
  7. package/components/ion-toast.js +1 -1
  8. package/components/p-DdgejEM3.js +4 -0
  9. package/components/{p-NVAi5HQQ.js → p-DohYi97K.js} +1 -1
  10. package/dist/cjs/{config-BiqQSDrb.js → config-OJmFhoxl.js} +56 -8
  11. package/dist/cjs/index.cjs.js +1 -1
  12. package/dist/cjs/ion-alert.cjs.entry.js +1 -1
  13. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +1 -1
  14. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  15. package/dist/cjs/ion-refresher_2.cjs.entry.js +1 -1
  16. package/dist/cjs/ion-select_3.cjs.entry.js +20 -7
  17. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  18. package/dist/collection/components/select/select.js +20 -7
  19. package/dist/collection/utils/sanitization/index.js +55 -8
  20. package/dist/docs.json +1 -1
  21. package/dist/esm/{config-DLfuRiEz.js → config-C5F1aoVz.js} +56 -9
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/ion-alert.entry.js +1 -1
  24. package/dist/esm/ion-infinite-scroll_2.entry.js +1 -1
  25. package/dist/esm/ion-loading.entry.js +1 -1
  26. package/dist/esm/ion-refresher_2.entry.js +1 -1
  27. package/dist/esm/ion-select_3.entry.js +20 -7
  28. package/dist/esm/ion-toast.entry.js +1 -1
  29. package/dist/ionic/index.esm.js +1 -1
  30. package/dist/ionic/ionic.esm.js +1 -1
  31. package/dist/ionic/{p-3f1dbb47.entry.js → p-3e186bd8.entry.js} +1 -1
  32. package/dist/ionic/{p-b4ba0050.entry.js → p-4a5ebd2b.entry.js} +1 -1
  33. package/dist/ionic/{p-7e6112fc.entry.js → p-729a5b04.entry.js} +1 -1
  34. package/dist/ionic/{p-c21a780d.entry.js → p-7d25ad9a.entry.js} +1 -1
  35. package/dist/ionic/p-c6516c13.entry.js +4 -0
  36. package/dist/ionic/{p-fd519e2b.entry.js → p-e7505567.entry.js} +1 -1
  37. package/dist/ionic/p-pI5qh5HW.js +4 -0
  38. package/dist/types/utils/sanitization/index.d.ts +18 -4
  39. package/hydrate/index.js +74 -14
  40. package/hydrate/index.mjs +74 -14
  41. package/package.json +1 -1
  42. package/components/p-VVrXfwLZ.js +0 -4
  43. package/dist/ionic/p-c5118189.entry.js +0 -4
  44. package/dist/ionic/p-u6HLvq0g.js +0 -4
@@ -6,7 +6,7 @@
6
6
  var index = require('./index-CzcLEdQ5.js');
7
7
  var index$1 = require('./index-BJrpF9T3.js');
8
8
  var ionicGlobal = require('./ionic-global-BW5tRzrz.js');
9
- var config = require('./config-BiqQSDrb.js');
9
+ var config = require('./config-OJmFhoxl.js');
10
10
  require('./helpers-DJYxKN5U.js');
11
11
  require('./focus-visible-BIj-I3-C.js');
12
12
 
@@ -4,7 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-CzcLEdQ5.js');
7
- var config = require('./config-BiqQSDrb.js');
7
+ var config = require('./config-OJmFhoxl.js');
8
8
  var helpers = require('./helpers-DJYxKN5U.js');
9
9
  var lockController = require('./lock-controller-aDB9wrEf.js');
10
10
  var overlays = require('./overlays-BuMIwR8B.js');
@@ -10,7 +10,7 @@ var helpers = require('./helpers-DJYxKN5U.js');
10
10
  var haptic = require('./haptic-CQJGW58i.js');
11
11
  var ionicGlobal = require('./ionic-global-BW5tRzrz.js');
12
12
  var animation = require('./animation-BZJ2wKuM.js');
13
- var config = require('./config-BiqQSDrb.js');
13
+ var config = require('./config-OJmFhoxl.js');
14
14
  var index$2 = require('./index-CgAbCW6L.js');
15
15
  var spinnerConfigs = require('./spinner-configs-DxHKnd3-.js');
16
16
  require('./focus-visible-BIj-I3-C.js');
@@ -5,7 +5,7 @@
5
5
 
6
6
  var index = require('./index-CzcLEdQ5.js');
7
7
  var caretDown = require('./caret-down-vtVgfXIs.js');
8
- var config = require('./config-BiqQSDrb.js');
8
+ var config = require('./config-OJmFhoxl.js');
9
9
  var notchController = require('./notch-controller-BTZCPOsd.js');
10
10
  var compareWithUtils = require('./compare-with-utils-DSicavqM.js');
11
11
  var validity = require('./validity-QmuwEptc.js');
@@ -947,7 +947,7 @@ const Select = class {
947
947
  * TODO(FW-5592): Remove hasStartEndSlots condition
948
948
  */
949
949
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
950
- return (index.h(index.Host, { key: 'b5c213595ee043d842a7b7d64aa142955db0ad88', onClick: this.onClick, class: theme.createColorClasses(this.color, {
950
+ return (index.h(index.Host, { key: 'ce995037cea6ce309ead79f881772c628086ab45', onClick: this.onClick, class: theme.createColorClasses(this.color, {
951
951
  [theme$1]: true,
952
952
  'in-item': inItem,
953
953
  'in-item-color': theme.hostContext('ion-item.ion-color', el),
@@ -966,7 +966,7 @@ const Select = class {
966
966
  [`select-shape-${shape}`]: shape !== undefined,
967
967
  [`select-label-placement-${labelPlacement}`]: true,
968
968
  [`select-size-${size}`]: size !== undefined,
969
- }) }, index.h("label", { key: '4b301ea9bc752639b1a5ad2ffbacddda86aba4e9', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), index.h("div", { key: 'eed3a60c53e9215d3c06857f0b1ad9e2f8fb7d61', class: "select-wrapper-inner", part: "inner" },
969
+ }) }, index.h("label", { key: '862fa9d03a7feeeac05463842898849001724cef', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), index.h("div", { key: '1e91cc271790756a97cfc0c8caaca767ba793467', class: "select-wrapper-inner", part: "inner" },
970
970
  /**
971
971
  * For the ionic theme, we render the outline container here
972
972
  * instead of higher up, so it can be positioned relative to
@@ -976,7 +976,7 @@ const Select = class {
976
976
  * <label> element, ensuring that clicking the label text
977
977
  * focuses the select.
978
978
  */
979
- theme$1 === 'ionic' && fill === 'outline' && index.h("div", { key: 'f567c3512f1c1482f5854cc09bcca2067431dc51', class: "select-outline" }), index.h("slot", { key: '4a332f517ee89bdb6da84c0dee9dea5f35f5a6cd', name: "start" }), index.h("div", { key: 'e9c541dcfe4b9d3cad4d4c3c094d7666e947cd46', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), index.h("slot", { key: '3c663f69f85fd87ece0f2da081a3b64e5e140bde', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && index.h("div", { key: '336f7c9564b7e19a8b93e2d8a497dbd3e5e4e993', class: "select-highlight" })), this.renderBottomContent()));
979
+ theme$1 === 'ionic' && fill === 'outline' && index.h("div", { key: '14a2a14daa10625fa59f8f148e124a1c0c147319', class: "select-outline" }), index.h("slot", { key: 'a5a4372feffbeb3652e6045e64cbfacb66c58da9', name: "start" }), index.h("div", { key: 'b6ac054eaca720a21e0617cf413e576ef23a60e8', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), index.h("slot", { key: '140d299760a7c7f186b31e9e38f968534b1e116a', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && index.h("div", { key: 'b1a1e98302b0e87c3cd850e9abd8faf946a2b492', class: "select-highlight" })), this.renderBottomContent()));
980
980
  }
981
981
  get el() { return index.getElement(this); }
982
982
  static get watchers() { return {
@@ -1129,6 +1129,17 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1129
1129
  if (!slotName && nodes.every((n) => n.nodeType === Node.TEXT_NODE)) {
1130
1130
  return nodes.map((n) => { var _a; return (_a = n.textContent) === null || _a === void 0 ? void 0 : _a.trim(); }).join(' ') || null;
1131
1131
  }
1132
+ /**
1133
+ * Mirror known custom-element properties (e.g. ion-icon's `icon`)
1134
+ * onto attributes before cloning. Frameworks like Vue set these as
1135
+ * DOM properties, which `cloneNode` doesn't copy, so without this
1136
+ * step the cloned overlay copy renders without the prop's value.
1137
+ */
1138
+ nodes.forEach((n) => {
1139
+ if (n.nodeType === Node.ELEMENT_NODE) {
1140
+ config.reflectPropertiesToAttributes(n);
1141
+ }
1142
+ });
1132
1143
  // Clone each node into a temporary container
1133
1144
  const container = document.createElement('div');
1134
1145
  nodes.forEach((n) => {
@@ -1142,9 +1153,11 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1142
1153
  }
1143
1154
  container.appendChild(clone);
1144
1155
  });
1145
- // Sanitize the cloned DOM in place. Author-written attributes (size,
1146
- // color, shape, etc.) are preserved; event handlers, javascript: URLs,
1147
- // and blocked tags are stripped.
1156
+ /**
1157
+ * Sanitize the cloned DOM in place. Trusted attributes (size, color,
1158
+ * shape, etc.) are preserved; event handlers, javascript: URLs, and
1159
+ * blocked tags are stripped.
1160
+ */
1148
1161
  config.sanitizeDOMTree(container);
1149
1162
  if (useHTML) {
1150
1163
  return container.innerHTML.trim() || null;
@@ -4,7 +4,7 @@
4
4
  'use strict';
5
5
 
6
6
  var index = require('./index-CzcLEdQ5.js');
7
- var config = require('./config-BiqQSDrb.js');
7
+ var config = require('./config-OJmFhoxl.js');
8
8
  var helpers = require('./helpers-DJYxKN5U.js');
9
9
  var lockController = require('./lock-controller-aDB9wrEf.js');
10
10
  var overlays = require('./overlays-BuMIwR8B.js');
@@ -9,7 +9,7 @@ import { focusVisibleElement, renderHiddenInput, inheritAttributes } from "../..
9
9
  import { printIonWarning } from "../../utils/logging/index";
10
10
  import { actionSheetController, alertController, popoverController, modalController } from "../../utils/overlays";
11
11
  import { isRTL } from "../../utils/rtl/index";
12
- import { sanitizeDOMTree } from "../../utils/sanitization/index";
12
+ import { reflectPropertiesToAttributes, sanitizeDOMTree } from "../../utils/sanitization/index";
13
13
  import { createColorClasses, hostContext } from "../../utils/theme";
14
14
  import { watchForOptions } from "../../utils/watch-options";
15
15
  import { caretDownSharp, chevronExpand } from "ionicons/icons";
@@ -994,7 +994,7 @@ export class Select {
994
994
  * TODO(FW-5592): Remove hasStartEndSlots condition
995
995
  */
996
996
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
997
- return (h(Host, { key: 'b5c213595ee043d842a7b7d64aa142955db0ad88', onClick: this.onClick, class: createColorClasses(this.color, {
997
+ return (h(Host, { key: 'ce995037cea6ce309ead79f881772c628086ab45', onClick: this.onClick, class: createColorClasses(this.color, {
998
998
  [theme]: true,
999
999
  'in-item': inItem,
1000
1000
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -1013,7 +1013,7 @@ export class Select {
1013
1013
  [`select-shape-${shape}`]: shape !== undefined,
1014
1014
  [`select-label-placement-${labelPlacement}`]: true,
1015
1015
  [`select-size-${size}`]: size !== undefined,
1016
- }) }, h("label", { key: '4b301ea9bc752639b1a5ad2ffbacddda86aba4e9', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: 'eed3a60c53e9215d3c06857f0b1ad9e2f8fb7d61', class: "select-wrapper-inner", part: "inner" },
1016
+ }) }, h("label", { key: '862fa9d03a7feeeac05463842898849001724cef', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: '1e91cc271790756a97cfc0c8caaca767ba793467', class: "select-wrapper-inner", part: "inner" },
1017
1017
  /**
1018
1018
  * For the ionic theme, we render the outline container here
1019
1019
  * instead of higher up, so it can be positioned relative to
@@ -1023,7 +1023,7 @@ export class Select {
1023
1023
  * <label> element, ensuring that clicking the label text
1024
1024
  * focuses the select.
1025
1025
  */
1026
- theme === 'ionic' && fill === 'outline' && h("div", { key: 'f567c3512f1c1482f5854cc09bcca2067431dc51', class: "select-outline" }), h("slot", { key: '4a332f517ee89bdb6da84c0dee9dea5f35f5a6cd', name: "start" }), h("div", { key: 'e9c541dcfe4b9d3cad4d4c3c094d7666e947cd46', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '3c663f69f85fd87ece0f2da081a3b64e5e140bde', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '336f7c9564b7e19a8b93e2d8a497dbd3e5e4e993', class: "select-highlight" })), this.renderBottomContent()));
1026
+ theme === 'ionic' && fill === 'outline' && h("div", { key: '14a2a14daa10625fa59f8f148e124a1c0c147319', class: "select-outline" }), h("slot", { key: 'a5a4372feffbeb3652e6045e64cbfacb66c58da9', name: "start" }), h("div", { key: 'b6ac054eaca720a21e0617cf413e576ef23a60e8', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '140d299760a7c7f186b31e9e38f968534b1e116a', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: 'b1a1e98302b0e87c3cd850e9abd8faf946a2b492', class: "select-highlight" })), this.renderBottomContent()));
1027
1027
  }
1028
1028
  static get is() { return "ion-select"; }
1029
1029
  static get encapsulation() { return "shadow"; }
@@ -1846,6 +1846,17 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1846
1846
  if (!slotName && nodes.every((n) => n.nodeType === Node.TEXT_NODE)) {
1847
1847
  return nodes.map((n) => { var _a; return (_a = n.textContent) === null || _a === void 0 ? void 0 : _a.trim(); }).join(' ') || null;
1848
1848
  }
1849
+ /**
1850
+ * Mirror known custom-element properties (e.g. ion-icon's `icon`)
1851
+ * onto attributes before cloning. Frameworks like Vue set these as
1852
+ * DOM properties, which `cloneNode` doesn't copy, so without this
1853
+ * step the cloned overlay copy renders without the prop's value.
1854
+ */
1855
+ nodes.forEach((n) => {
1856
+ if (n.nodeType === Node.ELEMENT_NODE) {
1857
+ reflectPropertiesToAttributes(n);
1858
+ }
1859
+ });
1849
1860
  // Clone each node into a temporary container
1850
1861
  const container = document.createElement('div');
1851
1862
  nodes.forEach((n) => {
@@ -1859,9 +1870,11 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1859
1870
  }
1860
1871
  container.appendChild(clone);
1861
1872
  });
1862
- // Sanitize the cloned DOM in place. Author-written attributes (size,
1863
- // color, shape, etc.) are preserved; event handlers, javascript: URLs,
1864
- // and blocked tags are stripped.
1873
+ /**
1874
+ * Sanitize the cloned DOM in place. Trusted attributes (size, color,
1875
+ * shape, etc.) are preserved; event handlers, javascript: URLs, and
1876
+ * blocked tags are stripped.
1877
+ */
1865
1878
  sanitizeDOMTree(container);
1866
1879
  if (useHTML) {
1867
1880
  return container.innerHTML.trim() || null;
@@ -11,7 +11,7 @@ import { printIonError } from "../logging/index";
11
11
  *
12
12
  * Use this when you have an HTML string from an unknown source and need
13
13
  * to render it via `innerHTML`. Prefer `sanitizeDOMTree` when the source
14
- * is author-controlled DOM that must keep its component attributes
14
+ * is a trusted DOM tree that must keep its component attributes
15
15
  * (`size`, `color`, `shape`, etc.).
16
16
  *
17
17
  * @param untrustedString - The HTML string to sanitize. Pass an
@@ -95,14 +95,14 @@ export const sanitizeDOMString = (untrustedString) => {
95
95
  }
96
96
  };
97
97
  /**
98
- * Sanitize an entire author-controlled DOM tree in place.
98
+ * Sanitize an entire trusted DOM tree in place.
99
99
  *
100
100
  * Removes blocked tags (`script`, `iframe`, etc.) from the subtree and
101
- * then sanitizes attributes on every remaining element. Author-written
101
+ * then sanitizes attributes on every remaining element. Component
102
102
  * attributes like `size`, `color`, and `shape` are preserved; event
103
103
  * handlers (`on*`) and `javascript:` URLs are stripped.
104
104
  *
105
- * Use this when you have a DOM tree that the developer authored (e.g.
105
+ * Use this when you have a DOM tree the developer controls (e.g.
106
106
  * cloned slot content from a component) and you need to render it
107
107
  * elsewhere safely.
108
108
  *
@@ -127,7 +127,7 @@ export const sanitizeDOMTree = (root) => {
127
127
  * clean those up as well
128
128
  */
129
129
  // TODO(FW-2832): type (using Element triggers other type errors as well)
130
- const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
130
+ const sanitizeElement = (element, allowSafeAttributes = false) => {
131
131
  // IE uses childNodes, so ignore nodes that are not elements
132
132
  if (element.nodeType && element.nodeType !== 1) {
133
133
  return;
@@ -147,12 +147,12 @@ const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
147
147
  const attributeName = attribute.name;
148
148
  const lowerName = attributeName.toLowerCase();
149
149
  // remove non-allowed attribs
150
- if (!allowSafeAuthorAttributes && !allowedAttributes.includes(lowerName)) {
150
+ if (!allowSafeAttributes && !allowedAttributes.includes(lowerName)) {
151
151
  element.removeAttribute(attributeName);
152
152
  continue;
153
153
  }
154
154
  // strip event-handler attributes (already removed by the allowlist
155
- // when !allowSafeAuthorAttributes; this guards the permissive path)
155
+ // when !allowSafeAttributes; this guards the permissive path)
156
156
  if (lowerName.startsWith('on')) {
157
157
  element.removeAttribute(attributeName);
158
158
  continue;
@@ -183,7 +183,7 @@ const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
183
183
  const childElements = getElementChildren(element);
184
184
  /* eslint-disable-next-line */
185
185
  for (let i = 0; i < childElements.length; i++) {
186
- sanitizeElement(childElements[i], allowSafeAuthorAttributes);
186
+ sanitizeElement(childElements[i], allowSafeAttributes);
187
187
  }
188
188
  };
189
189
  /**
@@ -208,8 +208,55 @@ const isSanitizerEnabled = () => {
208
208
  }
209
209
  return true;
210
210
  };
211
+ /**
212
+ * Mirror known custom-element DOM properties onto attributes so they
213
+ * survive `cloneNode`. Call this on a DOM subtree before cloning it for
214
+ * rendering elsewhere (e.g. cloning slotted option content into an
215
+ * overlay).
216
+ *
217
+ * Only sets the attribute when the property holds a non-empty string
218
+ * and the attribute isn't already present, so existing attributes
219
+ * take precedence.
220
+ *
221
+ * @param root - The root element whose subtree (and itself) will be
222
+ * inspected.
223
+ */
224
+ export const reflectPropertiesToAttributes = (root) => {
225
+ const candidates = [];
226
+ if (root.tagName in elementPropsToReflect) {
227
+ candidates.push(root);
228
+ }
229
+ for (const tagName of Object.keys(elementPropsToReflect)) {
230
+ candidates.push(...Array.from(root.querySelectorAll(tagName.toLowerCase())));
231
+ }
232
+ for (const el of candidates) {
233
+ if (!(el.tagName in elementPropsToReflect)) {
234
+ continue;
235
+ }
236
+ const props = elementPropsToReflect[el.tagName];
237
+ for (const prop of props) {
238
+ const value = el[prop];
239
+ if (typeof value === 'string' && value.length > 0 && !el.hasAttribute(prop)) {
240
+ el.setAttribute(prop, value);
241
+ }
242
+ }
243
+ }
244
+ };
211
245
  const allowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
212
246
  const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
247
+ /**
248
+ * Properties on custom elements that frameworks (Vue, Angular) often
249
+ * set as DOM properties rather than attributes. `cloneNode` only copies
250
+ * attributes, so these values are lost when slotted content is cloned
251
+ * into an overlay. For each known custom element, we mirror the listed
252
+ * properties onto attributes so the cloned copy still has the data it
253
+ * needs to render.
254
+ *
255
+ * Keyed by uppercased tagName so the lookup matches `Element.tagName`.
256
+ */
257
+ const elementPropsToReflect = {
258
+ 'ION-ICON': ['icon', 'name', 'src', 'ios', 'md'],
259
+ };
213
260
  export class IonicSafeString {
214
261
  constructor(value) {
215
262
  this.value = value;
package/dist/docs.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "timestamp": "2026-05-21T22:51:41",
2
+ "timestamp": "2026-05-22T00:55:46",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
5
  "version": "4.43.0",
@@ -12,7 +12,7 @@ import { j as printIonError } from './index-Omi_TcwW.js';
12
12
  *
13
13
  * Use this when you have an HTML string from an unknown source and need
14
14
  * to render it via `innerHTML`. Prefer `sanitizeDOMTree` when the source
15
- * is author-controlled DOM that must keep its component attributes
15
+ * is a trusted DOM tree that must keep its component attributes
16
16
  * (`size`, `color`, `shape`, etc.).
17
17
  *
18
18
  * @param untrustedString - The HTML string to sanitize. Pass an
@@ -96,14 +96,14 @@ const sanitizeDOMString = (untrustedString) => {
96
96
  }
97
97
  };
98
98
  /**
99
- * Sanitize an entire author-controlled DOM tree in place.
99
+ * Sanitize an entire trusted DOM tree in place.
100
100
  *
101
101
  * Removes blocked tags (`script`, `iframe`, etc.) from the subtree and
102
- * then sanitizes attributes on every remaining element. Author-written
102
+ * then sanitizes attributes on every remaining element. Component
103
103
  * attributes like `size`, `color`, and `shape` are preserved; event
104
104
  * handlers (`on*`) and `javascript:` URLs are stripped.
105
105
  *
106
- * Use this when you have a DOM tree that the developer authored (e.g.
106
+ * Use this when you have a DOM tree the developer controls (e.g.
107
107
  * cloned slot content from a component) and you need to render it
108
108
  * elsewhere safely.
109
109
  *
@@ -128,7 +128,7 @@ const sanitizeDOMTree = (root) => {
128
128
  * clean those up as well
129
129
  */
130
130
  // TODO(FW-2832): type (using Element triggers other type errors as well)
131
- const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
131
+ const sanitizeElement = (element, allowSafeAttributes = false) => {
132
132
  // IE uses childNodes, so ignore nodes that are not elements
133
133
  if (element.nodeType && element.nodeType !== 1) {
134
134
  return;
@@ -148,12 +148,12 @@ const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
148
148
  const attributeName = attribute.name;
149
149
  const lowerName = attributeName.toLowerCase();
150
150
  // remove non-allowed attribs
151
- if (!allowSafeAuthorAttributes && !allowedAttributes.includes(lowerName)) {
151
+ if (!allowSafeAttributes && !allowedAttributes.includes(lowerName)) {
152
152
  element.removeAttribute(attributeName);
153
153
  continue;
154
154
  }
155
155
  // strip event-handler attributes (already removed by the allowlist
156
- // when !allowSafeAuthorAttributes; this guards the permissive path)
156
+ // when !allowSafeAttributes; this guards the permissive path)
157
157
  if (lowerName.startsWith('on')) {
158
158
  element.removeAttribute(attributeName);
159
159
  continue;
@@ -184,7 +184,7 @@ const sanitizeElement = (element, allowSafeAuthorAttributes = false) => {
184
184
  const childElements = getElementChildren(element);
185
185
  /* eslint-disable-next-line */
186
186
  for (let i = 0; i < childElements.length; i++) {
187
- sanitizeElement(childElements[i], allowSafeAuthorAttributes);
187
+ sanitizeElement(childElements[i], allowSafeAttributes);
188
188
  }
189
189
  };
190
190
  /**
@@ -209,8 +209,55 @@ const isSanitizerEnabled = () => {
209
209
  }
210
210
  return true;
211
211
  };
212
+ /**
213
+ * Mirror known custom-element DOM properties onto attributes so they
214
+ * survive `cloneNode`. Call this on a DOM subtree before cloning it for
215
+ * rendering elsewhere (e.g. cloning slotted option content into an
216
+ * overlay).
217
+ *
218
+ * Only sets the attribute when the property holds a non-empty string
219
+ * and the attribute isn't already present, so existing attributes
220
+ * take precedence.
221
+ *
222
+ * @param root - The root element whose subtree (and itself) will be
223
+ * inspected.
224
+ */
225
+ const reflectPropertiesToAttributes = (root) => {
226
+ const candidates = [];
227
+ if (root.tagName in elementPropsToReflect) {
228
+ candidates.push(root);
229
+ }
230
+ for (const tagName of Object.keys(elementPropsToReflect)) {
231
+ candidates.push(...Array.from(root.querySelectorAll(tagName.toLowerCase())));
232
+ }
233
+ for (const el of candidates) {
234
+ if (!(el.tagName in elementPropsToReflect)) {
235
+ continue;
236
+ }
237
+ const props = elementPropsToReflect[el.tagName];
238
+ for (const prop of props) {
239
+ const value = el[prop];
240
+ if (typeof value === 'string' && value.length > 0 && !el.hasAttribute(prop)) {
241
+ el.setAttribute(prop, value);
242
+ }
243
+ }
244
+ }
245
+ };
212
246
  const allowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
213
247
  const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
248
+ /**
249
+ * Properties on custom elements that frameworks (Vue, Angular) often
250
+ * set as DOM properties rather than attributes. `cloneNode` only copies
251
+ * attributes, so these values are lost when slotted content is cloned
252
+ * into an overlay. For each known custom element, we mirror the listed
253
+ * properties onto attributes so the cloned copy still has the data it
254
+ * needs to render.
255
+ *
256
+ * Keyed by uppercased tagName so the lookup matches `Element.tagName`.
257
+ */
258
+ const elementPropsToReflect = {
259
+ 'ION-ICON': ['icon', 'name', 'src', 'ios', 'md'],
260
+ };
214
261
  class IonicSafeString {
215
262
  constructor(value) {
216
263
  this.value = value;
@@ -244,4 +291,4 @@ const getMode = () => {
244
291
  };
245
292
  const ENABLE_HTML_CONTENT_DEFAULT = false;
246
293
 
247
- export { ENABLE_HTML_CONTENT_DEFAULT as E, IonicSafeString as I, sanitizeDOMString as a, sanitizeDOMTree as b, getMode as g, setupConfig as s };
294
+ export { ENABLE_HTML_CONTENT_DEFAULT as E, IonicSafeString as I, sanitizeDOMString as a, sanitizeDOMTree as b, getMode as g, reflectPropertiesToAttributes as r, setupConfig as s };
package/dist/esm/index.js CHANGED
@@ -10,7 +10,7 @@ export { createGesture } from './index-CfgBF1SE.js';
10
10
  export { g as getPlatforms, i as initialize, a as isPlatform } from './ionic-global--9mOmThr.js';
11
11
  export { c as componentOnReady } from './helpers-Do7zwvM1.js';
12
12
  export { L as LogLevel } from './index-Omi_TcwW.js';
13
- export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-DLfuRiEz.js';
13
+ export { I as IonicSafeString, g as getMode, s as setupConfig } from './config-C5F1aoVz.js';
14
14
  export { o as openURL } from './theme-DaJxRxSQ.js';
15
15
  export { m as menuController } from './index-BWMvrRiE.js';
16
16
  export { b as actionSheetController, a as alertController, l as loadingController, m as modalController, p as pickerController, c as popoverController, t as toastController } from './overlays-CpQ6Df2g.js';
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { r as registerInstance, c as createEvent, e as config, f as printIonWarning, i as forceUpdate, h, d as Host, g as getElement } from './index-Omi_TcwW.js';
5
- import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-DLfuRiEz.js';
5
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-C5F1aoVz.js';
6
6
  import { c as createButtonActiveGesture } from './button-active-B016u5N-.js';
7
7
  import { r as raf } from './helpers-Do7zwvM1.js';
8
8
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
@@ -4,7 +4,7 @@
4
4
  import { r as registerInstance, c as createEvent, w as writeTask, a as readTask, h, d as Host, g as getElement, e as config } from './index-Omi_TcwW.js';
5
5
  import { f as findClosestIonContent, p as printIonContentErrorMsg, g as getScrollElement } from './index-BmkLokUL.js';
6
6
  import { c as getIonTheme } from './ionic-global--9mOmThr.js';
7
- import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-DLfuRiEz.js';
7
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-C5F1aoVz.js';
8
8
  import './helpers-Do7zwvM1.js';
9
9
  import './focus-visible-vXpMhGrs.js';
10
10
 
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { r as registerInstance, c as createEvent, e as config, h, d as Host, g as getElement } from './index-Omi_TcwW.js';
5
- import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-DLfuRiEz.js';
5
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-C5F1aoVz.js';
6
6
  import { r as raf } from './helpers-Do7zwvM1.js';
7
7
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
8
8
  import { d as createDelegateController, e as createTriggerController, B as BACKDROP, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod } from './overlays-CpQ6Df2g.js';
@@ -8,7 +8,7 @@ import { c as componentOnReady, t as transitionEndAsync, e as clamp, g as getEle
8
8
  import { d as hapticImpact, I as ImpactStyle } from './haptic-CbnKC3go.js';
9
9
  import { b as getIonMode, c as getIonTheme } from './ionic-global--9mOmThr.js';
10
10
  import { c as createAnimation } from './animation-Cd1EA2ar.js';
11
- import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-DLfuRiEz.js';
11
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-C5F1aoVz.js';
12
12
  import { h as arrowDown, i as caretBackSharp } from './index-D2tu5BUg.js';
13
13
  import { S as SPINNERS } from './spinner-configs-D4RIp70E.js';
14
14
  import './focus-visible-vXpMhGrs.js';
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { r as registerInstance, c as createEvent, e as config, f as printIonWarning, h, d as Host, g as getElement, i as forceUpdate } from './index-Omi_TcwW.js';
5
5
  import { c as caretDownSvg } from './caret-down-D1t981Ih.js';
6
- import { E as ENABLE_HTML_CONTENT_DEFAULT, b as sanitizeDOMTree } from './config-DLfuRiEz.js';
6
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, r as reflectPropertiesToAttributes, b as sanitizeDOMTree } from './config-C5F1aoVz.js';
7
7
  import { c as createNotchController } from './notch-controller-klgNWpjJ.js';
8
8
  import { i as isOptionSelected, c as compareOptions } from './compare-with-utils-sObYyvOy.js';
9
9
  import { c as checkInvalidState } from './validity-BjW8SOqw.js';
@@ -945,7 +945,7 @@ const Select = class {
945
945
  * TODO(FW-5592): Remove hasStartEndSlots condition
946
946
  */
947
947
  const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
948
- return (h(Host, { key: 'b5c213595ee043d842a7b7d64aa142955db0ad88', onClick: this.onClick, class: createColorClasses(this.color, {
948
+ return (h(Host, { key: 'ce995037cea6ce309ead79f881772c628086ab45', onClick: this.onClick, class: createColorClasses(this.color, {
949
949
  [theme]: true,
950
950
  'in-item': inItem,
951
951
  'in-item-color': hostContext('ion-item.ion-color', el),
@@ -964,7 +964,7 @@ const Select = class {
964
964
  [`select-shape-${shape}`]: shape !== undefined,
965
965
  [`select-label-placement-${labelPlacement}`]: true,
966
966
  [`select-size-${size}`]: size !== undefined,
967
- }) }, h("label", { key: '4b301ea9bc752639b1a5ad2ffbacddda86aba4e9', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: 'eed3a60c53e9215d3c06857f0b1ad9e2f8fb7d61', class: "select-wrapper-inner", part: "inner" },
967
+ }) }, h("label", { key: '862fa9d03a7feeeac05463842898849001724cef', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick, part: "wrapper" }, this.renderLabelContainer(), h("div", { key: '1e91cc271790756a97cfc0c8caaca767ba793467', class: "select-wrapper-inner", part: "inner" },
968
968
  /**
969
969
  * For the ionic theme, we render the outline container here
970
970
  * instead of higher up, so it can be positioned relative to
@@ -974,7 +974,7 @@ const Select = class {
974
974
  * <label> element, ensuring that clicking the label text
975
975
  * focuses the select.
976
976
  */
977
- theme === 'ionic' && fill === 'outline' && h("div", { key: 'f567c3512f1c1482f5854cc09bcca2067431dc51', class: "select-outline" }), h("slot", { key: '4a332f517ee89bdb6da84c0dee9dea5f35f5a6cd', name: "start" }), h("div", { key: 'e9c541dcfe4b9d3cad4d4c3c094d7666e947cd46', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '3c663f69f85fd87ece0f2da081a3b64e5e140bde', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: '336f7c9564b7e19a8b93e2d8a497dbd3e5e4e993', class: "select-highlight" })), this.renderBottomContent()));
977
+ theme === 'ionic' && fill === 'outline' && h("div", { key: '14a2a14daa10625fa59f8f148e124a1c0c147319', class: "select-outline" }), h("slot", { key: 'a5a4372feffbeb3652e6045e64cbfacb66c58da9', name: "start" }), h("div", { key: 'b6ac054eaca720a21e0617cf413e576ef23a60e8', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), h("slot", { key: '140d299760a7c7f186b31e9e38f968534b1e116a', name: "end" }), shouldRenderInnerIcon && this.renderSelectIcon()), shouldRenderOuterIcon && this.renderSelectIcon(), shouldRenderHighlight && h("div", { key: 'b1a1e98302b0e87c3cd850e9abd8faf946a2b492', class: "select-highlight" })), this.renderBottomContent()));
978
978
  }
979
979
  get el() { return getElement(this); }
980
980
  static get watchers() { return {
@@ -1127,6 +1127,17 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1127
1127
  if (!slotName && nodes.every((n) => n.nodeType === Node.TEXT_NODE)) {
1128
1128
  return nodes.map((n) => { var _a; return (_a = n.textContent) === null || _a === void 0 ? void 0 : _a.trim(); }).join(' ') || null;
1129
1129
  }
1130
+ /**
1131
+ * Mirror known custom-element properties (e.g. ion-icon's `icon`)
1132
+ * onto attributes before cloning. Frameworks like Vue set these as
1133
+ * DOM properties, which `cloneNode` doesn't copy, so without this
1134
+ * step the cloned overlay copy renders without the prop's value.
1135
+ */
1136
+ nodes.forEach((n) => {
1137
+ if (n.nodeType === Node.ELEMENT_NODE) {
1138
+ reflectPropertiesToAttributes(n);
1139
+ }
1140
+ });
1130
1141
  // Clone each node into a temporary container
1131
1142
  const container = document.createElement('div');
1132
1143
  nodes.forEach((n) => {
@@ -1140,9 +1151,11 @@ const getOptionContent = (option, slotName, useHTML = false) => {
1140
1151
  }
1141
1152
  container.appendChild(clone);
1142
1153
  });
1143
- // Sanitize the cloned DOM in place. Author-written attributes (size,
1144
- // color, shape, etc.) are preserved; event handlers, javascript: URLs,
1145
- // and blocked tags are stripped.
1154
+ /**
1155
+ * Sanitize the cloned DOM in place. Trusted attributes (size, color,
1156
+ * shape, etc.) are preserved; event handlers, javascript: URLs, and
1157
+ * blocked tags are stripped.
1158
+ */
1146
1159
  sanitizeDOMTree(container);
1147
1160
  if (useHTML) {
1148
1161
  return container.innerHTML.trim() || null;
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { f as printIonWarning, r as registerInstance, c as createEvent, e as config, j as printIonError, h, d as Host, g as getElement } from './index-Omi_TcwW.js';
5
- import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-DLfuRiEz.js';
5
+ import { E as ENABLE_HTML_CONTENT_DEFAULT, a as sanitizeDOMString } from './config-C5F1aoVz.js';
6
6
  import { g as getElementRoot, r as raf } from './helpers-Do7zwvM1.js';
7
7
  import { c as createLockController } from './lock-controller-B-hirT0v.js';
8
8
  import { O as OVERLAY_GESTURE_PRIORITY, d as createDelegateController, e as createTriggerController, i as isCancel, j as prepareOverlay, k as setOverlayId, f as present, g as dismiss, h as eventMethod, s as safeCall, G as GESTURE } from './overlays-CpQ6Df2g.js';
@@ -1,4 +1,4 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- export{c as createAnimation}from"./p-DDFhx1YX.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./p-E1wtzfO0.js";export{iosTransitionAnimation}from"./p-BYAxJDlE.js";export{mdTransitionAnimation}from"./p-BQgCYKKG.js";export{g as getTimeGivenProgression}from"./p-hHmYLOfE.js";export{createGesture}from"./p-Cl0B-RWe.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./p-DaknVxZR.js";export{c as componentOnReady}from"./p-CHE1xWbg.js";export{L as LogLevel}from"./p-Omi_TcwW.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-u6HLvq0g.js";export{o as openURL}from"./p-DaJxRxSQ.js";export{m as menuController}from"./p-CK179dBb.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./p-BFBCtvFI.js";import"./p-BTEOs1at.js";import"./p-vXpMhGrs.js";import"./p-FvDKM4Ax.js";const e=e=>{const{swiper:o,extendParams:t}=e,s={effect:void 0,direction:"horizontal",initialSlide:0,loop:!1,parallax:!1,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,zoom:{maxRatio:3,minRatio:1,toggle:!1},touchRatio:1,touchAngle:45,simulateTouch:!0,touchStartPreventDefault:!1,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,loopAdditionalSlides:0,noSwiping:!0,runCallbacksOnInit:!0,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flipEffect:{slideShadows:!0,limitRotation:!0},cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:!1},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};o.pagination&&(s.pagination={type:"bullets",clickable:!1,hideOnClick:!1}),o.scrollbar&&(s.scrollbar={hide:!0}),t(s)};export{e as IonicSlides}
4
+ export{c as createAnimation}from"./p-DDFhx1YX.js";export{a as LIFECYCLE_DID_ENTER,c as LIFECYCLE_DID_LEAVE,L as LIFECYCLE_WILL_ENTER,b as LIFECYCLE_WILL_LEAVE,d as LIFECYCLE_WILL_UNLOAD,g as getIonPageElement}from"./p-E1wtzfO0.js";export{iosTransitionAnimation}from"./p-BYAxJDlE.js";export{mdTransitionAnimation}from"./p-BQgCYKKG.js";export{g as getTimeGivenProgression}from"./p-hHmYLOfE.js";export{createGesture}from"./p-Cl0B-RWe.js";export{g as getPlatforms,i as initialize,a as isPlatform}from"./p-DaknVxZR.js";export{c as componentOnReady}from"./p-CHE1xWbg.js";export{L as LogLevel}from"./p-Omi_TcwW.js";export{I as IonicSafeString,g as getMode,s as setupConfig}from"./p-pI5qh5HW.js";export{o as openURL}from"./p-DaJxRxSQ.js";export{m as menuController}from"./p-CK179dBb.js";export{b as actionSheetController,a as alertController,l as loadingController,m as modalController,p as pickerController,c as popoverController,t as toastController}from"./p-BFBCtvFI.js";import"./p-BTEOs1at.js";import"./p-vXpMhGrs.js";import"./p-FvDKM4Ax.js";const e=e=>{const{swiper:o,extendParams:t}=e,s={effect:void 0,direction:"horizontal",initialSlide:0,loop:!1,parallax:!1,slidesPerView:1,spaceBetween:0,speed:300,slidesPerColumn:1,slidesPerColumnFill:"column",slidesPerGroup:1,centeredSlides:!1,slidesOffsetBefore:0,slidesOffsetAfter:0,touchEventsTarget:"container",freeMode:!1,freeModeMomentum:!0,freeModeMomentumRatio:1,freeModeMomentumBounce:!0,freeModeMomentumBounceRatio:1,freeModeMomentumVelocityRatio:1,freeModeSticky:!1,freeModeMinimumVelocity:.02,autoHeight:!1,setWrapperSize:!1,zoom:{maxRatio:3,minRatio:1,toggle:!1},touchRatio:1,touchAngle:45,simulateTouch:!0,touchStartPreventDefault:!1,shortSwipes:!0,longSwipes:!0,longSwipesRatio:.5,longSwipesMs:300,followFinger:!0,threshold:0,touchMoveStopPropagation:!0,touchReleaseOnEdges:!1,iOSEdgeSwipeDetection:!1,iOSEdgeSwipeThreshold:20,resistance:!0,resistanceRatio:.85,watchSlidesProgress:!1,watchSlidesVisibility:!1,preventClicks:!0,preventClicksPropagation:!0,slideToClickedSlide:!1,loopAdditionalSlides:0,noSwiping:!0,runCallbacksOnInit:!0,coverflowEffect:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0},flipEffect:{slideShadows:!0,limitRotation:!0},cubeEffect:{slideShadows:!0,shadow:!0,shadowOffset:20,shadowScale:.94},fadeEffect:{crossFade:!1},a11y:{prevSlideMessage:"Previous slide",nextSlideMessage:"Next slide",firstSlideMessage:"This is the first slide",lastSlideMessage:"This is the last slide"}};o.pagination&&(s.pagination={type:"bullets",clickable:!1,hideOnClick:!1}),o.scrollbar&&(s.scrollbar={hide:!0}),t(s)};export{e as IonicSlides}