@ionic/core 9.0.9 → 9.0.10-dev.11793383958.19a7d413

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 (43) hide show
  1. package/components/ion-input-otp.js +1 -1
  2. package/components/ion-menu.js +1 -1
  3. package/components/ion-router.js +1 -1
  4. package/dist/cjs/ion-input-otp.cjs.entry.js +126 -10
  5. package/dist/cjs/ion-menu_3.cjs.entry.js +25 -7
  6. package/dist/cjs/ion-route_4.cjs.entry.js +121 -16
  7. package/dist/cjs/ionic.cjs.js +1 -1
  8. package/dist/cjs/loader.cjs.js +1 -1
  9. package/dist/collection/components/input-otp/input-otp.ios.css +30 -5
  10. package/dist/collection/components/input-otp/input-otp.js +191 -12
  11. package/dist/collection/components/input-otp/input-otp.md.css +30 -5
  12. package/dist/collection/components/menu/menu.js +25 -8
  13. package/dist/collection/components/route/route.js +9 -1
  14. package/dist/collection/components/route-redirect/route-redirect.js +1 -1
  15. package/dist/collection/components/router/utils/constants.js +2 -0
  16. package/dist/collection/components/router/utils/matching.js +97 -14
  17. package/dist/collection/components/router/utils/path.js +17 -3
  18. package/dist/docs.json +92 -3
  19. package/dist/esm/ion-input-otp.entry.js +128 -12
  20. package/dist/esm/ion-menu_3.entry.js +26 -8
  21. package/dist/esm/ion-route_4.entry.js +121 -16
  22. package/dist/esm/ionic.js +1 -1
  23. package/dist/esm/loader.js +1 -1
  24. package/dist/html.html-data.json +10 -2
  25. package/dist/ionic/ionic.esm.js +1 -1
  26. package/dist/ionic/p-095da8ec.entry.js +4 -0
  27. package/dist/ionic/p-705759fd.entry.js +4 -0
  28. package/dist/ionic/p-99c518de.entry.js +4 -0
  29. package/dist/types/components/input-otp/input-otp-interface.d.ts +1 -0
  30. package/dist/types/components/input-otp/input-otp.d.ts +40 -2
  31. package/dist/types/components/menu/menu.d.ts +7 -0
  32. package/dist/types/components/route/route.d.ts +8 -0
  33. package/dist/types/components/route-redirect/route-redirect.d.ts +3 -1
  34. package/dist/types/components/router/utils/constants.d.ts +2 -0
  35. package/dist/types/components/router/utils/matching.d.ts +10 -0
  36. package/dist/types/components/router/utils/path.d.ts +5 -1
  37. package/dist/types/components.d.ts +32 -6
  38. package/hydrate/index.js +257 -33
  39. package/hydrate/index.mjs +257 -33
  40. package/package.json +1 -1
  41. package/dist/ionic/p-539d6c8e.entry.js +0 -4
  42. package/dist/ionic/p-7ce9c6f8.entry.js +0 -4
  43. package/dist/ionic/p-af11d3c6.entry.js +0 -4
package/hydrate/index.js CHANGED
@@ -21446,9 +21446,9 @@ class Input {
21446
21446
  }
21447
21447
  let inputIds$1 = 0;
21448
21448
 
