@shortfuse/materialdesignweb 0.2.0 → 0.5.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 (416) hide show
  1. package/.browserslistrc +2 -1
  2. package/.eslintrc.json +188 -30
  3. package/.stylelintrc.json +643 -2
  4. package/.vscode/launch.json +20 -5
  5. package/.vscode/settings.json +3 -0
  6. package/CHANGELOG.md +36 -0
  7. package/README.md +82 -2
  8. package/adapters/datatable/column.js +176 -0
  9. package/adapters/datatable/index.js +253 -437
  10. package/adapters/dom/index.js +586 -0
  11. package/adapters/list/index.js +36 -113
  12. package/adapters/search/index.js +153 -180
  13. package/components/appbar/_spec.scss +165 -0
  14. package/components/appbar/_theme.scss +0 -0
  15. package/components/appbar/index.scss +2 -0
  16. package/components/banner/_spec.scss +83 -0
  17. package/components/banner/_theme.scss +0 -0
  18. package/components/banner/index.scss +2 -0
  19. package/components/bottomnav/README.md +4 -4
  20. package/components/bottomnav/_spec.scss +149 -0
  21. package/components/bottomnav/_theme.scss +0 -0
  22. package/components/bottomnav/index.js +100 -120
  23. package/components/bottomnav/index.scss +2 -0
  24. package/components/bottomnav/item.js +88 -0
  25. package/components/button/README.md +16 -22
  26. package/components/button/_spec.scss +162 -0
  27. package/components/button/_theme.scss +42 -0
  28. package/components/button/index.eta +32 -0
  29. package/components/button/index.js +37 -48
  30. package/components/button/index.pug +18 -0
  31. package/components/button/index.scss +2 -0
  32. package/components/card/_spec.scss +241 -0
  33. package/components/card/_theme.scss +0 -0
  34. package/components/card/index.scss +2 -0
  35. package/components/chip/_spec.scss +111 -0
  36. package/components/chip/_theme.scss +105 -0
  37. package/components/chip/index.js +23 -0
  38. package/components/chip/index.scss +2 -0
  39. package/components/chip/item.js +20 -0
  40. package/components/datatable/_spec.scss +225 -0
  41. package/components/datatable/_theme.scss +128 -0
  42. package/components/datatable/cell.js +44 -0
  43. package/components/datatable/columnheader.js +46 -0
  44. package/components/datatable/index.js +339 -443
  45. package/components/datatable/index.scss +2 -0
  46. package/components/datatable/row.js +48 -0
  47. package/components/datatable/rowheader.js +18 -0
  48. package/components/dialog/_spec.scss +203 -0
  49. package/components/dialog/_theme.scss +7 -0
  50. package/components/dialog/index.js +512 -437
  51. package/components/dialog/index.scss +2 -0
  52. package/components/divider/_spec.scss +11 -0
  53. package/components/divider/_theme.scss +0 -0
  54. package/components/divider/index.scss +2 -0
  55. package/components/elevation/_spec.scss +9 -0
  56. package/components/elevation/_theme.scss +0 -0
  57. package/components/elevation/index.scss +2 -0
  58. package/components/fab/{style.scss → _spec.scss} +104 -79
  59. package/components/fab/_theme.scss +0 -0
  60. package/components/fab/index.js +85 -79
  61. package/components/fab/index.scss +2 -0
  62. package/components/grid/_spec.scss +169 -0
  63. package/components/grid/_theme.scss +0 -0
  64. package/components/grid/index.scss +2 -0
  65. package/components/layout/_mixins.scss +11 -0
  66. package/components/layout/_spec.scss +916 -0
  67. package/components/layout/_theme.scss +19 -0
  68. package/components/layout/index.js +454 -0
  69. package/components/layout/index.scss +2 -0
  70. package/components/list/_spec.scss +363 -0
  71. package/components/list/_theme.scss +102 -0
  72. package/components/list/content.js +106 -0
  73. package/components/list/index.js +234 -79
  74. package/components/list/index.scss +2 -0
  75. package/components/list/item.js +167 -0
  76. package/components/list/secondary.js +45 -0
  77. package/components/menu/_spec.scss +329 -0
  78. package/components/menu/_theme.scss +0 -0
  79. package/components/menu/index.js +636 -651
  80. package/components/menu/index.scss +2 -0
  81. package/components/menu/item.js +231 -0
  82. package/components/progress/_spec.scss +156 -0
  83. package/components/progress/_theme.scss +0 -0
  84. package/components/progress/index.js +29 -13
  85. package/components/progress/index.scss +2 -0
  86. package/components/selection/_spec.scss +376 -0
  87. package/components/selection/_theme.scss +134 -0
  88. package/components/selection/index.eta +60 -0
  89. package/components/selection/index.js +70 -0
  90. package/components/selection/index.pug +30 -0
  91. package/components/selection/index.scss +2 -0
  92. package/components/selection/input.js +54 -0
  93. package/components/selection/radiogroup.js +40 -0
  94. package/components/slider/{style.scss → _spec.scss} +31 -34
  95. package/components/slider/_theme.scss +0 -0
  96. package/components/slider/index.scss +2 -0
  97. package/components/snackbar/_spec.scss +150 -0
  98. package/components/snackbar/_theme.scss +0 -0
  99. package/components/snackbar/index.js +293 -206
  100. package/components/snackbar/index.scss +2 -0
  101. package/components/tab/_spec.scss +220 -0
  102. package/components/tab/_theme.scss +0 -0
  103. package/components/tab/content.js +210 -0
  104. package/components/tab/index.js +229 -213
  105. package/components/tab/index.scss +2 -0
  106. package/components/tab/item.js +88 -0
  107. package/components/tab/list.js +196 -0
  108. package/components/tab/panel.js +54 -0
  109. package/components/textfield/README.md +4 -4
  110. package/components/textfield/_spec.scss +763 -0
  111. package/components/textfield/_theme.scss +264 -0
  112. package/components/textfield/index.eta +74 -0
  113. package/components/textfield/index.js +132 -138
  114. package/components/textfield/index.pug +30 -0
  115. package/components/textfield/index.scss +2 -0
  116. package/components/tooltip/_spec.scss +185 -0
  117. package/components/tooltip/_theme.scss +0 -0
  118. package/components/tooltip/index.scss +2 -0
  119. package/components/type/_spec.scss +227 -0
  120. package/components/type/_theme.scss +0 -0
  121. package/components/type/index.scss +2 -0
  122. package/core/_breakpoint.scss +189 -0
  123. package/core/_elevation.scss +78 -0
  124. package/core/_length.scss +8 -0
  125. package/core/_motion.scss +31 -0
  126. package/core/_platform.scss +12 -0
  127. package/core/_type.scss +128 -0
  128. package/core/aria/attributes.js +141 -0
  129. package/core/aria/button.js +49 -0
  130. package/core/aria/keyboard.js +92 -0
  131. package/core/aria/rovingtabindex.js +175 -0
  132. package/core/aria/tab.js +59 -0
  133. package/core/document/index.js +39 -0
  134. package/core/dom.js +180 -0
  135. package/core/overlay/_spec.scss +28 -0
  136. package/core/overlay/_theme.scss +147 -0
  137. package/core/overlay/index.js +95 -0
  138. package/core/overlay/index.scss +2 -0
  139. package/core/ripple/_spec.scss +196 -0
  140. package/core/ripple/_theme.scss +20 -0
  141. package/core/ripple/index.js +286 -0
  142. package/core/ripple/index.scss +2 -0
  143. package/core/theme/_aliases.scss +15 -0
  144. package/core/theme/_config.scss +8 -0
  145. package/core/theme/_functions.scss +22 -0
  146. package/{components/theming/palettes.scss → core/theme/_palettes.scss} +173 -151
  147. package/core/theme/_spec.scss +0 -0
  148. package/core/theme/_theme.scss +268 -0
  149. package/core/theme/index.js +50 -0
  150. package/core/theme/index.scss +4 -0
  151. package/core/throttler.js +42 -0
  152. package/core/transition/index.js +465 -0
  153. package/docs/_flex.scss +28 -0
  154. package/docs/_menuoptions.js +183 -0
  155. package/docs/_partials/_androidnavbar.eta +5 -0
  156. package/docs/_partials/_androidstatusbar.eta +13 -0
  157. package/docs/_partials/_appbar.eta +27 -0
  158. package/docs/_partials/_buttontest.eta +31 -0
  159. package/docs/_partials/_header.eta +146 -0
  160. package/docs/_partials/_navlistitem.eta +16 -0
  161. package/docs/_partials/_target.eta +1 -0
  162. package/docs/_sample-utils.js +88 -0
  163. package/docs/{src/storage.js → _storage.js} +0 -0
  164. package/docs/docs.scss +331 -0
  165. package/docs/framework.scss +26 -0
  166. package/docs/index.eta +12 -0
  167. package/docs/index.js +7 -0
  168. package/docs/pages/appbar.eta +108 -0
  169. package/docs/pages/appbar.js +0 -0
  170. package/docs/pages/bottomnav.eta +188 -0
  171. package/docs/pages/bottomnav.js +118 -0
  172. package/docs/pages/button.eta +124 -0
  173. package/docs/pages/button.js +224 -0
  174. package/docs/pages/card.eta +90 -0
  175. package/docs/pages/card.js +175 -0
  176. package/docs/pages/chip.eta +122 -0
  177. package/docs/pages/chip.js +80 -0
  178. package/docs/pages/color.eta +143 -0
  179. package/docs/pages/color.js +261 -0
  180. package/docs/pages/datatable.eta +323 -0
  181. package/docs/pages/datatable.js +160 -0
  182. package/docs/pages/dialog.eta +184 -0
  183. package/docs/{src/components → pages}/dialog.js +35 -48
  184. package/docs/pages/dom.eta +26 -0
  185. package/docs/pages/dom.js +140 -0
  186. package/docs/pages/elevation.eta +35 -0
  187. package/docs/pages/elevation.js +0 -0
  188. package/docs/pages/fab.eta +99 -0
  189. package/docs/{src/components → pages}/fab.js +6 -13
  190. package/docs/pages/grid.eta +135 -0
  191. package/docs/pages/grid.js +128 -0
  192. package/docs/pages/layout.eta +8 -0
  193. package/docs/pages/layout.js +0 -0
  194. package/docs/pages/list.eta +465 -0
  195. package/docs/pages/list.js +8 -0
  196. package/docs/pages/menu.eta +274 -0
  197. package/docs/{src/components → pages}/menu.js +26 -42
  198. package/docs/pages/overlay.eta +69 -0
  199. package/docs/pages/overlay.js +3 -0
  200. package/docs/pages/progress.eta +23 -0
  201. package/docs/{src/components → pages}/progress.js +2 -4
  202. package/docs/pages/ripple.eta +27 -0
  203. package/docs/pages/ripple.js +3 -0
  204. package/docs/pages/search.eta +242 -0
  205. package/docs/pages/search.js +226 -0
  206. package/docs/pages/selection.eta +107 -0
  207. package/docs/pages/selection.js +12 -0
  208. package/docs/pages/slider.eta +23 -0
  209. package/docs/pages/slider.js +0 -0
  210. package/docs/pages/snackbar.eta +83 -0
  211. package/docs/{src/components → pages}/snackbar.js +31 -36
  212. package/docs/pages/tab.eta +407 -0
  213. package/docs/pages/tab.js +152 -0
  214. package/docs/pages/textfield.eta +487 -0
  215. package/docs/{src/components → pages}/textfield.js +41 -45
  216. package/docs/pages/tooltip.eta +92 -0
  217. package/docs/pages/tooltip.js +0 -0
  218. package/docs/pages/transition.eta +117 -0
  219. package/docs/pages/transition.js +52 -0
  220. package/docs/pages/type.eta +31 -0
  221. package/docs/pages/type.js +0 -0
  222. package/docs/postrender.js +41 -0
  223. package/docs/prerender.js +16 -0
  224. package/docs/pwa/_dialogs.eta +143 -0
  225. package/docs/pwa/_menus.eta +16 -0
  226. package/docs/pwa/pwa-prerender.js +3 -0
  227. package/docs/pwa/pwa.eta +478 -0
  228. package/docs/pwa/pwa.js +298 -0
  229. package/docs/pwa/pwa.scss +31 -0
  230. package/docs/themes/theme-colored.scss +15 -0
  231. package/docs/themes/theme-default.scss +3 -0
  232. package/index.scss +27 -0
  233. package/jsconfig.json +8 -2
  234. package/package.json +54 -27
  235. package/scripts/deploy-docs.sh +9 -0
  236. package/templates/index.eta +2 -0
  237. package/templates/index.pug +3 -0
  238. package/tsconfig.json +16 -0
  239. package/utils/function.js +3 -0
  240. package/webpack.config.js +224 -68
  241. package/_index.scss +0 -4
  242. package/components/all-components.scss +0 -21
  243. package/components/bottomnav/style.scss +0 -190
  244. package/components/bottomnav/theming.scss +0 -76
  245. package/components/button/style.scss +0 -315
  246. package/components/button/theming.scss +0 -134
  247. package/components/card/style.scss +0 -175
  248. package/components/card/theming.scss +0 -43
  249. package/components/common/dom.js +0 -51
  250. package/components/common/functions.scss +0 -174
  251. package/components/common/mixins.scss +0 -122
  252. package/components/common/motion.scss +0 -36
  253. package/components/common/type.scss +0 -104
  254. package/components/common/variables.scss +0 -46
  255. package/components/datatable/style.scss +0 -257
  256. package/components/datatable/theming.scss +0 -119
  257. package/components/dialog/style.scss +0 -159
  258. package/components/dialog/theming.scss +0 -29
  259. package/components/divider/style.scss +0 -7
  260. package/components/divider/theming.scss +0 -20
  261. package/components/elevation/style.scss +0 -32
  262. package/components/layout/style.scss +0 -223
  263. package/components/list/style.scss +0 -358
  264. package/components/list/theming.scss +0 -83
  265. package/components/menu/style.scss +0 -280
  266. package/components/menu/theming.scss +0 -80
  267. package/components/navdrawer/index.js +0 -200
  268. package/components/navdrawer/style.scss +0 -595
  269. package/components/navdrawer/theming.scss +0 -62
  270. package/components/progress/style.scss +0 -136
  271. package/components/ripple/index.js +0 -63
  272. package/components/ripple/ripple.scss +0 -122
  273. package/components/selection/style.scss +0 -320
  274. package/components/selection/theming.scss +0 -98
  275. package/components/snackbar/style.scss +0 -212
  276. package/components/switch/style.scss +0 -3
  277. package/components/tab/style.scss +0 -275
  278. package/components/tab/theming.scss +0 -34
  279. package/components/template/theming.scss +0 -31
  280. package/components/textfield/style.scss +0 -795
  281. package/components/textfield/theming.scss +0 -256
  282. package/components/theming/globals.scss +0 -25
  283. package/components/theming/theming.scss +0 -559
  284. package/components/toolbar/style.scss +0 -190
  285. package/components/toolbar/theming.scss +0 -32
  286. package/components/tooltip/style.scss +0 -135
  287. package/components/type/style.scss +0 -167
  288. package/components/type/theming.scss +0 -25
  289. package/docs/bottomnav.html +0 -1
  290. package/docs/bottomnav.min.js +0 -2
  291. package/docs/bottomnav.min.js.map +0 -1
  292. package/docs/button.html +0 -1
  293. package/docs/button.min.js +0 -2
  294. package/docs/button.min.js.map +0 -1
  295. package/docs/card.html +0 -1
  296. package/docs/card.min.js +0 -2
  297. package/docs/card.min.js.map +0 -1
  298. package/docs/components.min.css +0 -1
  299. package/docs/components.min.js +0 -2
  300. package/docs/components.min.js.map +0 -1
  301. package/docs/datatable.html +0 -1
  302. package/docs/datatable.min.js +0 -2
  303. package/docs/datatable.min.js.map +0 -1
  304. package/docs/dialog.html +0 -1
  305. package/docs/dialog.min.js +0 -2
  306. package/docs/dialog.min.js.map +0 -1
  307. package/docs/docs.min.css +0 -1
  308. package/docs/docs.min.js +0 -2
  309. package/docs/docs.min.js.map +0 -1
  310. package/docs/elevation.html +0 -1
  311. package/docs/elevation.min.js +0 -2
  312. package/docs/elevation.min.js.map +0 -1
  313. package/docs/fab.html +0 -1
  314. package/docs/fab.min.js +0 -2
  315. package/docs/fab.min.js.map +0 -1
  316. package/docs/index.html +0 -1
  317. package/docs/index.min.js +0 -2
  318. package/docs/index.min.js.map +0 -1
  319. package/docs/layout.html +0 -1
  320. package/docs/layout.min.js +0 -2
  321. package/docs/layout.min.js.map +0 -1
  322. package/docs/list.html +0 -1
  323. package/docs/list.min.js +0 -2
  324. package/docs/list.min.js.map +0 -1
  325. package/docs/menu.html +0 -1
  326. package/docs/menu.min.js +0 -2
  327. package/docs/menu.min.js.map +0 -1
  328. package/docs/navdrawer.html +0 -1
  329. package/docs/navdrawer.min.js +0 -2
  330. package/docs/navdrawer.min.js.map +0 -1
  331. package/docs/prerender.min.js +0 -2
  332. package/docs/prerender.min.js.map +0 -1
  333. package/docs/progress.html +0 -1
  334. package/docs/progress.min.js +0 -2
  335. package/docs/progress.min.js.map +0 -1
  336. package/docs/search.html +0 -1
  337. package/docs/search.min.js +0 -2
  338. package/docs/search.min.js.map +0 -1
  339. package/docs/selection.html +0 -1
  340. package/docs/selection.min.js +0 -2
  341. package/docs/selection.min.js.map +0 -1
  342. package/docs/slider.html +0 -1
  343. package/docs/slider.min.js +0 -2
  344. package/docs/slider.min.js.map +0 -1
  345. package/docs/snackbar.html +0 -1
  346. package/docs/snackbar.min.js +0 -2
  347. package/docs/snackbar.min.js.map +0 -1
  348. package/docs/src/components/bottomnav.js +0 -16
  349. package/docs/src/components/bottomnav.pug +0 -112
  350. package/docs/src/components/button.js +0 -156
  351. package/docs/src/components/button.pug +0 -194
  352. package/docs/src/components/card.js +0 -136
  353. package/docs/src/components/card.pug +0 -133
  354. package/docs/src/components/datatable.js +0 -183
  355. package/docs/src/components/datatable.pug +0 -324
  356. package/docs/src/components/dialog.pug +0 -138
  357. package/docs/src/components/elevation.js +0 -3
  358. package/docs/src/components/elevation.pug +0 -17
  359. package/docs/src/components/fab.pug +0 -84
  360. package/docs/src/components/layout.js +0 -116
  361. package/docs/src/components/layout.pug +0 -104
  362. package/docs/src/components/list.js +0 -15
  363. package/docs/src/components/list.pug +0 -293
  364. package/docs/src/components/menu.pug +0 -292
  365. package/docs/src/components/navdrawer.js +0 -112
  366. package/docs/src/components/navdrawer.pug +0 -113
  367. package/docs/src/components/progress.pug +0 -17
  368. package/docs/src/components/search.js +0 -206
  369. package/docs/src/components/search.pug +0 -149
  370. package/docs/src/components/selection.js +0 -6
  371. package/docs/src/components/selection.pug +0 -116
  372. package/docs/src/components/slider.js +0 -3
  373. package/docs/src/components/slider.pug +0 -19
  374. package/docs/src/components/snackbar.pug +0 -145
  375. package/docs/src/components/tab.js +0 -137
  376. package/docs/src/components/tab.pug +0 -329
  377. package/docs/src/components/textfield.pug +0 -416
  378. package/docs/src/components/toolbar.js +0 -6
  379. package/docs/src/components/toolbar.pug +0 -86
  380. package/docs/src/components/tooltip.js +0 -6
  381. package/docs/src/components/tooltip.pug +0 -76
  382. package/docs/src/components/type.js +0 -6
  383. package/docs/src/components/type.pug +0 -34
  384. package/docs/src/components.scss +0 -1
  385. package/docs/src/docs.scss +0 -284
  386. package/docs/src/index.js +0 -3
  387. package/docs/src/index.pug +0 -6
  388. package/docs/src/menuoptions.js +0 -136
  389. package/docs/src/mixins.pug +0 -139
  390. package/docs/src/prerender.js +0 -26
  391. package/docs/src/sample-utils.js +0 -108
  392. package/docs/src/targetHandler.js +0 -50
  393. package/docs/src/theming.ie11.scss +0 -18
  394. package/docs/src/theming.scss +0 -18
  395. package/docs/tab.html +0 -1
  396. package/docs/tab.min.js +0 -2
  397. package/docs/tab.min.js.map +0 -1
  398. package/docs/textfield.html +0 -2
  399. package/docs/textfield.min.js +0 -2
  400. package/docs/textfield.min.js.map +0 -1
  401. package/docs/theming.ie11.min.css +0 -1
  402. package/docs/theming.ie11.min.js +0 -2
  403. package/docs/theming.ie11.min.js.map +0 -1
  404. package/docs/theming.min.css +0 -1
  405. package/docs/theming.min.js +0 -2
  406. package/docs/theming.min.js.map +0 -1
  407. package/docs/toolbar.html +0 -1
  408. package/docs/toolbar.min.js +0 -2
  409. package/docs/toolbar.min.js.map +0 -1
  410. package/docs/tooltip.html +0 -1
  411. package/docs/tooltip.min.js +0 -2
  412. package/docs/tooltip.min.js.map +0 -1
  413. package/docs/type.html +0 -1
  414. package/docs/type.min.js +0 -2
  415. package/docs/type.min.js.map +0 -1
  416. package/index.js +0 -16
