voyager-ionic-core 8.0.0 → 8.1.0
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/checkbox.js +3 -3
- package/components/index2.js +119 -1
- package/components/input-shims.js +5 -5
- package/components/ion-accordion-group.js +2 -2
- package/components/ion-content.js +6 -4
- package/components/ion-datetime-button.js +2 -2
- package/components/ion-datetime.js +17 -14
- package/components/ion-fab-button.js +2 -2
- package/components/ion-fab-list.js +2 -2
- package/components/ion-fab.js +2 -2
- package/components/ion-footer.js +2 -2
- package/components/ion-grid.js +2 -2
- package/components/ion-header.js +2 -2
- package/components/ion-img.js +1 -1
- package/components/ion-infinite-scroll-content.js +2 -2
- package/components/ion-infinite-scroll.js +1 -1
- package/components/ion-input-password-toggle.js +3 -3
- package/components/ion-input.js +17 -4
- package/components/ion-item-divider.js +2 -2
- package/components/ion-item-group.js +1 -1
- package/components/ion-item-option.js +2 -2
- package/components/ion-item-options.js +1 -1
- package/components/ion-item-sliding.js +1 -1
- package/components/ion-loading.js +2 -2
- package/components/ion-menu-button.js +2 -2
- package/components/ion-menu-toggle.js +2 -2
- package/components/ion-menu.js +2 -2
- package/components/ion-modal.js +10 -8
- package/components/ion-nav-link.js +1 -1
- package/components/ion-nav.js +1 -1
- package/components/ion-note.js +2 -2
- package/components/ion-picker-legacy.js +2 -2
- package/components/ion-progress-bar.js +1 -1
- package/components/ion-range.js +3 -3
- package/components/ion-refresher-content.js +1 -1
- package/components/ion-refresher.js +1 -1
- package/components/ion-reorder-group.js +1 -1
- package/components/ion-reorder.js +1 -1
- package/components/ion-router-link.js +2 -2
- package/components/ion-router-outlet.js +1 -1
- package/components/ion-row.js +1 -1
- package/components/ion-searchbar.js +4 -4
- package/components/ion-segment-button.js +3 -3
- package/components/ion-segment.js +2 -2
- package/components/ion-select-option.js +1 -1
- package/components/ion-select.js +2 -2
- package/components/ion-skeleton-text.js +2 -2
- package/components/ion-split-pane.js +2 -2
- package/components/ion-tab-bar.js +2 -2
- package/components/ion-tab-button.js +2 -2
- package/components/ion-tab.js +2 -2
- package/components/ion-tabs.js +1 -1
- package/components/ion-text.js +2 -2
- package/components/ion-textarea.js +2 -2
- package/components/ion-thumbnail.js +1 -1
- package/components/ion-title.js +2 -2
- package/components/ion-toast.js +2 -2
- package/components/ion-toggle.js +3 -3
- package/components/ion-toolbar.js +2 -2
- package/components/ios.transition.js +94 -67
- package/components/label.js +3 -3
- package/components/list-header.js +2 -2
- package/components/list.js +1 -1
- package/components/overlays.js +3 -2
- package/components/picker-column-option.js +2 -2
- package/components/picker-column.js +156 -4
- package/components/picker-column2.js +2 -2
- package/components/picker.js +2 -2
- package/components/popover.js +6 -4
- package/components/radio-group.js +1 -1
- package/components/radio.js +3 -3
- package/components/ripple-effect.js +1 -1
- package/components/select-popover.js +2 -2
- package/components/spinner.js +1 -1
- package/css/core.css +1 -1
- package/css/core.css.map +1 -1
- package/css/global.bundle.css.map +1 -1
- package/css/ionic.bundle.css +1 -1
- package/css/ionic.bundle.css.map +1 -1
- package/css/palettes/dark.always.css +1 -1
- package/css/palettes/dark.always.css.map +1 -1
- package/css/palettes/dark.class.css +1 -1
- package/css/palettes/dark.class.css.map +1 -1
- package/css/palettes/dark.system.css +1 -1
- package/css/palettes/dark.system.css.map +1 -1
- package/css/palettes/high-contrast-dark.always.css.map +1 -1
- package/css/palettes/high-contrast-dark.class.css.map +1 -1
- package/css/palettes/high-contrast-dark.system.css.map +1 -1
- package/css/palettes/high-contrast.always.css.map +1 -1
- package/css/palettes/high-contrast.class.css.map +1 -1
- package/css/palettes/high-contrast.system.css.map +1 -1
- package/css/typography.css.map +1 -1
- package/dist/cjs/{app-globals-5bfa2d7f.js → app-globals-66b7dc06.js} +1 -1
- package/dist/cjs/{button-active-564be49f.js → button-active-9135c809.js} +1 -1
- package/dist/cjs/{hardware-back-button-44e7c052.js → hardware-back-button-ed931127.js} +2 -2
- package/dist/cjs/index-8709af32.js +2234 -0
- package/dist/cjs/{index-6d6ac424.js → index-c0b7f8f4.js} +124 -6
- package/dist/cjs/{index-defd575f.js → index-c54654c6.js} +2 -2
- package/dist/cjs/index.cjs.js +9 -9
- package/dist/cjs/{input-shims-20d639e6.js → input-shims-9e59ef62.js} +5 -5
- package/dist/cjs/ion-accordion_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-action-sheet.cjs.entry.js +5 -5
- package/dist/cjs/ion-alert.cjs.entry.js +5 -5
- package/dist/cjs/ion-app_8.cjs.entry.js +21 -20
- package/dist/cjs/ion-avatar_3.cjs.entry.js +3 -3
- package/dist/cjs/ion-back-button.cjs.entry.js +2 -2
- package/dist/cjs/ion-backdrop.cjs.entry.js +2 -2
- package/dist/cjs/ion-breadcrumb_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-button_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-card_5.cjs.entry.js +2 -2
- package/dist/cjs/ion-checkbox.cjs.entry.js +5 -5
- package/dist/cjs/ion-chip.cjs.entry.js +2 -2
- package/dist/cjs/ion-col_3.cjs.entry.js +5 -5
- package/dist/cjs/ion-datetime-button.cjs.entry.js +4 -4
- package/dist/cjs/ion-datetime_3.cjs.entry.js +25 -22
- package/dist/cjs/ion-fab_3.cjs.entry.js +8 -8
- package/dist/cjs/ion-img.cjs.entry.js +3 -3
- package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +5 -5
- package/dist/cjs/ion-input-password-toggle.cjs.entry.js +5 -5
- package/dist/cjs/ion-input.cjs.entry.js +18 -6
- package/dist/cjs/ion-item-option_3.cjs.entry.js +6 -6
- package/dist/cjs/ion-item_8.cjs.entry.js +15 -15
- package/dist/cjs/ion-loading.cjs.entry.js +6 -6
- package/dist/cjs/ion-menu_3.cjs.entry.js +11 -11
- package/dist/cjs/ion-modal.cjs.entry.js +13 -12
- package/dist/cjs/ion-nav_2.cjs.entry.js +6 -5
- package/dist/cjs/ion-picker-column-option.cjs.entry.js +4 -4
- package/dist/cjs/ion-picker-column.cjs.entry.js +156 -6
- package/dist/cjs/ion-picker.cjs.entry.js +3 -3
- package/dist/cjs/ion-popover.cjs.entry.js +9 -8
- package/dist/cjs/ion-progress-bar.cjs.entry.js +3 -3
- package/dist/cjs/ion-radio_2.cjs.entry.js +6 -6
- package/dist/cjs/ion-range.cjs.entry.js +5 -5
- package/dist/cjs/ion-refresher_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-reorder_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-ripple-effect.cjs.entry.js +3 -3
- package/dist/cjs/ion-route_4.cjs.entry.js +4 -4
- package/dist/cjs/ion-searchbar.cjs.entry.js +6 -6
- package/dist/cjs/ion-segment_2.cjs.entry.js +7 -7
- package/dist/cjs/ion-select_3.cjs.entry.js +9 -9
- package/dist/cjs/ion-spinner.cjs.entry.js +3 -3
- package/dist/cjs/ion-split-pane.cjs.entry.js +4 -4
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +6 -6
- package/dist/cjs/ion-tab_2.cjs.entry.js +4 -4
- package/dist/cjs/ion-text.cjs.entry.js +4 -4
- package/dist/cjs/ion-textarea.cjs.entry.js +4 -4
- package/dist/cjs/ion-toast.cjs.entry.js +6 -6
- package/dist/cjs/ion-toggle.cjs.entry.js +5 -5
- package/dist/cjs/{ionic-global-62487d02.js → ionic-global-35b86a09.js} +1 -1
- package/dist/cjs/ionic.cjs.js +31 -33
- package/dist/cjs/{ios.transition-d4f0ca4e.js → ios.transition-5ddf92f1.js} +98 -69
- package/dist/cjs/loader.cjs.js +4 -4
- package/dist/cjs/{md.transition-857328f3.js → md.transition-047c18c5.js} +4 -2
- package/dist/cjs/{overlays-10c452b2.js → overlays-cb04d075.js} +5 -3
- package/dist/cjs/{status-tap-81daddfa.js → status-tap-5b2775cd.js} +1 -1
- package/dist/collection/collection-manifest.json +2 -2
- package/dist/collection/components/accordion-group/accordion-group.js +3 -3
- package/dist/collection/components/checkbox/checkbox.js +4 -4
- package/dist/collection/components/content/content.js +23 -4
- package/dist/collection/components/content/test/content.spec.js +27 -0
- package/dist/collection/components/datetime/datetime.js +18 -15
- package/dist/collection/components/datetime/test/color/datetime.e2e.js +14 -7
- package/dist/collection/components/datetime/test/overlay-roles/datetime.e2e.js +34 -0
- package/dist/collection/components/datetime-button/datetime-button.js +2 -2
- package/dist/collection/components/fab/fab.js +2 -2
- package/dist/collection/components/fab-button/fab-button.js +2 -2
- package/dist/collection/components/fab-list/fab-list.js +2 -2
- package/dist/collection/components/footer/footer.js +2 -2
- package/dist/collection/components/grid/grid.js +2 -2
- package/dist/collection/components/header/header.js +2 -2
- package/dist/collection/components/img/img.js +1 -1
- package/dist/collection/components/infinite-scroll/infinite-scroll.js +1 -1
- package/dist/collection/components/infinite-scroll-content/infinite-scroll-content.js +2 -2
- package/dist/collection/components/input/input.js +34 -5
- package/dist/collection/components/input/test/input.spec.js +13 -0
- package/dist/collection/components/input-password-toggle/input-password-toggle.js +3 -3
- package/dist/collection/components/item/test/a11y/item.e2e.js +24 -4
- package/dist/collection/components/item-divider/item-divider.js +2 -2
- package/dist/collection/components/item-group/item-group.js +1 -1
- package/dist/collection/components/item-option/item-option.js +2 -2
- package/dist/collection/components/item-options/item-options.js +1 -1
- package/dist/collection/components/item-sliding/item-sliding.js +1 -1
- package/dist/collection/components/label/label.ios.css +1 -1
- package/dist/collection/components/label/label.js +2 -2
- package/dist/collection/components/list/list.js +1 -1
- package/dist/collection/components/list-header/list-header.js +2 -2
- package/dist/collection/components/loading/loading.js +2 -2
- package/dist/collection/components/menu/menu.js +2 -2
- package/dist/collection/components/menu-button/menu-button.js +2 -2
- package/dist/collection/components/menu-toggle/menu-toggle.js +2 -2
- package/dist/collection/components/modal/gestures/sheet.js +3 -2
- package/dist/collection/components/modal/modal.js +25 -6
- package/dist/collection/components/modal/test/basic/modal.spec.js +19 -0
- package/dist/collection/components/nav/nav.js +1 -1
- package/dist/collection/components/nav-link/nav-link.js +1 -1
- package/dist/collection/components/note/note.js +2 -2
- package/dist/collection/components/picker/picker.js +2 -2
- package/dist/collection/components/picker-column/picker-column.css +19 -0
- package/dist/collection/components/picker-column/picker-column.js +159 -4
- package/dist/collection/components/picker-column/test/picker-column.spec.js +83 -0
- package/dist/collection/components/picker-column-option/picker-column-option.js +2 -2
- package/dist/collection/components/picker-legacy/picker.js +2 -2
- package/dist/collection/components/picker-legacy-column/picker-column.js +2 -2
- package/dist/collection/components/popover/popover.js +23 -4
- package/dist/collection/components/popover/test/basic/popover.spec.js +19 -0
- package/dist/collection/components/progress-bar/progress-bar.js +1 -1
- package/dist/collection/components/radio/radio.js +3 -3
- package/dist/collection/components/radio-group/radio-group.js +2 -2
- package/dist/collection/components/range/range.js +4 -4
- package/dist/collection/components/refresher/refresher.js +1 -1
- package/dist/collection/components/refresher-content/refresher-content.js +1 -1
- package/dist/collection/components/reorder/reorder.js +1 -1
- package/dist/collection/components/reorder-group/reorder-group.js +1 -1
- package/dist/collection/components/ripple-effect/ripple-effect.js +1 -1
- package/dist/collection/components/router-link/router-link.js +2 -2
- package/dist/collection/components/router-outlet/router-outlet.js +1 -1
- package/dist/collection/components/row/row.js +1 -1
- package/dist/collection/components/searchbar/searchbar.js +5 -5
- package/dist/collection/components/segment/segment.js +3 -3
- package/dist/collection/components/segment-button/segment-button.js +3 -3
- package/dist/collection/components/select/select.js +3 -3
- package/dist/collection/components/select/test/fill/select.e2e.js +25 -0
- package/dist/collection/components/select-option/select-option.js +1 -1
- package/dist/collection/components/select-popover/select-popover.js +1 -1
- package/dist/collection/components/select-popover/select-popover.md.css +8 -1
- package/dist/collection/components/skeleton-text/skeleton-text.js +2 -2
- package/dist/collection/components/spinner/spinner.js +1 -1
- package/dist/collection/components/split-pane/split-pane.js +2 -2
- package/dist/collection/components/tab/tab.js +2 -2
- package/dist/collection/components/tab-bar/tab-bar.js +2 -2
- package/dist/collection/components/tab-button/tab-button.js +2 -2
- package/dist/collection/components/tabs/tabs.js +1 -1
- package/dist/collection/components/text/text.js +2 -2
- package/dist/collection/components/textarea/textarea.js +3 -3
- package/dist/collection/components/thumbnail/thumbnail.js +1 -1
- package/dist/collection/components/title/title.js +2 -2
- package/dist/collection/components/toast/toast.js +2 -2
- package/dist/collection/components/toggle/test/enable-on-off-labels/toggle.e2e.js +51 -31
- package/dist/collection/components/toggle/toggle.js +4 -4
- package/dist/collection/components/toolbar/toolbar.js +2 -2
- package/dist/collection/utils/focus-controller/index.js +112 -0
- package/dist/collection/utils/focus-controller/test/generic/focus-controller.e2e.js +52 -0
- package/dist/collection/utils/focus-controller/test/ionic/focus-controller.e2e.js +52 -0
- package/dist/collection/utils/input-shims/hacks/scroll-assist.js +5 -5
- package/dist/collection/utils/overlays.js +2 -1
- package/dist/collection/utils/test/playwright/page/utils/goto.js +12 -3
- package/dist/collection/utils/transition/index.js +11 -1
- package/dist/collection/utils/transition/ios.transition.js +94 -67
- package/dist/docs.json +110 -15
- package/dist/esm/{app-globals-49873df1.js → app-globals-b99e6d29.js} +1 -1
- package/dist/esm/{button-active-46df59c1.js → button-active-920addb8.js} +1 -1
- package/dist/esm/{hardware-back-button-ba8f64c2.js → hardware-back-button-2d9760b6.js} +2 -2
- package/dist/esm/{index-56d90da9.js → index-7ae7186a.js} +2 -2
- package/dist/esm/{index-f0d7371a.js → index-8e6b6a24.js} +122 -4
- package/dist/esm/index-9aab3bcf.js +2196 -0
- package/dist/esm/index.js +9 -9
- package/dist/esm/{input-shims-4530285e.js → input-shims-0314bbe5.js} +5 -5
- package/dist/esm/ion-accordion_2.entry.js +4 -4
- package/dist/esm/ion-action-sheet.entry.js +5 -5
- package/dist/esm/ion-alert.entry.js +5 -5
- package/dist/esm/ion-app_8.entry.js +21 -20
- package/dist/esm/ion-avatar_3.entry.js +3 -3
- package/dist/esm/ion-back-button.entry.js +2 -2
- package/dist/esm/ion-backdrop.entry.js +2 -2
- package/dist/esm/ion-breadcrumb_2.entry.js +2 -2
- package/dist/esm/ion-button_2.entry.js +2 -2
- package/dist/esm/ion-card_5.entry.js +2 -2
- package/dist/esm/ion-checkbox.entry.js +5 -5
- package/dist/esm/ion-chip.entry.js +2 -2
- package/dist/esm/ion-col_3.entry.js +5 -5
- package/dist/esm/ion-datetime-button.entry.js +4 -4
- package/dist/esm/ion-datetime_3.entry.js +25 -22
- package/dist/esm/ion-fab_3.entry.js +8 -8
- package/dist/esm/ion-img.entry.js +3 -3
- package/dist/esm/ion-infinite-scroll_2.entry.js +5 -5
- package/dist/esm/ion-input-password-toggle.entry.js +5 -5
- package/dist/esm/ion-input.entry.js +18 -6
- package/dist/esm/ion-item-option_3.entry.js +6 -6
- package/dist/esm/ion-item_8.entry.js +15 -15
- package/dist/esm/ion-loading.entry.js +6 -6
- package/dist/esm/ion-menu_3.entry.js +11 -11
- package/dist/esm/ion-modal.entry.js +13 -12
- package/dist/esm/ion-nav_2.entry.js +6 -5
- package/dist/esm/ion-picker-column-option.entry.js +4 -4
- package/dist/esm/ion-picker-column.entry.js +156 -6
- package/dist/esm/ion-picker.entry.js +3 -3
- package/dist/esm/ion-popover.entry.js +9 -8
- package/dist/esm/ion-progress-bar.entry.js +3 -3
- package/dist/esm/ion-radio_2.entry.js +6 -6
- package/dist/esm/ion-range.entry.js +5 -5
- package/dist/esm/ion-refresher_2.entry.js +4 -4
- package/dist/esm/ion-reorder_2.entry.js +4 -4
- package/dist/esm/ion-ripple-effect.entry.js +3 -3
- package/dist/esm/ion-route_4.entry.js +4 -4
- package/dist/esm/ion-searchbar.entry.js +6 -6
- package/dist/esm/ion-segment_2.entry.js +7 -7
- package/dist/esm/ion-select_3.entry.js +9 -9
- package/dist/esm/ion-spinner.entry.js +3 -3
- package/dist/esm/ion-split-pane.entry.js +4 -4
- package/dist/esm/ion-tab-bar_2.entry.js +6 -6
- package/dist/esm/ion-tab_2.entry.js +4 -4
- package/dist/esm/ion-text.entry.js +4 -4
- package/dist/esm/ion-textarea.entry.js +4 -4
- package/dist/esm/ion-toast.entry.js +6 -6
- package/dist/esm/ion-toggle.entry.js +5 -5
- package/dist/esm/{ionic-global-e6c98cd0.js → ionic-global-4528d288.js} +1 -1
- package/dist/esm/ionic.js +32 -34
- package/dist/esm/{ios.transition-71bfa932.js → ios.transition-e35d0940.js} +98 -69
- package/dist/esm/loader.js +5 -5
- package/dist/esm/{md.transition-86aef3c0.js → md.transition-4b90a1f0.js} +4 -2
- package/dist/esm/{overlays-6fb4a2f2.js → overlays-df2c06b2.js} +5 -4
- package/dist/esm/{status-tap-299361cd.js → status-tap-12c27922.js} +1 -1
- package/dist/esm-es5/app-globals-b99e6d29.js +4 -0
- package/dist/esm-es5/{button-active-46df59c1.js → button-active-920addb8.js} +1 -1
- package/dist/esm-es5/{hardware-back-button-ba8f64c2.js → hardware-back-button-2d9760b6.js} +1 -1
- package/dist/esm-es5/{index-56d90da9.js → index-7ae7186a.js} +1 -1
- package/dist/esm-es5/index-8e6b6a24.js +4 -0
- package/dist/esm-es5/index-9aab3bcf.js +5 -0
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/input-shims-0314bbe5.js +4 -0
- package/dist/esm-es5/ion-accordion_2.entry.js +1 -1
- package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
- package/dist/esm-es5/ion-alert.entry.js +1 -1
- package/dist/esm-es5/ion-app_8.entry.js +1 -1
- package/dist/esm-es5/ion-avatar_3.entry.js +1 -1
- package/dist/esm-es5/ion-back-button.entry.js +1 -1
- package/dist/esm-es5/ion-backdrop.entry.js +1 -1
- package/dist/esm-es5/ion-breadcrumb_2.entry.js +1 -1
- package/dist/esm-es5/ion-button_2.entry.js +1 -1
- package/dist/esm-es5/ion-card_5.entry.js +1 -1
- package/dist/esm-es5/ion-checkbox.entry.js +1 -1
- package/dist/esm-es5/ion-chip.entry.js +1 -1
- package/dist/esm-es5/ion-col_3.entry.js +1 -1
- package/dist/esm-es5/ion-datetime-button.entry.js +1 -1
- package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
- package/dist/esm-es5/ion-fab_3.entry.js +1 -1
- package/dist/esm-es5/ion-img.entry.js +1 -1
- package/dist/esm-es5/ion-infinite-scroll_2.entry.js +1 -1
- package/dist/esm-es5/ion-input-password-toggle.entry.js +1 -1
- package/dist/esm-es5/ion-input.entry.js +1 -1
- package/dist/esm-es5/ion-item-option_3.entry.js +1 -1
- package/dist/esm-es5/ion-item_8.entry.js +1 -1
- package/dist/esm-es5/ion-loading.entry.js +1 -1
- package/dist/esm-es5/ion-menu_3.entry.js +1 -1
- package/dist/esm-es5/ion-modal.entry.js +1 -1
- package/dist/esm-es5/ion-nav_2.entry.js +1 -1
- package/dist/esm-es5/ion-picker-column-option.entry.js +1 -1
- package/dist/esm-es5/ion-picker-column.entry.js +1 -1
- package/dist/esm-es5/ion-picker.entry.js +1 -1
- package/dist/esm-es5/ion-popover.entry.js +1 -1
- package/dist/esm-es5/ion-progress-bar.entry.js +1 -1
- package/dist/esm-es5/ion-radio_2.entry.js +1 -1
- package/dist/esm-es5/ion-range.entry.js +1 -1
- package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
- package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
- package/dist/esm-es5/ion-ripple-effect.entry.js +1 -1
- package/dist/esm-es5/ion-route_4.entry.js +1 -1
- package/dist/esm-es5/ion-searchbar.entry.js +1 -1
- package/dist/esm-es5/ion-segment_2.entry.js +1 -1
- package/dist/esm-es5/ion-select_3.entry.js +1 -1
- package/dist/esm-es5/ion-spinner.entry.js +1 -1
- package/dist/esm-es5/ion-split-pane.entry.js +1 -1
- package/dist/esm-es5/ion-tab-bar_2.entry.js +1 -1
- package/dist/esm-es5/ion-tab_2.entry.js +1 -1
- package/dist/esm-es5/ion-text.entry.js +1 -1
- package/dist/esm-es5/ion-textarea.entry.js +1 -1
- package/dist/esm-es5/ion-toast.entry.js +1 -1
- package/dist/esm-es5/ion-toggle.entry.js +1 -1
- package/dist/esm-es5/{ionic-global-e6c98cd0.js → ionic-global-4528d288.js} +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/ios.transition-e35d0940.js +4 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/md.transition-4b90a1f0.js +4 -0
- package/dist/esm-es5/{overlays-6fb4a2f2.js → overlays-df2c06b2.js} +1 -1
- package/dist/esm-es5/{status-tap-299361cd.js → status-tap-12c27922.js} +1 -1
- package/dist/html.html-data.json +24 -0
- package/dist/ionic/index.esm.js +1 -1
- package/dist/ionic/ionic.esm.js +1 -1
- package/dist/ionic/ionic.js +1 -1
- package/dist/ionic/{p-4f77a080.system.entry.js → p-01a27023.system.entry.js} +1 -1
- package/dist/ionic/p-0395be73.entry.js +4 -0
- package/dist/ionic/p-03b86a5e.js +4 -0
- package/dist/ionic/{p-5ad55625.entry.js → p-049d43bd.entry.js} +1 -1
- package/dist/ionic/p-0536574e.entry.js +4 -0
- package/dist/ionic/{p-005deca1.system.entry.js → p-08ea3402.system.entry.js} +1 -1
- package/dist/ionic/{p-f956e38a.entry.js → p-09538818.entry.js} +1 -1
- package/dist/ionic/{p-4a01cec0.entry.js → p-09b4e9ec.entry.js} +1 -1
- package/dist/ionic/{p-4809ddae.system.entry.js → p-0a6d801e.system.entry.js} +1 -1
- package/dist/ionic/{p-c54b167f.system.entry.js → p-0b007acc.system.entry.js} +1 -1
- package/dist/ionic/{p-e292247e.system.entry.js → p-10feef7e.system.entry.js} +1 -1
- package/dist/ionic/p-130299c9.entry.js +4 -0
- package/dist/ionic/p-15d1ddba.js +4 -0
- package/dist/ionic/{p-f8f8c5a8.system.entry.js → p-199f826f.system.entry.js} +1 -1
- package/dist/ionic/p-1b435d20.entry.js +4 -0
- package/dist/ionic/{p-96a561dd.js → p-1cc0b31f.js} +1 -1
- package/dist/ionic/p-1eb63fa4.entry.js +4 -0
- package/dist/ionic/{p-1ba197b6.entry.js → p-207e11dc.entry.js} +1 -1
- package/dist/ionic/{p-46111310.js → p-2690b1de.js} +1 -1
- package/dist/ionic/p-26bb6bb8.entry.js +4 -0
- package/dist/ionic/{p-f13dc6bd.system.entry.js → p-279f3bac.system.entry.js} +1 -1
- package/dist/ionic/p-29de09dd.entry.js +4 -0
- package/dist/ionic/{p-6e4dac1a.entry.js → p-2c588aa2.entry.js} +1 -1
- package/dist/ionic/p-2ff0e0aa.system.js +4 -0
- package/dist/ionic/p-30baae57.system.js +4 -0
- package/dist/ionic/{p-7a7ff5e3.system.js → p-31d27232.system.js} +1 -1
- package/dist/ionic/p-33e10509.system.js +4 -0
- package/dist/ionic/{p-7f33a6e2.system.entry.js → p-380efbfa.system.entry.js} +2 -2
- package/dist/ionic/p-3c27be4a.entry.js +4 -0
- package/dist/ionic/p-3d015cdb.system.js +5 -0
- package/dist/ionic/{p-1c42ad90.entry.js → p-3f53a0b1.entry.js} +1 -1
- package/dist/ionic/p-433157a4.entry.js +4 -0
- package/dist/ionic/{p-53d37363.entry.js → p-4824398b.entry.js} +1 -1
- package/dist/ionic/p-498eb648.system.entry.js +4 -0
- package/dist/ionic/{p-7c93f00b.system.entry.js → p-4d8f408d.system.entry.js} +1 -1
- package/dist/ionic/{p-ad2b9596.entry.js → p-5091f63c.entry.js} +1 -1
- package/dist/ionic/{p-6ef17d86.system.entry.js → p-509620b8.system.entry.js} +1 -1
- package/dist/ionic/{p-48f60474.entry.js → p-5109a566.entry.js} +1 -1
- package/dist/ionic/{p-4f6ebc2b.entry.js → p-52ce473d.entry.js} +1 -1
- package/dist/ionic/{p-4fadf4b0.entry.js → p-52f53904.entry.js} +1 -1
- package/dist/ionic/{p-aa8a2f40.system.entry.js → p-55f99a39.system.entry.js} +1 -1
- package/dist/ionic/{p-6ac30fc3.system.js → p-5734ac17.system.js} +1 -1
- package/dist/ionic/{p-55bc2a11.system.entry.js → p-57bc32e2.system.entry.js} +1 -1
- package/dist/ionic/{p-8f9e2850.js → p-5cc6dcf5.js} +1 -1
- package/dist/ionic/p-5dc9f99a.entry.js +4 -0
- package/dist/ionic/p-5ec3bb70.system.entry.js +4 -0
- package/dist/ionic/{p-b6519a42.entry.js → p-606f069c.entry.js} +1 -1
- package/dist/ionic/{p-3de2aab8.system.entry.js → p-628967e3.system.entry.js} +1 -1
- package/dist/ionic/{p-c927dbe2.system.entry.js → p-62e44e4a.system.entry.js} +1 -1
- package/dist/ionic/p-66ed603b.js +4 -0
- package/dist/ionic/{p-e548fedf.system.entry.js → p-670c9f57.system.entry.js} +1 -1
- package/dist/ionic/{p-d061515d.system.entry.js → p-6a2cf398.system.entry.js} +1 -1
- package/dist/ionic/{p-7492572a.entry.js → p-6c3666d5.entry.js} +1 -1
- package/dist/ionic/{p-53d69c70.system.entry.js → p-6df12af0.system.entry.js} +1 -1
- package/dist/ionic/p-6ec88301.entry.js +4 -0
- package/dist/ionic/p-6f008ad2.js +4 -0
- package/dist/ionic/{p-814efd87.system.entry.js → p-700567ab.system.entry.js} +1 -1
- package/dist/ionic/p-712d54ae.js +4 -0
- package/dist/ionic/{p-e8a713b5.entry.js → p-7349de07.entry.js} +1 -1
- package/dist/ionic/p-7402fcdf.entry.js +4 -0
- package/dist/ionic/{p-e6d46b5d.system.entry.js → p-77731f19.system.entry.js} +1 -1
- package/dist/ionic/{p-90f8498c.entry.js → p-78405458.entry.js} +1 -1
- package/dist/ionic/{p-b4a7f856.system.entry.js → p-7d6fd45f.system.entry.js} +1 -1
- package/dist/ionic/{p-332aa81e.entry.js → p-7eb47906.entry.js} +1 -1
- package/dist/ionic/{p-8a5152e5.entry.js → p-80265a58.entry.js} +1 -1
- package/dist/ionic/{p-68afa357.system.entry.js → p-83d748f8.system.entry.js} +2 -2
- package/dist/ionic/{p-6c5c1bb5.system.js → p-842c9fca.system.js} +1 -1
- package/dist/ionic/{p-e781c893.entry.js → p-8a03fbee.entry.js} +1 -1
- package/dist/ionic/{p-cf8101a6.system.entry.js → p-8cb80f83.system.entry.js} +1 -1
- package/dist/ionic/{p-9fd3ca09.system.entry.js → p-8d14ee8c.system.entry.js} +2 -2
- package/dist/ionic/p-90dfc454.system.entry.js +4 -0
- package/dist/ionic/{p-c4eafa12.system.entry.js → p-9213681c.system.entry.js} +1 -1
- package/dist/ionic/p-92d7e99d.system.js +4 -0
- package/dist/ionic/{p-2b86020c.system.entry.js → p-9664a1a2.system.entry.js} +1 -1
- package/dist/ionic/{p-dbc3e90c.entry.js → p-9797f6eb.entry.js} +1 -1
- package/dist/ionic/{p-987e38ef.system.entry.js → p-9848d7be.system.entry.js} +1 -1
- package/dist/ionic/{p-fea11771.entry.js → p-98f6116f.entry.js} +1 -1
- package/dist/ionic/{p-cbd87df6.entry.js → p-99884813.entry.js} +1 -1
- package/dist/ionic/{p-904df2ee.system.entry.js → p-99ca9787.system.entry.js} +1 -1
- package/dist/ionic/{p-ca5bb110.system.entry.js → p-9bfd7cda.system.entry.js} +1 -1
- package/dist/ionic/p-9c6dcf78.system.entry.js +4 -0
- package/dist/ionic/p-9da86308.js +4 -0
- package/dist/ionic/{p-83b445c3.js → p-9ec42be0.js} +1 -1
- package/dist/ionic/{p-5c26fed5.system.entry.js → p-a2e94ade.system.entry.js} +1 -1
- package/dist/ionic/{p-7bbcce53.system.js → p-a39d3482.system.js} +1 -1
- package/dist/ionic/p-a488b7ab.system.js +4 -0
- package/dist/ionic/{p-e1ad8e76.entry.js → p-a4ab7449.entry.js} +1 -1
- package/dist/ionic/{p-3d977e09.system.entry.js → p-a50f23bf.system.entry.js} +2 -2
- package/dist/ionic/{p-275dd0ba.system.entry.js → p-a76ab3ea.system.entry.js} +1 -1
- package/dist/ionic/{p-67f5b57a.js → p-a953ef66.js} +1 -1
- package/dist/ionic/p-aaaaaea1.entry.js +4 -0
- package/dist/ionic/{p-151e8afd.entry.js → p-b02eda30.entry.js} +1 -1
- package/dist/ionic/{p-341b3f37.entry.js → p-b04c27d8.entry.js} +1 -1
- package/dist/ionic/{p-6cf780b6.system.entry.js → p-b07affd5.system.entry.js} +1 -1
- package/dist/ionic/{p-aa79cc0e.system.entry.js → p-b28d3ccb.system.entry.js} +2 -2
- package/dist/ionic/{p-e099a6f3.entry.js → p-b563b6ac.entry.js} +1 -1
- package/dist/ionic/p-b62ae60a.system.entry.js +4 -0
- package/dist/ionic/p-b9181033.system.entry.js +4 -0
- package/dist/ionic/{p-e93cd31c.entry.js → p-ba70039f.entry.js} +1 -1
- package/dist/ionic/{p-1fe1f512.entry.js → p-bbbe869e.entry.js} +1 -1
- package/dist/ionic/{p-aea5f293.system.entry.js → p-c41435e6.system.entry.js} +1 -1
- package/dist/ionic/p-cec8589b.system.js +4 -0
- package/dist/ionic/{p-3008ca4e.system.entry.js → p-d69b26d9.system.entry.js} +1 -1
- package/dist/ionic/p-d73a16e6.system.entry.js +4 -0
- package/dist/ionic/p-dba5cb84.js +5 -0
- package/dist/ionic/{p-df0d39c7.system.entry.js → p-dc0d9ff5.system.entry.js} +2 -2
- package/dist/ionic/p-dc1e363a.entry.js +4 -0
- package/dist/ionic/{p-405fd996.entry.js → p-df517d1f.entry.js} +1 -1
- package/dist/ionic/p-dfb78785.system.js +4 -0
- package/dist/ionic/{p-98af538a.system.entry.js → p-e0a8ffd0.system.entry.js} +1 -1
- package/dist/ionic/{p-50205ef9.system.entry.js → p-e6e197f5.system.entry.js} +1 -1
- package/dist/ionic/{p-530207f9.entry.js → p-e6e88ab9.entry.js} +1 -1
- package/dist/ionic/{p-ffbc80ae.system.js → p-e81f22e3.system.js} +1 -1
- package/dist/ionic/{p-07584ab4.system.js → p-eb3023c9.system.js} +1 -1
- package/dist/ionic/p-ecbdbf25.system.entry.js +4 -0
- package/dist/ionic/{p-91b568e2.system.entry.js → p-ed5aebaa.system.entry.js} +1 -1
- package/dist/ionic/p-f357707e.entry.js +4 -0
- package/dist/ionic/{p-ca6decbd.entry.js → p-f53bcebd.entry.js} +1 -1
- package/dist/ionic/p-f9baf25c.entry.js +4 -0
- package/dist/ionic/{p-1472c130.entry.js → p-fa8f2e62.entry.js} +1 -1
- package/dist/ionic/{p-e81c3ca2.system.entry.js → p-fb21fd1c.system.entry.js} +1 -1
- package/dist/ionic/{p-bc3d649d.entry.js → p-fcecca8f.entry.js} +1 -1
- package/dist/types/components/accordion-group/accordion-group.d.ts +3 -4
- package/dist/types/components/checkbox/checkbox.d.ts +3 -4
- package/dist/types/components/content/content.d.ts +8 -0
- package/dist/types/components/datetime/datetime.d.ts +2 -0
- package/dist/types/components/input/input.d.ts +6 -0
- package/dist/types/components/modal/modal-interface.d.ts +1 -0
- package/dist/types/components/modal/modal.d.ts +18 -0
- package/dist/types/components/picker-column/picker-column.d.ts +37 -0
- package/dist/types/components/popover/popover-interface.d.ts +1 -0
- package/dist/types/components/popover/popover.d.ts +18 -0
- package/dist/types/components/radio-group/radio-group.d.ts +2 -0
- package/dist/types/components/range/range.d.ts +1 -1
- package/dist/types/components/searchbar/searchbar.d.ts +2 -0
- package/dist/types/components/segment/segment.d.ts +3 -2
- package/dist/types/components/select/select.d.ts +2 -0
- package/dist/types/components/textarea/textarea.d.ts +2 -0
- package/dist/types/components/toggle/toggle.d.ts +3 -2
- package/dist/types/components.d.ts +44 -12
- package/dist/types/utils/config.d.ts +9 -0
- package/dist/types/utils/focus-controller/index.d.ts +13 -0
- package/dist/types/utils/overlays.d.ts +1 -0
- package/hydrate/index.d.ts +1 -1
- package/hydrate/index.js +44900 -35418
- package/package.json +6 -6
- package/dist/cjs/index-bbc6c29f.js +0 -3324
- package/dist/esm/index-bcd8859b.js +0 -3286
- package/dist/esm-es5/app-globals-49873df1.js +0 -4
- package/dist/esm-es5/index-bcd8859b.js +0 -5
- package/dist/esm-es5/index-f0d7371a.js +0 -4
- package/dist/esm-es5/input-shims-4530285e.js +0 -4
- package/dist/esm-es5/ios.transition-71bfa932.js +0 -4
- package/dist/esm-es5/md.transition-86aef3c0.js +0 -4
- package/dist/ionic/p-0bd47555.js +0 -4
- package/dist/ionic/p-0e713efe.js +0 -4
- package/dist/ionic/p-13cc6ee6.entry.js +0 -4
- package/dist/ionic/p-1b0f4e6c.entry.js +0 -4
- package/dist/ionic/p-1fa53d02.entry.js +0 -4
- package/dist/ionic/p-23fdee0e.entry.js +0 -4
- package/dist/ionic/p-2613c305.system.js +0 -4
- package/dist/ionic/p-46f407f0.system.js +0 -4
- package/dist/ionic/p-495ed1c3.entry.js +0 -4
- package/dist/ionic/p-4de53118.js +0 -4
- package/dist/ionic/p-4edce583.system.entry.js +0 -4
- package/dist/ionic/p-510cb8e6.system.js +0 -4
- package/dist/ionic/p-582db405.system.entry.js +0 -4
- package/dist/ionic/p-5f28cb75.js +0 -4
- package/dist/ionic/p-6dc81903.entry.js +0 -4
- package/dist/ionic/p-7372cf23.system.entry.js +0 -4
- package/dist/ionic/p-7596e24d.system.js +0 -5
- package/dist/ionic/p-76971b4f.entry.js +0 -4
- package/dist/ionic/p-91dabef7.system.js +0 -4
- package/dist/ionic/p-9ccc8035.system.entry.js +0 -4
- package/dist/ionic/p-9fa5ff32.system.js +0 -4
- package/dist/ionic/p-a28ea4d8.system.entry.js +0 -4
- package/dist/ionic/p-a39a73e3.entry.js +0 -4
- package/dist/ionic/p-a90201f2.js +0 -4
- package/dist/ionic/p-ac045dad.entry.js +0 -4
- package/dist/ionic/p-ae42c907.entry.js +0 -4
- package/dist/ionic/p-ba35f07f.entry.js +0 -4
- package/dist/ionic/p-c1c77386.js +0 -5
- package/dist/ionic/p-c2762c6a.system.entry.js +0 -4
- package/dist/ionic/p-c4e495a3.system.js +0 -4
- package/dist/ionic/p-cf45a5c7.system.entry.js +0 -4
- package/dist/ionic/p-d73f49d0.entry.js +0 -4
- package/dist/ionic/p-dc4406d7.system.entry.js +0 -4
- package/dist/ionic/p-dec86943.entry.js +0 -4
- package/dist/ionic/p-e5a3659f.system.js +0 -4
- package/dist/ionic/p-ec178f19.entry.js +0 -4
- package/dist/ionic/p-eda2459e.entry.js +0 -4
- package/dist/ionic/p-f6ca4d02.js +0 -4
- package/dist/ionic/p-f6fec6a0.entry.js +0 -4
|
@@ -8,7 +8,7 @@ import { raf, inheritAttributes, hasLazyBuild } from "../../utils/helpers";
|
|
|
8
8
|
import { createLockController } from "../../utils/lock-controller";
|
|
9
9
|
import { printIonWarning } from "../../utils/logging/index";
|
|
10
10
|
import { Style as StatusBarStyle, StatusBar } from "../../utils/native/status-bar";
|
|
11
|
-
import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, } from "../../utils/overlays";
|
|
11
|
+
import { GESTURE, BACKDROP, dismiss, eventMethod, prepareOverlay, present, createTriggerController, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
|
|
12
12
|
import { getClassMap } from "../../utils/theme";
|
|
13
13
|
import { deepReady, waitForMount } from "../../utils/transition/index";
|
|
14
14
|
import { config } from "../../global/config";
|
|
@@ -101,6 +101,7 @@ export class Modal {
|
|
|
101
101
|
this.isOpen = false;
|
|
102
102
|
this.trigger = undefined;
|
|
103
103
|
this.keepContentsMounted = false;
|
|
104
|
+
this.focusTrap = true;
|
|
104
105
|
this.canDismiss = true;
|
|
105
106
|
}
|
|
106
107
|
onIsOpenChange(newValue, oldValue) {
|
|
@@ -557,23 +558,23 @@ export class Modal {
|
|
|
557
558
|
return true;
|
|
558
559
|
}
|
|
559
560
|
render() {
|
|
560
|
-
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes } = this;
|
|
561
|
+
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap } = this;
|
|
561
562
|
const showHandle = handle !== false && isSheetModal;
|
|
562
563
|
const mode = getIonMode(this);
|
|
563
564
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
564
565
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
565
|
-
return (h(Host, Object.assign({ key: '
|
|
566
|
+
return (h(Host, Object.assign({ key: 'fe6fd17cf857127f89d652b9aa3e9473d28c55db', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
566
567
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
567
|
-
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '
|
|
568
|
+
}, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), h("ion-backdrop", { key: '0f3a31363c2717e5483bc0412c25804897d4aff8', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { key: '0e5ed59162ff08fe0a9f757e06bdacc75f65c0ed', class: "modal-shadow" }), h("div", Object.assign({ key: '35cdbe2238765e5f346ad7be64f7eefa8c78f0c0',
|
|
568
569
|
/*
|
|
569
570
|
role and aria-modal must be used on the
|
|
570
571
|
same element. They must also be set inside the
|
|
571
572
|
shadow DOM otherwise ion-button will not be highlighted
|
|
572
573
|
when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
|
|
573
574
|
*/
|
|
574
|
-
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '
|
|
575
|
+
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { key: '7a4031eaebf9a098f4c4220a5fe9d1c25cc0ec92', class: "modal-handle",
|
|
575
576
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
576
|
-
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '
|
|
577
|
+
tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), h("slot", { key: '534adc8e5bd850199fe2e9e16f0e7c19217d8486' }))));
|
|
577
578
|
}
|
|
578
579
|
static get is() { return "ion-modal"; }
|
|
579
580
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1019,6 +1020,24 @@ export class Modal {
|
|
|
1019
1020
|
"reflect": false,
|
|
1020
1021
|
"defaultValue": "false"
|
|
1021
1022
|
},
|
|
1023
|
+
"focusTrap": {
|
|
1024
|
+
"type": "boolean",
|
|
1025
|
+
"mutable": false,
|
|
1026
|
+
"complexType": {
|
|
1027
|
+
"original": "boolean",
|
|
1028
|
+
"resolved": "boolean",
|
|
1029
|
+
"references": {}
|
|
1030
|
+
},
|
|
1031
|
+
"required": false,
|
|
1032
|
+
"optional": false,
|
|
1033
|
+
"docs": {
|
|
1034
|
+
"tags": [],
|
|
1035
|
+
"text": "If `true`, focus will not be allowed to move outside of this overlay.\nIf `false`, focus will be allowed to move outside of the overlay.\n\nIn most scenarios this property should remain set to `true`. Setting\nthis property to `false` can cause severe accessibility issues as users\nrelying on assistive technologies may be able to move focus into\na confusing state. We recommend only setting this to `false` when\nabsolutely necessary.\n\nDevelopers may want to consider disabling focus trapping if this\noverlay presents a non-Ionic overlay from a 3rd party library.\nDevelopers would disable focus trapping on the Ionic overlay\nwhen presenting the 3rd party overlay and then re-enable\nfocus trapping when dismissing the 3rd party overlay and moving\nfocus back to the Ionic overlay."
|
|
1036
|
+
},
|
|
1037
|
+
"attribute": "focus-trap",
|
|
1038
|
+
"reflect": false,
|
|
1039
|
+
"defaultValue": "true"
|
|
1040
|
+
},
|
|
1022
1041
|
"canDismiss": {
|
|
1023
1042
|
"type": "boolean",
|
|
1024
1043
|
"mutable": false,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { h } from "@stencil/core";
|
|
5
5
|
import { newSpecPage } from "@stencil/core/testing";
|
|
6
6
|
import { Modal } from "../../modal";
|
|
7
|
+
import { FOCUS_TRAP_DISABLE_CLASS } from "../../../../utils/overlays";
|
|
7
8
|
describe('modal: htmlAttributes inheritance', () => {
|
|
8
9
|
it('should correctly inherit attributes on host', async () => {
|
|
9
10
|
const page = await newSpecPage({
|
|
@@ -14,3 +15,21 @@ describe('modal: htmlAttributes inheritance', () => {
|
|
|
14
15
|
await expect(modal.getAttribute('data-testid')).toBe('basic-modal');
|
|
15
16
|
});
|
|
16
17
|
});
|
|
18
|
+
describe('modal: focus trap', () => {
|
|
19
|
+
it('should set the focus trap class when disabled', async () => {
|
|
20
|
+
const page = await newSpecPage({
|
|
21
|
+
components: [Modal],
|
|
22
|
+
template: () => h("ion-modal", { focusTrap: false, overlayIndex: 1 }),
|
|
23
|
+
});
|
|
24
|
+
const modal = page.body.querySelector('ion-modal');
|
|
25
|
+
expect(modal.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it('should not set the focus trap class by default', async () => {
|
|
28
|
+
const page = await newSpecPage({
|
|
29
|
+
components: [Modal],
|
|
30
|
+
template: () => h("ion-modal", { overlayIndex: 1 }),
|
|
31
|
+
});
|
|
32
|
+
const modal = page.body.querySelector('ion-modal');
|
|
33
|
+
expect(modal.classList.contains(FOCUS_TRAP_DISABLE_CLASS)).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -830,7 +830,7 @@ export class Nav {
|
|
|
830
830
|
}
|
|
831
831
|
}
|
|
832
832
|
render() {
|
|
833
|
-
return h("slot", { key: '
|
|
833
|
+
return h("slot", { key: 'e9d99a8a0b84f02f9964d8143cd5e647e43334f9' });
|
|
834
834
|
}
|
|
835
835
|
static get is() { return "ion-nav"; }
|
|
836
836
|
static get encapsulation() { return "shadow"; }
|
|
@@ -14,7 +14,7 @@ export class NavLink {
|
|
|
14
14
|
this.routerAnimation = undefined;
|
|
15
15
|
}
|
|
16
16
|
render() {
|
|
17
|
-
return h(Host, { key: '
|
|
17
|
+
return h(Host, { key: '42c23dcdec5fdb25defebaf6e8a9fa75754ff8eb', onClick: this.onClick });
|
|
18
18
|
}
|
|
19
19
|
static get is() { return "ion-nav-link"; }
|
|
20
20
|
static get properties() {
|
|
@@ -13,9 +13,9 @@ export class Note {
|
|
|
13
13
|
}
|
|
14
14
|
render() {
|
|
15
15
|
const mode = getIonMode(this);
|
|
16
|
-
return (h(Host, { key: '
|
|
16
|
+
return (h(Host, { key: '90ec2fe8c9487608ed8c0bdc32c2e80a6a0890b3', class: createColorClasses(this.color, {
|
|
17
17
|
[mode]: true,
|
|
18
|
-
}) }, h("slot", { key: '
|
|
18
|
+
}) }, h("slot", { key: '115ee3f79e6c526b0644443aad468e99385d0eda' })));
|
|
19
19
|
}
|
|
20
20
|
static get is() { return "ion-note"; }
|
|
21
21
|
static get encapsulation() { return "shadow"; }
|
|
@@ -474,7 +474,7 @@ export class Picker {
|
|
|
474
474
|
this.emitInputModeChange();
|
|
475
475
|
}
|
|
476
476
|
render() {
|
|
477
|
-
return (h(Host, { key: '
|
|
477
|
+
return (h(Host, { key: '02b0687b1f80ba295a965dfba76dd59e2d1de5d3', onPointerDown: (ev) => this.onPointerDown(ev), onClick: () => this.onClick() }, h("input", { key: 'f83ed84bcf9e02539c00d8a4e63e6a0d7fc4ac71', "aria-hidden": "true", tabindex: -1, inputmode: "numeric", type: "number", onKeyDown: (ev) => {
|
|
478
478
|
var _a;
|
|
479
479
|
/**
|
|
480
480
|
* The "Enter" key represents
|
|
@@ -489,7 +489,7 @@ export class Picker {
|
|
|
489
489
|
if (ev.key === 'Enter') {
|
|
490
490
|
(_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.blur();
|
|
491
491
|
}
|
|
492
|
-
}, ref: (el) => (this.inputEl = el), onInput: () => this.onInputChange(), onBlur: () => this.exitInputMode() }), h("div", { key: '
|
|
492
|
+
}, ref: (el) => (this.inputEl = el), onInput: () => this.onInputChange(), onBlur: () => this.exitInputMode() }), h("div", { key: '45b07fb0617d8e006712776bf78302288edb3ff4', class: "picker-before" }), h("div", { key: '73009229368e0d62b09c913aacade26f068a7aa9', class: "picker-after" }), h("div", { key: 'b73da00e446cd1cfd511c39212e14a00d355752e', class: "picker-highlight", ref: (el) => (this.highlightEl = el) }), h("slot", { key: 'd969f5efc5ddb9eda6c4828702efd1ceeb69f767' })));
|
|
493
493
|
}
|
|
494
494
|
static get is() { return "ion-picker"; }
|
|
495
495
|
static get encapsulation() { return "shadow"; }
|
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
*/
|
|
56
56
|
:host {
|
|
57
57
|
display: flex;
|
|
58
|
+
position: relative;
|
|
58
59
|
align-items: center;
|
|
59
60
|
justify-content: center;
|
|
60
61
|
max-width: 100%;
|
|
@@ -63,6 +64,24 @@
|
|
|
63
64
|
text-align: center;
|
|
64
65
|
}
|
|
65
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Renders an invisible element on top of the column that receives focus
|
|
69
|
+
* events. This allows screen readers to navigate the column.
|
|
70
|
+
*/
|
|
71
|
+
.assistive-focusable {
|
|
72
|
+
left: 0;
|
|
73
|
+
right: 0;
|
|
74
|
+
top: 0;
|
|
75
|
+
bottom: 0;
|
|
76
|
+
position: absolute;
|
|
77
|
+
z-index: 1;
|
|
78
|
+
pointer-events: none;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.assistive-focusable:focus {
|
|
82
|
+
outline: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
66
85
|
.picker-opts {
|
|
67
86
|
/**
|
|
68
87
|
* This padding must be set here and not on the
|
|
@@ -19,6 +19,7 @@ export class PickerColumn {
|
|
|
19
19
|
this.isScrolling = false;
|
|
20
20
|
this.isColumnVisible = false;
|
|
21
21
|
this.canExitInputMode = true;
|
|
22
|
+
this.updateValueTextOnScroll = false;
|
|
22
23
|
this.centerPickerItemInView = (target, smooth = true, canExitInputMode = true) => {
|
|
23
24
|
const { isColumnVisible, scrollEl } = this;
|
|
24
25
|
if (isColumnVisible && scrollEl) {
|
|
@@ -33,6 +34,7 @@ export class PickerColumn {
|
|
|
33
34
|
* of these can cause a scroll to occur.
|
|
34
35
|
*/
|
|
35
36
|
this.canExitInputMode = canExitInputMode;
|
|
37
|
+
this.updateValueTextOnScroll = false;
|
|
36
38
|
scrollEl.scroll({
|
|
37
39
|
top,
|
|
38
40
|
left: 0,
|
|
@@ -105,6 +107,7 @@ export class PickerColumn {
|
|
|
105
107
|
let activeEl = this.activeItem;
|
|
106
108
|
const scrollCallback = () => {
|
|
107
109
|
raf(() => {
|
|
110
|
+
var _a;
|
|
108
111
|
if (!scrollEl)
|
|
109
112
|
return;
|
|
110
113
|
if (timeout) {
|
|
@@ -185,8 +188,23 @@ export class PickerColumn {
|
|
|
185
188
|
}
|
|
186
189
|
activeEl = newActiveElement;
|
|
187
190
|
this.setPickerItemActiveState(newActiveElement, true);
|
|
191
|
+
/**
|
|
192
|
+
* Set the aria-valuetext even though the value prop has not been updated yet.
|
|
193
|
+
* This enables some screen readers to announce the value as the users drag
|
|
194
|
+
* as opposed to when their release their pointer from the screen.
|
|
195
|
+
*
|
|
196
|
+
* When the value is programmatically updated, we will smoothly scroll
|
|
197
|
+
* to the new option. However, we do not want to update aria-valuetext mid-scroll
|
|
198
|
+
* as that can cause the old value to be briefly set before being set to the
|
|
199
|
+
* correct option. This will cause some screen readers to announce the old value
|
|
200
|
+
* again before announcing the new value. The correct valuetext will be set on render.
|
|
201
|
+
*/
|
|
202
|
+
if (this.updateValueTextOnScroll) {
|
|
203
|
+
(_a = this.assistiveFocusable) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-valuetext', this.getOptionValueText(newActiveElement));
|
|
204
|
+
}
|
|
188
205
|
timeout = setTimeout(() => {
|
|
189
206
|
this.isScrolling = false;
|
|
207
|
+
this.updateValueTextOnScroll = true;
|
|
190
208
|
enableHaptics && hapticSelectionEnd();
|
|
191
209
|
/**
|
|
192
210
|
* Certain tasks (such as those that
|
|
@@ -245,12 +263,141 @@ export class PickerColumn {
|
|
|
245
263
|
*/
|
|
246
264
|
this.el.classList.remove('picker-column-active');
|
|
247
265
|
};
|
|
266
|
+
/**
|
|
267
|
+
* Find the next enabled option after the active option.
|
|
268
|
+
* @param stride - How many options to "jump" over in order to select the next option.
|
|
269
|
+
* This can be used to implement PageUp/PageDown behaviors where pressing these keys
|
|
270
|
+
* scrolls the picker by more than 1 option. For example, a stride of 5 means select
|
|
271
|
+
* the enabled option 5 options after the active one. Note that the actual option selected
|
|
272
|
+
* may be past the stride if the option at the stride is disabled.
|
|
273
|
+
*/
|
|
274
|
+
this.findNextOption = (stride = 1) => {
|
|
275
|
+
const { activeItem } = this;
|
|
276
|
+
if (!activeItem)
|
|
277
|
+
return null;
|
|
278
|
+
let prevNode = activeItem;
|
|
279
|
+
let node = activeItem.nextElementSibling;
|
|
280
|
+
while (node != null) {
|
|
281
|
+
if (stride > 0) {
|
|
282
|
+
stride--;
|
|
283
|
+
}
|
|
284
|
+
if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
|
|
285
|
+
return node;
|
|
286
|
+
}
|
|
287
|
+
prevNode = node;
|
|
288
|
+
// Use nextElementSibling instead of nextSibling to avoid text/comment nodes
|
|
289
|
+
node = node.nextElementSibling;
|
|
290
|
+
}
|
|
291
|
+
return prevNode;
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* Find the next enabled option after the active option.
|
|
295
|
+
* @param stride - How many options to "jump" over in order to select the next option.
|
|
296
|
+
* This can be used to implement PageUp/PageDown behaviors where pressing these keys
|
|
297
|
+
* scrolls the picker by more than 1 option. For example, a stride of 5 means select
|
|
298
|
+
* the enabled option 5 options before the active one. Note that the actual option selected
|
|
299
|
+
* may be past the stride if the option at the stride is disabled.
|
|
300
|
+
*/
|
|
301
|
+
this.findPreviousOption = (stride = 1) => {
|
|
302
|
+
const { activeItem } = this;
|
|
303
|
+
if (!activeItem)
|
|
304
|
+
return null;
|
|
305
|
+
let nextNode = activeItem;
|
|
306
|
+
let node = activeItem.previousElementSibling;
|
|
307
|
+
while (node != null) {
|
|
308
|
+
if (stride > 0) {
|
|
309
|
+
stride--;
|
|
310
|
+
}
|
|
311
|
+
if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
|
|
312
|
+
return node;
|
|
313
|
+
}
|
|
314
|
+
nextNode = node;
|
|
315
|
+
// Use previousElementSibling instead of previousSibling to avoid text/comment nodes
|
|
316
|
+
node = node.previousElementSibling;
|
|
317
|
+
}
|
|
318
|
+
return nextNode;
|
|
319
|
+
};
|
|
320
|
+
this.onKeyDown = (ev) => {
|
|
321
|
+
/**
|
|
322
|
+
* The below operations should be inverted when running on a mobile device.
|
|
323
|
+
* For example, swiping up will dispatch an "ArrowUp" event. On desktop,
|
|
324
|
+
* this should cause the previous option to be selected. On mobile, swiping
|
|
325
|
+
* up causes a view to scroll down. As a result, swiping up on mobile should
|
|
326
|
+
* cause the next option to be selected. The Home/End operations remain
|
|
327
|
+
* unchanged because those always represent the first/last options, respectively.
|
|
328
|
+
*/
|
|
329
|
+
const mobile = isPlatform('mobile');
|
|
330
|
+
let newOption = null;
|
|
331
|
+
switch (ev.key) {
|
|
332
|
+
case 'ArrowDown':
|
|
333
|
+
newOption = mobile ? this.findPreviousOption() : this.findNextOption();
|
|
334
|
+
break;
|
|
335
|
+
case 'ArrowUp':
|
|
336
|
+
newOption = mobile ? this.findNextOption() : this.findPreviousOption();
|
|
337
|
+
break;
|
|
338
|
+
case 'PageUp':
|
|
339
|
+
newOption = mobile ? this.findNextOption(5) : this.findPreviousOption(5);
|
|
340
|
+
break;
|
|
341
|
+
case 'PageDown':
|
|
342
|
+
newOption = mobile ? this.findPreviousOption(5) : this.findNextOption(5);
|
|
343
|
+
break;
|
|
344
|
+
case 'Home':
|
|
345
|
+
/**
|
|
346
|
+
* There is no guarantee that the first child will be an ion-picker-column-option,
|
|
347
|
+
* so we do not use firstElementChild.
|
|
348
|
+
*/
|
|
349
|
+
newOption = this.el.querySelector('ion-picker-column-option:first-of-type');
|
|
350
|
+
break;
|
|
351
|
+
case 'End':
|
|
352
|
+
/**
|
|
353
|
+
* There is no guarantee that the last child will be an ion-picker-column-option,
|
|
354
|
+
* so we do not use lastElementChild.
|
|
355
|
+
*/
|
|
356
|
+
newOption = this.el.querySelector('ion-picker-column-option:last-of-type');
|
|
357
|
+
break;
|
|
358
|
+
default:
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
if (newOption !== null) {
|
|
362
|
+
this.value = newOption.value;
|
|
363
|
+
// This stops any default browser behavior such as scrolling
|
|
364
|
+
ev.preventDefault();
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
/**
|
|
368
|
+
* Utility to generate the correct text for aria-valuetext.
|
|
369
|
+
*/
|
|
370
|
+
this.getOptionValueText = (el) => {
|
|
371
|
+
var _a;
|
|
372
|
+
return el ? (_a = el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : el.innerText : '';
|
|
373
|
+
};
|
|
374
|
+
/**
|
|
375
|
+
* Render an element that overlays the column. This element is for assistive
|
|
376
|
+
* tech to allow users to navigate the column up/down. This element should receive
|
|
377
|
+
* focus as it listens for synthesized keyboard events as required by the
|
|
378
|
+
* slider role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/slider_role
|
|
379
|
+
*/
|
|
380
|
+
this.renderAssistiveFocusable = () => {
|
|
381
|
+
const { activeItem } = this;
|
|
382
|
+
const valueText = this.getOptionValueText(activeItem);
|
|
383
|
+
/**
|
|
384
|
+
* When using the picker, the valuetext provides important context that valuenow
|
|
385
|
+
* does not. Additionally, using non-zero valuemin/valuemax values can cause
|
|
386
|
+
* WebKit to incorrectly announce numeric valuetext values (such as a year
|
|
387
|
+
* like "2024") as percentages: https://bugs.webkit.org/show_bug.cgi?id=273126
|
|
388
|
+
*/
|
|
389
|
+
return (h("div", { ref: (el) => (this.assistiveFocusable = el), class: "assistive-focusable", role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": valueText, "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }));
|
|
390
|
+
};
|
|
391
|
+
this.ariaLabel = null;
|
|
248
392
|
this.isActive = false;
|
|
249
393
|
this.disabled = false;
|
|
250
394
|
this.value = undefined;
|
|
251
395
|
this.color = 'primary';
|
|
252
396
|
this.numericInput = false;
|
|
253
397
|
}
|
|
398
|
+
ariaLabelChanged(newValue) {
|
|
399
|
+
this.ariaLabel = newValue;
|
|
400
|
+
}
|
|
254
401
|
valueChange() {
|
|
255
402
|
if (this.isColumnVisible) {
|
|
256
403
|
/**
|
|
@@ -366,6 +513,10 @@ export class PickerColumn {
|
|
|
366
513
|
this.scrollEl.focus();
|
|
367
514
|
}
|
|
368
515
|
}
|
|
516
|
+
connectedCallback() {
|
|
517
|
+
var _a;
|
|
518
|
+
this.ariaLabel = (_a = this.el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : 'Select a value';
|
|
519
|
+
}
|
|
369
520
|
get activeItem() {
|
|
370
521
|
const { value } = this;
|
|
371
522
|
const options = Array.from(this.el.querySelectorAll('ion-picker-column-option'));
|
|
@@ -383,14 +534,14 @@ export class PickerColumn {
|
|
|
383
534
|
render() {
|
|
384
535
|
const { color, disabled, isActive, numericInput } = this;
|
|
385
536
|
const mode = getIonMode(this);
|
|
386
|
-
return (h(Host, { key: '
|
|
537
|
+
return (h(Host, { key: 'ced35afc6326a20dbac68193921a807a9c10bb99', class: createColorClasses(color, {
|
|
387
538
|
[mode]: true,
|
|
388
539
|
['picker-column-active']: isActive,
|
|
389
540
|
['picker-column-numeric-input']: numericInput,
|
|
390
541
|
['picker-column-disabled']: disabled,
|
|
391
|
-
}) }, h("slot", { key: '
|
|
542
|
+
}) }, this.renderAssistiveFocusable(), h("slot", { key: '41e290dcc44dacb4237eb674ce2dedc7db66eb7d', name: "prefix" }), h("div", { key: '1fd869b063900103deadefc40929a1e8f02ec084', "aria-hidden": "true", class: "picker-opts", ref: (el) => {
|
|
392
543
|
this.scrollEl = el;
|
|
393
|
-
} }, h("div", { key: '
|
|
544
|
+
} }, h("div", { key: '0d2087f775b240c9b2534650eb27f3d99e7690a9', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '1245b2bb2b6314c3ec4e0ab3ece4e42beb360fc9', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '503b08f6bbe27fa7d34c165a93ec38ce7f1ad590', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("slot", { key: 'ec401a2b2d56546fb3f10239b71320ce7dc6a77d' }), h("div", { key: '97a234018291c5a6ca7a56bb1a9a417cac0b3e6f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '0197711f71486a8fa3c184b593cebe1c1e54c585', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '961304f0a2a10afb3502ce4c5fbdceef0aa933cf', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), h("slot", { key: 'f38b83d26c3c2ba8ef00da7caf7f0be518b2007d', name: "suffix" })));
|
|
394
545
|
}
|
|
395
546
|
static get is() { return "ion-picker-column"; }
|
|
396
547
|
static get encapsulation() { return "shadow"; }
|
|
@@ -490,6 +641,7 @@ export class PickerColumn {
|
|
|
490
641
|
}
|
|
491
642
|
static get states() {
|
|
492
643
|
return {
|
|
644
|
+
"ariaLabel": {},
|
|
493
645
|
"isActive": {}
|
|
494
646
|
};
|
|
495
647
|
}
|
|
@@ -502,7 +654,7 @@ export class PickerColumn {
|
|
|
502
654
|
"composed": true,
|
|
503
655
|
"docs": {
|
|
504
656
|
"tags": [],
|
|
505
|
-
"text": "Emitted when the value has changed."
|
|
657
|
+
"text": "Emitted when the value has changed.\n\nThis event will not emit when programmatically setting the `value` property."
|
|
506
658
|
},
|
|
507
659
|
"complexType": {
|
|
508
660
|
"original": "PickerColumnChangeEventDetail",
|
|
@@ -594,6 +746,9 @@ export class PickerColumn {
|
|
|
594
746
|
static get elementRef() { return "el"; }
|
|
595
747
|
static get watchers() {
|
|
596
748
|
return [{
|
|
749
|
+
"propName": "aria-label",
|
|
750
|
+
"methodName": "ariaLabelChanged"
|
|
751
|
+
}, {
|
|
597
752
|
"propName": "value",
|
|
598
753
|
"methodName": "valueChange"
|
|
599
754
|
}];
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { h } from "@stencil/core";
|
|
5
|
+
import { newSpecPage } from "@stencil/core/testing";
|
|
6
|
+
import { PickerColumn } from "../picker-column";
|
|
7
|
+
import { PickerColumnOption } from "../../picker-column-option/picker-column-option";
|
|
8
|
+
describe('picker-column: assistive element', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
const mockIntersectionObserver = jest.fn();
|
|
11
|
+
mockIntersectionObserver.mockReturnValue({
|
|
12
|
+
observe: () => null,
|
|
13
|
+
unobserve: () => null,
|
|
14
|
+
disconnect: () => null,
|
|
15
|
+
});
|
|
16
|
+
global.IntersectionObserver = mockIntersectionObserver;
|
|
17
|
+
});
|
|
18
|
+
it('should have a default label', async () => {
|
|
19
|
+
const page = await newSpecPage({
|
|
20
|
+
components: [PickerColumn],
|
|
21
|
+
template: () => h("ion-picker-column", null),
|
|
22
|
+
});
|
|
23
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
24
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
25
|
+
expect(assistiveFocusable.getAttribute('aria-label')).not.toBe(null);
|
|
26
|
+
});
|
|
27
|
+
it('should have a custom label', async () => {
|
|
28
|
+
const page = await newSpecPage({
|
|
29
|
+
components: [PickerColumn],
|
|
30
|
+
template: () => h("ion-picker-column", { "aria-label": "my label" }),
|
|
31
|
+
});
|
|
32
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
33
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
34
|
+
expect(assistiveFocusable.getAttribute('aria-label')).toBe('my label');
|
|
35
|
+
});
|
|
36
|
+
it('should update a custom label', async () => {
|
|
37
|
+
const page = await newSpecPage({
|
|
38
|
+
components: [PickerColumn],
|
|
39
|
+
template: () => h("ion-picker-column", null),
|
|
40
|
+
});
|
|
41
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
42
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
43
|
+
pickerCol.setAttribute('aria-label', 'my label');
|
|
44
|
+
await page.waitForChanges();
|
|
45
|
+
expect(assistiveFocusable.getAttribute('aria-label')).toBe('my label');
|
|
46
|
+
});
|
|
47
|
+
it('should receive keyboard focus when enabled', async () => {
|
|
48
|
+
const page = await newSpecPage({
|
|
49
|
+
components: [PickerColumn],
|
|
50
|
+
template: () => h("ion-picker-column", null),
|
|
51
|
+
});
|
|
52
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
53
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
54
|
+
expect(assistiveFocusable.tabIndex).toBe(0);
|
|
55
|
+
});
|
|
56
|
+
it('should not receive keyboard focus when disabled', async () => {
|
|
57
|
+
const page = await newSpecPage({
|
|
58
|
+
components: [PickerColumn],
|
|
59
|
+
template: () => h("ion-picker-column", { disabled: true }),
|
|
60
|
+
});
|
|
61
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
62
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
63
|
+
expect(assistiveFocusable.tabIndex).toBe(-1);
|
|
64
|
+
});
|
|
65
|
+
it('should use option aria-label as assistive element aria-valuetext', async () => {
|
|
66
|
+
const page = await newSpecPage({
|
|
67
|
+
components: [PickerColumn, PickerColumnOption],
|
|
68
|
+
template: () => (h("ion-picker-column", { value: 1 }, h("ion-picker-column-option", { value: 1, "aria-label": "My Label" }, "My Text"))),
|
|
69
|
+
});
|
|
70
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
71
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
72
|
+
expect(assistiveFocusable.getAttribute('aria-valuetext')).toBe('My Label');
|
|
73
|
+
});
|
|
74
|
+
it('should use option text as assistive element aria-valuetext when no label provided', async () => {
|
|
75
|
+
const page = await newSpecPage({
|
|
76
|
+
components: [PickerColumn, PickerColumnOption],
|
|
77
|
+
template: () => (h("ion-picker-column", { value: 1 }, h("ion-picker-column-option", { value: 1 }, "My Text"))),
|
|
78
|
+
});
|
|
79
|
+
const pickerCol = page.body.querySelector('ion-picker-column');
|
|
80
|
+
const assistiveFocusable = pickerCol.shadowRoot.querySelector('.assistive-focusable');
|
|
81
|
+
expect(assistiveFocusable.getAttribute('aria-valuetext')).toBe('My Text');
|
|
82
|
+
});
|
|
83
|
+
});
|
|
@@ -76,10 +76,10 @@ export class PickerColumnOption {
|
|
|
76
76
|
render() {
|
|
77
77
|
const { color, disabled, ariaLabel } = this;
|
|
78
78
|
const mode = getIonMode(this);
|
|
79
|
-
return (h(Host, { key: '
|
|
79
|
+
return (h(Host, { key: 'cc4435a0ce0e55be1321bcabaf342ed68cf5ba1e', class: createColorClasses(color, {
|
|
80
80
|
[mode]: true,
|
|
81
81
|
['option-disabled']: disabled,
|
|
82
|
-
}) }, h("button", { key: '
|
|
82
|
+
}) }, h("button", { key: '0187fb967771e0787807a8538dce4e59f6a98565', tabindex: "-1", "aria-label": ariaLabel, disabled: disabled, onClick: () => this.onClick() }, h("slot", { key: 'dbe52552f3f27332816748c12d929cc81060841d' }))));
|
|
83
83
|
}
|
|
84
84
|
static get is() { return "ion-picker-column-option"; }
|
|
85
85
|
static get encapsulation() { return "shadow"; }
|
|
@@ -182,11 +182,11 @@ export class Picker {
|
|
|
182
182
|
render() {
|
|
183
183
|
const { htmlAttributes } = this;
|
|
184
184
|
const mode = getIonMode(this);
|
|
185
|
-
return (h(Host, Object.assign({ key: '
|
|
185
|
+
return (h(Host, Object.assign({ key: '26e3144adcdf01605271d01e468bb4a75ce854b1', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
|
|
186
186
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
187
187
|
}, class: Object.assign({ [mode]: true,
|
|
188
188
|
// Used internally for styling
|
|
189
|
-
[`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: '
|
|
189
|
+
[`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), h("ion-backdrop", { key: 'fa212d21406606186cd95f8c7a4f119696ac8d4a', visible: this.showBackdrop, tappable: this.backdropDismiss }), h("div", { key: '19ea889f65cb6a68a9db26cf9f83c6587cfcf07e', tabindex: "0" }), h("div", { key: '5fc0f5d26915ba353b9f0335946f94b6fda95e1e', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, h("div", { key: '3fa5bff4ac0013ef31845482a27a14caebbdcd2f', class: "picker-toolbar" }, this.buttons.map((b) => (h("div", { class: buttonWrapperClass(b) }, h("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass(b) }, b.text))))), h("div", { key: '2ff6376956d01dcd9ec01b8d6972dd4b37ffb1a1', class: "picker-columns" }, h("div", { key: '4adcef77429f10a3faa50b41d1eaf3404387997c', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => h("ion-picker-legacy-column", { col: c })), h("div", { key: 'e0f37d3e9896eb2bc0f0aef4762a897130851963', class: "picker-below-highlight" }))), h("div", { key: '671bb7d0f487b0d7c7fa70388f8fa1de77448b9f', tabindex: "0" })));
|
|
190
190
|
}
|
|
191
191
|
static get is() { return "ion-picker-legacy"; }
|
|
192
192
|
static get encapsulation() { return "scoped"; }
|
|
@@ -336,9 +336,9 @@ export class PickerColumnCmp {
|
|
|
336
336
|
render() {
|
|
337
337
|
const col = this.col;
|
|
338
338
|
const mode = getIonMode(this);
|
|
339
|
-
return (h(Host, { key: '
|
|
339
|
+
return (h(Host, { key: '56289a294e5c580f3e7fe5fc12777aa7f80ad19b', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, getClassMap(col.cssClass)), style: {
|
|
340
340
|
'max-width': this.col.columnWidth,
|
|
341
|
-
} }, col.prefix && (h("div", { key: '
|
|
341
|
+
} }, col.prefix && (h("div", { key: 'd21f44667b5df567d6879723fe643ea7c2c60bef', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), h("div", { key: 'bb427e5f24fd832703926e0e847ad05567597262', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (h("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (h("div", { key: '0413f7c074b6534b8967387ecb9957a79a267aff', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
|
|
342
342
|
}
|
|
343
343
|
static get is() { return "ion-picker-legacy-column"; }
|
|
344
344
|
static get originalStyleUrls() {
|
|
@@ -7,7 +7,7 @@ import { CoreDelegate, attachComponent, detachComponent } from "../../utils/fram
|
|
|
7
7
|
import { addEventListener, raf, hasLazyBuild } from "../../utils/helpers";
|
|
8
8
|
import { createLockController } from "../../utils/lock-controller";
|
|
9
9
|
import { printIonWarning } from "../../utils/logging/index";
|
|
10
|
-
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId } from "../../utils/overlays";
|
|
10
|
+
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId, FOCUS_TRAP_DISABLE_CLASS, } from "../../utils/overlays";
|
|
11
11
|
import { isPlatform } from "../../utils/platform";
|
|
12
12
|
import { getClassMap } from "../../utils/theme";
|
|
13
13
|
import { deepReady, waitForMount } from "../../utils/transition/index";
|
|
@@ -107,6 +107,7 @@ export class Popover {
|
|
|
107
107
|
this.arrow = true;
|
|
108
108
|
this.isOpen = false;
|
|
109
109
|
this.keyboardEvents = false;
|
|
110
|
+
this.focusTrap = true;
|
|
110
111
|
this.keepContentsMounted = false;
|
|
111
112
|
}
|
|
112
113
|
onTriggerChange() {
|
|
@@ -333,12 +334,12 @@ export class Popover {
|
|
|
333
334
|
}
|
|
334
335
|
render() {
|
|
335
336
|
const mode = getIonMode(this);
|
|
336
|
-
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes } = this;
|
|
337
|
+
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
|
|
337
338
|
const desktop = isPlatform('desktop');
|
|
338
339
|
const enableArrow = arrow && !parentPopover;
|
|
339
|
-
return (h(Host, Object.assign({ key: '
|
|
340
|
+
return (h(Host, Object.assign({ key: '17e5e8b3e7ba5e251665fb9d0ade10c781f82f0e', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
340
341
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
341
|
-
}, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: '
|
|
342
|
+
}, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && h("ion-backdrop", { key: 'c12fb94b375d7e88a0c5d715440c0f66ad7ee817', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: '478b388cc9a5a382003a2863e968e77a174914ab', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { key: 'f1c63a0079f197a8d4577e7c00a654871fb9d816', class: "popover-arrow", part: "arrow" }), h("div", { key: '08b62a321c09ad4b0f90460468ecbc1d56320bf1', class: "popover-content", part: "content" }, h("slot", { key: '55645ff597f64d434219caa28015cf2a4ceb0ee5' })))));
|
|
342
343
|
}
|
|
343
344
|
static get is() { return "ion-popover"; }
|
|
344
345
|
static get encapsulation() { return "shadow"; }
|
|
@@ -860,6 +861,24 @@ export class Popover {
|
|
|
860
861
|
"reflect": false,
|
|
861
862
|
"defaultValue": "false"
|
|
862
863
|
},
|
|
864
|
+
"focusTrap": {
|
|
865
|
+
"type": "boolean",
|
|
866
|
+
"mutable": false,
|
|
867
|
+
"complexType": {
|
|
868
|
+
"original": "boolean",
|
|
869
|
+
"resolved": "boolean",
|
|
870
|
+
"references": {}
|
|
871
|
+
},
|
|
872
|
+
"required": false,
|
|
873
|
+
"optional": false,
|
|
874
|
+
"docs": {
|
|
875
|
+
"tags": [],
|
|
876
|
+
"text": "If `true`, focus will not be allowed to move outside of this overlay.\nIf `false`, focus will be allowed to move outside of the overlay.\n\nIn most scenarios this property should remain set to `true`. Setting\nthis property to `false` can cause severe accessibility issues as users\nrelying on assistive technologies may be able to move focus into\na confusing state. We recommend only setting this to `false` when\nabsolutely necessary.\n\nDevelopers may want to consider disabling focus trapping if this\noverlay presents a non-Ionic overlay from a 3rd party library.\nDevelopers would disable focus trapping on the Ionic overlay\nwhen presenting the 3rd party overlay and then re-enable\nfocus trapping when dismissing the 3rd party overlay and moving\nfocus back to the Ionic overlay."
|
|
877
|
+
},
|
|
878
|
+
"attribute": "focus-trap",
|
|
879
|
+
"reflect": false,
|
|
880
|
+
"defaultValue": "true"
|
|
881
|
+
},
|
|
863
882
|
"keepContentsMounted": {
|
|
864
883
|
"type": "boolean",
|
|
865
884
|
"mutable": false,
|