21449
- const inputOtpIosCss = () => `.sc-ion-input-otp-ios-h{--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--padding-top:16px;--padding-end:0;--padding-bottom:16px;--padding-start:0;--color:initial;--min-width:40px;--separator-width:8px;--separator-height:var(--separator-width);--separator-border-radius:999px;--separator-color:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;font-size:0.875rem}.input-otp-group.sc-ion-input-otp-ios{-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-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:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.native-wrapper.sc-ion-input-otp-ios{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:var(--min-width)}.native-input.sc-ion-input-otp-ios{border-radius:var(--border-radius);width:var(--width);min-width:inherit;height:var(--height);border-width:var(--border-width);border-style:solid;border-color:var(--border-color);background:var(--background);color:var(--color);font-size:inherit;text-align:center;-webkit-appearance:none;-moz-appearance:none;appearance:none}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{caret-color:var(--highlight-color)}.input-otp-description.sc-ion-input-otp-ios{color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-description-hidden.sc-ion-input-otp-ios{display:none}.input-otp-separator.sc-ion-input-otp-ios{border-radius:var(--separator-border-radius);-ms-flex-negative:0;flex-shrink:0;width:var(--separator-width);height:var(--separator-height);background:var(--separator-color)}.input-otp-size-small.sc-ion-input-otp-ios-h{--width:40px;--height:40px}.input-otp-size-small.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios{gap:8px}.input-otp-size-medium.sc-ion-input-otp-ios-h{--width:48px;--height:48px}.input-otp-size-large.sc-ion-input-otp-ios-h{--width:56px;--height:56px}.input-otp-size-medium.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios,.input-otp-size-large.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios{gap:12px}.input-otp-shape-round.sc-ion-input-otp-ios-h{--border-radius:16px}.input-otp-shape-soft.sc-ion-input-otp-ios-h{--border-radius:8px}.input-otp-shape-rectangular.sc-ion-input-otp-ios-h{--border-radius:0}.input-otp-fill-outline.sc-ion-input-otp-ios-h{--background:none}.input-otp-fill-solid.sc-ion-input-otp-ios-h{--border-color:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-disabled.sc-ion-input-otp-ios-h{--color:var(--ion-color-step-350, var(--ion-text-color-step-650, #a6a6a6))}.input-otp-fill-outline.input-otp-disabled.sc-ion-input-otp-ios-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.input-otp-disabled.sc-ion-input-otp-ios-h,.input-otp-disabled.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:disabled{cursor:not-allowed}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{--border-color:var(--highlight-color);outline:none}.input-otp-fill-outline.input-otp-readonly.sc-ion-input-otp-ios-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-fill-solid.input-otp-disabled.sc-ion-input-otp-ios-h,.input-otp-fill-solid.input-otp-readonly.sc-ion-input-otp-ios-h{--border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.ion-touched.ion-invalid.sc-ion-input-otp-ios-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-otp-ios-h{--highlight-color:var(--highlight-color-valid)}.has-focus.ion-valid.sc-ion-input-otp-ios-h,.ion-touched.ion-invalid.sc-ion-input-otp-ios-h{--border-color:var(--highlight-color)}.ion-color.sc-ion-input-otp-ios-h{--highlight-color-focused:var(--ion-color-base)}.input-otp-fill-outline.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{border-color:rgba(var(--ion-color-base-rgb), 0.6)}.input-otp-fill-outline.ion-color.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-outline.ion-color.has-focus.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.has-focus.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:var(--ion-color-danger, #c5000f)}.input-otp-fill-outline.ion-color.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-outline.ion-color.has-focus.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.has-focus.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:var(--ion-color-success, #2dd55b)}.input-otp-fill-outline.input-otp-disabled.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:rgba(var(--ion-color-base-rgb), 0.3)}.sc-ion-input-otp-ios-h{--border-width:0.55px}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{--border-width:1px}.input-otp-fill-outline.sc-ion-input-otp-ios-h{--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))))}`;
21449
+ const inputOtpIosCss = () => `.sc-ion-input-otp-ios-h{--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--padding-top:16px;--padding-end:0;--padding-bottom:16px;--padding-start:0;--color:initial;--min-width:40px;--separator-width:8px;--separator-height:var(--separator-width);--separator-border-radius:999px;--separator-color:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);--border-color:initial;display:block;position:relative;font-size:0.875rem}.input-otp-group.sc-ion-input-otp-ios{-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-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:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.native-wrapper.sc-ion-input-otp-ios{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:var(--min-width)}.native-input.sc-ion-input-otp-ios{border-radius:var(--border-radius);width:var(--width);min-width:inherit;height:var(--height);border-width:var(--border-width);border-style:solid;border-color:var(--border-color, var(--internal-border-color));background:var(--background);color:var(--color);font-size:inherit;text-align:center;-webkit-appearance:none;-moz-appearance:none;appearance:none}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{caret-color:var(--highlight-color)}.input-otp-description.sc-ion-input-otp-ios{color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-description-hidden.sc-ion-input-otp-ios{display:none}.input-otp-bottom.sc-ion-input-otp-ios{font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-bottom.sc-ion-input-otp-ios .error-text.sc-ion-input-otp-ios{display:none;color:var(--highlight-color-invalid)}.input-otp-bottom.sc-ion-input-otp-ios .helper-text.sc-ion-input-otp-ios{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-input-otp-ios-h .input-otp-bottom.sc-ion-input-otp-ios .error-text.sc-ion-input-otp-ios{display:block}.ion-touched.ion-invalid.sc-ion-input-otp-ios-h .input-otp-bottom.sc-ion-input-otp-ios .helper-text.sc-ion-input-otp-ios{display:none}.input-otp-separator.sc-ion-input-otp-ios{border-radius:var(--separator-border-radius);-ms-flex-negative:0;flex-shrink:0;width:var(--separator-width);height:var(--separator-height);background:var(--separator-color)}.input-otp-size-small.sc-ion-input-otp-ios-h{--width:40px;--height:40px}.input-otp-size-small.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios{gap:8px}.input-otp-size-medium.sc-ion-input-otp-ios-h{--width:48px;--height:48px}.input-otp-size-large.sc-ion-input-otp-ios-h{--width:56px;--height:56px}.input-otp-size-medium.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios,.input-otp-size-large.sc-ion-input-otp-ios-h .input-otp-group.sc-ion-input-otp-ios{gap:12px}.input-otp-shape-round.sc-ion-input-otp-ios-h{--border-radius:16px}.input-otp-shape-soft.sc-ion-input-otp-ios-h{--border-radius:8px}.input-otp-shape-rectangular.sc-ion-input-otp-ios-h{--border-radius:0}.input-otp-fill-outline.sc-ion-input-otp-ios-h{--background:none}.input-otp-fill-solid.sc-ion-input-otp-ios-h{--internal-border-color:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-disabled.sc-ion-input-otp-ios-h{--color:var(--ion-color-step-350, var(--ion-text-color-step-650, #a6a6a6))}.input-otp-fill-outline.input-otp-disabled.sc-ion-input-otp-ios-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--internal-border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.input-otp-disabled.sc-ion-input-otp-ios-h,.input-otp-disabled.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:disabled{cursor:not-allowed}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{--border-color:var(--highlight-color);outline:none}.input-otp-fill-outline.input-otp-readonly.sc-ion-input-otp-ios-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-fill-solid.input-otp-disabled.sc-ion-input-otp-ios-h,.input-otp-fill-solid.input-otp-readonly.sc-ion-input-otp-ios-h{--internal-border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.ion-touched.ion-invalid.sc-ion-input-otp-ios-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-otp-ios-h{--highlight-color:var(--highlight-color-valid)}.has-focus.ion-valid.sc-ion-input-otp-ios-h,.ion-touched.ion-invalid.sc-ion-input-otp-ios-h{--border-color:var(--highlight-color)}.ion-color.sc-ion-input-otp-ios-h{--highlight-color-focused:var(--ion-color-base)}.input-otp-fill-outline.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{border-color:rgba(var(--ion-color-base-rgb), 0.6)}.input-otp-fill-outline.ion-color.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-outline.ion-color.has-focus.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.has-focus.ion-invalid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:var(--ion-color-danger, #c5000f)}.input-otp-fill-outline.ion-color.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-outline.ion-color.has-focus.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios,.input-otp-fill-solid.ion-color.has-focus.ion-valid.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:var(--ion-color-success, #2dd55b)}.input-otp-fill-outline.input-otp-disabled.ion-color.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios{border-color:rgba(var(--ion-color-base-rgb), 0.3)}.sc-ion-input-otp-ios-h{--border-width:0.55px}.has-focus.sc-ion-input-otp-ios-h .native-input.sc-ion-input-otp-ios:focus{--border-width:1px}.input-otp-fill-outline.sc-ion-input-otp-ios-h{--internal-border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))))}`;
21450
21450
 