@@ -1,17 +1,33 @@
1
+ // https://www.w3.org/TR/wai-aria-1.1/#alert
1
2
  // https://www.w3.org/TR/wai-aria-practices/#alert
2
3
 
3
- import { Button } from '../button/index';
4
- import { findElementParentByClassName, dispatchDomEvent } from '../common/dom';
4
+ import {
5
+ dispatchDomEvent,
6
+ setTextNode,
7
+ } from '../../core/dom.js';
8
+ import * as Button from '../button/index.js';
5
9
 
6
- // Time to wait until hide animation finishes before destroying element
7
- const SNACKBAR_DESTROY_TIMEOUT_MS = 1000;
10
+ /**
11
+ * @typedef SnackbarCreateOptions
12
+ * @prop {!string} text
13
+ * @prop {!string} [buttonText]
14
+ * @prop {string} [buttonInk='primary']
15
+ * @prop {boolean} [stacked=false]
16
+ * @prop {number|boolean} [autoHide=4] Auto hide time in seconds
17
+ * @prop {boolean} [autoDestroy=true] Destroy element after hide
18
+ * @prop {Element} [parent] Parent element to which to append
19
+ * @prop {boolean} [show=true] Show element after creation
20
+ * @prop {boolean} [skipQueue=false] Skip queue
21
+ */
8
22
 
