voyager-ionic-core 8.8.2 → 8.8.5

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 (103) hide show
  1. package/components/ion-action-sheet.js +1 -1
  2. package/components/ion-checkbox.js +1 -1
  3. package/components/ion-content.js +1 -1
  4. package/components/ion-datetime.js +1 -1
  5. package/components/ion-input-otp.js +1 -1
  6. package/components/ion-modal.js +1 -1
  7. package/components/ion-picker-column.js +1 -1
  8. package/components/ion-radio-group.js +1 -1
  9. package/components/ion-select-modal.js +1 -1
  10. package/components/ion-select-popover.js +1 -1
  11. package/components/ion-select.js +1 -1
  12. package/components/p-0z8QSI5b.js +4 -0
  13. package/components/{p-ApmKVjaE.js → p-BGHGpkPX.js} +1 -1
  14. package/components/p-BlNv564p.js +4 -0
  15. package/components/p-D-cP12ZN.js +4 -0
  16. package/components/p-D3Ti70Hx.js +4 -0
  17. package/components/{p-Bk2zuNWT.js → p-DvOO1fxp.js} +1 -1
  18. package/components/p-FBcnjE5W.js +4 -0
  19. package/components/p-SBseW5KJ.js +4 -0
  20. package/css/palettes/dark.always.css +1 -1
  21. package/css/palettes/dark.always.css.map +1 -1
  22. package/css/palettes/dark.class.css +1 -1
  23. package/css/palettes/dark.class.css.map +1 -1
  24. package/css/palettes/dark.system.css +1 -1
  25. package/css/palettes/dark.system.css.map +1 -1
  26. package/css/palettes/high-contrast-dark.always.css +1 -1
  27. package/css/palettes/high-contrast-dark.always.css.map +1 -1
  28. package/css/palettes/high-contrast-dark.class.css +1 -1
  29. package/css/palettes/high-contrast-dark.class.css.map +1 -1
  30. package/css/palettes/high-contrast-dark.system.css +1 -1
  31. package/css/palettes/high-contrast-dark.system.css.map +1 -1
  32. package/dist/cjs/ion-action-sheet.cjs.entry.js +4 -4
  33. package/dist/cjs/ion-app_8.cjs.entry.js +1 -1
  34. package/dist/cjs/ion-checkbox.cjs.entry.js +39 -32
  35. package/dist/cjs/ion-datetime_3.cjs.entry.js +17 -6
  36. package/dist/cjs/ion-input-otp.cjs.entry.js +21 -6
  37. package/dist/cjs/ion-modal.cjs.entry.js +99 -45
  38. package/dist/cjs/ion-picker-column.cjs.entry.js +4 -4
  39. package/dist/cjs/ion-radio_2.cjs.entry.js +13 -1
  40. package/dist/cjs/ion-select-modal.cjs.entry.js +18 -7
  41. package/dist/cjs/ion-select_3.cjs.entry.js +18 -7
  42. package/dist/collection/components/action-sheet/action-sheet.js +4 -4
  43. package/dist/collection/components/checkbox/checkbox.js +39 -32
  44. package/dist/collection/components/content/content.css +1 -1
  45. package/dist/collection/components/datetime/datetime.js +17 -6
  46. package/dist/collection/components/input-otp/input-otp.js +21 -6
  47. package/dist/collection/components/modal/modal.js +73 -44
  48. package/dist/collection/components/modal/safe-area-utils.js +27 -2
  49. package/dist/collection/components/picker-column/picker-column.js +5 -5
  50. package/dist/collection/components/radio-group/radio-group.js +13 -1
  51. package/dist/collection/components/radio-group/test/fixtures.js +2 -2
  52. package/dist/collection/components/select-modal/select-modal.js +18 -7
  53. package/dist/collection/components/select-modal/test/fixtures.js +4 -0
  54. package/dist/collection/components/select-popover/select-popover.js +18 -7
  55. package/dist/collection/components/select-popover/test/fixtures.js +4 -0
  56. package/dist/docs.json +1 -1
  57. package/dist/esm/ion-action-sheet.entry.js +4 -4
  58. package/dist/esm/ion-app_8.entry.js +1 -1
  59. package/dist/esm/ion-checkbox.entry.js +39 -32
  60. package/dist/esm/ion-datetime_3.entry.js +17 -6
  61. package/dist/esm/ion-input-otp.entry.js +21 -6
  62. package/dist/esm/ion-modal.entry.js +99 -45
  63. package/dist/esm/ion-picker-column.entry.js +5 -5
  64. package/dist/esm/ion-radio_2.entry.js +13 -1
  65. package/dist/esm/ion-select-modal.entry.js +18 -7
  66. package/dist/esm/ion-select_3.entry.js +18 -7
  67. package/dist/ionic/ionic.esm.js +1 -1
  68. package/dist/ionic/p-078037da.entry.js +4 -0
  69. package/dist/ionic/p-23ec35e4.entry.js +4 -0
  70. package/dist/ionic/p-268a3397.entry.js +4 -0
  71. package/dist/ionic/p-28a9e720.entry.js +4 -0
  72. package/dist/ionic/p-4c67ce4c.entry.js +4 -0
  73. package/dist/ionic/p-87125490.entry.js +4 -0
  74. package/dist/ionic/{p-4dd5e8e0.entry.js → p-8fda6a62.entry.js} +1 -1
  75. package/dist/ionic/{p-9eac4eb1.entry.js → p-aa812c4b.entry.js} +1 -1
  76. package/dist/ionic/p-cb27fe68.entry.js +4 -0
  77. package/dist/ionic/p-ce2edb36.entry.js +4 -0
  78. package/dist/types/components/checkbox/checkbox.d.ts +0 -1
  79. package/dist/types/components/datetime/datetime.d.ts +1 -0
  80. package/dist/types/components/modal/modal.d.ts +41 -3
  81. package/dist/types/components/modal/safe-area-utils.d.ts +16 -0
  82. package/dist/types/components/radio-group/test/fixtures.d.ts +1 -1
  83. package/dist/types/components/select-modal/select-modal.d.ts +1 -0
  84. package/dist/types/components/select-modal/test/fixtures.d.ts +1 -0
  85. package/dist/types/components/select-popover/select-popover.d.ts +1 -0
  86. package/dist/types/components/select-popover/test/fixtures.d.ts +1 -0
  87. package/hydrate/index.js +199 -87
  88. package/hydrate/index.mjs +199 -87
  89. package/package.json +4 -4
  90. package/components/p-1KVKSLu5.js +0 -4
  91. package/components/p-BI7WNErr.js +0 -4
  92. package/components/p-C7AoMl7c.js +0 -4
  93. package/components/p-D6pdfDIA.js +0 -4
  94. package/components/p-cvHphHJA.js +0 -4
  95. package/components/p-e-EDj2CO.js +0 -4
  96. package/dist/ionic/p-2d4eb1b4.entry.js +0 -4
  97. package/dist/ionic/p-3e143d1d.entry.js +0 -4
  98. package/dist/ionic/p-51c11c47.entry.js +0 -4
  99. package/dist/ionic/p-5681dde4.entry.js +0 -4
  100. package/dist/ionic/p-9fae83d8.entry.js +0 -4
  101. package/dist/ionic/p-c744307d.entry.js +0 -4
  102. package/dist/ionic/p-cb78f5a0.entry.js +0 -4
  103. package/dist/ionic/p-e6c5f060.entry.js +0 -4