21451
- const inputOtpMdCss = () => `.sc-ion-input-otp-md-h{--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--padding-top:16px;--padding-end:0;--padding-bottom:16px;--padding-start:0;--color:initial;--min-width:40px;--separator-width:8px;--separator-height:var(--separator-width);--separator-border-radius:999px;--separator-color:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;font-size:0.875rem}.input-otp-group.sc-ion-input-otp-md{-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-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:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.native-wrapper.sc-ion-input-otp-md{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:var(--min-width)}.native-input.sc-ion-input-otp-md{border-radius:var(--border-radius);width:var(--width);min-width:inherit;height:var(--height);border-width:var(--border-width);border-style:solid;border-color:var(--border-color);background:var(--background);color:var(--color);font-size:inherit;text-align:center;-webkit-appearance:none;-moz-appearance:none;appearance:none}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{caret-color:var(--highlight-color)}.input-otp-description.sc-ion-input-otp-md{color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-description-hidden.sc-ion-input-otp-md{display:none}.input-otp-separator.sc-ion-input-otp-md{border-radius:var(--separator-border-radius);-ms-flex-negative:0;flex-shrink:0;width:var(--separator-width);height:var(--separator-height);background:var(--separator-color)}.input-otp-size-small.sc-ion-input-otp-md-h{--width:40px;--height:40px}.input-otp-size-small.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md{gap:8px}.input-otp-size-medium.sc-ion-input-otp-md-h{--width:48px;--height:48px}.input-otp-size-large.sc-ion-input-otp-md-h{--width:56px;--height:56px}.input-otp-size-medium.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md,.input-otp-size-large.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md{gap:12px}.input-otp-shape-round.sc-ion-input-otp-md-h{--border-radius:16px}.input-otp-shape-soft.sc-ion-input-otp-md-h{--border-radius:8px}.input-otp-shape-rectangular.sc-ion-input-otp-md-h{--border-radius:0}.input-otp-fill-outline.sc-ion-input-otp-md-h{--background:none}.input-otp-fill-solid.sc-ion-input-otp-md-h{--border-color:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-disabled.sc-ion-input-otp-md-h{--color:var(--ion-color-step-350, var(--ion-text-color-step-650, #a6a6a6))}.input-otp-fill-outline.input-otp-disabled.sc-ion-input-otp-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.input-otp-disabled.sc-ion-input-otp-md-h,.input-otp-disabled.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:disabled{cursor:not-allowed}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{--border-color:var(--highlight-color);outline:none}.input-otp-fill-outline.input-otp-readonly.sc-ion-input-otp-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-fill-solid.input-otp-disabled.sc-ion-input-otp-md-h,.input-otp-fill-solid.input-otp-readonly.sc-ion-input-otp-md-h{--border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.ion-touched.ion-invalid.sc-ion-input-otp-md-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-otp-md-h{--highlight-color:var(--highlight-color-valid)}.has-focus.ion-valid.sc-ion-input-otp-md-h,.ion-touched.ion-invalid.sc-ion-input-otp-md-h{--border-color:var(--highlight-color)}.ion-color.sc-ion-input-otp-md-h{--highlight-color-focused:var(--ion-color-base)}.input-otp-fill-outline.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{border-color:rgba(var(--ion-color-base-rgb), 0.6)}.input-otp-fill-outline.ion-color.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-outline.ion-color.has-focus.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.has-focus.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:var(--ion-color-danger, #c5000f)}.input-otp-fill-outline.ion-color.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-outline.ion-color.has-focus.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.has-focus.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:var(--ion-color-success, #2dd55b)}.input-otp-fill-outline.input-otp-disabled.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:rgba(var(--ion-color-base-rgb), 0.3)}.sc-ion-input-otp-md-h{--border-width:1px}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{--border-width:2px}.input-otp-fill-outline.sc-ion-input-otp-md-h{--border-color:var(--ion-color-step-300, var(--ion-background-color-step-300, #b3b3b3))}`;
21451
+ const inputOtpMdCss = () => `.sc-ion-input-otp-md-h{--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--padding-top:16px;--padding-end:0;--padding-bottom:16px;--padding-start:0;--color:initial;--min-width:40px;--separator-width:8px;--separator-height:var(--separator-width);--separator-border-radius:999px;--separator-color:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);--border-color:initial;display:block;position:relative;font-size:0.875rem}.input-otp-group.sc-ion-input-otp-md{-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-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:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.native-wrapper.sc-ion-input-otp-md{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:var(--min-width)}.native-input.sc-ion-input-otp-md{border-radius:var(--border-radius);width:var(--width);min-width:inherit;height:var(--height);border-width:var(--border-width);border-style:solid;border-color:var(--border-color, var(--internal-border-color));background:var(--background);color:var(--color);font-size:inherit;text-align:center;-webkit-appearance:none;-moz-appearance:none;appearance:none}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{caret-color:var(--highlight-color)}.input-otp-description.sc-ion-input-otp-md{color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-description-hidden.sc-ion-input-otp-md{display:none}.input-otp-bottom.sc-ion-input-otp-md{font-size:0.75rem;line-height:1.25rem;text-align:center}.input-otp-bottom.sc-ion-input-otp-md .error-text.sc-ion-input-otp-md{display:none;color:var(--highlight-color-invalid)}.input-otp-bottom.sc-ion-input-otp-md .helper-text.sc-ion-input-otp-md{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-input-otp-md-h .input-otp-bottom.sc-ion-input-otp-md .error-text.sc-ion-input-otp-md{display:block}.ion-touched.ion-invalid.sc-ion-input-otp-md-h .input-otp-bottom.sc-ion-input-otp-md .helper-text.sc-ion-input-otp-md{display:none}.input-otp-separator.sc-ion-input-otp-md{border-radius:var(--separator-border-radius);-ms-flex-negative:0;flex-shrink:0;width:var(--separator-width);height:var(--separator-height);background:var(--separator-color)}.input-otp-size-small.sc-ion-input-otp-md-h{--width:40px;--height:40px}.input-otp-size-small.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md{gap:8px}.input-otp-size-medium.sc-ion-input-otp-md-h{--width:48px;--height:48px}.input-otp-size-large.sc-ion-input-otp-md-h{--width:56px;--height:56px}.input-otp-size-medium.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md,.input-otp-size-large.sc-ion-input-otp-md-h .input-otp-group.sc-ion-input-otp-md{gap:12px}.input-otp-shape-round.sc-ion-input-otp-md-h{--border-radius:16px}.input-otp-shape-soft.sc-ion-input-otp-md-h{--border-radius:8px}.input-otp-shape-rectangular.sc-ion-input-otp-md-h{--border-radius:0}.input-otp-fill-outline.sc-ion-input-otp-md-h{--background:none}.input-otp-fill-solid.sc-ion-input-otp-md-h{--internal-border-color:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-disabled.sc-ion-input-otp-md-h{--color:var(--ion-color-step-350, var(--ion-text-color-step-650, #a6a6a6))}.input-otp-fill-outline.input-otp-disabled.sc-ion-input-otp-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--internal-border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.input-otp-disabled.sc-ion-input-otp-md-h,.input-otp-disabled.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:disabled{cursor:not-allowed}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{--border-color:var(--highlight-color);outline:none}.input-otp-fill-outline.input-otp-readonly.sc-ion-input-otp-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2))}.input-otp-fill-solid.input-otp-disabled.sc-ion-input-otp-md-h,.input-otp-fill-solid.input-otp-readonly.sc-ion-input-otp-md-h{--internal-border-color:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.ion-touched.ion-invalid.sc-ion-input-otp-md-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-otp-md-h{--highlight-color:var(--highlight-color-valid)}.has-focus.ion-valid.sc-ion-input-otp-md-h,.ion-touched.ion-invalid.sc-ion-input-otp-md-h{--border-color:var(--highlight-color)}.ion-color.sc-ion-input-otp-md-h{--highlight-color-focused:var(--ion-color-base)}.input-otp-fill-outline.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{border-color:rgba(var(--ion-color-base-rgb), 0.6)}.input-otp-fill-outline.ion-color.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-outline.ion-color.has-focus.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.has-focus.ion-invalid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:var(--ion-color-danger, #c5000f)}.input-otp-fill-outline.ion-color.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-outline.ion-color.has-focus.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md,.input-otp-fill-solid.ion-color.has-focus.ion-valid.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:var(--ion-color-success, #2dd55b)}.input-otp-fill-outline.input-otp-disabled.ion-color.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md{border-color:rgba(var(--ion-color-base-rgb), 0.3)}.sc-ion-input-otp-md-h{--border-width:1px}.has-focus.sc-ion-input-otp-md-h .native-input.sc-ion-input-otp-md:focus{--border-width:2px}.input-otp-fill-outline.sc-ion-input-otp-md-h{--internal-border-color:var(--ion-color-step-300, var(--ion-background-color-step-300, #b3b3b3))}`;
21452
21452
 
