@rakeyshgidwani/roger-ui-bank-theme-stan-design 0.2.11 → 0.2.16

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 (483) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/dist/components/ui/accessibility-demo.esm.js +80 -258
  3. package/dist/components/ui/accessibility-demo.js +80 -258
  4. package/dist/components/ui/advanced-component-architecture-demo.esm.js +256 -916
  5. package/dist/components/ui/advanced-component-architecture-demo.js +256 -916
  6. package/dist/components/ui/advanced-transition-system-demo.esm.js +59 -670
  7. package/dist/components/ui/advanced-transition-system-demo.js +59 -670
  8. package/dist/components/ui/advanced-transition-system.esm.js +194 -378
  9. package/dist/components/ui/advanced-transition-system.js +194 -378
  10. package/dist/components/ui/animation/animated-container.esm.js +98 -159
  11. package/dist/components/ui/animation/animated-container.js +98 -159
  12. package/dist/components/ui/animation/index.esm.js +3 -18
  13. package/dist/components/ui/animation/index.js +3 -18
  14. package/dist/components/ui/animation/staggered-container.esm.js +37 -68
  15. package/dist/components/ui/animation/staggered-container.js +37 -68
  16. package/dist/components/ui/animation-demo.esm.js +30 -250
  17. package/dist/components/ui/animation-demo.js +30 -250
  18. package/dist/components/ui/badge.esm.js +15 -28
  19. package/dist/components/ui/badge.js +15 -28
  20. package/dist/components/ui/battery-conscious-animation-demo.esm.js +136 -565
  21. package/dist/components/ui/battery-conscious-animation-demo.js +136 -565
  22. package/dist/components/ui/border-radius-shadow-demo.esm.js +3 -184
  23. package/dist/components/ui/border-radius-shadow-demo.js +3 -184
  24. package/dist/components/ui/button.esm.js +14 -33
  25. package/dist/components/ui/button.js +14 -33
  26. package/dist/components/ui/card.esm.js +74 -188
  27. package/dist/components/ui/card.js +74 -188
  28. package/dist/components/ui/checkbox.esm.js +11 -30
  29. package/dist/components/ui/checkbox.js +11 -30
  30. package/dist/components/ui/color-preview.esm.js +50 -405
  31. package/dist/components/ui/color-preview.js +50 -405
  32. package/dist/components/ui/data-display/chart.esm.js +210 -632
  33. package/dist/components/ui/data-display/chart.js +210 -632
  34. package/dist/components/ui/data-display/data-grid-simple.esm.js +16 -74
  35. package/dist/components/ui/data-display/data-grid-simple.js +16 -74
  36. package/dist/components/ui/data-display/data-grid.esm.js +173 -661
  37. package/dist/components/ui/data-display/data-grid.js +173 -661
  38. package/dist/components/ui/data-display/list.esm.js +88 -446
  39. package/dist/components/ui/data-display/list.js +88 -446
  40. package/dist/components/ui/data-display/table.esm.js +109 -468
  41. package/dist/components/ui/data-display/table.js +109 -468
  42. package/dist/components/ui/data-display/timeline.esm.js +92 -431
  43. package/dist/components/ui/data-display/timeline.js +92 -431
  44. package/dist/components/ui/data-display/tree.esm.js +211 -585
  45. package/dist/components/ui/data-display/tree.js +211 -585
  46. package/dist/components/ui/data-display/types.esm.js +1 -530
  47. package/dist/components/ui/data-display/types.js +1 -530
  48. package/dist/components/ui/enterprise-mobile-experience-demo.esm.js +76 -749
  49. package/dist/components/ui/enterprise-mobile-experience-demo.js +76 -749
  50. package/dist/components/ui/enterprise-mobile-experience.esm.js +152 -460
  51. package/dist/components/ui/enterprise-mobile-experience.js +152 -460
  52. package/dist/components/ui/feedback/alert.esm.js +40 -148
  53. package/dist/components/ui/feedback/alert.js +40 -148
  54. package/dist/components/ui/feedback/progress.esm.js +74 -278
  55. package/dist/components/ui/feedback/progress.js +74 -278
  56. package/dist/components/ui/feedback/skeleton.esm.js +64 -173
  57. package/dist/components/ui/feedback/skeleton.js +64 -173
  58. package/dist/components/ui/feedback/toast.esm.js +86 -225
  59. package/dist/components/ui/feedback/toast.js +86 -225
  60. package/dist/components/ui/feedback/types.esm.js +1 -125
  61. package/dist/components/ui/feedback/types.js +1 -125
  62. package/dist/components/ui/font-preview.esm.js +56 -283
  63. package/dist/components/ui/font-preview.js +56 -283
  64. package/dist/components/ui/form-demo.esm.js +191 -553
  65. package/dist/components/ui/form-demo.js +191 -553
  66. package/dist/components/ui/hardware-acceleration-demo.esm.js +103 -544
  67. package/dist/components/ui/hardware-acceleration-demo.js +103 -544
  68. package/dist/components/ui/input.esm.js +13 -32
  69. package/dist/components/ui/input.js +13 -32
  70. package/dist/components/ui/label.esm.js +6 -16
  71. package/dist/components/ui/label.js +6 -16
  72. package/dist/components/ui/layout-demo.esm.js +76 -367
  73. package/dist/components/ui/layout-demo.js +76 -367
  74. package/dist/components/ui/layouts/adaptive-layout.esm.js +60 -139
  75. package/dist/components/ui/layouts/adaptive-layout.js +60 -139
  76. package/dist/components/ui/layouts/desktop-layout.esm.js +39 -224
  77. package/dist/components/ui/layouts/desktop-layout.js +39 -224
  78. package/dist/components/ui/layouts/index.esm.js +4 -10
  79. package/dist/components/ui/layouts/index.js +4 -10
  80. package/dist/components/ui/layouts/mobile-layout.esm.js +49 -162
  81. package/dist/components/ui/layouts/mobile-layout.js +49 -162
  82. package/dist/components/ui/layouts/tablet-layout.esm.js +53 -197
  83. package/dist/components/ui/layouts/tablet-layout.js +53 -197
  84. package/dist/components/ui/mobile-form-validation.esm.js +185 -420
  85. package/dist/components/ui/mobile-form-validation.js +185 -420
  86. package/dist/components/ui/mobile-input-demo.esm.js +11 -198
  87. package/dist/components/ui/mobile-input-demo.js +11 -198
  88. package/dist/components/ui/mobile-input.esm.js +187 -270
  89. package/dist/components/ui/mobile-input.js +187 -270
  90. package/dist/components/ui/mobile-skeleton-loading-demo.esm.js +144 -638
  91. package/dist/components/ui/mobile-skeleton-loading-demo.js +144 -638
  92. package/dist/components/ui/navigation/breadcrumb.esm.js +51 -154
  93. package/dist/components/ui/navigation/breadcrumb.js +51 -154
  94. package/dist/components/ui/navigation/index.esm.js +0 -3
  95. package/dist/components/ui/navigation/index.js +0 -3
  96. package/dist/components/ui/navigation/menu.esm.js +178 -365
  97. package/dist/components/ui/navigation/menu.js +178 -365
  98. package/dist/components/ui/navigation/navigation-demo.esm.js +130 -315
  99. package/dist/components/ui/navigation/navigation-demo.js +130 -315
  100. package/dist/components/ui/navigation/pagination.esm.js +142 -264
  101. package/dist/components/ui/navigation/pagination.js +142 -264
  102. package/dist/components/ui/navigation/sidebar.esm.js +156 -368
  103. package/dist/components/ui/navigation/sidebar.js +156 -368
  104. package/dist/components/ui/navigation/stepper.esm.js +131 -295
  105. package/dist/components/ui/navigation/stepper.js +131 -295
  106. package/dist/components/ui/navigation/tabs.esm.js +89 -198
  107. package/dist/components/ui/navigation/tabs.js +89 -198
  108. package/dist/components/ui/navigation/types.esm.js +1 -295
  109. package/dist/components/ui/navigation/types.js +1 -295
  110. package/dist/components/ui/overlay/backdrop.esm.js +39 -78
  111. package/dist/components/ui/overlay/backdrop.js +39 -78
  112. package/dist/components/ui/overlay/focus-manager.esm.js +96 -140
  113. package/dist/components/ui/overlay/focus-manager.js +96 -140
  114. package/dist/components/ui/overlay/index.esm.js +0 -5
  115. package/dist/components/ui/overlay/index.js +0 -5
  116. package/dist/components/ui/overlay/modal.esm.js +94 -249
  117. package/dist/components/ui/overlay/modal.js +94 -249
  118. package/dist/components/ui/overlay/overlay-manager.esm.js +60 -100
  119. package/dist/components/ui/overlay/overlay-manager.js +60 -100
  120. package/dist/components/ui/overlay/popover.esm.js +258 -438
  121. package/dist/components/ui/overlay/popover.js +258 -438
  122. package/dist/components/ui/overlay/portal.esm.js +45 -74
  123. package/dist/components/ui/overlay/portal.js +45 -74
  124. package/dist/components/ui/overlay/tooltip.esm.js +202 -288
  125. package/dist/components/ui/overlay/tooltip.js +202 -288
  126. package/dist/components/ui/overlay/types.esm.js +1 -196
  127. package/dist/components/ui/overlay/types.js +1 -196
  128. package/dist/components/ui/performance-demo.esm.js +110 -596
  129. package/dist/components/ui/performance-demo.js +110 -596
  130. package/dist/components/ui/semantic-input-system-demo.esm.js +87 -501
  131. package/dist/components/ui/semantic-input-system-demo.js +87 -501
  132. package/dist/components/ui/theme-customizer.esm.js +123 -371
  133. package/dist/components/ui/theme-customizer.js +123 -371
  134. package/dist/components/ui/theme-preview.esm.js +44 -306
  135. package/dist/components/ui/theme-preview.js +44 -306
  136. package/dist/components/ui/theme-switcher.esm.js +79 -258
  137. package/dist/components/ui/theme-switcher.js +79 -258
  138. package/dist/components/ui/theme-toggle.esm.js +22 -35
  139. package/dist/components/ui/theme-toggle.js +22 -35
  140. package/dist/components/ui/token-demo.esm.js +42 -189
  141. package/dist/components/ui/token-demo.js +42 -189
  142. package/dist/components/ui/touch-demo.esm.js +96 -462
  143. package/dist/components/ui/touch-demo.js +96 -462
  144. package/dist/components/ui/touch-friendly-interface-demo.esm.js +63 -519
  145. package/dist/components/ui/touch-friendly-interface-demo.js +63 -519
  146. package/dist/components/ui/touch-friendly-interface.esm.js +103 -281
  147. package/dist/components/ui/touch-friendly-interface.js +103 -281
  148. package/dist/hooks/index.esm.js +23 -181
  149. package/dist/hooks/index.js +23 -181
  150. package/dist/hooks/use-accessibility-support.esm.js +377 -518
  151. package/dist/hooks/use-accessibility-support.js +377 -518
  152. package/dist/hooks/use-adaptive-layout.esm.js +212 -287
  153. package/dist/hooks/use-adaptive-layout.js +212 -287
  154. package/dist/hooks/use-advanced-patterns.esm.js +185 -293
  155. package/dist/hooks/use-advanced-patterns.js +185 -293
  156. package/dist/hooks/use-advanced-transition-system.esm.js +286 -392
  157. package/dist/hooks/use-advanced-transition-system.js +286 -392
  158. package/dist/hooks/use-animation-profile.esm.js +221 -283
  159. package/dist/hooks/use-animation-profile.js +221 -283
  160. package/dist/hooks/use-battery-animations.esm.js +310 -384
  161. package/dist/hooks/use-battery-animations.js +310 -384
  162. package/dist/hooks/use-battery-conscious-loading.esm.js +374 -468
  163. package/dist/hooks/use-battery-conscious-loading.js +374 -468
  164. package/dist/hooks/use-battery-optimization.esm.js +267 -329
  165. package/dist/hooks/use-battery-optimization.js +267 -329
  166. package/dist/hooks/use-battery-status.esm.js +213 -293
  167. package/dist/hooks/use-battery-status.js +213 -293
  168. package/dist/hooks/use-component-performance.esm.js +235 -341
  169. package/dist/hooks/use-component-performance.js +235 -341
  170. package/dist/hooks/use-device-loading-states.esm.js +356 -457
  171. package/dist/hooks/use-device-loading-states.js +356 -457
  172. package/dist/hooks/use-device.esm.js +77 -102
  173. package/dist/hooks/use-device.js +77 -102
  174. package/dist/hooks/use-enterprise-mobile-experience.esm.js +349 -487
  175. package/dist/hooks/use-enterprise-mobile-experience.js +349 -487
  176. package/dist/hooks/use-form-feedback.esm.js +313 -398
  177. package/dist/hooks/use-form-feedback.js +313 -398
  178. package/dist/hooks/use-form-performance.esm.js +407 -500
  179. package/dist/hooks/use-form-performance.js +407 -500
  180. package/dist/hooks/use-frame-rate.esm.js +178 -251
  181. package/dist/hooks/use-frame-rate.js +178 -251
  182. package/dist/hooks/use-gestures.esm.js +230 -332
  183. package/dist/hooks/use-gestures.js +230 -332
  184. package/dist/hooks/use-hardware-acceleration.esm.js +246 -339
  185. package/dist/hooks/use-hardware-acceleration.js +246 -339
  186. package/dist/hooks/use-input-accessibility.esm.js +350 -454
  187. package/dist/hooks/use-input-accessibility.js +350 -454
  188. package/dist/hooks/use-input-performance.esm.js +419 -502
  189. package/dist/hooks/use-input-performance.js +419 -502
  190. package/dist/hooks/use-layout-performance.esm.js +233 -319
  191. package/dist/hooks/use-layout-performance.js +233 -319
  192. package/dist/hooks/use-loading-accessibility.esm.js +421 -531
  193. package/dist/hooks/use-loading-accessibility.js +421 -531
  194. package/dist/hooks/use-loading-performance.esm.js +398 -469
  195. package/dist/hooks/use-loading-performance.js +398 -469
  196. package/dist/hooks/use-memory-usage.esm.js +211 -287
  197. package/dist/hooks/use-memory-usage.js +211 -287
  198. package/dist/hooks/use-mobile-form-layout.esm.js +365 -458
  199. package/dist/hooks/use-mobile-form-layout.js +365 -458
  200. package/dist/hooks/use-mobile-form-validation.esm.js +384 -497
  201. package/dist/hooks/use-mobile-form-validation.js +384 -497
  202. package/dist/hooks/use-mobile-keyboard-optimization.esm.js +354 -468
  203. package/dist/hooks/use-mobile-keyboard-optimization.js +354 -468
  204. package/dist/hooks/use-mobile-layout.esm.js +207 -294
  205. package/dist/hooks/use-mobile-layout.js +207 -294
  206. package/dist/hooks/use-mobile-optimization.esm.js +308 -404
  207. package/dist/hooks/use-mobile-optimization.js +308 -404
  208. package/dist/hooks/use-mobile-skeleton.esm.js +300 -402
  209. package/dist/hooks/use-mobile-skeleton.js +300 -402
  210. package/dist/hooks/use-mobile-touch.esm.js +314 -412
  211. package/dist/hooks/use-mobile-touch.js +314 -412
  212. package/dist/hooks/use-performance-throttling.esm.js +276 -344
  213. package/dist/hooks/use-performance-throttling.js +276 -344
  214. package/dist/hooks/use-performance.esm.js +216 -313
  215. package/dist/hooks/use-performance.js +216 -313
  216. package/dist/hooks/use-reusable-architecture.esm.js +255 -408
  217. package/dist/hooks/use-reusable-architecture.js +255 -408
  218. package/dist/hooks/use-semantic-input-types.esm.js +290 -356
  219. package/dist/hooks/use-semantic-input-types.js +290 -356
  220. package/dist/hooks/use-semantic-input.esm.js +446 -549
  221. package/dist/hooks/use-semantic-input.js +446 -549
  222. package/dist/hooks/use-tablet-layout.esm.js +279 -384
  223. package/dist/hooks/use-tablet-layout.js +279 -384
  224. package/dist/hooks/use-touch-friendly-input.esm.js +401 -519
  225. package/dist/hooks/use-touch-friendly-input.js +401 -519
  226. package/dist/hooks/use-touch-friendly-interface.esm.js +242 -331
  227. package/dist/hooks/use-touch-friendly-interface.js +242 -331
  228. package/dist/hooks/use-touch-optimization.esm.js +288 -370
  229. package/dist/hooks/use-touch-optimization.js +288 -370
  230. package/dist/index.esm.js +150 -161
  231. package/dist/index.js +150 -161
  232. package/dist/lib/utils.esm.js +4 -5
  233. package/dist/lib/utils.js +4 -5
  234. package/dist/plugins/theme-css-generator.esm.js +292 -346
  235. package/dist/plugins/theme-css-generator.js +292 -346
  236. package/dist/provider.esm.js +3 -19
  237. package/dist/provider.js +3 -19
  238. package/dist/styles/layers/validation.esm.js +275 -0
  239. package/dist/styles/layers/validation.js +275 -0
  240. package/dist/styles.css +1 -1
  241. package/dist/theme.esm.js +654 -658
  242. package/dist/theme.js +654 -658
  243. package/dist/themes/ThemeContext.esm.js +1 -27
  244. package/dist/themes/ThemeContext.js +1 -27
  245. package/dist/themes/ThemeProvider.esm.js +191 -223
  246. package/dist/themes/ThemeProvider.js +191 -223
  247. package/dist/themes/accessibility/index.esm.js +0 -4
  248. package/dist/themes/accessibility/index.js +0 -4
  249. package/dist/themes/accessibility.esm.js +175 -240
  250. package/dist/themes/accessibility.js +175 -240
  251. package/dist/themes/aria-patterns.esm.js +345 -401
  252. package/dist/themes/aria-patterns.js +345 -401
  253. package/dist/themes/base-themes.esm.js +15 -24
  254. package/dist/themes/base-themes.js +15 -24
  255. package/dist/themes/colorManager.esm.js +293 -357
  256. package/dist/themes/colorManager.js +293 -357
  257. package/dist/themes/examples/dark-theme.esm.js +129 -133
  258. package/dist/themes/examples/dark-theme.js +129 -133
  259. package/dist/themes/examples/minimal-theme.esm.js +80 -85
  260. package/dist/themes/examples/minimal-theme.js +80 -85
  261. package/dist/themes/focus-management.esm.js +541 -677
  262. package/dist/themes/focus-management.js +541 -677
  263. package/dist/themes/fontLoader.esm.js +151 -180
  264. package/dist/themes/fontLoader.js +151 -180
  265. package/dist/themes/high-contrast.esm.js +394 -558
  266. package/dist/themes/high-contrast.js +394 -558
  267. package/dist/themes/index.esm.js +1 -9
  268. package/dist/themes/index.js +1 -9
  269. package/dist/themes/inheritance.esm.js +145 -180
  270. package/dist/themes/inheritance.js +145 -180
  271. package/dist/themes/keyboard-navigation.esm.js +418 -510
  272. package/dist/themes/keyboard-navigation.js +418 -510
  273. package/dist/themes/motion-reduction.esm.js +434 -591
  274. package/dist/themes/motion-reduction.js +434 -591
  275. package/dist/themes/navigation.esm.js +1 -234
  276. package/dist/themes/navigation.js +1 -234
  277. package/dist/themes/screen-reader.esm.js +515 -616
  278. package/dist/themes/screen-reader.js +515 -616
  279. package/dist/themes/systemThemeDetector.esm.js +135 -164
  280. package/dist/themes/systemThemeDetector.js +135 -164
  281. package/dist/themes/themeCSSUpdater.esm.js +217 -252
  282. package/dist/themes/themeCSSUpdater.js +217 -252
  283. package/dist/themes/themePersistence.esm.js +181 -212
  284. package/dist/themes/themePersistence.js +181 -212
  285. package/dist/themes/themes/default.esm.js +584 -0
  286. package/dist/themes/themes/default.js +584 -0
  287. package/dist/themes/themes/harvey.esm.js +551 -0
  288. package/dist/themes/themes/harvey.js +551 -0
  289. package/dist/themes/themes/stan-design.esm.js +654 -658
  290. package/dist/themes/themes/stan-design.js +654 -658
  291. package/dist/themes/types.esm.js +1 -458
  292. package/dist/themes/types.js +1 -458
  293. package/dist/themes/useSystemTheme.esm.js +34 -42
  294. package/dist/themes/useSystemTheme.js +34 -42
  295. package/dist/themes/useTheme.esm.js +23 -28
  296. package/dist/themes/useTheme.js +23 -28
  297. package/dist/themes/validation.esm.js +380 -433
  298. package/dist/themes/validation.js +380 -433
  299. package/dist/tokens/index.esm.js +2 -13
  300. package/dist/tokens/index.js +2 -13
  301. package/dist/tokens/tokenExporter.esm.js +309 -373
  302. package/dist/tokens/tokenExporter.js +309 -373
  303. package/dist/tokens/tokenGenerator.esm.js +241 -273
  304. package/dist/tokens/tokenGenerator.js +241 -273
  305. package/dist/tokens/tokenManager.esm.js +187 -241
  306. package/dist/tokens/tokenManager.js +187 -241
  307. package/dist/tokens/tokenValidator.esm.js +402 -522
  308. package/dist/tokens/tokenValidator.js +402 -522
  309. package/dist/tokens/types.esm.js +1 -78
  310. package/dist/tokens/types.js +1 -78
  311. package/dist/types.esm.js +3 -0
  312. package/dist/types.js +3 -0
  313. package/dist/utils/bundle-analyzer.esm.js +188 -246
  314. package/dist/utils/bundle-analyzer.js +188 -246
  315. package/dist/utils/bundle-splitting.esm.js +330 -458
  316. package/dist/utils/bundle-splitting.js +330 -458
  317. package/dist/utils/lazy-loading.esm.js +311 -417
  318. package/dist/utils/lazy-loading.js +311 -417
  319. package/dist/utils/performance-monitor.esm.js +369 -490
  320. package/dist/utils/performance-monitor.js +369 -490
  321. package/dist/utils/tree-shaking.esm.js +194 -264
  322. package/dist/utils/tree-shaking.js +194 -264
  323. package/package.json +18 -2
  324. package/src/index.ts +150 -149
  325. package/src/provider.tsx +3 -3
  326. package/src/theme.ts +1 -1
  327. package/{dist/theme.d.ts → src/themes/themes/default.ts} +77 -169
  328. package/src/themes/themes/harvey.ts +554 -0
  329. package/{dist/themes/types.d.ts → src/types.ts} +7 -1
  330. package/dist/components/ui/accessibility-demo.d.ts +0 -259
  331. package/dist/components/ui/advanced-component-architecture-demo.d.ts +0 -718
  332. package/dist/components/ui/advanced-transition-system-demo.d.ts +0 -660
  333. package/dist/components/ui/advanced-transition-system.d.ts +0 -391
  334. package/dist/components/ui/animation/animated-container.d.ts +0 -162
  335. package/dist/components/ui/animation/index.d.ts +0 -9
  336. package/dist/components/ui/animation/staggered-container.d.ts +0 -64
  337. package/dist/components/ui/animation-demo.d.ts +0 -238
  338. package/dist/components/ui/badge.d.ts +0 -28
  339. package/dist/components/ui/battery-conscious-animation-demo.d.ts +0 -561
  340. package/dist/components/ui/border-radius-shadow-demo.d.ts +0 -183
  341. package/dist/components/ui/button.d.ts +0 -33
  342. package/dist/components/ui/card.d.ts +0 -205
  343. package/dist/components/ui/checkbox.d.ts +0 -26
  344. package/dist/components/ui/color-preview.d.ts +0 -402
  345. package/dist/components/ui/data-display/chart.d.ts +0 -646
  346. package/dist/components/ui/data-display/data-grid-simple.d.ts +0 -73
  347. package/dist/components/ui/data-display/data-grid.d.ts +0 -670
  348. package/dist/components/ui/data-display/list.d.ts +0 -448
  349. package/dist/components/ui/data-display/table.d.ts +0 -472
  350. package/dist/components/ui/data-display/timeline.d.ts +0 -433
  351. package/dist/components/ui/data-display/tree.d.ts +0 -594
  352. package/dist/components/ui/data-display/types.d.ts +0 -534
  353. package/dist/components/ui/enterprise-mobile-experience-demo.d.ts +0 -735
  354. package/dist/components/ui/enterprise-mobile-experience.d.ts +0 -461
  355. package/dist/components/ui/feedback/alert.d.ts +0 -154
  356. package/dist/components/ui/feedback/progress.d.ts +0 -288
  357. package/dist/components/ui/feedback/skeleton.d.ts +0 -182
  358. package/dist/components/ui/feedback/toast.d.ts +0 -277
  359. package/dist/components/ui/feedback/types.d.ts +0 -123
  360. package/dist/components/ui/font-preview.d.ts +0 -282
  361. package/dist/components/ui/form-demo.d.ts +0 -544
  362. package/dist/components/ui/hardware-acceleration-demo.d.ts +0 -540
  363. package/dist/components/ui/input.d.ts +0 -33
  364. package/dist/components/ui/label.d.ts +0 -13
  365. package/dist/components/ui/layout-demo.d.ts +0 -352
  366. package/dist/components/ui/layouts/adaptive-layout.d.ts +0 -132
  367. package/dist/components/ui/layouts/desktop-layout.d.ts +0 -219
  368. package/dist/components/ui/layouts/index.d.ts +0 -5
  369. package/dist/components/ui/layouts/mobile-layout.d.ts +0 -158
  370. package/dist/components/ui/layouts/tablet-layout.d.ts +0 -192
  371. package/dist/components/ui/mobile-form-validation.d.ts +0 -439
  372. package/dist/components/ui/mobile-input-demo.d.ts +0 -197
  373. package/dist/components/ui/mobile-input.d.ts +0 -273
  374. package/dist/components/ui/mobile-skeleton-loading-demo.d.ts +0 -628
  375. package/dist/components/ui/navigation/breadcrumb.d.ts +0 -149
  376. package/dist/components/ui/navigation/index.d.ts +0 -25
  377. package/dist/components/ui/navigation/menu.d.ts +0 -366
  378. package/dist/components/ui/navigation/navigation-demo.d.ts +0 -169
  379. package/dist/components/ui/navigation/pagination.d.ts +0 -261
  380. package/dist/components/ui/navigation/sidebar.d.ts +0 -375
  381. package/dist/components/ui/navigation/stepper.d.ts +0 -294
  382. package/dist/components/ui/navigation/tabs.d.ts +0 -196
  383. package/dist/components/ui/navigation/types.d.ts +0 -293
  384. package/dist/components/ui/overlay/backdrop.d.ts +0 -79
  385. package/dist/components/ui/overlay/focus-manager.d.ts +0 -141
  386. package/dist/components/ui/overlay/index.d.ts +0 -27
  387. package/dist/components/ui/overlay/modal.d.ts +0 -262
  388. package/dist/components/ui/overlay/overlay-manager.d.ts +0 -107
  389. package/dist/components/ui/overlay/popover.d.ts +0 -450
  390. package/dist/components/ui/overlay/portal.d.ts +0 -75
  391. package/dist/components/ui/overlay/tooltip.d.ts +0 -298
  392. package/dist/components/ui/overlay/types.d.ts +0 -194
  393. package/dist/components/ui/performance-demo.d.ts +0 -583
  394. package/dist/components/ui/semantic-input-system-demo.d.ts +0 -490
  395. package/dist/components/ui/theme-customizer.d.ts +0 -378
  396. package/dist/components/ui/theme-preview.d.ts +0 -305
  397. package/dist/components/ui/theme-switcher.d.ts +0 -259
  398. package/dist/components/ui/theme-toggle.d.ts +0 -34
  399. package/dist/components/ui/token-demo.d.ts +0 -188
  400. package/dist/components/ui/touch-demo.d.ts +0 -455
  401. package/dist/components/ui/touch-friendly-interface-demo.d.ts +0 -512
  402. package/dist/components/ui/touch-friendly-interface.d.ts +0 -292
  403. package/dist/hooks/index.d.ts +0 -161
  404. package/dist/hooks/use-accessibility-support.d.ts +0 -516
  405. package/dist/hooks/use-adaptive-layout.d.ts +0 -287
  406. package/dist/hooks/use-advanced-patterns.d.ts +0 -292
  407. package/dist/hooks/use-advanced-transition-system.d.ts +0 -390
  408. package/dist/hooks/use-animation-profile.d.ts +0 -285
  409. package/dist/hooks/use-battery-animations.d.ts +0 -382
  410. package/dist/hooks/use-battery-conscious-loading.d.ts +0 -473
  411. package/dist/hooks/use-battery-optimization.d.ts +0 -328
  412. package/dist/hooks/use-battery-status.d.ts +0 -297
  413. package/dist/hooks/use-component-performance.d.ts +0 -342
  414. package/dist/hooks/use-device-loading-states.d.ts +0 -456
  415. package/dist/hooks/use-device.d.ts +0 -104
  416. package/dist/hooks/use-enterprise-mobile-experience.d.ts +0 -486
  417. package/dist/hooks/use-form-feedback.d.ts +0 -401
  418. package/dist/hooks/use-form-performance.d.ts +0 -511
  419. package/dist/hooks/use-frame-rate.d.ts +0 -249
  420. package/dist/hooks/use-gestures.d.ts +0 -336
  421. package/dist/hooks/use-hardware-acceleration.d.ts +0 -339
  422. package/dist/hooks/use-input-accessibility.d.ts +0 -451
  423. package/dist/hooks/use-input-performance.d.ts +0 -503
  424. package/dist/hooks/use-layout-performance.d.ts +0 -317
  425. package/dist/hooks/use-loading-accessibility.d.ts +0 -532
  426. package/dist/hooks/use-loading-performance.d.ts +0 -471
  427. package/dist/hooks/use-memory-usage.d.ts +0 -285
  428. package/dist/hooks/use-mobile-form-layout.d.ts +0 -462
  429. package/dist/hooks/use-mobile-form-validation.d.ts +0 -516
  430. package/dist/hooks/use-mobile-keyboard-optimization.d.ts +0 -469
  431. package/dist/hooks/use-mobile-layout.d.ts +0 -300
  432. package/dist/hooks/use-mobile-optimization.d.ts +0 -404
  433. package/dist/hooks/use-mobile-skeleton.d.ts +0 -399
  434. package/dist/hooks/use-mobile-touch.d.ts +0 -412
  435. package/dist/hooks/use-performance-throttling.d.ts +0 -346
  436. package/dist/hooks/use-performance.d.ts +0 -314
  437. package/dist/hooks/use-reusable-architecture.d.ts +0 -412
  438. package/dist/hooks/use-semantic-input-types.d.ts +0 -354
  439. package/dist/hooks/use-semantic-input.d.ts +0 -563
  440. package/dist/hooks/use-tablet-layout.d.ts +0 -382
  441. package/dist/hooks/use-touch-friendly-input.d.ts +0 -520
  442. package/dist/hooks/use-touch-friendly-interface.d.ts +0 -329
  443. package/dist/hooks/use-touch-optimization.d.ts +0 -373
  444. package/dist/index.d.ts +0 -149
  445. package/dist/lib/utils.d.ts +0 -3
  446. package/dist/plugins/theme-css-generator.d.ts +0 -345
  447. package/dist/provider.d.ts +0 -17
  448. package/dist/themes/ThemeContext.d.ts +0 -27
  449. package/dist/themes/ThemeProvider.d.ts +0 -222
  450. package/dist/themes/accessibility/index.d.ts +0 -7
  451. package/dist/themes/accessibility.d.ts +0 -259
  452. package/dist/themes/aria-patterns.d.ts +0 -418
  453. package/dist/themes/base-themes.d.ts +0 -34
  454. package/dist/themes/colorManager.d.ts +0 -327
  455. package/dist/themes/examples/dark-theme.d.ts +0 -139
  456. package/dist/themes/examples/minimal-theme.d.ts +0 -93
  457. package/dist/themes/focus-management.d.ts +0 -699
  458. package/dist/themes/fontLoader.d.ts +0 -163
  459. package/dist/themes/high-contrast.d.ts +0 -619
  460. package/dist/themes/index.d.ts +0 -11
  461. package/dist/themes/inheritance.d.ts +0 -160
  462. package/dist/themes/keyboard-navigation.d.ts +0 -550
  463. package/dist/themes/motion-reduction.d.ts +0 -660
  464. package/dist/themes/navigation.d.ts +0 -232
  465. package/dist/themes/screen-reader.d.ts +0 -645
  466. package/dist/themes/systemThemeDetector.d.ts +0 -148
  467. package/dist/themes/themeCSSUpdater.d.ts +0 -229
  468. package/dist/themes/themePersistence.d.ts +0 -192
  469. package/dist/themes/themes/stan-design.d.ts +0 -678
  470. package/dist/themes/useSystemTheme.d.ts +0 -43
  471. package/dist/themes/useTheme.d.ts +0 -20
  472. package/dist/themes/validation.d.ts +0 -406
  473. package/dist/tokens/index.d.ts +0 -25
  474. package/dist/tokens/tokenExporter.d.ts +0 -336
  475. package/dist/tokens/tokenGenerator.d.ts +0 -250
  476. package/dist/tokens/tokenManager.d.ts +0 -194
  477. package/dist/tokens/tokenValidator.d.ts +0 -488
  478. package/dist/tokens/types.d.ts +0 -78
  479. package/dist/utils/bundle-analyzer.d.ts +0 -260
  480. package/dist/utils/bundle-splitting.d.ts +0 -483
  481. package/dist/utils/lazy-loading.d.ts +0 -437
  482. package/dist/utils/performance-monitor.d.ts +0 -513
  483. package/dist/utils/tree-shaking.d.ts +0 -274
