@shortfuse/materialdesignweb 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (398) hide show
  1. package/.eslintrc.json +136 -30
  2. package/.stylelintrc.json +6 -40
  3. package/.vscode/launch.json +20 -5
  4. package/CHANGELOG.md +24 -0
  5. package/README.md +12 -9
  6. package/adapters/datatable/column.js +82 -74
  7. package/adapters/datatable/index.js +173 -131
  8. package/adapters/dom/index.js +529 -75
  9. package/adapters/list/index.js +25 -12
  10. package/adapters/search/index.js +13 -13
  11. package/components/appbar/_spec.scss +87 -64
  12. package/components/appbar/index.scss +2 -2
  13. package/components/banner/_spec.scss +8 -8
  14. package/components/banner/index.scss +2 -2
  15. package/components/bottomnav/_spec.scss +22 -17
  16. package/components/bottomnav/index.js +61 -52
  17. package/components/bottomnav/index.scss +2 -2
  18. package/components/bottomnav/item.js +44 -25
  19. package/components/button/README.md +14 -14
  20. package/components/button/_spec.scss +23 -22
  21. package/components/button/_theme.scss +37 -21
  22. package/components/button/index.eta +32 -0
  23. package/components/button/index.js +12 -12
  24. package/components/button/index.scss +2 -2
  25. package/components/card/_spec.scss +40 -36
  26. package/components/card/index.scss +2 -2
  27. package/components/chip/_spec.scss +7 -8
  28. package/components/chip/_theme.scss +31 -31
  29. package/components/chip/index.js +3 -2
  30. package/components/chip/index.scss +2 -2
  31. package/components/chip/item.js +1 -16
  32. package/components/datatable/_spec.scss +71 -85
  33. package/components/datatable/_theme.scss +61 -156
  34. package/components/datatable/cell.js +45 -0
  35. package/components/datatable/columnheader.js +47 -0
  36. package/components/datatable/index.js +279 -366
  37. package/components/datatable/index.scss +2 -2
  38. package/components/datatable/row.js +49 -0
  39. package/components/datatable/rowheader.js +18 -0
  40. package/components/dialog/_spec.scss +61 -41
  41. package/components/dialog/index.js +325 -297
  42. package/components/dialog/index.scss +2 -2
  43. package/components/divider/_spec.scss +8 -6
  44. package/components/divider/index.scss +2 -2
  45. package/components/elevation/_spec.scss +2 -2
  46. package/components/elevation/index.scss +2 -2
  47. package/components/fab/_spec.scss +23 -24
  48. package/components/fab/index.js +50 -50
  49. package/components/fab/index.scss +2 -2
  50. package/components/grid/_spec.scss +33 -31
  51. package/components/grid/index.scss +2 -2
  52. package/components/layout/_mixins.scss +5 -5
  53. package/components/layout/_spec.scss +206 -176
  54. package/components/layout/_theme.scss +14 -16
  55. package/components/layout/index.js +181 -153
  56. package/components/layout/index.scss +2 -2
  57. package/components/list/_spec.scss +117 -104
  58. package/components/list/_theme.scss +31 -34
  59. package/components/list/content.js +68 -52
  60. package/components/list/index.js +194 -61
  61. package/components/list/index.scss +2 -2
  62. package/components/list/item.js +136 -12
  63. package/components/list/secondary.js +46 -0
  64. package/components/menu/_spec.scss +32 -19
  65. package/components/menu/index.js +242 -229
  66. package/components/menu/index.scss +2 -2
  67. package/components/menu/item.js +95 -110
  68. package/components/progress/_spec.scss +35 -27
  69. package/components/progress/index.js +21 -0
  70. package/components/progress/index.scss +2 -1
  71. package/components/selection/_spec.scss +242 -224
  72. package/components/selection/_theme.scss +100 -95
  73. package/components/selection/index.eta +60 -0
  74. package/components/selection/index.js +76 -0
  75. package/components/selection/index.pug +15 -8
  76. package/components/selection/index.scss +2 -2
  77. package/components/selection/input.js +56 -0
  78. package/components/selection/radiogroup.js +47 -0
  79. package/components/slider/_spec.scss +10 -8
  80. package/components/slider/index.scss +2 -2
  81. package/components/snackbar/_spec.scss +22 -21
  82. package/components/snackbar/index.js +102 -111
  83. package/components/snackbar/index.scss +2 -2
  84. package/components/tab/_spec.scss +20 -19
  85. package/components/tab/content.js +41 -40
  86. package/components/tab/index.js +192 -99
  87. package/components/tab/index.scss +2 -2
  88. package/components/tab/item.js +38 -55
  89. package/components/tab/list.js +96 -72
  90. package/components/tab/panel.js +12 -13
  91. package/components/template/_theme.scss +11 -11
  92. package/components/textfield/_mixins.scss +52 -0
  93. package/components/textfield/_spec.scss +215 -266
  94. package/components/textfield/_theme.scss +95 -72
  95. package/components/textfield/index.eta +74 -0
  96. package/components/textfield/index.js +63 -57
  97. package/components/textfield/index.scss +2 -2
  98. package/components/tooltip/_spec.scss +27 -25
  99. package/components/tooltip/index.scss +2 -2
  100. package/components/type/_spec.scss +51 -38
  101. package/components/type/index.scss +2 -2
  102. package/core/_breakpoint.scss +75 -91
  103. package/core/_elevation.scss +10 -10
  104. package/core/_length.scss +9 -0
  105. package/core/_motion.scss +14 -14
  106. package/core/_platform.scss +9 -15
  107. package/core/_type.scss +33 -32
  108. package/core/aria/attributes.js +125 -25
  109. package/core/aria/button.js +23 -23
  110. package/core/aria/keyboard.js +93 -0
  111. package/core/aria/rovingtabindex.js +69 -154
  112. package/core/aria/tab.js +31 -28
  113. package/core/color/_theme.scss +240 -280
  114. package/core/color/index.scss +2 -2
  115. package/core/document/index.js +39 -0
  116. package/core/dom.js +12 -12
  117. package/core/overlay/_spec.scss +0 -3
  118. package/core/overlay/_theme.scss +56 -74
  119. package/core/overlay/index.js +49 -18
  120. package/core/overlay/index.scss +2 -2
  121. package/core/ripple/_spec.scss +22 -39
  122. package/core/ripple/_theme.scss +13 -13
  123. package/core/ripple/index.js +137 -134
  124. package/core/ripple/index.scss +2 -2
  125. package/core/theme/_config.scss +2 -0
  126. package/core/theme/_mixins.scss +172 -0
  127. package/core/theme/_palettes.scss +155 -135
  128. package/core/theme/_variables.scss +24 -15
  129. package/core/theme/index.js +50 -0
  130. package/core/throttler.js +1 -1
  131. package/core/transition/index.js +36 -20
  132. package/{docs-src → docs}/_flex.scss +0 -0
  133. package/{docs-src → docs}/_menuoptions.js +21 -34
  134. package/{docs-src → docs}/_mixins.pug +39 -26
  135. package/docs/_partials/_androidnavbar.eta +5 -0
  136. package/docs/_partials/_androidstatusbar.eta +13 -0
  137. package/docs/_partials/_appbar.eta +29 -0
  138. package/docs/_partials/_buttontest.eta +31 -0
  139. package/docs/_partials/_header.eta +149 -0
  140. package/docs/_partials/_navlistitem.eta +16 -0
  141. package/docs/_partials/_target.eta +1 -0
  142. package/{docs-src → docs}/_sample-utils.js +8 -6
  143. package/{docs-src → docs}/_storage.js +0 -0
  144. package/{docs-src → docs}/docs.scss +5 -2
  145. package/docs/index.eta +16 -0
  146. package/{docs-src → docs}/index.js +0 -0
  147. package/docs/pages/appbar.eta +114 -0
  148. package/{docs-src/components → docs/pages}/appbar.js +0 -0
  149. package/{docs-src/components → docs/pages}/appbar.pug +15 -18
  150. package/docs/pages/bottomnav.eta +188 -0
  151. package/{docs-src/components → docs/pages}/bottomnav.js +23 -24
  152. package/{docs-src/components → docs/pages}/bottomnav.pug +4 -4
  153. package/docs/pages/button.eta +124 -0
  154. package/{docs-src/components → docs/pages}/button.js +19 -19
  155. package/{docs-src/components → docs/pages}/button.pug +15 -15
  156. package/docs/pages/card.eta +90 -0
  157. package/{docs-src/components → docs/pages}/card.js +3 -3
  158. package/{docs-src/components → docs/pages}/card.pug +7 -7
  159. package/docs/pages/chip.eta +122 -0
  160. package/{docs-src/components → docs/pages}/chip.js +3 -6
  161. package/{docs-src/components → docs/pages}/chip.pug +2 -2
  162. package/docs/pages/color.eta +143 -0
  163. package/{docs-src/core → docs/pages}/color.js +95 -20
  164. package/docs/pages/color.pug +121 -0
  165. package/docs/pages/datatable.eta +323 -0
  166. package/{docs-src/components → docs/pages}/datatable.js +26 -13
  167. package/docs/pages/datatable.pug +283 -0
  168. package/docs/pages/dialog.eta +186 -0
  169. package/{docs-src/components → docs/pages}/dialog.js +26 -13
  170. package/{docs-src/components → docs/pages}/dialog.pug +46 -28
  171. package/docs/pages/dom.eta +26 -0
  172. package/docs/pages/dom.js +143 -0
  173. package/docs/pages/dom.pug +22 -0
  174. package/docs/pages/elevation.eta +35 -0
  175. package/{docs-src/components → docs/pages}/elevation.js +0 -0
  176. package/{docs-src/components → docs/pages}/elevation.pug +0 -0
  177. package/docs/pages/fab.eta +99 -0
  178. package/{docs-src/components → docs/pages}/fab.js +3 -3
  179. package/{docs-src/components → docs/pages}/fab.pug +2 -2
  180. package/docs/pages/grid.eta +135 -0
  181. package/{docs-src/components → docs/pages}/grid.js +1 -1
  182. package/{docs-src/components → docs/pages}/grid.pug +3 -3
  183. package/docs/pages/layout.eta +8 -0
  184. package/{docs-src/components → docs/pages}/layout.js +0 -0
  185. package/{docs-src/components → docs/pages}/layout.pug +0 -0
  186. package/docs/pages/list.eta +465 -0
  187. package/{docs-src/components → docs/pages}/list.js +2 -2
  188. package/{docs-src/components → docs/pages}/list.pug +7 -14
  189. package/docs/pages/menu.eta +276 -0
  190. package/{docs-src/components → docs/pages}/menu.js +14 -10
  191. package/{docs-src/components → docs/pages}/menu.pug +0 -0
  192. package/docs/pages/overlay.eta +69 -0
  193. package/docs/pages/overlay.js +4 -0
  194. package/{docs-src/core → docs/pages}/overlay.pug +14 -11
  195. package/docs/pages/progress.eta +23 -0
  196. package/{docs-src/components → docs/pages}/progress.js +1 -1
  197. package/{docs-src/components → docs/pages}/progress.pug +1 -1
  198. package/docs/pages/ripple.eta +27 -0
  199. package/docs/pages/ripple.js +4 -0
  200. package/{docs-src/core → docs/pages}/ripple.pug +4 -4
  201. package/docs/pages/search.eta +246 -0
  202. package/{docs-src/components → docs/pages}/search.js +59 -42
  203. package/{docs-src/components → docs/pages}/search.pug +50 -51
  204. package/docs/pages/selection.eta +111 -0
  205. package/docs/pages/selection.js +13 -0
  206. package/docs/pages/selection.pug +74 -0
  207. package/docs/pages/slider.eta +23 -0
  208. package/{docs-src/components → docs/pages}/slider.js +0 -0
  209. package/{docs-src/components → docs/pages}/slider.pug +0 -0
  210. package/docs/pages/snackbar.eta +83 -0
  211. package/{docs-src/components → docs/pages}/snackbar.js +3 -3
  212. package/{docs-src/components → docs/pages}/snackbar.pug +0 -0
  213. package/docs/pages/tab.eta +421 -0
  214. package/{docs-src/components → docs/pages}/tab.js +18 -35
  215. package/{docs-src/components → docs/pages}/tab.pug +4 -4
  216. package/docs/pages/textfield.eta +486 -0
  217. package/{docs-src/components → docs/pages}/textfield.js +3 -4
  218. package/{docs-src/components → docs/pages}/textfield.pug +87 -35
  219. package/docs/pages/tooltip.eta +94 -0
  220. package/{docs-src/components → docs/pages}/tooltip.js +0 -0
  221. package/{docs-src/components → docs/pages}/tooltip.pug +0 -1
  222. package/docs/pages/transition.eta +117 -0
  223. package/{docs-src/core → docs/pages}/transition.js +7 -8
  224. package/{docs-src/core → docs/pages}/transition.pug +0 -0
  225. package/docs/pages/type.eta +31 -0
  226. package/{docs-src/components → docs/pages}/type.js +0 -0
  227. package/{docs-src/components → docs/pages}/type.pug +0 -1
  228. package/docs/postrender.js +39 -0
  229. package/{docs-src → docs}/prerender.js +3 -9
  230. package/docs/pwa/_dialogs.eta +143 -0
  231. package/docs/pwa/_dialogs.pug +96 -0
  232. package/docs/pwa/_menus.eta +16 -0
  233. package/{docs-src → docs}/pwa/_menus.pug +0 -0
  234. package/docs/pwa/pwa-prerender.js +3 -0
  235. package/docs/pwa/pwa.eta +480 -0
  236. package/docs/pwa/pwa.js +306 -0
  237. package/{docs-src → docs}/pwa/pwa.pug +166 -263
  238. package/docs/pwa/pwa.scss +26 -0
  239. package/docs/spec.scss +26 -0
  240. package/docs/themes/_component-themes.scss +26 -0
  241. package/docs/themes/theme-colored-fallbacks.scss +17 -0
  242. package/docs/themes/theme-colored.scss +17 -0
  243. package/docs/themes/theme-default-fallbacks.scss +17 -0
  244. package/docs/themes/theme-default.scss +17 -0
  245. package/jsconfig.json +4 -2
  246. package/package.json +40 -27
  247. package/scripts/deploy-docs.sh +9 -0
  248. package/templates/index.eta +2 -0
  249. package/utils/function.js +3 -0
  250. package/webpack.config.cjs +257 -0
  251. package/_spec.scss +0 -27
  252. package/_theme.scss +0 -27
  253. package/components/list/expander.js +0 -142
  254. package/components/list/itemgroup.js +0 -22
  255. package/core/theme/_builder.scss +0 -116
  256. package/core/theme/index.scss +0 -68
  257. package/docs/appbar.html +0 -1
  258. package/docs/appbar.min.js +0 -2
  259. package/docs/appbar.min.js.map +0 -1
  260. package/docs/bottomnav.html +0 -1
  261. package/docs/bottomnav.min.js +0 -2
  262. package/docs/bottomnav.min.js.map +0 -1
  263. package/docs/button.html +0 -1
  264. package/docs/button.min.js +0 -2
  265. package/docs/button.min.js.map +0 -1
  266. package/docs/card.html +0 -1
  267. package/docs/card.min.js +0 -2
  268. package/docs/card.min.js.map +0 -1
  269. package/docs/chip.html +0 -1
  270. package/docs/chip.min.js +0 -2
  271. package/docs/chip.min.js.map +0 -1
  272. package/docs/color.html +0 -1
  273. package/docs/color.min.js +0 -2
  274. package/docs/color.min.js.map +0 -1
  275. package/docs/datatable.html +0 -1
  276. package/docs/datatable.min.js +0 -2
  277. package/docs/datatable.min.js.map +0 -1
  278. package/docs/default.common.min.js +0 -2
  279. package/docs/default.common.min.js.map +0 -1
  280. package/docs/dialog.html +0 -1
  281. package/docs/dialog.min.js +0 -2
  282. package/docs/dialog.min.js.map +0 -1
  283. package/docs/docs.min.css +0 -1
  284. package/docs/docs.min.js +0 -2
  285. package/docs/docs.min.js.map +0 -1
  286. package/docs/elevation.html +0 -1
  287. package/docs/elevation.min.js +0 -2
  288. package/docs/elevation.min.js.map +0 -1
  289. package/docs/fab.html +0 -1
  290. package/docs/fab.min.js +0 -2
  291. package/docs/fab.min.js.map +0 -1
  292. package/docs/grid.html +0 -1
  293. package/docs/grid.min.js +0 -2
  294. package/docs/grid.min.js.map +0 -1
  295. package/docs/index.html +0 -1
  296. package/docs/index.min.js +0 -2
  297. package/docs/index.min.js.map +0 -1
  298. package/docs/ink.html +0 -1
  299. package/docs/ink.min.js +0 -2
  300. package/docs/ink.min.js.map +0 -1
  301. package/docs/layout.html +0 -1
  302. package/docs/layout.min.js +0 -2
  303. package/docs/layout.min.js.map +0 -1
  304. package/docs/list.html +0 -1
  305. package/docs/list.min.js +0 -2
  306. package/docs/list.min.js.map +0 -1
  307. package/docs/menu.html +0 -1
  308. package/docs/menu.min.js +0 -2
  309. package/docs/menu.min.js.map +0 -1
  310. package/docs/overlay.html +0 -1
  311. package/docs/overlay.min.js +0 -2
  312. package/docs/overlay.min.js.map +0 -1
  313. package/docs/prerender.common.min.js +0 -2
  314. package/docs/prerender.common.min.js.map +0 -1
  315. package/docs/prerender.min.js +0 -2
  316. package/docs/prerender.min.js.map +0 -1
  317. package/docs/progress.html +0 -1
  318. package/docs/progress.min.js +0 -2
  319. package/docs/progress.min.js.map +0 -1
  320. package/docs/pwa-prerender.min.js +0 -2
  321. package/docs/pwa-prerender.min.js.map +0 -1
  322. package/docs/pwa.html +0 -11
  323. package/docs/pwa.min.css +0 -1
  324. package/docs/pwa.min.js +0 -2
  325. package/docs/pwa.min.js.map +0 -1
  326. package/docs/ripple.html +0 -1
  327. package/docs/ripple.min.js +0 -2
  328. package/docs/ripple.min.js.map +0 -1
  329. package/docs/search.html +0 -1
  330. package/docs/search.min.js +0 -2
  331. package/docs/search.min.js.map +0 -1
  332. package/docs/selection.html +0 -1
  333. package/docs/selection.min.js +0 -2
  334. package/docs/selection.min.js.map +0 -1
  335. package/docs/slider.html +0 -1
  336. package/docs/slider.min.js +0 -2
  337. package/docs/slider.min.js.map +0 -1
  338. package/docs/snackbar.html +0 -1
  339. package/docs/snackbar.min.js +0 -2
  340. package/docs/snackbar.min.js.map +0 -1
  341. package/docs/spec.min.css +0 -1
  342. package/docs/spec.min.js +0 -2
  343. package/docs/spec.min.js.map +0 -1
  344. package/docs/surface.html +0 -1
  345. package/docs/surface.min.js +0 -2
  346. package/docs/surface.min.js.map +0 -1
  347. package/docs/tab.html +0 -1
  348. package/docs/tab.min.js +0 -2
  349. package/docs/tab.min.js.map +0 -1
  350. package/docs/textfield.html +0 -2
  351. package/docs/textfield.min.js +0 -2
  352. package/docs/textfield.min.js.map +0 -1
  353. package/docs/theme-colored-fallbacks.min.css +0 -1
  354. package/docs/theme-colored-fallbacks.min.js +0 -2
  355. package/docs/theme-colored-fallbacks.min.js.map +0 -1
  356. package/docs/theme-colored.min.css +0 -1
  357. package/docs/theme-colored.min.js +0 -2
  358. package/docs/theme-colored.min.js.map +0 -1
  359. package/docs/theme-default-fallbacks.min.css +0 -1
  360. package/docs/theme-default-fallbacks.min.js +0 -2
  361. package/docs/theme-default-fallbacks.min.js.map +0 -1
  362. package/docs/theme-default.min.css +0 -1
  363. package/docs/theme-default.min.js +0 -2
  364. package/docs/theme-default.min.js.map +0 -1
  365. package/docs/themes-fallbacks.min.css +0 -1
  366. package/docs/themes-fallbacks.min.js +0 -2
  367. package/docs/themes-fallbacks.min.js.map +0 -1
  368. package/docs/themes.min.css +0 -1
  369. package/docs/themes.min.js +0 -2
  370. package/docs/themes.min.js.map +0 -1
  371. package/docs/tooltip.html +0 -1
  372. package/docs/tooltip.min.js +0 -2
  373. package/docs/tooltip.min.js.map +0 -1
  374. package/docs/transition.html +0 -1
  375. package/docs/transition.min.js +0 -2
  376. package/docs/transition.min.js.map +0 -1
  377. package/docs/type.html +0 -1
  378. package/docs/type.min.js +0 -2
  379. package/docs/type.min.js.map +0 -1
  380. package/docs-src/components/datatable.pug +0 -327
  381. package/docs-src/components/selection.js +0 -9
  382. package/docs-src/components/selection.pug +0 -77
  383. package/docs-src/core/color.pug +0 -201
  384. package/docs-src/core/overlay.js +0 -4
  385. package/docs-src/core/ripple.js +0 -4
  386. package/docs-src/index.pug +0 -9
  387. package/docs-src/pwa/_dialogs.pug +0 -15
  388. package/docs-src/pwa/pwa-prerender.js +0 -3
  389. package/docs-src/pwa/pwa.js +0 -182
  390. package/docs-src/pwa/pwa.scss +0 -25
  391. package/docs-src/spec.scss +0 -1
  392. package/docs-src/themes/theme-colored-fallbacks.scss +0 -14
  393. package/docs-src/themes/theme-colored.scss +0 -14
  394. package/docs-src/themes/theme-default-fallbacks.scss +0 -14
  395. package/docs-src/themes/theme-default.scss +0 -14
  396. package/index.js +0 -51
  397. package/index.scss +0 -2
  398. package/webpack.config.js +0 -187
