@cloudscape-design/components 3.0.333 → 3.0.335

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 (345) hide show
  1. package/alert/styles.css.js +19 -19
  2. package/alert/styles.scoped.css +33 -33
  3. package/alert/styles.selectors.js +19 -19
  4. package/annotation-context/annotation/styles.css.js +24 -24
  5. package/annotation-context/annotation/styles.scoped.css +30 -30
  6. package/annotation-context/annotation/styles.selectors.js +24 -24
  7. package/app-layout/index.js +3 -3
  8. package/app-layout/index.js.map +1 -1
  9. package/app-layout/visual-refresh/context.d.ts.map +1 -1
  10. package/app-layout/visual-refresh/context.js +3 -3
  11. package/app-layout/visual-refresh/context.js.map +1 -1
  12. package/app-layout/visual-refresh/styles.css.js +69 -69
  13. package/app-layout/visual-refresh/styles.scoped.css +168 -168
  14. package/app-layout/visual-refresh/styles.selectors.js +69 -69
  15. package/attribute-editor/styles.css.js +14 -14
  16. package/attribute-editor/styles.scoped.css +27 -27
  17. package/attribute-editor/styles.selectors.js +14 -14
  18. package/autosuggest/virtual-list.d.ts.map +1 -1
  19. package/autosuggest/virtual-list.js +2 -2
  20. package/autosuggest/virtual-list.js.map +1 -1
  21. package/badge/styles.css.js +5 -5
  22. package/badge/styles.scoped.css +7 -7
  23. package/badge/styles.selectors.js +5 -5
  24. package/box/styles.css.js +189 -189
  25. package/box/styles.scoped.css +238 -238
  26. package/box/styles.selectors.js +189 -189
  27. package/breadcrumb-group/styles.css.js +7 -7
  28. package/breadcrumb-group/styles.scoped.css +14 -14
  29. package/breadcrumb-group/styles.selectors.js +7 -7
  30. package/button/internal.d.ts.map +1 -1
  31. package/button/internal.js +12 -1
  32. package/button/internal.js.map +1 -1
  33. package/button/styles.css.js +20 -20
  34. package/button/styles.scoped.css +154 -154
  35. package/button/styles.selectors.js +20 -20
  36. package/button-dropdown/index.d.ts.map +1 -1
  37. package/button-dropdown/index.js +2 -2
  38. package/button-dropdown/index.js.map +1 -1
  39. package/button-dropdown/interfaces.d.ts +31 -0
  40. package/button-dropdown/interfaces.d.ts.map +1 -1
  41. package/button-dropdown/interfaces.js.map +1 -1
  42. package/button-dropdown/internal.d.ts.map +1 -1
  43. package/button-dropdown/internal.js +64 -8
  44. package/button-dropdown/internal.js.map +1 -1
  45. package/button-dropdown/mobile-expandable-group/styles.css.js +5 -5
  46. package/button-dropdown/mobile-expandable-group/styles.scoped.css +6 -6
  47. package/button-dropdown/mobile-expandable-group/styles.selectors.js +5 -5
  48. package/button-dropdown/styles.css.js +14 -8
  49. package/button-dropdown/styles.scoped.css +44 -14
  50. package/button-dropdown/styles.selectors.js +14 -8
  51. package/button-dropdown/utils/use-button-dropdown.d.ts +1 -0
  52. package/button-dropdown/utils/use-button-dropdown.d.ts.map +1 -1
  53. package/button-dropdown/utils/use-button-dropdown.js +1 -0
  54. package/button-dropdown/utils/use-button-dropdown.js.map +1 -1
  55. package/calendar/styles.css.js +18 -18
  56. package/calendar/styles.scoped.css +40 -40
  57. package/calendar/styles.selectors.js +18 -18
  58. package/cards/index.js +5 -4
  59. package/cards/index.js.map +1 -1
  60. package/cards/styles.css.js +38 -38
  61. package/cards/styles.scoped.css +55 -55
  62. package/cards/styles.selectors.js +38 -38
  63. package/checkbox/styles.css.js +3 -3
  64. package/checkbox/styles.scoped.css +7 -7
  65. package/checkbox/styles.selectors.js +3 -3
  66. package/code-editor/index.js +2 -2
  67. package/code-editor/index.js.map +1 -1
  68. package/code-editor/status-bar.d.ts.map +1 -1
  69. package/code-editor/status-bar.js +3 -3
  70. package/code-editor/status-bar.js.map +1 -1
  71. package/code-editor/styles.css.js +32 -32
  72. package/code-editor/styles.scoped.css +129 -129
  73. package/code-editor/styles.selectors.js +32 -32
  74. package/collection-preferences/content-display/styles.css.js +11 -11
  75. package/collection-preferences/content-display/styles.scoped.css +19 -19
  76. package/collection-preferences/content-display/styles.selectors.js +11 -11
  77. package/collection-preferences/styles.css.js +37 -37
  78. package/collection-preferences/styles.scoped.css +47 -47
  79. package/collection-preferences/styles.selectors.js +37 -37
  80. package/column-layout/flexible-column-layout/index.d.ts.map +1 -1
  81. package/column-layout/flexible-column-layout/index.js +2 -2
  82. package/column-layout/flexible-column-layout/index.js.map +1 -1
  83. package/column-layout/styles.css.js +13 -13
  84. package/column-layout/styles.scoped.css +44 -44
  85. package/column-layout/styles.selectors.js +13 -13
  86. package/container/styles.css.js +28 -28
  87. package/container/styles.scoped.css +52 -52
  88. package/container/styles.selectors.js +28 -28
  89. package/date-picker/styles.css.js +7 -7
  90. package/date-picker/styles.scoped.css +10 -10
  91. package/date-picker/styles.selectors.js +7 -7
  92. package/date-range-picker/styles.css.js +38 -38
  93. package/date-range-picker/styles.scoped.css +48 -48
  94. package/date-range-picker/styles.selectors.js +38 -38
  95. package/expandable-section/styles.css.js +29 -29
  96. package/expandable-section/styles.scoped.css +65 -65
  97. package/expandable-section/styles.selectors.js +29 -29
  98. package/flashbar/styles.css.js +46 -46
  99. package/flashbar/styles.scoped.css +160 -160
  100. package/flashbar/styles.selectors.js +46 -46
  101. package/form/internal.d.ts.map +1 -1
  102. package/form/internal.js +7 -2
  103. package/form/internal.js.map +1 -1
  104. package/form/styles.css.js +9 -9
  105. package/form/styles.scoped.css +9 -9
  106. package/form/styles.selectors.js +9 -9
  107. package/form-field/internal.d.ts.map +1 -1
  108. package/form-field/internal.js +8 -3
  109. package/form-field/internal.js.map +1 -1
  110. package/form-field/styles.css.js +19 -19
  111. package/form-field/styles.scoped.css +31 -31
  112. package/form-field/styles.selectors.js +19 -19
  113. package/grid/styles.css.js +53 -53
  114. package/grid/styles.scoped.css +55 -55
  115. package/grid/styles.selectors.js +53 -53
  116. package/header/styles.css.js +44 -44
  117. package/header/styles.scoped.css +50 -50
  118. package/header/styles.selectors.js +44 -44
  119. package/help-panel/styles.css.js +4 -4
  120. package/help-panel/styles.scoped.css +70 -69
  121. package/help-panel/styles.selectors.js +4 -4
  122. package/icon/styles.css.js +21 -21
  123. package/icon/styles.scoped.css +50 -50
  124. package/icon/styles.selectors.js +21 -21
  125. package/input/styles.css.js +12 -12
  126. package/input/styles.scoped.css +35 -35
  127. package/input/styles.selectors.js +12 -12
  128. package/internal/analytics/components/analytics-funnel.d.ts.map +1 -1
  129. package/internal/analytics/components/analytics-funnel.js +58 -11
  130. package/internal/analytics/components/analytics-funnel.js.map +1 -1
  131. package/internal/analytics/context/analytics-context.d.ts +5 -1
  132. package/internal/analytics/context/analytics-context.d.ts.map +1 -1
  133. package/internal/analytics/context/analytics-context.js +3 -0
  134. package/internal/analytics/context/analytics-context.js.map +1 -1
  135. package/internal/analytics/hooks/use-funnel.d.ts +3 -0
  136. package/internal/analytics/hooks/use-funnel.d.ts.map +1 -1
  137. package/internal/analytics/hooks/use-funnel.js +7 -2
  138. package/internal/analytics/hooks/use-funnel.js.map +1 -1
  139. package/internal/base-component/styles.scoped.css +8 -7
  140. package/internal/components/button-trigger/styles.css.js +9 -9
  141. package/internal/components/button-trigger/styles.scoped.css +26 -26
  142. package/internal/components/button-trigger/styles.selectors.js +9 -9
  143. package/internal/components/cartesian-chart/labels-measure.d.ts.map +1 -1
  144. package/internal/components/cartesian-chart/labels-measure.js +2 -2
  145. package/internal/components/cartesian-chart/labels-measure.js.map +1 -1
  146. package/internal/components/chart-filter/styles.css.js +3 -3
  147. package/internal/components/chart-filter/styles.scoped.css +4 -4
  148. package/internal/components/chart-filter/styles.selectors.js +3 -3
  149. package/internal/components/chart-legend/styles.css.js +6 -6
  150. package/internal/components/chart-legend/styles.scoped.css +16 -16
  151. package/internal/components/chart-legend/styles.selectors.js +6 -6
  152. package/internal/components/chart-popover/styles.css.js +3 -3
  153. package/internal/components/chart-popover/styles.scoped.css +4 -4
  154. package/internal/components/chart-popover/styles.selectors.js +3 -3
  155. package/internal/components/chart-series-details/styles.css.js +5 -5
  156. package/internal/components/chart-series-details/styles.scoped.css +10 -10
  157. package/internal/components/chart-series-details/styles.selectors.js +5 -5
  158. package/internal/components/chart-series-marker/styles.css.js +5 -5
  159. package/internal/components/chart-series-marker/styles.scoped.css +8 -8
  160. package/internal/components/chart-series-marker/styles.selectors.js +5 -5
  161. package/internal/components/chart-wrapper/styles.css.js +6 -6
  162. package/internal/components/chart-wrapper/styles.scoped.css +9 -9
  163. package/internal/components/chart-wrapper/styles.selectors.js +6 -6
  164. package/internal/components/dropdown/styles.css.js +20 -20
  165. package/internal/components/dropdown/styles.scoped.css +36 -36
  166. package/internal/components/dropdown/styles.selectors.js +20 -20
  167. package/internal/components/dropdown-footer/styles.css.js +3 -3
  168. package/internal/components/dropdown-footer/styles.scoped.css +4 -4
  169. package/internal/components/dropdown-footer/styles.selectors.js +3 -3
  170. package/internal/components/dropdown-status/index.d.ts.map +1 -1
  171. package/internal/components/dropdown-status/index.js +1 -1
  172. package/internal/components/dropdown-status/index.js.map +1 -1
  173. package/internal/components/dropdown-status/styles.css.js +2 -2
  174. package/internal/components/dropdown-status/styles.scoped.css +3 -3
  175. package/internal/components/dropdown-status/styles.selectors.js +2 -2
  176. package/internal/components/menu-dropdown/styles.css.js +7 -7
  177. package/internal/components/menu-dropdown/styles.scoped.css +14 -14
  178. package/internal/components/menu-dropdown/styles.selectors.js +7 -7
  179. package/internal/components/option/styles.css.js +17 -17
  180. package/internal/components/option/styles.scoped.css +31 -31
  181. package/internal/components/option/styles.selectors.js +17 -17
  182. package/internal/components/options-list/styles.css.js +2 -2
  183. package/internal/components/options-list/styles.scoped.css +3 -3
  184. package/internal/components/options-list/styles.selectors.js +2 -2
  185. package/internal/components/selectable-item/styles.css.js +16 -16
  186. package/internal/components/selectable-item/styles.scoped.css +29 -29
  187. package/internal/components/selectable-item/styles.selectors.js +16 -16
  188. package/internal/components/token-list/styles.css.js +9 -9
  189. package/internal/components/token-list/styles.scoped.css +21 -21
  190. package/internal/components/token-list/styles.selectors.js +9 -9
  191. package/internal/environment.js +1 -1
  192. package/internal/generated/theming/index.cjs +24 -13
  193. package/internal/generated/theming/index.js +24 -13
  194. package/internal/hooks/container-queries/index.d.ts +0 -2
  195. package/internal/hooks/container-queries/index.d.ts.map +1 -1
  196. package/internal/hooks/container-queries/index.js +2 -1
  197. package/internal/hooks/container-queries/index.js.map +1 -1
  198. package/internal/hooks/container-queries/use-container-breakpoints.d.ts.map +1 -1
  199. package/internal/hooks/container-queries/use-container-breakpoints.js +2 -2
  200. package/internal/hooks/container-queries/use-container-breakpoints.js.map +1 -1
  201. package/internal/hooks/container-queries/use-resize-observer.d.ts +1 -1
  202. package/internal/hooks/container-queries/use-resize-observer.d.ts.map +1 -1
  203. package/internal/hooks/container-queries/use-resize-observer.js +0 -2
  204. package/internal/hooks/container-queries/use-resize-observer.js.map +1 -1
  205. package/internal/hooks/use-dynamic-overlap/index.js +2 -2
  206. package/internal/hooks/use-dynamic-overlap/index.js.map +1 -1
  207. package/internal/manifest.json +1 -1
  208. package/internal/utils/use-container-width.d.ts.map +1 -1
  209. package/internal/utils/use-container-width.js +5 -3
  210. package/internal/utils/use-container-width.js.map +1 -1
  211. package/link/styles.css.js +20 -20
  212. package/link/styles.scoped.css +73 -73
  213. package/link/styles.selectors.js +20 -20
  214. package/modal/internal.d.ts.map +1 -1
  215. package/modal/internal.js +2 -1
  216. package/modal/internal.js.map +1 -1
  217. package/modal/styles.css.js +23 -23
  218. package/modal/styles.scoped.css +40 -40
  219. package/modal/styles.selectors.js +23 -23
  220. package/multiselect/styles.css.js +1 -1
  221. package/multiselect/styles.scoped.css +2 -2
  222. package/multiselect/styles.selectors.js +1 -1
  223. package/package.json +1 -1
  224. package/pagination/styles.css.js +9 -9
  225. package/pagination/styles.scoped.css +24 -24
  226. package/pagination/styles.selectors.js +9 -9
  227. package/pie-chart/styles.css.js +23 -23
  228. package/pie-chart/styles.scoped.css +42 -42
  229. package/pie-chart/styles.selectors.js +23 -23
  230. package/popover/styles.css.js +50 -50
  231. package/popover/styles.scoped.css +66 -66
  232. package/popover/styles.selectors.js +50 -50
  233. package/progress-bar/styles.css.js +18 -18
  234. package/progress-bar/styles.scoped.css +35 -35
  235. package/progress-bar/styles.selectors.js +18 -18
  236. package/property-filter/index.d.ts.map +1 -1
  237. package/property-filter/index.js +2 -3
  238. package/property-filter/index.js.map +1 -1
  239. package/property-filter/styles.css.js +29 -29
  240. package/property-filter/styles.scoped.css +32 -32
  241. package/property-filter/styles.selectors.js +29 -29
  242. package/property-filter/token-editor.d.ts.map +1 -1
  243. package/property-filter/token-editor.js +2 -2
  244. package/property-filter/token-editor.js.map +1 -1
  245. package/radio-group/styles.css.js +9 -9
  246. package/radio-group/styles.scoped.css +17 -17
  247. package/radio-group/styles.selectors.js +9 -9
  248. package/s3-resource-selector/s3-in-context/styles.css.js +7 -7
  249. package/s3-resource-selector/s3-in-context/styles.scoped.css +9 -9
  250. package/s3-resource-selector/s3-in-context/styles.selectors.js +7 -7
  251. package/segmented-control/styles.css.js +14 -14
  252. package/segmented-control/styles.scoped.css +35 -35
  253. package/segmented-control/styles.selectors.js +14 -14
  254. package/select/parts/virtual-list.js +2 -2
  255. package/select/parts/virtual-list.js.map +1 -1
  256. package/select/styles.css.js +1 -1
  257. package/select/styles.scoped.css +2 -2
  258. package/select/styles.selectors.js +1 -1
  259. package/side-navigation/styles.css.js +27 -27
  260. package/side-navigation/styles.scoped.css +39 -39
  261. package/side-navigation/styles.selectors.js +27 -27
  262. package/spinner/styles.css.js +13 -13
  263. package/spinner/styles.scoped.css +20 -20
  264. package/spinner/styles.selectors.js +13 -13
  265. package/split-panel/styles.css.js +56 -56
  266. package/split-panel/styles.scoped.css +78 -78
  267. package/split-panel/styles.selectors.js +56 -56
  268. package/status-indicator/internal.d.ts +6 -3
  269. package/status-indicator/internal.d.ts.map +1 -1
  270. package/status-indicator/internal.js +2 -2
  271. package/status-indicator/internal.js.map +1 -1
  272. package/status-indicator/styles.css.js +22 -20
  273. package/status-indicator/styles.scoped.css +33 -28
  274. package/status-indicator/styles.selectors.js +22 -20
  275. package/table/internal.d.ts.map +1 -1
  276. package/table/internal.js +6 -4
  277. package/table/internal.js.map +1 -1
  278. package/table/sticky-scrollbar/styles.css.js +4 -4
  279. package/table/sticky-scrollbar/styles.scoped.css +4 -5
  280. package/table/sticky-scrollbar/styles.selectors.js +4 -4
  281. package/table/styles.css.js +34 -34
  282. package/table/styles.scoped.css +43 -43
  283. package/table/styles.selectors.js +34 -34
  284. package/tabs/styles.css.js +21 -21
  285. package/tabs/styles.scoped.css +39 -39
  286. package/tabs/styles.selectors.js +21 -21
  287. package/tabs/tab-header-bar.js +2 -2
  288. package/tabs/tab-header-bar.js.map +1 -1
  289. package/test-utils/dom/button-dropdown/index.d.ts +2 -0
  290. package/test-utils/dom/button-dropdown/index.js +6 -1
  291. package/test-utils/dom/button-dropdown/index.js.map +1 -1
  292. package/test-utils/selectors/button-dropdown/index.d.ts +2 -0
  293. package/test-utils/selectors/button-dropdown/index.js +6 -1
  294. package/test-utils/selectors/button-dropdown/index.js.map +1 -1
  295. package/test-utils/tsconfig.tsbuildinfo +1 -1
  296. package/text-content/styles.css.js +1 -1
  297. package/text-content/styles.scoped.css +64 -64
  298. package/text-content/styles.selectors.js +1 -1
  299. package/text-filter/styles.css.js +3 -3
  300. package/text-filter/styles.scoped.css +4 -4
  301. package/text-filter/styles.selectors.js +3 -3
  302. package/textarea/styles.css.js +4 -4
  303. package/textarea/styles.scoped.css +14 -14
  304. package/textarea/styles.selectors.js +4 -4
  305. package/tiles/styles.css.js +28 -28
  306. package/tiles/styles.scoped.css +70 -70
  307. package/tiles/styles.selectors.js +28 -28
  308. package/toggle/styles.css.js +8 -8
  309. package/toggle/styles.scoped.css +15 -15
  310. package/toggle/styles.selectors.js +8 -8
  311. package/token-group/styles.css.js +7 -7
  312. package/token-group/styles.scoped.css +17 -17
  313. package/token-group/styles.selectors.js +7 -7
  314. package/top-navigation/1.0-beta/styles.css.js +25 -25
  315. package/top-navigation/1.0-beta/styles.scoped.css +43 -43
  316. package/top-navigation/1.0-beta/styles.selectors.js +25 -25
  317. package/top-navigation/1.0-beta/use-top-navigation.d.ts.map +1 -1
  318. package/top-navigation/1.0-beta/use-top-navigation.js +2 -1
  319. package/top-navigation/1.0-beta/use-top-navigation.js.map +1 -1
  320. package/top-navigation/styles.css.js +47 -47
  321. package/top-navigation/styles.scoped.css +70 -70
  322. package/top-navigation/styles.selectors.js +47 -47
  323. package/top-navigation/use-top-navigation.d.ts.map +1 -1
  324. package/top-navigation/use-top-navigation.js +2 -1
  325. package/top-navigation/use-top-navigation.js.map +1 -1
  326. package/tutorial-panel/components/tutorial-detail-view/styles.css.js +20 -20
  327. package/tutorial-panel/components/tutorial-detail-view/styles.scoped.css +23 -23
  328. package/tutorial-panel/components/tutorial-detail-view/styles.selectors.js +20 -20
  329. package/tutorial-panel/components/tutorial-list/styles.css.js +18 -18
  330. package/tutorial-panel/components/tutorial-list/styles.scoped.css +30 -30
  331. package/tutorial-panel/components/tutorial-list/styles.selectors.js +18 -18
  332. package/tutorial-panel/styles.css.js +1 -1
  333. package/tutorial-panel/styles.scoped.css +2 -2
  334. package/tutorial-panel/styles.selectors.js +1 -1
  335. package/wizard/styles.css.js +31 -31
  336. package/wizard/styles.scoped.css +63 -63
  337. package/wizard/styles.selectors.js +31 -31
  338. package/internal/hooks/container-queries/interfaces.d.ts +0 -10
  339. package/internal/hooks/container-queries/interfaces.d.ts.map +0 -1
  340. package/internal/hooks/container-queries/interfaces.js +0 -4
  341. package/internal/hooks/container-queries/interfaces.js.map +0 -1
  342. package/internal/hooks/container-queries/use-container-query.d.ts +0 -22
  343. package/internal/hooks/container-queries/use-container-query.d.ts.map +0 -1
  344. package/internal/hooks/container-queries/use-container-query.js +0 -32
  345. package/internal/hooks/container-queries/use-container-query.js.map +0 -1
