@ionic/core 7.5.2-dev.11697818830.1a33c881 → 7.5.2-dev.11698187124.1b7ea660

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/components/action-sheet.js +2 -2
  2. package/components/alert.js +2 -2
  3. package/components/animation.js +18 -3
  4. package/components/index8.js +0 -1
  5. package/components/input-shims.js +9 -1
  6. package/components/ion-input.js +11 -4
  7. package/components/ion-menu.js +3 -3
  8. package/components/ion-refresher.js +8 -1
  9. package/components/ion-searchbar.js +9 -2
  10. package/components/ion-select.js +2 -2
  11. package/components/ion-textarea.js +11 -4
  12. package/components/radio.js +0 -1
  13. package/components/watch-options.js +14 -3
  14. package/dist/cjs/{animation-c8bdd3c7.js → animation-1083855c.js} +18 -3
  15. package/dist/cjs/{index-eccba000.js → index-174dc666.js} +2 -2
  16. package/dist/cjs/{index-5e7529f6.js → index-5a2463aa.js} +1 -1
  17. package/dist/cjs/{index-10873539.js → index-da2c7a37.js} +0 -1
  18. package/dist/cjs/index.cjs.js +5 -5
  19. package/dist/cjs/{input-shims-da7dc0de.js → input-shims-b0a75a01.js} +10 -2
  20. package/dist/cjs/ion-action-sheet.cjs.entry.js +3 -3
  21. package/dist/cjs/ion-alert.cjs.entry.js +3 -3
  22. package/dist/cjs/ion-app_8.cjs.entry.js +4 -4
  23. package/dist/cjs/ion-datetime_3.cjs.entry.js +1 -1
  24. package/dist/cjs/ion-infinite-scroll_2.cjs.entry.js +1 -1
  25. package/dist/cjs/ion-input.cjs.entry.js +10 -3
  26. package/dist/cjs/ion-item-option_3.cjs.entry.js +2 -2
  27. package/dist/cjs/ion-loading.cjs.entry.js +1 -1
  28. package/dist/cjs/ion-menu_3.cjs.entry.js +5 -5
  29. package/dist/cjs/ion-modal.cjs.entry.js +3 -3
  30. package/dist/cjs/ion-nav_2.cjs.entry.js +1 -1
  31. package/dist/cjs/ion-popover.cjs.entry.js +2 -2
  32. package/dist/cjs/ion-radio_2.cjs.entry.js +0 -1
  33. package/dist/cjs/ion-range.cjs.entry.js +1 -1
  34. package/dist/cjs/ion-refresher_2.cjs.entry.js +10 -3
  35. package/dist/cjs/ion-reorder_2.cjs.entry.js +1 -1
  36. package/dist/cjs/ion-searchbar.cjs.entry.js +8 -1
  37. package/dist/cjs/ion-select_3.cjs.entry.js +3 -3
  38. package/dist/cjs/ion-textarea.cjs.entry.js +10 -3
  39. package/dist/cjs/ion-toast.cjs.entry.js +1 -1
  40. package/dist/cjs/ionic.cjs.js +1 -1
  41. package/dist/cjs/{ios.transition-5af5991e.js → ios.transition-74ad019b.js} +2 -2
  42. package/dist/cjs/{md.transition-1e740a6a.js → md.transition-efcc0ad3.js} +2 -2
  43. package/dist/cjs/{status-tap-778e8054.js → status-tap-b19eb3c8.js} +1 -1
  44. package/dist/cjs/{watch-options-f3f77e54.js → watch-options-53bbb124.js} +14 -3
  45. package/dist/collection/collection-manifest.json +1 -1
  46. package/dist/collection/components/action-sheet/action-sheet.ios.css +16 -3
  47. package/dist/collection/components/action-sheet/action-sheet.md.css +16 -3
  48. package/dist/collection/components/alert/alert.ios.css +18 -5
  49. package/dist/collection/components/alert/alert.md.css +18 -5
  50. package/dist/collection/components/input/input.ios.css +14 -14
  51. package/dist/collection/components/input/input.js +9 -2
  52. package/dist/collection/components/input/input.md.css +4 -16
  53. package/dist/collection/components/menu/menu.js +3 -3
  54. package/dist/collection/components/radio/radio.js +5 -2
  55. package/dist/collection/components/radio/test/legacy/a11y/radio.e2e.js +5 -5
  56. package/dist/collection/components/refresher/refresher.utils.js +8 -1
  57. package/dist/collection/components/searchbar/searchbar.js +9 -2
  58. package/dist/collection/components/select/select.ios.css +14 -11
  59. package/dist/collection/components/select/select.md.css +4 -13
  60. package/dist/collection/components/textarea/textarea.ios.css +18 -18
  61. package/dist/collection/components/textarea/textarea.js +9 -2
  62. package/dist/collection/components/textarea/textarea.md.css +14 -20
  63. package/dist/collection/utils/animation/animation.js +18 -3
  64. package/dist/collection/utils/content/index.js +0 -1
  65. package/dist/collection/utils/input-shims/hacks/common.js +9 -1
  66. package/dist/collection/utils/watch-options.js +14 -3
  67. package/dist/docs.json +2 -2
  68. package/dist/esm/{animation-92066c62.js → animation-8aa13916.js} +18 -3
  69. package/dist/esm/{index-746a238e.js → index-4392efa5.js} +0 -1
  70. package/dist/esm/{index-df55802d.js → index-aae132ba.js} +1 -1
  71. package/dist/esm/{index-a09eac70.js → index-ec72506a.js} +2 -2
  72. package/dist/esm/index.js +5 -5
  73. package/dist/esm/{input-shims-d78a3c77.js → input-shims-d0c93e5d.js} +10 -2
  74. package/dist/esm/ion-action-sheet.entry.js +3 -3
  75. package/dist/esm/ion-alert.entry.js +3 -3
  76. package/dist/esm/ion-app_8.entry.js +4 -4
  77. package/dist/esm/ion-datetime_3.entry.js +1 -1
  78. package/dist/esm/ion-infinite-scroll_2.entry.js +1 -1
  79. package/dist/esm/ion-input.entry.js +11 -4
  80. package/dist/esm/ion-item-option_3.entry.js +2 -2
  81. package/dist/esm/ion-loading.entry.js +1 -1
  82. package/dist/esm/ion-menu_3.entry.js +5 -5
  83. package/dist/esm/ion-modal.entry.js +3 -3
  84. package/dist/esm/ion-nav_2.entry.js +1 -1
  85. package/dist/esm/ion-popover.entry.js +2 -2
  86. package/dist/esm/ion-radio_2.entry.js +0 -1
  87. package/dist/esm/ion-range.entry.js +1 -1
  88. package/dist/esm/ion-refresher_2.entry.js +10 -3
  89. package/dist/esm/ion-reorder_2.entry.js +1 -1
  90. package/dist/esm/ion-searchbar.entry.js +9 -2
  91. package/dist/esm/ion-select_3.entry.js +3 -3
  92. package/dist/esm/ion-textarea.entry.js +11 -4
  93. package/dist/esm/ion-toast.entry.js +1 -1
  94. package/dist/esm/ionic.js +1 -1
  95. package/dist/esm/{ios.transition-4d1322d6.js → ios.transition-f1cea7e0.js} +2 -2
  96. package/dist/esm/{md.transition-66b425d0.js → md.transition-1bf39c32.js} +2 -2
  97. package/dist/esm/{status-tap-9aeeaca5.js → status-tap-4e96ecf3.js} +1 -1
  98. package/dist/esm/{watch-options-355a920a.js → watch-options-02d8498b.js} +14 -3
  99. package/dist/esm-es5/animation-8aa13916.js +4 -0
  100. package/dist/esm-es5/{index-df55802d.js → index-aae132ba.js} +1 -1
  101. package/dist/esm-es5/{index-a09eac70.js → index-ec72506a.js} +1 -1
  102. package/dist/esm-es5/index.js +1 -1
  103. package/dist/esm-es5/{input-shims-d78a3c77.js → input-shims-d0c93e5d.js} +1 -1
  104. package/dist/esm-es5/ion-action-sheet.entry.js +1 -1
  105. package/dist/esm-es5/ion-alert.entry.js +1 -1
  106. package/dist/esm-es5/ion-app_8.entry.js +1 -1
  107. package/dist/esm-es5/ion-datetime_3.entry.js +1 -1
  108. package/dist/esm-es5/ion-infinite-scroll_2.entry.js +1 -1
  109. package/dist/esm-es5/ion-input.entry.js +1 -1
  110. package/dist/esm-es5/ion-item-option_3.entry.js +1 -1
  111. package/dist/esm-es5/ion-loading.entry.js +1 -1
  112. package/dist/esm-es5/ion-menu_3.entry.js +1 -1
  113. package/dist/esm-es5/ion-modal.entry.js +1 -1
  114. package/dist/esm-es5/ion-nav_2.entry.js +1 -1
  115. package/dist/esm-es5/ion-popover.entry.js +1 -1
  116. package/dist/esm-es5/ion-range.entry.js +1 -1
  117. package/dist/esm-es5/ion-refresher_2.entry.js +1 -1
  118. package/dist/esm-es5/ion-reorder_2.entry.js +1 -1
  119. package/dist/esm-es5/ion-searchbar.entry.js +1 -1
  120. package/dist/esm-es5/ion-select_3.entry.js +1 -1
  121. package/dist/esm-es5/ion-textarea.entry.js +1 -1
  122. package/dist/esm-es5/ion-toast.entry.js +1 -1
  123. package/dist/esm-es5/{ios.transition-4d1322d6.js → ios.transition-f1cea7e0.js} +1 -1
  124. package/dist/esm-es5/{md.transition-66b425d0.js → md.transition-1bf39c32.js} +1 -1
  125. package/dist/esm-es5/{status-tap-9aeeaca5.js → status-tap-4e96ecf3.js} +1 -1
  126. package/dist/esm-es5/{watch-options-355a920a.js → watch-options-02d8498b.js} +1 -1
  127. package/dist/ionic/index.esm.js +1 -1
  128. package/dist/ionic/ionic.esm.js +1 -1
  129. package/dist/ionic/ionic.js +1 -1
  130. package/dist/ionic/{p-0e3b9926.entry.js → p-0362c48a.entry.js} +1 -1
  131. package/dist/ionic/{p-d29dcf9b.system.entry.js → p-07989b03.system.entry.js} +1 -1
  132. package/dist/ionic/{p-f15c9fd3.system.entry.js → p-0c0d536f.system.entry.js} +1 -1
  133. package/dist/ionic/p-0e0b3668.system.entry.js +4 -0
  134. package/dist/ionic/{p-755b2917.system.js → p-0fb53284.system.js} +1 -1
  135. package/dist/ionic/p-15e6ef90.system.entry.js +4 -0
  136. package/dist/ionic/{p-97afc3e8.system.entry.js → p-1676eeff.system.entry.js} +1 -1
  137. package/dist/ionic/{p-ecb860e5.system.entry.js → p-2222b68a.system.entry.js} +2 -2
  138. package/dist/ionic/{p-5f2cd7d2.system.entry.js → p-23410b18.system.entry.js} +1 -1
  139. package/dist/ionic/{p-5db56c84.system.entry.js → p-26d0ec66.system.entry.js} +1 -1
  140. package/dist/ionic/p-2debdac3.entry.js +4 -0
  141. package/dist/ionic/p-2e8e0045.js +4 -0
  142. package/dist/ionic/{p-7d3fe69c.system.entry.js → p-306d845d.system.entry.js} +1 -1
  143. package/dist/ionic/{p-8e24ebbc.js → p-311d91cc.js} +1 -1
  144. package/dist/ionic/{p-bc08029e.system.entry.js → p-3574440a.system.entry.js} +1 -1
  145. package/dist/ionic/p-3602001b.system.js +4 -0
  146. package/dist/ionic/p-498f031c.entry.js +4 -0
  147. package/dist/ionic/p-4a329bd3.entry.js +4 -0
  148. package/dist/ionic/{p-cbc8d5c6.entry.js → p-4e70a7cc.entry.js} +1 -1
  149. package/dist/ionic/{p-1f81b5be.entry.js → p-4e9114af.entry.js} +1 -1
  150. package/dist/ionic/{p-de68588d.js → p-507845ca.js} +1 -1
  151. package/dist/ionic/{p-c87827ca.system.js → p-5aac9314.system.js} +1 -1
  152. package/dist/ionic/{p-7d58a178.entry.js → p-5c92c941.entry.js} +1 -1
  153. package/dist/ionic/p-5fba0b2d.entry.js +4 -0
  154. package/dist/ionic/{p-e028178a.system.js → p-62b29300.system.js} +1 -1
  155. package/dist/ionic/p-62bfd4cb.system.entry.js +4 -0
  156. package/dist/ionic/{p-091c8792.system.js → p-664d1430.system.js} +1 -1
  157. package/dist/ionic/{p-b132c2c0.system.js → p-67eecef4.system.js} +1 -1
  158. package/dist/ionic/{p-00853890.system.entry.js → p-68f78c9b.system.entry.js} +1 -1
  159. package/dist/ionic/p-70263330.entry.js +4 -0
  160. package/dist/ionic/{p-33e10fbe.system.entry.js → p-79d430f7.system.entry.js} +1 -1
  161. package/dist/ionic/{p-62e7d4fa.js → p-79fdc224.js} +1 -1
  162. package/dist/ionic/{p-496a045c.entry.js → p-83198481.entry.js} +1 -1
  163. package/dist/ionic/{p-35b26732.entry.js → p-892710a8.entry.js} +1 -1
  164. package/dist/ionic/{p-2a40090a.system.entry.js → p-8fdd6396.system.entry.js} +1 -1
  165. package/dist/ionic/{p-446230d7.js → p-97c65aa5.js} +1 -1
  166. package/dist/ionic/{p-bd68ea5d.entry.js → p-99eba967.entry.js} +1 -1
  167. package/dist/ionic/p-9d166dc1.js +4 -0
  168. package/dist/ionic/{p-3bc2289f.system.entry.js → p-9ebd9c24.system.entry.js} +1 -1
  169. package/dist/ionic/{p-c49672d8.system.js → p-b216de09.system.js} +1 -1
  170. package/dist/ionic/p-b9a17fcb.system.entry.js +4 -0
  171. package/dist/ionic/{p-2a8eeef7.system.js → p-be7fcb09.system.js} +1 -1
  172. package/dist/ionic/{p-ad48dd13.system.js → p-c50ea33f.system.js} +1 -1
  173. package/dist/ionic/{p-0f10b5f5.system.entry.js → p-c6cae705.system.entry.js} +1 -1
  174. package/dist/ionic/p-c842da0a.js +4 -0
  175. package/dist/ionic/p-ce56d7b5.system.entry.js +4 -0
  176. package/dist/ionic/p-d3ba42e6.system.entry.js +4 -0
  177. package/dist/ionic/{p-a3fe2e01.entry.js → p-db0140c0.entry.js} +1 -1
  178. package/dist/ionic/{p-0f217f27.entry.js → p-df189fa7.entry.js} +1 -1
  179. package/dist/ionic/{p-803cd5c3.entry.js → p-e552cf80.entry.js} +1 -1
  180. package/dist/ionic/{p-c679fcb5.entry.js → p-f089f3b1.entry.js} +1 -1
  181. package/dist/ionic/p-f10de93b.js +4 -0
  182. package/dist/ionic/p-f1e15f7a.entry.js +4 -0
  183. package/dist/ionic/p-f4bd51c5.entry.js +4 -0
  184. package/dist/ionic/{p-2d8caacb.entry.js → p-f5e7ed0e.entry.js} +1 -1
  185. package/dist/ionic/{p-e0f0d55f.system.js → p-fe08d5d6.system.js} +1 -1
  186. package/dist/types/components/radio/radio.d.ts +1 -1
  187. package/dist/types/components.d.ts +625 -1
  188. package/dist/types/stencil-public-runtime.d.ts +2 -0
  189. package/dist/types/utils/content/index.d.ts +1 -1
  190. package/dist/types/utils/focus-visible.d.ts +3 -2
  191. package/dist/types/utils/watch-options.d.ts +9 -1
  192. package/hydrate/index.js +95 -40
  193. package/package.json +2 -2
  194. package/dist/esm-es5/animation-92066c62.js +0 -4
  195. package/dist/ionic/p-0001660a.system.entry.js +0 -4
  196. package/dist/ionic/p-015187e5.system.js +0 -4
  197. package/dist/ionic/p-1d17ce29.system.entry.js +0 -4
  198. package/dist/ionic/p-1f260a7b.entry.js +0 -4
  199. package/dist/ionic/p-29b56db6.system.entry.js +0 -4
  200. package/dist/ionic/p-35e399bd.entry.js +0 -4
  201. package/dist/ionic/p-4eb15462.entry.js +0 -4
  202. package/dist/ionic/p-54200074.entry.js +0 -4
  203. package/dist/ionic/p-5bf16a18.js +0 -4
  204. package/dist/ionic/p-79aeaba4.system.entry.js +0 -4
  205. package/dist/ionic/p-9825577f.system.entry.js +0 -4
  206. package/dist/ionic/p-9f2e0db9.js +0 -4
  207. package/dist/ionic/p-a38ec116.entry.js +0 -4
  208. package/dist/ionic/p-a46ca692.entry.js +0 -4
  209. package/dist/ionic/p-c44fe9fd.js +0 -4
  210. package/dist/ionic/p-e1d13a71.system.entry.js +0 -4
  211. package/dist/ionic/p-e81634c7.entry.js +0 -4
  212. package/dist/ionic/p-eb7d0922.js +0 -4
  213. /package/dist/esm-es5/{index-746a238e.js → index-4392efa5.js} +0 -0
  214. /package/dist/ionic/{p-b24aa895.js → p-114a36ed.js} +0 -0
  215. /package/dist/ionic/{p-64475ab5.system.js → p-8a308596.system.js} +0 -0
