@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.
- package/components/ion-input-otp.js +1 -1
- package/components/ion-menu.js +1 -1
- package/components/ion-router.js +1 -1
- package/dist/cjs/ion-input-otp.cjs.entry.js +126 -10
- package/dist/cjs/ion-menu_3.cjs.entry.js +25 -7
- package/dist/cjs/ion-route_4.cjs.entry.js +121 -16
- package/dist/cjs/ionic.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/input-otp/input-otp.ios.css +30 -5
- package/dist/collection/components/input-otp/input-otp.js +191 -12
- package/dist/collection/components/input-otp/input-otp.md.css +30 -5
- package/dist/collection/components/menu/menu.js +25 -8
- package/dist/collection/components/route/route.js +9 -1
- package/dist/collection/components/route-redirect/route-redirect.js +1 -1
- package/dist/collection/components/router/utils/constants.js +2 -0
- package/dist/collection/components/router/utils/matching.js +97 -14
- package/dist/collection/components/router/utils/path.js +17 -3
- package/dist/docs.json +92 -3
- package/dist/esm/ion-input-otp.entry.js +128 -12
- package/dist/esm/ion-menu_3.entry.js +26 -8
- package/dist/esm/ion-route_4.entry.js +121 -16
- package/dist/esm/ionic.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/html.html-data.json +10 -2
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/p-095da8ec.entry.js +4 -0
- package/dist/ionic/p-705759fd.entry.js +4 -0
- package/dist/ionic/p-99c518de.entry.js +4 -0
- package/dist/types/components/input-otp/input-otp-interface.d.ts +1 -0
- package/dist/types/components/input-otp/input-otp.d.ts +40 -2
- package/dist/types/components/menu/menu.d.ts +7 -0
- package/dist/types/components/route/route.d.ts +8 -0
- package/dist/types/components/route-redirect/route-redirect.d.ts +3 -1
- package/dist/types/components/router/utils/constants.d.ts +2 -0
- package/dist/types/components/router/utils/matching.d.ts +10 -0
- package/dist/types/components/router/utils/path.d.ts +5 -1
- package/dist/types/components.d.ts +32 -6
- package/hydrate/index.js +257 -33
- package/hydrate/index.mjs +257 -33
- package/package.json +1 -1
- package/dist/ionic/p-539d6c8e.entry.js +0 -4
- package/dist/ionic/p-7ce9c6f8.entry.js +0 -4
- package/dist/ionic/p-af11d3c6.entry.js +0 -4
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
|
-
import { r as registerInstance, d as createEvent, a as printIonWarning, h, F as Fragment, f as Host, g as getElement } from './index-BpRUsN_W.js';
|
|
5
|
-
import {
|
|
4
|
+
import { r as registerInstance, d as createEvent, j as forceUpdate, a as printIonWarning, h, c as printIonError, F as Fragment, f as Host, g as getElement } from './index-BpRUsN_W.js';
|
|
5
|
+
import { a as createAttributeController } from './attribute-controller-DPMIcbef.js';
|
|
6
|
+
import { q as ariaAttributes } from './helpers-BJqKF1pr.js';
|
|
6
7
|
import { i as isRTL } from './dir-Dojwmvde.js';
|
|
8
|
+
import { c as checkInvalidState } from './validity-DJztqcrH.js';
|
|
7
9
|
import { c as createColorClasses } from './theme-byZM6qHV.js';
|
|
8
10
|
import { b as getIonMode } from './ionic-global-Cep6oYzK.js';
|
|
9
11
|
|
|
10
|
-
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))))}`;
|
|
12
|
+
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))))}`;
|
|
11
13
|
|
|
12
|
-
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))}`;
|
|
14
|
+
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))}`;
|
|
13
15
|
|
|
14
16
|
const InputOTP = class {
|
|
15
17
|
constructor(hostRef) {
|
|
@@ -19,9 +21,11 @@ const InputOTP = class {
|
|
|
19
21
|
this.ionComplete = createEvent(this, "ionComplete", 7);
|
|
20
22
|
this.ionBlur = createEvent(this, "ionBlur", 7);
|
|
21
23
|
this.ionFocus = createEvent(this, "ionFocus", 7);
|
|
22
|
-
this.inheritedAttributes = {};
|
|
23
24
|
this.inputRefs = [];
|
|
24
25
|
this.inputId = `ion-input-otp-${inputIds++}`;
|
|
26
|
+
this.helperTextId = `${this.inputId}-helper-text`;
|
|
27
|
+
this.errorTextId = `${this.inputId}-error-text`;
|
|
28
|
+
this.descriptionId = `${this.inputId}-description`;
|
|
25
29
|
this.parsedSeparators = [];
|
|
26
30
|
/**
|
|
27
31
|
* Tracks whether the user is navigating through input boxes using keyboard navigation
|
|
@@ -37,6 +41,7 @@ const InputOTP = class {
|
|
|
37
41
|
this.inputValues = [];
|
|
38
42
|
this.hasFocus = false;
|
|
39
43
|
this.previousInputValues = [];
|
|
44
|
+
this.isInvalid = false;
|
|
40
45
|
/**
|
|
41
46
|
* Indicates whether and how the text value should be automatically capitalized as it is entered/edited by the user.
|
|
42
47
|
* Available options: `"off"`, `"none"`, `"on"`, `"sentences"`, `"words"`, `"characters"`.
|
|
@@ -389,6 +394,10 @@ const InputOTP = class {
|
|
|
389
394
|
this.inputRefs[tabbableIndex]?.focus();
|
|
390
395
|
}
|
|
391
396
|
}
|
|
397
|
+
// The host keeps these (see `HOST_ARIA_ATTRIBUTES`), so re-render when they change
|
|
398
|
+
onHostAriaChange() {
|
|
399
|
+
forceUpdate(this);
|
|
400
|
+
}
|
|
392
401
|
valueChanged() {
|
|
393
402
|
this.initializeValues();
|
|
394
403
|
this.updateTabIndexes();
|
|
@@ -445,13 +454,45 @@ const InputOTP = class {
|
|
|
445
454
|
}
|
|
446
455
|
this.parsedSeparators = separatorValues.filter((pos) => pos <= length);
|
|
447
456
|
}
|
|
457
|
+
connectedCallback() {
|
|
458
|
+
const { el } = this;
|
|
459
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
460
|
+
this.validationObserver = new MutationObserver(() => {
|
|
461
|
+
const newIsInvalid = checkInvalidState(el);
|
|
462
|
+
if (this.isInvalid !== newIsInvalid) {
|
|
463
|
+
this.isInvalid = newIsInvalid;
|
|
464
|
+
// Force a re-render to update aria-describedby immediately
|
|
465
|
+
forceUpdate(this);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
this.validationObserver.observe(el, {
|
|
469
|
+
attributes: true,
|
|
470
|
+
attributeFilter: ['class'],
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
this.isInvalid = checkInvalidState(el);
|
|
474
|
+
// Resumes watching after a move, since `componentWillLoad` only runs once
|
|
475
|
+
this.ariaController?.init();
|
|
476
|
+
}
|
|
477
|
+
disconnectedCallback() {
|
|
478
|
+
this.ariaController?.destroy();
|
|
479
|
+
if (this.validationObserver) {
|
|
480
|
+
this.validationObserver.disconnect();
|
|
481
|
+
this.validationObserver = undefined;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
448
484
|
componentWillLoad() {
|
|
449
|
-
|
|
485
|
+
// Only read `role` at load so a later host write isn't copied to the group
|
|
486
|
+
this.ariaController = createAttributeController(this.el, ariaAttributes.filter((attr) => !HOST_ARIA_ATTRIBUTES.includes(attr)), () => forceUpdate(this), ['role']);
|
|
450
487
|
this.processSeparators();
|
|
451
488
|
this.initializeValues();
|
|
452
489
|
}
|
|
453
490
|
componentDidLoad() {
|
|
454
491
|
this.updateTabIndexes();
|
|
492
|
+
// The description only exists after the first render, so render again to reference it
|
|
493
|
+
if (this.getDescriptionText()) {
|
|
494
|
+
forceUpdate(this);
|
|
495
|
+
}
|
|
455
496
|
}
|
|
456
497
|
componentDidRender() {
|
|
457
498
|
if (this.updateTabIndexesAfterRender) {
|
|
@@ -629,14 +670,77 @@ const InputOTP = class {
|
|
|
629
670
|
const { length } = this;
|
|
630
671
|
return this.parsedSeparators.includes(index + 1) && index < length - 1;
|
|
631
672
|
}
|
|
673
|
+
/**
|
|
674
|
+
* Returns `undefined` until the first render creates the description container.
|
|
675
|
+
*/
|
|
676
|
+
getDescriptionText() {
|
|
677
|
+
return this.el.querySelector('.input-otp-description')?.textContent?.trim();
|
|
678
|
+
}
|
|
679
|
+
getHintTextId() {
|
|
680
|
+
const { isInvalid, helperText, errorText, helperTextId, errorTextId } = this;
|
|
681
|
+
if (isInvalid && errorText) {
|
|
682
|
+
return errorTextId;
|
|
683
|
+
}
|
|
684
|
+
if (helperText) {
|
|
685
|
+
return helperTextId;
|
|
686
|
+
}
|
|
687
|
+
return undefined;
|
|
688
|
+
}
|
|
689
|
+
renderHintText() {
|
|
690
|
+
const { helperText, errorText, helperTextId, errorTextId, isInvalid } = this;
|
|
691
|
+
return [
|
|
692
|
+
h("div", { id: helperTextId, class: "helper-text", "aria-live": "polite" }, !isInvalid ? helperText : null),
|
|
693
|
+
h("div", { id: errorTextId, class: "error-text", role: "alert" }, isInvalid ? errorText : null),
|
|
694
|
+
];
|
|
695
|
+
}
|
|
696
|
+
renderBottomContent() {
|
|
697
|
+
const { helperText, errorText } = this;
|
|
698
|
+
if (!helperText && !errorText) {
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
return h("div", { class: "input-otp-bottom" }, this.renderHintText());
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* A custom formatter is used as is so translators control the whole name.
|
|
705
|
+
* With a host `aria-labelledby`, each box also references itself so its
|
|
706
|
+
* position is still read.
|
|
707
|
+
*/
|
|
708
|
+
getInputLabelAttributes(index, hostAttributes) {
|
|
709
|
+
const { inputId, inputLabelFormatter, length } = this;
|
|
710
|
+
const hostLabel = hostAttributes['aria-label'];
|
|
711
|
+
const hostLabelledBy = hostAttributes['aria-labelledby'];
|
|
712
|
+
const position = `${index + 1} of ${length}`;
|
|
713
|
+
if (inputLabelFormatter !== undefined) {
|
|
714
|
+
try {
|
|
715
|
+
return { 'aria-label': inputLabelFormatter(index, length) };
|
|
716
|
+
}
|
|
717
|
+
catch (e) {
|
|
718
|
+
printIonError('[ion-input-otp] - Exception in provided `inputLabelFormatter`:', e);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
if (hostLabelledBy) {
|
|
722
|
+
return { 'aria-label': position, 'aria-labelledby': `${hostLabelledBy} ${inputId}-${index}` };
|
|
723
|
+
}
|
|
724
|
+
return { 'aria-label': hostLabel ? `${hostLabel}, ${position}` : `Input ${position}` };
|
|
725
|
+
}
|
|
632
726
|
render() {
|
|
633
|
-
const { autocapitalize, color, disabled, el, fill, hasFocus,
|
|
727
|
+
const { ariaController, autocapitalize, color, descriptionId, disabled, el, fill, hasFocus, inputId, inputRefs, inputValues, isInvalid, length, readonly, shape, size, } = this;
|
|
634
728
|
const mode = getIonMode(this);
|
|
635
729
|
const inputmode = this.getInputmode();
|
|
636
730
|
const tabbableIndex = this.getTabbableIndex();
|
|
637
731
|
const pattern = this.getPattern();
|
|
638
|
-
const
|
|
639
|
-
|
|
732
|
+
const descriptionText = this.getDescriptionText();
|
|
733
|
+
// Keep the description visible until the first render can check it
|
|
734
|
+
const hasDescription = descriptionText !== '';
|
|
735
|
+
/**
|
|
736
|
+
* Screen readers only announce these from the focused input. The
|
|
737
|
+
* description stays on the group so it isn't repeated for every input.
|
|
738
|
+
*/
|
|
739
|
+
const { 'aria-errormessage': ariaErrorMessage, 'aria-required': ariaRequired, ...groupAttributes } = ariaController?.attributes ?? {};
|
|
740
|
+
const hostDescribedBy = el.getAttribute('aria-describedby');
|
|
741
|
+
const hostInvalid = el.getAttribute('aria-invalid') ?? undefined;
|
|
742
|
+
const describedBy = [hostDescribedBy, this.getHintTextId()].filter(Boolean).join(' ');
|
|
743
|
+
return (h(Host, { key: '5b13c3bed3979e269cf4409895954edb171d68f3', class: createColorClasses(color, {
|
|
640
744
|
[mode]: true,
|
|
641
745
|
'has-focus': hasFocus,
|
|
642
746
|
[`input-otp-size-${size}`]: true,
|
|
@@ -644,7 +748,7 @@ const InputOTP = class {
|
|
|
644
748
|
[`input-otp-fill-${fill}`]: true,
|
|
645
749
|
'input-otp-disabled': disabled,
|
|
646
750
|
'input-otp-readonly': readonly,
|
|
647
|
-
}) }, h("div", { key: '
|
|
751
|
+
}) }, h("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) => (h(Fragment, null, h("div", { class: "native-wrapper" }, h("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) => {
|
|
648
752
|
if (el) {
|
|
649
753
|
inputRefs[index] = el;
|
|
650
754
|
}
|
|
@@ -652,13 +756,19 @@ const InputOTP = class {
|
|
|
652
756
|
// The input was removed, so drop its ref and any after it.
|
|
653
757
|
inputRefs.splice(index);
|
|
654
758
|
}
|
|
655
|
-
}, onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && h("div", { class: "input-otp-separator" }))))), h("div", { key: '
|
|
759
|
+
}, onInput: this.onInput(index), onBlur: this.onBlur, onFocus: this.onFocus(index), onKeyDown: this.onKeyDown(index), onPaste: this.onPaste })), this.showSeparator(index) && h("div", { class: "input-otp-separator" }))))), h("div", { key: '4d55d7532dcc28fadcb2f860dd2fcd2aa45ccccc', id: descriptionId, class: {
|
|
656
760
|
'input-otp-description': true,
|
|
657
761
|
'input-otp-description-hidden': !hasDescription,
|
|
658
|
-
} }, h("slot", { key: '
|
|
762
|
+
} }, h("slot", { key: '5d6823f48a9786799c9d485ce0d6b9de2ae7f537' })), this.renderBottomContent()));
|
|
659
763
|
}
|
|
660
764
|
get el() { return getElement(this); }
|
|
661
765
|
static get watchers() { return {
|
|
766
|
+
"aria-describedby": [{
|
|
767
|
+
"onHostAriaChange": 0
|
|
768
|
+
}],
|
|
769
|
+
"aria-invalid": [{
|
|
770
|
+
"onHostAriaChange": 0
|
|
771
|
+
}],
|
|
662
772
|
"value": [{
|
|
663
773
|
"valueChanged": 0
|
|
664
774
|
}],
|
|
@@ -673,6 +783,12 @@ const InputOTP = class {
|
|
|
673
783
|
}; }
|
|
674
784
|
};
|
|
675
785
|
let inputIds = 0;
|
|
786
|
+
/**
|
|
787
|
+
* The attribute controller removes these from the host, so an app could never
|
|
788
|
+
* clear them. They stay on the host instead, which only works for global
|
|
789
|
+
* attributes since the host has no role.
|
|
790
|
+
*/
|
|
791
|
+
const HOST_ARIA_ATTRIBUTES = ['aria-describedby', 'aria-invalid'];
|
|
676
792
|
InputOTP.style = {
|
|
677
793
|
ios: inputOtpIosCss(),
|
|
678
794
|
md: inputOtpMdCss()
|
|
@@ -8,7 +8,7 @@ import { G as GESTURE_CONTROLLER } from './gesture-controller-B_gJaBk0.js';
|
|
|
8
8
|
import { s as isEndSide, i as inheritAriaAttributes, l as assert, e as clamp } from './helpers-BJqKF1pr.js';
|
|
9
9
|
import { m as menuController } from './index-DIouXecD.js';
|
|
10
10
|
import { b as getIonMode, a as isPlatform } from './ionic-global-Cep6oYzK.js';
|
|
11
|
-
import {
|
|
11
|
+
import { c as createColorClasses, h as hostContext } from './theme-byZM6qHV.js';
|
|
12
12
|
import { u as menuOutline, v as menuSharp } from './index-BvabGprD.js';
|
|
13
13
|
import './framework-delegate-CDjM1vRH.js';
|
|
14
14
|
import './dir-Dojwmvde.js';
|
|
@@ -172,7 +172,7 @@ const Menu = class {
|
|
|
172
172
|
* of the split pane. If the split pane is
|
|
173
173
|
* hidden then the menu should be too.
|
|
174
174
|
*/
|
|
175
|
-
const splitPane = this.
|
|
175
|
+
const splitPane = this.getSplitPane();
|
|
176
176
|
if (splitPane !== null) {
|
|
177
177
|
this.isPaneVisible = await splitPane.isVisible();
|
|
178
178
|
}
|
|
@@ -211,8 +211,8 @@ const Menu = class {
|
|
|
211
211
|
this.contentEl = undefined;
|
|
212
212
|
}
|
|
213
213
|
onSplitPaneChanged(ev) {
|
|
214
|
-
const
|
|
215
|
-
if (
|
|
214
|
+
const splitPane = this.getSplitPane();
|
|
215
|
+
if (splitPane !== null && splitPane === ev.target) {
|
|
216
216
|
this.isPaneVisible = ev.detail.visible;
|
|
217
217
|
this.updateState();
|
|
218
218
|
}
|
|
@@ -410,6 +410,24 @@ const Menu = class {
|
|
|
410
410
|
_isActive() {
|
|
411
411
|
return !this.disabled && !this.isPaneVisible;
|
|
412
412
|
}
|
|
413
|
+
/**
|
|
414
|
+
* Returns the split pane this menu is a side pane of.
|
|
415
|
+
* A menu inside the split pane's main content, such as one
|
|
416
|
+
* in a page, is a regular menu. The menu doesn't need to be
|
|
417
|
+
* a direct child, since it can be wrapped in a component.
|
|
418
|
+
*/
|
|
419
|
+
getSplitPane() {
|
|
420
|
+
const splitPane = this.el.closest('ion-split-pane');
|
|
421
|
+
const main = this.el.closest('.split-pane-main');
|
|
422
|
+
/**
|
|
423
|
+
* A split pane can be the main content of an outer split
|
|
424
|
+
* pane, so only this split pane's main content counts.
|
|
425
|
+
*/
|
|
426
|
+
if (splitPane === null || (main !== null && main !== splitPane && splitPane.contains(main))) {
|
|
427
|
+
return null;
|
|
428
|
+
}
|
|
429
|
+
return splitPane;
|
|
430
|
+
}
|
|
413
431
|
canSwipe() {
|
|
414
432
|
return this.swipeGesture && !this.isAnimating && this._isActive();
|
|
415
433
|
}
|
|
@@ -653,21 +671,21 @@ const Menu = class {
|
|
|
653
671
|
}
|
|
654
672
|
}
|
|
655
673
|
render() {
|
|
656
|
-
const { type, disabled,
|
|
674
|
+
const { type, disabled, isPaneVisible, inheritedAttributes, side } = this;
|
|
657
675
|
const mode = getIonMode(this);
|
|
658
676
|
/**
|
|
659
677
|
* If the Close Watcher is enabled then
|
|
660
678
|
* the ionBackButton listener in the menu controller
|
|
661
679
|
* will handle closing the menu when Escape is pressed.
|
|
662
680
|
*/
|
|
663
|
-
return (h(Host, { key: '
|
|
681
|
+
return (h(Host, { key: '7481c8a32a135fb0fd6d5591eecbf3fb0a8e8dde', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
|
|
664
682
|
[mode]: true,
|
|
665
683
|
[`menu-type-${type}`]: true,
|
|
666
684
|
'menu-enabled': !disabled,
|
|
667
685
|
[`menu-side-${side}`]: true,
|
|
668
686
|
'menu-pane-visible': isPaneVisible,
|
|
669
|
-
'split-pane-side':
|
|
670
|
-
} }, h("div", { key: '
|
|
687
|
+
'split-pane-side': this.getSplitPane() !== null,
|
|
688
|
+
} }, h("div", { key: '8ac2f0f531db944a46e5fef016d0b18bd7b804cc', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, h("slot", { key: '1ac3e13ccccf1adb7915b739fc794f2889b626ce' })), h("ion-backdrop", { key: 'f8becbf4de1a13feb57fb87973befecb88510bab', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
|
|
671
689
|
}
|
|
672
690
|
get el() { return getElement(this); }
|
|
673
691
|
static get watchers() { return {
|
|
@@ -17,6 +17,14 @@ const Route = class {
|
|
|
17
17
|
*
|
|
18
18
|
* Accepts paths similar to expressjs so that you can define parameters
|
|
19
19
|
* in the url /foo/:bar where bar would be available in incoming props.
|
|
20
|
+
*
|
|
21
|
+
* A url ending in `*`, such as `*` or `/admin/*`, matches any remaining path,
|
|
22
|
+
* including none, so `/admin/*` also matches `/admin`. It only wins over a
|
|
23
|
+
* route that matches the whole path when it has more fixed segments, so
|
|
24
|
+
* `/admin/*` wins over `/:section/:id` but not over `/admin/:id`. It always
|
|
25
|
+
* wins over a route that matches by ignoring trailing segments, such as
|
|
26
|
+
* `/admin` for `/admin/users`. The matched path is passed in the `pathMatch`
|
|
27
|
+
* prop without a leading `/`. A `*` on a route with child routes is ignored.
|
|
20
28
|
*/
|
|
21
29
|
this.url = '';
|
|
22
30
|
}
|
|
@@ -80,6 +88,8 @@ const RouteRedirect = class {
|
|
|
80
88
|
const ROUTER_INTENT_NONE = 'root';
|
|
81
89
|
const ROUTER_INTENT_FORWARD = 'forward';
|
|
82
90
|
const ROUTER_INTENT_BACK = 'back';
|
|
91
|
+
/** Param that holds the path matched by a trailing `*` in an `ion-route` url. */
|
|
92
|
+
const WILDCARD_PARAM = 'pathMatch';
|
|
83
93
|
|
|
84
94
|
/** Join the non empty segments with "/". */
|
|
85
95
|
const generatePath = (segments) => {
|
|
@@ -113,12 +123,13 @@ const writeSegments = (history, root, useHash, segments, direction, state, query
|
|
|
113
123
|
*
|
|
114
124
|
* Notes:
|
|
115
125
|
* - parameter segments of the form :param are replaced with their value,
|
|
116
|
-
* - null is returned when a value is missing for any parameter segment
|
|
126
|
+
* - null is returned when a value is missing for any parameter segment,
|
|
127
|
+
* - a trailing wildcard is replaced with the path it matched.
|
|
117
128
|
*/
|
|
118
129
|
const chainToSegments = (chain) => {
|
|
119
130
|
const segments = [];
|
|
120
131
|
for (const route of chain) {
|
|
121
|
-
for (const segment of route.segments) {
|
|
132
|
+
for (const segment of withoutWildcard(route.segments)) {
|
|
122
133
|
if (segment[0] === ':') {
|
|
123
134
|
const param = route.params && route.params[segment.slice(1)];
|
|
124
135
|
if (!param) {
|
|
@@ -130,9 +141,22 @@ const chainToSegments = (chain) => {
|
|
|
130
141
|
segments.push(segment);
|
|
131
142
|
}
|
|
132
143
|
}
|
|
144
|
+
segments.push(...wildcardSegments(route));
|
|
133
145
|
}
|
|
134
146
|
return segments;
|
|
135
147
|
};
|
|
148
|
+
/** Only a `*` in the last segment of a route url is a wildcard. Elsewhere it's matched literally. */
|
|
149
|
+
const endsWithWildcard = (segments) => {
|
|
150
|
+
return segments[segments.length - 1] === '*';
|
|
151
|
+
};
|
|
152
|
+
/** Returns the path segments matched by the trailing wildcard of the route. */
|
|
153
|
+
const wildcardSegments = (route) => {
|
|
154
|
+
const pathMatch = endsWithWildcard(route.segments) ? route.params?.[WILDCARD_PARAM] : undefined;
|
|
155
|
+
return pathMatch ? pathMatch.split('/').filter((s) => s.length > 0) : [];
|
|
156
|
+
};
|
|
157
|
+
const withoutWildcard = (segments) => {
|
|
158
|
+
return endsWithWildcard(segments) ? segments.slice(0, -1) : segments;
|
|
159
|
+
};
|
|
136
160
|
/**
|
|
137
161
|
* Removes the prefix segments from the path segments.
|
|
138
162
|
*
|
|
@@ -465,6 +489,10 @@ const matchesIDs = (ids, chain) => {
|
|
|
465
489
|
if (routeId.id.toLowerCase() !== routeChain.id) {
|
|
466
490
|
break;
|
|
467
491
|
}
|
|
492
|
+
// Weight a wildcard route when the outlet reports its `pathMatch`
|
|
493
|
+
if (routeId.params?.[WILDCARD_PARAM] !== undefined && endsWithWildcard(routeChain.segments)) {
|
|
494
|
+
score++;
|
|
495
|
+
}
|
|
468
496
|
if (routeId.params) {
|
|
469
497
|
const routeIdParams = Object.keys(routeId.params);
|
|
470
498
|
// Only compare routes with the chain that have the same number of parameters.
|
|
@@ -520,21 +548,28 @@ const matchesSegments = (segments, chain) => {
|
|
|
520
548
|
matchesDefault = true;
|
|
521
549
|
}
|
|
522
550
|
else {
|
|
523
|
-
|
|
551
|
+
const params = {};
|
|
552
|
+
for (const segment of withoutWildcard(chainSegments)) {
|
|
524
553
|
const data = inputSegments.next();
|
|
525
554
|
// data param
|
|
526
555
|
if (segment[0] === ':') {
|
|
527
556
|
if (data === '') {
|
|
528
557
|
return null;
|
|
529
558
|
}
|
|
530
|
-
allparams = allparams || [];
|
|
531
|
-
const params = allparams[i] || (allparams[i] = {});
|
|
532
559
|
params[segment.slice(1)] = data;
|
|
533
560
|
}
|
|
534
561
|
else if (data !== segment) {
|
|
535
562
|
return null;
|
|
536
563
|
}
|
|
537
564
|
}
|
|
565
|
+
// A trailing `*` on a parent route has no effect. Its children match the rest of the path.
|
|
566
|
+
if (i === chain.length - 1 && endsWithWildcard(chainSegments)) {
|
|
567
|
+
params[WILDCARD_PARAM] = inputSegments.rest().join('/');
|
|
568
|
+
}
|
|
569
|
+
if (Object.keys(params).length > 0) {
|
|
570
|
+
allparams = allparams || [];
|
|
571
|
+
allparams[i] = params;
|
|
572
|
+
}
|
|
538
573
|
matchesDefault = false;
|
|
539
574
|
}
|
|
540
575
|
}
|
|
@@ -566,25 +601,38 @@ const mergeParams = (a, b) => {
|
|
|
566
601
|
* Returns the best match or null when no match is found.
|
|
567
602
|
* When a chain is returned the parameters are updated from the RouteIDs.
|
|
568
603
|
* That is they contain both the componentProps of the <ion-route> and the parameter segment.
|
|
604
|
+
*
|
|
605
|
+
* When a wildcard route ties with other routes, a route without a wildcard that can build a url wins,
|
|
606
|
+
* then the wildcard route. Otherwise the first route declared wins a tie.
|
|
569
607
|
*/
|
|
570
608
|
const findChainForIDs = (ids, chains) => {
|
|
571
|
-
let match = null;
|
|
572
609
|
let maxMatches = 0;
|
|
610
|
+
let tied = [];
|
|
573
611
|
for (const chain of chains) {
|
|
574
612
|
const score = matchesIDs(ids, chain);
|
|
575
613
|
if (score > maxMatches) {
|
|
576
|
-
match = chain;
|
|
577
614
|
maxMatches = score;
|
|
615
|
+
tied = [chain];
|
|
616
|
+
}
|
|
617
|
+
else if (score > 0 && score === maxMatches) {
|
|
618
|
+
tied.push(chain);
|
|
578
619
|
}
|
|
579
620
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
621
|
+
const matches = tied.map((chain) => chain.map((route, i) => ({
|
|
622
|
+
id: route.id,
|
|
623
|
+
segments: route.segments,
|
|
624
|
+
params: mergeParams(route.params, ids[i]?.params),
|
|
625
|
+
})));
|
|
626
|
+
if (!matches.some(chainEndsWithWildcard)) {
|
|
627
|
+
return matches.length > 0 ? matches[0] : null;
|
|
586
628
|
}
|
|
587
|
-
return
|
|
629
|
+
return matches.reduce((best, chain) => (tieRank(chain) > tieRank(best) ? chain : best));
|
|
630
|
+
};
|
|
631
|
+
const tieRank = (chain) => {
|
|
632
|
+
if (chainEndsWithWildcard(chain)) {
|
|
633
|
+
return 1;
|
|
634
|
+
}
|
|
635
|
+
return chainToSegments(chain) !== null ? 2 : 0;
|
|
588
636
|
};
|
|
589
637
|
/**
|
|
590
638
|
* Finds the best match for the segments in the chains.
|
|
@@ -592,10 +640,17 @@ const findChainForIDs = (ids, chains) => {
|
|
|
592
640
|
* Returns the best match or null when no match is found.
|
|
593
641
|
* When a chain is returned the parameters are updated from the segments.
|
|
594
642
|
* That is they contain both the componentProps of the <ion-route> and the parameter segments.
|
|
643
|
+
*
|
|
644
|
+
* When wildcard routes match, the one with the most fixed segments wins if it has more fixed segments than every
|
|
645
|
+
* route that matched the whole path. Routes that only matched by ignoring trailing segments don't count.
|
|
595
646
|
*/
|
|
596
647
|
const findChainForSegments = (segments, chains) => {
|
|
597
648
|
let match = null;
|
|
598
649
|
let bestScore = 0;
|
|
650
|
+
let fullMatch = null;
|
|
651
|
+
let bestFullScore = 0;
|
|
652
|
+
let maxFullFixed = -1;
|
|
653
|
+
let wildcard = null;
|
|
599
654
|
for (const chain of chains) {
|
|
600
655
|
const matchedChain = matchesSegments(segments, chain);
|
|
601
656
|
if (matchedChain !== null) {
|
|
@@ -604,9 +659,51 @@ const findChainForSegments = (segments, chains) => {
|
|
|
604
659
|
bestScore = score;
|
|
605
660
|
match = matchedChain;
|
|
606
661
|
}
|
|
662
|
+
if (chainEndsWithWildcard(matchedChain)) {
|
|
663
|
+
if (wildcard === null || winsWildcard(matchedChain, wildcard)) {
|
|
664
|
+
wildcard = matchedChain;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
else if (!isPartialMatch(segments, matchedChain)) {
|
|
668
|
+
if (score > bestFullScore) {
|
|
669
|
+
bestFullScore = score;
|
|
670
|
+
fullMatch = matchedChain;
|
|
671
|
+
}
|
|
672
|
+
maxFullFixed = Math.max(maxFullFixed, countFixedSegments(matchedChain));
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
// Without a wildcard to match the rest of the path, routes can still ignore trailing segments.
|
|
677
|
+
if (wildcard === null) {
|
|
678
|
+
return match;
|
|
679
|
+
}
|
|
680
|
+
// Compare fixed segments rather than priority, since nesting under default routes raises the priority
|
|
681
|
+
return countFixedSegments(wildcard) > maxFullFixed ? wildcard : fullMatch;
|
|
682
|
+
};
|
|
683
|
+
/** Returns whether the chain matched the path segments only by ignoring some trailing segments. */
|
|
684
|
+
const isPartialMatch = (segments, chain) => {
|
|
685
|
+
const matched = chainToSegments(chain);
|
|
686
|
+
return matched !== null && matched.length < segments.filter((s) => s !== '').length;
|
|
687
|
+
};
|
|
688
|
+
const chainEndsWithWildcard = (chain) => {
|
|
689
|
+
return endsWithWildcard(chain[chain.length - 1].segments);
|
|
690
|
+
};
|
|
691
|
+
/** Returns whether the wildcard chain beats `best` by fixed segments, then by priority. */
|
|
692
|
+
const winsWildcard = (chain, best) => {
|
|
693
|
+
const chainFixed = countFixedSegments(chain);
|
|
694
|
+
const bestFixed = countFixedSegments(best);
|
|
695
|
+
return chainFixed > bestFixed || (chainFixed === bestFixed && computePriority(chain) > computePriority(best));
|
|
696
|
+
};
|
|
697
|
+
const countFixedSegments = (chain) => {
|
|
698
|
+
let count = 0;
|
|
699
|
+
for (const route of chain) {
|
|
700
|
+
for (const segment of withoutWildcard(route.segments)) {
|
|
701
|
+
if (segment !== '' && segment[0] !== ':') {
|
|
702
|
+
count++;
|
|
703
|
+
}
|
|
607
704
|
}
|
|
608
705
|
}
|
|
609
|
-
return
|
|
706
|
+
return count;
|
|
610
707
|
};
|
|
611
708
|
/**
|
|
612
709
|
* Computes the priority of a chain.
|
|
@@ -618,12 +715,14 @@ const findChainForSegments = (segments, chains) => {
|
|
|
618
715
|
* - /path/to/page
|
|
619
716
|
*
|
|
620
717
|
* The second one will be given a higher priority because "page" is a fixed segment (vs ":where", a parameter segment).
|
|
718
|
+
*
|
|
719
|
+
* A trailing wildcard is not counted.
|
|
621
720
|
*/
|
|
622
721
|
const computePriority = (chain) => {
|
|
623
722
|
let score = 1;
|
|
624
723
|
let level = 1;
|
|
625
724
|
for (const route of chain) {
|
|
626
|
-
for (const segment of route.segments) {
|
|
725
|
+
for (const segment of withoutWildcard(route.segments)) {
|
|
627
726
|
if (segment[0] === ':') {
|
|
628
727
|
score += Math.pow(1, level);
|
|
629
728
|
}
|
|
@@ -645,6 +744,12 @@ class RouterSegments {
|
|
|
645
744
|
}
|
|
646
745
|
return '';
|
|
647
746
|
}
|
|
747
|
+
/** Consumes and returns the remaining non empty segments. */
|
|
748
|
+
rest() {
|
|
749
|
+
const rest = this.segments.filter((s) => s !== '');
|
|
750
|
+
this.segments = [];
|
|
751
|
+
return rest;
|
|
752
|
+
}
|
|
648
753
|
}
|
|
649
754
|
|
|
650
755
|
const readProp = (el, prop) => {
|