package/hydrate/index.js CHANGED
@@ -9798,7 +9798,7 @@ class ActionSheet {
9798
9798
  if (isRadio) {
9799
9799
  htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
9800
9800
  }
9801
- return (hAsync("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass$3(b)), { 'action-sheet-selected': isActiveRadio }), onClick: () => {
9801
+ return (hAsync("button", Object.assign({}, htmlAttrs, { role: isRadio ? 'radio' : undefined, type: "button", id: buttonId, class: Object.assign(Object.assign({}, buttonClass$3(b)), (isRadio && { 'action-sheet-selected': isActiveRadio })), onClick: () => {
9802
9802
  if (isRadio) {
9803
9803
  this.selectRadioButton(b);
9804
9804
  }
@@ -9813,12 +9813,12 @@ class ActionSheet {
9813
9813
  const cancelButton = allButtons.find((b) => b.role === 'cancel');
9814
9814
  const buttons = allButtons.filter((b) => b.role !== 'cancel');
9815
9815
  const headerID = `action-sheet-${overlayIndex}-header`;
9816
- return (hAsync(Host, Object.assign({ key: '173fcff5b1da7c33c267de4667591c946b8c8d03', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
9816
+ return (hAsync(Host, Object.assign({ key: 'a56ee2ab59c763036140dbd10306a708c26e3c17', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
9817
9817
  zIndex: `${20000 + this.overlayIndex}`,
9818
- }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '521ede659f747864f6c974e09016436eceb7158c', tappable: this.backdropDismiss }), hAsync("div", { key: '7a7946fc434bc444f16a70638f5e948c69d33fcd', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'bcff39a580489dbafa255842e57aa8602c6d0f18', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '84bba13ce14261f0f0daa3f9c77648c9e7f36e0e', class: "action-sheet-container" }, hAsync("div", { key: 'd9c8ac404fd6719a7adf8cb36549f67616f9a0c4', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (hAsync("div", { key: '180433a8ad03ef5c54728a1a8f34715b6921d658', id: headerID, class: {
9818
+ }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: 'c32eb4281fd6348c7d3989a3f509c211263048e6', tappable: this.backdropDismiss }), hAsync("div", { key: '7f0123114a876fc7cfff3cfb564aded4a7017797', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '645b1d5fde39a8907f21983d66e6ecb7a99aa05d', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: 'a78fb02848462d1a4f9356ac4fa1c43a2e5d90e4', class: "action-sheet-container" }, hAsync("div", { key: '5e846f53e067b211b985d6e1512b72b9d7c1a3aa', class: "action-sheet-group", ref: (el) => (this.groupEl = el), role: hasRadioButtons ? 'radiogroup' : undefined }, header !== undefined && (hAsync("div", { key: 'a90a0e096e1b2fa78b9adb9253c0a517f16e62cb', id: headerID, class: {
9819
9819
  'action-sheet-title': true,
9820
9820
  'action-sheet-has-sub-title': this.subHeader !== undefined,
9821
- } }, header, this.subHeader && hAsync("div", { key: '7138e79e61b1a8f42bc5a9175c57fa2f15d7ec5a', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (hAsync("div", { key: 'b617c722f5b8028d73ed34b69310f312c65f34a7', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: 'd0dd876fc48815df3710413c201c0b445a8e16c0' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: 'e7b960157cc6fc5fe92a12090b2be55e8ae072e4', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: '05498ffc60cab911dbff0ecbc6168dea59ada9a5', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '3d401346cea301be4ca03671f7370f6f4b0b6bde' })))))), hAsync("div", { key: '971f3c5fcc07f36c28eb469a47ec0290c692e139', tabindex: "0", "aria-hidden": "true" })));
9821
+ } }, header, this.subHeader && hAsync("div", { key: '40f00b12341625c548546de1885b9c9d93bc169c', class: "action-sheet-sub-title" }, this.subHeader))), this.renderActionSheetButtons(buttons)), cancelButton && (hAsync("div", { key: 'ef6974cb63089623df08087274b82745443cee8c', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: 'b02911a6491d60f9dcb5da7d942392a9e96552c1' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '1187433e676eda55e52b5ae328a8e68bba22deb6', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: '079ab2a6bd40b996950053617f1c1c8207ecb1f1', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '3bc473add8ac299f202f8c359d26708872c02f52' })))))), hAsync("div", { key: '9b1ae7b4e3649e9b85632f0d65627ca81499e68d', tabindex: "0", "aria-hidden": "true" })));
9822
9822
  }
9823
9823
  get el() { return getElement(this); }
9824
9824
  static get watchers() { return {
@@ -12051,14 +12051,12 @@ class Checkbox {
12051
12051
  this.onDivLabelClick = (ev) => {
12052
12052
  ev.stopPropagation();
12053
12053
  };
12054
- this.onSlotChange = () => {
12055
- this.hasLabelContent = this.el.textContent !== '';
12056
- };
12057
12054
  }
12058
12055
  connectedCallback() {
12059
12056
  const { el } = this;
12060
12057
  // Always set initial state
12061
12058
  this.isInvalid = checkInvalidState(el);
12059
+ this.hasLabelContent = this.el.textContent !== '';
12062
12060
  }
12063
12061
  componentWillLoad() {
12064
12062
  this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
@@ -12108,7 +12106,7 @@ class Checkbox {
12108
12106
  renderHiddenInput(true, el, name, checked ? value : '', disabled);
12109
12107
  // The host element must have a checkbox role to ensure proper VoiceOver
12110
12108
  // support in Safari for accessibility.
12111
- return (hAsync(Host, { key: '78eb720868106bcbe8357e50ebae2ab2fce8bdd6', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses$1(color, {
12109
+ return (hAsync(Host, { key: '0da370f94c5cdf3b08bc9008395558334a300f35', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, "aria-labelledby": this.hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, "aria-required": required ? 'true' : undefined, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses$1(color, {
12112
12110
  [mode]: true,
12113
12111
  'in-item': hostContext('ion-item', el),
12114
12112
  'checkbox-checked': checked,
@@ -12118,10 +12116,10 @@ class Checkbox {
12118
12116
  [`checkbox-justify-${justify}`]: justify !== undefined,
12119
12117
  [`checkbox-alignment-${alignment}`]: alignment !== undefined,
12120
12118
  [`checkbox-label-placement-${labelPlacement}`]: true,
12121
- }) }, hAsync("label", { key: '3bd09a96e126bc72a0589a9c9ff8459cb60e1084', class: "checkbox-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: 'f55c566f36dc6b0f069c75dccdebd2c5b3e7385e', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), hAsync("div", { key: '11db1139eabfe0b83688c574b81d1a6e8b7ae8c6', class: {
12119
+ }) }, hAsync("label", { key: '991f1763356671230af119a5fbdc22d0a39974e7', class: "checkbox-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: '982f8a7f84d013b272b17607936355d2b6c251f4', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, required: required }, inheritedAttributes)), hAsync("div", { key: 'c8f9e8baa20ac68e69fd3c6fcf0e7a26a1084d83', class: {
12122
12120
  'label-text-wrapper': true,
12123
12121
  'label-text-wrapper-hidden': !this.hasLabelContent,
12124
- }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '6b3dd09e86063e2bc48014a1715cd788038ca01d', onSlotchange: this.onSlotChange }), this.renderHintText()), hAsync("div", { key: 'bb2c75c8a893fd81e213c6b2ba807d5cba5a4966', class: "native-wrapper" }, hAsync("svg", { key: '028a4c7d211c3697a91743d6242f202209e14c1a', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
12122
+ }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '6018205e0a73dec826c7881d687f1c2ca8dcb0ab' }), this.renderHintText()), hAsync("div", { key: '57530b9d6ff59ee7ab98f960cd65d66ee87cfd1d', class: "native-wrapper" }, hAsync("svg", { key: '63d719154ff44459e9ca448e3f5d7de94d9ab248', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container", "aria-hidden": "true" }, path)))));
12125
12123
  }
12126
12124
  getSVGPath(mode, indeterminate) {
12127
12125
  let path = indeterminate ? (hAsync("path", { d: "M6 12L18 12", part: "mark" })) : (hAsync("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
@@ -12369,7 +12367,7 @@ const isRTL$1 = (hostEl) => {
12369
12367
  return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
12370
12368
  };
12371
12369
 
12372
- const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
12370
+ const contentCss = () => `:host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom) + var(--ion-content-safe-area-padding-bottom, 0px));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:""}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}`;
12373
12371
 
12374
12372
  /**
12375
12373
  * @slot - Content is placed in the scrollable area if provided without a slot.
@@ -15350,6 +15348,12 @@ class Datetime {
15350
15348
  this.el.classList.add('datetime-ready');
15351
15349
  });
15352
15350
  };
15351
+ this.loadTimeoutCleanup = () => {
15352
+ if (this.loadTimeout) {
15353
+ clearTimeout(this.loadTimeout);
15354
+ this.loadTimeout = undefined;
15355
+ }
15356
+ };
15353
15357
  this.processValue = (value) => {
15354
15358
  const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
15355
15359
  const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
@@ -15497,9 +15501,10 @@ class Datetime {
15497
15501
  if (!prevMonth) {
15498
15502
  return;
15499
15503
  }
15504
+ const left = prevMonth.offsetWidth * 2;
15500
15505
  calendarBodyRef.scrollTo({
15501
15506
  top: 0,
15502
- left: 0,
15507
+ left: left * (isRTL$1(this.el) ? 1 : -1),
15503
15508
  behavior: 'smooth',
15504
15509
  });
15505
15510
  };
@@ -15621,15 +15626,16 @@ class Datetime {
15621
15626
  }
15622
15627
  connectedCallback() {
15623
15628
  this.clearFocusVisible = startFocusVisible(this.el).destroy;
15629
+ this.loadTimeout = setTimeout(() => {
15630
+ this.ensureReadyIfVisible();
15631
+ }, 100);
15624
15632
  }
15625
15633
  disconnectedCallback() {
15626
15634
  if (this.clearFocusVisible) {
15627
15635
  this.clearFocusVisible();
15628
15636
  this.clearFocusVisible = undefined;
15629
15637
  }
15630
- if (this.loadTimeout) {
15631
- clearTimeout(this.loadTimeout);
15632
- }
15638
+ this.loadTimeoutCleanup();
15633
15639
  }
15634
15640
  initializeListeners() {
15635
15641
  this.initializeCalendarListener();
@@ -15677,7 +15683,10 @@ class Datetime {
15677
15683
  * we still initialize listeners and mark the component as ready.
15678
15684
  *
15679
15685
  * We schedule this after everything has had a chance to run.
15686
+ *
15687
+ * We also clean up the load timeout to ensure that we don't have multiple timeouts running.
15680
15688
  */
15689
+ this.loadTimeoutCleanup();
15681
15690
  this.loadTimeout = setTimeout(() => {
15682
15691
  this.ensureReadyIfVisible();
15683
15692
  }, 100);
@@ -16436,7 +16445,7 @@ class Datetime {
16436
16445
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
16437
16446
  const hasWheelVariant = hasDatePresentation && preferWheel;
16438
16447
  renderHiddenInput(true, el, name, formatValue(value), disabled);
16439
- return (hAsync(Host, { key: '191a6d7ce7bc2d57bfaaebd8aee31e3c36f2b56a', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
16448
+ return (hAsync(Host, { key: '59e0811aa273e88dfb8e4b703e6824088a457380', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
16440
16449
  [mode]: true,
16441
16450
  ['datetime-readonly']: readonly,
16442
16451
  ['datetime-disabled']: disabled,
@@ -16446,7 +16455,7 @@ class Datetime {
16446
16455
  [`datetime-size-${size}`]: true,
16447
16456
  [`datetime-prefer-wheel`]: hasWheelVariant,
16448
16457
  [`datetime-grid`]: isGridStyle,
16449
- })) }, hAsync("div", { key: '5c75290394cf7dc37c7dcba6372af003a50a9c04', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
16458
+ })) }, hAsync("div", { key: '3753ff3dde3085070916c3de83687a219a49e553', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
16450
16459
  }
16451
16460
  get el() { return getElement(this); }
16452
16461
  static get watchers() { return {
@@ -19607,9 +19616,18 @@ class InputOTP {
19607
19616
  * - Tab: Allows normal tab navigation between components
19608
19617
  */
19609
19618
  this.onKeyDown = (index) => (event) => {
19610
- const { length } = this;
19619
+ const { disabled, length, readonly } = this;
19611
19620
  const rtl = isRTL$1(this.el);
19612
19621
  const input = event.target;
19622
+ if (disabled) {
19623
+ return;
19624
+ }
19625
+ if (readonly) {
19626
+ if (event.key === 'Backspace' || event.key === 'Delete') {
19627
+ event.preventDefault();
19628
+ return;
19629
+ }
19630
+ }
19613
19631
  // Meta shortcuts are used to copy, paste, and select text
19614
19632
  // We don't want to handle these keys here
19615
19633
  const metaShortcuts = ['a', 'c', 'v', 'x', 'r', 'z', 'y'];
@@ -19672,10 +19690,13 @@ class InputOTP {
19672
19690
  */
19673
19691
  this.onInput = (index) => (event) => {
19674
19692
  var _a, _b;
19675
- const { length, validKeyPattern } = this;
19693
+ const { disabled, length, readonly, validKeyPattern } = this;
19676
19694
  const input = event.target;
19677
19695
  const value = input.value;
19678
19696
  const previousValue = this.previousInputValues[index] || '';
19697
+ if (disabled || readonly) {
19698
+ return;
19699
+ }
19679
19700
  // 1. Autofill handling
19680
19701
  // If the length of the value increases by more than 1 from the previous
19681
19702
  // value, treat this as autofill. This is to prevent the case where the
@@ -19794,8 +19815,11 @@ class InputOTP {
19794
19815
  */
19795
19816
  this.onPaste = (event) => {
19796
19817
  var _a, _b;
19797
- const { inputRefs, length, validKeyPattern } = this;
19818
+ const { disabled, inputRefs, length, readonly, validKeyPattern } = this;
19798
19819
  event.preventDefault();
19820
+ if (disabled || readonly) {
19821
+ return;
19822
+ }
19799
19823
  const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
19800
19824
  // If there is no pasted text, still emit the input change event
19801
19825
  // because this is how the native input element behaves
@@ -20082,7 +20106,7 @@ class InputOTP {
20082
20106
  const tabbableIndex = this.getTabbableIndex();
20083
20107
  const pattern = this.getPattern();
20084
20108
  const hasDescription = ((_b = (_a = el.querySelector('.input-otp-description')) === null || _a === void 0 ? void 0 : _a.textContent) === null || _b === void 0 ? void 0 : _b.trim()) !== '';
20085
- return (hAsync(Host, { key: 'f15a29fb17b681ef55885ca36d3d5f899cbaca83', class: createColorClasses$1(color, {
20109
+ return (hAsync(Host, { key: '5c1386ae6b8038ec33ca94fd818c9353b1b37f75', class: createColorClasses$1(color, {
20086
20110
  [mode]: true,
20087
20111
  'has-focus': hasFocus,
20088
20112
  [`input-otp-size-${size}`]: true,
@@ -20090,10 +20114,10 @@ class InputOTP {
20090
20114
  [`input-otp-fill-${fill}`]: true,
20091
20115
  'input-otp-disabled': disabled,
20092
20116
  'input-otp-readonly': readonly,
20093
- }) }, hAsync("div", Object.assign({ key: 'd7e1d4edd8aafcf2ed4313301287282e90fc7e82', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index) => (hAsync(Fragment, null, hAsync("div", { class: "native-wrapper" }, hAsync("input", { class: "native-input", id: `${inputId}-${index}`, "aria-label": `Input ${index + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index === tabbableIndex ? 0 : -1, value: inputValues[index] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index] = el), onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && hAsync("div", { class: "input-otp-separator" }))))), hAsync("div", { key: '3724a3159d02860971879a906092f9965f5a7c47', class: {
20117
+ }) }, hAsync("div", Object.assign({ key: '9a19129688e55095f8386826c73ef3f9744becff', role: "group", "aria-label": "One-time password input", class: "input-otp-group" }, inheritedAttributes), Array.from({ length }).map((_, index) => (hAsync(Fragment, null, hAsync("div", { class: "native-wrapper" }, hAsync("input", { class: "native-input", id: `${inputId}-${index}`, "aria-label": `Input ${index + 1} of ${length}`, type: "text", autoCapitalize: autocapitalize, inputmode: inputmode, pattern: pattern, disabled: disabled, readOnly: readonly, tabIndex: index === tabbableIndex ? 0 : -1, value: inputValues[index] || '', autocomplete: "one-time-code", ref: (el) => (inputRefs[index] = el), onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && hAsync("div", { class: "input-otp-separator" }))))), hAsync("div", { key: '7853819c3610c4691191f1836b947bf4ec17939d', class: {
20094
20118
  'input-otp-description': true,
20095
20119
  'input-otp-description-hidden': !hasDescription,
20096
- } }, hAsync("slot", { key: '11baa2624926a08274508afe0833d9237a8dc35c' }))));
20120
+ } }, hAsync("slot", { key: 'f4674d47d3d3991f21a0a79321ebc323968071dc' }))));
20097
20121
  }
20098
20122
  get el() { return getElement(this); }
20099
20123
  static get watchers() { return {
@@ -24984,6 +25008,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
24984
25008
  const MODAL_INSET_MIN_WIDTH = 768;
24985
25009
  const MODAL_INSET_MIN_HEIGHT = 600;
24986
25010
  const EDGE_THRESHOLD = 5;
25011
+ /**
25012
+ * CSS values for `--width` / `--height` that are treated as fullscreen
25013
+ * (modal touches the corresponding screen edges). Empty string means the
25014
+ * property was not overridden. See `hasCustomModalDimensions()`.
25015
+ */
25016
+ const FULLSCREEN_SIZE_VALUES = new Set(['', '100%', '100vw', '100vh', '100dvw', '100dvh', '100svw', '100svh']);
24987
25017
  /**
24988
25018
  * Cache for resolved root safe-area-top value, invalidated once per frame.
24989
25019
  */
@@ -25032,6 +25062,22 @@ const getRootSafeAreaTop = () => {
25032
25062
  }
25033
25063
  return value;
25034
25064
  };
25065
+ /**
25066
+ * True when the modal host declares BOTH a non-fullscreen `--width` AND a
25067
+ * non-fullscreen `--height` (i.e. a centered-dialog-like modal that doesn't
25068
+ * touch any screen edge).
25069
+ *
25070
+ * The conservative "both axes" check avoids mis-zeroing safe-area for
25071
+ * partial-custom modals where the modal still touches top/bottom edges
25072
+ * (e.g. only `--width` overridden). Partial cases fall through to the
25073
+ * existing position-based post-animation correction.
25074
+ */
25075
+ const hasCustomModalDimensions = (hostEl) => {
25076
+ const styles = getComputedStyle(hostEl);
25077
+ const width = styles.getPropertyValue('--width').trim();
25078
+ const height = styles.getPropertyValue('--height').trim();
25079
+ return !FULLSCREEN_SIZE_VALUES.has(width) && !FULLSCREEN_SIZE_VALUES.has(height);
25080
+ };
25035
25081
  /**
25036
25082
  * Returns the initial safe-area configuration based on modal type.
25037
25083
  * This is called before animation starts and uses configuration-based prediction.
@@ -25066,8 +25112,11 @@ const getInitialSafeAreaConfig = (context) => {
25066
25112
  }
25067
25113
  // On viewports that meet the centered dialog media query breakpoints,
25068
25114
  // regular modals render as centered dialogs (not fullscreen), so they
25069
- // don't touch any screen edges and don't need safe-area insets.
25070
- if (isCenteredDialogViewport()) {
25115
+ // don't touch any screen edges and don't need safe-area insets. Also
25116
+ // applies to phone viewports when the modal declares custom --width and
25117
+ // --height; these don't touch screen edges either, so the initial
25118
+ // prediction must be zero to avoid a post-animation correction flash.
25119
+ if (isCenteredDialogViewport() || context.hasCustomDimensions) {
25071
25120
  return {
25072
25121
  top: '0px',
25073
25122
  bottom: '0px',
@@ -25379,12 +25428,10 @@ class Modal {
25379
25428
  // since the viewport may have crossed the centered-dialog breakpoint.
25380
25429
  if (!context.isSheetModal && !context.isCardModal) {
25381
25430
  this.updateSafeAreaOverrides();
25382
- // Re-evaluate fullscreen safe-area padding: clear first, then re-apply
25383
- if (this.wrapperEl) {
25384
- this.wrapperEl.style.removeProperty('height');
25385
- this.wrapperEl.style.removeProperty('padding-bottom');
25386
- }
25387
- this.applyFullscreenSafeArea();
25431
+ // Re-evaluate fullscreen safe-area padding: clear first, then re-apply.
25432
+ const { contentEl, hasFooter } = this.findContentAndFooter();
25433
+ this.clearContentSafeAreaPadding(contentEl);
25434
+ this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
25388
25435
  }
25389
25436
  }, 50); // Debounce to avoid excessive calls during active resizing
25390
25437
  }
@@ -26131,6 +26178,11 @@ class Modal {
26131
26178
  }
26132
26179
  /**
26133
26180
  * Creates the context object for safe-area utilities.
26181
+ *
26182
+ * `hasCustomDimensions` is only set by `setInitialSafeAreaOverrides()`
26183
+ * because it is only read by `getInitialSafeAreaConfig()`. Other callers
26184
+ * (resize handler, post-animation update, fullscreen-padding apply) would
26185
+ * pay a `getComputedStyle()` cost for a value they never consult.
26134
26186
  */
26135
26187
  getSafeAreaContext() {
26136
26188
  return {
@@ -26152,7 +26204,7 @@ class Modal {
26152
26204
  * sheets to prevent header content from getting double-offset padding).
26153
26205
  */
26154
26206
  setInitialSafeAreaOverrides() {
26155
- const context = this.getSafeAreaContext();
26207
+ const context = Object.assign(Object.assign({}, this.getSafeAreaContext()), { hasCustomDimensions: hasCustomModalDimensions(this.el) });
26156
26208
  const safeAreaConfig = getInitialSafeAreaConfig(context);
26157
26209
  applySafeAreaOverrides(this.el, safeAreaConfig);
26158
26210
  // Set the internal offset property with the resolved root safe-area-top value
@@ -26192,59 +26244,85 @@ class Modal {
26192
26244
  applySafeAreaOverrides(el, safeAreaConfig);
26193
26245
  }
26194
26246
  /**
26195
- * Applies padding-bottom to fullscreen modal wrapper to prevent
26196
- * content from overlapping system navigation bar.
26247
+ * Applies safe-area-bottom scroll padding to ion-content inside
26248
+ * fullscreen modals that have no ion-footer. This prevents content
26249
+ * from being hidden behind the system navigation bar while keeping
26250
+ * the modal background edge-to-edge (no visible gap).
26197
26251
  */
26198
26252
  applyFullscreenSafeArea() {
26199
- const { wrapperEl, el } = this;
26200
- if (!wrapperEl)
26201
- return;
26202
26253
  const context = this.getSafeAreaContext();
26203
26254
  if (context.isSheetModal || context.isCardModal)
26204
26255
  return;
26205
- // Check for standard Ionic layout children (ion-content, ion-footer),
26206
- // searching one level deep for wrapped components (e.g.,
26207
- // <app-footer><ion-footer>...</ion-footer></app-footer>).
26208
- // Note: uses a manual loop instead of querySelector(':scope > ...') because
26209
- // Stencil's mock-doc (used in spec tests) does not support :scope.
26210
- let hasContent = false;
26256
+ const { contentEl, hasFooter } = this.findContentAndFooter();
26257
+ this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
26258
+ }
26259
+ /**
26260
+ * Sets --ion-content-safe-area-padding-bottom on the given ion-content
26261
+ * when no footer is present, so ion-content's .inner-scroll includes
26262
+ * safe-area-bottom in its scroll padding. This keeps the modal background
26263
+ * edge-to-edge while ensuring content scrolls clear of the system nav bar.
26264
+ *
26265
+ * --ion-content-safe-area-padding-bottom is an internal CSS property used
26266
+ * only by this code path. It is not part of ion-content's public API and
26267
+ * should not be set by consumers. The default of 0px makes it a no-op
26268
+ * when unset, which is the expected state for ion-content used outside of
26269
+ * a fullscreen modal without a footer.
26270
+ */
26271
+ applyFullscreenSafeAreaTo(contentEl, hasFooter) {
26272
+ // Only apply for standard Ionic layouts (has ion-content but no
26273
+ // ion-footer). When a footer is present it handles its own safe-area
26274
+ // padding. Custom modals with raw HTML are developer-controlled.
26275
+ if (!contentEl || hasFooter)
26276
+ return;
26277
+ contentEl.style.setProperty('--ion-content-safe-area-padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
26278
+ }
26279
+ /**
26280
+ * Removes the internal --ion-content-safe-area-padding-bottom property
26281
+ * from an already-located ion-content. Callers do their own
26282
+ * findContentAndFooter() so they can also read hasFooter if needed.
26283
+ */
26284
+ clearContentSafeAreaPadding(contentEl) {
26285
+ if (!contentEl)
26286
+ return;
26287
+ contentEl.style.removeProperty('--ion-content-safe-area-padding-bottom');
26288
+ }
26289
+ /**
26290
+ * Finds ion-content and ion-footer among direct children and one level of
26291
+ * grandchildren (for wrapped components like <app-footer><ion-footer>).
26292
+ *
26293
+ * Intentionally does NOT use findIonContent() or querySelector() because
26294
+ * those search the full subtree and would match ion-content inside nested
26295
+ * routes/pages. We only want direct slot children (+ one wrapper level).
26296
+ *
26297
+ * Uses a manual loop instead of querySelector(':scope > ...') because
26298
+ * Stencil's mock-doc (used in spec tests) does not support :scope.
26299
+ */
26300
+ findContentAndFooter() {
26301
+ let contentEl = null;
26211
26302
  let hasFooter = false;
26212
- for (const child of Array.from(el.children)) {
26303
+ for (const child of Array.from(this.el.children)) {
26213
26304
  if (child.tagName === 'ION-CONTENT')
26214
- hasContent = true;
26305
+ contentEl = child;
26215
26306
  if (child.tagName === 'ION-FOOTER')
26216
26307
  hasFooter = true;
26217
26308
  for (const grandchild of Array.from(child.children)) {
26218
- if (grandchild.tagName === 'ION-CONTENT')
26219
- hasContent = true;
26309
+ if (grandchild.tagName === 'ION-CONTENT' && !contentEl)
26310
+ contentEl = grandchild;
26220
26311
  if (grandchild.tagName === 'ION-FOOTER')
26221
26312
  hasFooter = true;
26222
26313
  }
26223
26314
  }
26224
- // Only apply wrapper padding for standard Ionic layouts (has ion-content
26225
- // but no ion-footer). Custom modals with raw HTML are fully
26226
- // developer-controlled and should not be modified.
26227
- if (!hasContent || hasFooter)
26228
- return;
26229
- // Reduce wrapper height by safe-area and add equivalent padding so the
26230
- // total visual size stays the same but the flex content area shrinks.
26231
- // Using height + padding instead of box-sizing: border-box avoids
26232
- // breaking custom modals that set --border-width (border-box would
26233
- // include the border inside the height, changing the layout).
26234
- wrapperEl.style.setProperty('height', 'calc(var(--height) - var(--ion-safe-area-bottom, 0px))');
26235
- wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
26315
+ return { contentEl, hasFooter };
26236
26316
  }
26237
26317
  /**
26238
- * Clears all safe-area overrides and padding from wrapper.
26318
+ * Clears all safe-area overrides and padding.
26239
26319
  */
26240
26320
  cleanupSafeAreaOverrides() {
26241
26321
  clearSafeAreaOverrides(this.el);
26242
26322
  // Remove internal sheet offset property
26243
26323
  this.el.style.removeProperty('--ion-modal-offset-top');
26244
- if (this.wrapperEl) {
26245
- this.wrapperEl.style.removeProperty('height');
26246
- this.wrapperEl.style.removeProperty('padding-bottom');
26247
- }
26324
+ const { contentEl } = this.findContentAndFooter();
26325
+ this.clearContentSafeAreaPadding(contentEl);
26248
26326
  }
26249
26327
  render() {
26250
26328
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
@@ -26253,20 +26331,20 @@ class Modal {
26253
26331
  const isCardModal = presentingElement !== undefined && mode === 'ios';
26254
26332
  const isHandleCycle = handleBehavior === 'cycle';
26255
26333
  const isSheetModalWithHandle = isSheetModal && showHandle;
26256
- return (hAsync(Host, Object.assign({ key: '1a53e8f87532abccc169ca4b24973a39c5f9ba16', "no-router": true,
26334
+ return (hAsync(Host, Object.assign({ key: '4bf38aa67df9a3f977163bba5423960bbafd16de', "no-router": true,
26257
26335
  // Allow the modal to be navigable when the handle is focusable
26258
26336
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
26259
26337
  zIndex: `${20000 + this.overlayIndex}`,
26260
- }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), hAsync("ion-backdrop", { key: 'fa8e0a436c0d458331402e1850f87af3dc97b582', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: 'f00de6027d3c8b5bc93db3b0f7a50a87628d40bb', class: "modal-shadow" }), hAsync("div", Object.assign({ key: 'ae5e33bd6c58e541edb2edbca92420ea02dd5175',
26338
+ }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle, onFocus: this.onModalFocus }), hAsync("ion-backdrop", { key: '866da40cc5fc8d3e36637098fb3066a5bc9f4e0f', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: '5a2a05514ea8592c8feb0465e504aa7c7af17963', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '4d327115306451f57d190b06ab8cbb6191a6f1d7',
26261
26339
  /*
26262
26340
  role and aria-modal must be used on the
26263
26341
  same element. They must also be set inside the
26264
26342
  shadow DOM otherwise ion-button will not be highlighted
26265
26343
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
26266
26344
  */
26267
- role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: '141cdd8f8522331f4b764e2a4d79ec6596b1eb3a', class: "modal-handle",
26345
+ role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: 'd1882835cc049232c0d957e3ba1e79676a07d179', class: "modal-handle",
26268
26346
  // Prevents the handle from receiving keyboard focus when it does not cycle
26269
- tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), hAsync("slot", { key: '7de20298b61abee67a16d275c9ebd9a25ce7dd26', onSlotchange: this.onSlotChange }))));
26347
+ tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle", ref: (el) => (this.dragHandleEl = el) })), hAsync("slot", { key: '81dc58b09cf7d7022b04cd170f53113604364d5e', onSlotchange: this.onSlotChange }))));
26270
26348
  }
26271
26349
  get el() { return getElement(this); }
26272
26350
  static get watchers() { return {
@@ -28594,7 +28672,7 @@ class PickerColumn {
28594
28672
  * Because this initial call to scrollActiveItemIntoView has to fire before
28595
28673
  * the scroll listener is set up, we need to manage the active class manually.
28596
28674
  */
28597
- const oldActive = getElementRoot(el).querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
28675
+ const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
28598
28676
  if (oldActive) {
28599
28677
  this.setPickerItemActiveState(oldActive, false);
28600
28678
  }
@@ -28694,14 +28772,14 @@ class PickerColumn {
28694
28772
  render() {
28695
28773
  const { color, disabled, isActive, numericInput } = this;
28696
28774
  const mode = getIonMode$1(this);
28697
- return (hAsync(Host, { key: 'db903fd415f8a2d91994dececca481c1af8ba6a9', class: createColorClasses$1(color, {
28775
+ return (hAsync(Host, { key: '234c96a501d7ac413b9b0ea56b33017681e25b40', class: createColorClasses$1(color, {
28698
28776
  [mode]: true,
28699
28777
  ['picker-column-active']: isActive,
28700
28778
  ['picker-column-numeric-input']: numericInput,
28701
28779
  ['picker-column-disabled']: disabled,
28702
- }) }, hAsync("slot", { key: '02ce9e1dd7df91afcd50b06416552bcffb5dec98', name: "prefix" }), hAsync("div", { key: '6dfd7d2429bec19244a6b1afb4448121963a031b', class: "picker-opts", ref: (el) => {
28780
+ }) }, hAsync("slot", { key: '9dc15ea0601ddd2cb2e0a745e91e036a8bd96f8b', name: "prefix" }), hAsync("div", { key: 'de4fe28ee4bc46b7c0420d6ab0df0e7809443da9', class: "picker-opts", ref: (el) => {
28703
28781
  this.scrollEl = el;
28704
- }, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, hAsync("div", { key: 'e30ce0b9cefbfe4d4441fa33acf595da31855c3f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '8be2bd293c12c6ba720d9b31d0d561a96f42e97d', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '8afdcddddabbf646fbb55cb0ba4448309a2c1dd9', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("slot", { key: '6aa0dacc34d6848575ad5b122b9046982308ca43' }), hAsync("div", { key: '92ec8a357414c1b779b11d1dd18fb87a7ee63982', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: 'b89457cb74b5907c25594ff6720ac54ca537e933', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '5bbc92e6bc24de08e39873bf08c5b668373ac0f8', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), hAsync("slot", { key: 'd7bf2b519214f0f3576a4ca79844ad97827dd97f', name: "suffix" })));
28782
+ }, role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": this.getOptionValueText(this.activeItem), "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }, hAsync("div", { key: '5297617462cc30e9444039ae032d8bdf718349af', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '55ea39ef867bcb1a11a912d52ecd20cb886c5fb3', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '3496730ce6182ebfd33e0ee4bafc130feb575a31', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("slot", { key: '44c3628aa957d60f799dc7019f72fe8b676c7843' }), hAsync("div", { key: '5a1809f6c949678a67e0d4b5bfe93ea335c0161d', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '98fd57f1c66dbaebc2db2dd5da142671b3159fd1', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '85590708abddfa885994e549deac64866fec938f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), hAsync("slot", { key: 'bb7e674f543696a80fcbfb1f68f2e975826898a6', name: "suffix" })));
28705
28783
  }
28706
28784
  get el() { return getElement(this); }
28707
28785
  static get watchers() { return {
@@ -31279,6 +31357,18 @@ class RadioGroup {
31279
31357
  // to the bottom of the screen
31280
31358
  ev.preventDefault();
31281
31359
  }
31360
+ // Inside a select interface, Enter commits the focused radio
31361
+ // value (matching native <select>). The !ev.repeat guard stops
31362
+ // a held Enter on the triggering ion-select from re-committing
31363
+ // once focus lands in the opened popover/modal.
31364
+ if (ev.key === 'Enter' && inSelectInterface && !ev.repeat) {
31365
+ const previousValue = this.value;
31366
+ this.value = current.value;
31367
+ if (previousValue !== this.value) {
31368
+ this.emitValueChange(ev);
31369
+ }
31370
+ ev.preventDefault();
31371
+ }
31282
31372
  }
31283
31373
  }
31284
31374
  /** @internal */
@@ -31311,7 +31401,7 @@ class RadioGroup {
31311
31401
  const { label, labelId, el, name, value } = this;
31312
31402
  const mode = getIonMode$1(this);
31313
31403
  renderHiddenInput(true, el, name, value, false);
31314
- return (hAsync(Host, { key: 'db593b3ed511e9395e3c7bfd91b787328692cd6d', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), hAsync("slot", { key: 'd683b01c1ba34fe843c4b320bce4661a117472a5' })));
31404
+ return (hAsync(Host, { key: '377e4aa3a656cc84b742f9d7a7d4be65d20c69f5', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.hintTextId, "aria-invalid": this.isInvalid ? 'true' : undefined, onClick: this.onClick, class: mode }, this.renderHintText(), hAsync("slot", { key: 'c3187a2497773b4f15cea3b413b036502bcec8c0' })));
31315
31405
  }
31316
31406
  get el() { return getElement(this); }
31317
31407
  static get watchers() { return {
@@ -37401,6 +37491,10 @@ const selectModalMdCss = () => `.sc-ion-select-modal-md-h{height:100%}ion-list.s
37401
37491
  class SelectModal {
37402
37492
  constructor(hostRef) {
37403
37493
  registerInstance(this, hostRef);
37494
+ // Tracks the option that received Enter-keydown so keyup only
37495
+ // dismisses when the press started on the same option. Prevents
37496
+ // Enter on the triggering ion-select from auto-dismissing.
37497
+ this.pendingEnterTarget = null;
37404
37498
  /**
37405
37499
  * The text to display on the cancel button.
37406
37500
  */
@@ -37450,15 +37544,22 @@ class SelectModal {
37450
37544
  return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, this.options.map((option) => (hAsync("ion-item", { lines: "none", class: Object.assign({
37451
37545
  // TODO FW-4784
37452
37546
  'item-radio-checked': option.value === checked
37453
- }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyUp: (ev) => {
37547
+ }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyDown: (ev) => {
37548
+ if (ev.key === 'Enter' && !ev.repeat) {
37549
+ this.pendingEnterTarget = ev.currentTarget;
37550
+ }
37551
+ }, onKeyUp: (ev) => {
37454
37552
  if (ev.key === ' ') {
37455
- /**
37456
- * Selecting a radio option with keyboard navigation,
37457
- * either through the Enter or Space keys, should
37458
- * dismiss the modal.
37459
- */
37553
+ // Space selects and dismisses in one press.
37460
37554
  this.closeModal();
37461
37555
  }
37556
+ else if (ev.key === 'Enter') {
37557
+ const shouldClose = this.pendingEnterTarget === ev.currentTarget;
37558
+ this.pendingEnterTarget = null;
37559
+ if (shouldClose) {
37560
+ this.closeModal();
37561
+ }
37562
+ }
37462
37563
  } }, option.text))))));
37463
37564
  }
37464
37565
  renderCheckboxOptions() {
@@ -37471,7 +37572,7 @@ class SelectModal {
37471
37572
  } }, option.text))));
37472
37573
  }
37473
37574
  render() {
37474
- return (hAsync(Host, { key: 'f8a4cd6ff23ff01eaa1bdaf3c046814e7b30b23b', class: getIonMode$1(this) }, hAsync("ion-header", { key: '9e29a7e57ad5cf332641111882f16852187ec8ba' }, hAsync("ion-toolbar", { key: 'e6af5d6eabbf4b10799fc8a0b8f91d29b12d41f5' }, this.header !== undefined && hAsync("ion-title", { key: '6056e52d15dbf307571d25e0305d67228a79237d' }, this.header), hAsync("ion-buttons", { key: 'c9aa4fb2e21a93f3a95c5a8f0ba8b7d5553c5a72', slot: "end" }, hAsync("ion-button", { key: '5ffbf512719bcb053b652fc96b1b6154d0593095', onClick: () => this.closeModal() }, this.cancelText)))), hAsync("ion-content", { key: '0ec9098798a4e6de7a83a0a7e9d10bdcd7c98a78' }, hAsync("ion-list", { key: 'd60b1700d3c2f8655951632de810900707a101f0' }, this.multiple === true ? this.renderCheckboxOptions() : this.renderRadioOptions()))));
37575
+ return (hAsync(Host, { key: 'fda0bf6f93cd5ec9f3c64f88a52de849e0e140a2', class: getIonMode$1(this) }, hAsync("ion-header", { key: '27c0b17175a53db9ff159feeeb96451a3f011dab' }, hAsync("ion-toolbar", { key: '91a4155ebc317fbc9f1bb3e26a7e94754b953c9b' }, this.header !== undefined && hAsync("ion-title", { key: 'f6dae8e4e381f322cc90efefd9bb6ef81d4d2f3e' }, this.header), hAsync("ion-buttons", { key: 'e7760532fb2e7e7385ed6e62097d92d96ff20148', slot: "end" }, hAsync("ion-button", { key: '4999b6fc46cba138186546dca67b7950855e6fb7', onClick: () => this.closeModal() }, this.cancelText)))), hAsync("ion-content", { key: 'c73f80a4bc25b9061ea65cf11e5d811c1a4d8704' }, hAsync("ion-list", { key: 'b21905d15b36ad5eb45845e768918d2763cf48b1' }, this.multiple === true ? this.renderCheckboxOptions() : this.renderRadioOptions()))));
37475
37576
  }
37476
37577
  get el() { return getElement(this); }
37477
37578
  static get style() { return {
@@ -37534,6 +37635,10 @@ const selectPopoverMdCss = () => `.sc-ion-select-popover-md-h ion-list.sc-ion-se
37534
37635
  class SelectPopover {
37535
37636
  constructor(hostRef) {
37536
37637
  registerInstance(this, hostRef);
37638
+ // Tracks the option that received Enter-keydown so keyup only
37639
+ // dismisses when the press started on the same option. Prevents
37640
+ // Enter on the triggering ion-select from auto-dismissing.
37641
+ this.pendingEnterTarget = null;
37537
37642
  /**
37538
37643
  * An array of options for the popover
37539
37644
  */
@@ -37609,21 +37714,28 @@ class SelectPopover {
37609
37714
  return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, options.map((option) => (hAsync("ion-item", { class: Object.assign({
37610
37715
  // TODO FW-4784
37611
37716
  'item-radio-checked': option.value === checked
37612
- }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyUp: (ev) => {
37717
+ }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyDown: (ev) => {
37718
+ if (ev.key === 'Enter' && !ev.repeat) {
37719
+ this.pendingEnterTarget = ev.currentTarget;
37720
+ }
37721
+ }, onKeyUp: (ev) => {
37613
37722
  if (ev.key === ' ') {
37614
- /**
37615
- * Selecting a radio option with keyboard navigation,
37616
- * either through the Enter or Space keys, should
37617
- * dismiss the popover.
37618
- */
37723
+ // Space selects and dismisses in one press.
37619
37724
  this.dismissParentPopover();
37620
37725
  }
37726
+ else if (ev.key === 'Enter') {
37727
+ const shouldDismiss = this.pendingEnterTarget === ev.currentTarget;
37728
+ this.pendingEnterTarget = null;
37729
+ if (shouldDismiss) {
37730
+ this.dismissParentPopover();
37731
+ }
37732
+ }
37621
37733
  } }, option.text))))));
37622
37734
  }
37623
37735
  render() {
37624
37736
  const { header, message, options, subHeader } = this;
37625
37737
  const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
37626
- return (hAsync(Host, { key: '0c9845a40d3fc392b0a7d64e2a6ed27d94bb7634', class: getIonMode$1(this) }, hAsync("ion-list", { key: '84a30f6661b0f8c00e6fa199658ed2adbcf27358' }, header !== undefined && hAsync("ion-list-header", { key: '13f5f56bbfbc06751fa516291a2da72629b60ece' }, header), hasSubHeaderOrMessage && (hAsync("ion-item", { key: '3d39d18e720e798bbde334e79e6832091c7dfb81' }, hAsync("ion-label", { key: 'd3051b0d140120b44bf5e79572f6f287e7cfb03a', class: "ion-text-wrap" }, subHeader !== undefined && hAsync("h3", { key: 'b16805956f3316f8ec703c123b76f717488e8637' }, subHeader), message !== undefined && hAsync("p", { key: '2215ac4ab4146a14e75a79192e319a8016286b5f' }, message)))), this.renderOptions(options))));
37738
+ return (hAsync(Host, { key: 'e7449a1ecfcdbf45a79f8e26a00253c4e146448a', class: getIonMode$1(this) }, hAsync("ion-list", { key: '52abdfc8668c3429a0dcefef8ddedb6647fdd894' }, header !== undefined && hAsync("ion-list-header", { key: '978e5c03728756feafcc60a0e10e6ec59bf2ae11' }, header), hasSubHeaderOrMessage && (hAsync("ion-item", { key: 'e93c44e7f07a76def16e4b11f0fb4780d84ed402' }, hAsync("ion-label", { key: 'bba1aac43b0bc7f4f00978dd8301985233f3725c', class: "ion-text-wrap" }, subHeader !== undefined && hAsync("h3", { key: 'ad96f6017cf2cc5219540bded2c4f1ca3b532de2' }, subHeader), message !== undefined && hAsync("p", { key: '3fd038921dc40c4d0c29734433984b279ccaeec3' }, message)))), this.renderOptions(options))));
37627
37739
  }
37628
37740
  get el() { return getElement(this); }
37629
37741
  static get style() { return {