@shortfuse/materialdesignweb 0.0.9 → 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 (392) hide show
  1. package/.browserslistrc +3 -0
  2. package/.eslintrc.json +146 -27
  3. package/.stylelintrc.json +598 -2
  4. package/.vscode/launch.json +20 -5
  5. package/.vscode/settings.json +3 -0
  6. package/.vscode/tasks.json +19 -10
  7. package/CHANGELOG.md +24 -0
  8. package/README.md +84 -2
  9. package/adapters/datatable/column.js +203 -0
  10. package/adapters/datatable/index.js +972 -0
  11. package/adapters/dom/index.js +601 -0
  12. package/adapters/list/index.js +69 -0
  13. package/adapters/search/index.js +521 -0
  14. package/components/appbar/_spec.scss +225 -0
  15. package/components/appbar/_theme.scss +0 -0
  16. package/components/appbar/index.scss +2 -0
  17. package/components/banner/_spec.scss +118 -0
  18. package/components/banner/_theme.scss +0 -0
  19. package/components/banner/index.scss +2 -0
  20. package/components/bottomnav/README.md +85 -0
  21. package/components/bottomnav/_spec.scss +157 -0
  22. package/components/bottomnav/_theme.scss +0 -0
  23. package/components/bottomnav/index.js +122 -0
  24. package/components/bottomnav/index.scss +2 -0
  25. package/components/bottomnav/item.js +89 -0
  26. package/components/{core/button → button}/README.md +16 -22
  27. package/components/button/_spec.scss +161 -0
  28. package/components/button/_theme.scss +65 -0
  29. package/components/button/index.eta +32 -0
  30. package/components/button/index.js +43 -0
  31. package/components/button/index.pug +18 -0
  32. package/components/button/index.scss +2 -0
  33. package/components/card/_spec.scss +249 -0
  34. package/components/card/_theme.scss +0 -0
  35. package/components/card/index.scss +2 -0
  36. package/components/chip/_spec.scss +134 -0
  37. package/components/chip/_theme.scss +177 -0
  38. package/components/chip/index.js +21 -0
  39. package/components/chip/index.scss +2 -0
  40. package/components/chip/item.js +20 -0
  41. package/components/datatable/_spec.scss +288 -0
  42. package/components/datatable/_theme.scss +154 -0
  43. package/components/datatable/cell.js +45 -0
  44. package/components/datatable/columnheader.js +47 -0
  45. package/components/datatable/index.js +388 -0
  46. package/components/datatable/index.scss +2 -0
  47. package/components/datatable/row.js +49 -0
  48. package/components/datatable/rowheader.js +18 -0
  49. package/components/dialog/_spec.scss +213 -0
  50. package/components/dialog/_theme.scss +0 -0
  51. package/components/dialog/index.js +627 -0
  52. package/components/dialog/index.scss +2 -0
  53. package/components/divider/_spec.scss +13 -0
  54. package/components/divider/_theme.scss +0 -0
  55. package/components/divider/index.scss +2 -0
  56. package/components/elevation/_spec.scss +9 -0
  57. package/components/elevation/_theme.scss +0 -0
  58. package/components/elevation/index.scss +2 -0
  59. package/components/fab/_spec.scss +222 -0
  60. package/components/fab/_theme.scss +0 -0
  61. package/components/fab/index.js +103 -0
  62. package/components/fab/index.scss +2 -0
  63. package/components/grid/_spec.scss +312 -0
  64. package/components/grid/_theme.scss +0 -0
  65. package/components/grid/index.scss +2 -0
  66. package/components/layout/_mixins.scss +33 -0
  67. package/components/layout/_spec.scss +1012 -0
  68. package/components/layout/_theme.scss +44 -0
  69. package/components/layout/index.js +464 -0
  70. package/components/layout/index.scss +2 -0
  71. package/components/list/_spec.scss +397 -0
  72. package/components/list/_theme.scss +111 -0
  73. package/components/list/content.js +110 -0
  74. package/components/list/index.js +260 -0
  75. package/components/list/index.scss +2 -0
  76. package/components/list/item.js +170 -0
  77. package/components/list/secondary.js +46 -0
  78. package/components/menu/_spec.scss +362 -0
  79. package/components/menu/_theme.scss +0 -0
  80. package/components/menu/index.js +721 -0
  81. package/components/menu/index.scss +2 -0
  82. package/components/menu/item.js +239 -0
  83. package/components/{core/progress/style.scss → progress/_spec.scss} +36 -25
  84. package/components/progress/_theme.scss +0 -0
  85. package/components/progress/index.js +36 -0
  86. package/components/progress/index.scss +2 -0
  87. package/components/selection/_spec.scss +386 -0
  88. package/components/selection/_theme.scss +166 -0
  89. package/components/selection/index.eta +60 -0
  90. package/components/selection/index.js +76 -0
  91. package/components/selection/index.pug +30 -0
  92. package/components/selection/index.scss +2 -0
  93. package/components/selection/input.js +56 -0
  94. package/components/selection/radiogroup.js +47 -0
  95. package/components/slider/_spec.scss +64 -0
  96. package/components/slider/_theme.scss +0 -0
  97. package/components/slider/index.scss +2 -0
  98. package/components/snackbar/_spec.scss +195 -0
  99. package/components/snackbar/_theme.scss +0 -0
  100. package/components/snackbar/index.js +344 -0
  101. package/components/snackbar/index.scss +2 -0
  102. package/components/tab/_spec.scss +235 -0
  103. package/components/tab/_theme.scss +0 -0
  104. package/components/tab/content.js +205 -0
  105. package/components/tab/index.js +260 -0
  106. package/components/tab/index.scss +2 -0
  107. package/components/tab/item.js +89 -0
  108. package/components/tab/list.js +210 -0
  109. package/components/tab/panel.js +54 -0
  110. package/components/template/_theme.scss +27 -0
  111. package/components/{core/textfield → textfield}/README.md +70 -50
  112. package/components/textfield/_mixins.scss +52 -0
  113. package/components/textfield/_spec.scss +809 -0
  114. package/components/textfield/_theme.scss +299 -0
  115. package/components/textfield/index.eta +74 -0
  116. package/components/textfield/index.js +168 -0
  117. package/components/textfield/index.pug +30 -0
  118. package/components/textfield/index.scss +2 -0
  119. package/components/tooltip/_spec.scss +188 -0
  120. package/components/tooltip/_theme.scss +0 -0
  121. package/components/tooltip/index.scss +2 -0
  122. package/components/type/_spec.scss +224 -0
  123. package/components/type/_theme.scss +0 -0
  124. package/components/type/index.scss +2 -0
  125. package/core/_breakpoint.scss +189 -0
  126. package/core/_elevation.scss +38 -0
  127. package/core/_length.scss +9 -0
  128. package/core/_motion.scss +31 -0
  129. package/core/_platform.scss +34 -0
  130. package/core/_type.scss +127 -0
  131. package/core/aria/attributes.js +141 -0
  132. package/core/aria/button.js +50 -0
  133. package/core/aria/keyboard.js +93 -0
  134. package/core/aria/rovingtabindex.js +178 -0
  135. package/core/aria/tab.js +60 -0
  136. package/core/color/_spec.scss +0 -0
  137. package/core/color/_theme.scss +390 -0
  138. package/core/color/index.scss +2 -0
  139. package/core/document/index.js +39 -0
  140. package/core/dom.js +271 -0
  141. package/core/overlay/_spec.scss +31 -0
  142. package/core/overlay/_theme.scss +171 -0
  143. package/core/overlay/index.js +108 -0
  144. package/core/overlay/index.scss +2 -0
  145. package/core/ripple/_spec.scss +197 -0
  146. package/core/ripple/_theme.scss +40 -0
  147. package/core/ripple/index.js +294 -0
  148. package/core/ripple/index.scss +2 -0
  149. package/core/theme/_config.scss +2 -0
  150. package/core/theme/_mixins.scss +172 -0
  151. package/{components/theming/palettes.scss → core/theme/_palettes.scss} +173 -150
  152. package/core/theme/_variables.scss +24 -0
  153. package/core/theme/index.js +50 -0
  154. package/core/throttler.js +42 -0
  155. package/core/transition/index.js +468 -0
  156. package/docs/_flex.scss +22 -0
  157. package/docs/_menuoptions.js +183 -0
  158. package/docs/_mixins.pug +155 -0
  159. package/docs/_partials/_androidnavbar.eta +5 -0
  160. package/docs/_partials/_androidstatusbar.eta +13 -0
  161. package/docs/_partials/_appbar.eta +29 -0
  162. package/docs/_partials/_buttontest.eta +31 -0
  163. package/docs/_partials/_header.eta +149 -0
  164. package/docs/_partials/_navlistitem.eta +16 -0
  165. package/docs/_partials/_target.eta +1 -0
  166. package/docs/_sample-utils.js +93 -0
  167. package/docs/_storage.js +33 -0
  168. package/docs/docs.scss +295 -0
  169. package/docs/index.eta +16 -0
  170. package/docs/index.js +0 -0
  171. package/docs/pages/appbar.eta +114 -0
  172. package/docs/pages/appbar.js +0 -0
  173. package/docs/pages/appbar.pug +78 -0
  174. package/docs/pages/bottomnav.eta +188 -0
  175. package/docs/pages/bottomnav.js +115 -0
  176. package/docs/pages/bottomnav.pug +137 -0
  177. package/docs/pages/button.eta +124 -0
  178. package/docs/pages/button.js +224 -0
  179. package/docs/pages/button.pug +121 -0
  180. package/docs/pages/card.eta +90 -0
  181. package/docs/pages/card.js +177 -0
  182. package/docs/pages/card.pug +74 -0
  183. package/docs/pages/chip.eta +122 -0
  184. package/docs/pages/chip.js +82 -0
  185. package/docs/pages/chip.pug +91 -0
  186. package/docs/pages/color.eta +143 -0
  187. package/docs/pages/color.js +262 -0
  188. package/docs/pages/color.pug +121 -0
  189. package/docs/pages/datatable.eta +323 -0
  190. package/docs/pages/datatable.js +164 -0
  191. package/docs/pages/datatable.pug +283 -0
  192. package/docs/pages/dialog.eta +186 -0
  193. package/docs/pages/dialog.js +177 -0
  194. package/docs/pages/dialog.pug +132 -0
  195. package/docs/pages/dom.eta +26 -0
  196. package/docs/pages/dom.js +143 -0
  197. package/docs/pages/dom.pug +22 -0
  198. package/docs/pages/elevation.eta +35 -0
  199. package/docs/pages/elevation.js +0 -0
  200. package/docs/pages/elevation.pug +25 -0
  201. package/docs/pages/fab.eta +99 -0
  202. package/docs/pages/fab.js +44 -0
  203. package/docs/pages/fab.pug +66 -0
  204. package/docs/pages/grid.eta +135 -0
  205. package/docs/pages/grid.js +128 -0
  206. package/docs/pages/grid.pug +95 -0
  207. package/docs/pages/layout.eta +8 -0
  208. package/docs/pages/layout.js +0 -0
  209. package/docs/pages/layout.pug +7 -0
  210. package/docs/pages/list.eta +465 -0
  211. package/docs/pages/list.js +9 -0
  212. package/docs/pages/list.pug +326 -0
  213. package/docs/pages/menu.eta +276 -0
  214. package/docs/pages/menu.js +217 -0
  215. package/docs/pages/menu.pug +205 -0
  216. package/docs/pages/overlay.eta +69 -0
  217. package/docs/pages/overlay.js +4 -0
  218. package/docs/pages/overlay.pug +55 -0
  219. package/docs/pages/progress.eta +23 -0
  220. package/docs/pages/progress.js +12 -0
  221. package/docs/pages/progress.pug +16 -0
  222. package/docs/pages/ripple.eta +27 -0
  223. package/docs/pages/ripple.js +4 -0
  224. package/docs/pages/ripple.pug +21 -0
  225. package/docs/pages/search.eta +246 -0
  226. package/docs/pages/search.js +243 -0
  227. package/docs/pages/search.pug +165 -0
  228. package/docs/pages/selection.eta +111 -0
  229. package/docs/pages/selection.js +13 -0
  230. package/docs/pages/selection.pug +74 -0
  231. package/docs/pages/slider.eta +23 -0
  232. package/docs/pages/slider.js +0 -0
  233. package/docs/pages/slider.pug +17 -0
  234. package/docs/pages/snackbar.eta +83 -0
  235. package/docs/pages/snackbar.js +158 -0
  236. package/docs/pages/snackbar.pug +60 -0
  237. package/docs/pages/tab.eta +421 -0
  238. package/docs/pages/tab.js +151 -0
  239. package/docs/pages/tab.pug +304 -0
  240. package/docs/pages/textfield.eta +486 -0
  241. package/docs/pages/textfield.js +254 -0
  242. package/docs/pages/textfield.pug +360 -0
  243. package/docs/pages/tooltip.eta +94 -0
  244. package/docs/pages/tooltip.js +0 -0
  245. package/docs/pages/tooltip.pug +78 -0
  246. package/docs/pages/transition.eta +117 -0
  247. package/docs/pages/transition.js +54 -0
  248. package/docs/pages/transition.pug +76 -0
  249. package/docs/pages/type.eta +31 -0
  250. package/docs/pages/type.js +0 -0
  251. package/docs/pages/type.pug +29 -0
  252. package/docs/postrender.js +39 -0
  253. package/docs/prerender.js +16 -0
  254. package/docs/pwa/_dialogs.eta +143 -0
  255. package/docs/pwa/_dialogs.pug +96 -0
  256. package/docs/pwa/_menus.eta +16 -0
  257. package/docs/pwa/_menus.pug +11 -0
  258. package/docs/pwa/pwa-prerender.js +3 -0
  259. package/docs/pwa/pwa.eta +480 -0
  260. package/docs/pwa/pwa.js +306 -0
  261. package/docs/pwa/pwa.pug +325 -0
  262. package/docs/pwa/pwa.scss +26 -0
  263. package/docs/spec.scss +26 -0
  264. package/docs/themes/_component-themes.scss +26 -0
  265. package/docs/themes/theme-colored-fallbacks.scss +17 -0
  266. package/docs/themes/theme-colored.scss +17 -0
  267. package/docs/themes/theme-default-fallbacks.scss +17 -0
  268. package/docs/themes/theme-default.scss +17 -0
  269. package/jsconfig.json +4 -2
  270. package/package.json +43 -28
  271. package/scripts/deploy-docs.sh +9 -0
  272. package/templates/index.eta +2 -0
  273. package/templates/index.pug +3 -0
  274. package/utils/function.js +3 -0
  275. package/webpack.config.cjs +257 -0
  276. package/components/_index.scss +0 -4
  277. package/components/all-components.scss +0 -14
  278. package/components/common/functions.scss +0 -173
  279. package/components/common/mixins.scss +0 -107
  280. package/components/common/motion.scss +0 -36
  281. package/components/common/ripple.scss +0 -92
  282. package/components/common/variables.scss +0 -48
  283. package/components/complex/dialog/style.scss +0 -159
  284. package/components/complex/dialog/theming.scss +0 -29
  285. package/components/complex/navdrawer/style.scss +0 -477
  286. package/components/complex/navdrawer/theming.scss +0 -58
  287. package/components/complex/search/index.js +0 -492
  288. package/components/core/bottomnav/README.md +0 -85
  289. package/components/core/bottomnav/index.js +0 -140
  290. package/components/core/bottomnav/style.scss +0 -173
  291. package/components/core/bottomnav/theming.scss +0 -42
  292. package/components/core/button/index.js +0 -52
  293. package/components/core/button/style.scss +0 -283
  294. package/components/core/button/theming.scss +0 -131
  295. package/components/core/list/index.js +0 -94
  296. package/components/core/list/style.scss +0 -269
  297. package/components/core/list/theming.scss +0 -74
  298. package/components/core/menu/index.js +0 -127
  299. package/components/core/menu/style.scss +0 -239
  300. package/components/core/menu/theming.scss +0 -55
  301. package/components/core/progress/index.js +0 -33
  302. package/components/core/selection/style.scss +0 -249
  303. package/components/core/selection/theming.scss +0 -49
  304. package/components/core/switch/style.scss +0 -3
  305. package/components/core/tab/index.js +0 -174
  306. package/components/core/tab/style.scss +0 -202
  307. package/components/core/tab/theming.scss +0 -43
  308. package/components/core/textfield/index.js +0 -169
  309. package/components/core/textfield/style.scss +0 -672
  310. package/components/core/textfield/theming.scss +0 -262
  311. package/components/core/toolbar/style.scss +0 -109
  312. package/components/core/toolbar/theming.scss +0 -28
  313. package/components/core/tooltip/style.scss +0 -127
  314. package/components/core/type/style.scss +0 -133
  315. package/components/core/type/theming.scss +0 -25
  316. package/components/index.js +0 -24
  317. package/components/template/theming.scss +0 -31
  318. package/components/theming/theming.scss +0 -504
  319. package/docs/bottomnav.html +0 -171
  320. package/docs/bottomnav.min.js +0 -383
  321. package/docs/button.html +0 -322
  322. package/docs/button.min.js +0 -251
  323. package/docs/components.min.css +0 -1
  324. package/docs/components.min.js +0 -83
  325. package/docs/dialog.html +0 -103
  326. package/docs/dialog.min.js +0 -160
  327. package/docs/docs.min.css +0 -1
  328. package/docs/docs.min.js +0 -83
  329. package/docs/index.html +0 -55
  330. package/docs/index.min.js +0 -83
  331. package/docs/list.html +0 -442
  332. package/docs/list.min.js +0 -312
  333. package/docs/menu.html +0 -185
  334. package/docs/menu.min.js +0 -370
  335. package/docs/navdrawer.html +0 -199
  336. package/docs/navdrawer.min.js +0 -244
  337. package/docs/progress.html +0 -75
  338. package/docs/progress.min.js +0 -162
  339. package/docs/search.html +0 -230
  340. package/docs/search.min.js +0 -1202
  341. package/docs/selection.html +0 -188
  342. package/docs/selection.min.js +0 -160
  343. package/docs/src/complex/dialog.js +0 -3
  344. package/docs/src/complex/dialog.pug +0 -44
  345. package/docs/src/complex/navdrawer.js +0 -82
  346. package/docs/src/complex/navdrawer.pug +0 -109
  347. package/docs/src/complex/search.js +0 -207
  348. package/docs/src/complex/search.pug +0 -143
  349. package/docs/src/components.scss +0 -1
  350. package/docs/src/core/bottomnav.js +0 -22
  351. package/docs/src/core/bottomnav.pug +0 -93
  352. package/docs/src/core/button.js +0 -16
  353. package/docs/src/core/button.pug +0 -73
  354. package/docs/src/core/list.js +0 -21
  355. package/docs/src/core/list.pug +0 -246
  356. package/docs/src/core/menu.js +0 -33
  357. package/docs/src/core/menu.pug +0 -108
  358. package/docs/src/core/progress.js +0 -11
  359. package/docs/src/core/progress.pug +0 -17
  360. package/docs/src/core/selection.js +0 -4
  361. package/docs/src/core/selection.pug +0 -92
  362. package/docs/src/core/tab.js +0 -21
  363. package/docs/src/core/tab.pug +0 -180
  364. package/docs/src/core/textfield.js +0 -15
  365. package/docs/src/core/textfield.pug +0 -274
  366. package/docs/src/core/toolbar.js +0 -4
  367. package/docs/src/core/toolbar.pug +0 -79
  368. package/docs/src/core/tooltip.js +0 -4
  369. package/docs/src/core/tooltip.pug +0 -76
  370. package/docs/src/core/type.js +0 -4
  371. package/docs/src/core/type.pug +0 -36
  372. package/docs/src/docs.scss +0 -200
  373. package/docs/src/index.pug +0 -5
  374. package/docs/src/mixins.pug +0 -72
  375. package/docs/src/targetHandler.js +0 -50
  376. package/docs/src/theming.ie11.scss +0 -35
  377. package/docs/src/theming.scss +0 -36
  378. package/docs/tab.html +0 -301
  379. package/docs/tab.min.js +0 -397
  380. package/docs/textfield.html +0 -476
  381. package/docs/textfield.min.js +0 -381
  382. package/docs/theming.ie11.min.css +0 -1
  383. package/docs/theming.ie11.min.js +0 -83
  384. package/docs/theming.min.css +0 -1
  385. package/docs/theming.min.js +0 -83
  386. package/docs/toolbar.html +0 -213
  387. package/docs/toolbar.min.js +0 -160
  388. package/docs/tooltip.html +0 -138
  389. package/docs/tooltip.min.js +0 -160
  390. package/docs/type.html +0 -94
  391. package/docs/type.min.js +0 -160
  392. package/webpack.config.js +0 -176