@@ -1,238 +1,122 @@
1
1
  // https://www.w3.org/TR/wai-aria-practices/#grid
2
2
 
3
- import {
4
- dispatchDomEvent,
5
- isRtl,
6
- findElementParentByClassName,
7
- iterateArrayLike,
8
- iterateSomeOfArrayLike,
9
- } from '../../core/dom';
3
+ import * as Keyboard from '../../core/aria/keyboard.js';
4
+ import * as RovingTabIndex from '../../core/aria/rovingtabindex.js';
5
+ import { iterateArrayLike } from '../../core/dom.js';
6
+
7
+ import * as DataTableCell from './cell.js';
8
+ import * as DataTableColumnHeader from './columnheader.js';
9
+ import * as DataTableRow from './row.js';
10
+ import * as DataTableRowHeader from './rowheader.js';
11
+
12
+ export const CELL_TABINDEX_QUERIES = [
13
+ 'td:not([mdw-autofocus-widget])',
14
+ 'th:not([mdw-autofocus-widget])',
15
+ 'td[mdw-autofocus-widget] .mdw-datatable__widget',
16
+ 'th[mdw-autofocus-widget] .mdw-datatable__widget',
17
+ ];
10
18
 
11
19
  /**
12
- * @param {Element} element
20
+ * @param {CustomEvent} event
13
21
  * @return {void}
14
22
  */