@@ -1,701 +1,565 @@
1
1
  import { screenReaderOptimizer } from './screen-reader';
2
-
3
2
  // Focus management utilities
4
3
  export class AccessibilityFocusManager {
5
- private focusableSelectors: string[];
6
- private focusableElements: HTMLElement[];
7
- private lastFocusedElement: HTMLElement | null;
8
- private focusTraps: Map<string, FocusTrap>;
9
- private focusHistory: HTMLElement[];
10
- private maxHistorySize: number;
11
-
12
- constructor() {
13
- this.focusableSelectors = [
14
- 'a[href]',
15
- 'button:not([disabled])',
16
- 'input:not([disabled])',
17
- 'select:not([disabled])',
18
- 'textarea:not([disabled])',
19
- '[tabindex]:not([tabindex="-1"])',
20
- '[contenteditable="true"]',
21
- 'audio[controls]',
22
- 'video[controls]',
23
- 'iframe'
24
- ];
25
-
26
- this.focusableElements = [];
27
- this.lastFocusedElement = null;
28
- this.focusTraps = new Map();
29
- this.focusHistory = [];
30
- this.maxHistorySize = 10;
31
-
32
- this.initialize();
33
- }
34
-
35
- // Initialize focus management
36
- private initialize(): void {
37
- this.updateFocusableElements();
38
- this.setupEventListeners();
39
- }
40
-
41
- // Update list of focusable elements
42
- private updateFocusableElements(): void {
43
- this.focusableElements = Array.from(
44
- document.querySelectorAll(this.focusableSelectors.join(','))
45
- ) as HTMLElement[];
46
- }
47
-
48
- // Setup event listeners
49
- private setupEventListeners(): void {
50
- // Track focus changes
51
- document.addEventListener('focusin', this.handleFocusIn.bind(this));
52
- document.addEventListener('focusout', this.handleFocusOut.bind(this));
53
-
54
- // Handle tab key navigation
55
- document.addEventListener('keydown', this.handleKeyDown.bind(this));
56
-
57
- // Update focusable elements when DOM changes
58
- const observer = new MutationObserver(() => {
59
- this.updateFocusableElements();
60
- });
61
-
62
- observer.observe(document.body, {
63
- childList: true,
64
- subtree: true
65
- });
66
- }
67
-
68
- // Handle focus in events
69
- private handleFocusIn(event: FocusEvent): void {
70
- const target = event.target as HTMLElement;
71
-
72
- if (target && target !== this.lastFocusedElement) {
73
- // Add to focus history
74
- this.addToFocusHistory(target);
75
-
76
- // Update last focused element
77
- this.lastFocusedElement = target;
78
-
79
- // Announce focus change for screen readers
80
- if (screenReaderOptimizer) {
81
- screenReaderOptimizer.announceFocusChange(
82
- this.getElementDescription(target),
83
- this.getElementContext(target)
84
- );
85
- }
86
- }
87
- }
88
-
89
- // Handle focus out events
90
- private handleFocusOut(_event: FocusEvent): void {
91
- // Focus out handling if needed
92
- }
93
-
94
- // Handle key down events
95
- private handleKeyDown(event: KeyboardEvent): void {
96
- if (event.key === 'Tab') {
97
- this.handleTabNavigation(event);
98
- }
99
- }
100
-
101
- // Handle tab navigation
102
- private handleTabNavigation(event: KeyboardEvent): void {
103
- const isShiftTab = event.shiftKey;
104
- const currentElement = event.target as HTMLElement;
105
-
106
- // Check if we're in a focus trap
107
- const activeTrap = this.getActiveFocusTrap(currentElement);
108
- if (activeTrap) {
109
- event.preventDefault();
110
- this.navigateInFocusTrap(activeTrap, isShiftTab);
111
- return;
112
- }
113
-
114
- // Normal tab navigation
115
- this.navigateFocusableElements(isShiftTab);
116
- }
117
-
118
- // Get active focus trap for element
119
- private getActiveFocusTrap(element: HTMLElement): FocusTrap | null {
120
- for (const trap of this.focusTraps.values()) {
121
- if (trap.isActive && trap.container.contains(element)) {
4
+ constructor() {
5
+ this.focusableSelectors = [
6
+ 'a[href]',
7
+ 'button:not([disabled])',
8
+ 'input:not([disabled])',
9
+ 'select:not([disabled])',
10
+ 'textarea:not([disabled])',
11
+ '[tabindex]:not([tabindex="-1"])',
12
+ '[contenteditable="true"]',
13
+ 'audio[controls]',
14
+ 'video[controls]',
15
+ 'iframe'
16
+ ];
17
+ this.focusableElements = [];
18
+ this.lastFocusedElement = null;
19
+ this.focusTraps = new Map();
20
+ this.focusHistory = [];
21
+ this.maxHistorySize = 10;
22
+ this.initialize();
23
+ }
24
+ // Initialize focus management
25
+ initialize() {
26
+ this.updateFocusableElements();
27
+ this.setupEventListeners();
28
+ }
29
+ // Update list of focusable elements
30
+ updateFocusableElements() {
31
+ this.focusableElements = Array.from(document.querySelectorAll(this.focusableSelectors.join(',')));
32
+ }
33
+ // Setup event listeners
34
+ setupEventListeners() {
35
+ // Track focus changes
36
+ document.addEventListener('focusin', this.handleFocusIn.bind(this));
37
+ document.addEventListener('focusout', this.handleFocusOut.bind(this));
38
+ // Handle tab key navigation
39
+ document.addEventListener('keydown', this.handleKeyDown.bind(this));
40
+ // Update focusable elements when DOM changes
41
+ const observer = new MutationObserver(() => {
42
+ this.updateFocusableElements();
43
+ });
44
+ observer.observe(document.body, {
45
+ childList: true,
46
+ subtree: true
47
+ });
48
+ }
49
+ // Handle focus in events
50
+ handleFocusIn(event) {
51
+ const target = event.target;
52
+ if (target && target !== this.lastFocusedElement) {
53
+ // Add to focus history
54
+ this.addToFocusHistory(target);
55
+ // Update last focused element
56
+ this.lastFocusedElement = target;
57
+ // Announce focus change for screen readers
58
+ if (screenReaderOptimizer) {
59
+ screenReaderOptimizer.announceFocusChange(this.getElementDescription(target), this.getElementContext(target));
60
+ }
61
+ }
62
+ }
63
+ // Handle focus out events
64
+ handleFocusOut(_event) {
65
+ // Focus out handling if needed
66
+ }
67
+ // Handle key down events
68
+ handleKeyDown(event) {
69
+ if (event.key === 'Tab') {
70
+ this.handleTabNavigation(event);
71
+ }
72
+ }
73
+ // Handle tab navigation
74
+ handleTabNavigation(event) {
75
+ const isShiftTab = event.shiftKey;
76
+ const currentElement = event.target;
77
+ // Check if we're in a focus trap
78
+ const activeTrap = this.getActiveFocusTrap(currentElement);
79
+ if (activeTrap) {
80
+ event.preventDefault();
81
+ this.navigateInFocusTrap(activeTrap, isShiftTab);
82
+ return;
83
+ }
84
+ // Normal tab navigation
85
+ this.navigateFocusableElements(isShiftTab);
86
+ }
87
+ // Get active focus trap for element
88
+ getActiveFocusTrap(element) {
89
+ for (const trap of this.focusTraps.values()) {
90
+ if (trap.isActive && trap.container.contains(element)) {
91
+ return trap;
92
+ }
93
+ }
94
+ return null;
95
+ }
96
+ // Navigate within a focus trap
97
+ navigateInFocusTrap(trap, isShiftTab) {
98
+ const focusableElements = trap.getFocusableElements();
99
+ if (focusableElements.length === 0)
100
+ return;
101
+ const currentIndex = focusableElements.indexOf(document.activeElement);
102
+ let nextIndex;
103
+ if (isShiftTab) {
104
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : focusableElements.length - 1;
105
+ }
106
+ else {
107
+ nextIndex = currentIndex < focusableElements.length - 1 ? currentIndex + 1 : 0;
108
+ }
109
+ focusableElements[nextIndex]?.focus();
110
+ }
111
+ // Navigate focusable elements
112
+ navigateFocusableElements(isShiftTab) {
113
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
114
+ let nextIndex;
115
+ if (isShiftTab) {
116
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
117
+ }
118
+ else {
119
+ nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
120
+ }
121
+ this.focusableElements[nextIndex]?.focus();
122
+ }
123
+ // Add element to focus history
124
+ addToFocusHistory(element) {
125
+ // Remove if already exists
126
+ this.focusHistory = this.focusHistory.filter(el => el !== element);
127
+ // Add to beginning
128
+ this.focusHistory.unshift(element);
129
+ // Maintain history size
130
+ if (this.focusHistory.length > this.maxHistorySize) {
131
+ this.focusHistory.pop();
132
+ }
133
+ }
134
+ // Get element description for screen readers
135
+ getElementDescription(element) {
136
+ const ariaLabel = element.getAttribute('aria-label');
137
+ if (ariaLabel)
138
+ return ariaLabel;
139
+ const ariaLabelledBy = element.getAttribute('aria-labelledby');
140
+ if (ariaLabelledBy) {
141
+ const labelElement = document.getElementById(ariaLabelledBy);
142
+ if (labelElement)
143
+ return labelElement.textContent || '';
144
+ }
145
+ const placeholder = element.getAttribute('placeholder');
146
+ if (placeholder)
147
+ return placeholder;
148
+ const title = element.getAttribute('title');
149
+ if (title)
150
+ return title;
151
+ return element.textContent || element.tagName.toLowerCase();
152
+ }
153
+ // Get element context for screen readers
154
+ getElementContext(element) {
155
+ // Find nearest landmark or section
156
+ const landmark = element.closest('[role], section, article, aside, nav, header, footer, main');
157
+ if (landmark) {
158
+ const role = landmark.getAttribute('role');
159
+ const ariaLabel = landmark.getAttribute('aria-label');
160
+ return ariaLabel || role || landmark.tagName.toLowerCase();
161
+ }
162
+ return undefined;
163
+ }
164
+ // Create focus trap
165
+ createFocusTrap(container, options = {}) {
166
+ const trap = new FocusTrap(container, options);
167
+ this.focusTraps.set(trap.id, trap);
122
168
  return trap;
123
- }
124
- }
125
- return null;
126
- }
127
-
128
- // Navigate within a focus trap
129
- private navigateInFocusTrap(trap: FocusTrap, isShiftTab: boolean): void {
130
- const focusableElements = trap.getFocusableElements();
131
- if (focusableElements.length === 0) return;
132
-
133
- const currentIndex = focusableElements.indexOf(document.activeElement as HTMLElement);
134
- let nextIndex: number;
135
-
136
- if (isShiftTab) {
137
- nextIndex = currentIndex > 0 ? currentIndex - 1 : focusableElements.length - 1;
138
- } else {
139
- nextIndex = currentIndex < focusableElements.length - 1 ? currentIndex + 1 : 0;
140
- }
141
-
142
- focusableElements[nextIndex]?.focus();
143
- }
144
-
145
- // Navigate focusable elements
146
- private navigateFocusableElements(isShiftTab: boolean): void {
147
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
148
- let nextIndex: number;
149
-
150
- if (isShiftTab) {
151
- nextIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
152
- } else {
153
- nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
154
- }
155
-
156
- this.focusableElements[nextIndex]?.focus();
157
- }
158
-
159
- // Add element to focus history
160
- private addToFocusHistory(element: HTMLElement): void {
161
- // Remove if already exists
162
- this.focusHistory = this.focusHistory.filter(el => el !== element);
163
-
164
- // Add to beginning
165
- this.focusHistory.unshift(element);
166
-
167
- // Maintain history size
168
- if (this.focusHistory.length > this.maxHistorySize) {
169
- this.focusHistory.pop();
170
- }
171
- }
172
-
173
- // Get element description for screen readers
174
- private getElementDescription(element: HTMLElement): string {
175
- const ariaLabel = element.getAttribute('aria-label');
176
- if (ariaLabel) return ariaLabel;
177
-
178
- const ariaLabelledBy = element.getAttribute('aria-labelledby');
179
- if (ariaLabelledBy) {
180
- const labelElement = document.getElementById(ariaLabelledBy);
181
- if (labelElement) return labelElement.textContent || '';
182
- }
183
-
184
- const placeholder = element.getAttribute('placeholder');
185
- if (placeholder) return placeholder;
186
-
187
- const title = element.getAttribute('title');
188
- if (title) return title;
189
-
190
- return element.textContent || element.tagName.toLowerCase();
191
- }
192
-
193
- // Get element context for screen readers
194
- private getElementContext(element: HTMLElement): string | undefined {
195
- // Find nearest landmark or section
196
- const landmark = element.closest('[role], section, article, aside, nav, header, footer, main');
197
- if (landmark) {
198
- const role = landmark.getAttribute('role');
199
- const ariaLabel = landmark.getAttribute('aria-label');
200
- return ariaLabel || role || landmark.tagName.toLowerCase();
201
- }
202
- return undefined;
203
- }
204
-
205
- // Create focus trap
206
- createFocusTrap(container: HTMLElement, options: FocusTrapOptions = {}): FocusTrap {
207
- const trap = new FocusTrap(container, options);
208
- this.focusTraps.set(trap.id, trap);
209
- return trap;
210
- }
211
-
212
- // Remove focus trap
213
- removeFocusTrap(trapId: string): void {
214
- const trap = this.focusTraps.get(trapId);
215
- if (trap) {
216
- trap.deactivate();
217
- this.focusTraps.delete(trapId);
218
- }
219
- }
220
-
221
- // Focus first focusable element
222
- focusFirst(): void {
223
- const firstElement = this.focusableElements[0];
224
- if (firstElement) {
225
- firstElement.focus();
226
- }
227
- }
228
-
229
- // Focus last focusable element
230
- focusLast(): void {
231
- const lastElement = this.focusableElements[this.focusableElements.length - 1];
232
- if (lastElement) {
233
- lastElement.focus();
234
- }
235
- }
236
-
237
- // Focus next element
238
- focusNext(): void {
239
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
240
- const nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
241
- this.focusableElements[nextIndex]?.focus();
242
- }
243
-
244
- // Focus previous element
245
- focusPrevious(): void {
246
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
247
- const prevIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
248
- this.focusableElements[prevIndex]?.focus();
249
- }
250
-
251
- // Focus element by index
252
- focusByIndex(index: number): void {
253
- if (index >= 0 && index < this.focusableElements.length) {
254
- this.focusableElements[index].focus();
255
- }
256
- }
257
-
258
- // Focus element by ID
259
- focusById(id: string): void {
260
- const element = document.getElementById(id);
261
- if (element && this.focusableElements.includes(element)) {
262
- element.focus();
263
- }
264
- }
265
-
266
- // Focus element by data attribute
267
- focusByDataAttribute(attribute: string, value: string): void {
268
- const element = document.querySelector(`[data-${attribute}="${value}"]`) as HTMLElement;
269
- if (element && this.focusableElements.includes(element)) {
270
- element.focus();
271
- }
272
- }
273
-
274
- // Restore previous focus
275
- restoreFocus(): void {
276
- if (this.lastFocusedElement && this.lastFocusedElement.offsetParent !== null) {
277
- this.lastFocusedElement.focus();
278
- }
279
- }
280
-
281
- // Get focus history
282
- getFocusHistory(): HTMLElement[] {
283
- return [...this.focusHistory];
284
- }
285
-
286
- // Clear focus history
287
- clearFocusHistory(): void {
288
- this.focusHistory = [];
289
- }
290
-
291
- // Get current focus information
292
- getCurrentFocusInfo(): {
293
- element: HTMLElement | null;
294
- index: number;
295
- total: number;
296
- context: string | undefined;
297
- } {
298
- const currentElement = document.activeElement as HTMLElement;
299
- const index = this.focusableElements.indexOf(currentElement);
300
-
301
- return {
302
- element: currentElement,
303
- index: index >= 0 ? index : -1,
304
- total: this.focusableElements.length,
305
- context: currentElement ? this.getElementContext(currentElement) : undefined
306
- };
307
- }
308
-
309
- // Check if element is focusable
310
- isFocusable(element: HTMLElement): boolean {
311
- return this.focusableElements.includes(element);
312
- }
313
-
314
- // Get all focusable elements
315
- getAllFocusableElements(): HTMLElement[] {
316
- return [...this.focusableElements];
317
- }
318
-
319
- // Get focusable elements within container
320
- getFocusableElementsInContainer(container: HTMLElement): HTMLElement[] {
321
- return this.focusableElements.filter(element =>
322
- container.contains(element)
323
- );
324
- }
325
-
326
- // Update focusable elements manually
327
- refreshFocusableElements(): void {
328
- this.updateFocusableElements();
329
- }
330
-
331
- // Destroy focus manager
332
- destroy(): void {
333
- // Remove all focus traps
334
- this.focusTraps.forEach(trap => trap.deactivate());
335
- this.focusTraps.clear();
336
-
169
+ }
170
+ // Remove focus trap
171
+ removeFocusTrap(trapId) {
172
+ const trap = this.focusTraps.get(trapId);
173
+ if (trap) {
174
+ trap.deactivate();
175
+ this.focusTraps.delete(trapId);
176
+ }
177
+ }
178
+ // Focus first focusable element
179
+ focusFirst() {
180
+ const firstElement = this.focusableElements[0];
181
+ if (firstElement) {
182
+ firstElement.focus();
183
+ }
184
+ }
185
+ // Focus last focusable element
186
+ focusLast() {
187
+ const lastElement = this.focusableElements[this.focusableElements.length - 1];
188
+ if (lastElement) {
189
+ lastElement.focus();
190
+ }
191
+ }
192
+ // Focus next element
193
+ focusNext() {
194
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
195
+ const nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
196
+ this.focusableElements[nextIndex]?.focus();
197
+ }
198
+ // Focus previous element
199
+ focusPrevious() {
200
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
201
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
202
+ this.focusableElements[prevIndex]?.focus();
203
+ }
204
+ // Focus element by index
205
+ focusByIndex(index) {
206
+ if (index >= 0 && index < this.focusableElements.length) {
207
+ this.focusableElements[index].focus();
208
+ }
209
+ }
210
+ // Focus element by ID
211
+ focusById(id) {
212
+ const element = document.getElementById(id);
213
+ if (element && this.focusableElements.includes(element)) {
214
+ element.focus();
215
+ }
216
+ }
217
+ // Focus element by data attribute
218
+ focusByDataAttribute(attribute, value) {
219
+ const element = document.querySelector(`[data-${attribute}="${value}"]`);
220
+ if (element && this.focusableElements.includes(element)) {
221
+ element.focus();
222
+ }
223
+ }
224
+ // Restore previous focus
225
+ restoreFocus() {
226
+ if (this.lastFocusedElement && this.lastFocusedElement.offsetParent !== null) {
227
+ this.lastFocusedElement.focus();
228
+ }
229
+ }
230
+ // Get focus history
231
+ getFocusHistory() {
232
+ return [...this.focusHistory];
233
+ }
337
234
  // Clear focus history
338
- this.focusHistory = [];
339
-
340
- // Remove event listeners
341
- document.removeEventListener('focusin', this.handleFocusIn.bind(this));
342
- document.removeEventListener('focusout', this.handleFocusOut.bind(this));
343
- document.removeEventListener('keydown', this.handleKeyDown.bind(this));
344
- }
345
- }
346
-
347
- // Focus trap options
348
- export interface FocusTrapOptions {
349
- autoFocus?: boolean;
350
- returnFocus?: boolean;
351
- escapeDeactivates?: boolean;
352
- clickOutsideDeactivates?: boolean;
353
- allowOutsideClick?: boolean;
354
- fallbackFocus?: HTMLElement;
235
+ clearFocusHistory() {
236
+ this.focusHistory = [];
237
+ }
238
+ // Get current focus information
239
+ getCurrentFocusInfo() {
240
+ const currentElement = document.activeElement;
241
+ const index = this.focusableElements.indexOf(currentElement);
242
+ return {
243
+ element: currentElement,
244
+ index: index >= 0 ? index : -1,
245
+ total: this.focusableElements.length,
246
+ context: currentElement ? this.getElementContext(currentElement) : undefined
247
+ };
248
+ }
249
+ // Check if element is focusable
250
+ isFocusable(element) {
251
+ return this.focusableElements.includes(element);
252
+ }
253
+ // Get all focusable elements
254
+ getAllFocusableElements() {
255
+ return [...this.focusableElements];
256
+ }
257
+ // Get focusable elements within container
258
+ getFocusableElementsInContainer(container) {
259
+ return this.focusableElements.filter(element => container.contains(element));
260
+ }
261
+ // Update focusable elements manually
262
+ refreshFocusableElements() {
263
+ this.updateFocusableElements();
264
+ }
265
+ // Destroy focus manager
266
+ destroy() {
267
+ // Remove all focus traps
268
+ this.focusTraps.forEach(trap => trap.deactivate());
269
+ this.focusTraps.clear();
270
+ // Clear focus history
271
+ this.focusHistory = [];
272
+ // Remove event listeners
273
+ document.removeEventListener('focusin', this.handleFocusIn.bind(this));
274
+ document.removeEventListener('focusout', this.handleFocusOut.bind(this));
275
+ document.removeEventListener('keydown', this.handleKeyDown.bind(this));
276
+ }
355
277
  }