@@ -0,0 +1,2 @@
1
+ @forward './_spec.scss';
2
+ @forward './_theme.scss';
@@ -0,0 +1,239 @@
1
+ // https://www.w3.org/TR/wai-aria-practices/#menu
2
+
3
+ import * as Attributes from '../../core/aria/attributes.js';
4
+ import {
5
+ dispatchDomEvent,
6
+ iterateArrayLike,
7
+ iterateElementSiblings,
8
+ } from '../../core/dom.js';
9
+ import * as Overlay from '../../core/overlay/index.js';
10
+ import * as Ripple from '../../core/ripple/index.js';
11
+
12
+ export const ACTIVATE_EVENT = 'mdw:menuitem-activate';
13
+ export const CHECK_EVENT = 'mdw:menuitem-check';
14
+ export const UNCHECK_EVENT = 'mdw:menuitem-uncheck';
15
+
16
+ /**
17
+ * @param {Element} element
18
+ * @return {void}
19
+ */
20
+ export function setupARIA(element) {
21
+ if (element.hasAttribute('mdw-no-aria')) {
22
+ return;
23
+ }
24
+ const role = element.getAttribute('role');
25
+ let useAriaChecked = false;
26
+ if (role === 'menuitemcheckbox' || role === 'menuitemradio') {
27
+ useAriaChecked = true;
28
+ } else if (role !== 'menuitem') {
29
+ if (element.getElementsByClassName('mdw-menu__check').length) {
30
+ useAriaChecked = true;
31
+ element.setAttribute('role', 'menuitemcheckbox');
32
+ } else if (element.getElementsByClassName('mdw-menu__radio').length) {
33
+ useAriaChecked = true;
34
+ element.setAttribute('role', 'menuitemradio');
35
+ } else {
36
+ element.setAttribute('role', 'menuitem');
37
+ }
38
+ }
39
+ if (useAriaChecked && !element.hasAttribute('aria-checked')) {
40
+ element.setAttribute('aria-checked', 'false');
41
+ }
42
+ iterateArrayLike(element.getElementsByClassName('mdw-menu__icon'),
43
+ (el) => el.setAttribute('aria-hidden', 'true'));
44
+ iterateArrayLike(element.getElementsByClassName('mdw-menu__text'),
45
+ (el) => el.setAttribute('role', 'text'));
46
+ iterateArrayLike(element.getElementsByClassName('mdw-menu__check'),
47
+ (el) => el.setAttribute('aria-hidden', 'true'));
48
+ iterateArrayLike(element.getElementsByClassName('mdw-menu__info'),
49
+ (el) => el.setAttribute('role', 'note'));
50
+ }
51
+
52
+ /**
53
+ * @param {MouseEvent} event
54
+ * @return {void}
55
+ */
56
+ export function onMouseMove(event) {
57
+ /** @type {HTMLElement} */
58
+ const el = (event.currentTarget);
59
+ if (!el) {
60
+ return;
61
+ }
62
+ const previousFocus = document.activeElement;
63
+ if (previousFocus === el) {
64
+ // Already focused
65
+ return;
66
+ }
67
+ if (el.getAttribute('aria-disabled') === 'true') {
68
+ return;
69
+ }
70
+ el.focus();
71
+ if (document.activeElement !== el) {
72
+ if (document.activeElement !== previousFocus && previousFocus instanceof HTMLElement) {
73
+ previousFocus.focus();
74
+ }
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @param {Element} element
80
+ * @param {boolean} checked
81
+ * @return {boolean} uiChanged
82
+ */
83
+ export function setChecked(element, checked) {
84
+ const role = element.getAttribute('role');
85
+ let isCheckable = false;
86
+ if (role === 'menuitemcheckbox') {
87
+ isCheckable = true;
88
+ if (!dispatchDomEvent(element, checked ? CHECK_EVENT : UNCHECK_EVENT)) {
89
+ return false;
90
+ }
91
+ }
92
+ if (role === 'menuitemradio') {
93
+ isCheckable = true;
94
+ if (checked) {
95
+ if (!dispatchDomEvent(element, CHECK_EVENT)) {
96
+ return false;
97
+ }
98
+ iterateElementSiblings(element, (sibling) => {
99
+ if (sibling.getAttribute('role') === 'menuitemradio') {
100
+ sibling.setAttribute('aria-checked', 'false');
101
+ }
102
+ });
103
+ }
104
+ }
105
+ if (!isCheckable) {
106
+ return false;
107
+ }
108
+ element.setAttribute('aria-checked', checked ? 'true' : 'false');
109
+ return true;
110
+ }
111
+
112
+ /**
113
+ * @param {Element} element
114
+ * @return {boolean}
115
+ */
116
+ export function toggleChecked(element) {
117
+ const checked = !Attributes.isChecked(element);
118
+ return setChecked(element, checked);
119
+ }
120
+
121
+ /**
122
+ * @param {Element} element
123
+ * @return {boolean} handled
124
+ */
125
+ export function openSubMenu(element) {
126
+ const hasPopup = element.getAttribute('aria-haspopup');
127
+ if (hasPopup !== 'menu' && hasPopup !== 'true') {
128
+ return false;
129
+ }
130
+
131
+ // TODO: Open new menu
132
+ return false;
133
+ }
134
+
135
+ /**
136
+ * @param {MouseEvent|KeyboardEvent|PointerEvent} event
137
+ * @return {void}
138
+ */
139
+ export function onClick(event) {
140
+ event.stopPropagation();
141
+
142
+ /** @type {HTMLElement} */
143
+ const menuItemElement = (event.currentTarget);
144
+ if (Attributes.isDisabled(menuItemElement)) {
145
+ return;
146
+ }
147
+ const role = menuItemElement.getAttribute('role');
148
+ if (role === 'menuitemcheckbox') {
149
+ toggleChecked(menuItemElement);
150
+ } else if (role === 'menuitemradio') {
151
+ setChecked(menuItemElement, true);
152
+ }
153
+ dispatchDomEvent(menuItemElement, ACTIVATE_EVENT);
154
+ }
155
+
156
+ /**
157
+ * @param {KeyboardEvent} event
158
+ * @return {void}
159
+ */
160
+ export function onKeyDown(event) {
161
+ /** @type {HTMLElement} */
162
+ const menuItemElement = (event.currentTarget);
163
+
164
+ if (event.key === 'Enter') {
165
+ event.stopPropagation();
166
+ event.preventDefault();
167
+ if (Attributes.isDisabled(menuItemElement)) {
168
+ return;
169
+ }
170
+ onClick(event);
171
+ return;
172
+ }
173
+
174
+ if (event.key === 'Spacebar' || (event.key === ' ')) {
175
+ event.stopPropagation();
176
+ event.preventDefault();
177
+ if (Attributes.isDisabled(menuItemElement)) {
178
+ return;
179
+ }
180
+ const role = menuItemElement.getAttribute('role');
181
+ if (role === 'menuitemcheckbox') {
182
+ toggleChecked(menuItemElement);
183
+ } else if (role === 'menuitemradio') {
184
+ setChecked(menuItemElement, true);
185
+ } else {
186
+ dispatchDomEvent(menuItemElement, ACTIVATE_EVENT);
187
+ }
188
+ }
189
+ }
190
+
191
+ /**
192
+ * @param {Element} element
193
+ * @return {void}
194
+ */
195
+ export function attachCore(element) {
196
+ // If mouseover is used, an item can still lose focus via keyboard navigation.
197
+ // An extra event listener would need to be created to catch blur but the cursor
198
+ // would still remain over the element, thus needing another mousemove event.
199
+ // Prioritization is given to less event listeners rather than operations per second.
200
+ element.addEventListener('mousemove', onMouseMove);
201
+ element.addEventListener('click', onClick);
202
+ element.addEventListener('keydown', onKeyDown);
203
+ setupARIA(element);
204
+ }
205
+
206
+ /**
207
+ * @param {Element} element
208
+ * @return {void}
209
+ */
210
+ export function attach(element) {
211
+ element.classList.add('mdw-overlay');
212
+ Overlay.attach(element);
213
+
214
+ element.classList.add('mdw-ripple');
215
+ Ripple.attach(element);
216
+
217
+ attachCore(element);
218
+ }
219
+
220
+ /**
221
+ * @param {Element} element
222
+ * @return {void}
223
+ */
224
+ export function detachCore(element) {
225
+ element.removeEventListener('click', onClick);
226
+ element.removeEventListener('mousemove', onMouseMove);
227
+ element.removeEventListener('keydown', onKeyDown);
228
+ element.removeAttribute('mdw-js');
229
+ }
230
+
231
+ /**
232
+ * @param {Element} element
233
+ * @return {void}
234
+ */
235
+ export function detach(element) {
236
+ detachCore(element);
237
+ Ripple.detach(element);
238
+ Overlay.detach(element);
239
+ }
@@ -1,32 +1,41 @@
1
1
  // https://material.io/guidelines/components/progress-activity.html#
2
2
 
3
- $radius: 8.75;
4
- $pi: 3.14159265359;
5
- $circumference: 2 * $pi * $radius;
6
- $duration: 1500ms;
3
+ // https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/anim/progress_indeterminate_rotation_material.xml
4
+ // https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/anim/progress_indeterminate_material.xml
5
+ // https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/drawable/vector_drawable_progress_bar_medium.xml
6
+
7
+ @use "sass:math";
8
+
9
+ @use '../../core/_motion.scss' as motion;
10
+ @use '../../core/_platform.scss' as platform;
11
+
12
+ $duration: 1333ms;
13
+
7
14
 
8
15
  /*
9
16
  * SVG Animated Material Spin Animation
10
17
  * radius = 8.75
11
18
  * pi = 3.14159
12
19
  * circumference = 2 * pi * r = (54.977825)
13
- * dash-length = circumference * (100-x)/100
20
+ * dash-length = circumference * (100-x)/100
14
21
  *
15
22
  * Every cycle rotates entire shape an additional -90deg (CCW)
16
23
  *
17
24
  * Entire animation rotates 4x speed (CW)
18
25
  *
19
- * 1. Start 0.072% from head
20
- * 2. Increase to 75% from head
21
- * 3. Reduce tail to 0.521% from tail
26
+ * 1. Start head at: 0.5%
27
+ * 2. Ease in head: to 75%
28
+ * 3. Ease out tail: to 74.5%
22
29
  * 4. Rotate -90 deg
23
30
  *
24
31
  * Animate with ease-in-out
25
32
  */
26
33
 
27
-
28
34
  @function circlePercentage($percent, $limit: 100) {
29
- @return $circumference * ((3 * ($limit/100)) - $percent/100);
35
+ $radius: 8.75;
36
+ $pi: 3.14159265359;
37
+ $circumference: 2 * $pi * $radius;
38
+ @return $circumference * (math.div($limit,100) - math.div($percent,100));
30
39
  }
31
40
 
32
41
  @keyframes rotate-clockwise {
@@ -51,7 +60,7 @@ $duration: 1500ms;
51
60
  0% {
52
61
  stroke-dashoffset: circlePercentage(0.5, 75);
53
62
  }
54
- 50% {
63
+ #{motion.$standardPeakVelocity * 100%} {
55
64
  stroke-dashoffset: circlePercentage(75,75);
56
65
  }
57
66
  100% {
@@ -79,31 +88,36 @@ $duration: 1500ms;
79
88
  stroke: currentColor;
80
89
  transform-origin: center center;
81
90
  &:nth-child(1) {
82
- stroke-linecap: square;
83
- stroke-dasharray: $circumference * 0.75;
84
- stroke-dashoffset: circlePercentage(33.33, 75);
85
- transform: rotate(0deg);
86
- will-change: stroke-dashoffset, transform;
87
91
  animation-name: mdw-progress-dash, rotate-counterclockwise;
88
92
  animation-duration: $duration, $duration * 4;
89
- animation-timing-function: $motion-easing-standard, steps(4,end);
93
+ animation-timing-function: motion.$standardEasing, steps(4,end);
90
94
  animation-iteration-count: infinite;
95
+
96
+ stroke-dasharray: circlePercentage(25, 100);
97
+ stroke-dashoffset: circlePercentage(math.div(100, 3), 75); // Fallback 33% length for IE
98
+ stroke-linecap: round;
99
+
91
100
  }
92
101
  &:nth-child(2) {
93
102
  display: none;
103
+
94
104
  transition-property: stroke-dashoffset;
95
- transition-duration: $duration;
105
+ transition-duration: motion.$shapeChangeDuration;
106
+ transition-timing-function: motion.$standardEasing;
107
+
108
+ stroke-dasharray: circlePercentage(0, 100);
96
109
  stroke-dashoffset: circlePercentage(0, 100);
97
- stroke-dasharray: $circumference;
110
+ stroke-linecap: square;
98
111
  }
99
112
 
100
113
  }
101
114
  }
102
115
 
103
- // IE and Edge do not support animated SVG
104
- @include MSOnly {
116
+ // IE does not support animated SVG
117
+ // Double rotation speed
118
+ @include platform.ifIE() {
105
119
  &:not([mdw-determinate]) svg {
106
- animation-duration: $duration / 2;
120
+ animation-duration: $duration * 0.5;
107
121
  }
108
122
  }
109
123
  }
@@ -112,13 +126,10 @@ $duration: 1500ms;
112
126
  svg {
113
127
  animation: none;
114
128
  will-change: none;
115
- transform: none;
116
129
  & > path {
117
130
  &:nth-child(1) {
118
131
  display: none;
119
132
  animation: none;
120
- will-change: none;
121
- transform: none;
122
133
  }
123
134
  &:nth-child(2) {
124
135
  display: inline;
File without changes
@@ -0,0 +1,36 @@
1
+ const radius = 8.75;
2
+ const circumference = 2 * Math.PI * radius;
3
+
4
+ // TODO: Upgrade IE/Edge browsers to animate with rAF
5
+
6
+ /**
7
+ * @param {Element} progressCircleElement
8
+ * @return {void}
9
+ */
10
+ export function attach(progressCircleElement) {
11
+ /** @type {Element} */
12
+ let svg = (progressCircleElement.getElementsByTagName('svg')[0]);
13
+ if (!svg) {
14
+ svg = (document.createElement('svg'));
15
+ svg.setAttribute('viewbox', '0 0 24 24');
16
+ progressCircleElement.appendChild(svg);
17
+ }
18
+ const paths = svg.getElementsByTagName('path');
19
+ if (paths.length !== 2) {
20
+ svg.innerHTML = /* html */ `
21
+ <path d="M12 3.25A8.75 8.75 0 1 1 3.25 12"/>
22
+ <path d="M12 3.25A8.75 8.75 0 1 1 3.25 12 A 8.75 8.75 0 0 1 12 3.25"/>
23
+ `;
24
+ }
25
+ }
26
+
27
+ /**
28
+ * @param {Element} progressCircleElement
29
+ * @param {number} value Percentage value (0-100);
30
+ * @return {void}
31
+ */
32
+ export function setValue(progressCircleElement, value) {
33
+ const dashOffset = circumference * (3 - (value / 100));
34
+ const pathElements = progressCircleElement.getElementsByTagName('path');
35
+ pathElements[pathElements.length - 1].style.setProperty('stroke-dashoffset', dashOffset.toString());
36
+ }
@@ -0,0 +1,2 @@
1
+ @forward './_spec.scss';
2
+ @forward './_theme.scss';