9
- class SnackbarStack {
23
+ class SnackbarQueueItem {
10
24
  /**
11
25
  * @param {Element} element
26
+ * @param {SnackbarCreateOptions} [options]
12
27
  */
13
- constructor(element) {
28
+ constructor(element, options) {
14
29
  this.element = element;
30
+ this.options = options;
15
31
  this.hideTimeout = null;
16
32
  }
17
33
 
@@ -24,228 +40,299 @@ class SnackbarStack {
24
40
  }
25
41
  }
26
42
 
27
- /** @type {SnackbarStack[]} */
28
- const OPEN_SNACKBARS = [];
29
- class Snackbar {
30
- /**
31
- * @param {Element} snackbarElement
32
- * @return {void}
33
- */
34
- static attach(snackbarElement) {
35
- const button = snackbarElement.getElementsByClassName('mdw-button')[0];
36
- if (button) {
37
- Button.attach(button);
38
- button.addEventListener('click', Snackbar.onButtonClick);
39
- }
40
- snackbarElement.setAttribute('mdw-js', '');
41
- }
43
+ /** @type {SnackbarQueueItem[]} */
44
+ const SNACKBAR_QUEUE = [];
42
45
 
43
- static detach(snackbarElement) {
44
- const button = snackbarElement.getElementsByClassName('mdw-button')[0];
45
- if (button) {
46
- Button.detach(button);
47
- button.removeEventListener('click', Snackbar.onButtonClick);
48
- }
49
- // Remove timeouts and stacks
50
- OPEN_SNACKBARS.slice().reverse().forEach((stack, reverseIndex, array) => {
51
- if (stack.element === snackbarElement) {
52
- stack.clearHideTimeout();
53
- const index = array.length - reverseIndex - 1;
54
- OPEN_SNACKBARS.splice(index, 1);
55
- }
56
- });
57
- snackbarElement.removeAttribute('mdw-js');
58
- }
59
-
60
- static onButtonClick(event) {
61
- if (event && event.currentTarget instanceof HTMLAnchorElement) {
62
- event.preventDefault();
63
- }
64
- const snackbarElement = findElementParentByClassName(event.currentTarget, 'mdw-snackbar');
65
- Snackbar.hide(snackbarElement);
66
- }
46
+ export const HIDE_EVENT = 'mdw:snackbar-hide';
47
+ export const SHOW_EVENT = 'mdw:snackbar-show';
67
48
 
68
- /** @return {SnackbarStack} */
69
- static getNextSnackbarStack() {
70
- const nextSnackbar = OPEN_SNACKBARS[0];
71
- if (nextSnackbar && (!nextSnackbar.element || !nextSnackbar.element.parentElement)) {
72
- // Item was removed from DOM externally
73
- OPEN_SNACKBARS.splice(0, 1);
74
- return this.getNextSnackbarStack();
75
- }
76
- return nextSnackbar;
49
+ /**
50
+ * @param {Element} snackbarElement
51
+ * @return {void}
52
+ */
53
+ export function setupARIA(snackbarElement) {
54
+ if (snackbarElement.hasAttribute('mdw-no-aria')) {
55
+ return;
77
56
  }
57
+ snackbarElement.setAttribute('role', 'alert');
58
+ snackbarElement.setAttribute('tabindex', '-1');
59
+ }
78
60
 
79
- /**
80
- * @param {Element} snackbarElement
81
- * @return {boolean} handled
82
- */
83
- static hide(snackbarElement) {
84
- if (snackbarElement.hasAttribute('mdw-hide')) {
85
- return false;
61
+ /**
62
+ * @param {Element} element
63
+ * @return {SnackbarQueueItem}
64
+ */
65
+ export function findNextQueueItem(element) {
66
+ let queue = null;
67
+ SNACKBAR_QUEUE.some((q) => {
68
+ if (q.element === element) {
69
+ queue = q;
70
+ return true;
86
71
  }
87
- if (!dispatchDomEvent(snackbarElement, 'mdw:hide')) {
88
- return false;
72
+ return false;
73
+ });
74
+ return queue;
75
+ }
76
+
77
+ /**
78
+ * @param {Element} snackbarElement
79
+ * @return {void}
80
+ */
81
+ export function handleAnimationChange(snackbarElement) {
82
+ const showing = snackbarElement.getAttribute('aria-hidden') === 'false';
83
+ if (showing) {
84
+ const currentQueueItem = findNextQueueItem(snackbarElement);
85
+ if (currentQueueItem && currentQueueItem.hideTimeout) {
86
+ return;
89
87
  }
90
- snackbarElement.setAttribute('mdw-hide', '');
91
- let stackIndex = -1;
92
- OPEN_SNACKBARS.some((stack, index) => {
93
- if (stack.element === snackbarElement) {
94
- stackIndex = index;
95
- stack.clearHideTimeout();
96
- return true;
97
- }
98
- return false;
99
- });
100
- if (stackIndex !== -1) {
101
- OPEN_SNACKBARS.splice(stackIndex, 1);
88
+ const autoHideString = snackbarElement.getAttribute('mdw-autohide');
89
+ if (autoHideString == null) {
90
+ return;
102
91
  }
103
- if (snackbarElement.hasAttribute('mdw-autodestroy')) {
104
- setTimeout(() => {
105
- if (!snackbarElement.parentElement) {
106
- return;
107
- }
108
- if (!dispatchDomEvent(snackbarElement, 'mdw:destroy')) {
109
- return;
110
- }
111
- snackbarElement.parentElement.removeChild(snackbarElement);
112
- }, SNACKBAR_DESTROY_TIMEOUT_MS);
92
+ const timeInSeconds = Number.parseFloat(autoHideString) || 4;
93
+ if (timeInSeconds < 0) {
94
+ return;
113
95
  }
114
- const nextSnackbar = Snackbar.getNextSnackbarStack();
115
- if (nextSnackbar) {
116
- nextSnackbar.element.setAttribute('mdw-consecutive', '');
117
- Snackbar.show(nextSnackbar.element);
96
+ const timeout = setTimeout(() => {
97
+ // eslint-disable-next-line no-use-before-define
98
+ hide(snackbarElement);
99
+ }, timeInSeconds * 1000);
100
+ if (currentQueueItem) {
101
+ currentQueueItem.hideTimeout = timeout;
118
102
  }
119
- return true;
103
+ return;
120
104
  }
121
105
 
122
- /**
123
- * @param {Element} snackbarElement
124
- * @return {boolean} handled
125
- */
126
- static show(snackbarElement) {
127
- if (!snackbarElement.hasAttribute('mdw-hide') && snackbarElement.hasAttribute('mdw-show')) {
128
- // Already shown
129
- return false;
130
- }
131
- if (!dispatchDomEvent(snackbarElement, 'mdw:show')) {
132
- // Event was canceled
133
- return false;
134
- }
135
- let snackbarStackIndex = -1;
136
- let snackbarStack;
137
- OPEN_SNACKBARS.some((stack, index) => {
138
- if (stack.element === snackbarElement) {
139
- snackbarStack = stack;
140
- snackbarStackIndex = index;
141
- return true;
142
- }
143
- return false;
144
- });
145
- if (snackbarStackIndex > 0) {
146
- // Stacked for later
147
- return true;
148
- }
149
- if (!snackbarStack) {
150
- snackbarStack = new SnackbarStack(snackbarElement);
151
- OPEN_SNACKBARS.push(snackbarStack);
152
- if (OPEN_SNACKBARS.length !== 1) {
153
- // Not first, show later
154
- return true;
155
- }
156
- }
157
- snackbarElement.removeAttribute('mdw-hide');
158
- snackbarElement.setAttribute('mdw-show', '');
159
- Snackbar.attach(snackbarElement);
160
- snackbarStack.clearHideTimeout();
161
- if (snackbarElement.hasAttribute('mdw-autohide')) {
162
- const timeInSeconds = parseInt(snackbarElement.getAttribute('mdw-autohide'), 10) || 4;
163
- if (timeInSeconds > 0) {
164
- snackbarStack.hideTimeout = setTimeout(() => {
165
- Snackbar.hide(snackbarElement);
166
- }, timeInSeconds * 1000);
167
- }
168
- }
169
- return true;
106
+ const nextQueueItem = findNextQueueItem(snackbarElement);
107
+ if (nextQueueItem) {
108
+ // eslint-disable-next-line no-use-before-define
109
+ update(snackbarElement, nextQueueItem.options);
110
+ // eslint-disable-next-line no-use-before-define
111
+ show(snackbarElement);
112
+ return;
113
+ }
114
+ if (snackbarElement.hasAttribute('mdw-autodestroy') && snackbarElement.parentElement) {
115
+ snackbarElement.remove();
170
116
  }
117
+ }
171
118
 
172
- /**
173
- * @typedef SnackbarCreateOptions
174
- * @property {!string} text
175
- * @property {!string=} buttonText
176
- * @property {string=} [buttonThemeColor='primary']
177
- * @property {boolean} [stacked=false]
178
- * @property {number|boolean} [autoHide=4] Auto hide time in seconds
179
- * @property {boolean} [autoDestroy=true] Destroy element after hide
180
- * @property {HTMLElement=} parent Parent element to which to append
181
- * @property {boolean=} show Show element after creation
182
- */
119
+ /**
120
+ * @param {AnimationEvent} event
121
+ * @return {void}
122
+ */
123
+ export function onAnimationEnd(event) {
124
+ handleAnimationChange(/** @type {Element} */ (event.currentTarget));
125
+ }
183
126
 
184
- /**
185
- * @param {SnackbarCreateOptions} options
186
- * @return {HTMLElement}
187
- */
188
- static create(options) {
189
- const element = document.createElement('div');
190
- element.classList.add('mdw-snackbar');
191
- element.setAttribute('role', 'alert');
192
- element.setAttribute('mdw-hide', '');
193
-
194
- const span = document.createElement('span');
195
- span.textContent = options.text;
196
- element.appendChild(span);
127
+ /**
128
+ * @param {Element} snackbarElement
129
+ * @return {boolean} changed
130
+ */
131
+ export function hide(snackbarElement) {
132
+ if (snackbarElement.getAttribute('aria-hidden') === 'true') {
133
+ return false;
134
+ }
135
+ if (!dispatchDomEvent(snackbarElement, HIDE_EVENT)) {
136
+ return false;
137
+ }
138
+ snackbarElement.setAttribute('aria-hidden', 'true');
139
+ const currentQueueItem = findNextQueueItem(snackbarElement);
140
+ if (currentQueueItem) {
141
+ SNACKBAR_QUEUE.splice(SNACKBAR_QUEUE.indexOf(currentQueueItem), 1);
142
+ }
143
+ if (window.getComputedStyle(snackbarElement).animationName === 'none') {
144
+ requestAnimationFrame(() => handleAnimationChange(snackbarElement));
145
+ }
146
+ return true;
147
+ }
197
148
 
198
- if (options.buttonText) {
199
- const button = document.createElement('button');
200
- button.classList.add('mdw-button');
201
- if (typeof options.buttonThemeColor === 'undefined') {
202
- button.setAttribute('mdw-theme-color', 'primary');
203
- } else if (typeof options.buttonThemeColor === 'string') {
204
- button.setAttribute('mdw-theme-color', options.buttonThemeColor);
205
- } else {
206
- // Don't set attribute if null is passed
207
- }
149
+ /**
150
+ * @param {KeyboardEvent} event
151
+ * @return {void}
152
+ */
153
+ export function onKeyDown(event) {
154
+ if (event.key === 'Escape' || event.key === 'Esc') {
155
+ // Allow users to close snackbar with escape, for accessibilty reasons
156
+ event.stopPropagation();
157
+ event.preventDefault();
158
+ const snackbarElement = /** @type {Element} */ (event.currentTarget);
159
+ hide(snackbarElement);
160
+ }
161
+ }
162
+
163
+ /**
164
+ * @param {MouseEvent} event
165
+ * @return {void}
166
+ */
167
+ export function onButtonClick(event) {
168
+ const buttonElement = /** @type {HTMLElement} */ (event.currentTarget);
169
+ if (buttonElement instanceof HTMLAnchorElement) {
170
+ event.preventDefault();
171
+ }
172
+ const snackbarElement = buttonElement.closest('.mdw-snackbar');
173
+ hide(snackbarElement);
174
+ }
175
+
176
+ /**
177
+ * @param {Element} element
178
+ * @param {SnackbarCreateOptions} options
179
+ * @return {void}
180
+ */
181
+ export function update(element, options) {
182
+ element.classList.add('mdw-snackbar');
183
+ if (!element.classList.contains('mdw-theme')) {
184
+ // Guidelines conflict stating a background should be fully opaque
185
+ // But says spec says to use #000000 with 87% opacity
186
+ // Calculated against white, opaque value is #212121 (Gray-900)
187
+ element.classList.add('mdw-theme');
188
+ element.setAttribute('mdw-surface', 'background 900');
189
+ element.setAttribute('mdw-dark', '');
190
+ }
191
+ let span = element.getElementsByTagName('span')[0];
192
+ if (span) {
193
+ // To trigger screen readers, we destroy and create a new span and textnode
194
+ span.remove();
195
+ }
196
+ span = document.createElement('span');
197
+ if (element.firstChild) {
198
+ element.prepend(span);
199
+ } else {
200
+ element.appendChild(span);
201
+ }
202
+ const textNode = document.createTextNode(options.text);
203
+ span.appendChild(textNode);
204
+ let button = element.getElementsByClassName('mdw-button')[0];
205
+ if (options.buttonText) {
206
+ if (!button) {
207
+ button = document.createElement('a');
208
208
  element.appendChild(button);
209
209
  }
210
- if (options.stacked) {
211
- element.setAttribute('mdw-stacked', '');
210
+ setTextNode(button, options.buttonText);
211
+ button.classList.add('mdw-button');
212
+ if (typeof options.buttonInk === 'undefined') {
213
+ button.classList.add('mdw-theme');
214
+ button.setAttribute('mdw-ink', 'secondary');
215
+ } else if (typeof options.buttonInk === 'string') {
216
+ button.classList.add('mdw-theme');
217
+ button.setAttribute('mdw-ink', options.buttonInk);
218
+ } else {
219
+ // Don't set attribute if null is passed
212
220
  }
213
- if (options.autoHide !== false) {
214
- let timeInSeconds;
215
- if (options.autoHide === true) {
216
- timeInSeconds = 4;
217
- } else if (options.autoHide == null) {
218
- timeInSeconds = 4;
219
- } else {
220
- timeInSeconds = options.autoHide;
221
- }
222
- if (timeInSeconds > 0) {
223
- element.setAttribute('mdw-autohide', timeInSeconds.toString());
224
- }
221
+ } else if (button && button.parentElement) {
222
+ button.remove();
223
+ }
224
+ if (options.stacked) {
225
+ element.setAttribute('mdw-stacked', '');
226
+ }
227
+ if (options.autoHide !== false) {
228
+ let timeInSeconds;
229
+ if (options.autoHide === true) {
230
+ timeInSeconds = 4;
231
+ } else if (options.autoHide == null) {
232
+ timeInSeconds = 4;
233
+ } else {
234
+ timeInSeconds = options.autoHide;
225
235
  }
226
- if (options.autoDestroy !== false) {
227
- element.setAttribute('mdw-autodestroy', '');
236
+ if (timeInSeconds > 0) {
237
+ element.setAttribute('mdw-autohide', timeInSeconds.toString());
228
238
  }
239
+ }
240
+ if (options.autoDestroy !== false) {
241
+ element.setAttribute('mdw-autodestroy', '');
242
+ }
243
+ }
244
+
245
+ /**
246
+ * @param {Element} snackbarElement
247
+ * @return {void}
248
+ */
249
+ export function attach(snackbarElement) {
250
+ const button = snackbarElement.getElementsByClassName('mdw-button')[0];
251
+ if (button) {
252
+ Button.attach(button);
253
+ button.addEventListener('click', onButtonClick);
254
+ }
255
+ snackbarElement.setAttribute('mdw-js', '');
256
+ snackbarElement.addEventListener('animationend', onAnimationEnd);
257
+ snackbarElement.addEventListener('keydown', onKeyDown);
258
+ setupARIA(snackbarElement);
259
+ }
260
+
261
+ /**
262
+ * @param {Element} snackbarElement
263
+ * @return {void}
264
+ */
265
+ export function detach(snackbarElement) {
266
+ const button = snackbarElement.getElementsByClassName('mdw-button')[0];
267
+ if (button) {
268
+ Button.detach(button);
269
+ button.removeEventListener('click', onButtonClick);
270
+ }
271
+ // Remove timeouts and stacks
272
+ for (let i = SNACKBAR_QUEUE.length - 1; i >= 0; i--) {
273
+ const queue = SNACKBAR_QUEUE[i];
274
+ if (queue.element === snackbarElement) {
275
+ queue.clearHideTimeout();
276
+ SNACKBAR_QUEUE.splice(i, 1);
277
+ }
278
+ }
279
+ snackbarElement.removeAttribute('mdw-js');
280
+ }
281
+
282
+ /**
283
+ * @param {?Element} snackbarElement
284
+ * @return {boolean} changed
285
+ */
286
+ export function show(snackbarElement) {
287
+ if (snackbarElement.getAttribute('aria-hidden') === 'false') {
288
+ return false;
289
+ }
290
+ if (!dispatchDomEvent(snackbarElement, SHOW_EVENT)) {
291
+ return false;
292
+ }
293
+ snackbarElement.setAttribute('aria-hidden', 'false');
294
+ attach(snackbarElement);
295
+ if (window.getComputedStyle(snackbarElement).animationName === 'none') {
296
+ requestAnimationFrame(() => handleAnimationChange(snackbarElement));
297
+ }
298
+ return true;
299
+ }
300
+
301
+ /**
302
+ * Creates a Snackbar element if required and adds to show queue
303
+ * @param {SnackbarCreateOptions} options
304
+ * @return {HTMLElement}
305
+ */
306
+ export function create(options) {
307
+ let element;
308
+ let newlyCreated = false;
309
+ if (options.parent) {
310
+ /** @type {HTMLElement} */
311
+ element = (options.parent.getElementsByClassName('mdw-snackbar')[0]);
312
+ }
313
+ if (!element) {
314
+ element = document.createElement('div');
229
315
  if (options.parent) {
230
316
  options.parent.appendChild(element);
231
- if (options.show) {
232
- // Wait two frames before calling for, allowing animation to occur
233
- const onDrawCallback = () => {
234
- Snackbar.show(element);
235
- };
236
- if (window.requestAnimationFrame) {
237
- window.requestAnimationFrame(() => {
238
- window.requestAnimationFrame(onDrawCallback);
239
- });
240
- } else {
241
- setTimeout(onDrawCallback, 2 / 60);
242
- }
243
- }
244
317
  }
245
- return element;
318
+ newlyCreated = true;
319
+ }
320
+ const queue = new SnackbarQueueItem(element, options);
321
+ if (options.skipQueue) {
322
+ SNACKBAR_QUEUE.splice(0, 0, queue);
323
+ } else {
324
+ SNACKBAR_QUEUE.push(queue);
246
325
  }
247
- }
248
326
 
249
- export {
250
- Snackbar,
251
- };
327
+ if (options.show !== false) {
328
+ if (newlyCreated) {
329
+ // Update after show to trigger a text change
330
+ update(element, options);
331
+ show(element);
332
+ update(element, options);
333
+ } else {
334
+ show(element);
335
+ }
336
+ }
337
+ return element;
338
+ }
@@ -0,0 +1,2 @@
1
+ @forward './_spec.scss';
2
+ @forward './_theme.scss';