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.mjs CHANGED
@@ -9796,7 +9796,7 @@ class ActionSheet {
9796
9796
  if (isRadio) {
9797
9797
  htmlAttrs['aria-checked'] = isActiveRadio ? 'true' : 'false';
9798
9798
  }
9799
- 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: () => {
9799
+ 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: () => {
9800
9800
  if (isRadio) {
9801
9801
  this.selectRadioButton(b);
9802
9802
  }
@@ -9811,12 +9811,12 @@ class ActionSheet {
9811
9811
  const cancelButton = allButtons.find((b) => b.role === 'cancel');
9812
9812
  const buttons = allButtons.filter((b) => b.role !== 'cancel');
9813
9813
  const headerID = `action-sheet-${overlayIndex}-header`;
9814
- return (hAsync(Host, Object.assign({ key: '173fcff5b1da7c33c267de4667591c946b8c8d03', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
9814
+ return (hAsync(Host, Object.assign({ key: 'a56ee2ab59c763036140dbd10306a708c26e3c17', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
9815
9815
  zIndex: `${20000 + this.overlayIndex}`,
9816
- }, 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: {
9816
+ }, 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: {
9817
9817
  'action-sheet-title': true,
9818
9818
  'action-sheet-has-sub-title': this.subHeader !== undefined,
9819
- } }, 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" })));
9819
+ } }, 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" })));
9820
9820
  }
9821
9821
  get el() { return getElement(this); }
9822
9822
  static get watchers() { return {
@@ -12049,14 +12049,12 @@ class Checkbox {
12049
12049
  this.onDivLabelClick = (ev) => {
12050
12050
  ev.stopPropagation();
12051
12051
  };
12052
- this.onSlotChange = () => {
12053
- this.hasLabelContent = this.el.textContent !== '';
12054
- };
12055
12052
  }
12056
12053
  connectedCallback() {
12057
12054
  const { el } = this;
12058
12055
  // Always set initial state
12059
12056
  this.isInvalid = checkInvalidState(el);
12057
+ this.hasLabelContent = this.el.textContent !== '';
12060
12058
  }
12061
12059
  componentWillLoad() {
12062
12060
  this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
@@ -12106,7 +12104,7 @@ class Checkbox {
12106
12104
  renderHiddenInput(true, el, name, checked ? value : '', disabled);
12107
12105
  // The host element must have a checkbox role to ensure proper VoiceOver
12108
12106
  // support in Safari for accessibility.
12109
- 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, {
12107
+ 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, {
12110
12108
  [mode]: true,
12111
12109
  'in-item': hostContext('ion-item', el),
12112
12110
  'checkbox-checked': checked,
@@ -12116,10 +12114,10 @@ class Checkbox {
12116
12114
  [`checkbox-justify-${justify}`]: justify !== undefined,
12117
12115
  [`checkbox-alignment-${alignment}`]: alignment !== undefined,
12118
12116
  [`checkbox-label-placement-${labelPlacement}`]: true,
12119
- }) }, 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: {
12117
+ }) }, 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: {
12120
12118
  'label-text-wrapper': true,
12121
12119
  'label-text-wrapper-hidden': !this.hasLabelContent,
12122
- }, 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)))));
12120
+ }, 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)))));
12123
12121
  }
12124
12122
  getSVGPath(mode, indeterminate) {
12125
12123
  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" }));
@@ -12367,7 +12365,7 @@ const isRTL$1 = (hostEl) => {
12367
12365
  return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
12368
12366
  };
12369
12367
 
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));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)}`;
12368
+ 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)}`;
12371
12369
 