@@ -122,12 +122,25 @@
122
122
  overscroll-behavior-y: contain;
123
123
  }
124
124
 
125
- .alert-checkbox-group::-webkit-scrollbar,
126
- .alert-radio-group::-webkit-scrollbar,
127
- .alert-message::-webkit-scrollbar {
128
- display: none;
125
+ /**
126
+ * Scrollbars on mobile devices will be hidden.
127
+ * Users can still scroll the content by swiping.
128
+ * If a user has a fine pointing device, such as a
129
+ * mouse or trackpad, then scrollbars will be
130
+ * visible. This allows users to scroll the
131
+ * content with their pointing device.
132
+ * Otherwise, the user would have to use the
133
+ * keyboard to navigate through the options.
134
+ * This may not be intuitive for users who
135
+ * are not familiar with keyboard navigation.
136
+ */
137
+ @media (any-pointer: coarse) {
138
+ .alert-checkbox-group::-webkit-scrollbar,
139
+ .alert-radio-group::-webkit-scrollbar,
140
+ .alert-message::-webkit-scrollbar {
141
+ display: none;
142
+ }
129
143
  }
130
-
131
144
  .alert-input {
132
145
  padding-left: 0;
133
146
  padding-right: 0;
@@ -122,12 +122,25 @@
122
122
  overscroll-behavior-y: contain;
123
123
  }
124
124
 
125
- .alert-checkbox-group::-webkit-scrollbar,
126
- .alert-radio-group::-webkit-scrollbar,
127
- .alert-message::-webkit-scrollbar {
128
- display: none;
125
+ /**
126
+ * Scrollbars on mobile devices will be hidden.
127
+ * Users can still scroll the content by swiping.
128
+ * If a user has a fine pointing device, such as a
129
+ * mouse or trackpad, then scrollbars will be
130
+ * visible. This allows users to scroll the
131
+ * content with their pointing device.
132
+ * Otherwise, the user would have to use the
133
+ * keyboard to navigate through the options.
134
+ * This may not be intuitive for users who
135
+ * are not familiar with keyboard navigation.
136
+ */
137
+ @media (any-pointer: coarse) {
138
+ .alert-checkbox-group::-webkit-scrollbar,
139
+ .alert-radio-group::-webkit-scrollbar,
140
+ .alert-message::-webkit-scrollbar {
141
+ display: none;
142
+ }
129
143
  }
130
-
131
144
  .alert-input {
132
145
  padding-left: 0;
133
146
  padding-right: 0;
@@ -121,20 +121,6 @@
121
121
  --highlight-color-focused: var(--ion-color-base);
122
122
  }
123
123
 
124
- :host(:not(.legacy-input)) {
125
- min-height: 44px;
126
- }
127
-
128
- /**
129
- * Since the label sits on top of the element,
130
- * the component needs to be taller otherwise the
131
- * label will appear too close to the input text.
132
- */
133
- :host(.input-label-placement-floating),
134
- :host(.input-label-placement-stacked) {
135
- min-height: 56px;
136
- }
137
-
138
124
  .native-input {
139
125
  padding-left: 0;
140
126
  padding-right: 0;
@@ -734,6 +720,20 @@
734
720
  height: 18px;
735
721
  }
736
722
 
723
+ :host(:not(.legacy-input)) {
724
+ min-height: 44px;
725
+ }
726
+
727
+ /**
728
+ * Since the label sits on top of the element,
729
+ * the component needs to be taller otherwise the
730
+ * label will appear too close to the input text.
731
+ */
732
+ :host(.input-label-placement-floating),
733
+ :host(.input-label-placement-stacked) {
734
+ min-height: 56px;
735
+ }
736
+
737
737
  :host(.legacy-input) .native-input[disabled],
738
738
  :host(.input-disabled) {
739
739
  opacity: 0.3;
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { Build, Host, forceUpdate, h } from "@stencil/core";
5
5
  import { createLegacyFormController, createNotchController } from "../../utils/forms/index";
6
- import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes } from "../../utils/helpers";
6
+ import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes, componentOnReady, } from "../../utils/helpers";
7
7
  import { printIonWarning } from "../../utils/logging/index";
8
8
  import { createSlotMutationController } from "../../utils/slot-mutation-controller";
9
9
  import { createColorClasses, hostContext } from "../../utils/theme";
@@ -207,7 +207,14 @@ export class Input {
207
207
  /**
208
208
  * Returns the native `<input>` element used under the hood.
209
209
  */
210
- getInputElement() {
210
+ async getInputElement() {
211
+ /**
212
+ * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
213
+ * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
214
+ */
215
+ if (!this.nativeInput) {
216
+ await new Promise((resolve) => componentOnReady(this.el, resolve));
217
+ }
211
218
  return Promise.resolve(this.nativeInput);
212
219
  }
213
220
  /**
@@ -121,20 +121,6 @@
121
121
  --highlight-color-focused: var(--ion-color-base);
122
122
  }
123
123
 
124
- :host(:not(.legacy-input)) {
125
- min-height: 44px;
126
- }
127
-
128
- /**
129
- * Since the label sits on top of the element,
130
- * the component needs to be taller otherwise the
131
- * label will appear too close to the input text.
132
- */
133
- :host(.input-label-placement-floating),
134
- :host(.input-label-placement-stacked) {
135
- min-height: 56px;
136
- }
137
-
138
124
  .native-input {
139
125
  padding-left: 0;
140
126
  padding-right: 0;
@@ -748,7 +734,6 @@
748
734
  --border-radius: 4px;
749
735
  --padding-start: 16px;
750
736
  --padding-end: 16px;
751
- min-height: 56px;
752
737
  }
753
738
 
754
739
  /**
@@ -867,7 +852,6 @@
867
852
  --border-radius: 4px;
868
853
  --padding-start: 16px;
869
854
  --padding-end: 16px;
870
- min-height: 56px;
871
855
  }
872
856
 
873
857
  :host(.input-fill-outline.input-shape-round) {
@@ -1198,6 +1182,10 @@
1198
1182
  letter-spacing: 0.0333333333em;
1199
1183
  }
1200
1184
 
1185
+ :host(:not(.legacy-input)) {
1186
+ min-height: 56px;
1187
+ }
1188
+
1201
1189
  /**
1202
1190
  * When the input is focused the label should
1203
1191
  * take on the highlight color. This should
@@ -343,11 +343,11 @@ export class Menu {
343
343
  this.animation = undefined;
344
344
  }
345
345
  // Create new animation
346
- this.animation = await menuController._createAnimation(this.type, this);
346
+ const animation = (this.animation = await menuController._createAnimation(this.type, this));
347
347
  if (!config.getBoolean('animated', true)) {
348
- this.animation.duration(0);
348
+ animation.duration(0);
349
349
  }
350
- this.animation.fill('both');
350
+ animation.fill('both');
351
351
  }
352
352
  async startAnimation(shouldOpen, animated) {
353
353
  const isReversed = !shouldOpen;
@@ -85,7 +85,6 @@ export class Radio {
85
85
  }
86
86
  /** @internal */
87
87
  async setFocus(ev) {
88
- // TODO(FW-2832): type (using Event triggers a build error due to conflict with Stencil Event import)
89
88
  ev.stopPropagation();
90
89
  ev.preventDefault();
91
90
  this.el.focus();
@@ -416,7 +415,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
416
415
  return {
417
416
  "setFocus": {
418
417
  "complexType": {
419
- "signature": "(ev: any) => Promise<void>",
418
+ "signature": "(ev: globalThis.Event) => Promise<void>",
420
419
  "parameters": [{
421
420
  "tags": [],
422
421
  "text": ""
@@ -425,6 +424,10 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
425
424
  "Promise": {
426
425
  "location": "global",
427
426
  "id": "global::Promise"
427
+ },
428
+ "globalThis": {
429
+ "location": "global",
430
+ "id": "global::globalThis"
428
431
  }
429
432
  },
430
433
  "return": "Promise<void>"
@@ -8,9 +8,11 @@ import { configs, test } from "../../../../../utils/test/playwright/index";
8
8
  */
9
9
  configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => {
10
10
  test.describe(title('radio: a11y'), () => {
11
- // TODO(FW-5218)
12
- test.fixme('tabbing should switch between radio groups', async ({ page, pageUtils }) => {
11
+ test.beforeEach(async ({ page, skip }) => {
12
+ skip.browser('webkit', 'Tabbing is flaky in Safari');
13
13
  await page.goto(`/src/components/radio/test/legacy/a11y`, config);
14
+ });
15
+ test('tabbing should switch between radio groups', async ({ page, pageUtils }) => {
14
16
  const firstGroupRadios = page.locator('#first-group ion-radio');
15
17
  const secondGroupRadios = page.locator('#second-group ion-radio');
16
18
  await pageUtils.pressKeys('Tab');
@@ -20,9 +22,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
20
22
  await pageUtils.pressKeys('shift+Tab');
21
23
  await expect(firstGroupRadios.nth(0)).toBeFocused();
22
24
  });
23
- // TODO(FW-5218)
24
- test.fixme('using arrow keys should move between enabled radios within group', async ({ page, pageUtils }) => {
25
- await page.goto(`/src/components/radio/test/legacy/a11y`, config);
25
+ test('using arrow keys should move between enabled radios within group', async ({ page, pageUtils }) => {
26
26
  const firstGroupRadios = page.locator('#first-group ion-radio');
27
27
  await pageUtils.pressKeys('Tab');
28
28
  await expect(firstGroupRadios.nth(0)).toBeFocused();
@@ -16,7 +16,6 @@ export const createPullingAnimation = (type, pullingSpinner, refresherEl) => {
16
16
  : createTranslateAnimation(pullingSpinner, refresherEl);
17
17
  };
18
18
  const createBaseAnimation = (pullingRefresherIcon) => {
19
- // TODO(FW-2832): add types/re-evaluate asserting so many things
20
19
  const spinner = pullingRefresherIcon.querySelector('ion-spinner');
21
20
  const circle = spinner.shadowRoot.querySelector('circle');
22
21
  const spinnerArrowContainer = pullingRefresherIcon.querySelector('.spinner-arrow-container');
@@ -173,6 +172,14 @@ export const shouldUseNativeRefresher = async (referenceEl, mode) => {
173
172
  const refreshingSpinner = referenceEl.querySelector('ion-refresher-content .refresher-refreshing ion-spinner');
174
173
  return (pullingSpinner !== null &&
175
174
  refreshingSpinner !== null &&
175
+ /**
176
+ * We use webkitOverflowScrolling for feature detection with rubber band scrolling
177
+ * on iOS. When doing referenceEl.style, webkitOverflowScrolling is undefined on non-iOS platforms.
178
+ * However, it will be the empty string on iOS.
179
+ * Note that we do not use getPropertyValue (and thus need to cast as any) because calling
180
+ * getPropertyValue('-webkit-overflow-scrolling') will return the empty string if it is not
181
+ * set on the element, even if the platform does not support that.
182
+ */
176
183
  ((mode === 'ios' && isPlatform('mobile') && referenceEl.style.webkitOverflowScrolling !== undefined) ||
177
184
  mode === 'md'));
178
185
  };
@@ -2,7 +2,7 @@
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
4
  import { Host, forceUpdate, h } from "@stencil/core";
5
- import { debounceEvent, raf } from "../../utils/helpers";
5
+ import { debounceEvent, raf, componentOnReady } from "../../utils/helpers";
6
6
  import { isRTL } from "../../utils/rtl/index";
7
7
  import { createColorClasses } from "../../utils/theme";
8
8
  import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from "ionicons/icons";
@@ -189,7 +189,14 @@ export class Searchbar {
189
189
  /**
190
190
  * Returns the native `<input>` element used under the hood.
191
191
  */
192
- getInputElement() {
192
+ async getInputElement() {
193
+ /**
194
+ * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
195
+ * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
196
+ */
197
+ if (!this.nativeInput) {
198
+ await new Promise((resolve) => componentOnReady(this.el, resolve));
199
+ }
193
200
  return Promise.resolve(this.nativeInput);
194
201
  }
195
202
  /**
@@ -81,17 +81,6 @@
81
81
 
82
82
  :host(:not(.legacy-select)) {
83
83
  width: 100%;
84
- min-height: 44px;
85
- }
86
-
87
- /**
88
- * Since the label sits on top of the element,
89
- * the component needs to be taller otherwise the
90
- * label will appear too close to the select text.
91
- */
92
- :host(.select-label-placement-floating),
93
- :host(.select-label-placement-stacked) {
94
- min-height: 56px;
95
84
  }
96
85
 
97
86
  :host(.ion-color) {
@@ -632,6 +621,20 @@ button {
632
621
  --padding-start: 16px;
633
622
  }
634
623
 
624
+ :host(:not(.legacy-select)) {
625
+ min-height: 44px;
626
+ }
627
+
628
+ /**
629
+ * Since the label sits on top of the element,
630
+ * the component needs to be taller otherwise the
631
+ * label will appear too close to the select text.
632
+ */
633
+ :host(.select-label-placement-floating),
634
+ :host(.select-label-placement-stacked) {
635
+ min-height: 56px;
636
+ }
637
+
635
638
  .select-icon {
636
639
  width: 1.125rem;
637
640
  height: 1.125rem;
@@ -81,17 +81,6 @@
81
81
 
82
82
  :host(:not(.legacy-select)) {
83
83
  width: 100%;
84
- min-height: 44px;
85
- }
86
-
87
- /**
88
- * Since the label sits on top of the element,
89
- * the component needs to be taller otherwise the
90
- * label will appear too close to the select text.
91
- */
92
- :host(.select-label-placement-floating),
93
- :host(.select-label-placement-stacked) {
94
- min-height: 56px;
95
84
  }
96
85
 
97
86
  :host(.ion-color) {
@@ -664,7 +653,6 @@ button {
664
653
  --border-radius: 4px;
665
654
  --padding-start: 16px;
666
655
  --padding-end: 16px;
667
- min-height: 56px;
668
656
  }
669
657
 
670
658
  /**
@@ -785,7 +773,6 @@ button {
785
773
  --border-radius: 4px;
786
774
  --padding-start: 16px;
787
775
  --padding-end: 16px;
788
- min-height: 56px;
789
776
  }
790
777
 
791
778
  :host(.select-fill-outline.select-shape-round) {
@@ -1040,6 +1027,10 @@ button {
1040
1027
  --padding-start: 16px;
1041
1028
  }
1042
1029
 
1030
+ :host(:not(.legacy-select)) {
1031
+ min-height: 56px;
1032
+ }
1033
+
1043
1034
  .select-icon {
1044
1035
  width: 0.8125rem;
1045
1036
  transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
@@ -88,24 +88,6 @@
88
88
  box-sizing: border-box;
89
89
  }
90
90
 
91
- :host(:not(.legacy-textarea)) {
92
- min-height: 44px;
93
- }
94
-
95
- /**
96
- * Since the label sits on top of the element,
97
- * the component needs to be taller otherwise the
98
- * label will appear too close to the textarea text.
99
- * Also, floating and stacked labels should not
100
- * push the label down since it it
101
- * sits on top of the textarea.
102
- */
103
- :host(.textarea-label-placement-floating),
104
- :host(.textarea-label-placement-stacked) {
105
- --padding-top: 0px;
106
- min-height: 56px;
107
- }
108
-
109
91
  /**
110
92
  * When the cols property is set we should
111
93
  * respect that width instead of defaulting
@@ -844,4 +826,22 @@
844
826
  :host(.legacy-textarea) .native-textarea[disabled],
845
827
  :host(.textarea-disabled) {
846
828
  opacity: 0.3;
829
+ }
830
+
831
+ :host(:not(.legacy-textarea)) {
832
+ min-height: 44px;
833
+ }
834
+
835
+ /**
836
+ * Since the label sits on top of the element,
837
+ * the component needs to be taller otherwise the
838
+ * label will appear too close to the textarea text.
839
+ * Also, floating and stacked labels should not
840
+ * push the label down since it it
841
+ * sits on top of the textarea.
842
+ */
843
+ :host(.textarea-label-placement-floating),
844
+ :host(.textarea-label-placement-stacked) {
845
+ --padding-top: 0px;
846
+ min-height: 56px;
847
847
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import { Build, Host, forceUpdate, h, writeTask, } from "@stencil/core";
5
5
  import { createLegacyFormController, createNotchController } from "../../utils/forms/index";
6
- import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes } from "../../utils/helpers";
6
+ import { inheritAriaAttributes, debounceEvent, findItemLabel, inheritAttributes, componentOnReady, } from "../../utils/helpers";
7
7
  import { printIonWarning } from "../../utils/logging/index";
8
8
  import { createSlotMutationController } from "../../utils/slot-mutation-controller";
9
9
  import { createColorClasses, hostContext } from "../../utils/theme";
@@ -169,7 +169,14 @@ export class Textarea {
169
169
  /**
170
170
  * Returns the native `<textarea>` element used under the hood.
171
171
  */
172
- getInputElement() {
172
+ async getInputElement() {
173
+ /**
174
+ * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
175
+ * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
176
+ */
177
+ if (!this.nativeInput) {
178
+ await new Promise((resolve) => componentOnReady(this.el, resolve));
179
+ }
173
180
  return Promise.resolve(this.nativeInput);
174
181
  }
175
182
  emitStyle() {
@@ -88,24 +88,6 @@
88
88
  box-sizing: border-box;
89
89
  }
90
90
 
91
- :host(:not(.legacy-textarea)) {
92
- min-height: 44px;
93
- }
94
-
95
- /**
96
- * Since the label sits on top of the element,
97
- * the component needs to be taller otherwise the
98
- * label will appear too close to the textarea text.
99
- * Also, floating and stacked labels should not
100
- * push the label down since it it
101
- * sits on top of the textarea.
102
- */
103
- :host(.textarea-label-placement-floating),
104
- :host(.textarea-label-placement-stacked) {
105
- --padding-top: 0px;
106
- min-height: 56px;
107
- }
108
-
109
91
  /**
110
92
  * When the cols property is set we should
111
93
  * respect that width instead of defaulting
@@ -856,7 +838,6 @@
856
838
  --border-radius: 4px;
857
839
  --padding-start: 16px;
858
840
  --padding-end: 16px;
859
- min-height: 56px;
860
841
  }
861
842
 
862
843
  /**
@@ -975,7 +956,6 @@
975
956
  --border-radius: 4px;
976
957
  --padding-start: 16px;
977
958
  --padding-end: 16px;
978
- min-height: 56px;
979
959
  }
980
960
 
981
961
  :host(.textarea-fill-outline.textarea-shape-round) {
@@ -1268,6 +1248,20 @@
1268
1248
  letter-spacing: 0.0333333333em;
1269
1249
  }
1270
1250
 
1251
+ :host(:not(.legacy-textarea)) {
1252
+ min-height: 56px;
1253
+ }
1254
+
1255
+ /**
1256
+ * Floating and stacked labels should not
1257
+ * push the label down since it it
1258
+ * sits on top of the textarea.
1259
+ */
1260
+ :host(.textarea-label-placement-floating),
1261
+ :host(.textarea-label-placement-stacked) {
1262
+ --padding-top: 0px;
1263
+ }
1264
+
1271
1265
  /**
1272
1266
  * When the textarea is focused the label should
1273
1267
  * take on the highlight color. This should
@@ -387,11 +387,25 @@ export const createAnimation = (animationId) => {
387
387
  const updateKeyframes = (keyframeValues) => {
388
388
  if (supportsWebAnimations) {
389
389
  getWebAnimations().forEach((animation) => {
390
- if (animation.effect.setKeyframes) {
391
- animation.effect.setKeyframes(keyframeValues);
390
+ /**
391
+ * animation.effect's type is AnimationEffect.
392
+ * However, in this case we have a more specific
393
+ * type of AnimationEffect called KeyframeEffect which
394
+ * inherits from AnimationEffect. As a result,
395
+ * we cast animation.effect to KeyframeEffect.
396
+ */
397
+ const keyframeEffect = animation.effect;
398
+ /**
399
+ * setKeyframes is not supported in all browser
400
+ * versions that Ionic supports, so we need to
401
+ * check for support before using it.
402
+ */
403
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
404
+ if (keyframeEffect.setKeyframes) {
405
+ keyframeEffect.setKeyframes(keyframeValues);
392
406
  }
393
407
  else {
394
- const newEffect = new KeyframeEffect(animation.effect.target, keyframeValues, animation.effect.getTiming());
408
+ const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
395
409
  animation.effect = newEffect;
396
410
  }
397
411
  });
@@ -536,6 +550,7 @@ export const createAnimation = (animationId) => {
536
550
  step = Math.min(Math.max(step, 0), 0.9999);
537
551
  if (supportsWebAnimations) {
538
552
  webAnimations.forEach((animation) => {
553
+ // When creating the animation the delay is guaranteed to be set to a number.
539
554
  animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
540
555
  animation.pause();
541
556
  });
@@ -58,7 +58,6 @@ export const findClosestIonContent = (el) => {
58
58
  * Scrolls to the top of the element. If an `ion-content` is found, it will scroll
59
59
  * using the public API `scrollToTop` with a duration.
60
60
  */
61
- // TODO(FW-2832): type
62
61
  export const scrollToTop = (el, durationMs) => {
63
62
  if (isIonContent(el)) {
64
63
  const content = el;
@@ -13,8 +13,16 @@ export const relocateInput = (componentEl, inputEl, shouldRelocate, inputRelativ
13
13
  removeClone(componentEl, inputEl);
14
14
  }
15
15
  };
16
- // TODO(FW-2832): type
17
16
  export const isFocused = (input) => {
17
+ /**
18
+ * https://developer.mozilla.org/en-US/docs/Web/API/Node/getRootNode
19
+ * Calling getRootNode on an element in standard web page will return HTMLDocument.
20
+ * Calling getRootNode on an element inside of the Shadow DOM will return the associated ShadowRoot.
21
+ * Calling getRootNode on an element that is not attached to a document/shadow tree will return
22
+ * the root of the DOM tree it belongs to.
23
+ * isFocused is used for the hide-caret utility which only considers input/textarea elements
24
+ * that are present in the DOM, so we don't set types for that final case since it does not apply.
25
+ */
18
26
  return input === input.getRootNode().activeElement;
19
27
  };
20
28
  const addClone = (componentEl, inputEl, inputRelativeY, disabledClonedInput = false) => {
@@ -1,7 +1,6 @@
1
1
  /*!
2
2
  * (C) Ionic http://ionicframework.com - MIT License
3
3
  */
4
- // TODO(FW-2832): types
5
4
  export const watchForOptions = (containerEl, tagName, onChange) => {
6
5
  if (typeof MutationObserver === 'undefined') {
7
6
  return;
@@ -25,10 +24,22 @@ const getSelectedOption = (mutationList, tagName) => {
25
24
  });
26
25
  return newOption;
27
26
  };
28
- export const findCheckedOption = (el, tagName) => {
29
- if (el.nodeType !== 1) {
27
+ /**
28
+ * The "value" key is only set on some components such as ion-select-option.
29
+ * As a result, we create a default union type of HTMLElement and the "value" key.
30
+ * However, implementers are required to provide the appropriate component type
31
+ * such as HTMLIonSelectOptionElement.
32
+ */
33
+ export const findCheckedOption = (node, tagName) => {
34
+ /**
35
+ * https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
36
+ * The above check ensures "node" is an Element (nodeType 1).
37
+ */
38
+ if (node.nodeType !== 1) {
30
39
  return undefined;
31
40
  }
41
+ // HTMLElement inherits from Element, so we cast "el" as T.
42
+ const el = node;
32
43
  const options = el.tagName === tagName.toUpperCase() ? [el] : Array.from(el.querySelectorAll(tagName));
33
44
  return options.find((o) => o.value === el.value);
34
45
  };
package/dist/docs.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
- "timestamp": "2023-10-20T16:22:43",
2
+ "timestamp": "2023-10-24T22:41:46",
3
3
  "compiler": {
4
4
  "name": "@stencil/core",
5
- "version": "4.5.0",
5
+ "version": "4.6.0",
6
6
  "typescriptVersion": "5.2.2"
7
7
  },
8
8
  "components": [
@@ -510,11 +510,25 @@ const createAnimation = (animationId) => {
510
510
  const updateKeyframes = (keyframeValues) => {
511
511
  if (supportsWebAnimations) {
512
512
  getWebAnimations().forEach((animation) => {
513
- if (animation.effect.setKeyframes) {
514
- animation.effect.setKeyframes(keyframeValues);
513
+ /**
514
+ * animation.effect's type is AnimationEffect.
515
+ * However, in this case we have a more specific
516
+ * type of AnimationEffect called KeyframeEffect which
517
+ * inherits from AnimationEffect. As a result,
518
+ * we cast animation.effect to KeyframeEffect.
519
+ */
520
+ const keyframeEffect = animation.effect;
521
+ /**
522
+ * setKeyframes is not supported in all browser
523
+ * versions that Ionic supports, so we need to
524
+ * check for support before using it.
525
+ */
526
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
527
+ if (keyframeEffect.setKeyframes) {
528
+ keyframeEffect.setKeyframes(keyframeValues);
515
529
  }
516
530
  else {
517
- const newEffect = new KeyframeEffect(animation.effect.target, keyframeValues, animation.effect.getTiming());
531
+ const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
518
532
  animation.effect = newEffect;
519
533
  }
520
534
  });
@@ -659,6 +673,7 @@ const createAnimation = (animationId) => {
659
673
  step = Math.min(Math.max(step, 0), 0.9999);
660
674
  if (supportsWebAnimations) {
661
675
  webAnimations.forEach((animation) => {
676
+ // When creating the animation the delay is guaranteed to be set to a number.
662
677
  animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
663
678
  animation.pause();
664
679
  });
@@ -59,7 +59,6 @@ const findClosestIonContent = (el) => {
59
59
  * Scrolls to the top of the element. If an `ion-content` is found, it will scroll
60
60
  * using the public API `scrollToTop` with a duration.
61
61
  */
62
- // TODO(FW-2832): type
63
62
  const scrollToTop = (el, durationMs) => {
64
63
  if (isIonContent(el)) {
65
64
  const content = el;