356
-
357
278
  // Focus trap class
358
279
  export class FocusTrap {
359
- public readonly id: string;
360
- public readonly container: HTMLElement;
361
- public readonly options: FocusTrapOptions;
362
- public isActive: boolean = false;
363
-
364
- private returnFocusElement: HTMLElement | null = null;
365
- private focusableElements: HTMLElement[] = [];
366
- private eventListeners: Array<{ event: string; handler: (event: any) => void }> = [];
367
-
368
- constructor(container: HTMLElement, options: FocusTrapOptions = {}) {
369
- this.id = `focus-trap-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
370
- this.container = container;
371
- this.options = {
372
- autoFocus: true,
373
- returnFocus: true,
374
- escapeDeactivates: true,
375
- clickOutsideDeactivates: false,
376
- allowOutsideClick: false,
377
- fallbackFocus: container,
378
- ...options
379
- };
380
- }
381
-
382
- // Activate focus trap
383
- activate(): void {
384
- if (this.isActive) return;
385
-
386
- // Store current focus for return
387
- if (this.options.returnFocus) {
388
- this.returnFocusElement = document.activeElement as HTMLElement;
389
- }
390
-
280
+ constructor(container, options = {}) {
281
+ this.isActive = false;
282
+ this.returnFocusElement = null;
283
+ this.focusableElements = [];
284
+ this.eventListeners = [];
285
+ this.id = `focus-trap-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
286
+ this.container = container;
287
+ this.options = {
288
+ autoFocus: true,
289
+ returnFocus: true,
290
+ escapeDeactivates: true,
291
+ clickOutsideDeactivates: false,
292
+ allowOutsideClick: false,
293
+ fallbackFocus: container,
294
+ ...options
295
+ };
296
+ }
297
+ // Activate focus trap
298
+ activate() {
299
+ if (this.isActive)
300
+ return;
301
+ // Store current focus for return
302
+ if (this.options.returnFocus) {
303
+ this.returnFocusElement = document.activeElement;
304
+ }
305
+ // Get focusable elements within container
306
+ this.focusableElements = this.getFocusableElements();
307
+ // Auto-focus first element or fallback
308
+ if (this.options.autoFocus && this.focusableElements.length > 0) {
309
+ this.focusableElements[0].focus();
310
+ }
311
+ else if (this.options.fallbackFocus) {
312
+ this.options.fallbackFocus.focus();
313
+ }
314
+ // Setup event listeners
315
+ this.setupEventListeners();
316
+ this.isActive = true;
317
+ }
318
+ // Deactivate focus trap
319
+ deactivate() {
320
+ if (!this.isActive)
321
+ return;
322
+ // Remove event listeners
323
+ this.removeEventListeners();
324
+ // Return focus if requested
325
+ if (this.options.returnFocus && this.returnFocusElement) {
326
+ this.returnFocusElement.focus();
327
+ }
328
+ this.isActive = false;
329
+ }
391
330
  // Get focusable elements within container
392
- this.focusableElements = this.getFocusableElements();
393
-
394
- // Auto-focus first element or fallback
395
- if (this.options.autoFocus && this.focusableElements.length > 0) {
396
- this.focusableElements[0].focus();
397
- } else if (this.options.fallbackFocus) {
398
- this.options.fallbackFocus.focus();
399
- }
400
-
331
+ getFocusableElements() {
332
+ const focusableSelectors = [
333
+ 'a[href]',
334
+ 'button:not([disabled])',
335
+ 'input:not([disabled])',
336
+ 'select:not([disabled])',
337
+ 'textarea:not([disabled])',
338
+ '[tabindex]:not([tabindex="-1"])',
339
+ '[contenteditable="true"]'
340
+ ];
341
+ return Array.from(this.container.querySelectorAll(focusableSelectors.join(',')));
342
+ }
401
343
  // Setup event listeners
402
- this.setupEventListeners();
403
-
404
- this.isActive = true;
405
- }
406
-
407
- // Deactivate focus trap
408
- deactivate(): void {
409
- if (!this.isActive) return;
410
-
344
+ setupEventListeners() {
345
+ // Handle escape key
346
+ if (this.options.escapeDeactivates) {
347
+ const escapeHandler = (event) => {
348
+ if (event.key === 'Escape') {
349
+ this.deactivate();
350
+ }
351
+ };
352
+ document.addEventListener('keydown', escapeHandler);
353
+ this.eventListeners.push({ event: 'keydown', handler: escapeHandler });
354
+ }
355
+ // Handle click outside
356
+ if (this.options.clickOutsideDeactivates) {
357
+ const clickHandler = (event) => {
358
+ if (!this.container.contains(event.target)) {
359
+ this.deactivate();
360
+ }
361
+ };
362
+ document.addEventListener('click', clickHandler);
363
+ this.eventListeners.push({ event: 'click', handler: clickHandler });
364
+ }
365
+ // Handle tab key within trap
366
+ const tabHandler = (event) => {
367
+ if (event.key === 'Tab') {
368
+ event.preventDefault();
369
+ this.handleTabNavigation(event.shiftKey);
370
+ }
371
+ };
372
+ this.container.addEventListener('keydown', tabHandler);
373
+ this.eventListeners.push({ event: 'keydown', handler: tabHandler });
374
+ }
411
375
  // Remove event listeners
412
- this.removeEventListeners();
413
-
414
- // Return focus if requested
415
- if (this.options.returnFocus && this.returnFocusElement) {
416
- this.returnFocusElement.focus();
417
- }
418
-
419
- this.isActive = false;
420
- }
421
-
422
- // Get focusable elements within container
423
- getFocusableElements(): HTMLElement[] {
424
- const focusableSelectors = [
425
- 'a[href]',
426
- 'button:not([disabled])',
427
- 'input:not([disabled])',
428
- 'select:not([disabled])',
429
- 'textarea:not([disabled])',
430
- '[tabindex]:not([tabindex="-1"])',
431
- '[contenteditable="true"]'
432
- ];
433
-
434
- return Array.from(
435
- this.container.querySelectorAll(focusableSelectors.join(','))
436
- ) as HTMLElement[];
437
- }
438
-
439
- // Setup event listeners
440
- private setupEventListeners(): void {
441
- // Handle escape key
442
- if (this.options.escapeDeactivates) {
443
- const escapeHandler = (event: KeyboardEvent) => {
444
- if (event.key === 'Escape') {
445
- this.deactivate();
446
- }
447
- };
448
-
449
- document.addEventListener('keydown', escapeHandler);
450
- this.eventListeners.push({ event: 'keydown', handler: escapeHandler });
451
- }
452
-
453
- // Handle click outside
454
- if (this.options.clickOutsideDeactivates) {
455
- const clickHandler = (event: MouseEvent) => {
456
- if (!this.container.contains(event.target as Node)) {
457
- this.deactivate();
458
- }
459
- };
460
-
461
- document.addEventListener('click', clickHandler);
462
- this.eventListeners.push({ event: 'click', handler: clickHandler });
463
- }
464
-
465
- // Handle tab key within trap
466
- const tabHandler = (event: KeyboardEvent) => {
467
- if (event.key === 'Tab') {
468
- event.preventDefault();
469
- this.handleTabNavigation(event.shiftKey);
470
- }
471
- };
472
-
473
- this.container.addEventListener('keydown', tabHandler);
474
- this.eventListeners.push({ event: 'keydown', handler: tabHandler });
475
- }
476
-
477
- // Remove event listeners
478
- private removeEventListeners(): void {
479
- this.eventListeners.forEach(({ event, handler }) => {
480
- if (event === 'keydown' && handler.toString().includes('tabHandler')) {
481
- this.container.removeEventListener(event, handler);
482
- } else {
483
- document.removeEventListener(event, handler);
484
- }
485
- });
486
-
487
- this.eventListeners = [];
488
- }
489
-
490
- // Handle tab navigation within trap
491
- private handleTabNavigation(isShiftTab: boolean): void {
492
- if (this.focusableElements.length === 0) return;
493
-
494
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
495
- let nextIndex: number;
496
-
497
- if (isShiftTab) {
498
- nextIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
499
- } else {
500
- nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
501
- }
502
-
503
- this.focusableElements[nextIndex]?.focus();
504
- }
505
-
506
- // Focus first element in trap
507
- focusFirst(): void {
508
- if (this.focusableElements.length > 0) {
509
- this.focusableElements[0].focus();
510
- }
511
- }
512
-
513
- // Focus last element in trap
514
- focusLast(): void {
515
- if (this.focusableElements.length > 0) {
516
- this.focusableElements[this.focusableElements.length - 1].focus();
517
- }
518
- }
519
-
520
- // Focus next element in trap
521
- focusNext(): void {
522
- if (this.focusableElements.length === 0) return;
523
-
524
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
525
- const nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
526
- this.focusableElements[nextIndex]?.focus();
527
- }
528
-
529
- // Focus previous element in trap
530
- focusPrevious(): void {
531
- if (this.focusableElements.length === 0) return;
532
-
533
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
534
- const prevIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
535
- this.focusableElements[prevIndex]?.focus();
536
- }
537
-
538
- // Get trap information
539
- getInfo(): {
540
- id: string;
541
- isActive: boolean;
542
- focusableElementsCount: number;
543
- currentFocusIndex: number;
544
- container: HTMLElement;
545
- } {
546
- const currentIndex = this.focusableElements.indexOf(document.activeElement as HTMLElement);
547
-
548
- return {
549
- id: this.id,
550
- isActive: this.isActive,
551
- focusableElementsCount: this.focusableElements.length,
552
- currentFocusIndex: currentIndex >= 0 ? currentIndex : -1,
553
- container: this.container
554
- };
555
- }
376
+ removeEventListeners() {
377
+ this.eventListeners.forEach(({ event, handler }) => {
378
+ if (event === 'keydown' && handler.toString().includes('tabHandler')) {
379
+ this.container.removeEventListener(event, handler);
380
+ }
381
+ else {
382
+ document.removeEventListener(event, handler);
383
+ }
384
+ });
385
+ this.eventListeners = [];
386
+ }
387
+ // Handle tab navigation within trap
388
+ handleTabNavigation(isShiftTab) {
389
+ if (this.focusableElements.length === 0)
390
+ return;
391
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
392
+ let nextIndex;
393
+ if (isShiftTab) {
394
+ nextIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
395
+ }
396
+ else {
397
+ nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
398
+ }
399
+ this.focusableElements[nextIndex]?.focus();
400
+ }
401
+ // Focus first element in trap
402
+ focusFirst() {
403
+ if (this.focusableElements.length > 0) {
404
+ this.focusableElements[0].focus();
405
+ }
406
+ }
407
+ // Focus last element in trap
408
+ focusLast() {
409
+ if (this.focusableElements.length > 0) {
410
+ this.focusableElements[this.focusableElements.length - 1].focus();
411
+ }
412
+ }
413
+ // Focus next element in trap
414
+ focusNext() {
415
+ if (this.focusableElements.length === 0)
416
+ return;
417
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
418
+ const nextIndex = currentIndex < this.focusableElements.length - 1 ? currentIndex + 1 : 0;
419
+ this.focusableElements[nextIndex]?.focus();
420
+ }
421
+ // Focus previous element in trap
422
+ focusPrevious() {
423
+ if (this.focusableElements.length === 0)
424
+ return;
425
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
426
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : this.focusableElements.length - 1;
427
+ this.focusableElements[prevIndex]?.focus();
428
+ }
429
+ // Get trap information
430
+ getInfo() {
431
+ const currentIndex = this.focusableElements.indexOf(document.activeElement);
432
+ return {
433
+ id: this.id,
434
+ isActive: this.isActive,
435
+ focusableElementsCount: this.focusableElements.length,
436
+ currentFocusIndex: currentIndex >= 0 ? currentIndex : -1,
437
+ container: this.container
438
+ };
439
+ }
556
440
  }