12372
12370
  /**
12373
12371
  * @slot - Content is placed in the scrollable area if provided without a slot.
@@ -15348,6 +15346,12 @@ class Datetime {
15348
15346
  this.el.classList.add('datetime-ready');
15349
15347
  });
15350
15348
  };
15349
+ this.loadTimeoutCleanup = () => {
15350
+ if (this.loadTimeout) {
15351
+ clearTimeout(this.loadTimeout);
15352
+ this.loadTimeout = undefined;
15353
+ }
15354
+ };
15351
15355
  this.processValue = (value) => {
15352
15356
  const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
15353
15357
  const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
@@ -15495,9 +15499,10 @@ class Datetime {
15495
15499
  if (!prevMonth) {
15496
15500
  return;
15497
15501
  }
15502
+ const left = prevMonth.offsetWidth * 2;
15498
15503
  calendarBodyRef.scrollTo({
15499
15504
  top: 0,
15500
- left: 0,
15505
+ left: left * (isRTL$1(this.el) ? 1 : -1),
15501
15506
  behavior: 'smooth',
15502
15507
  });
15503
15508
  };
@@ -15619,15 +15624,16 @@ class Datetime {
15619
15624
  }
15620
15625
  connectedCallback() {
15621
15626
  this.clearFocusVisible = startFocusVisible(this.el).destroy;
15627
+ this.loadTimeout = setTimeout(() => {
15628
+ this.ensureReadyIfVisible();
15629
+ }, 100);
15622
15630
  }
15623
15631
  disconnectedCallback() {
15624
15632
  if (this.clearFocusVisible) {
15625
15633
  this.clearFocusVisible();
15626
15634
  this.clearFocusVisible = undefined;
15627
15635
  }
15628
- if (this.loadTimeout) {
15629
- clearTimeout(this.loadTimeout);
15630
- }
15636
+ this.loadTimeoutCleanup();
15631
15637
  }
15632
15638
  initializeListeners() {
15633
15639
  this.initializeCalendarListener();
@@ -15675,7 +15681,10 @@ class Datetime {
15675
15681
  * we still initialize listeners and mark the component as ready.
15676
15682
  *
15677
15683
  * We schedule this after everything has had a chance to run.
15684
+ *
15685
+ * We also clean up the load timeout to ensure that we don't have multiple timeouts running.
15678
15686
  */
15687
+ this.loadTimeoutCleanup();
15679
15688
  this.loadTimeout = setTimeout(() => {
15680
15689
  this.ensureReadyIfVisible();
15681
15690
  }, 100);