@@ -1,17 +1,17 @@
1
1
 
2
2
  import './styles.scoped.css';
3
3
  export default {
4
- "root": "awsui_root_2rhyz_19bat_93",
5
- "input": "awsui_input_2rhyz_19bat_97",
6
- "input-readonly": "awsui_input-readonly_2rhyz_19bat_120",
7
- "input-invalid": "awsui_input-invalid_2rhyz_19bat_181",
8
- "input-has-icon-left": "awsui_input-has-icon-left_2rhyz_19bat_192",
9
- "input-type-search": "awsui_input-type-search_2rhyz_19bat_197",
10
- "input-has-icon-right": "awsui_input-has-icon-right_2rhyz_19bat_213",
11
- "input-has-no-border-radius": "awsui_input-has-no-border-radius_2rhyz_19bat_216",
12
- "input-container": "awsui_input-container_2rhyz_19bat_220",
13
- "input-icon-left": "awsui_input-icon-left_2rhyz_19bat_225",
14
- "input-icon-right": "awsui_input-icon-right_2rhyz_19bat_232",
15
- "input-button-right": "awsui_input-button-right_2rhyz_19bat_238"
4
+ "root": "awsui_root_2rhyz_w519p_93",
5
+ "input": "awsui_input_2rhyz_w519p_97",
6
+ "input-readonly": "awsui_input-readonly_2rhyz_w519p_120",
7
+ "input-invalid": "awsui_input-invalid_2rhyz_w519p_181",
8
+ "input-has-icon-left": "awsui_input-has-icon-left_2rhyz_w519p_192",
9
+ "input-type-search": "awsui_input-type-search_2rhyz_w519p_197",
10
+ "input-has-icon-right": "awsui_input-has-icon-right_2rhyz_w519p_213",
11
+ "input-has-no-border-radius": "awsui_input-has-no-border-radius_2rhyz_w519p_216",
12
+ "input-container": "awsui_input-container_2rhyz_w519p_220",
13
+ "input-icon-left": "awsui_input-icon-left_2rhyz_w519p_225",
14
+ "input-icon-right": "awsui_input-icon-right_2rhyz_w519p_232",
15
+ "input-button-right": "awsui_input-button-right_2rhyz_w519p_238"
16
16
  };