557
-
558
441
  // Focus restoration utilities
559
442
  export class FocusRestoration {
560
- private focusStack: HTMLElement[] = [];
561
- private maxStackSize: number = 20;
562
-
563
- // Push current focus to stack
564
- pushFocus(): void {
565
- const currentElement = document.activeElement as HTMLElement;
566
- if (currentElement && currentElement !== document.body) {
567
- this.focusStack.push(currentElement);
568
-
569
- // Maintain stack size
570
- if (this.focusStack.length > this.maxStackSize) {
571
- this.focusStack.shift();
572
- }
573
- }
574
- }
575
-
576
- // Pop and restore focus from stack
577
- popFocus(): boolean {
578
- const element = this.focusStack.pop();
579
- if (element && element.offsetParent !== null) {
580
- element.focus();
581
- return true;
582
- }
583
- return false;
584
- }
585
-
586
- // Peek at top of focus stack
587
- peekFocus(): HTMLElement | undefined {
588
- return this.focusStack[this.focusStack.length - 1];
589
- }
590
-
591
- // Clear focus stack
592
- clear(): void {
593
- this.focusStack = [];
594
- }
595
-
596
- // Get stack size
597
- getSize(): number {
598
- return this.focusStack.length;
599
- }
600
-
601
- // Check if stack is empty
602
- isEmpty(): boolean {
603
- return this.focusStack.length === 0;
604
- }
443
+ constructor() {
444
+ this.focusStack = [];
445
+ this.maxStackSize = 20;
446
+ }
447
+ // Push current focus to stack
448
+ pushFocus() {
449
+ const currentElement = document.activeElement;
450
+ if (currentElement && currentElement !== document.body) {
451
+ this.focusStack.push(currentElement);
452
+ // Maintain stack size
453
+ if (this.focusStack.length > this.maxStackSize) {
454
+ this.focusStack.shift();
455
+ }
456
+ }
457
+ }
458
+ // Pop and restore focus from stack
459
+ popFocus() {
460
+ const element = this.focusStack.pop();
461
+ if (element && element.offsetParent !== null) {
462
+ element.focus();
463
+ return true;
464
+ }
465
+ return false;
466
+ }
467
+ // Peek at top of focus stack
468
+ peekFocus() {
469
+ return this.focusStack[this.focusStack.length - 1];
470
+ }
471
+ // Clear focus stack
472
+ clear() {
473
+ this.focusStack = [];
474
+ }
475
+ // Get stack size
476
+ getSize() {
477
+ return this.focusStack.length;
478
+ }
479
+ // Check if stack is empty
480
+ isEmpty() {
481
+ return this.focusStack.length === 0;
482
+ }
605
483
  }
