@ionic/core 8.0.0-beta.0 → 8.0.0-beta.1
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/input-shims.js +8 -1
- package/components/ion-item-divider.js +1 -1
- package/components/ion-menu.js +6 -27
- package/components/ion-modal.js +37 -5
- package/components/item.js +23 -9
- package/components/overlays.js +79 -36
- package/components/picker-column.js +20 -5
- package/components/popover.js +4 -4
- package/dist/cjs/{app-globals-92ad1b3d.js → app-globals-4d26cb5a.js} +1 -1
- package/dist/cjs/{button-active-8f6a8e77.js → button-active-e447f58b.js} +1 -1
- package/dist/cjs/{hardware-back-button-2696acaf.js → hardware-back-button-4cb049f1.js} +2 -2
- package/dist/cjs/{index-88b3bd6f.js → index-92bb95d6.js} +3 -3
- package/dist/cjs/{index-16fc2c94.js → index-bbc5b1f7.js} +2 -2
- package/dist/cjs/{index-0ffe376d.js → index-ea266398.js} +2 -2
- package/dist/cjs/index.cjs.js +8 -8
- package/dist/cjs/{input-shims-37843ce5.js → input-shims-679d87bc.js} +8 -1
- package/dist/cjs/ion-accordion_2.cjs.entry.js +2 -2
- 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 +7 -7
- package/dist/cjs/ion-avatar_3.cjs.entry.js +2 -2
- 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 +2 -2
- package/dist/cjs/ion-chip.cjs.entry.js +2 -2
- package/dist/cjs/ion-col_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-datetime-button.cjs.entry.js +2 -2
- package/dist/cjs/ion-datetime_3.cjs.entry.js +4 -4
- package/dist/cjs/ion-fab_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-img.cjs.entry.js +2 -2
- package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-input.cjs.entry.js +2 -2
- package/dist/cjs/ion-item-option_3.cjs.entry.js +2 -2
- package/dist/cjs/ion-item_8.cjs.entry.js +25 -11
- package/dist/cjs/ion-loading.cjs.entry.js +4 -4
- package/dist/cjs/ion-menu_3.cjs.entry.js +11 -32
- package/dist/cjs/ion-modal.cjs.entry.js +42 -10
- package/dist/cjs/ion-nav_2.cjs.entry.js +3 -3
- package/dist/cjs/ion-picker-column-option.cjs.entry.js +2 -2
- package/dist/cjs/ion-picker-column.cjs.entry.js +22 -7
- package/dist/cjs/ion-picker.cjs.entry.js +1 -1
- package/dist/cjs/ion-popover.cjs.entry.js +8 -8
- package/dist/cjs/ion-progress-bar.cjs.entry.js +2 -2
- package/dist/cjs/ion-radio_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-range.cjs.entry.js +2 -2
- package/dist/cjs/ion-refresher_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-reorder_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-ripple-effect.cjs.entry.js +2 -2
- package/dist/cjs/ion-route_4.cjs.entry.js +2 -2
- package/dist/cjs/ion-searchbar.cjs.entry.js +2 -2
- package/dist/cjs/ion-segment_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-select_3.cjs.entry.js +4 -4
- package/dist/cjs/ion-spinner.cjs.entry.js +2 -2
- package/dist/cjs/ion-split-pane.cjs.entry.js +2 -2
- package/dist/cjs/ion-tab-bar_2.cjs.entry.js +2 -2
- package/dist/cjs/ion-tab_2.cjs.entry.js +1 -1
- package/dist/cjs/ion-text.cjs.entry.js +2 -2
- package/dist/cjs/ion-textarea.cjs.entry.js +2 -2
- package/dist/cjs/ion-toast.cjs.entry.js +4 -4
- package/dist/cjs/ion-toggle.cjs.entry.js +2 -2
- package/dist/cjs/{ionic-global-59a10130.js → ionic-global-59aa7eb7.js} +1 -1
- package/dist/cjs/ionic.cjs.js +5 -5
- package/dist/cjs/{ios.transition-b102ee38.js → ios.transition-997fe325.js} +2 -2
- package/dist/cjs/loader.cjs.js +4 -4
- package/dist/cjs/{md.transition-a5454240.js → md.transition-2b76c2c6.js} +2 -2
- package/dist/cjs/{overlays-6b7d156b.js → overlays-3d02b54f.js} +81 -37
- package/dist/cjs/{status-tap-b60dcbd8.js → status-tap-3761c2d4.js} +1 -1
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/datetime/test/basic/datetime.e2e.js +3 -1
- package/dist/collection/components/input/test/item/input.e2e.js +21 -0
- package/dist/collection/components/item/item.ios.css +1 -1
- package/dist/collection/components/item/item.js +20 -6
- package/dist/collection/components/item/item.md.css +5 -15
- package/dist/collection/components/item-divider/item-divider.md.css +4 -14
- package/dist/collection/components/menu/menu.js +6 -26
- package/dist/collection/components/modal/modal.js +37 -5
- package/dist/collection/components/modal/test/modal-attributes.spec.js +32 -0
- package/dist/collection/components/picker-column/picker-column.js +20 -5
- package/dist/collection/components/popover/popover.js +5 -4
- package/dist/collection/components/textarea/test/item/textarea.e2e.js +21 -0
- package/dist/collection/utils/focus-trap.js +78 -0
- package/dist/collection/utils/input-shims/input-shims.js +8 -1
- package/dist/collection/utils/overlays.js +3 -34
- package/dist/docs.json +2 -2
- package/dist/esm/{app-globals-5cf6195b.js → app-globals-cfb6787b.js} +1 -1
- package/dist/esm/{button-active-4407b98c.js → button-active-454e5c57.js} +1 -1
- package/dist/esm/{hardware-back-button-b410a047.js → hardware-back-button-3a14f99e.js} +2 -2
- package/dist/esm/{index-8758824c.js → index-03086279.js} +2 -2
- package/dist/esm/{index-1eff8599.js → index-5847f4a9.js} +3 -3
- package/dist/esm/{index-4c30cddd.js → index-9b6d6df3.js} +2 -2
- package/dist/esm/index.js +8 -8
- package/dist/esm/{input-shims-91e6634c.js → input-shims-56c1f603.js} +8 -1
- package/dist/esm/ion-accordion_2.entry.js +2 -2
- 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 +7 -7
- package/dist/esm/ion-avatar_3.entry.js +2 -2
- 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 +2 -2
- package/dist/esm/ion-chip.entry.js +2 -2
- package/dist/esm/ion-col_3.entry.js +2 -2
- package/dist/esm/ion-datetime-button.entry.js +2 -2
- package/dist/esm/ion-datetime_3.entry.js +4 -4
- package/dist/esm/ion-fab_3.entry.js +2 -2
- package/dist/esm/ion-img.entry.js +2 -2
- package/dist/esm/ion-infinite-scroll_2.entry.js +2 -2
- package/dist/esm/ion-input.entry.js +2 -2
- package/dist/esm/ion-item-option_3.entry.js +2 -2
- package/dist/esm/ion-item_8.entry.js +25 -11
- package/dist/esm/ion-loading.entry.js +4 -4
- package/dist/esm/ion-menu_3.entry.js +11 -32
- package/dist/esm/ion-modal.entry.js +42 -10
- package/dist/esm/ion-nav_2.entry.js +3 -3
- package/dist/esm/ion-picker-column-option.entry.js +2 -2
- package/dist/esm/ion-picker-column.entry.js +22 -7
- package/dist/esm/ion-picker.entry.js +1 -1
- package/dist/esm/ion-popover.entry.js +8 -8
- package/dist/esm/ion-progress-bar.entry.js +2 -2
- package/dist/esm/ion-radio_2.entry.js +2 -2
- package/dist/esm/ion-range.entry.js +2 -2
- package/dist/esm/ion-refresher_2.entry.js +2 -2
- package/dist/esm/ion-reorder_2.entry.js +2 -2
- package/dist/esm/ion-ripple-effect.entry.js +2 -2
- package/dist/esm/ion-route_4.entry.js +2 -2
- package/dist/esm/ion-searchbar.entry.js +2 -2
- package/dist/esm/ion-segment_2.entry.js +2 -2
- package/dist/esm/ion-select_3.entry.js +4 -4
- package/dist/esm/ion-spinner.entry.js +2 -2
- package/dist/esm/ion-split-pane.entry.js +2 -2
- package/dist/esm/ion-tab-bar_2.entry.js +2 -2
- package/dist/esm/ion-tab_2.entry.js +1 -1
- package/dist/esm/ion-text.entry.js +2 -2
- package/dist/esm/ion-textarea.entry.js +2 -2
- package/dist/esm/ion-toast.entry.js +4 -4
- package/dist/esm/ion-toggle.entry.js +2 -2
- package/dist/esm/{ionic-global-ad9a1810.js → ionic-global-c976d684.js} +1 -1
- package/dist/esm/ionic.js +6 -6
- package/dist/esm/{ios.transition-189b73b7.js → ios.transition-a097dbf5.js} +2 -2
- package/dist/esm/loader.js +5 -5
- package/dist/esm/{md.transition-c9761eef.js → md.transition-b4170ef7.js} +2 -2
- package/dist/esm/{overlays-c69d2a07.js → overlays-4ba3b255.js} +81 -38
- package/dist/esm/{status-tap-1d638ee6.js → status-tap-7a12f017.js} +1 -1
- package/dist/esm-es5/app-globals-cfb6787b.js +4 -0
- package/dist/esm-es5/{button-active-4407b98c.js → button-active-454e5c57.js} +1 -1
- package/dist/esm-es5/{hardware-back-button-b410a047.js → hardware-back-button-3a14f99e.js} +1 -1
- package/dist/esm-es5/{index-8758824c.js → index-03086279.js} +1 -1
- package/dist/esm-es5/{index-1eff8599.js → index-5847f4a9.js} +1 -1
- package/dist/esm-es5/{index-4c30cddd.js → index-9b6d6df3.js} +1 -1
- package/dist/esm-es5/index.js +1 -1
- package/dist/esm-es5/{input-shims-91e6634c.js → input-shims-56c1f603.js} +1 -1
- 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.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-ad9a1810.js → ionic-global-c976d684.js} +1 -1
- package/dist/esm-es5/ionic.js +1 -1
- package/dist/esm-es5/{ios.transition-189b73b7.js → ios.transition-a097dbf5.js} +1 -1
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/md.transition-b4170ef7.js +4 -0
- package/dist/esm-es5/overlays-4ba3b255.js +4 -0
- package/dist/esm-es5/{status-tap-1d638ee6.js → status-tap-7a12f017.js} +1 -1
- 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-03f63663.system.js +4 -0
- package/dist/ionic/{p-d9b6b588.entry.js → p-060fdc03.entry.js} +1 -1
- package/dist/ionic/{p-7292add8.entry.js → p-06fccad7.entry.js} +1 -1
- package/dist/ionic/{p-eb506d19.system.entry.js → p-08dfa278.system.entry.js} +1 -1
- package/dist/ionic/{p-0612cdcc.system.entry.js → p-09872ec8.system.entry.js} +1 -1
- package/dist/ionic/p-0ca35c1d.system.entry.js +4 -0
- package/dist/ionic/{p-916a4e14.entry.js → p-0efb1cce.entry.js} +1 -1
- package/dist/ionic/{p-0b34d3a7.system.js → p-134d4936.system.js} +1 -1
- package/dist/ionic/{p-5e70f800.system.entry.js → p-1600d68c.system.entry.js} +1 -1
- package/dist/ionic/p-19e79fe8.entry.js +4 -0
- package/dist/ionic/{p-de0a7606.system.entry.js → p-1a5ed3fe.system.entry.js} +1 -1
- package/dist/ionic/{p-f7d802e1.entry.js → p-1a68de09.entry.js} +1 -1
- package/dist/ionic/{p-3c47c5c8.system.entry.js → p-1bca443b.system.entry.js} +1 -1
- package/dist/ionic/{p-3d77b300.system.entry.js → p-1c436e95.system.entry.js} +1 -1
- package/dist/ionic/{p-e46adaf1.system.entry.js → p-1ccbaaf3.system.entry.js} +1 -1
- package/dist/ionic/{p-8fe3c4ef.entry.js → p-1ce172db.entry.js} +1 -1
- package/dist/ionic/{p-5133c4a3.system.entry.js → p-1e0a18a1.system.entry.js} +1 -1
- package/dist/ionic/{p-6e14d3ca.system.entry.js → p-1ed99eba.system.entry.js} +1 -1
- package/dist/ionic/{p-de55ec45.js → p-1fa738c4.js} +1 -1
- package/dist/ionic/p-22d2a891.js +4 -0
- package/dist/ionic/{p-385f66bc.entry.js → p-25850474.entry.js} +1 -1
- package/dist/ionic/{p-ceceac26.js → p-27594fc2.js} +1 -1
- package/dist/ionic/{p-ec77b7ad.system.entry.js → p-2b3e0d99.system.entry.js} +1 -1
- package/dist/ionic/{p-13e8ad2e.entry.js → p-300b2cf1.entry.js} +1 -1
- package/dist/ionic/{p-6525a8cd.system.js → p-30892e0c.system.js} +1 -1
- package/dist/ionic/{p-16e06393.system.js → p-3410a9cb.system.js} +1 -1
- package/dist/ionic/{p-973c7550.system.entry.js → p-3bac30bf.system.entry.js} +1 -1
- package/dist/ionic/{p-cefbb7b7.entry.js → p-41970e75.entry.js} +1 -1
- package/dist/ionic/p-41b9cdd2.entry.js +4 -0
- package/dist/ionic/{p-5eabaa80.js → p-43322b14.js} +1 -1
- package/dist/ionic/p-4523be60.entry.js +4 -0
- package/dist/ionic/{p-5d64e680.entry.js → p-466bdeae.entry.js} +1 -1
- package/dist/ionic/{p-717c4b72.entry.js → p-4825e380.entry.js} +1 -1
- package/dist/ionic/p-4ad02639.entry.js +4 -0
- package/dist/ionic/{p-1df25966.entry.js → p-4c2cac66.entry.js} +1 -1
- package/dist/ionic/{p-00a762c9.entry.js → p-5a055df4.entry.js} +1 -1
- package/dist/ionic/{p-5d7e32ce.js → p-5aa60929.js} +1 -1
- package/dist/ionic/{p-e311af42.entry.js → p-5afb6e48.entry.js} +1 -1
- package/dist/ionic/{p-5797981d.system.entry.js → p-5c3991e3.system.entry.js} +2 -2
- package/dist/ionic/{p-1f79e54a.entry.js → p-602494c6.entry.js} +1 -1
- package/dist/ionic/{p-ed7a529f.js → p-60efe117.js} +1 -1
- package/dist/ionic/{p-c9e21694.system.entry.js → p-62f15daf.system.entry.js} +2 -2
- package/dist/ionic/{p-f0a7e80b.js → p-65d3f0e9.js} +1 -1
- package/dist/ionic/p-6657681b.system.entry.js +4 -0
- package/dist/ionic/{p-98e6b3b8.system.js → p-6d95943d.system.js} +1 -1
- package/dist/ionic/p-6e1fa025.js +4 -0
- package/dist/ionic/{p-6ad90d41.entry.js → p-6e5eeb35.entry.js} +1 -1
- package/dist/ionic/{p-f7ccf8d9.entry.js → p-6f6d56f1.entry.js} +1 -1
- package/dist/ionic/{p-e1819aee.js → p-6fd26009.js} +1 -1
- package/dist/ionic/{p-11bb459e.system.entry.js → p-70218e28.system.entry.js} +1 -1
- package/dist/ionic/{p-d47a1a78.system.entry.js → p-72bc2484.system.entry.js} +1 -1
- package/dist/ionic/{p-acf70e64.system.entry.js → p-7541ca9f.system.entry.js} +1 -1
- package/dist/ionic/{p-34d0f143.system.entry.js → p-7665bbbc.system.entry.js} +1 -1
- package/dist/ionic/{p-1d545773.entry.js → p-77982637.entry.js} +1 -1
- package/dist/ionic/{p-0a8a78db.system.entry.js → p-780ff3b5.system.entry.js} +1 -1
- package/dist/ionic/{p-415ccddd.entry.js → p-7a3fa32c.entry.js} +1 -1
- package/dist/ionic/{p-9f84474d.entry.js → p-7b44b443.entry.js} +1 -1
- package/dist/ionic/p-7cc01684.js +4 -0
- package/dist/ionic/{p-2d7624d4.system.js → p-816476b0.system.js} +1 -1
- package/dist/ionic/{p-b434ded7.system.entry.js → p-81869a97.system.entry.js} +1 -1
- package/dist/ionic/{p-97248203.system.entry.js → p-82f5375e.system.entry.js} +1 -1
- package/dist/ionic/{p-d3f79a49.js → p-842777af.js} +1 -1
- package/dist/ionic/{p-1a4db355.system.entry.js → p-85464e28.system.entry.js} +2 -2
- package/dist/ionic/{p-9d795c4b.entry.js → p-85cb4733.entry.js} +1 -1
- package/dist/ionic/{p-fd783a38.system.entry.js → p-874510e9.system.entry.js} +1 -1
- package/dist/ionic/{p-d7c78a97.system.entry.js → p-8aeed464.system.entry.js} +1 -1
- package/dist/ionic/p-8ba5912c.entry.js +4 -0
- package/dist/ionic/{p-72fa96bf.system.js → p-8d602214.system.js} +1 -1
- package/dist/ionic/{p-640fac4a.system.entry.js → p-8e3ee444.system.entry.js} +1 -1
- package/dist/ionic/{p-892e2567.system.entry.js → p-8e83b7f1.system.entry.js} +1 -1
- package/dist/ionic/{p-1e07fdb2.system.entry.js → p-91a72ad6.system.entry.js} +1 -1
- package/dist/ionic/p-9382ebab.entry.js +4 -0
- package/dist/ionic/{p-3209217f.entry.js → p-942c19cb.entry.js} +1 -1
- package/dist/ionic/{p-eb9803e9.system.js → p-95e14c7b.system.js} +1 -1
- package/dist/ionic/{p-d13689a6.entry.js → p-96391c0e.entry.js} +1 -1
- package/dist/ionic/{p-80704be1.entry.js → p-97135baa.entry.js} +1 -1
- package/dist/ionic/p-a06af32c.system.js +4 -0
- package/dist/ionic/{p-446f3909.system.entry.js → p-a375c9f6.system.entry.js} +1 -1
- package/dist/ionic/{p-93e79b55.js → p-a58ec401.js} +1 -1
- package/dist/ionic/p-a5b7a286.entry.js +4 -0
- package/dist/ionic/{p-31e02742.system.js → p-a71dc777.system.js} +1 -1
- package/dist/ionic/{p-174856b4.system.js → p-a8cc0027.system.js} +1 -1
- package/dist/ionic/{p-c8d61b6c.system.entry.js → p-aaca8dd4.system.entry.js} +1 -1
- package/dist/ionic/{p-2dcf2ec2.system.entry.js → p-ad2b216a.system.entry.js} +1 -1
- package/dist/ionic/{p-ef636601.entry.js → p-add93c7a.entry.js} +1 -1
- package/dist/ionic/{p-ab427719.entry.js → p-afcd4f49.entry.js} +1 -1
- package/dist/ionic/{p-94f85e19.system.entry.js → p-b1a9e85a.system.entry.js} +1 -1
- package/dist/ionic/{p-dd7c79ce.system.entry.js → p-b4bb9cd0.system.entry.js} +1 -1
- package/dist/ionic/{p-d8643420.system.entry.js → p-baa409f1.system.entry.js} +1 -1
- package/dist/ionic/{p-8b8b900d.entry.js → p-bcb58446.entry.js} +1 -1
- package/dist/ionic/p-c2336a9e.system.entry.js +4 -0
- package/dist/ionic/{p-1deadb7f.system.js → p-c38c5dfc.system.js} +1 -1
- package/dist/ionic/{p-5d530ae5.entry.js → p-c3a2e5cc.entry.js} +1 -1
- package/dist/ionic/{p-c6dbc089.system.entry.js → p-c5b77291.system.entry.js} +1 -1
- package/dist/ionic/{p-b2d58604.system.entry.js → p-cb0e4100.system.entry.js} +1 -1
- package/dist/ionic/{p-6dbea874.system.entry.js → p-cb3f2ab6.system.entry.js} +1 -1
- package/dist/ionic/{p-bca27ea7.entry.js → p-cbc3840e.entry.js} +1 -1
- package/dist/ionic/{p-4bbc949f.system.entry.js → p-cd366840.system.entry.js} +1 -1
- package/dist/ionic/{p-60a92a48.system.entry.js → p-cf852615.system.entry.js} +1 -1
- package/dist/ionic/{p-174b0d50.system.entry.js → p-d4d0538c.system.entry.js} +1 -1
- package/dist/ionic/{p-993da5df.entry.js → p-d504bc71.entry.js} +1 -1
- package/dist/ionic/{p-0dca0eee.system.entry.js → p-da83d833.system.entry.js} +1 -1
- package/dist/ionic/{p-4dfe0487.system.entry.js → p-dcfc297d.system.entry.js} +1 -1
- package/dist/ionic/{p-5f9fbad0.entry.js → p-ddc4e717.entry.js} +1 -1
- package/dist/ionic/{p-d7dc29c5.entry.js → p-ded27993.entry.js} +1 -1
- package/dist/ionic/{p-4b3a4938.entry.js → p-df7ea05d.entry.js} +1 -1
- package/dist/ionic/p-e15eda82.system.js +4 -0
- package/dist/ionic/{p-d84c9fc4.entry.js → p-e38b3c29.entry.js} +1 -1
- package/dist/ionic/{p-6d659d62.entry.js → p-e470466e.entry.js} +1 -1
- package/dist/ionic/{p-12b55b00.system.entry.js → p-ebe0be94.system.entry.js} +1 -1
- package/dist/ionic/{p-89ca4c4b.system.js → p-eec92f77.system.js} +1 -1
- package/dist/ionic/{p-7e185a31.entry.js → p-ef99a759.entry.js} +1 -1
- package/dist/ionic/{p-2b3544ad.entry.js → p-f16bfd53.entry.js} +1 -1
- package/dist/ionic/{p-df6a1571.entry.js → p-f3d6085c.entry.js} +1 -1
- package/dist/ionic/{p-3807cd45.system.entry.js → p-f6a6b7ef.system.entry.js} +1 -1
- package/dist/ionic/{p-ef9736b9.entry.js → p-f71082f7.entry.js} +1 -1
- package/dist/ionic/{p-3c51cf97.system.entry.js → p-f7ed6a44.system.entry.js} +1 -1
- package/dist/ionic/{p-0dfbbdbe.entry.js → p-fc5ddbf6.entry.js} +1 -1
- package/dist/ionic/{p-f7c3d736.system.entry.js → p-fd94dd20.system.entry.js} +1 -1
- package/dist/ionic/{p-6aeb0272.entry.js → p-feb66f6f.entry.js} +1 -1
- package/dist/types/components/menu/menu.d.ts +0 -2
- package/dist/types/utils/focus-trap.d.ts +35 -0
- package/dist/types/utils/overlays.d.ts +0 -6
- package/hydrate/index.js +223 -114
- package/package.json +1 -1
- package/dist/collection/components/modal/test/a11y/modal.spec.js +0 -22
- package/dist/esm-es5/app-globals-5cf6195b.js +0 -4
- package/dist/esm-es5/md.transition-c9761eef.js +0 -4
- package/dist/esm-es5/overlays-c69d2a07.js +0 -4
- package/dist/ionic/p-0f25a7bb.system.js +0 -4
- package/dist/ionic/p-0f81df5e.entry.js +0 -4
- package/dist/ionic/p-17082c91.system.js +0 -4
- package/dist/ionic/p-2c768965.entry.js +0 -4
- package/dist/ionic/p-32fb7d95.entry.js +0 -4
- package/dist/ionic/p-4e7abe76.js +0 -4
- package/dist/ionic/p-5dbf7222.entry.js +0 -4
- package/dist/ionic/p-75861cd3.entry.js +0 -4
- package/dist/ionic/p-90b3e3b0.system.entry.js +0 -4
- package/dist/ionic/p-96107183.js +0 -4
- package/dist/ionic/p-986a47ee.system.entry.js +0 -4
- package/dist/ionic/p-9c93fdcd.js +0 -4
- package/dist/ionic/p-9ecc1e42.entry.js +0 -4
- package/dist/ionic/p-cd0ffc8c.entry.js +0 -4
- package/dist/ionic/p-df504a37.system.js +0 -4
- package/dist/ionic/p-e755046f.system.entry.js +0 -4
|
@@ -41,3 +41,24 @@ configs().forEach(({ title, screenshot, config }) => {
|
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
|
+
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
45
|
+
test.describe(title('input: item functionality'), () => {
|
|
46
|
+
test('clicking padded space within item should focus the input', async ({ page }) => {
|
|
47
|
+
await page.setContent(`
|
|
48
|
+
<ion-item>
|
|
49
|
+
<ion-input label="Input"></ion-input>
|
|
50
|
+
</ion-item>
|
|
51
|
+
`, config);
|
|
52
|
+
const itemNative = page.locator('.item-native');
|
|
53
|
+
const input = page.locator('ion-input input');
|
|
54
|
+
// Clicks the padded space within the item
|
|
55
|
+
await itemNative.click({
|
|
56
|
+
position: {
|
|
57
|
+
x: 5,
|
|
58
|
+
y: 5,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
await expect(input).toBeFocused();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -199,7 +199,7 @@ export class Item {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
getFirstInteractive() {
|
|
202
|
-
const controls = this.el.querySelectorAll('ion-toggle:not([disabled]), ion-checkbox:not([disabled]), ion-radio:not([disabled]), ion-select:not([disabled])');
|
|
202
|
+
const controls = this.el.querySelectorAll('ion-toggle:not([disabled]), ion-checkbox:not([disabled]), ion-radio:not([disabled]), ion-select:not([disabled]), ion-input:not([disabled]), ion-textarea:not([disabled])');
|
|
203
203
|
return controls[0];
|
|
204
204
|
}
|
|
205
205
|
render() {
|
|
@@ -241,7 +241,17 @@ export class Item {
|
|
|
241
241
|
*/
|
|
242
242
|
const clickedWithinShadowRoot = this.el.shadowRoot.contains(target);
|
|
243
243
|
if (clickedWithinShadowRoot) {
|
|
244
|
-
|
|
244
|
+
/**
|
|
245
|
+
* For input/textarea clicking the padding should focus the
|
|
246
|
+
* text field (thus making it editable). For everything else,
|
|
247
|
+
* we want to click the control so it activates.
|
|
248
|
+
*/
|
|
249
|
+
if (firstInteractive.tagName === 'ION-INPUT' || firstInteractive.tagName === 'ION-TEXTAREA') {
|
|
250
|
+
firstInteractive.setFocus();
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
firstInteractive.click();
|
|
254
|
+
}
|
|
245
255
|
}
|
|
246
256
|
}
|
|
247
257
|
}
|
|
@@ -255,25 +265,29 @@ export class Item {
|
|
|
255
265
|
const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null;
|
|
256
266
|
const fillValue = fill || 'none';
|
|
257
267
|
const inList = hostContext('ion-list', this.el) && !hostContext('ion-radio-group', this.el);
|
|
258
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Inputs and textareas do not need to show a cursor pointer.
|
|
270
|
+
* However, other form controls such as checkboxes and radios do.
|
|
271
|
+
*/
|
|
272
|
+
const firstInteractiveNeedsPointerCursor = firstInteractive !== undefined && !['ION-INPUT', 'ION-TEXTAREA'].includes(firstInteractive.tagName);
|
|
273
|
+
return (h(Host, { key: 'cea10ae44ddc3ac8ebcee481f2696bae900a3a34', "aria-disabled": ariaDisabled, class: Object.assign(Object.assign(Object.assign({}, childStyles), labelColorStyles), createColorClasses(this.color, {
|
|
259
274
|
item: true,
|
|
260
275
|
[mode]: true,
|
|
261
276
|
'item-lines-default': lines === undefined,
|
|
262
277
|
[`item-lines-${lines}`]: lines !== undefined,
|
|
263
278
|
[`item-fill-${fillValue}`]: true,
|
|
264
279
|
[`item-shape-${shape}`]: shape !== undefined,
|
|
265
|
-
'item-
|
|
280
|
+
'item-control-needs-pointer-cursor': firstInteractiveNeedsPointerCursor,
|
|
266
281
|
'item-disabled': disabled,
|
|
267
282
|
'in-list': inList,
|
|
268
283
|
'item-multiple-inputs': this.multipleInputs,
|
|
269
284
|
'ion-activatable': canActivate,
|
|
270
285
|
'ion-focusable': this.focusable,
|
|
271
286
|
'item-rtl': document.dir === 'rtl',
|
|
272
|
-
})), role: inList ? 'listitem' : null }, h(TagType, Object.assign({ key: '
|
|
287
|
+
})), role: inList ? 'listitem' : null }, h(TagType, Object.assign({ key: '48fd3c900652d21d364c738ceb328101dfce6260' }, attrs, inheritedAriaAttributes, { class: "item-native", part: "native", disabled: disabled }, clickFn), h("slot", { key: 'd6f1e007a969f60977789f4cca3d2a8a3f52dd70', name: "start" }), h("div", { key: '0a8fafdaf5171ab073890532d65dd96aa9d2aa86', class: "item-inner" }, h("div", { key: '063bd8f3d87b8efee1f97582cb212db8dc502bf4', class: "input-wrapper" }, h("slot", { key: '18276aad72ef4e91c1a5d6f368729589f9b50205' })), h("slot", { key: '39e365fbd888084b54b58811a44c6ae019801d92', name: "end" }), showDetail && (h("ion-icon", { icon: detailIcon, lazy: false, class: "item-detail-icon", part: "detail-icon", "aria-hidden": "true", "flip-rtl": detailIcon === chevronForward })), h("div", { key: '96daef747b2ba84fe8206c332624a90640ecc448', class: "item-inner-highlight" })), canActivate && mode === 'md' && h("ion-ripple-effect", null), h("div", { key: 'e6d77ef9da1b7a6e530ba37e37f51aa8e1102460', class: "item-highlight" })), h("div", { key: '20223b90730b563bb38edd5f3769b2b7607d8097', class: "item-bottom" }, h("slot", { key: '4657f1f0a57ddc5e136473d98a93e91eed00ec19', name: "error" }), h("slot", { key: '37a5acffe53d3e6a472cc2fac1548362b236cad8', name: "helper" }), counterString && h("ion-note", { class: "item-counter" }, counterString))));
|
|
273
288
|
}
|
|
274
289
|
static get is() { return "ion-item"; }
|
|
275
290
|
static get encapsulation() { return "shadow"; }
|
|
276
|
-
static get delegatesFocus() { return true; }
|
|
277
291
|
static get originalStyleUrls() {
|
|
278
292
|
return {
|
|
279
293
|
"ios": ["item.ios.scss"],
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
background: var(--ion-color-contrast);
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
:host(.item-
|
|
192
|
+
:host(.item-control-needs-pointer-cursor) {
|
|
193
193
|
cursor: pointer;
|
|
194
194
|
}
|
|
195
195
|
|
|
@@ -872,13 +872,13 @@ ion-ripple-effect {
|
|
|
872
872
|
}
|
|
873
873
|
|
|
874
874
|
::slotted([slot=start]) {
|
|
875
|
-
-webkit-margin-end:
|
|
876
|
-
margin-inline-end:
|
|
875
|
+
-webkit-margin-end: 16px;
|
|
876
|
+
margin-inline-end: 16px;
|
|
877
877
|
}
|
|
878
878
|
|
|
879
879
|
::slotted([slot=end]) {
|
|
880
|
-
-webkit-margin-start:
|
|
881
|
-
margin-inline-start:
|
|
880
|
+
-webkit-margin-start: 16px;
|
|
881
|
+
margin-inline-start: 16px;
|
|
882
882
|
}
|
|
883
883
|
|
|
884
884
|
:host(.item-fill-solid) ::slotted([slot=start]),
|
|
@@ -942,16 +942,6 @@ ion-ripple-effect {
|
|
|
942
942
|
padding-bottom: 10px;
|
|
943
943
|
}
|
|
944
944
|
|
|
945
|
-
::slotted(ion-note[slot=start]) {
|
|
946
|
-
-webkit-padding-end: 16px;
|
|
947
|
-
padding-inline-end: 16px;
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
::slotted(ion-note[slot=end]) {
|
|
951
|
-
-webkit-padding-start: 16px;
|
|
952
|
-
padding-inline-start: 16px;
|
|
953
|
-
}
|
|
954
|
-
|
|
955
945
|
::slotted(ion-avatar) {
|
|
956
946
|
width: 40px;
|
|
957
947
|
height: 40px;
|
|
@@ -290,13 +290,13 @@
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
::slotted([slot=start]) {
|
|
293
|
-
-webkit-margin-end:
|
|
294
|
-
margin-inline-end:
|
|
293
|
+
-webkit-margin-end: 16px;
|
|
294
|
+
margin-inline-end: 16px;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
297
|
::slotted([slot=end]) {
|
|
298
|
-
-webkit-margin-start:
|
|
299
|
-
margin-inline-start:
|
|
298
|
+
-webkit-margin-start: 16px;
|
|
299
|
+
margin-inline-start: 16px;
|
|
300
300
|
}
|
|
301
301
|
|
|
302
302
|
::slotted(ion-label) {
|
|
@@ -346,16 +346,6 @@
|
|
|
346
346
|
padding-bottom: 10px;
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
-
::slotted(ion-note[slot=start]) {
|
|
350
|
-
-webkit-padding-end: 16px;
|
|
351
|
-
padding-inline-end: 16px;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
::slotted(ion-note[slot=end]) {
|
|
355
|
-
-webkit-padding-start: 16px;
|
|
356
|
-
padding-inline-start: 16px;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
349
|
::slotted(ion-avatar) {
|
|
360
350
|
width: 40px;
|
|
361
351
|
height: 40px;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Build, Host, h } from "@stencil/core";
|
|
5
5
|
import { getTimeGivenProgression } from "../../utils/animation/cubic-bezier";
|
|
6
|
+
import { focusFirstDescendant, focusLastDescendant } from "../../utils/focus-trap";
|
|
6
7
|
import { GESTURE_CONTROLLER } from "../../utils/gesture/index";
|
|
7
8
|
import { shoudUseCloseWatcher } from "../../utils/hardware-back-button";
|
|
8
9
|
import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from "../../utils/helpers";
|
|
@@ -15,7 +16,6 @@ const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
|
|
|
15
16
|
const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
|
|
16
17
|
const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
|
|
17
18
|
const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
|
|
18
|
-
const focusableQueryString = '[tabindex]:not([tabindex^="-"]), input:not([type=hidden]):not([tabindex^="-"]), textarea:not([tabindex^="-"]), button:not([tabindex^="-"]), select:not([tabindex^="-"]), .ion-focusable:not([tabindex^="-"])';
|
|
19
19
|
/**
|
|
20
20
|
* @part container - The container for the menu content.
|
|
21
21
|
* @part backdrop - The backdrop that appears over the main content when the menu is open.
|
|
@@ -253,27 +253,6 @@ export class Menu {
|
|
|
253
253
|
setOpen(shouldOpen, animated = true) {
|
|
254
254
|
return menuController._setOpen(this, shouldOpen, animated);
|
|
255
255
|
}
|
|
256
|
-
focusFirstDescendant() {
|
|
257
|
-
const { el } = this;
|
|
258
|
-
const firstInput = el.querySelector(focusableQueryString);
|
|
259
|
-
if (firstInput) {
|
|
260
|
-
firstInput.focus();
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
el.focus();
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
focusLastDescendant() {
|
|
267
|
-
const { el } = this;
|
|
268
|
-
const inputs = Array.from(el.querySelectorAll(focusableQueryString));
|
|
269
|
-
const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
|
|
270
|
-
if (lastInput) {
|
|
271
|
-
lastInput.focus();
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
el.focus();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
256
|
trapKeyboardFocus(ev, doc) {
|
|
278
257
|
const target = ev.target;
|
|
279
258
|
if (!target) {
|
|
@@ -291,13 +270,14 @@ export class Menu {
|
|
|
291
270
|
* Otherwise, we are about to have focus go out of the menu.
|
|
292
271
|
* Wrap the focus to either the first or last element.
|
|
293
272
|
*/
|
|
273
|
+
const { el } = this;
|
|
294
274
|
/**
|
|
295
275
|
* Once we call `focusFirstDescendant`, another focus event
|
|
296
276
|
* will fire, which will cause `lastFocus` to be updated
|
|
297
277
|
* before we can run the code after that. We cache the value
|
|
298
278
|
* here to avoid that.
|
|
299
279
|
*/
|
|
300
|
-
|
|
280
|
+
focusFirstDescendant(el);
|
|
301
281
|
/**
|
|
302
282
|
* If the cached last focused element is the same as the now-
|
|
303
283
|
* active element, that means the user was on the first element
|
|
@@ -305,7 +285,7 @@ export class Menu {
|
|
|
305
285
|
* last descendant.
|
|
306
286
|
*/
|
|
307
287
|
if (this.lastFocus === doc.activeElement) {
|
|
308
|
-
|
|
288
|
+
focusLastDescendant(el);
|
|
309
289
|
}
|
|
310
290
|
}
|
|
311
291
|
}
|
|
@@ -606,14 +586,14 @@ export class Menu {
|
|
|
606
586
|
* the ionBackButton listener in the menu controller
|
|
607
587
|
* will handle closing the menu when Escape is pressed.
|
|
608
588
|
*/
|
|
609
|
-
return (h(Host, { key: '
|
|
589
|
+
return (h(Host, { key: 'b75052668f8384e55009d5a9f436f2de590bf2c3', onKeyDown: shoudUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
|
|
610
590
|
[mode]: true,
|
|
611
591
|
[`menu-type-${type}`]: true,
|
|
612
592
|
'menu-enabled': !disabled,
|
|
613
593
|
[`menu-side-${side}`]: true,
|
|
614
594
|
'menu-pane-visible': isPaneVisible,
|
|
615
595
|
'split-pane-side': hostContext('ion-split-pane', el),
|
|
616
|
-
} }, h("div", { key: '
|
|
596
|
+
} }, h("div", { key: 'd500486fe03917b9115fa399921d73f95602d14e', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, h("slot", { key: '2078b5b36210658681980be69b8dc791e0b7dd96' })), h("ion-backdrop", { key: 'c43171d0f0804c0430b319de54e80c38d1768c80', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
|
|
617
597
|
}
|
|
618
598
|
static get is() { return "ion-menu"; }
|
|
619
599
|
static get encapsulation() { return "shadow"; }
|
|
@@ -131,9 +131,41 @@ export class Modal {
|
|
|
131
131
|
this.triggerController.removeClickListener();
|
|
132
132
|
}
|
|
133
133
|
componentWillLoad() {
|
|
134
|
-
const { breakpoints, initialBreakpoint, el } = this;
|
|
134
|
+
const { breakpoints, initialBreakpoint, el, htmlAttributes } = this;
|
|
135
135
|
const isSheetModal = (this.isSheetModal = breakpoints !== undefined && initialBreakpoint !== undefined);
|
|
136
|
-
|
|
136
|
+
const attributesToInherit = ['aria-label', 'role'];
|
|
137
|
+
this.inheritedAttributes = inheritAttributes(el, attributesToInherit);
|
|
138
|
+
/**
|
|
139
|
+
* When using a controller modal you can set attributes
|
|
140
|
+
* using the htmlAttributes property. Since the above attributes
|
|
141
|
+
* need to be inherited inside of the modal, we need to look
|
|
142
|
+
* and see if these attributes are being set via htmlAttributes.
|
|
143
|
+
*
|
|
144
|
+
* We could alternatively move this to componentDidLoad to simplify the work
|
|
145
|
+
* here, but we'd then need to make inheritedAttributes a State variable,
|
|
146
|
+
* thus causing another render to always happen after the first render.
|
|
147
|
+
*/
|
|
148
|
+
if (htmlAttributes !== undefined) {
|
|
149
|
+
attributesToInherit.forEach((attribute) => {
|
|
150
|
+
const attributeValue = htmlAttributes[attribute];
|
|
151
|
+
if (attributeValue) {
|
|
152
|
+
/**
|
|
153
|
+
* If an attribute we need to inherit was
|
|
154
|
+
* set using htmlAttributes then add it to
|
|
155
|
+
* inheritedAttributes and remove it from htmlAttributes.
|
|
156
|
+
* This ensures the attribute is inherited and not
|
|
157
|
+
* set on the host.
|
|
158
|
+
*
|
|
159
|
+
* In this case, if an inherited attribute is set
|
|
160
|
+
* on the host element and using htmlAttributes then
|
|
161
|
+
* htmlAttributes wins, but that's not a pattern that we recommend.
|
|
162
|
+
* The only time you'd need htmlAttributes is when using modalController.
|
|
163
|
+
*/
|
|
164
|
+
this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [attribute]: htmlAttributes[attribute] });
|
|
165
|
+
delete htmlAttributes[attribute];
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
137
169
|
if (isSheetModal) {
|
|
138
170
|
this.currentBreakpoint = this.initialBreakpoint;
|
|
139
171
|
}
|
|
@@ -530,9 +562,9 @@ export class Modal {
|
|
|
530
562
|
const mode = getIonMode(this);
|
|
531
563
|
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
|
532
564
|
const isHandleCycle = handleBehavior === 'cycle';
|
|
533
|
-
return (h(Host, Object.assign({ key: '
|
|
565
|
+
return (h(Host, Object.assign({ key: 'dbd61751e4964ad81fc1dee19468b716d4f23c8a', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
534
566
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
535
|
-
}, 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: '
|
|
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: 'a7646a7a7aeef7eef1bb647373f509d4a26036ad', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && h("div", { class: "modal-shadow" }), h("div", Object.assign({ key: 'bc6bc6ff7d2357206265240eaa76d730a0ecfd2c',
|
|
536
568
|
/*
|
|
537
569
|
role and aria-modal must be used on the
|
|
538
570
|
same element. They must also be set inside the
|
|
@@ -541,7 +573,7 @@ export class Modal {
|
|
|
541
573
|
*/
|
|
542
574
|
role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (h("button", { class: "modal-handle",
|
|
543
575
|
// Prevents the handle from receiving keyboard focus when it does not cycle
|
|
544
|
-
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: '
|
|
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: '0ce06b895deb1da5fbdefa65b079dbd1ada349f7' }))));
|
|
545
577
|
}
|
|
546
578
|
static get is() { return "ion-modal"; }
|
|
547
579
|
static get encapsulation() { return "shadow"; }
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { Modal } from "../modal";
|
|
7
|
+
it('should inherit attributes', async () => {
|
|
8
|
+
/**
|
|
9
|
+
* Note: This example should not be used in production.
|
|
10
|
+
* This only serves to check that `role` can be customized.
|
|
11
|
+
*/
|
|
12
|
+
const page = await newSpecPage({
|
|
13
|
+
components: [Modal],
|
|
14
|
+
template: () => h("ion-modal", { overlayIndex: 1, "aria-label": "my label", role: "presentation" }),
|
|
15
|
+
});
|
|
16
|
+
const modal = page.body.querySelector('ion-modal');
|
|
17
|
+
const contentWrapper = modal.shadowRoot.querySelector('[part="content"]');
|
|
18
|
+
expect(contentWrapper.getAttribute('aria-label')).toBe('my label');
|
|
19
|
+
expect(contentWrapper.getAttribute('role')).toBe('presentation');
|
|
20
|
+
});
|
|
21
|
+
it('should inherit attributes when set via htmlAttributes', async () => {
|
|
22
|
+
const page = await newSpecPage({
|
|
23
|
+
components: [Modal],
|
|
24
|
+
template: () => (h("ion-modal", { overlayIndex: 1, htmlAttributes: { 'aria-label': 'my label', role: 'presentation' } })),
|
|
25
|
+
});
|
|
26
|
+
const modal = page.body.querySelector('ion-modal');
|
|
27
|
+
const contentWrapper = modal.shadowRoot.querySelector('[part="content"]');
|
|
28
|
+
expect(contentWrapper.getAttribute('aria-label')).toBe('my label');
|
|
29
|
+
expect(contentWrapper.getAttribute('role')).toBe('presentation');
|
|
30
|
+
expect(modal.hasAttribute('aria-label')).toBe(false);
|
|
31
|
+
expect(modal.hasAttribute('role')).toBe(false);
|
|
32
|
+
});
|
|
@@ -267,6 +267,13 @@ export class PickerColumn {
|
|
|
267
267
|
* height of 0px.
|
|
268
268
|
*/
|
|
269
269
|
componentWillLoad() {
|
|
270
|
+
/**
|
|
271
|
+
* We cache parentEl in a local variable
|
|
272
|
+
* so we don't need to keep accessing
|
|
273
|
+
* the class variable (which comes with
|
|
274
|
+
* a small performance hit)
|
|
275
|
+
*/
|
|
276
|
+
const parentEl = (this.parentEl = this.el.closest('ion-picker'));
|
|
270
277
|
const visibleCallback = (entries) => {
|
|
271
278
|
const ev = entries[0];
|
|
272
279
|
if (ev.isIntersecting) {
|
|
@@ -294,8 +301,16 @@ export class PickerColumn {
|
|
|
294
301
|
}
|
|
295
302
|
}
|
|
296
303
|
};
|
|
297
|
-
|
|
298
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Set the root to be the parent picker element
|
|
306
|
+
* This causes the IO callback
|
|
307
|
+
* to be fired in WebKit as soon as the element
|
|
308
|
+
* is visible. If we used the default root value
|
|
309
|
+
* then WebKit would only fire the IO callback
|
|
310
|
+
* after any animations (such as a modal transition)
|
|
311
|
+
* finished, and there would potentially be a flicker.
|
|
312
|
+
*/
|
|
313
|
+
new IntersectionObserver(visibleCallback, { threshold: 0.001, root: this.parentEl }).observe(this.el);
|
|
299
314
|
if (parentEl !== null) {
|
|
300
315
|
// TODO(FW-2832): type
|
|
301
316
|
parentEl.addEventListener('ionInputModeChange', (ev) => this.inputModeChange(ev));
|
|
@@ -364,14 +379,14 @@ export class PickerColumn {
|
|
|
364
379
|
render() {
|
|
365
380
|
const { color, disabled, isActive, numericInput } = this;
|
|
366
381
|
const mode = getIonMode(this);
|
|
367
|
-
return (h(Host, { key: '
|
|
382
|
+
return (h(Host, { key: '0b055a464237262bab4d99b2de320c9ea1312f29', class: createColorClasses(color, {
|
|
368
383
|
[mode]: true,
|
|
369
384
|
['picker-column-active']: isActive,
|
|
370
385
|
['picker-column-numeric-input']: numericInput,
|
|
371
386
|
['picker-column-disabled']: disabled,
|
|
372
|
-
}) }, h("slot", { key: '
|
|
387
|
+
}) }, h("slot", { key: 'a162598e503c1f4eef59dbadaa5ecc11dc45d82c', name: "prefix" }), h("div", { key: '23f0370a1639adcdacde40fc59ced3cd49fc8e91', class: "picker-opts", tabindex: disabled ? undefined : 0, ref: (el) => {
|
|
373
388
|
this.scrollEl = el;
|
|
374
|
-
} }, h("div", { key: '
|
|
389
|
+
} }, h("div", { key: '9b86b9b11a53f06b3afea9b76ecca9344e025bc4', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: 'c95a1998f3d4c13ca60b81f0de01f1f5811d86df', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '04381e68d992a247a38942aea307d1f863876eb5', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("slot", { key: '379fda12a9e49c5616e590deb9ddaea908fbed9b' }), h("div", { key: 'c911bf19f4bb531d1ca46d1b3f9d6286d0ac3801', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '9dc907617ad53c1542d492ab1d60c986dd869348', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), h("div", { key: '219691c9c450dd1eecaf1304eac5870dad1d76e8', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), h("slot", { key: '8471ea689166cd864ad0fcdb959b7a9db15dfb8d', name: "suffix" })));
|
|
375
390
|
}
|
|
376
391
|
static get is() { return "ion-picker-column"; }
|
|
377
392
|
static get encapsulation() { return "shadow"; }
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
3
|
*/
|
|
4
4
|
import { Host, h } from "@stencil/core";
|
|
5
|
+
import { focusFirstDescendant } from "../../utils/focus-trap";
|
|
5
6
|
import { CoreDelegate, attachComponent, detachComponent } from "../../utils/framework-delegate";
|
|
6
7
|
import { addEventListener, raf, hasLazyBuild } from "../../utils/helpers";
|
|
7
8
|
import { createLockController } from "../../utils/lock-controller";
|
|
8
9
|
import { printIonWarning } from "../../utils/logging/index";
|
|
9
|
-
import { BACKDROP, dismiss, eventMethod,
|
|
10
|
+
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present, setOverlayId } from "../../utils/overlays";
|
|
10
11
|
import { isPlatform } from "../../utils/platform";
|
|
11
12
|
import { getClassMap } from "../../utils/theme";
|
|
12
13
|
import { deepReady, waitForMount } from "../../utils/transition/index";
|
|
@@ -269,7 +270,7 @@ export class Popover {
|
|
|
269
270
|
* descendant inside of the popover.
|
|
270
271
|
*/
|
|
271
272
|
if (this.focusDescendantOnPresent) {
|
|
272
|
-
focusFirstDescendant(
|
|
273
|
+
focusFirstDescendant(el);
|
|
273
274
|
}
|
|
274
275
|
unlock();
|
|
275
276
|
}
|
|
@@ -335,9 +336,9 @@ export class Popover {
|
|
|
335
336
|
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes } = this;
|
|
336
337
|
const desktop = isPlatform('desktop');
|
|
337
338
|
const enableArrow = arrow && !parentPopover;
|
|
338
|
-
return (h(Host, Object.assign({ key: '
|
|
339
|
+
return (h(Host, Object.assign({ key: 'a4a6fb333562cb2ecc2ac2350541de9be61837af', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
|
|
339
340
|
zIndex: `${20000 + this.overlayIndex}`,
|
|
340
|
-
}, 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", { tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: '
|
|
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", { tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), h("div", { key: 'de9c7ad73f221e6e9a55e2bc7e1ffad7b936b0dd', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && h("div", { class: "popover-arrow", part: "arrow" }), h("div", { key: '1cb5abc9835c044e6d14d444283f34b65b0b134e', class: "popover-content", part: "content" }, h("slot", { key: '0e4db95e6341e823f87877325bb1164193ae6676' })))));
|
|
341
342
|
}
|
|
342
343
|
static get is() { return "ion-popover"; }
|
|
343
344
|
static get encapsulation() { return "shadow"; }
|
|
@@ -41,3 +41,24 @@ configs().forEach(({ title, screenshot, config }) => {
|
|
|
41
41
|
});
|
|
42
42
|
});
|
|
43
43
|
});
|
|
44
|
+
configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
|
|
45
|
+
test.describe(title('textarea: item functionality'), () => {
|
|
46
|
+
test('clicking padded space within item should focus the textarea', async ({ page }) => {
|
|
47
|
+
await page.setContent(`
|
|
48
|
+
<ion-item>
|
|
49
|
+
<ion-textarea label="Textarea"></ion-textarea>
|
|
50
|
+
</ion-item>
|
|
51
|
+
`, config);
|
|
52
|
+
const itemNative = page.locator('.item-native');
|
|
53
|
+
const textarea = page.locator('ion-textarea textarea');
|
|
54
|
+
// Clicks the padded space within the item
|
|
55
|
+
await itemNative.click({
|
|
56
|
+
position: {
|
|
57
|
+
x: 5,
|
|
58
|
+
y: 5,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
await expect(textarea).toBeFocused();
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* (C) Ionic http://ionicframework.com - MIT License
|
|
3
|
+
*/
|
|
4
|
+
import { focusVisibleElement } from "./helpers";
|
|
5
|
+
/**
|
|
6
|
+
* This query string selects elements that
|
|
7
|
+
* are eligible to receive focus. We select
|
|
8
|
+
* interactive elements that meet the following
|
|
9
|
+
* criteria:
|
|
10
|
+
* 1. Element does not have a negative tabindex
|
|
11
|
+
* 2. Element does not have `hidden`
|
|
12
|
+
* 3. Element does not have `disabled` for non-Ionic components.
|
|
13
|
+
* 4. Element does not have `disabled` or `disabled="true"` for Ionic components.
|
|
14
|
+
* Note: We need this distinction because `disabled="false"` is
|
|
15
|
+
* valid usage for the disabled property on ion-button.
|
|
16
|
+
*/
|
|
17
|
+
export const focusableQueryString = '[tabindex]:not([tabindex^="-"]):not([hidden]):not([disabled]), input:not([type=hidden]):not([tabindex^="-"]):not([hidden]):not([disabled]), textarea:not([tabindex^="-"]):not([hidden]):not([disabled]), button:not([tabindex^="-"]):not([hidden]):not([disabled]), select:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable[disabled="false"]:not([tabindex^="-"]):not([hidden])';
|
|
18
|
+
/**
|
|
19
|
+
* Focuses the first descendant in a context
|
|
20
|
+
* that can receive focus. If none exists,
|
|
21
|
+
* a fallback element will be focused.
|
|
22
|
+
* This fallback is typically an ancestor
|
|
23
|
+
* container such as a menu or overlay so focus does not
|
|
24
|
+
* leave the container we are trying to trap focus in.
|
|
25
|
+
*
|
|
26
|
+
* If no fallback is specified then we focus the container itself.
|
|
27
|
+
*/
|
|
28
|
+
export const focusFirstDescendant = (ref, fallbackElement) => {
|
|
29
|
+
const firstInput = ref.querySelector(focusableQueryString);
|
|
30
|
+
focusElementInContext(firstInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Focuses the last descendant in a context
|
|
34
|
+
* that can receive focus. If none exists,
|
|
35
|
+
* a fallback element will be focused.
|
|
36
|
+
* This fallback is typically an ancestor
|
|
37
|
+
* container such as a menu or overlay so focus does not
|
|
38
|
+
* leave the container we are trying to trap focus in.
|
|
39
|
+
*
|
|
40
|
+
* If no fallback is specified then we focus the container itself.
|
|
41
|
+
*/
|
|
42
|
+
export const focusLastDescendant = (ref, fallbackElement) => {
|
|
43
|
+
const inputs = Array.from(ref.querySelectorAll(focusableQueryString));
|
|
44
|
+
const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
|
|
45
|
+
focusElementInContext(lastInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Focuses a particular element in a context. If the element
|
|
49
|
+
* doesn't have anything focusable associated with it then
|
|
50
|
+
* a fallback element will be focused.
|
|
51
|
+
*
|
|
52
|
+
* This fallback is typically an ancestor
|
|
53
|
+
* container such as a menu or overlay so focus does not
|
|
54
|
+
* leave the container we are trying to trap focus in.
|
|
55
|
+
* This should be used instead of the focus() method
|
|
56
|
+
* on most elements because the focusable element
|
|
57
|
+
* may not be the host element.
|
|
58
|
+
*
|
|
59
|
+
* For example, if an ion-button should be focused
|
|
60
|
+
* then we should actually focus the native <button>
|
|
61
|
+
* element inside of ion-button's shadow root, not
|
|
62
|
+
* the host element itself.
|
|
63
|
+
*/
|
|
64
|
+
const focusElementInContext = (hostToFocus, fallbackElement) => {
|
|
65
|
+
let elementToFocus = hostToFocus;
|
|
66
|
+
const shadowRoot = hostToFocus === null || hostToFocus === void 0 ? void 0 : hostToFocus.shadowRoot;
|
|
67
|
+
if (shadowRoot) {
|
|
68
|
+
// If there are no inner focusable elements, just focus the host element.
|
|
69
|
+
elementToFocus = shadowRoot.querySelector(focusableQueryString) || hostToFocus;
|
|
70
|
+
}
|
|
71
|
+
if (elementToFocus) {
|
|
72
|
+
focusVisibleElement(elementToFocus);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Focus fallback element instead of letting focus escape
|
|
76
|
+
fallbackElement.focus();
|
|
77
|
+
}
|
|
78
|
+
};
|
|
@@ -29,7 +29,14 @@ export const startInputShims = async (config, platform) => {
|
|
|
29
29
|
const keyboardHeight = config.getNumber('keyboardHeight', 290);
|
|
30
30
|
const scrollAssist = config.getBoolean('scrollAssist', true);
|
|
31
31
|
const hideCaret = config.getBoolean('hideCaretOnScroll', isIOS);
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* The team is evaluating if inputBlurring is still needed. As a result
|
|
34
|
+
* this feature is disabled by default as of Ionic 8.0. Developers are
|
|
35
|
+
* able to re-enable it temporarily. The team may remove this utility
|
|
36
|
+
* if it is determined that doing so would not bring any adverse side effects.
|
|
37
|
+
* TODO FW-6014 remove input blurring utility (including implementation)
|
|
38
|
+
*/
|
|
39
|
+
const inputBlurring = config.getBoolean('inputBlurring', false);
|
|
33
40
|
const scrollPadding = config.getBoolean('scrollPadding', true);
|
|
34
41
|
const inputs = Array.from(doc.querySelectorAll('ion-input, ion-textarea'));
|
|
35
42
|
const hideCaretMap = new WeakMap();
|