21453
21453
  class InputOTP {
21454
21454
  constructor(hostRef) {
@@ -21458,9 +21458,11 @@ class InputOTP {
21458
21458
  this.ionComplete = createEvent(this, "ionComplete", 7);
21459
21459
  this.ionBlur = createEvent(this, "ionBlur", 7);
21460
21460
  this.ionFocus = createEvent(this, "ionFocus", 7);
21461
- this.inheritedAttributes = {};
21462
21461
  this.inputRefs = [];
21463
21462
  this.inputId = `ion-input-otp-${inputIds++}`;
21463
+ this.helperTextId = `${this.inputId}-helper-text`;
21464
+ this.errorTextId = `${this.inputId}-error-text`;
21465
+ this.descriptionId = `${this.inputId}-description`;
21464
21466
  this.parsedSeparators = [];
21465
21467
  /**
21466
21468
  * Tracks whether the user is navigating through input boxes using keyboard navigation
@@ -21476,6 +21478,7 @@ class InputOTP {
21476
21478
  this.inputValues = [];
21477
21479
  this.hasFocus = false;
21478
21480
  this.previousInputValues = [];
21481
+ this.isInvalid = false;
21479
21482
  /**
21480
21483
  * Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
21481
21484
  * Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
@@ -21828,6 +21831,9 @@ class InputOTP {
21828
21831
  this.inputRefs[tabbableIndex]?.focus();
21829
21832
  }
21830
21833
  }
21834
+ // The host keeps these (see `HOST_ARIA_ATTRIBUTES`), so re-render when they change
21835
+ onHostAriaChange() {
21836
+ }
21831
21837
  valueChanged() {
21832
21838
  this.initializeValues();
21833
21839
  this.updateTabIndexes();
@@ -21884,13 +21890,29 @@ class InputOTP {
21884
21890
  }
21885
21891
  this.parsedSeparators = separatorValues.filter((pos) => pos <= length);
21886
21892
  }
21893
+ connectedCallback() {
21894
+ const { el } = this;
21895
+ this.isInvalid = checkInvalidState(el);
21896
+ // Resumes watching after a move, since `componentWillLoad` only runs once
21897
+ this.ariaController?.init();
21898
+ }
21899
+ disconnectedCallback() {
21900
+ this.ariaController?.destroy();
21901
+ if (this.validationObserver) {
21902
+ this.validationObserver.disconnect();
21903
+ this.validationObserver = undefined;
21904
+ }
21905
+ }
21887
21906
  componentWillLoad() {
21888
- this.inheritedAttributes = inheritAriaAttributes(this.el);
21907
+ // Only read `role` at load so a later host write isn't copied to the group
21908
+ this.ariaController = createAttributeController(this.el, ariaAttributes.filter((attr) => !HOST_ARIA_ATTRIBUTES.includes(attr)), () => forceUpdate(), ['role']);
21889
21909
  this.processSeparators();
21890
21910
  this.initializeValues();
21891
21911
  }
21892
21912
  componentDidLoad() {
21893
21913
  this.updateTabIndexes();
21914
+ // The description only exists after the first render, so render again to reference it
21915
+ if (this.getDescriptionText()) ;
21894
21916
  }
21895
21917
  componentDidRender() {
21896
21918
  if (this.updateTabIndexesAfterRender) {
@@ -22068,14 +22090,77 @@ class InputOTP {
22068
22090
  const { length } = this;
22069
22091
  return this.parsedSeparators.includes(index + 1) && index < length - 1;
22070
22092
  }
22093
+ /**
22094
+ * Returns `undefined` until the first render creates the description container.
22095
+ */
22096
+ getDescriptionText() {
22097
+ return this.el.querySelector('.input-otp-description')?.textContent?.trim();
22098
+ }
22099
+ getHintTextId() {
22100
+ const { isInvalid, helperText, errorText, helperTextId, errorTextId } = this;
22101
+ if (isInvalid && errorText) {
22102
+ return errorTextId;
22103
+ }
22104
+ if (helperText) {
22105
+ return helperTextId;
22106
+ }
22107
+ return undefined;
22108
+ }
22109
+ renderHintText() {
22110
+ const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
22111
+ return [
22112
+ hAsync("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null),
22113
+ hAsync("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null),
22114
+ ];
22115
+ }
22116
+ renderBottomContent() {
22117
+ const { helperText, errorText } = this;
22118
+ if (!helperText && !errorText) {
22119
+ return;
22120
+ }
22121
+ return hAsync("div", { class: "input-otp-bottom" }, this.renderHintText());
22122
+ }
22123
+ /**
22124
+ * A custom formatter is used as is so translators control the whole name.
22125
+ * With a host `aria-labelledby`, each box also references itself so its
22126
+ * position is still read.
22127
+ */
22128
+ getInputLabelAttributes(index, hostAttributes) {
22129
+ const { inputId, inputLabelFormatter, length } = this;
22130
+ const hostLabel = hostAttributes['aria-label'];
22131
+ const hostLabelledBy = hostAttributes['aria-labelledby'];
22132
+ const position = `${index + 1} of ${length}`;
22133
+ if (inputLabelFormatter !== undefined) {
22134
+ try {
22135
+ return { 'aria-label': inputLabelFormatter(index, length) };
22136
+ }
22137
+ catch (e) {
22138
+ printIonError('[ion-input-otp] - Exception in provided `inputLabelFormatter`:', e);
22139
+ }
22140
+ }
22141
+ if (hostLabelledBy) {
22142
+ return { 'aria-label': position, 'aria-labelledby': `${hostLabelledBy} ${inputId}-${index}` };
22143
+ }
22144
+ return { 'aria-label': hostLabel ? `${hostLabel}, ${position}` : `Input ${position}` };
22145
+ }
22071
22146
  render() {
22072
- const { autocapitalize, color, disabled, el, fill, hasFocus, inheritedAttributes, inputId, inputRefs, inputValues, length, readonly, shape, size, } = this;
22147
+ const { ariaController, autocapitalize, color, descriptionId, disabled, el, fill, hasFocus, inputId, inputRefs, inputValues, isInvalid, length, readonly, shape, size, } = this;
22073
22148
  const mode = getIonMode$1(this);
22074
22149
  const inputmode = this.getInputmode();
22075
22150
  const tabbableIndex = this.getTabbableIndex();
22076
22151
  const pattern = this.getPattern();
22077
- const hasDescription = el.querySelector('.input-otp-description')?.textContent?.trim() !== '';
22078
- return (hAsync(Host, { key: 'def9fbd4fa135e6f435380c6ea86ac1621b4a111', class: createColorClasses$1(color, {
22152
+ const descriptionText = this.getDescriptionText();
22153
+ // Keep the description visible until the first render can check it
22154
+ const hasDescription = descriptionText !== '';
22155
+ /**
22156
+ * Screen readers only announce these from the focused input. The
22157
+ * description stays on the group so it isn't repeated for every input.
22158
+ */
22159
+ const { 'aria-errormessage': ariaErrorMessage, 'aria-required': ariaRequired, ...groupAttributes } = ariaController?.attributes ?? {};
22160
+ const hostDescribedBy = el.getAttribute('aria-describedby');
22161
+ const hostInvalid = el.getAttribute('aria-invalid') ?? undefined;
22162
+ const describedBy = [hostDescribedBy, this.getHintTextId()].filter(Boolean).join(' ');
22163
+ return (hAsync(Host, { key: '5b13c3bed3979e269cf4409895954edb171d68f3', class: createColorClasses$1(color, {
22079
22164
  [mode]: true,
22080
22165
  'has-focus': hasFocus,
22081
22166
  [`input-otp-size-${size}`]: true,
@@ -22083,7 +22168,7 @@ class InputOTP {
22083
22168
  [`input-otp-fill-${fill}`]: true,
22084
22169
  'input-otp-disabled': disabled,
22085
22170
  'input-otp-readonly': readonly,
22086
- }) }, hAsync("div", { key: '5d3d7646a3d4fc856b7b2e1f53d29fca47b10baf', 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) => {
22171
+ }) }, hAsync("div", { key: '6db010743f0eb5e059dc00de5822f117a264bb16', role: "group", class: "input-otp-group", ...groupAttributes, "aria-label": groupAttributes['aria-label'] || 'One-time password input', "aria-describedby": descriptionText ? descriptionId : undefined }, Array.from({ length }).map((_, index) => (hAsync(Fragment, null, hAsync("div", { class: "native-wrapper" }, hAsync("input", { class: "native-input", id: `${inputId}-${index}`, ...this.getInputLabelAttributes(index, groupAttributes), "aria-describedby": describedBy || undefined, "aria-errormessage": ariaErrorMessage, "aria-invalid": isInvalid ? 'true' : hostInvalid, "aria-required": ariaRequired, 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) => {
22087
22172
  if (el) {
22088
22173
  inputRefs[index] = el;
22089
22174
  }
@@ -22091,13 +22176,19 @@ class InputOTP {
22091
22176
  // The input was removed, so drop its ref and any after it.
22092
22177
  inputRefs.splice(index);
22093
22178
  }
22094
- }, 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: '9d72a4ab35b5fdd6bba9701050c385ed253b310f', class: {
22179
+ }, 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: '4d55d7532dcc28fadcb2f860dd2fcd2aa45ccccc', id: descriptionId, class: {
22095
22180
  'input-otp-description': true,
22096
22181
  'input-otp-description-hidden': !hasDescription,
22097
- } }, hAsync("slot", { key: '7deb3373c0d4e5deac22fa51577d271b9bb3a6d2' }))));
22182
+ } }, hAsync("slot", { key: '5d6823f48a9786799c9d485ce0d6b9de2ae7f537' })), this.renderBottomContent()));
22098
22183
  }
22099
22184
  get el() { return getElement(this); }
22100
22185
  static get watchers() { return {
22186
+ "aria-describedby": [{
22187
+ "onHostAriaChange": 0
22188
+ }],
22189
+ "aria-invalid": [{
22190
+ "onHostAriaChange": 0
22191
+ }],
22101
22192
  "value": [{
22102
22193
  "valueChanged": 0
22103
22194
  }],
@@ -22121,7 +22212,10 @@ class InputOTP {
22121
22212
  "autocapitalize": [1],
22122
22213
  "color": [513],
22123
22214
  "disabled": [516],
22215
+ "errorText": [1, "error-text"],
22124
22216
  "fill": [1],
22217
+ "helperText": [1, "helper-text"],
22218
+ "inputLabelFormatter": [16],
22125
22219
  "inputmode": [1],
22126
22220
  "length": [2],
22127
22221
  "pattern": [1],
@@ -22134,6 +22228,7 @@ class InputOTP {
22134
22228
  "inputValues": [32],
22135
22229
  "hasFocus": [32],
22136
22230
  "previousInputValues": [32],
22231
+ "isInvalid": [32],
22137
22232
  "setFocus": [64]
22138
22233
  },
22139
22234
  "$listeners$": undefined,
@@ -22142,6 +22237,12 @@ class InputOTP {
22142
22237
  }; }
22143
22238
  }
22144
22239
  let inputIds = 0;
22240
+ /**
22241
+ * The attribute controller removes these from the host, so an app could never
22242
+ * clear them. They stay on the host instead, which only works for global
22243
+ * attributes since the host has no role.
22244
+ */
22245
+ const HOST_ARIA_ATTRIBUTES = ['aria-describedby', 'aria-invalid'];
22145
22246
 
22146
22247
  const iosInputPasswordToggleCss = () => ``;
22147
22248
 
@@ -24331,7 +24432,7 @@ class Menu {
24331
24432
  * of the split pane. If the split pane is
24332
24433
  * hidden then the menu should be too.
24333
24434
  */
24334
- const splitPane = this.el.closest('ion-split-pane');
24435
+ const splitPane = this.getSplitPane();
24335
24436
  if (splitPane !== null) {
24336
24437
  this.isPaneVisible = await splitPane.isVisible();
24337
24438
  }
@@ -24370,8 +24471,8 @@ class Menu {
24370
24471
  this.contentEl = undefined;
24371
24472
  }
24372
24473
  onSplitPaneChanged(ev) {
24373
- const closestSplitPane = this.el.closest('ion-split-pane');
24374
- if (closestSplitPane !== null && closestSplitPane === ev.target) {
24474
+ const splitPane = this.getSplitPane();
24475
+ if (splitPane !== null && splitPane === ev.target) {
24375
24476
  this.isPaneVisible = ev.detail.visible;
24376
24477
  this.updateState();
24377
24478
  }
@@ -24569,6 +24670,24 @@ class Menu {
24569
24670
  _isActive() {
24570
24671
  return !this.disabled && !this.isPaneVisible;
24571
24672
  }
24673
+ /**
24674
+ * Returns the split pane this menu is a side pane of.
24675
+ * A menu inside the split pane's main content, such as one
24676
+ * in a page, is a regular menu. The menu doesn't need to be
24677
+ * a direct child, since it can be wrapped in a component.
24678
+ */
24679
+ getSplitPane() {
24680
+ const splitPane = this.el.closest('ion-split-pane');
24681
+ const main = this.el.closest('.split-pane-main');
24682
+ /**
24683
+ * A split pane can be the main content of an outer split
24684
+ * pane, so only this split pane's main content counts.
24685
+ */
24686
+ if (splitPane === null || (main !== null && main !== splitPane && splitPane.contains(main))) {
24687
+ return null;
24688
+ }
24689
+ return splitPane;
24690
+ }
24572
24691
  canSwipe() {
24573
24692
  return this.swipeGesture && !this.isAnimating && this._isActive();
24574
24693
  }
@@ -24811,21 +24930,21 @@ class Menu {
24811
24930
  }
24812
24931
  }
24813
24932
  render() {
24814
- const { type, disabled, el, isPaneVisible, inheritedAttributes, side } = this;
24933
+ const { type, disabled, isPaneVisible, inheritedAttributes, side } = this;
24815
24934
  const mode = getIonMode$1(this);
24816
24935
  /**
24817
24936
  * If the Close Watcher is enabled then
24818
24937
  * the ionBackButton listener in the menu controller
24819
24938
  * will handle closing the menu when Escape is pressed.
24820
24939
  */
24821
- return (hAsync(Host, { key: '5cf26df26d4e539860cbeaea98ec621b98c3fcfc', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
24940
+ return (hAsync(Host, { key: '7481c8a32a135fb0fd6d5591eecbf3fb0a8e8dde', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
24822
24941
  [mode]: true,
24823
24942
  [`menu-type-${type}`]: true,
24824
24943
  'menu-enabled': !disabled,
24825
24944
  [`menu-side-${side}`]: true,
24826
24945
  'menu-pane-visible': isPaneVisible,
24827
- 'split-pane-side': hostContext('ion-split-pane', el),
24828
- } }, hAsync("div", { key: 'f337016e293bb8665c99762e0c389dd6c372bb33', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, hAsync("slot", { key: '4c3fe331aa42cd57d7ad9bd1f5910f8eeb62d7da' })), hAsync("ion-backdrop", { key: '61af7ea876d81574841e1dd3e81e2352e555d096', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
24946
+ 'split-pane-side': this.getSplitPane() !== null,
24947
+ } }, hAsync("div", { key: '8ac2f0f531db944a46e5fef016d0b18bd7b804cc', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, hAsync("slot", { key: '1ac3e13ccccf1adb7915b739fc794f2889b626ce' })), hAsync("ion-backdrop", { key: 'f8becbf4de1a13feb57fb87973befecb88510bab', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
24829
24948
  }
24830
24949
  get el() { return getElement(this); }
24831
24950
  static get watchers() { return {
@@ -35719,6 +35838,14 @@ class Route {
35719
35838
  *
35720
35839
  * Accepts paths similar to expressjs so that you can define parameters
35721
35840
  * in the url /foo/:bar where bar would be available in incoming props.
35841
+ *
35842
+ * A url ending in `*`, such as `*` or `/admin/*`, matches any remaining path,
35843
+ * including none, so `/admin/*` also matches `/admin`. It only wins over a
35844
+ * route that matches the whole path when it has more fixed segments, so
35845
+ * `/admin/*` wins over `/:section/:id` but not over `/admin/:id`. It always
35846
+ * wins over a route that matches by ignoring trailing segments, such as
35847
+ * `/admin` for `/admin/users`. The matched path is passed in the `pathMatch`
35848
+ * prop without a leading `/`. A `*` on a route with child routes is ignored.
35722
35849
  */
35723
35850
  this.url = '';
35724
35851
  }
@@ -35807,6 +35934,8 @@ class RouteRedirect {
35807
35934
  const ROUTER_INTENT_NONE = 'root';
35808
35935
  const ROUTER_INTENT_FORWARD = 'forward';
35809
35936
  const ROUTER_INTENT_BACK = 'back';
35937
+ /** Param that holds the path matched by a trailing `*` in an `ion-route` url. */
35938
+ const WILDCARD_PARAM = 'pathMatch';
35810
35939
 
35811
35940
  /** Join the non empty segments with "/". */
35812
35941
  const generatePath = (segments) => {
@@ -35840,12 +35969,13 @@ const writeSegments = (history, root, useHash, segments, direction, state, query
35840
35969
  *
35841
35970
  * Notes:
35842
35971
  * - parameter segments of the form :param are replaced with their value,
35843
- * - null is returned when a value is missing for any parameter segment.
35972
+ * - null is returned when a value is missing for any parameter segment,
35973
+ * - a trailing wildcard is replaced with the path it matched.
35844
35974
  */
35845
35975
  const chainToSegments = (chain) => {
35846
35976
  const segments = [];
35847
35977
  for (const route of chain) {
35848
- for (const segment of route.segments) {
35978
+ for (const segment of withoutWildcard(route.segments)) {
35849
35979
  if (segment[0] === ':') {
35850
35980
  const param = route.params && route.params[segment.slice(1)];
35851
35981
  if (!param) {
@@ -35857,9 +35987,22 @@ const chainToSegments = (chain) => {
35857
35987
  segments.push(segment);
35858
35988
  }
35859
35989
  }
35990
+ segments.push(...wildcardSegments(route));
35860
35991
  }
35861
35992
  return segments;
35862
35993
  };
35994
+ /** Only a `*` in the last segment of a route url is a wildcard. Elsewhere it's matched literally. */
35995
+ const endsWithWildcard = (segments) => {
35996
+ return segments[segments.length - 1] === '*';
35997
+ };
35998
+ /** Returns the path segments matched by the trailing wildcard of the route. */
35999
+ const wildcardSegments = (route) => {
36000
+ const pathMatch = endsWithWildcard(route.segments) ? route.params?.[WILDCARD_PARAM] : undefined;
36001
+ return pathMatch ? pathMatch.split('/').filter((s) => s.length > 0) : [];
36002
+ };
36003
+ const withoutWildcard = (segments) => {
36004
+ return endsWithWildcard(segments) ? segments.slice(0, -1) : segments;
36005
+ };
35863
36006
  /**
35864
36007
  * Removes the prefix segments from the path segments.
35865
36008
  *
@@ -36192,6 +36335,10 @@ const matchesIDs = (ids, chain) => {
36192
36335
  if (routeId.id.toLowerCase() !== routeChain.id) {
36193
36336
  break;
36194
36337
  }
36338
+ // Weight a wildcard route when the outlet reports its `pathMatch`
36339
+ if (routeId.params?.[WILDCARD_PARAM] !== undefined && endsWithWildcard(routeChain.segments)) {
36340
+ score++;
36341
+ }
36195
36342
  if (routeId.params) {
36196
36343
  const routeIdParams = Object.keys(routeId.params);
36197
36344
  // Only compare routes with the chain that have the same number of parameters.
@@ -36247,21 +36394,28 @@ const matchesSegments = (segments, chain) => {
36247
36394
  matchesDefault = true;
36248
36395
  }
36249
36396
  else {
36250
- for (const segment of chainSegments) {
36397
+ const params = {};
36398
+ for (const segment of withoutWildcard(chainSegments)) {
36251
36399
  const data = inputSegments.next();
36252
36400
  // data param
36253
36401
  if (segment[0] === ':') {
36254
36402
  if (data === '') {
36255
36403
  return null;
36256
36404
  }
36257
- allparams = allparams || [];
36258
- const params = allparams[i] || (allparams[i] = {});
36259
36405
  params[segment.slice(1)] = data;
36260
36406
  }
36261
36407
  else if (data !== segment) {
36262
36408
  return null;
36263
36409
  }
36264
36410
  }
36411
+ // A trailing `*` on a parent route has no effect. Its children match the rest of the path.
36412
+ if (i === chain.length - 1 && endsWithWildcard(chainSegments)) {
36413
+ params[WILDCARD_PARAM] = inputSegments.rest().join('/');
36414
+ }
36415
+ if (Object.keys(params).length > 0) {
36416
+ allparams = allparams || [];
36417
+ allparams[i] = params;
36418
+ }
36265
36419
  matchesDefault = false;
36266
36420
  }
36267
36421
  }
@@ -36293,25 +36447,38 @@ const mergeParams = (a, b) => {
36293
36447
  * Returns the best match or null when no match is found.
36294
36448
  * When a chain is returned the parameters are updated from the RouteIDs.
36295
36449
  * That is they contain both the componentProps of the <ion-route> and the parameter segment.
36450
+ *
36451
+ * When a wildcard route ties with other routes, a route without a wildcard that can build a url wins,
36452
+ * then the wildcard route. Otherwise the first route declared wins a tie.
36296
36453
  */
36297
36454
  const findChainForIDs = (ids, chains) => {
36298
- let match = null;
36299
36455
  let maxMatches = 0;
36456
+ let tied = [];
36300
36457
  for (const chain of chains) {
36301
36458
  const score = matchesIDs(ids, chain);
36302
36459
  if (score > maxMatches) {
36303
- match = chain;
36304
36460
  maxMatches = score;
36461
+ tied = [chain];
36462
+ }
36463
+ else if (score > 0 && score === maxMatches) {
36464
+ tied.push(chain);
36305
36465
  }
36306
36466
  }
36307
- if (match) {
36308
- return match.map((route, i) => ({
36309
- id: route.id,
36310
- segments: route.segments,
36311
- params: mergeParams(route.params, ids[i]?.params),
36312
- }));
36467
+ const matches = tied.map((chain) => chain.map((route, i) => ({
36468
+ id: route.id,
36469
+ segments: route.segments,
36470
+ params: mergeParams(route.params, ids[i]?.params),
36471
+ })));
36472
+ if (!matches.some(chainEndsWithWildcard)) {
36473
+ return matches.length > 0 ? matches[0] : null;
36313
36474
  }
36314
- return null;
36475
+ return matches.reduce((best, chain) => (tieRank(chain) > tieRank(best) ? chain : best));
36476
+ };
36477
+ const tieRank = (chain) => {
36478
+ if (chainEndsWithWildcard(chain)) {
36479
+ return 1;
36480
+ }
36481
+ return chainToSegments(chain) !== null ? 2 : 0;
36315
36482
  };
36316
36483
  /**
36317
36484
  * Finds the best match for the segments in the chains.
@@ -36319,10 +36486,17 @@ const findChainForIDs = (ids, chains) => {
36319
36486
  * Returns the best match or null when no match is found.
36320
36487
  * When a chain is returned the parameters are updated from the segments.
36321
36488
  * That is they contain both the componentProps of the <ion-route> and the parameter segments.
36489
+ *
36490
+ * When wildcard routes match, the one with the most fixed segments wins if it has more fixed segments than every
36491
+ * route that matched the whole path. Routes that only matched by ignoring trailing segments don't count.
36322
36492
  */
36323
36493
  const findChainForSegments = (segments, chains) => {
36324
36494
  let match = null;
36325
36495
  let bestScore = 0;
36496
+ let fullMatch = null;
36497
+ let bestFullScore = 0;
36498
+ let maxFullFixed = -1;
36499
+ let wildcard = null;
36326
36500
  for (const chain of chains) {
36327
36501
  const matchedChain = matchesSegments(segments, chain);
36328
36502
  if (matchedChain !== null) {
@@ -36331,9 +36505,51 @@ const findChainForSegments = (segments, chains) => {
36331
36505
  bestScore = score;
36332
36506
  match = matchedChain;
36333
36507
  }
36508
+ if (chainEndsWithWildcard(matchedChain)) {
36509
+ if (wildcard === null || winsWildcard(matchedChain, wildcard)) {
36510
+ wildcard = matchedChain;
36511
+ }
36512
+ }
36513
+ else if (!isPartialMatch(segments, matchedChain)) {
36514
+ if (score > bestFullScore) {
36515
+ bestFullScore = score;
36516
+ fullMatch = matchedChain;
36517
+ }
36518
+ maxFullFixed = Math.max(maxFullFixed, countFixedSegments(matchedChain));
36519
+ }
36520
+ }
36521
+ }
36522
+ // Without a wildcard to match the rest of the path, routes can still ignore trailing segments.
36523
+ if (wildcard === null) {
36524
+ return match;
36525
+ }
36526
+ // Compare fixed segments rather than priority, since nesting under default routes raises the priority
36527
+ return countFixedSegments(wildcard) > maxFullFixed ? wildcard : fullMatch;
36528
+ };
36529
+ /** Returns whether the chain matched the path segments only by ignoring some trailing segments. */
36530
+ const isPartialMatch = (segments, chain) => {
36531
+ const matched = chainToSegments(chain);
36532
+ return matched !== null && matched.length < segments.filter((s) => s !== '').length;
36533
+ };
36534
+ const chainEndsWithWildcard = (chain) => {
36535
+ return endsWithWildcard(chain[chain.length - 1].segments);
36536
+ };
36537
+ /** Returns whether the wildcard chain beats `best` by fixed segments, then by priority. */
36538
+ const winsWildcard = (chain, best) => {
36539
+ const chainFixed = countFixedSegments(chain);
36540
+ const bestFixed = countFixedSegments(best);
36541
+ return chainFixed > bestFixed || (chainFixed === bestFixed && computePriority(chain) > computePriority(best));
36542
+ };
36543
+ const countFixedSegments = (chain) => {
36544
+ let count = 0;
36545
+ for (const route of chain) {
36546
+ for (const segment of withoutWildcard(route.segments)) {
36547
+ if (segment !== '' && segment[0] !== ':') {
36548
+ count++;
36549
+ }
36334
36550
  }
36335
36551
  }
36336
- return match;
36552
+ return count;
36337
36553
  };
36338
36554
  /**
36339
36555
  * Computes the priority of a chain.
@@ -36345,12 +36561,14 @@ const findChainForSegments = (segments, chains) => {
36345
36561
  * - /path/to/page
36346
36562
  *
36347
36563
  * The second one will be given a higher priority because "page" is a fixed segment (vs ":where", a parameter segment).
36564
+ *
36565
+ * A trailing wildcard is not counted.
36348
36566
  */
36349
36567
  const computePriority = (chain) => {
36350
36568
  let score = 1;
36351
36569
  let level = 1;
36352
36570
  for (const route of chain) {
36353
- for (const segment of route.segments) {
36571
+ for (const segment of withoutWildcard(route.segments)) {
36354
36572
  if (segment[0] === ':') {
36355
36573
  score += Math.pow(1, level);
36356
36574
  }
@@ -36372,6 +36590,12 @@ class RouterSegments {
36372
36590
  }
36373
36591
  return '';
36374
36592
  }
36593
+ /** Consumes and returns the remaining non empty segments. */
36594
+ rest() {
36595
+ const rest = this.segments.filter((s) => s !== '');
36596
+ this.segments = [];
36597
+ return rest;
36598
+ }
36375
36599
  }
36376
36600
 
36377
36601
  const readProp = (el, prop) => {