606
-
607
484
  // Focus navigation utilities
608
485
  export class FocusNavigation {
609
- // Navigate to next heading
610
- static focusNextHeading(): void {
611
- const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
612
- const currentIndex = headings.indexOf(document.activeElement as HTMLElement);
613
- const nextIndex = currentIndex < headings.length - 1 ? currentIndex + 1 : 0;
614
-
615
- if (headings[nextIndex]) {
616
- (headings[nextIndex] as HTMLElement).focus();
617
- }
618
- }
619
-
620
- // Navigate to previous heading
621
- static focusPreviousHeading(): void {
622
- const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
623
- const currentIndex = headings.indexOf(document.activeElement as HTMLElement);
624
- const prevIndex = currentIndex > 0 ? currentIndex - 1 : headings.length - 1;
625
-
626
- if (headings[prevIndex]) {
627
- (headings[prevIndex] as HTMLElement).focus();
628
- }
629
- }
630
-
631
- // Navigate to next landmark
632
- static focusNextLandmark(): void {
633
- const landmarks = Array.from(document.querySelectorAll('[role="banner"], [role="main"], [role="navigation"], [role="complementary"], [role="contentinfo"]'));
634
- const currentIndex = landmarks.indexOf(document.activeElement as HTMLElement);
635
- const nextIndex = currentIndex < landmarks.length - 1 ? currentIndex + 1 : 0;
636
-
637
- if (landmarks[nextIndex]) {
638
- (landmarks[nextIndex] as HTMLElement).focus();
639
- }
640
- }
641
-
642
- // Navigate to previous landmark
643
- static focusPreviousLandmark(): void {
644
- const landmarks = Array.from(document.querySelectorAll('[role="banner"], [role="main"], [role="navigation"], [role="complementary"], [role="contentinfo"]'));
645
- const currentIndex = landmarks.indexOf(document.activeElement as HTMLElement);
646
- const prevIndex = currentIndex > 0 ? currentIndex - 1 : landmarks.length - 1;
647
-
648
- if (landmarks[prevIndex]) {
649
- (landmarks[prevIndex] as HTMLElement).focus();
650
- }
651
- }
652
-
653
- // Focus first focusable element in container
654
- static focusFirstInContainer(container: HTMLElement): void {
655
- const focusableSelectors = [
656
- 'a[href]',
657
- 'button:not([disabled])',
658
- 'input:not([disabled])',
659
- 'select:not([disabled])',
660
- 'textarea:not([disabled])',
661
- '[tabindex]:not([tabindex="-1"])'
662
- ];
663
-
664
- const firstElement = container.querySelector(focusableSelectors.join(','));
665
- if (firstElement) {
666
- (firstElement as HTMLElement).focus();
667
- }
668
- }
669
-
670
- // Focus last focusable element in container
671
- static focusLastInContainer(container: HTMLElement): void {
672
- const focusableSelectors = [
673
- 'a[href]',
674
- 'button:not([disabled])',
675
- 'input:not([disabled])',
676
- 'select:not([disabled])',
677
- 'textarea:not([disabled])',
678
- '[tabindex]:not([tabindex="-1"])'
679
- ];
680
-
681
- const elements = Array.from(container.querySelectorAll(focusableSelectors.join(',')));
682
- const lastElement = elements[elements.length - 1];
683
- if (lastElement) {
684
- (lastElement as HTMLElement).focus();
685
- }
686
- }
486
+ // Navigate to next heading
487
+ static focusNextHeading() {
488
+ const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
489
+ const currentIndex = headings.indexOf(document.activeElement);
490
+ const nextIndex = currentIndex < headings.length - 1 ? currentIndex + 1 : 0;
491
+ if (headings[nextIndex]) {
492
+ headings[nextIndex].focus();
493
+ }
494
+ }
495
+ // Navigate to previous heading
496
+ static focusPreviousHeading() {
497
+ const headings = Array.from(document.querySelectorAll('h1, h2, h3, h4, h5, h6'));
498
+ const currentIndex = headings.indexOf(document.activeElement);
499
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : headings.length - 1;
500
+ if (headings[prevIndex]) {
501
+ headings[prevIndex].focus();
502
+ }
503
+ }
504
+ // Navigate to next landmark
505
+ static focusNextLandmark() {
506
+ const landmarks = Array.from(document.querySelectorAll('[role="banner"], [role="main"], [role="navigation"], [role="complementary"], [role="contentinfo"]'));
507
+ const currentIndex = landmarks.indexOf(document.activeElement);
508
+ const nextIndex = currentIndex < landmarks.length - 1 ? currentIndex + 1 : 0;
509
+ if (landmarks[nextIndex]) {
510
+ landmarks[nextIndex].focus();
511
+ }
512
+ }
513
+ // Navigate to previous landmark
514
+ static focusPreviousLandmark() {
515
+ const landmarks = Array.from(document.querySelectorAll('[role="banner"], [role="main"], [role="navigation"], [role="complementary"], [role="contentinfo"]'));
516
+ const currentIndex = landmarks.indexOf(document.activeElement);
517
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : landmarks.length - 1;
518
+ if (landmarks[prevIndex]) {
519
+ landmarks[prevIndex].focus();
520
+ }
521
+ }
522
+ // Focus first focusable element in container
523
+ static focusFirstInContainer(container) {
524
+ const focusableSelectors = [
525
+ 'a[href]',
526
+ 'button:not([disabled])',
527
+ 'input:not([disabled])',
528
+ 'select:not([disabled])',
529
+ 'textarea:not([disabled])',
530
+ '[tabindex]:not([tabindex="-1"])'
531
+ ];
532
+ const firstElement = container.querySelector(focusableSelectors.join(','));
533
+ if (firstElement) {
534
+ firstElement.focus();
535
+ }
536
+ }
537
+ // Focus last focusable element in container
538
+ static focusLastInContainer(container) {
539
+ const focusableSelectors = [
540
+ 'a[href]',
541
+ 'button:not([disabled])',
542
+ 'input:not([disabled])',
543
+ 'select:not([disabled])',
544
+ 'textarea:not([disabled])',
545
+ '[tabindex]:not([tabindex="-1"])'
546
+ ];
547
+ const elements = Array.from(container.querySelectorAll(focusableSelectors.join(',')));
548
+ const lastElement = elements[elements.length - 1];
549
+ if (lastElement) {
550
+ lastElement.focus();
551
+ }
552
+ }
687
553
  }
688
-
689
554
  // Export default instances
690
555
  export const focusManager = new AccessibilityFocusManager();
691
556
  export const focusRestoration = new FocusRestoration();
692
-
693
557
  // Export default
694
558
  export default {
695
- AccessibilityFocusManager,
696
- FocusTrap,
697
- FocusRestoration,
698
- FocusNavigation,
699
- focusManager,
700
- focusRestoration
559
+ AccessibilityFocusManager,
560
+ FocusTrap,
561
+ FocusRestoration,
562
+ FocusNavigation,
563
+ focusManager,
564
+ focusRestoration
701
565
  };