@@ -16434,7 +16443,7 @@ class Datetime {
16434
16443
  const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
16435
16444
  const hasWheelVariant = hasDatePresentation && preferWheel;
16436
16445
  renderHiddenInput(true, el, name, formatValue(value), disabled);
16437
- return (hAsync(Host, { key: '191a6d7ce7bc2d57bfaaebd8aee31e3c36f2b56a', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
16446
+ return (hAsync(Host, { key: '59e0811aa273e88dfb8e4b703e6824088a457380', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
16438
16447
  [mode]: true,
16439
16448
  ['datetime-readonly']: readonly,
16440
16449
  ['datetime-disabled']: disabled,
@@ -16444,7 +16453,7 @@ class Datetime {
16444
16453
  [`datetime-size-${size}`]: true,
16445
16454
  [`datetime-prefer-wheel`]: hasWheelVariant,
16446
16455
  [`datetime-grid`]: isGridStyle,
16447
- })) }, hAsync("div", { key: '5c75290394cf7dc37c7dcba6372af003a50a9c04', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
16456
+ })) }, hAsync("div", { key: '3753ff3dde3085070916c3de83687a219a49e553', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
16448
16457
  }
16449
16458
  get el() { return getElement(this); }
16450
16459
  static get watchers() { return {
@@ -19605,9 +19614,18 @@ class InputOTP {
19605
19614
  * - Tab: Allows normal tab navigation between components
19606
19615
  */
19607
19616
  this.onKeyDown = (index) => (event) => {
19608
- const { length } = this;
19617
+ const { disabled, length, readonly } = this;
19609
19618
  const rtl = isRTL$1(this.el);
19610
19619
  const input = event.target;
19620
+ if (disabled) {
19621
+ return;
19622
+ }
19623
+ if (readonly) {
19624
+ if (event.key === 'Backspace' || event.key === 'Delete') {
19625
+ event.preventDefault();
19626
+ return;
19627
+ }
19628
+ }
19611
19629
  // Meta shortcuts are used to copy, paste, and select text
19612
19630
  // We don't want to handle these keys here
19613
19631
  const metaShortcuts = ['a', 'c', 'v', 'x', 'r', 'z', 'y'];
@@ -19670,10 +19688,13 @@ class InputOTP {
19670
19688
  */
19671
19689
  this.onInput = (index) => (event) => {
19672
19690
  var _a, _b;
19673
- const { length, validKeyPattern } = this;
19691
+ const { disabled, length, readonly, validKeyPattern } = this;
19674
19692
  const input = event.target;
19675
19693
  const value = input.value;
19676
19694
  const previousValue = this.previousInputValues[index] || '';
19695
+ if (disabled || readonly) {
19696
+ return;
19697
+ }
19677
19698
  // 1. Autofill handling
19678
19699
  // If the length of the value increases by more than 1 from the previous
19679
19700
  // value, treat this as autofill. This is to prevent the case where the
@@ -19792,8 +19813,11 @@ class InputOTP {
19792
19813
  */
19793
19814
  this.onPaste = (event) => {
19794
19815
  var _a, _b;
19795
- const { inputRefs, length, validKeyPattern } = this;
19816
+ const { disabled, inputRefs, length, readonly, validKeyPattern } = this;
19796
19817
  event.preventDefault();
19818
+ if (disabled || readonly) {
19819
+ return;
19820
+ }
19797
19821
  const pastedText = (_a = event.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text');
19798
19822
  // If there is no pasted text, still emit the input change event
19799
19823
  // because this is how the native input element behaves
@@ -20080,7 +20104,7 @@ class InputOTP {
20080
20104
  const tabbableIndex = this.getTabbableIndex();
20081
20105
  const pattern = this.getPattern();
20082
20106
  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()) !== '';
20083
- return (hAsync(Host, { key: 'f15a29fb17b681ef55885ca36d3d5f899cbaca83', class: createColorClasses$1(color, {
20107
+ return (hAsync(Host, { key: '5c1386ae6b8038ec33ca94fd818c9353b1b37f75', class: createColorClasses$1(color, {
20084
20108
  [mode]: true,
20085
20109
  'has-focus': hasFocus,
20086
20110
  [`input-otp-size-${size}`]: true,
@@ -20088,10 +20112,10 @@ class InputOTP {
20088
20112
  [`input-otp-fill-${fill}`]: true,
20089
20113
  'input-otp-disabled': disabled,
20090
20114
  'input-otp-readonly': readonly,
20091
- }) }, 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: {
20115
+ }) }, 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: {
20092
20116
  'input-otp-description': true,
20093
20117
  'input-otp-description-hidden': !hasDescription,
20094
- } }, hAsync("slot", { key: '11baa2624926a08274508afe0833d9237a8dc35c' }))));
20118
+ } }, hAsync("slot", { key: 'f4674d47d3d3991f21a0a79321ebc323968071dc' }))));
20095
20119
  }
20096
20120
  get el() { return getElement(this); }
20097
20121
  static get watchers() { return {
@@ -24982,6 +25006,12 @@ const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, ba
24982
25006
  const MODAL_INSET_MIN_WIDTH = 768;
24983
25007
  const MODAL_INSET_MIN_HEIGHT = 600;
24984
25008
  const EDGE_THRESHOLD = 5;
25009
+ /**
25010
+ * CSS values for `--width` / `--height` that are treated as fullscreen
25011
+ * (modal touches the corresponding screen edges). Empty string means the
25012
+ * property was not overridden. See `hasCustomModalDimensions()`.
25013
+ */
25014
+ const FULLSCREEN_SIZE_VALUES = new Set(['', '100%', '100vw', '100vh', '100dvw', '100dvh', '100svw', '100svh']);
24985
25015
  /**
24986
25016
  * Cache for resolved root safe-area-top value, invalidated once per frame.
24987
25017
  */
@@ -25030,6 +25060,22 @@ const getRootSafeAreaTop = () => {
25030
25060
  }
25031
25061
  return value;
25032
25062
  };
25063
+ /**
25064
+ * True when the modal host declares BOTH a non-fullscreen `--width` AND a
25065
+ * non-fullscreen `--height` (i.e. a centered-dialog-like modal that doesn't
25066
+ * touch any screen edge).
25067
+ *
25068
+ * The conservative "both axes" check avoids mis-zeroing safe-area for
25069
+ * partial-custom modals where the modal still touches top/bottom edges
25070
+ * (e.g. only `--width` overridden). Partial cases fall through to the
25071
+ * existing position-based post-animation correction.
25072
+ */
25073
+ const hasCustomModalDimensions = (hostEl) => {
25074
+ const styles = getComputedStyle(hostEl);
25075
+ const width = styles.getPropertyValue('--width').trim();
25076
+ const height = styles.getPropertyValue('--height').trim();
25077
+ return !FULLSCREEN_SIZE_VALUES.has(width) && !FULLSCREEN_SIZE_VALUES.has(height);
25078
+ };
25033
25079
  /**
25034
25080
  * Returns the initial safe-area configuration based on modal type.
25035
25081
  * This is called before animation starts and uses configuration-based prediction.
@@ -25064,8 +25110,11 @@ const getInitialSafeAreaConfig = (context) => {
25064
25110
  }
25065
25111
  // On viewports that meet the centered dialog media query breakpoints,
25066
25112
  // regular modals render as centered dialogs (not fullscreen), so they
25067
- // don't touch any screen edges and don't need safe-area insets.
25068
- if (isCenteredDialogViewport()) {
25113
+ // don't touch any screen edges and don't need safe-area insets. Also
25114
+ // applies to phone viewports when the modal declares custom --width and
25115
+ // --height; these don't touch screen edges either, so the initial
25116
+ // prediction must be zero to avoid a post-animation correction flash.
25117
+ if (isCenteredDialogViewport() || context.hasCustomDimensions) {
25069
25118
  return {
25070
25119
  top: '0px',
25071
25120
  bottom: '0px',
@@ -25377,12 +25426,10 @@ class Modal {
25377
25426
  // since the viewport may have crossed the centered-dialog breakpoint.
25378
25427
  if (!context.isSheetModal && !context.isCardModal) {
25379
25428
  this.updateSafeAreaOverrides();
25380
- // Re-evaluate fullscreen safe-area padding: clear first, then re-apply
25381
- if (this.wrapperEl) {
25382
- this.wrapperEl.style.removeProperty('height');
25383
- this.wrapperEl.style.removeProperty('padding-bottom');
25384
- }
25385
- this.applyFullscreenSafeArea();
25429
+ // Re-evaluate fullscreen safe-area padding: clear first, then re-apply.
25430
+ const { contentEl, hasFooter } = this.findContentAndFooter();
25431
+ this.clearContentSafeAreaPadding(contentEl);
25432
+ this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
25386
25433
  }
25387
25434
  }, 50); // Debounce to avoid excessive calls during active resizing
25388
25435
  }
@@ -26129,6 +26176,11 @@ class Modal {
26129
26176
  }
26130
26177
  /**
26131
26178
  * Creates the context object for safe-area utilities.
26179
+ *
26180
+ * `hasCustomDimensions` is only set by `setInitialSafeAreaOverrides()`
26181
+ * because it is only read by `getInitialSafeAreaConfig()`. Other callers
26182
+ * (resize handler, post-animation update, fullscreen-padding apply) would
26183
+ * pay a `getComputedStyle()` cost for a value they never consult.
26132
26184
  */
26133
26185
  getSafeAreaContext() {
26134
26186
  return {
@@ -26150,7 +26202,7 @@ class Modal {
26150
26202
  * sheets to prevent header content from getting double-offset padding).
26151
26203
  */
26152
26204
  setInitialSafeAreaOverrides() {
26153
- const context = this.getSafeAreaContext();
26205
+ const context = Object.assign(Object.assign({}, this.getSafeAreaContext()), { hasCustomDimensions: hasCustomModalDimensions(this.el) });
26154
26206
  const safeAreaConfig = getInitialSafeAreaConfig(context);
26155
26207
  applySafeAreaOverrides(this.el, safeAreaConfig);
26156
26208
  // Set the internal offset property with the resolved root safe-area-top value
@@ -26190,59 +26242,85 @@ class Modal {
26190
26242
  applySafeAreaOverrides(el, safeAreaConfig);
26191
26243
  }
26192
26244
  /**
26193
- * Applies padding-bottom to fullscreen modal wrapper to prevent
26194
- * content from overlapping system navigation bar.
26245
+ * Applies safe-area-bottom scroll padding to ion-content inside
26246
+ * fullscreen modals that have no ion-footer. This prevents content
26247
+ * from being hidden behind the system navigation bar while keeping
26248
+ * the modal background edge-to-edge (no visible gap).
26195
26249
  */
26196
26250
  applyFullscreenSafeArea() {
26197
- const { wrapperEl, el } = this;
26198
- if (!wrapperEl)
26199
- return;
26200
26251
  const context = this.getSafeAreaContext();
26201
26252
  if (context.isSheetModal || context.isCardModal)
26202
26253
  return;
26203
- // Check for standard Ionic layout children (ion-content, ion-footer),
26204
- // searching one level deep for wrapped components (e.g.,
26205
- // <app-footer><ion-footer>...</ion-footer></app-footer>).
26206
- // Note: uses a manual loop instead of querySelector(':scope > ...') because
26207
- // Stencil's mock-doc (used in spec tests) does not support :scope.
26208
- let hasContent = false;
26254
+ const { contentEl, hasFooter } = this.findContentAndFooter();
26255
+ this.applyFullscreenSafeAreaTo(contentEl, hasFooter);
26256
+ }
26257
+ /**
26258
+ * Sets --ion-content-safe-area-padding-bottom on the given ion-content
26259
+ * when no footer is present, so ion-content's .inner-scroll includes
26260
+ * safe-area-bottom in its scroll padding. This keeps the modal background
26261
+ * edge-to-edge while ensuring content scrolls clear of the system nav bar.
26262
+ *
26263
+ * --ion-content-safe-area-padding-bottom is an internal CSS property used
26264
+ * only by this code path. It is not part of ion-content's public API and
26265
+ * should not be set by consumers. The default of 0px makes it a no-op
26266
+ * when unset, which is the expected state for ion-content used outside of
26267
+ * a fullscreen modal without a footer.
26268
+ */
26269
+ applyFullscreenSafeAreaTo(contentEl, hasFooter) {
26270
+ // Only apply for standard Ionic layouts (has ion-content but no
26271
+ // ion-footer). When a footer is present it handles its own safe-area
26272
+ // padding. Custom modals with raw HTML are developer-controlled.
26273
+ if (!contentEl || hasFooter)
26274
+ return;
26275
+ contentEl.style.setProperty('--ion-content-safe-area-padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
26276
+ }
26277
+ /**
26278
+ * Removes the internal --ion-content-safe-area-padding-bottom property
26279
+ * from an already-located ion-content. Callers do their own
26280
+ * findContentAndFooter() so they can also read hasFooter if needed.
26281
+ */
26282
+ clearContentSafeAreaPadding(contentEl) {
26283
+ if (!contentEl)
26284
+ return;
26285
+ contentEl.style.removeProperty('--ion-content-safe-area-padding-bottom');
26286
+ }
26287
+ /**
26288
+ * Finds ion-content and ion-footer among direct children and one level of
26289
+ * grandchildren (for wrapped components like <app-footer><ion-footer>).
26290
+ *
26291
+ * Intentionally does NOT use findIonContent() or querySelector() because
26292
+ * those search the full subtree and would match ion-content inside nested
26293
+ * routes/pages. We only want direct slot children (+ one wrapper level).
26294
+ *
26295
+ * Uses a manual loop instead of querySelector(':scope > ...') because
26296
+ * Stencil's mock-doc (used in spec tests) does not support :scope.
26297
+ */
26298
+ findContentAndFooter() {
26299
+ let contentEl = null;
26209
26300
  let hasFooter = false;
26210
- for (const child of Array.from(el.children)) {
26301
+ for (const child of Array.from(this.el.children)) {
26211
26302
  if (child.tagName === 'ION-CONTENT')
26212
- hasContent = true;
26303
+ contentEl = child;
26213
26304
  if (child.tagName === 'ION-FOOTER')
26214
26305
  hasFooter = true;
26215
26306
  for (const grandchild of Array.from(child.children)) {
26216
- if (grandchild.tagName === 'ION-CONTENT')
26217
- hasContent = true;
26307
+ if (grandchild.tagName === 'ION-CONTENT' && !contentEl)
26308
+ contentEl = grandchild;
26218
26309
  if (grandchild.tagName === 'ION-FOOTER')
26219
26310
  hasFooter = true;
26220
26311
  }
26221
26312
  }
26222
- // Only apply wrapper padding for standard Ionic layouts (has ion-content
26223
- // but no ion-footer). Custom modals with raw HTML are fully
26224
- // developer-controlled and should not be modified.
26225
- if (!hasContent || hasFooter)
26226
- return;
26227
- // Reduce wrapper height by safe-area and add equivalent padding so the
26228
- // total visual size stays the same but the flex content area shrinks.
26229
- // Using height + padding instead of box-sizing: border-box avoids
26230
- // breaking custom modals that set --border-width (border-box would
26231
- // include the border inside the height, changing the layout).
26232
- wrapperEl.style.setProperty('height', 'calc(var(--height) - var(--ion-safe-area-bottom, 0px))');
26233
- wrapperEl.style.setProperty('padding-bottom', 'var(--ion-safe-area-bottom, 0px)');
26313
+ return { contentEl, hasFooter };
26234
26314
  }
26235
26315
  /**
26236
- * Clears all safe-area overrides and padding from wrapper.
26316
+ * Clears all safe-area overrides and padding.
26237
26317
  */
26238
26318
  cleanupSafeAreaOverrides() {
26239
26319
  clearSafeAreaOverrides(this.el);
26240
26320
  // Remove internal sheet offset property
26241
26321
  this.el.style.removeProperty('--ion-modal-offset-top');
26242
- if (this.wrapperEl) {
26243
- this.wrapperEl.style.removeProperty('height');
26244
- this.wrapperEl.style.removeProperty('padding-bottom');
26245
- }
26322
+ const { contentEl } = this.findContentAndFooter();
26323
+ this.clearContentSafeAreaPadding(contentEl);
26246
26324
  }
26247
26325
  render() {
26248
26326
  const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
@@ -26251,20 +26329,20 @@ class Modal {
26251
26329
  const isCardModal = presentingElement !== undefined && mode === 'ios';
26252
26330
  const isHandleCycle = handleBehavior === 'cycle';
26253
26331
  const isSheetModalWithHandle = isSheetModal && showHandle;
26254
- return (hAsync(Host, Object.assign({ key: '1a53e8f87532abccc169ca4b24973a39c5f9ba16', "no-router": true,
26332
+ return (hAsync(Host, Object.assign({ key: '4bf38aa67df9a3f977163bba5423960bbafd16de', "no-router": true,
26255
26333
  // Allow the modal to be navigable when the handle is focusable
26256
26334
  tabIndex: isHandleCycle && isSheetModalWithHandle ? 0 : -1 }, htmlAttributes, { style: {
26257
26335
  zIndex: `${20000 + this.overlayIndex}`,
26258
- }, 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',
26336
+ }, 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',
26259
26337
  /*
26260
26338
  role and aria-modal must be used on the
26261
26339
  same element. They must also be set inside the
26262
26340
  shadow DOM otherwise ion-button will not be highlighted
26263
26341
  when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
26264
26342
  */
26265
- 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",
26343
+ 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",
26266
26344
  // Prevents the handle from receiving keyboard focus when it does not cycle
26267
- 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 }))));
26345
+ 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 }))));
26268
26346
  }
26269
26347
  get el() { return getElement(this); }
26270
26348
  static get watchers() { return {
@@ -28592,7 +28670,7 @@ class PickerColumn {
28592
28670
  * Because this initial call to scrollActiveItemIntoView has to fire before
28593
28671
  * the scroll listener is set up, we need to manage the active class manually.
28594
28672
  */
28595
- const oldActive = getElementRoot(el).querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
28673
+ const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
28596
28674
  if (oldActive) {
28597
28675
  this.setPickerItemActiveState(oldActive, false);
28598
28676
  }
@@ -28692,14 +28770,14 @@ class PickerColumn {
28692
28770
  render() {
28693
28771
  const { color, disabled, isActive, numericInput } = this;
28694
28772
  const mode = getIonMode$1(this);
28695
- return (hAsync(Host, { key: 'db903fd415f8a2d91994dececca481c1af8ba6a9', class: createColorClasses$1(color, {
28773
+ return (hAsync(Host, { key: '234c96a501d7ac413b9b0ea56b33017681e25b40', class: createColorClasses$1(color, {
28696
28774
  [mode]: true,
28697
28775
  ['picker-column-active']: isActive,
28698
28776
  ['picker-column-numeric-input']: numericInput,
28699
28777
  ['picker-column-disabled']: disabled,
28700
- }) }, hAsync("slot", { key: '02ce9e1dd7df91afcd50b06416552bcffb5dec98', name: "prefix" }), hAsync("div", { key: '6dfd7d2429bec19244a6b1afb4448121963a031b', class: "picker-opts", ref: (el) => {
28778
+ }) }, hAsync("slot", { key: '9dc15ea0601ddd2cb2e0a745e91e036a8bd96f8b', name: "prefix" }), hAsync("div", { key: 'de4fe28ee4bc46b7c0420d6ab0df0e7809443da9', class: "picker-opts", ref: (el) => {
28701
28779
  this.scrollEl = el;
28702
- }, 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" })));
28780
+ }, 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" })));
28703
28781
  }
28704
28782
  get el() { return getElement(this); }
28705
28783
  static get watchers() { return {
@@ -31277,6 +31355,18 @@ class RadioGroup {
31277
31355
  // to the bottom of the screen
31278
31356
  ev.preventDefault();
31279
31357
  }
31358
+ // Inside a select interface, Enter commits the focused radio
31359
+ // value (matching native <select>). The !ev.repeat guard stops
31360
+ // a held Enter on the triggering ion-select from re-committing
31361
+ // once focus lands in the opened popover/modal.
31362
+ if (ev.key === 'Enter' && inSelectInterface && !ev.repeat) {
31363
+ const previousValue = this.value;
31364
+ this.value = current.value;
31365
+ if (previousValue !== this.value) {
31366
+ this.emitValueChange(ev);
31367
+ }
31368
+ ev.preventDefault();
31369
+ }
31280
31370
  }
31281
31371
  }
31282
31372
  /** @internal */
@@ -31309,7 +31399,7 @@ class RadioGroup {
31309
31399
  const { label, labelId, el, name, value } = this;
31310
31400
  const mode = getIonMode$1(this);
31311
31401
  renderHiddenInput(true, el, name, value, false);
31312
- 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' })));
31402
+ 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' })));
31313
31403
  }
31314
31404
  get el() { return getElement(this); }
31315
31405
  static get watchers() { return {
@@ -37399,6 +37489,10 @@ const selectModalMdCss = () => `.sc-ion-select-modal-md-h{height:100%}ion-list.s
37399
37489
  class SelectModal {
37400
37490
  constructor(hostRef) {
37401
37491
  registerInstance(this, hostRef);
37492
+ // Tracks the option that received Enter-keydown so keyup only
37493
+ // dismisses when the press started on the same option. Prevents
37494
+ // Enter on the triggering ion-select from auto-dismissing.
37495
+ this.pendingEnterTarget = null;
37402
37496
  /**
37403
37497
  * The text to display on the cancel button.
37404
37498
  */
@@ -37448,15 +37542,22 @@ class SelectModal {
37448
37542
  return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, this.options.map((option) => (hAsync("ion-item", { lines: "none", class: Object.assign({
37449
37543
  // TODO FW-4784
37450
37544
  'item-radio-checked': option.value === checked
37451
- }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyUp: (ev) => {
37545
+ }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyDown: (ev) => {
37546
+ if (ev.key === 'Enter' && !ev.repeat) {
37547
+ this.pendingEnterTarget = ev.currentTarget;
37548
+ }
37549
+ }, onKeyUp: (ev) => {
37452
37550
  if (ev.key === ' ') {
37453
- /**
37454
- * Selecting a radio option with keyboard navigation,
37455
- * either through the Enter or Space keys, should
37456
- * dismiss the modal.
37457
- */
37551
+ // Space selects and dismisses in one press.
37458
37552
  this.closeModal();
37459
37553
  }
37554
+ else if (ev.key === 'Enter') {
37555
+ const shouldClose = this.pendingEnterTarget === ev.currentTarget;
37556
+ this.pendingEnterTarget = null;
37557
+ if (shouldClose) {
37558
+ this.closeModal();
37559
+ }
37560
+ }
37460
37561
  } }, option.text))))));
37461
37562
  }
37462
37563
  renderCheckboxOptions() {
@@ -37469,7 +37570,7 @@ class SelectModal {
37469
37570
  } }, option.text))));
37470
37571
  }
37471
37572
  render() {
37472
- 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()))));
37573
+ 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()))));
37473
37574
  }
37474
37575
  get el() { return getElement(this); }
37475
37576
  static get style() { return {
@@ -37532,6 +37633,10 @@ const selectPopoverMdCss = () => `.sc-ion-select-popover-md-h ion-list.sc-ion-se
37532
37633
  class SelectPopover {
37533
37634
  constructor(hostRef) {
37534
37635
  registerInstance(this, hostRef);
37636
+ // Tracks the option that received Enter-keydown so keyup only
37637
+ // dismisses when the press started on the same option. Prevents
37638
+ // Enter on the triggering ion-select from auto-dismissing.
37639
+ this.pendingEnterTarget = null;
37535
37640
  /**
37536
37641
  * An array of options for the popover
37537
37642
  */
@@ -37607,21 +37712,28 @@ class SelectPopover {
37607
37712
  return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, options.map((option) => (hAsync("ion-item", { class: Object.assign({
37608
37713
  // TODO FW-4784
37609
37714
  'item-radio-checked': option.value === checked
37610
- }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyUp: (ev) => {
37715
+ }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyDown: (ev) => {
37716
+ if (ev.key === 'Enter' && !ev.repeat) {
37717
+ this.pendingEnterTarget = ev.currentTarget;
37718
+ }
37719
+ }, onKeyUp: (ev) => {
37611
37720
  if (ev.key === ' ') {
37612
- /**
37613
- * Selecting a radio option with keyboard navigation,
37614
- * either through the Enter or Space keys, should
37615
- * dismiss the popover.
37616
- */
37721
+ // Space selects and dismisses in one press.
37617
37722
  this.dismissParentPopover();
37618
37723
  }
37724
+ else if (ev.key === 'Enter') {
37725
+ const shouldDismiss = this.pendingEnterTarget === ev.currentTarget;
37726
+ this.pendingEnterTarget = null;
37727
+ if (shouldDismiss) {
37728
+ this.dismissParentPopover();
37729
+ }
37730
+ }
37619
37731
  } }, option.text))))));
37620
37732
  }
37621
37733
  render() {
37622
37734
  const { header, message, options, subHeader } = this;
37623
37735
  const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
37624
- 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))));
37736
+ 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))));
37625
37737
  }
37626
37738
  get el() { return getElement(this); }
37627
37739
  static get style() { return {