15
- export function attach(element) {
16
- if (!element.hasAttribute('role')) {
17
- element.setAttribute('role', 'grid');
18
- }
19
- element.setAttribute('mdw-js', '');
20
- const headerRow = getHeaderRow(element);
21
- const tbody = getTableBody(element);
22
- const cellFocusable = element.hasAttribute('mdw-cell-focusable');
23
- const rowFocusable = element.hasAttribute('mdw-row-focusable');
24
-
25
- headerRow.addEventListener('click', onHeaderRowClick);
26
- tbody.addEventListener('keydown', onTableBodyKeyDown);
27
- tbody.addEventListener('click', onTableBodyClick);
28
- let firstRow = null;
29
- let foundTabbableRow = false;
30
- let firstCell = null;
31
- let foundTabbableCell = false;
32
- iterateArrayLike(tbody.rows, (row) => {
33
- if (rowFocusable) {
34
- if (!firstRow) {
35
- firstRow = row;
36
- }
37
- if (!foundTabbableRow && row.getAttribute('tabindex') === '0') {
38
- foundTabbableRow = true;
39
- } else {
40
- row.setAttribute('tabindex', '-1');
41
- }
42
- } else {
43
- row.removeAttribute('tabindex');
44
- }
45
- iterateArrayLike(row.cells, (cell) => {
46
- if (cellFocusable && !rowFocusable) {
47
- if (!firstCell) {
48
- firstCell = cell;
49
- }
50
- if (!foundTabbableCell && cell.getAttribute('tabindex') === '0') {
51
- foundTabbableCell = true;
52
- } else {
53
- cell.setAttribute('tabindex', '-1');
54
- }
55
- } else {
56
- cell.removeAttribute('tabindex');
57
- }
58
- });
59
- });
60
- if (rowFocusable && !foundTabbableRow && firstRow) {
61
- updateTabIndex(firstRow, false);
62
- } else if (cellFocusable && !foundTabbableCell && firstCell) {
63
- updateTabIndex(firstCell, false);
23
+ export function onSelectedChange(event) {
24
+ const selected = event.detail.value === 'true';
25
+ /** @type {HTMLElement} */
26
+ const dataTableElement = (event.currentTarget);
27
+ const hasSelection = selected || dataTableElement.querySelector('td[aria-selected="true"],tr[aria-selected="true"]');
28
+ if (hasSelection) {
29
+ dataTableElement.setAttribute('mdw-has-selection', '');
30
+ } else {
31
+ dataTableElement.removeAttribute('mdw-has-selection');
64
32
  }
65
33
  }
66
34
 
67
35
  /**
68
- * @param {MouseEvent} event
69
- * @return {void}
36
+ * @param {Element} datatableElement
37
+ * @return {HTMLElement}
70
38
  */
71
- export function onTableBodyClick(event) {
72
- /** @type {HTMLTableSectionElement} */
73
- const tbody = (event.currentTarget);
74
- const mdwDataTable = findElementParentByClassName(tbody, 'mdw-datatable');
75
- const { target } = event;
76
- let cell = null;
77
- /** @type {HTMLTableRowElement} */
78
- let row = null;
79
-
80
- if (target instanceof HTMLInputElement && target.getAttribute('type') === 'checkbox') {
81
- if (mdwDataTable.hasAttribute('mdw-datatable-adapter')) {
82
- return;
83
- }
84
- // Checkbox clicked
85
- cell = findParentCell(target);
86
- if (!cell.hasAttribute('mdw-selector')) {
87
- return;
88
- }
89
- event.stopPropagation();
90
- /** @type {HTMLTableRowElement} */
91
- row = (cell.parentElement);
92
- let hasSelection = false;
93
- if (target.checked) {
94
- row.setAttribute('aria-selected', 'true');
95
- hasSelection = true;
96
- } else {
97
- row.setAttribute('aria-selected', 'false');
98
- /** @type {NodeListOf<HTMLInputElement>} */
99
- const checkboxes = (mdwDataTable.querySelectorAll('td[mdw-selector] input[type=checkbox]'));
100
- hasSelection = iterateSomeOfArrayLike(checkboxes, checkbox => checkbox.checked);
101
- }
102
- if (hasSelection) {
103
- mdwDataTable.setAttribute('mdw-has-selection', '');
39
+ export function getScroller(datatableElement) {
40
+ /** @type {HTMLElement} */
41
+ let scroller = (datatableElement.getElementsByClassName('mdw-datatable__scroller')[0]);
42
+ if (!scroller) {
43
+ scroller = document.createElement('div');
44
+ scroller.classList.add('mdw-datatable__scroller');
45
+ const footer = datatableElement.getElementsByClassName('mdw-datatable__footer')[0];
46
+ if (footer) {
47
+ datatableElement.insertBefore(scroller, footer);
104
48
  } else {
105
- mdwDataTable.removeAttribute('mdw-has-selection');
106
- }
107
- return;
108
- }
109
- if (target instanceof HTMLTableRowElement) {
110
- row = target;
111
- } else if (target instanceof HTMLTableCellElement) {
112
- cell = target;
113
- } else {
114
- cell = findParentCell(/** @type {Element} */ (target));
115
- }
116
-
117
- if (cell) {
118
- /** @type {HTMLTableRowElement} */
119
- row = (cell.parentElement);
120
- const cellFocusable = mdwDataTable.hasAttribute('mdw-cell-focusable');
121
- if (cellFocusable) {
122
- updateTabIndex(cell);
123
- return;
49
+ datatableElement.appendChild(scroller);
124
50
  }
125
- }
126
- if (row) {
127
- const rowFocusable = mdwDataTable.hasAttribute('mdw-row-focusable');
128
- if (rowFocusable) {
129
- updateTabIndex(row);
51
+ // Move table into scroller if it exists
52
+ const table = datatableElement.getElementsByTagName('table')[0];
53
+ if (table) {
54
+ table.parentElement.removeChild(table);
55
+ scroller.appendChild(table);
130
56
  }
131
57
  }
58
+ return scroller;
132
59
  }
133
60
 
134
61
  /**
135
- * @param {HTMLTableRowElement|HTMLTableCellElement} element
136
- * @param {boolean} [removeOtherTabIndexes=true]
137
- * @return {void}
62
+ * @param {Element} datatableElement
63
+ * @return {HTMLTableElement}
138
64
  */
139
- export function updateTabIndex(element, removeOtherTabIndexes) {
140
- if (removeOtherTabIndexes !== false) {
141
- /** @type {HTMLElement} */
142
- let tbody = element;
143
- while (tbody != null && tbody instanceof HTMLTableSectionElement === false) {
144
- tbody = tbody.parentElement;
145
- }
146
- if (element instanceof HTMLTableCellElement) {
147
- iterateArrayLike(tbody.querySelectorAll('td[tabindex="0"]'), (td) => {
148
- if (td !== element) {
149
- td.setAttribute('tabindex', '-1');
150
- }
151
- });
152
- }
153
- if (element instanceof HTMLTableRowElement) {
154
- iterateArrayLike(tbody.querySelectorAll('tr[tabindex="0"]'), (tr) => {
155
- if (tr !== element) {
156
- tr.setAttribute('tabindex', '-1');
157
- }
158
- });
159
- }
65
+ export function getTable(datatableElement) {
66
+ if (datatableElement instanceof HTMLTableElement) {
67
+ return datatableElement;
160
68
  }
161
- if (element.getAttribute('tabindex') !== '0') {
162
- element.setAttribute('tabindex', '0');
163
- dispatchDomEvent(element, 'mdw:tabindexchanged');
69
+ let table = datatableElement.getElementsByTagName('table')[0];
70
+ if (!table) {
71
+ const scroller = getScroller(datatableElement);
72
+ table = document.createElement('table');
73
+ scroller.appendChild(table);
164
74
  }
75
+ return table;
165
76
  }
166
77
 
167
78
  /**
168
- * @param {Element} element
169
- * @return {HTMLTableCellElement}
79
+ * @param {Element} datatableElement
80
+ * @return {HTMLTableSectionElement}
170
81
  */
171
- export function findParentCell(element) {
172
- let el = element;
173
- while (el != null) {
174
- if (el instanceof HTMLTableElement) {
175
- return null;
176
- }
177
- if (el instanceof HTMLTableCellElement) {
178
- return el;
179
- }
180
- el = el.parentElement;
82
+ export function getTableBody(datatableElement) {
83
+ let tbody = datatableElement.getElementsByTagName('tbody')[0];
84
+ if (!tbody) {
85
+ const table = getTable(datatableElement);
86
+ tbody = document.createElement('tbody');
87
+ table.appendChild(tbody);
181
88
  }
182
- return null;
89
+ return tbody;
183
90
  }
184
91
 
185
92
  /**
186
- * @param {MouseEvent} event
93
+ * @param {Element} datatableElement
94
+ * @param {number} columnIndex
95
+ * @param {boolean} ascending
187
96
  * @return {void}
188
97
  */
189
- export function onHeaderRowClick(event) {
190
- /** @type {HTMLElement} */
191
- const targetElement = (event.target);
192
- const cell = findParentCell(targetElement);
193
- if (!cell) {
194
- return;
195
- }
196
- if (cell.cellIndex === -1) {
197
- return;
198
- }
199
- if (!cell.hasAttribute('mdw-sortable')) {
200
- return;
201
- }
202
- /** @type {HTMLElement} */
203
- const headerRow = (event.currentTarget);
204
- const mdwTable = findElementParentByClassName(headerRow, 'mdw-datatable');
205
- if (!mdwTable) {
206
- return;
207
- }
208
- if (mdwTable.hasAttribute('mdw-datatable-adapter')) {
98
+ export function sortColumn(datatableElement, columnIndex, ascending = true) {
99
+ if (datatableElement.hasAttribute('mdw-datatable-adapter')) {
209
100
  return;
210
101
  }
211
- let ascending = true;
212
- if (cell.hasAttribute('mdw-sorted') && !cell.getAttribute('mdw-sorted')) {
213
- ascending = false;
214
- }
215
- if (ascending) {
216
- cell.setAttribute('mdw-sorted', '');
217
- } else {
218
- cell.setAttribute('mdw-sorted', 'desc');
219
- }
220
- iterateArrayLike(cell.parentElement.getElementsByTagName('th'), (th) => {
221
- if (th !== cell) {
222
- th.removeAttribute('mdw-sorted');
102
+ iterateArrayLike(datatableElement.getElementsByTagName('th'), (th) => {
103
+ if (th.cellIndex === columnIndex) {
104
+ th.setAttribute('aria-sort', ascending ? 'ascending' : 'descending');
105
+ } else if (th.hasAttribute('aria-sort')) {
106
+ th.setAttribute('aria-sort', 'none');
223
107
  }
224
108
  });
225
109
 
226
110
  /** @type {HTMLTableSectionElement} */
227
- const tbody = getTableBody(mdwTable);
111
+ const tbody = getTableBody(datatableElement);
228
112
  const rows = [];
229
113
  for (let i = tbody.rows.length - 1; i >= 0; i -= 1) {
230
114
  rows.push(tbody.rows.item(i));
231
115
  tbody.deleteRow(i);
232
116
  }
233
117
  rows.sort((a, b) => {
234
- const aCell = a.cells.item(cell.cellIndex);
235
- const bCell = b.cells.item(cell.cellIndex);
118
+ const aCell = a.cells.item(columnIndex);
119
+ const bCell = b.cells.item(columnIndex);
236
120
  const aText = aCell.textContent;
237
121
  const bText = bCell.textContent;
238
122
  if (aCell.dataset.type === 'number') {
@@ -248,197 +132,198 @@ export function onHeaderRowClick(event) {
248
132
  fragment.appendChild(row);
249
133
  });
250
134
  tbody.appendChild(fragment);
251
- event.stopPropagation();
252
135
  }
253
136
 
254
137
  /**
255
- * @param {KeyboardEvent} event
138
+ * @param {CustomEvent} event
256
139
  * @return {void}
257
140
  */
258
- export function onTableBodyKeyDown(event) {
259
- const currentSelection = document.activeElement;
260
- let cellIndex = 0;
261
- /** @type {HTMLTableRowElement} */
262
- let row = null;
263
- let isRow = false;
264
- /** @type {HTMLTableRowElement|HTMLTableCellElement} */
265
- let nextSelection = null;
266
- if (currentSelection instanceof HTMLTableCellElement) {
267
- ({ cellIndex } = currentSelection);
268
- /** @type {HTMLTableRowElement} */
269
- row = (currentSelection.parentElement);
270
- } else if (currentSelection instanceof HTMLTableRowElement) {
271
- isRow = true;
272
- row = currentSelection;
141
+ export function onItemFocus(event) {
142
+ /** @type {HTMLElement} */
143
+ const datatableElement = (event.currentTarget);
144
+ const onFocusInteraction = datatableElement.getAttribute('mdw-on-focus');
145
+ if (!onFocusInteraction) {
146
+ return;
273
147
  }
274
- if (!row) {
148
+ /** @type {HTMLElement} */
149
+ const itemElement = (event.target);
150
+ if (itemElement.getAttribute('aria-disabled') === 'true') {
275
151
  return;
276
152
  }
277
- /** @type {HTMLTableSectionElement} */
278
- const tbody = (event.currentTarget);
279
- if (event.key === 'ArrowUp' || (event.key === 'Up')) {
280
- if (row.sectionRowIndex === 0) {
281
- return;
282
- }
283
- const newRow = tbody.rows.item(row.sectionRowIndex - 1);
284
- if (isRow) {
285
- nextSelection = newRow;
286
- } else {
287
- nextSelection = newRow.cells.item(cellIndex);
288
- }
289
- } else if (event.key === 'ArrowDown' || (event.key === 'Down')) {
290
- const newIndex = row.sectionRowIndex + 1;
291
- if (newIndex >= tbody.rows.length) {
292
- return;
293
- }
294
- const newRow = tbody.rows.item(newIndex);
295
- if (isRow) {
296
- nextSelection = newRow;
297
- } else {
298
- nextSelection = newRow.cells.item(cellIndex);
299
- }
300
- } else if (event.ctrlKey && event.key === 'Home') {
301
- if (row.sectionRowIndex === 0 && cellIndex === 0) {
302
- return;
303
- }
304
- const newRow = tbody.rows.item(0);
305
- if (isRow) {
306
- nextSelection = newRow;
307
- } else {
308
- nextSelection = newRow.cells.item(0);
309
- }
310
- } else if (event.ctrlKey && event.key === 'End') {
311
- const newRowIndex = tbody.rows.length - 1;
312
- let newCellIndex = 0;
313
- if (!isRow) {
314
- newCellIndex = row.cells.length - 1;
315
- }
316
- if (row.sectionRowIndex === newRowIndex && cellIndex === newCellIndex) {
317
- return;
318
- }
319
- const newRow = tbody.rows.item(newRowIndex);
320
- if (isRow) {
321
- nextSelection = newRow;
322
- } else {
323
- nextSelection = newRow.cells.item(newCellIndex);
324
- }
325
- } else if (event.key === 'Home') {
326
- if (isRow) {
327
- return;
328
- }
329
- if (cellIndex === 0) {
330
- return;
331
- }
332
- nextSelection = row.cells.item(0);
333
- } else if (event.key === 'End') {
334
- if (isRow) {
335
- return;
336
- }
337
- const newIndex = row.cells.length - 1;
338
- if (newIndex === cellIndex) {
339
- return;
340
- }
341
- nextSelection = row.cells.item(newIndex);
342
- } else {
343
- const isRtlEnabled = isRtl();
344
- let isLeft = false;
345
- let isRight = false;
346
- if (event.key === 'ArrowLeft' || (event.key === 'Left')) {
347
- if (isRtlEnabled) {
348
- isRight = true;
349
- } else {
350
- isLeft = true;
351
- }
352
- }
353
- if (event.key === 'ArrowRight' || (event.key === 'Right')) {
354
- if (isRtlEnabled) {
355
- isLeft = true;
356
- } else {
357
- isRight = true;
358
- }
359
- }
360
- if (isLeft) {
361
- if (isRow) {
362
- return;
363
- }
364
- if (cellIndex === 0) {
365
- return;
366
- }
367
- nextSelection = row.cells.item(cellIndex - 1);
368
- } else if (isRight) {
369
- if (isRow) {
370
- return;
371
- }
372
- const newIndex = cellIndex + 1;
373
- if (newIndex >= row.cells.length) {
374
- return;
375
- }
376
- nextSelection = row.cells.item(newIndex);
153
+ onFocusInteraction.split(' ').forEach((interaction) => {
154
+ switch (interaction) {
155
+ case 'select':
156
+ if (itemElement instanceof HTMLTableRowElement) {
157
+ DataTableRow.setSelected(itemElement, true);
158
+ } else {
159
+ DataTableCell.setSelected(itemElement, true);
160
+ }
161
+ break;
162
+ default:
377
163
  }
378
- }
379
- if (nextSelection) {
380
- event.stopPropagation();
381
- event.preventDefault();
382
- currentSelection.setAttribute('tabindex', '-1');
383
- nextSelection.focus();
384
- updateTabIndex(nextSelection, false);
385
- }
164
+ });
386
165
  }
387
166
 
388
167
  /**
389
- * @param {Element} element
168
+ * @param {CustomEvent} event
390
169
  * @return {void}
391
170
  */
392
- export function detach(element) {
393
- element.removeAttribute('mdw-js');
394
- const headerRow = getHeaderRow(element);
395
- const tbody = getTableBody(element);
396
- headerRow.removeEventListener('click', onHeaderRowClick);
397
- tbody.removeEventListener('keydown', onTableBodyKeyDown);
398
- tbody.removeEventListener('click', onTableBodyClick);
171
+ export function onSort(event) {
172
+ /** @type {HTMLElement} */
173
+ const datatableElement = (event.currentTarget);
174
+ /** @type {HTMLTableHeaderCellElement} */
175
+ const cell = (event.target);
176
+ sortColumn(datatableElement, cell.cellIndex, event.detail.sort === 'ascending');
399
177
  }
400
178
 
401
179
  /**
402
- * @param {Element} datatableElement
403
- * @return {HTMLElement}
180
+ * @param {CustomEvent} event
181
+ * @return {void}
404
182
  */
405
- export function getScroller(datatableElement) {
183
+ export function onRowHeaderCheckedChange(event) {
184
+ /** @type {HTMLTableHeaderCellElement} */
185
+ const cell = (event.target);
186
+ const row = cell.parentElement;
187
+ DataTableRow.setSelected(row, event.detail.value);
188
+ }
189
+
190
+ /**
191
+ * @param {Event} event
192
+ * @return {void}
193
+ */
194
+ function onTabIndexZeroed(event) {
406
195
  /** @type {HTMLElement} */
407
- let scroller = (datatableElement.getElementsByClassName('mdw-datatable__scroller')[0]);
408
- if (!scroller) {
409
- scroller = document.createElement('div');
410
- scroller.classList.add('mdw-datatable__scroller');
411
- const footer = datatableElement.getElementsByClassName('mdw-datatable__footer')[0];
412
- if (footer) {
413
- datatableElement.insertBefore(scroller, footer);
414
- } else {
415
- datatableElement.appendChild(scroller);
416
- }
417
- // Move table into scroller if it exists
418
- const table = datatableElement.getElementsByTagName('table')[0];
419
- if (table) {
420
- table.parentElement.removeChild(table);
421
- scroller.appendChild(table);
422
- }
196
+ const dataTableElement = (event.currentTarget);
197
+ /** @type {HTMLElement} */
198
+ const emitter = (event.target);
199
+
200
+ const row = (emitter instanceof HTMLTableRowElement && emitter);
201
+ const cell = (!row && emitter instanceof HTMLTableCellElement && emitter);
202
+ if (!row && !cell) {
203
+ return;
423
204
  }
424
- return scroller;
205
+ event.stopPropagation();
206
+ RovingTabIndex.removeTabIndex(dataTableElement.querySelectorAll(row ? 'tr' : CELL_TABINDEX_QUERIES.join(',')), [emitter]);
425
207
  }
426
208
 
427
209
  /**
428
- * @param {Element} datatableElement
429
- * @return {HTMLTableElement}
210
+ * @param {CustomEvent} event
211
+ * @return {void}
430
212
  */
431
- export function getTable(datatableElement) {
432
- if (datatableElement instanceof HTMLTableElement) {
433
- return datatableElement;
213
+ export function onKeyboard(event) {
214
+ /** @type {HTMLElement} */
215
+ const dataTableElement = (event.currentTarget);
216
+ /** @type {HTMLElement} */
217
+ const emitter = (event.target);
218
+ let current = document.activeElement;
219
+
220
+ let row = (emitter instanceof HTMLTableRowElement && emitter);
221
+ const cell = (!row && emitter instanceof HTMLTableCellElement && emitter);
222
+ if (!row && !cell) {
223
+ return;
434
224
  }
435
- let table = datatableElement.getElementsByTagName('table')[0];
436
- if (!table) {
437
- const scroller = getScroller(datatableElement);
438
- table = document.createElement('table');
439
- scroller.appendChild(table);
225
+ if (!row) {
226
+ /** @type {HTMLTableRowElement} */
227
+ row = (cell.parentElement);
440
228
  }
441
- return table;
229
+
230
+ let checkNavKeys = false;
231
+ switch (event.type) {
232
+ case Keyboard.SPACEBAR_KEY:
233
+ if (event.detail.ctrlKey || event.detail.altKey || event.detail.metaKey) {
234
+ return;
235
+ }
236
+ if (!event.detail.shiftKey) {
237
+ return;
238
+ }
239
+ if (!row.hasAttribute('aria-selected')) {
240
+ return;
241
+ }
242
+ DataTableRow.setSelected(row, row.getAttribute('aria-selected') !== 'true', true);
243
+ break;
244
+ default:
245
+ checkNavKeys = true;
246
+ }
247
+
248
+ if (checkNavKeys) {
249
+ // Keyboard Navigation
250
+ /** @type {ArrayLike<HTMLElement>} */
251
+ let searchElements;
252
+ let reverse = false;
253
+ let loop = false;
254
+ switch (event.type) {
255
+ case Keyboard.UP_ARROW_KEY:
256
+ reverse = true;
257
+ // eslint-disable-next-line no-fallthrough
258
+ case Keyboard.DOWN_ARROW_KEY:
259
+ if (event.detail.ctrlKey || event.detail.altKey || event.detail.metaKey) {
260
+ return;
261
+ }
262
+ if (cell) {
263
+ searchElements = getTableBody(dataTableElement).querySelectorAll(
264
+ CELL_TABINDEX_QUERIES.map((q) => `${q}:nth-child(${cell.cellIndex + 1})`).join(','),
265
+ );
266
+ } else {
267
+ searchElements = getTableBody(dataTableElement).getElementsByTagName('tr');
268
+ }
269
+ break;
270
+ case Keyboard.BACK_ARROW_KEY:
271
+ reverse = true;
272
+ // eslint-disable-next-line no-fallthrough
273
+ case Keyboard.FORWARD_ARROW_KEY:
274
+ if (event.detail.ctrlKey || event.detail.altKey || event.detail.metaKey) {
275
+ return;
276
+ }
277
+ if (!cell) {
278
+ return;
279
+ }
280
+ searchElements = cell.parentElement.querySelectorAll(CELL_TABINDEX_QUERIES.join(','));
281
+ break;
282
+ case Keyboard.END_KEY:
283
+ reverse = true;
284
+ // eslint-disable-next-line no-fallthrough
285
+ case Keyboard.HOME_KEY:
286
+ if (event.detail.altKey || event.detail.metaKey) {
287
+ return;
288
+ }
289
+ if (!cell) {
290
+ return;
291
+ }
292
+ if (event.detail.ctrlKey) {
293
+ searchElements = getTableBody(dataTableElement).querySelectorAll(CELL_TABINDEX_QUERIES.join(','));
294
+ } else {
295
+ searchElements = cell.parentElement.querySelectorAll(CELL_TABINDEX_QUERIES.join(','));
296
+ }
297
+ cell.setAttribute('tabindex', '-1');
298
+ current = null;
299
+ loop = true;
300
+ break;
301
+ default:
302
+ return;
303
+ }
304
+ RovingTabIndex.selectNext(searchElements, current, loop, reverse);
305
+ }
306
+
307
+ event.preventDefault();
308
+ event.stopPropagation();
309
+ }
310
+
311
+ /**
312
+ * @param {Element} element
313
+ * @return {void}
314
+ */
315
+ export function detach(element) {
316
+ element.removeAttribute('mdw-datatable-js');
317
+ element.removeEventListener(DataTableRow.FOCUS_EVENT, onItemFocus);
318
+ element.removeEventListener(DataTableCell.FOCUS_EVENT, onItemFocus);
319
+ element.removeEventListener(DataTableColumnHeader.SORT_EVENT, onSort);
320
+ element.removeEventListener(Keyboard.UP_ARROW_KEY, onKeyboard);
321
+ element.removeEventListener(Keyboard.DOWN_ARROW_KEY, onKeyboard);
322
+ element.removeEventListener(Keyboard.FORWARD_ARROW_KEY, onKeyboard);
323
+ element.removeEventListener(Keyboard.BACK_ARROW_KEY, onKeyboard);
324
+ element.removeEventListener(Keyboard.HOME_KEY, onKeyboard);
325
+ element.removeEventListener(Keyboard.END_KEY, onKeyboard);
326
+ element.removeEventListener(RovingTabIndex.TABINDEX_ZEROED, onTabIndexZeroed);
442
327
  }
443
328
 
444
329
  /**
@@ -461,15 +346,43 @@ export function getHeaderRow(tableElement) {
461
346
  }
462
347
 
463
348
  /**
464
- * @param {Element} datatableElement
465
- * @return {HTMLTableSectionElement}
349
+ * @param {Element} element
350
+ * @return {void}
466
351
  */
467
- export function getTableBody(datatableElement) {
468
- let tbody = datatableElement.getElementsByTagName('tbody')[0];
469
- if (!tbody) {
470
- const table = getTable(datatableElement);
471
- tbody = document.createElement('tbody');
472
- table.appendChild(tbody);
352
+ export function attach(element) {
353
+ element.setAttribute('mdw-datatable-js', '');
354
+
355
+ const table = getTable(element);
356
+ table.setAttribute('role', 'grid');
357
+ const headerRow = getHeaderRow(element);
358
+ const tbody = getTableBody(element);
359
+
360
+ iterateArrayLike(headerRow.getElementsByTagName('th'), DataTableColumnHeader.attach);
361
+ iterateArrayLike(tbody.getElementsByTagName('th'), DataTableRowHeader.attach);
362
+
363
+ const tableRows = tbody.getElementsByTagName('tr');
364
+ iterateArrayLike(tableRows, DataTableRow.attach);
365
+
366
+ const rowFocusable = element.hasAttribute('mdw-row-focusable');
367
+ if (rowFocusable) {
368
+ RovingTabIndex.setupTabIndexes(tableRows);
473
369
  }
474
- return tbody;
370
+ const cellFocusable = element.hasAttribute('mdw-cell-focusable');
371
+ if (cellFocusable) {
372
+ RovingTabIndex.setupTabIndexes(tbody.querySelectorAll(CELL_TABINDEX_QUERIES.join(',')));
373
+ }
374
+
375
+ element.addEventListener(DataTableRow.FOCUS_EVENT, onItemFocus);
376
+ element.addEventListener(DataTableRow.SELECTED_CHANGE_EVENT, onSelectedChange);
377
+ element.addEventListener(DataTableCell.FOCUS_EVENT, onItemFocus);
378
+ element.addEventListener(DataTableCell.SELECTED_CHANGE_EVENT, onSelectedChange);
379
+ element.addEventListener(DataTableColumnHeader.SORT_EVENT, onSort);
380
+ element.addEventListener(Keyboard.SPACEBAR_KEY, onKeyboard);
381
+ element.addEventListener(Keyboard.UP_ARROW_KEY, onKeyboard);
382
+ element.addEventListener(Keyboard.DOWN_ARROW_KEY, onKeyboard);
383
+ element.addEventListener(Keyboard.FORWARD_ARROW_KEY, onKeyboard);
384
+ element.addEventListener(Keyboard.BACK_ARROW_KEY, onKeyboard);
385
+ element.addEventListener(Keyboard.HOME_KEY, onKeyboard);
386
+ element.addEventListener(Keyboard.END_KEY, onKeyboard);
387
+ element.addEventListener(RovingTabIndex.TABINDEX_ZEROED, onTabIndexZeroed);
475
388
  }