17
17
 
@@ -90,11 +90,11 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
90
90
  Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
91
91
  SPDX-License-Identifier: Apache-2.0
92
92
  */
93
- .awsui_root_2rhyz_19bat_93:not(#\9) {
93
+ .awsui_root_2rhyz_w519p_93:not(#\9) {
94
94
  /* used in test-utils for component to distinguish input from other input-like components, for example autosuggest */
95
95
  }
96
96
 
97
- .awsui_input_2rhyz_19bat_97:not(#\9) {
97
+ .awsui_input_2rhyz_w519p_97:not(#\9) {
98
98
  /* stylelint-disable-next-line plugin/no-unsupported-browser-features */
99
99
  border-collapse: separate;
100
100
  border-spacing: 0;
@@ -125,7 +125,7 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
125
125
  word-spacing: normal;
126
126
  box-sizing: border-box;
127
127
  font-size: var(--font-body-m-size-7dign1, 14px);
128
- line-height: var(--font-body-m-line-height-rfgrp9, 22px);
128
+ line-height: var(--font-body-m-line-height-ghizru, 20px);
129
129
  color: var(--color-text-body-default-su7kuo, #000716);
130
130
  font-weight: 400;
131
131
  font-family: var(--font-family-base-wn913o, "Open Sans", "Helvetica Neue", Roboto, Arial, sans-serif);
@@ -140,73 +140,73 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
140
140
  border-radius: var(--border-radius-input-g1eef0, 8px);
141
141
  border: var(--border-field-width-riro62, 2px) solid var(--color-border-input-default-zb6g42, #7d8998);
142
142
  font-size: var(--font-body-m-size-7dign1, 14px);
143
- line-height: var(--font-body-m-line-height-rfgrp9, 22px);
144
- height: var(--size-vertical-input-u93i5u, 34px);
143
+ line-height: var(--font-body-m-line-height-ghizru, 20px);
144
+ height: var(--size-vertical-input-pta06y, 32px);
145
145
  }
146
- .awsui_input_2rhyz_19bat_97.awsui_input-readonly_2rhyz_19bat_120:not(#\9) {
146
+ .awsui_input_2rhyz_w519p_97.awsui_input-readonly_2rhyz_w519p_120:not(#\9) {
147
147
  background-color: var(--color-background-input-default-y2omd4, #ffffff);
148
148
  border: var(--border-field-width-riro62, 2px) solid var(--color-border-input-disabled-06dcc0, #e9ebed);
149
149
  }
150
- .awsui_input_2rhyz_19bat_97:not(#\9)::-webkit-input-placeholder {
150
+ .awsui_input_2rhyz_w519p_97:not(#\9)::-webkit-input-placeholder {
151
151
  color: var(--color-text-input-placeholder-3y98yw, #5f6b7a);
152
152
  font-style: italic;
153
153
  -webkit-user-select: none;
154
154
  user-select: none;
155
155
  }
156
- .awsui_input_2rhyz_19bat_97:not(#\9)::-ms-input-placeholder {
156
+ .awsui_input_2rhyz_w519p_97:not(#\9)::-ms-input-placeholder {
157
157
  color: var(--color-text-input-placeholder-3y98yw, #5f6b7a);
158
158
  font-style: italic;
159
159
  }
160
- .awsui_input_2rhyz_19bat_97:not(#\9)::-moz-placeholder {
160
+ .awsui_input_2rhyz_w519p_97:not(#\9)::-moz-placeholder {
161
161
  color: var(--color-text-input-placeholder-3y98yw, #5f6b7a);
162
162
  font-style: italic;
163
163
  opacity: 1;
164
164
  }
165
- .awsui_input_2rhyz_19bat_97:not(#\9):-ms-input-placeholder {
165
+ .awsui_input_2rhyz_w519p_97:not(#\9):-ms-input-placeholder {
166
166
  color: var(--color-text-input-placeholder-3y98yw, #5f6b7a);
167
167
  font-style: italic;
168
168
  }
169
- .awsui_input_2rhyz_19bat_97:not(#\9):-moz-placeholder {
169
+ .awsui_input_2rhyz_w519p_97:not(#\9):-moz-placeholder {
170
170
  color: var(--color-text-input-placeholder-3y98yw, #5f6b7a);
171
171
  font-style: italic;
172
172
  opacity: 1;
173
173
  }
174
- .awsui_input_2rhyz_19bat_97:not(#\9):focus {
174
+ .awsui_input_2rhyz_w519p_97:not(#\9):focus {
175
175
  outline: 2px dotted transparent;
176
176
  border: var(--border-field-width-riro62, 2px) solid var(--color-border-item-focused-4t19h5, #0972d3);
177
177
  border-radius: var(--border-radius-input-g1eef0, 8px);
178
178
  box-shadow: 0 0 0 var(--border-control-focus-ring-shadow-spread-cwek11, 0px) var(--color-border-item-focused-4t19h5, #0972d3);
179
179
  }
180
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled {
180
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled {
181
181
  background-color: var(--color-background-input-disabled-nvrgh4, #e9ebed);
182
182
  border: var(--border-field-width-riro62, 2px) solid var(--color-border-input-disabled-06dcc0, #e9ebed);
183
183
  color: var(--color-text-input-disabled-dmotcr, #9ba7b6);
184
184
  cursor: auto;
185
185
  cursor: default;
186
186
  }
187
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled::-webkit-input-placeholder {
187
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled::-webkit-input-placeholder {
188
188
  color: var(--color-text-input-placeholder-disabled-kxks79, #9ba7b6);
189
189
  -webkit-user-select: none;
190
190
  user-select: none;
191
191
  }
192
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled::-ms-input-placeholder {
192
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled::-ms-input-placeholder {
193
193
  color: var(--color-text-input-placeholder-disabled-kxks79, #9ba7b6);
194
194
  }
195
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled::-moz-placeholder {
195
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled::-moz-placeholder {
196
196
  color: var(--color-text-input-placeholder-disabled-kxks79, #9ba7b6);
197
197
  opacity: 1;
198
198
  }
199
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled:-ms-input-placeholder {
199
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled:-ms-input-placeholder {
200
200
  color: var(--color-text-input-placeholder-disabled-kxks79, #9ba7b6);
201
201
  }
202
- .awsui_input_2rhyz_19bat_97:not(#\9):disabled:-moz-placeholder {
202
+ .awsui_input_2rhyz_w519p_97:not(#\9):disabled:-moz-placeholder {
203
203
  color: var(--color-text-input-placeholder-disabled-kxks79, #9ba7b6);
204
204
  opacity: 1;
205
205
  }
206
- .awsui_input_2rhyz_19bat_97:not(#\9):invalid {
206
+ .awsui_input_2rhyz_w519p_97:not(#\9):invalid {
207
207
  box-shadow: none;
208
208
  }
209
- .awsui_input_2rhyz_19bat_97.awsui_input-invalid_2rhyz_19bat_181:not(#\9) {
209
+ .awsui_input_2rhyz_w519p_97.awsui_input-invalid_2rhyz_w519p_181:not(#\9) {
210
210
  color: var(--color-text-status-error-p6dh5n, #d91515);
211
211
  border-color: var(--color-text-status-error-p6dh5n, #d91515);
212
212
  padding-left: calc(
@@ -214,55 +214,55 @@ surrounding text. (WCAG F73) https://www.w3.org/WAI/WCAG21/Techniques/failures/F
214
214
  );
215
215
  border-left-width: var(--border-invalid-width-u1caet, 8px);
216
216
  }
217
- .awsui_input_2rhyz_19bat_97.awsui_input-invalid_2rhyz_19bat_181:not(#\9):focus {
217
+ .awsui_input_2rhyz_w519p_97.awsui_input-invalid_2rhyz_w519p_181:not(#\9):focus {
218
218
  box-shadow: 0 0 0 var(--border-control-invalid-focus-ring-shadow-spread-yfz0fs, 2px) var(--color-border-item-focused-4t19h5, #0972d3);
219
219
  }
220
- .awsui_input_2rhyz_19bat_97.awsui_input-invalid_2rhyz_19bat_181.awsui_input-has-icon-left_2rhyz_19bat_192:not(#\9) {
220
+ .awsui_input_2rhyz_w519p_97.awsui_input-invalid_2rhyz_w519p_181.awsui_input-has-icon-left_2rhyz_w519p_192:not(#\9) {
221
221
  padding-left: calc(
222
222
  var(--space-field-icon-offset-o8qwwh, 36px) - (var(--border-invalid-width-u1caet, 8px) - var(--border-field-width-riro62, 2px))
223
223
  );
224
224
  }
225
- .awsui_input_2rhyz_19bat_97.awsui_input-type-search_2rhyz_19bat_197:not(#\9) {
225
+ .awsui_input_2rhyz_w519p_97.awsui_input-type-search_2rhyz_w519p_197:not(#\9) {
226
226
  box-sizing: border-box;
227
227
  -webkit-appearance: none; /* stylelint-disable-line plugin/no-unsupported-browser-features */
228
228
  }
229
- .awsui_input_2rhyz_19bat_97.awsui_input-type-search_2rhyz_19bat_197:not(#\9)::-ms-clear {
229
+ .awsui_input_2rhyz_w519p_97.awsui_input-type-search_2rhyz_w519p_197:not(#\9)::-ms-clear {
230
230
  display: none;
231
231
  }
232
- .awsui_input_2rhyz_19bat_97.awsui_input-type-search_2rhyz_19bat_197:not(#\9)::-webkit-search-decoration {
232
+ .awsui_input_2rhyz_w519p_97.awsui_input-type-search_2rhyz_w519p_197:not(#\9)::-webkit-search-decoration {
233
233
  -webkit-appearance: none; /* stylelint-disable-line plugin/no-unsupported-browser-features */
234
234
  }
235
- .awsui_input_2rhyz_19bat_97.awsui_input-type-search_2rhyz_19bat_197:not(#\9)::-webkit-search-cancel-button {
235
+ .awsui_input_2rhyz_w519p_97.awsui_input-type-search_2rhyz_w519p_197:not(#\9)::-webkit-search-cancel-button {
236
236
  display: none;
237
237
  }
238
- .awsui_input_2rhyz_19bat_97.awsui_input-has-icon-left_2rhyz_19bat_192:not(#\9) {
238
+ .awsui_input_2rhyz_w519p_97.awsui_input-has-icon-left_2rhyz_w519p_192:not(#\9) {
239
239
  padding-left: var(--space-field-icon-offset-o8qwwh, 36px);
240
240
  }
241
- .awsui_input_2rhyz_19bat_97.awsui_input-has-icon-right_2rhyz_19bat_213:not(#\9) {
241
+ .awsui_input_2rhyz_w519p_97.awsui_input-has-icon-right_2rhyz_w519p_213:not(#\9) {
242
242
  padding-right: var(--space-field-icon-offset-o8qwwh, 36px);
243
243
  }
244
- .awsui_input_2rhyz_19bat_97.awsui_input-has-no-border-radius_2rhyz_19bat_216:not(#\9) {
244
+ .awsui_input_2rhyz_w519p_97.awsui_input-has-no-border-radius_2rhyz_w519p_216:not(#\9) {
245
245
  border-radius: var(--border-radius-dropdown-re1k6b, 8px);
246
246
  }
247
247
 
248
- .awsui_input-container_2rhyz_19bat_220:not(#\9) {
248
+ .awsui_input-container_2rhyz_w519p_220:not(#\9) {
249
249
  display: flex;
250
250
  position: relative;
251
251
  }
252
252
 
253
- .awsui_input-icon-left_2rhyz_19bat_225:not(#\9) {
253
+ .awsui_input-icon-left_2rhyz_w519p_225:not(#\9) {
254
254
  position: absolute;
255
255
  pointer-events: none;
256
256
  left: var(--space-field-horizontal-8qo3uw, 12px);
257
- top: calc(50% - var(--font-body-m-line-height-rfgrp9, 22px) / 2);
257
+ top: calc(50% - var(--font-body-m-line-height-ghizru, 20px) / 2);
258
258
  }
259
259
 
260
- .awsui_input-icon-right_2rhyz_19bat_232:not(#\9) {
260
+ .awsui_input-icon-right_2rhyz_w519p_232:not(#\9) {
261
261
  position: absolute;
262
- top: calc(50% - var(--font-body-m-line-height-rfgrp9, 22px) / 2);
262
+ top: calc(50% - var(--font-body-m-line-height-ghizru, 20px) / 2);
263
263
  right: calc(var(--space-field-horizontal-8qo3uw, 12px) - var(--space-xxs-ja5cp8, 4px));
264
264
  }
265
265
 
266
- .awsui_input-button-right_2rhyz_19bat_238:not(#\9) {
266
+ .awsui_input-button-right_2rhyz_w519p_238:not(#\9) {
267
267
  /* used in test-utils */
268
268
  }
@@ -2,17 +2,17 @@
2
2
  // es-module interop with Babel and Typescript
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  module.exports.default = {
5
- "root": "awsui_root_2rhyz_19bat_93",
6
- "input": "awsui_input_2rhyz_19bat_97",
7
- "input-readonly": "awsui_input-readonly_2rhyz_19bat_120",
8
- "input-invalid": "awsui_input-invalid_2rhyz_19bat_181",
9
- "input-has-icon-left": "awsui_input-has-icon-left_2rhyz_19bat_192",
10
- "input-type-search": "awsui_input-type-search_2rhyz_19bat_197",
11
- "input-has-icon-right": "awsui_input-has-icon-right_2rhyz_19bat_213",
12
- "input-has-no-border-radius": "awsui_input-has-no-border-radius_2rhyz_19bat_216",
13
- "input-container": "awsui_input-container_2rhyz_19bat_220",
14
- "input-icon-left": "awsui_input-icon-left_2rhyz_19bat_225",
15
- "input-icon-right": "awsui_input-icon-right_2rhyz_19bat_232",
16
- "input-button-right": "awsui_input-button-right_2rhyz_19bat_238"
5
+ "root": "awsui_root_2rhyz_w519p_93",
6
+ "input": "awsui_input_2rhyz_w519p_97",
7
+ "input-readonly": "awsui_input-readonly_2rhyz_w519p_120",
8
+ "input-invalid": "awsui_input-invalid_2rhyz_w519p_181",
9
+ "input-has-icon-left": "awsui_input-has-icon-left_2rhyz_w519p_192",
10
+ "input-type-search": "awsui_input-type-search_2rhyz_w519p_197",
11
+ "input-has-icon-right": "awsui_input-has-icon-right_2rhyz_w519p_213",
12
+ "input-has-no-border-radius": "awsui_input-has-no-border-radius_2rhyz_w519p_216",
13
+ "input-container": "awsui_input-container_2rhyz_w519p_220",
14
+ "input-icon-left": "awsui_input-icon-left_2rhyz_w519p_225",
15
+ "input-icon-right": "awsui_input-icon-right_2rhyz_w519p_232",
16
+ "input-button-right": "awsui_input-button-right_2rhyz_w519p_238"
17
17
  };
18
18
 
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAKL,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAQtC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAW7D,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,KAAK,oBAAoB,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,GAAG,IAAI,CAC/D,WAAW,EACX,YAAY,GAAG,qBAAqB,GAAG,kBAAkB,CAC1D,CAAC;AAEF,eAAO,MAAM,eAAe,2BAA4B,oBAAoB,gBAgE3E,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,sBAAsB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CACnF,GAAG,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,kBAAkB,CAAC,CAAC;AAE7D,eAAO,MAAM,mBAAmB,+CAAgD,wBAAwB,gBAyCvG,CAAC;AACF,UAAU,2BAA2B;IACnC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,sBAAsB,iBAAkB,2BAA2B,gBAsB/E,CAAC"}
1
+ {"version":3,"file":"analytics-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAE3D,OAAO,EAKL,sBAAsB,EAEvB,MAAM,8BAA8B,CAAC;AAQtC,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAW7D,eAAO,MAAM,cAAc,QAAQ,CAAC;AAEpC,KAAK,oBAAoB,GAAG;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,GAAG,IAAI,CAC/D,WAAW,EACX,YAAY,GAAG,qBAAqB,GAAG,kBAAkB,CAC1D,CAAC;AAEF,eAAO,MAAM,eAAe,2BAA4B,oBAAoB,gBAkH3E,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,sBAAsB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CACnF,GAAG,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,kBAAkB,CAAC,CAAC;AAE7D,eAAO,MAAM,mBAAmB,+CAAgD,wBAAwB,gBA2CvG,CAAC;AACF,UAAU,2BAA2B;IACnC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,eAAO,MAAM,sBAAsB,iBAAkB,2BAA2B,gBAsB/E,CAAC"}
@@ -14,8 +14,10 @@ export const AnalyticsFunnel = (_a) => {
14
14
  var { children } = _a, props = __rest(_a, ["children"]);
15
15
  const [funnelInteractionId, setFunnelInteractionId] = useState('');
16
16
  const [submissionAttempt, setSubmissionAttempt] = useState(0);
17
- const funnelResultRef = useRef(false);
18
17
  const isVisualRefresh = useVisualRefresh();
18
+ const funnelState = useRef('default');
19
+ const errorCount = useRef(0);
20
+ const loadingButtonCount = useRef(0);
19
21
  // This useEffect hook is run once on component mount to initiate the funnel analytics.
20
22
  // It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details
21
23
  // about the funnel, and receives a unique interaction id.
@@ -27,6 +29,8 @@ export const AnalyticsFunnel = (_a) => {
27
29
  // The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,
28
30
  // hence we do not provide any dependencies.
29
31
  useEffect(() => {
32
+ // Reset the state, in case the component was re-mounted.
33
+ funnelState.current = 'default';
30
34
  const funnelInteractionId = FunnelMetrics.funnelStart({
31
35
  funnelNameSelector: getFunnelNameSelector(),
32
36
  optionalStepNumbers: props.optionalStepNumbers,
@@ -37,24 +41,62 @@ export const AnalyticsFunnel = (_a) => {
37
41
  funnelVersion: FUNNEL_VERSION,
38
42
  });
39
43
  setFunnelInteractionId(funnelInteractionId);
44
+ /*
45
+ A funnel counts as "successful" if it is unmounted after being "complete".
46
+ */
47
+ /* eslint-disable react-hooks/exhaustive-deps */
40
48
  return () => {
41
- if (funnelResultRef.current === true) {
49
+ if (funnelState.current === 'validating') {
50
+ // Finish the validation phase early.
51
+ FunnelMetrics.funnelComplete({ funnelInteractionId });
52
+ funnelState.current = 'complete';
53
+ }
54
+ if (funnelState.current === 'complete') {
42
55
  FunnelMetrics.funnelSuccessful({ funnelInteractionId });
43
56
  }
44
57
  else {
45
58
  FunnelMetrics.funnelCancelled({ funnelInteractionId });
59
+ funnelState.current === 'cancelled';
46
60
  }
47
61
  };
48
- // eslint-disable-next-line react-hooks/exhaustive-deps
49
62
  }, []);
63
+ /* eslint-enable react-hooks/exhaustive-deps */
50
64
  const funnelSubmit = () => {
51
- FunnelMetrics.funnelComplete({ funnelInteractionId });
52
- funnelResultRef.current = true;
65
+ funnelState.current = 'validating';
66
+ /*
67
+ When the user attempts to submit the form, we wait for 50 milliseconds before checking
68
+ if any form validation errors are present. This value was chosen to give enough time
69
+ for validation and rerendering to occur, but be low enough that the user will not
70
+ be able to take further action in the meantime.
71
+ */
72
+ const VALIDATION_WAIT_DELAY = 50;
73
+ /*
74
+ Loading is expected to take longer than validation, so we can keep the pressure on the CPU low.
75
+ */
76
+ const LOADING_WAIT_DELAY = 100;
77
+ const checkForCompleteness = () => {
78
+ if (funnelState.current === 'complete') {
79
+ return;
80
+ }
81
+ if (loadingButtonCount.current > 0) {
82
+ setTimeout(checkForCompleteness, LOADING_WAIT_DELAY);
83
+ return;
84
+ }
85
+ if (errorCount.current === 0) {
86
+ /*
87
+ If no validation errors are rendered, we treat the funnel as complete.
88
+ */
89
+ FunnelMetrics.funnelComplete({ funnelInteractionId });
90
+ funnelState.current = 'complete';
91
+ }
92
+ else {
93
+ funnelState.current = 'default';
94
+ }
95
+ };
96
+ setTimeout(checkForCompleteness, VALIDATION_WAIT_DELAY);
53
97
  };
54
98
  const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);
55
- const funnelCancel = () => {
56
- funnelResultRef.current = false;
57
- };
99
+ const funnelCancel = () => { };
58
100
  const funnelContextValue = {
59
101
  funnelInteractionId,
60
102
  setFunnelInteractionId,
@@ -65,11 +107,14 @@ export const AnalyticsFunnel = (_a) => {
65
107
  funnelCancel,
66
108
  submissionAttempt,
67
109
  funnelNextOrSubmitAttempt,
110
+ funnelState,
111
+ errorCount,
112
+ loadingButtonCount,
68
113
  };
69
114
  return React.createElement(FunnelContext.Provider, { value: funnelContextValue }, children);
70
115
  };
71
116
  export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }) => {
72
- const { funnelInteractionId } = useFunnel();
117
+ const { funnelInteractionId, funnelState } = useFunnel();
73
118
  const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };
74
119
  // This useEffect hook is used to track the start and completion of interaction with the step.
75
120
  // On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics
@@ -77,7 +122,7 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
77
122
  // On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.
78
123
  useEffect(() => {
79
124
  const stepName = getNameFromSelector(stepNameSelector);
80
- if (funnelInteractionId) {
125
+ if (funnelInteractionId && funnelState.current === 'default') {
81
126
  FunnelMetrics.funnelStepStart({
82
127
  funnelInteractionId,
83
128
  stepNumber,
@@ -87,7 +132,8 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
87
132
  });
88
133
  }
89
134
  return () => {
90
- if (funnelInteractionId) {
135
+ //eslint-disable-next-line react-hooks/exhaustive-deps
136
+ if (funnelInteractionId && funnelState.current === 'default') {
91
137
  FunnelMetrics.funnelStepComplete({
92
138
  funnelInteractionId,
93
139
  stepNumber,
@@ -97,6 +143,7 @@ export const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector })
97
143
  });
98
144
  }
99
145
  };
146
+ //eslint-disable-next-line react-hooks/exhaustive-deps
100
147
  }, [funnelInteractionId, stepNumber, stepNameSelector]);
101
148
  const contextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };
102
149
  return (React.createElement(FunnelStepContext.Provider, { value: contextValue }, typeof children === 'function' ? children(contextValue) : children));
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport {\n FunnelStepContext,\n FunnelSubStepContext,\n FunnelContext,\n FunnelContextValue,\n FunnelStepContextValue,\n} from '../context/analytics-context';\nimport { useFunnel, useFunnelStep } from '../hooks/use-funnel';\nimport { useUniqueId } from '../../hooks/use-unique-id';\nimport { useVisualRefresh } from '../../hooks/use-visual-mode';\n\nimport { PACKAGE_VERSION } from '../../environment';\n\nimport { FunnelMetrics } from '../';\nimport { FunnelProps, FunnelStepProps } from '../interfaces';\n\nimport {\n DATA_ATTR_FUNNEL_STEP,\n getFunnelNameSelector,\n getNameFromSelector,\n getSubStepAllSelector,\n getSubStepNameSelector,\n getSubStepSelector,\n} from '../selectors';\n\nexport const FUNNEL_VERSION = '1.0';\n\ntype AnalyticsFunnelProps = { children?: React.ReactNode } & Pick<\n FunnelProps,\n 'funnelType' | 'optionalStepNumbers' | 'totalFunnelSteps'\n>;\n\nexport const AnalyticsFunnel = ({ children, ...props }: AnalyticsFunnelProps) => {\n const [funnelInteractionId, setFunnelInteractionId] = useState<string>('');\n const [submissionAttempt, setSubmissionAttempt] = useState(0);\n const funnelResultRef = useRef<boolean>(false);\n const isVisualRefresh = useVisualRefresh();\n\n // This useEffect hook is run once on component mount to initiate the funnel analytics.\n // It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details\n // about the funnel, and receives a unique interaction id.\n // This unique interaction id is then stored in the state for further use.\n //\n // On component unmount, it checks whether the funnel was successfully completed.\n // Based on this, it either calls 'funnelComplete' or 'funnelCancelled' method from FunnelMetrics.\n //\n // The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,\n // hence we do not provide any dependencies.\n useEffect(() => {\n const funnelInteractionId = FunnelMetrics.funnelStart({\n funnelNameSelector: getFunnelNameSelector(),\n optionalStepNumbers: props.optionalStepNumbers,\n funnelType: props.funnelType,\n totalFunnelSteps: props.totalFunnelSteps,\n componentVersion: PACKAGE_VERSION,\n theme: isVisualRefresh ? 'vr' : 'classic',\n funnelVersion: FUNNEL_VERSION,\n });\n\n setFunnelInteractionId(funnelInteractionId);\n\n return () => {\n if (funnelResultRef.current === true) {\n FunnelMetrics.funnelSuccessful({ funnelInteractionId });\n } else {\n FunnelMetrics.funnelCancelled({ funnelInteractionId });\n }\n };\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const funnelSubmit = () => {\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelResultRef.current = true;\n };\n\n const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);\n\n const funnelCancel = () => {\n funnelResultRef.current = false;\n };\n\n const funnelContextValue: FunnelContextValue = {\n funnelInteractionId,\n setFunnelInteractionId,\n funnelType: props.funnelType,\n optionalStepNumbers: props.optionalStepNumbers,\n totalFunnelSteps: props.totalFunnelSteps,\n funnelSubmit,\n funnelCancel,\n submissionAttempt,\n funnelNextOrSubmitAttempt,\n };\n\n return <FunnelContext.Provider value={funnelContextValue}>{children}</FunnelContext.Provider>;\n};\n\ntype AnalyticsFunnelStepProps = {\n children?: React.ReactNode | ((props: FunnelStepContextValue) => React.ReactNode);\n} & Pick<FunnelStepProps, 'stepNumber' | 'stepNameSelector'>;\n\nexport const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }: AnalyticsFunnelStepProps) => {\n const { funnelInteractionId } = useFunnel();\n\n const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };\n\n // This useEffect hook is used to track the start and completion of interaction with the step.\n // On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics\n // to record the beginning of the interaction with the current step.\n // On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.\n useEffect(() => {\n const stepName = getNameFromSelector(stepNameSelector);\n\n if (funnelInteractionId) {\n FunnelMetrics.funnelStepStart({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n\n return () => {\n if (funnelInteractionId) {\n FunnelMetrics.funnelStepComplete({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n }, [funnelInteractionId, stepNumber, stepNameSelector]);\n\n const contextValue: FunnelStepContextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };\n return (\n <FunnelStepContext.Provider value={contextValue}>\n {typeof children === 'function' ? children(contextValue) : children}\n </FunnelStepContext.Provider>\n );\n};\ninterface AnalyticsFunnelSubStepProps {\n children?: React.ReactNode;\n}\n\nexport const AnalyticsFunnelSubStep = ({ children }: AnalyticsFunnelSubStepProps) => {\n const { funnelInteractionId } = useFunnel();\n const { stepNumber, stepNameSelector } = useFunnelStep();\n\n const subStepId = useUniqueId('substep');\n const subStepSelector = getSubStepSelector(subStepId);\n const subStepNameSelector = getSubStepNameSelector(subStepId);\n\n return (\n <FunnelSubStepContext.Provider\n value={{\n funnelInteractionId,\n stepNumber,\n stepNameSelector,\n subStepSelector,\n subStepNameSelector,\n subStepId,\n }}\n >\n {children}\n </FunnelSubStepContext.Provider>\n );\n};\n"]}
1
+ {"version":3,"file":"analytics-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/components/analytics-funnel.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport React, { useEffect, useRef, useState } from 'react';\n\nimport {\n FunnelStepContext,\n FunnelSubStepContext,\n FunnelContext,\n FunnelContextValue,\n FunnelStepContextValue,\n FunnelState,\n} from '../context/analytics-context';\nimport { useFunnel, useFunnelStep } from '../hooks/use-funnel';\nimport { useUniqueId } from '../../hooks/use-unique-id';\nimport { useVisualRefresh } from '../../hooks/use-visual-mode';\n\nimport { PACKAGE_VERSION } from '../../environment';\n\nimport { FunnelMetrics } from '../';\nimport { FunnelProps, FunnelStepProps } from '../interfaces';\n\nimport {\n DATA_ATTR_FUNNEL_STEP,\n getFunnelNameSelector,\n getNameFromSelector,\n getSubStepAllSelector,\n getSubStepNameSelector,\n getSubStepSelector,\n} from '../selectors';\n\nexport const FUNNEL_VERSION = '1.0';\n\ntype AnalyticsFunnelProps = { children?: React.ReactNode } & Pick<\n FunnelProps,\n 'funnelType' | 'optionalStepNumbers' | 'totalFunnelSteps'\n>;\n\nexport const AnalyticsFunnel = ({ children, ...props }: AnalyticsFunnelProps) => {\n const [funnelInteractionId, setFunnelInteractionId] = useState<string>('');\n const [submissionAttempt, setSubmissionAttempt] = useState(0);\n const isVisualRefresh = useVisualRefresh();\n const funnelState = useRef<FunnelState>('default');\n const errorCount = useRef<number>(0);\n const loadingButtonCount = useRef<number>(0);\n\n // This useEffect hook is run once on component mount to initiate the funnel analytics.\n // It first calls the 'funnelStart' method from FunnelMetrics, providing all necessary details\n // about the funnel, and receives a unique interaction id.\n // This unique interaction id is then stored in the state for further use.\n //\n // On component unmount, it checks whether the funnel was successfully completed.\n // Based on this, it either calls 'funnelComplete' or 'funnelCancelled' method from FunnelMetrics.\n //\n // The eslint-disable is required as we deliberately want this effect to run only once on mount and unmount,\n // hence we do not provide any dependencies.\n useEffect(() => {\n // Reset the state, in case the component was re-mounted.\n funnelState.current = 'default';\n\n const funnelInteractionId = FunnelMetrics.funnelStart({\n funnelNameSelector: getFunnelNameSelector(),\n optionalStepNumbers: props.optionalStepNumbers,\n funnelType: props.funnelType,\n totalFunnelSteps: props.totalFunnelSteps,\n componentVersion: PACKAGE_VERSION,\n theme: isVisualRefresh ? 'vr' : 'classic',\n funnelVersion: FUNNEL_VERSION,\n });\n\n setFunnelInteractionId(funnelInteractionId);\n\n /*\n A funnel counts as \"successful\" if it is unmounted after being \"complete\".\n */\n /* eslint-disable react-hooks/exhaustive-deps */\n return () => {\n if (funnelState.current === 'validating') {\n // Finish the validation phase early.\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelState.current = 'complete';\n }\n\n if (funnelState.current === 'complete') {\n FunnelMetrics.funnelSuccessful({ funnelInteractionId });\n } else {\n FunnelMetrics.funnelCancelled({ funnelInteractionId });\n funnelState.current === 'cancelled';\n }\n };\n }, []);\n /* eslint-enable react-hooks/exhaustive-deps */\n\n const funnelSubmit = () => {\n funnelState.current = 'validating';\n\n /*\n When the user attempts to submit the form, we wait for 50 milliseconds before checking\n if any form validation errors are present. This value was chosen to give enough time\n for validation and rerendering to occur, but be low enough that the user will not\n be able to take further action in the meantime.\n */\n const VALIDATION_WAIT_DELAY = 50;\n /*\n Loading is expected to take longer than validation, so we can keep the pressure on the CPU low.\n */\n const LOADING_WAIT_DELAY = 100;\n\n const checkForCompleteness = () => {\n if (funnelState.current === 'complete') {\n return;\n }\n\n if (loadingButtonCount.current > 0) {\n setTimeout(checkForCompleteness, LOADING_WAIT_DELAY);\n return;\n }\n\n if (errorCount.current === 0) {\n /*\n If no validation errors are rendered, we treat the funnel as complete.\n */\n FunnelMetrics.funnelComplete({ funnelInteractionId });\n funnelState.current = 'complete';\n } else {\n funnelState.current = 'default';\n }\n };\n\n setTimeout(checkForCompleteness, VALIDATION_WAIT_DELAY);\n };\n\n const funnelNextOrSubmitAttempt = () => setSubmissionAttempt(i => i + 1);\n\n const funnelCancel = () => {};\n\n const funnelContextValue: FunnelContextValue = {\n funnelInteractionId,\n setFunnelInteractionId,\n funnelType: props.funnelType,\n optionalStepNumbers: props.optionalStepNumbers,\n totalFunnelSteps: props.totalFunnelSteps,\n funnelSubmit,\n funnelCancel,\n submissionAttempt,\n funnelNextOrSubmitAttempt,\n funnelState,\n errorCount,\n loadingButtonCount,\n };\n\n return <FunnelContext.Provider value={funnelContextValue}>{children}</FunnelContext.Provider>;\n};\n\ntype AnalyticsFunnelStepProps = {\n children?: React.ReactNode | ((props: FunnelStepContextValue) => React.ReactNode);\n} & Pick<FunnelStepProps, 'stepNumber' | 'stepNameSelector'>;\n\nexport const AnalyticsFunnelStep = ({ children, stepNumber, stepNameSelector }: AnalyticsFunnelStepProps) => {\n const { funnelInteractionId, funnelState } = useFunnel();\n\n const funnelStepProps = { [DATA_ATTR_FUNNEL_STEP]: stepNumber };\n\n // This useEffect hook is used to track the start and completion of interaction with the step.\n // On mount, if there is a valid funnel interaction id, it calls the 'funnelStepStart' method from FunnelMetrics\n // to record the beginning of the interaction with the current step.\n // On unmount, it does a similar thing but this time calling 'funnelStepComplete' to record the completion of the interaction.\n useEffect(() => {\n const stepName = getNameFromSelector(stepNameSelector);\n\n if (funnelInteractionId && funnelState.current === 'default') {\n FunnelMetrics.funnelStepStart({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n\n return () => {\n //eslint-disable-next-line react-hooks/exhaustive-deps\n if (funnelInteractionId && funnelState.current === 'default') {\n FunnelMetrics.funnelStepComplete({\n funnelInteractionId,\n stepNumber,\n stepName,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n //eslint-disable-next-line react-hooks/exhaustive-deps\n }, [funnelInteractionId, stepNumber, stepNameSelector]);\n\n const contextValue: FunnelStepContextValue = { funnelInteractionId, stepNumber, stepNameSelector, funnelStepProps };\n return (\n <FunnelStepContext.Provider value={contextValue}>\n {typeof children === 'function' ? children(contextValue) : children}\n </FunnelStepContext.Provider>\n );\n};\ninterface AnalyticsFunnelSubStepProps {\n children?: React.ReactNode;\n}\n\nexport const AnalyticsFunnelSubStep = ({ children }: AnalyticsFunnelSubStepProps) => {\n const { funnelInteractionId } = useFunnel();\n const { stepNumber, stepNameSelector } = useFunnelStep();\n\n const subStepId = useUniqueId('substep');\n const subStepSelector = getSubStepSelector(subStepId);\n const subStepNameSelector = getSubStepNameSelector(subStepId);\n\n return (\n <FunnelSubStepContext.Provider\n value={{\n funnelInteractionId,\n stepNumber,\n stepNameSelector,\n subStepSelector,\n subStepNameSelector,\n subStepId,\n }}\n >\n {children}\n </FunnelSubStepContext.Provider>\n );\n};\n"]}
@@ -1,8 +1,9 @@
1
- /// <reference types="react" />
1
+ import { MutableRefObject, RefObject } from 'react';
2
2
  import { FunnelType } from '../interfaces';
3
3
  export interface BaseContextProps {
4
4
  funnelInteractionId: string | undefined;
5
5
  }
6
+ export type FunnelState = 'default' | 'validating' | 'complete' | 'cancelled';
6
7
  export interface FunnelContextValue extends BaseContextProps {
7
8
  funnelType: FunnelType;
8
9
  optionalStepNumbers: number[];
@@ -12,6 +13,9 @@ export interface FunnelContextValue extends BaseContextProps {
12
13
  setFunnelInteractionId: (funnelInteractionId: string) => void;
13
14
  submissionAttempt: number;
14
15
  funnelNextOrSubmitAttempt: () => void;
16
+ funnelState: RefObject<FunnelState>;
17
+ errorCount: MutableRefObject<number>;
18
+ loadingButtonCount: MutableRefObject<number>;
15
19
  }
16
20
  export interface FunnelStepContextValue extends BaseContextProps {
17
21
  stepNameSelector: string;
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-context.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":";AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,sBAAsB,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yBAAyB,EAAE,MAAM,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC5E;AAGD,eAAO,MAAM,aAAa,6CAUxB,CAAC;AAEH,eAAO,MAAM,iBAAiB,iDAK5B,CAAC;AAEH,eAAO,MAAM,oBAAoB,oDAQ/B,CAAC"}
1
+ {"version":3,"file":"analytics-context.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAiB,MAAM,OAAO,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,WAAW,CAAC;AAE9E,MAAM,WAAW,kBAAmB,SAAQ,gBAAgB;IAC1D,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,sBAAsB,EAAE,CAAC,mBAAmB,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,CAAC;IACpC,UAAU,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACrC,kBAAkB,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,yBAA0B,SAAQ,sBAAsB;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;CAC5E;AAGD,eAAO,MAAM,aAAa,6CAaxB,CAAC;AAEH,eAAO,MAAM,iBAAiB,iDAK5B,CAAC;AAEH,eAAO,MAAM,oBAAoB,oDAQ/B,CAAC"}
@@ -12,6 +12,9 @@ export const FunnelContext = createContext({
12
12
  funnelCancel: () => { },
13
13
  submissionAttempt: 0,
14
14
  funnelNextOrSubmitAttempt: () => { },
15
+ funnelState: { current: 'default' },
16
+ errorCount: { current: 0 },
17
+ loadingButtonCount: { current: 0 },
15
18
  });
16
19
  export const FunnelStepContext = createContext({
17
20
  funnelInteractionId: undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"analytics-context.js","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAgCtC,0BAA0B;AAC1B,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB;IAC7D,mBAAmB,EAAE,SAAS;IAC9B,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,UAAU,EAAE,aAAa;IACzB,mBAAmB,EAAE,EAAE;IACvB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,iBAAiB,EAAE,CAAC;IACpB,yBAAyB,EAAE,GAAG,EAAE,GAAE,CAAC;CACpC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAyB;IACrE,mBAAmB,EAAE,SAAS;IAC9B,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE,CAAC;IACb,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAA4B;IAC3E,mBAAmB,EAAE,SAAS;IAC9B,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,EAAE;IACpB,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;IACvB,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { createContext } from 'react';\nimport { FunnelType } from '../interfaces';\n\nexport interface BaseContextProps {\n funnelInteractionId: string | undefined;\n}\n\nexport interface FunnelContextValue extends BaseContextProps {\n funnelType: FunnelType;\n optionalStepNumbers: number[];\n totalFunnelSteps: number;\n funnelSubmit: () => void;\n funnelCancel: () => void;\n setFunnelInteractionId: (funnelInteractionId: string) => void;\n submissionAttempt: number;\n funnelNextOrSubmitAttempt: () => void;\n}\n\nexport interface FunnelStepContextValue extends BaseContextProps {\n stepNameSelector: string;\n stepNumber: number;\n funnelStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\nexport interface FunnelSubStepContextValue extends FunnelStepContextValue {\n subStepId: string;\n subStepSelector: string;\n subStepNameSelector: string;\n stepNumber: number;\n funnelSubStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\n/* istanbul ignore next */\nexport const FunnelContext = createContext<FunnelContextValue>({\n funnelInteractionId: undefined,\n setFunnelInteractionId: () => {},\n funnelType: 'single-page',\n optionalStepNumbers: [],\n totalFunnelSteps: 0,\n funnelSubmit: () => {},\n funnelCancel: () => {},\n submissionAttempt: 0,\n funnelNextOrSubmitAttempt: () => {},\n});\n\nexport const FunnelStepContext = createContext<FunnelStepContextValue>({\n funnelInteractionId: undefined,\n stepNameSelector: '',\n stepNumber: 0,\n funnelStepProps: {},\n});\n\nexport const FunnelSubStepContext = createContext<FunnelSubStepContextValue>({\n funnelInteractionId: undefined,\n subStepId: '',\n stepNumber: 0,\n stepNameSelector: '',\n subStepSelector: '',\n subStepNameSelector: '',\n funnelStepProps: {},\n});\n"]}
1
+ {"version":3,"file":"analytics-context.js","sourceRoot":"lib/default/","sources":["internal/analytics/context/analytics-context.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AACtC,OAAO,EAA+B,aAAa,EAAE,MAAM,OAAO,CAAC;AAqCnE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAqB;IAC7D,mBAAmB,EAAE,SAAS;IAC9B,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,UAAU,EAAE,aAAa;IACzB,mBAAmB,EAAE,EAAE;IACvB,gBAAgB,EAAE,CAAC;IACnB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,YAAY,EAAE,GAAG,EAAE,GAAE,CAAC;IACtB,iBAAiB,EAAE,CAAC;IACpB,yBAAyB,EAAE,GAAG,EAAE,GAAE,CAAC;IACnC,WAAW,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE;IACnC,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;IAC1B,kBAAkB,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE;CACnC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAyB;IACrE,mBAAmB,EAAE,SAAS;IAC9B,gBAAgB,EAAE,EAAE;IACpB,UAAU,EAAE,CAAC;IACb,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,aAAa,CAA4B;IAC3E,mBAAmB,EAAE,SAAS;IAC9B,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,EAAE;IACpB,eAAe,EAAE,EAAE;IACnB,mBAAmB,EAAE,EAAE;IACvB,eAAe,EAAE,EAAE;CACpB,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\nimport { MutableRefObject, RefObject, createContext } from 'react';\nimport { FunnelType } from '../interfaces';\n\nexport interface BaseContextProps {\n funnelInteractionId: string | undefined;\n}\n\nexport type FunnelState = 'default' | 'validating' | 'complete' | 'cancelled';\n\nexport interface FunnelContextValue extends BaseContextProps {\n funnelType: FunnelType;\n optionalStepNumbers: number[];\n totalFunnelSteps: number;\n funnelSubmit: () => void;\n funnelCancel: () => void;\n setFunnelInteractionId: (funnelInteractionId: string) => void;\n submissionAttempt: number;\n funnelNextOrSubmitAttempt: () => void;\n funnelState: RefObject<FunnelState>;\n errorCount: MutableRefObject<number>;\n loadingButtonCount: MutableRefObject<number>;\n}\n\nexport interface FunnelStepContextValue extends BaseContextProps {\n stepNameSelector: string;\n stepNumber: number;\n funnelStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\nexport interface FunnelSubStepContextValue extends FunnelStepContextValue {\n subStepId: string;\n subStepSelector: string;\n subStepNameSelector: string;\n stepNumber: number;\n funnelSubStepProps?: Record<string, string | number | boolean | undefined>;\n}\n\n/* istanbul ignore next */\nexport const FunnelContext = createContext<FunnelContextValue>({\n funnelInteractionId: undefined,\n setFunnelInteractionId: () => {},\n funnelType: 'single-page',\n optionalStepNumbers: [],\n totalFunnelSteps: 0,\n funnelSubmit: () => {},\n funnelCancel: () => {},\n submissionAttempt: 0,\n funnelNextOrSubmitAttempt: () => {},\n funnelState: { current: 'default' },\n errorCount: { current: 0 },\n loadingButtonCount: { current: 0 },\n});\n\nexport const FunnelStepContext = createContext<FunnelStepContextValue>({\n funnelInteractionId: undefined,\n stepNameSelector: '',\n stepNumber: 0,\n funnelStepProps: {},\n});\n\nexport const FunnelSubStepContext = createContext<FunnelSubStepContextValue>({\n funnelInteractionId: undefined,\n subStepId: '',\n stepNumber: 0,\n stepNameSelector: '',\n subStepSelector: '',\n subStepNameSelector: '',\n funnelStepProps: {},\n});\n"]}
@@ -45,6 +45,9 @@ export declare const useFunnel: () => {
45
45
  setFunnelInteractionId: (funnelInteractionId: string) => void;
46
46
  submissionAttempt: number;
47
47
  funnelNextOrSubmitAttempt: () => void;
48
+ funnelState: import("react").RefObject<import("../context/analytics-context").FunnelState>;
49
+ errorCount: import("react").MutableRefObject<number>;
50
+ loadingButtonCount: import("react").MutableRefObject<number>;
48
51
  funnelInteractionId: string | undefined;
49
52
  funnelProps: Record<string, string | number | boolean | undefined>;
50
53
  };
@@ -1 +1 @@
1
- {"version":3,"file":"use-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":";AAQA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;CA6C5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,qEAGzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;CASrB,CAAC"}
1
+ {"version":3,"file":"use-funnel.d.ts","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":";AAQA;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;CAqD5B,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,qEAGzB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;CASrB,CAAC"}
@@ -18,10 +18,12 @@ export const useFunnelSubStep = () => {
18
18
  const subStepRef = useRef(null);
19
19
  const context = useContext(FunnelSubStepContext);
20
20
  const { funnelInteractionId, subStepId, subStepSelector, subStepNameSelector, stepNumber, stepNameSelector } = context;
21
+ const { funnelState } = useFunnel();
21
22
  const onFocus = (event) => {
22
23
  if (funnelInteractionId &&
23
24
  subStepRef.current &&
24
- (!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget))) {
25
+ (!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget)) &&
26
+ funnelState.current === 'default') {
25
27
  FunnelMetrics.funnelSubStepStart({
26
28
  funnelInteractionId,
27
29
  subStepSelector,
@@ -33,7 +35,10 @@ export const useFunnelSubStep = () => {
33
35
  }
34
36
  };
35
37
  const onBlur = (event) => {
36
- if (funnelInteractionId && subStepRef.current && !subStepRef.current.contains(event.relatedTarget)) {
38
+ if (funnelInteractionId &&
39
+ subStepRef.current &&
40
+ !subStepRef.current.contains(event.relatedTarget) &&
41
+ funnelState.current === 'default') {
37
42
  FunnelMetrics.funnelSubStepComplete({
38
43
  funnelInteractionId,
39
44
  subStepSelector,
@@ -1 +1 @@
1
- {"version":3,"file":"use-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAC1G,OAAO,CAAC;IAEV,MAAM,OAAO,GAAG,CAAC,KAAuC,EAAE,EAAE;QAC1D,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,CAAC,EACnF;YACA,aAAa,CAAC,kBAAkB,CAAC;gBAC/B,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,KAAuC,EAAE,EAAE;QACzD,IAAI,mBAAmB,IAAI,UAAU,CAAC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE;YAClG,aAAa,CAAC,qBAAqB,CAAC;gBAClC,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAwB,mBAAmB;QACjE,CAAC,CAAC;YACE,CAAC,wBAAwB,CAAC,EAAE,SAAS;YACrC,OAAO;YACP,MAAM;SACP;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,kBAAkB,EAAE,UAAU,IAAK,OAAO,EAAG;AACxD,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,WAAW,GAA0D,OAAO,CAAC,mBAAmB;QACpG,CAAC,CAAC;YACE,CAAC,+BAA+B,CAAC,EAAE,OAAO,CAAC,mBAAmB;SAC/D;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,WAAW,IAAK,OAAO,EAAG;AACrC,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useContext, useRef } from 'react';\nimport { FunnelContext, FunnelStepContext, FunnelSubStepContext } from '../context/analytics-context';\nimport { DATA_ATTR_FUNNEL_INTERACTION_ID, DATA_ATTR_FUNNEL_SUBSTEP, getSubStepAllSelector } from '../selectors';\nimport { FunnelMetrics } from '../';\n\n/**\n * Custom React Hook to manage and interact with FunnelSubStep.\n * This hook will provide necessary properties and methods required\n * to track and manage interactions with a FunnelSubStep component.\n *\n * The `onFocus` method is used to track the beginning of interaction with the FunnelSubStep.\n * The `onBlur` method is used to track the completion of interaction with the FunnelSubStep.\n * The subStepId is a unique identifier for the funnel sub-step.\n * The subStepRef is a reference to the DOM element of the funnel sub-step.\n */\nexport const useFunnelSubStep = () => {\n const subStepRef = useRef<HTMLDivElement | null>(null);\n const context = useContext(FunnelSubStepContext);\n const { funnelInteractionId, subStepId, subStepSelector, subStepNameSelector, stepNumber, stepNameSelector } =\n context;\n\n const onFocus = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n funnelInteractionId &&\n subStepRef.current &&\n (!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget as Node))\n ) {\n FunnelMetrics.funnelSubStepStart({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const onBlur = (event: React.FocusEvent<HTMLDivElement>) => {\n if (funnelInteractionId && subStepRef.current && !subStepRef.current.contains(event.relatedTarget)) {\n FunnelMetrics.funnelSubStepComplete({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const funnelSubStepProps: Record<string, any> = funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_SUBSTEP]: subStepId,\n onFocus,\n onBlur,\n }\n : {};\n\n return { funnelSubStepProps, subStepRef, ...context };\n};\n\n/**\n * Custom React Hook to manage and interact with FunnelStep.\n * This hook will provide necessary properties required to track\n * and manage interactions with a FunnelStep component.\n *\n * The 'data-analytics-funnel-step' property of funnelStepProps is used to track the index of the current step in the funnel.\n * The context contains additional properties of the FunnelStep.\n */\nexport const useFunnelStep = () => {\n const context = useContext(FunnelStepContext);\n return context;\n};\n\n/**\n * Custom React Hook to manage and interact with Funnel.\n * This hook will provide necessary properties required to track\n * and manage interactions with a Funnel component.\n *\n * The 'data-analytics-funnel-interaction-id' property of funnelProps is used to track the unique identifier of the current interaction with the funnel.\n */\nexport const useFunnel = () => {\n const context = useContext(FunnelContext);\n const funnelProps: Record<string, string | number | boolean | undefined> = context.funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_INTERACTION_ID]: context.funnelInteractionId,\n }\n : {};\n\n return { funnelProps, ...context };\n};\n"]}
1
+ {"version":3,"file":"use-funnel.js","sourceRoot":"lib/default/","sources":["internal/analytics/hooks/use-funnel.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACtG,OAAO,EAAE,+BAA+B,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAChH,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,MAAM,UAAU,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;IACjD,MAAM,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAC1G,OAAO,CAAC;IAEV,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC;IAEpC,MAAM,OAAO,GAAG,CAAC,KAAuC,EAAE,EAAE;QAC1D,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAqB,CAAC,CAAC;YACnF,WAAW,CAAC,OAAO,KAAK,SAAS,EACjC;YACA,aAAa,CAAC,kBAAkB,CAAC;gBAC/B,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,KAAuC,EAAE,EAAE;QACzD,IACE,mBAAmB;YACnB,UAAU,CAAC,OAAO;YAClB,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC;YACjD,WAAW,CAAC,OAAO,KAAK,SAAS,EACjC;YACA,aAAa,CAAC,qBAAqB,CAAC;gBAClC,mBAAmB;gBACnB,eAAe;gBACf,mBAAmB;gBACnB,UAAU;gBACV,gBAAgB;gBAChB,kBAAkB,EAAE,qBAAqB,EAAE;aAC5C,CAAC,CAAC;SACJ;IACH,CAAC,CAAC;IAEF,MAAM,kBAAkB,GAAwB,mBAAmB;QACjE,CAAC,CAAC;YACE,CAAC,wBAAwB,CAAC,EAAE,SAAS;YACrC,OAAO;YACP,MAAM;SACP;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,kBAAkB,EAAE,UAAU,IAAK,OAAO,EAAG;AACxD,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE;IAChC,MAAM,OAAO,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;IAC9C,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,EAAE;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IAC1C,MAAM,WAAW,GAA0D,OAAO,CAAC,mBAAmB;QACpG,CAAC,CAAC;YACE,CAAC,+BAA+B,CAAC,EAAE,OAAO,CAAC,mBAAmB;SAC/D;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,uBAAS,WAAW,IAAK,OAAO,EAAG;AACrC,CAAC,CAAC","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { useContext, useRef } from 'react';\nimport { FunnelContext, FunnelStepContext, FunnelSubStepContext } from '../context/analytics-context';\nimport { DATA_ATTR_FUNNEL_INTERACTION_ID, DATA_ATTR_FUNNEL_SUBSTEP, getSubStepAllSelector } from '../selectors';\nimport { FunnelMetrics } from '../';\n\n/**\n * Custom React Hook to manage and interact with FunnelSubStep.\n * This hook will provide necessary properties and methods required\n * to track and manage interactions with a FunnelSubStep component.\n *\n * The `onFocus` method is used to track the beginning of interaction with the FunnelSubStep.\n * The `onBlur` method is used to track the completion of interaction with the FunnelSubStep.\n * The subStepId is a unique identifier for the funnel sub-step.\n * The subStepRef is a reference to the DOM element of the funnel sub-step.\n */\nexport const useFunnelSubStep = () => {\n const subStepRef = useRef<HTMLDivElement | null>(null);\n const context = useContext(FunnelSubStepContext);\n const { funnelInteractionId, subStepId, subStepSelector, subStepNameSelector, stepNumber, stepNameSelector } =\n context;\n\n const { funnelState } = useFunnel();\n\n const onFocus = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n funnelInteractionId &&\n subStepRef.current &&\n (!event.relatedTarget || !subStepRef.current.contains(event.relatedTarget as Node)) &&\n funnelState.current === 'default'\n ) {\n FunnelMetrics.funnelSubStepStart({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const onBlur = (event: React.FocusEvent<HTMLDivElement>) => {\n if (\n funnelInteractionId &&\n subStepRef.current &&\n !subStepRef.current.contains(event.relatedTarget) &&\n funnelState.current === 'default'\n ) {\n FunnelMetrics.funnelSubStepComplete({\n funnelInteractionId,\n subStepSelector,\n subStepNameSelector,\n stepNumber,\n stepNameSelector,\n subStepAllSelector: getSubStepAllSelector(),\n });\n }\n };\n\n const funnelSubStepProps: Record<string, any> = funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_SUBSTEP]: subStepId,\n onFocus,\n onBlur,\n }\n : {};\n\n return { funnelSubStepProps, subStepRef, ...context };\n};\n\n/**\n * Custom React Hook to manage and interact with FunnelStep.\n * This hook will provide necessary properties required to track\n * and manage interactions with a FunnelStep component.\n *\n * The 'data-analytics-funnel-step' property of funnelStepProps is used to track the index of the current step in the funnel.\n * The context contains additional properties of the FunnelStep.\n */\nexport const useFunnelStep = () => {\n const context = useContext(FunnelStepContext);\n return context;\n};\n\n/**\n * Custom React Hook to manage and interact with Funnel.\n * This hook will provide necessary properties required to track\n * and manage interactions with a Funnel component.\n *\n * The 'data-analytics-funnel-interaction-id' property of funnelProps is used to track the unique identifier of the current interaction with the funnel.\n */\nexport const useFunnel = () => {\n const context = useContext(FunnelContext);\n const funnelProps: Record<string, string | number | boolean | undefined> = context.funnelInteractionId\n ? {\n [DATA_ATTR_FUNNEL_INTERACTION_ID]: context.funnelInteractionId,\n }\n : {};\n\n return { funnelProps, ...context };\n};\n"]}