voom-presenters 0.2.0 → 2.1.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 (447) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/ISSUE_TEMPLATE/questions-support.md +10 -0
  6. data/.github/workflows/semantic-release.yml +42 -0
  7. data/.gitignore +3 -2
  8. data/.releaserc +15 -0
  9. data/.ruby-version +2 -1
  10. data/CHANGELOG.md +71 -108
  11. data/CONTRIBUTING.md +60 -0
  12. data/Gemfile +14 -4
  13. data/Gemfile.lock +93 -46
  14. data/Procfile +1 -0
  15. data/README.md +48 -39
  16. data/app/demo/components/avatars.pom +40 -0
  17. data/app/demo/components/cards.pom +11 -4
  18. data/app/demo/components/chips.pom +61 -54
  19. data/app/demo/components/content.pom +96 -16
  20. data/app/demo/components/dialogs.pom +175 -6
  21. data/app/demo/components/file_inputs.pom +38 -2
  22. data/app/demo/components/google_maps.pom +6 -1
  23. data/app/demo/components/headers.pom +80 -20
  24. data/app/demo/components/icons.pom +86 -55
  25. data/app/demo/components/image_lists.pom +100 -0
  26. data/app/demo/components/images.pom +45 -0
  27. data/app/demo/components/layouts.pom +3 -25
  28. data/app/demo/components/lists.pom +24 -4
  29. data/app/demo/components/menus.pom +14 -4
  30. data/app/demo/components/multi_selects.pom +29 -0
  31. data/app/demo/components/nav/menu.pom +39 -7
  32. data/app/demo/components/nav/pattern_menu.pom +2 -2
  33. data/app/demo/components/number_fields.pom +53 -0
  34. data/app/demo/components/padding.pom +96 -0
  35. data/app/demo/components/progress.pom +71 -0
  36. data/app/demo/components/selects.pom +45 -5
  37. data/app/demo/components/sliders.pom +5 -0
  38. data/app/demo/components/tab_bars.pom +15 -0
  39. data/app/demo/components/tables.pom +51 -40
  40. data/app/demo/components/text_areas.pom +23 -16
  41. data/app/demo/components/text_fields.pom +61 -15
  42. data/app/demo/components/toggles.pom +35 -4
  43. data/app/demo/components/tooltips.pom +8 -4
  44. data/app/demo/components/unordered_list.pom +81 -0
  45. data/app/demo/custom_css.pom +37 -0
  46. data/app/demo/events/actions/autocomplete.pom +32 -0
  47. data/app/demo/events/actions/clear.pom +5 -3
  48. data/app/demo/events/actions/dialogs/discard.pom +9 -0
  49. data/app/demo/events/actions/dialogs/show_dialog.pom +4 -2
  50. data/app/demo/events/actions/last_response.pom +40 -0
  51. data/app/demo/events/actions/prompt_if_dirty.pom +54 -0
  52. data/app/demo/events/content_as_form.pom +313 -0
  53. data/app/demo/events/nav/drawer.pom +7 -3
  54. data/app/demo/events/parallel.pom +44 -0
  55. data/app/demo/index.pom +5 -5
  56. data/app/demo/nav/top_nav.pom +10 -4
  57. data/app/demo/patterns/drag_drop.pom +89 -0
  58. data/app/demo/patterns/floating_card.pom +29 -0
  59. data/app/demo/patterns/search_select.pom +9 -7
  60. data/app/demo/plugins/chart.pom +254 -0
  61. data/app/demo/plugins/image_crop.pom +44 -0
  62. data/app/demo/plugins/index.pom +29 -0
  63. data/app/demo/plugins/nav/drawer.pom +19 -0
  64. data/app/demo/shared/context_list.pom +1 -1
  65. data/app/demo/styles.pom +3 -1
  66. data/bin/console +4 -4
  67. data/component-status.yml +15 -15
  68. data/config.ru +20 -10
  69. data/docs/settings.md +81 -0
  70. data/exe/presenters +3 -0
  71. data/lib/hash_ext/traverse.rb +14 -0
  72. data/lib/voom.rb +25 -0
  73. data/lib/voom/container_methods.rb +2 -2
  74. data/lib/voom/engine.rb +5 -0
  75. data/lib/voom/presenters/api/app.rb +31 -11
  76. data/lib/voom/presenters/api/router.rb +3 -49
  77. data/lib/voom/presenters/app.rb +3 -3
  78. data/lib/voom/presenters/cli.rb +28 -0
  79. data/lib/voom/presenters/demo/dragon_drop.rb +48 -0
  80. data/lib/voom/presenters/demo/echo.rb +2 -0
  81. data/lib/voom/presenters/demo/slow.rb +18 -0
  82. data/lib/voom/presenters/dsl/components/actions/autocomplete.rb +15 -0
  83. data/lib/voom/presenters/dsl/components/actions/base.rb +36 -8
  84. data/lib/voom/presenters/dsl/components/actions/clear.rb +0 -2
  85. data/lib/voom/presenters/dsl/components/actions/close_dialog.rb +17 -0
  86. data/lib/voom/presenters/dsl/components/actions/deletes.rb +0 -2
  87. data/lib/voom/presenters/dsl/components/actions/dialog.rb +0 -2
  88. data/lib/voom/presenters/dsl/components/actions/loads.rb +5 -6
  89. data/lib/voom/presenters/dsl/components/actions/navigates.rb +0 -2
  90. data/lib/voom/presenters/dsl/components/actions/post_message.rb +17 -0
  91. data/lib/voom/presenters/dsl/components/actions/posts.rb +5 -2
  92. data/lib/voom/presenters/dsl/components/actions/prompt_if_dirty.rb +15 -0
  93. data/lib/voom/presenters/dsl/components/actions/remove.rb +0 -2
  94. data/lib/voom/presenters/dsl/components/actions/replaces.rb +4 -4
  95. data/lib/voom/presenters/dsl/components/actions/snackbar.rb +0 -2
  96. data/lib/voom/presenters/dsl/components/actions/stepper.rb +0 -2
  97. data/lib/voom/presenters/dsl/components/actions/toggle_disabled.rb +15 -0
  98. data/lib/voom/presenters/dsl/components/actions/toggle_visibility.rb +0 -2
  99. data/lib/voom/presenters/dsl/components/actions/updates.rb +5 -2
  100. data/lib/voom/presenters/dsl/components/avatar.rb +4 -8
  101. data/lib/voom/presenters/dsl/components/badge.rb +0 -2
  102. data/lib/voom/presenters/dsl/components/base.rb +25 -18
  103. data/lib/voom/presenters/dsl/components/button.rb +15 -11
  104. data/lib/voom/presenters/dsl/components/card.rb +49 -36
  105. data/lib/voom/presenters/dsl/components/checkbox.rb +0 -2
  106. data/lib/voom/presenters/dsl/components/chip.rb +5 -7
  107. data/lib/voom/presenters/dsl/components/chipset.rb +33 -0
  108. data/lib/voom/presenters/dsl/components/content.rb +28 -18
  109. data/lib/voom/presenters/dsl/components/datetime_base.rb +0 -2
  110. data/lib/voom/presenters/dsl/components/datetime_field.rb +0 -2
  111. data/lib/voom/presenters/dsl/components/dialog.rb +36 -12
  112. data/lib/voom/presenters/dsl/components/drawer.rb +9 -6
  113. data/lib/voom/presenters/dsl/components/event.rb +106 -65
  114. data/lib/voom/presenters/dsl/components/event_base.rb +1 -3
  115. data/lib/voom/presenters/dsl/components/expansion_panel.rb +0 -3
  116. data/lib/voom/presenters/dsl/components/file_input.rb +18 -6
  117. data/lib/voom/presenters/dsl/components/footer.rb +2 -2
  118. data/lib/voom/presenters/dsl/components/form.rb +2 -17
  119. data/lib/voom/presenters/dsl/components/grid.rb +52 -50
  120. data/lib/voom/presenters/dsl/components/header.rb +17 -1
  121. data/lib/voom/presenters/dsl/components/hidden_field.rb +0 -2
  122. data/lib/voom/presenters/dsl/components/icon.rb +2 -4
  123. data/lib/voom/presenters/dsl/components/icon_base.rb +5 -7
  124. data/lib/voom/presenters/dsl/components/icon_toggle.rb +2 -4
  125. data/lib/voom/presenters/dsl/components/image.rb +61 -13
  126. data/lib/voom/presenters/dsl/components/image_list.rb +43 -0
  127. data/lib/voom/presenters/dsl/components/input.rb +14 -5
  128. data/lib/voom/presenters/dsl/components/link.rb +33 -0
  129. data/lib/voom/presenters/dsl/components/list.rb +6 -13
  130. data/lib/voom/presenters/dsl/components/lists/action.rb +9 -11
  131. data/lib/voom/presenters/dsl/components/lists/actions.rb +0 -3
  132. data/lib/voom/presenters/dsl/components/lists/line.rb +27 -15
  133. data/lib/voom/presenters/dsl/components/menu.rb +51 -9
  134. data/lib/voom/presenters/dsl/components/mixins/append.rb +2 -2
  135. data/lib/voom/presenters/dsl/components/mixins/attaches.rb +0 -2
  136. data/lib/voom/presenters/dsl/components/mixins/avatar.rb +1 -3
  137. data/lib/voom/presenters/dsl/components/mixins/chips.rb +0 -2
  138. data/lib/voom/presenters/dsl/components/mixins/chipset.rb +19 -0
  139. data/lib/voom/presenters/dsl/components/mixins/common.rb +13 -14
  140. data/lib/voom/presenters/dsl/components/mixins/dialogs.rb +0 -2
  141. data/lib/voom/presenters/dsl/components/mixins/event.rb +0 -2
  142. data/lib/voom/presenters/dsl/components/mixins/image_lists.rb +15 -0
  143. data/lib/voom/presenters/dsl/components/mixins/last_response.rb +48 -0
  144. data/lib/voom/presenters/dsl/components/mixins/padding.rb +42 -0
  145. data/lib/voom/presenters/dsl/components/mixins/progress.rb +16 -0
  146. data/lib/voom/presenters/dsl/components/mixins/selects.rb +6 -0
  147. data/lib/voom/presenters/dsl/components/mixins/tab_bars.rb +2 -0
  148. data/lib/voom/presenters/dsl/components/mixins/tables.rb +15 -0
  149. data/lib/voom/presenters/dsl/components/mixins/text_fields.rb +5 -0
  150. data/lib/voom/presenters/dsl/components/mixins/toggles.rb +0 -2
  151. data/lib/voom/presenters/dsl/components/mixins/typography.rb +55 -8
  152. data/lib/voom/presenters/dsl/components/mixins/yield_to.rb +2 -2
  153. data/lib/voom/presenters/dsl/components/multi_select.rb +56 -0
  154. data/lib/voom/presenters/dsl/components/number_field.rb +20 -0
  155. data/lib/voom/presenters/dsl/components/page_title.rb +31 -0
  156. data/lib/voom/presenters/dsl/components/progress.rb +27 -0
  157. data/lib/voom/presenters/dsl/components/radio_button.rb +0 -1
  158. data/lib/voom/presenters/dsl/components/rich_text_area.rb +5 -11
  159. data/lib/voom/presenters/dsl/components/select.rb +18 -9
  160. data/lib/voom/presenters/dsl/components/separator.rb +21 -0
  161. data/lib/voom/presenters/dsl/components/slider.rb +6 -7
  162. data/lib/voom/presenters/dsl/components/stepper.rb +0 -10
  163. data/lib/voom/presenters/dsl/components/switch.rb +0 -2
  164. data/lib/voom/presenters/dsl/components/tab_bar.rb +0 -3
  165. data/lib/voom/presenters/dsl/components/table.rb +39 -20
  166. data/lib/voom/presenters/dsl/components/text_area.rb +1 -3
  167. data/lib/voom/presenters/dsl/components/text_field.rb +54 -11
  168. data/lib/voom/presenters/dsl/components/time_field.rb +0 -2
  169. data/lib/voom/presenters/dsl/components/toggle_base.rb +8 -6
  170. data/lib/voom/presenters/dsl/components/typography.rb +4 -4
  171. data/lib/voom/presenters/dsl/components/unordered_list.rb +50 -0
  172. data/lib/voom/presenters/dsl/definer.rb +0 -4
  173. data/lib/voom/presenters/dsl/definition.rb +6 -5
  174. data/lib/voom/presenters/dsl/protect_from_forgery.rb +43 -0
  175. data/lib/voom/presenters/dsl/user_interface.rb +37 -22
  176. data/lib/voom/presenters/errors.rb +1 -0
  177. data/lib/voom/presenters/errors/invalid_dsl.rb +8 -0
  178. data/lib/voom/presenters/errors/parameter_validation.rb +1 -3
  179. data/lib/voom/presenters/generators/inflectors.rb +59 -0
  180. data/lib/voom/presenters/generators/plugin.rb +115 -0
  181. data/lib/voom/presenters/generators/templates/plugin/.gitignore +12 -0
  182. data/lib/voom/presenters/generators/templates/plugin/Gemfile +6 -0
  183. data/lib/voom/presenters/generators/templates/plugin/LICENSE.txt.tt +21 -0
  184. data/lib/voom/presenters/generators/templates/plugin/README.md +253 -0
  185. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/action.rb.tt +16 -0
  186. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/dsl.rb.tt +22 -0
  187. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/component.rb.tt +18 -0
  188. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/dsl.rb.tt +19 -0
  189. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/helpers/helper.rb.tt +15 -0
  190. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/plugin.rb.tt +9 -0
  191. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/actions/data.rb.tt +17 -0
  192. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/render.rb.tt +23 -0
  193. data/lib/voom/presenters/generators/templates/plugin/presenter_plugin.gemspec.tt +21 -0
  194. data/lib/voom/presenters/generators/templates/plugin/views/assets/css/components/component.css.tt +21 -0
  195. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/actions/action.js.tt +15 -0
  196. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/component.js.tt +39 -0
  197. data/lib/voom/presenters/generators/templates/plugin/views/components/component.erb.tt +14 -0
  198. data/lib/voom/presenters/generators/templates/plugin/views/components/component_header.erb.tt +20 -0
  199. data/lib/voom/presenters/helpers.rb +2 -8
  200. data/lib/voom/presenters/helpers/inflector.rb +1 -1
  201. data/lib/voom/presenters/helpers/rails.rb +15 -8
  202. data/lib/voom/presenters/helpers/redact.rb +13 -0
  203. data/lib/voom/presenters/helpers/route.rb +12 -5
  204. data/lib/voom/presenters/pluggable.rb +37 -0
  205. data/lib/voom/presenters/plugins.rb +7 -0
  206. data/lib/voom/presenters/plugins/google_maps.rb +24 -0
  207. data/lib/voom/presenters/plugins/google_maps/google_map.erb +10 -0
  208. data/lib/voom/presenters/{dsl/components → plugins/google_maps}/google_map.rb +4 -3
  209. data/lib/voom/presenters/{dsl.rb → registry.rb} +13 -15
  210. data/lib/voom/presenters/router.rb +59 -0
  211. data/lib/voom/presenters/settings.rb +18 -8
  212. data/lib/voom/presenters/version.rb +3 -1
  213. data/lib/voom/presenters/web_client/app.rb +86 -29
  214. data/lib/voom/presenters/web_client/component_decorator_factory.rb +27 -0
  215. data/lib/voom/presenters/web_client/component_html_decorator.rb +50 -0
  216. data/lib/voom/presenters/web_client/component_renderer.rb +49 -0
  217. data/lib/voom/presenters/web_client/custom_css.rb +65 -0
  218. data/lib/voom/presenters/web_client/{markdown_render.rb → custom_render.rb} +5 -3
  219. data/lib/voom/presenters/web_client/helpers/expand_hash.rb +19 -0
  220. data/lib/voom/presenters/web_client/helpers/form_helpers.rb +14 -0
  221. data/lib/voom/presenters/web_client/helpers/padding_helpers.rb +21 -0
  222. data/lib/voom/presenters/web_client/plugin_headers.rb +37 -0
  223. data/lib/voom/presenters/web_client/router.rb +3 -54
  224. data/lib/voom/railtie.rb +37 -0
  225. data/lib/voom/symbol/to_str.rb +3 -3
  226. data/lib/voom/trace.rb +0 -2
  227. data/presenters.gemspec +10 -6
  228. data/public/bundle.css +18256 -0
  229. data/public/bundle.js +60106 -0
  230. data/public/img/demo/avatar.jpg +0 -0
  231. data/public/presenters/custom_css.css +26 -0
  232. data/public/wc.js +52861 -0
  233. data/scripts/build.sh +10 -0
  234. data/views/mdc/.eslintrc.yml +1 -0
  235. data/views/mdc/.nvmrc +1 -0
  236. data/views/mdc/assets/js/app.js +13 -2
  237. data/views/mdc/assets/js/components/base-component.js +147 -12
  238. data/views/mdc/assets/js/components/base-container.js +54 -14
  239. data/views/mdc/assets/js/components/base-toggle.js +56 -0
  240. data/views/mdc/assets/js/components/button.js +74 -5
  241. data/views/mdc/assets/js/components/cards.js +3 -3
  242. data/views/mdc/assets/js/components/checkboxes.js +7 -30
  243. data/views/mdc/assets/js/components/chips.js +76 -12
  244. data/views/mdc/assets/js/components/content.js +5 -4
  245. data/views/mdc/assets/js/components/data-tables.js +11 -34
  246. data/views/mdc/assets/js/components/datetime.js +29 -6
  247. data/views/mdc/assets/js/components/dialogs.js +128 -31
  248. data/views/mdc/assets/js/components/drag_n_drop.js +182 -0
  249. data/views/mdc/assets/js/components/drawer.js +43 -0
  250. data/views/mdc/assets/js/components/events.js +190 -73
  251. data/views/mdc/assets/js/components/events/action_parameter.js +62 -0
  252. data/views/mdc/assets/js/components/events/action_parameter.test.js +62 -0
  253. data/views/mdc/assets/js/components/events/autocomplete.js +94 -0
  254. data/views/mdc/assets/js/components/events/base.js +139 -23
  255. data/views/mdc/assets/js/components/events/clears.js +15 -12
  256. data/views/mdc/assets/js/components/events/close_dialog.js +50 -0
  257. data/views/mdc/assets/js/components/events/dialog.js +32 -14
  258. data/views/mdc/assets/js/components/events/encode.js +8 -0
  259. data/views/mdc/assets/js/components/events/errors.js +175 -92
  260. data/views/mdc/assets/js/components/events/loads.js +50 -11
  261. data/views/mdc/assets/js/components/events/navigates.js +17 -15
  262. data/views/mdc/assets/js/components/events/plugin.js +18 -0
  263. data/views/mdc/assets/js/components/events/post_message.js +21 -0
  264. data/views/mdc/assets/js/components/events/posts.js +147 -65
  265. data/views/mdc/assets/js/components/events/prompt_if_dirty.js +67 -0
  266. data/views/mdc/assets/js/components/events/removes.js +7 -6
  267. data/views/mdc/assets/js/components/events/replaces.js +87 -33
  268. data/views/mdc/assets/js/components/events/snackbar.js +10 -10
  269. data/views/mdc/assets/js/components/events/stepper.js +8 -10
  270. data/views/mdc/assets/js/components/events/toggle_disabled.js +41 -0
  271. data/views/mdc/assets/js/components/events/toggle_visibility.js +57 -15
  272. data/views/mdc/assets/js/components/file-inputs.js +68 -21
  273. data/views/mdc/assets/js/components/form-fields.js +16 -0
  274. data/views/mdc/assets/js/components/forms.js +3 -3
  275. data/views/mdc/assets/js/components/get_event_target.js +15 -0
  276. data/views/mdc/assets/js/components/grid.js +7 -6
  277. data/views/mdc/assets/js/components/header.js +20 -0
  278. data/views/mdc/assets/js/components/hidden-fields.js +19 -8
  279. data/views/mdc/assets/js/components/icon-toggles.js +7 -7
  280. data/views/mdc/assets/js/components/images.js +19 -0
  281. data/views/mdc/assets/js/components/initialize.js +54 -27
  282. data/views/mdc/assets/js/components/lists.js +9 -4
  283. data/views/mdc/assets/js/components/menus.js +60 -13
  284. data/views/mdc/assets/js/components/mixins/dirtyable.js +22 -0
  285. data/views/mdc/assets/js/components/mixins/event-handler.js +7 -7
  286. data/views/mdc/assets/js/components/mixins/visibility-observer.js +22 -21
  287. data/views/mdc/assets/js/components/multi-select.js +75 -0
  288. data/views/mdc/assets/js/components/plugins.js +86 -0
  289. data/views/mdc/assets/js/components/progress.js +31 -0
  290. data/views/mdc/assets/js/components/radios.js +6 -31
  291. data/views/mdc/assets/js/components/rich-text-area.js +217 -33
  292. data/views/mdc/assets/js/components/rich-text-area/horizontal-rule-blot.js +23 -0
  293. data/views/mdc/assets/js/components/root_document.js +5 -0
  294. data/views/mdc/assets/js/components/selects.js +18 -8
  295. data/views/mdc/assets/js/components/sliders.js +23 -12
  296. data/views/mdc/assets/js/components/snackbar.js +11 -8
  297. data/views/mdc/assets/js/components/steppers.js +3 -3
  298. data/views/mdc/assets/js/components/switches.js +6 -29
  299. data/views/mdc/assets/js/components/tab-bars.js +18 -4
  300. data/views/mdc/assets/js/components/text-fields.js +94 -22
  301. data/views/mdc/assets/js/components/tooltip.js +17 -0
  302. data/views/mdc/assets/js/components/typography.js +28 -0
  303. data/views/mdc/assets/js/components/uninitialize.js +7 -0
  304. data/views/mdc/assets/js/wc.js +111 -0
  305. data/views/mdc/assets/scss/app.scss +13 -5
  306. data/views/mdc/assets/scss/components/avatar.scss +51 -7
  307. data/views/mdc/assets/scss/components/button.scss +7 -9
  308. data/views/mdc/assets/scss/components/card.scss +6 -5
  309. data/views/mdc/assets/scss/components/chip.scss +4 -0
  310. data/views/mdc/assets/scss/components/content.scss +25 -0
  311. data/views/mdc/assets/scss/components/data-table.scss +12 -1
  312. data/views/mdc/assets/scss/components/datetime.scss +1 -2
  313. data/views/mdc/assets/scss/components/dialog.scss +7 -2
  314. data/views/mdc/assets/scss/components/drag_n_drop.scss +17 -0
  315. data/views/mdc/assets/scss/components/drawer.scss +82 -0
  316. data/views/mdc/assets/scss/components/expansion-panel.scss +2 -2
  317. data/views/mdc/assets/scss/components/fab.scss +23 -5
  318. data/views/mdc/assets/scss/components/file-input.scss +10 -14
  319. data/views/mdc/assets/scss/components/grid.scss +32 -17
  320. data/views/mdc/assets/scss/components/header.scss +21 -0
  321. data/views/mdc/assets/scss/components/icon-button-toggles.scss +2 -0
  322. data/views/mdc/assets/scss/components/icon.scss +23 -0
  323. data/views/mdc/assets/scss/components/image-list.scss +18 -0
  324. data/views/mdc/assets/scss/components/image.scss +13 -21
  325. data/views/mdc/assets/scss/components/list.scss +9 -3
  326. data/views/mdc/assets/scss/components/menu.scss +13 -3
  327. data/views/mdc/assets/scss/components/multi-select.scss +44 -0
  328. data/views/mdc/assets/scss/components/progress.scss +1 -0
  329. data/views/mdc/assets/scss/components/rich-text-area.scss +38 -2
  330. data/views/mdc/assets/scss/components/select.scss +6 -3
  331. data/views/mdc/assets/scss/components/separator.scss +3 -0
  332. data/views/mdc/assets/scss/components/switch.scss +10 -0
  333. data/views/mdc/assets/scss/components/textfield.scss +8 -4
  334. data/views/mdc/assets/scss/components/tooltip.scss +3 -0
  335. data/views/mdc/assets/scss/components/typography.scss +6 -0
  336. data/views/mdc/assets/scss/components/unordered-lists.scss +17 -0
  337. data/views/mdc/assets/scss/material.blue_grey-orange.min.css +1 -1
  338. data/views/mdc/assets/scss/media.scss +39 -0
  339. data/views/mdc/assets/scss/palette.scss +16 -0
  340. data/views/mdc/assets/scss/styles.scss +39 -1
  341. data/views/mdc/assets/scss/theme.scss +19 -2
  342. data/views/mdc/body/dismissable-drawer.erb +34 -0
  343. data/views/mdc/body/drawer/divider.erb +1 -0
  344. data/views/mdc/body/drawer/item.erb +13 -0
  345. data/views/mdc/body/drawer/label.erb +1 -0
  346. data/views/mdc/body/drawers/menu.erb +1 -1
  347. data/views/mdc/body/footers/menu_item.erb +2 -2
  348. data/views/mdc/body/header.erb +38 -31
  349. data/views/mdc/body/modal-drawer.erb +35 -0
  350. data/views/mdc/body/snackbar.erb +11 -5
  351. data/views/mdc/components/actions/autocomplete.rb +8 -0
  352. data/views/mdc/components/actions/close_dialog.rb +10 -0
  353. data/views/mdc/components/actions/loads.rb +7 -1
  354. data/views/mdc/components/actions/navigates.rb +1 -1
  355. data/views/mdc/components/actions/post.rb +4 -7
  356. data/views/mdc/components/actions/post_message.rb +10 -0
  357. data/views/mdc/components/actions/prompt_if_dirty.rb +17 -0
  358. data/views/mdc/components/actions/replaces.rb +5 -1
  359. data/views/mdc/components/actions/resolver.rb +39 -0
  360. data/views/mdc/components/actions/snackbar.rb +3 -1
  361. data/views/mdc/components/actions/toggle_disabled.rb +10 -0
  362. data/views/mdc/components/avatar.erb +12 -7
  363. data/views/mdc/components/badge.erb +1 -1
  364. data/views/mdc/components/button.erb +2 -3
  365. data/views/mdc/components/buttons/button.erb +12 -12
  366. data/views/mdc/components/buttons/fab.erb +3 -2
  367. data/views/mdc/components/buttons/icon.erb +5 -5
  368. data/views/mdc/components/buttons/image.erb +4 -3
  369. data/views/mdc/components/card.erb +67 -44
  370. data/views/mdc/components/checkbox.erb +32 -35
  371. data/views/mdc/components/chip.erb +38 -30
  372. data/views/mdc/components/chipset.erb +18 -0
  373. data/views/mdc/components/content.erb +35 -14
  374. data/views/mdc/components/datetime.erb +6 -19
  375. data/views/mdc/components/dialog.erb +45 -25
  376. data/views/mdc/components/drag_and_drop/drag_and_drop.rb +16 -0
  377. data/views/mdc/components/event.erb +3 -5
  378. data/views/mdc/components/expansion_panel.erb +8 -6
  379. data/views/mdc/components/file_input.erb +14 -10
  380. data/views/mdc/components/form.erb +4 -19
  381. data/views/mdc/components/grid.erb +20 -17
  382. data/views/mdc/components/hidden_field.erb +3 -4
  383. data/views/mdc/components/icon.erb +7 -5
  384. data/views/mdc/components/icon_toggle.erb +9 -8
  385. data/views/mdc/components/image.erb +23 -5
  386. data/views/mdc/components/image_list.erb +38 -0
  387. data/views/mdc/components/link.erb +3 -13
  388. data/views/mdc/components/list.erb +4 -2
  389. data/views/mdc/components/list/avatar.erb +2 -1
  390. data/views/mdc/components/list/header.erb +5 -3
  391. data/views/mdc/components/list/hidden_field.erb +3 -0
  392. data/views/mdc/components/list/icon.erb +2 -1
  393. data/views/mdc/components/list/line.erb +19 -9
  394. data/views/mdc/components/list/menu.erb +7 -2
  395. data/views/mdc/components/list/separator.erb +1 -1
  396. data/views/mdc/components/menu.erb +14 -6
  397. data/views/mdc/components/multi_select.erb +33 -0
  398. data/views/mdc/components/number_field.erb +38 -0
  399. data/views/mdc/components/page_title.erb +2 -2
  400. data/views/mdc/components/progress.erb +11 -0
  401. data/views/mdc/components/radio_button.erb +5 -6
  402. data/views/mdc/components/render.erb +2 -3
  403. data/views/mdc/components/rich_text_area.erb +13 -10
  404. data/views/mdc/components/select.erb +28 -12
  405. data/views/mdc/components/separator.erb +3 -0
  406. data/views/mdc/components/shared/hint_error_display.erb +9 -0
  407. data/views/mdc/components/shared/input_label.erb +7 -0
  408. data/views/mdc/components/slider.erb +3 -1
  409. data/views/mdc/components/stepper.erb +1 -1
  410. data/views/mdc/components/stepper/step.erb +1 -1
  411. data/views/mdc/components/switch.erb +8 -7
  412. data/views/mdc/components/tab_bar.erb +7 -1
  413. data/views/mdc/components/table.erb +26 -13
  414. data/views/mdc/components/table/checkbox.erb +6 -3
  415. data/views/mdc/components/table/column.erb +18 -0
  416. data/views/mdc/components/table/footer.erb +8 -0
  417. data/views/mdc/components/table/header.erb +5 -4
  418. data/views/mdc/components/table/pagination.erb +2 -6
  419. data/views/mdc/components/table/row.erb +5 -5
  420. data/views/mdc/components/text_area.erb +9 -11
  421. data/views/mdc/components/text_field.erb +29 -37
  422. data/views/mdc/components/tooltip.erb +2 -2
  423. data/views/mdc/components/typography.erb +7 -5
  424. data/views/mdc/components/unordered_list.erb +10 -0
  425. data/views/mdc/components/unordered_list/icon.erb +3 -0
  426. data/views/mdc/components/unordered_list/list_item.erb +7 -0
  427. data/views/mdc/layout.erb +41 -29
  428. data/views/mdc/package-lock.json +2241 -1332
  429. data/views/mdc/package.json +47 -29
  430. data/views/mdc/web.erb +4 -0
  431. data/views/mdc/webpack.config.js +13 -1
  432. metadata +228 -32
  433. data/app/demo/component_status.pom +0 -76
  434. data/lib/voom-presenters.rb +0 -9
  435. data/lib/voom/presenters-engine.rb +0 -44
  436. data/lib/voom/presenters.rb +0 -19
  437. data/public/.gitignore +0 -2
  438. data/scripts/bump.sh +0 -5
  439. data/scripts/changelog.sh +0 -5
  440. data/scripts/deploy-demo.sh +0 -3
  441. data/scripts/release.sh +0 -5
  442. data/scripts/tag.sh +0 -5
  443. data/views/mdc/assets/js/dialog-polyfill.js +0 -738
  444. data/views/mdc/assets/scss/components/icon-toggles.scss +0 -9
  445. data/views/mdc/assets/scss/components/vendor/flatpickr.min.css +0 -13
  446. data/views/mdc/body/drawer.erb +0 -18
  447. data/views/mdc/components/google_map.erb +0 -9
@@ -0,0 +1,62 @@
1
+ class VActionParameter {
2
+ constructor(options) {
3
+ this.value = options.value;
4
+ this.response_index = options.response_index;
5
+ }
6
+
7
+ fetchValue(results) {
8
+ const result = results[results.length - this.response_index - 1];
9
+ return this.resolve(this.value, JSON.parse(result.content));
10
+ }
11
+
12
+ resolve(path, obj) {
13
+ return this.value.reduce(function(prev, curr) {
14
+ return prev ? prev[curr] : null;
15
+ }, obj || self);
16
+ }
17
+ }
18
+
19
+ function isObject(thing) {
20
+ return thing && typeof thing === 'object';
21
+ }
22
+
23
+ /**
24
+ * expandParam resolves an parameter `value` to a primitive value
25
+ * according to the given path for the parameter in `results`.
26
+ * If the `value` is not an action_parameter, it is returned unaltered.
27
+ * @param {Object} results An action's results
28
+ * @param {*} value The value of the parameter
29
+ * @return {*} A resolved primitive value
30
+ */
31
+ export function expandParam(results, value) {
32
+ if (isObject(value) && value.type === 'action_parameter') {
33
+ return new VActionParameter(value).fetchValue(results);
34
+ }
35
+
36
+ return value;
37
+ }
38
+
39
+ /**
40
+ * expandParams resolves all values in `params` to primitive values.
41
+ *
42
+ * Primitive values are passed through unaltered.
43
+ * Values of action_parameter parameters are resolved to primitive values
44
+ * via `results`.
45
+ * @param {Object} results An action's results
46
+ * @param {Object} params An action's parameters
47
+ * @return {Object}
48
+ */
49
+ export function expandParams(results, params) {
50
+ const expandedParams = {};
51
+
52
+ for (const [key, value] of Object.entries(params)) {
53
+ if (!isObject(value) || value.type === 'action_parameter') {
54
+ expandedParams[key] = expandParam(results, value);
55
+ }
56
+ else {
57
+ expandedParams[key] = expandParams(results, value);
58
+ }
59
+ }
60
+
61
+ return expandedParams;
62
+ }
@@ -0,0 +1,62 @@
1
+ import {expandParam, expandParams} from './action_parameter';
2
+
3
+ const mockMessage = {
4
+ errors: {},
5
+ snackbar: [],
6
+ warnings: {},
7
+ };
8
+ const mockPayload = 'hello, world!';
9
+ const mockContent = {
10
+ data: mockPayload,
11
+ status: 0,
12
+ message: mockMessage,
13
+ };
14
+ const mockAction = {
15
+ action: 'posts',
16
+ content: JSON.stringify(mockContent),
17
+ contentType: 'application/json; charset=utf-8',
18
+ method: undefined,
19
+ responseURL: 'https://example.com',
20
+ statusCode: 200
21
+ };
22
+ const mockResults = [mockAction];
23
+ const mockActionParameter = {
24
+ value: ['data'],
25
+ type: 'action_parameter',
26
+ response_index: 0,
27
+ };
28
+
29
+ describe('expandParam', () => {
30
+ test('resolves values of action parameters', () => {
31
+ expect(expandParam(mockResults, mockActionParameter)).toEqual(mockPayload);
32
+ });
33
+
34
+ test('passes through objects unaltered', () => {
35
+ expect(expandParam(mockResults, {key: 'value'})).toEqual({key: 'value'});
36
+ });
37
+
38
+ test('passes through primitive values unalthered', () => {
39
+ expect(expandParam(mockResults, 4)).toEqual(4);
40
+ expect(expandParam(mockResults, 'string')).toEqual('string');
41
+ expect(expandParam(mockResults, true)).toEqual(true);
42
+ expect(expandParam(mockResults, null)).toEqual(null);
43
+ });
44
+ });
45
+
46
+ describe('expandParams', () => {
47
+ const params = {
48
+ primitive: 'value',
49
+ action: mockActionParameter,
50
+ nested: { integer: 4, action: mockActionParameter },
51
+ };
52
+
53
+ test('resolves values of action parameters', () => {
54
+ expect(expandParams(mockResults, params).action).toEqual(mockPayload);
55
+ expect(expandParams(mockResults, params).nested.action).toEqual(mockPayload);
56
+ });
57
+
58
+ test('passes through primitive values unalthered', () => {
59
+ expect(expandParams(mockResults, params).primitive).toEqual('value');
60
+ expect(expandParams(mockResults, params).nested.integer).toEqual(4);
61
+ });
62
+ });
@@ -0,0 +1,94 @@
1
+ import {VBase} from './base';
2
+
3
+ // Auto complete a datalist
4
+ // The elementId is a datalist
5
+ // The url is called as a GET expecting json back
6
+ export class VAutoComplete extends VBase {
7
+ constructor(options, url, params, event, root) {
8
+ super(options, root);
9
+ this.element_id = options.target;
10
+ this.url = url;
11
+ this.params = params;
12
+ this.event = event;
13
+ }
14
+
15
+ call(results) {
16
+ // Clear the timeout if it has already been set.
17
+ // This will prevent the previous task from executing
18
+ // if it has been less than <MILLISECONDS>
19
+ let parentElement = this.parentElement();
20
+ let updateElement = this.createUpdateElementHandler(this);
21
+ let promiseObj = new Promise(function (resolve) {
22
+ clearTimeout(parentElement.vTimeout);
23
+ // Make a new timeout
24
+ parentElement.vTimeout = setTimeout(updateElement, 500);
25
+ results.push({action:'autocomplete', statusCode: 200});
26
+ resolve(results);
27
+ });
28
+ return promiseObj;
29
+ }
30
+
31
+ // This is used to get a proper binding of the object
32
+ // https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example
33
+ createUpdateElementHandler(_this_) {
34
+ return function () {
35
+ _this_.updateElement();
36
+ };
37
+ }
38
+
39
+ updateElement() {
40
+ this.clearErrors();
41
+ this.getData(this.populateOptions);
42
+ }
43
+
44
+ dataList() {
45
+ return this.root.getElementById(this.element_id);
46
+ }
47
+
48
+ getData(funcProcessData) {
49
+ let comp = this.component();
50
+ console.log(comp);
51
+ if(comp.value().length < 2){
52
+ return;
53
+ }
54
+ let httpRequest = new XMLHttpRequest();
55
+ if (!httpRequest) {
56
+ throw new Error('Cannot talk to server! Please upgrade your browser to one that supports XMLHttpRequest.');
57
+ }
58
+ let dataList = this.dataList();
59
+ let url = this.buildURL(this.url, this.params, this.inputValues());
60
+
61
+ httpRequest.onreadystatechange = function () {
62
+ if (httpRequest.readyState === XMLHttpRequest.DONE) {
63
+ console.log(httpRequest.status + ':' + this.getResponseHeader('content-type'));
64
+ if (httpRequest.status === 200) {
65
+ let response = JSON.parse(httpRequest.responseText);
66
+ funcProcessData(response, dataList);
67
+ } else {
68
+ console.error("Unable to autocomplete! ElementId: " + this.element_id);
69
+ }
70
+ }
71
+ };
72
+ console.log('GET:' + url);
73
+ httpRequest.open('GET', url, true);
74
+ httpRequest.send();
75
+ }
76
+
77
+ populateOptions(response, dataList) {
78
+ dataList.innerHTML = "";
79
+
80
+ response.forEach(function (item) {
81
+ let value = item;
82
+ let key = null;
83
+ if (Array.isArray(item)) {
84
+ value = item[0];
85
+ key = item[1];
86
+ }
87
+ // Create a new <option> element.
88
+ let option = document.createElement('option');
89
+ option.value = value;
90
+ option.dataset.key = key;
91
+ dataList.appendChild(option);
92
+ });
93
+ }
94
+ }
@@ -1,51 +1,167 @@
1
+ import 'core-js/features/array/flat';
2
+ import 'core-js/features/array/flat-map';
1
3
  import {VErrors} from './errors';
2
4
  import {VUrls} from '../../utils/urls';
3
5
 
4
6
  export class VBase extends VUrls {
5
- constructor(options) {
7
+ constructor(options, root) {
6
8
  super();
7
9
  this.options = options;
10
+ this.root = root;
8
11
  }
9
12
 
10
13
  clearErrors() {
11
- new VErrors().clearErrors();
14
+ new VErrors(this.root).clearErrors();
12
15
  }
13
16
 
14
17
  parentElement() {
15
- return document.getElementById(this.options.__parent_id__);
18
+ return this.root.getElementById(this.options.__parent_id__);
16
19
  }
17
20
 
18
- inputValues(form) {
19
- let params = [];
21
+ /**
22
+ * taggedInputs retrieves all components matching this event's input_tag
23
+ * value.
24
+ * @return {NodeList}
25
+ */
26
+ taggedInputs() {
27
+ const inputTag = this.options.input_tag;
20
28
 
21
- // If tagged input is asked for. Fetch all the matching tag elements and then call any bound components
22
- if (this.options.input_tag !== undefined) {
23
- var taggedInputs = document.querySelectorAll('[data-input-tag=' + this.options.input_tag + ']');
24
- for (let input of taggedInputs) {
25
- if (input.vComponent && typeof input.vComponent.prepareSubmit === 'function') {
26
- input.vComponent.prepareSubmit(params);
27
- }
29
+ if (!inputTag) {
30
+ return [];
31
+ }
32
+
33
+ const selector = `[data-input-tag="${inputTag}"]`;
34
+ const inputs = this.root.querySelectorAll(selector);
35
+
36
+ if (inputs.length < 1) {
37
+ console.warn(
38
+ `input_tag ${inputTag} matched 0 elements. Are you sure`
39
+ + 'you\'ve specified the correct value?'
40
+ );
41
+ }
42
+
43
+ return inputs;
44
+ }
45
+
46
+ /**
47
+ * inputs retrieves relevant input elements for this event.
48
+ *
49
+ * - If an `input_tag` has been provided, all matching tagged elements are
50
+ * included.
51
+ * - If this component is a input element, it is included.
52
+ * - If this component has input elements, its input elements are included.
53
+ * If not, the input elements of the nearest container (dialog or content)
54
+ * are included.
55
+ * @return {Array<HTMLElement>}
56
+ */
57
+ inputs() {
58
+ const components = [];
59
+
60
+ // Collect tagged components, if applicable:
61
+ if (this.options.input_tag) {
62
+ const taggedComponents = Array.from(this.taggedInputs())
63
+ .filter((element) => element.vComponent)
64
+ .map((element) => element.vComponent);
65
+
66
+ components.push(taggedComponents);
67
+ }
68
+
69
+ let comp = this.component();
70
+
71
+ if (comp) {
72
+ // Include ourselves if we're a form field component, but not a
73
+ // container:
74
+ if (comp.respondTo('prepareSubmit') && !comp.respondTo('inputs')) {
75
+ components.push(comp);
76
+ }
77
+ else if (!comp.respondTo('inputs')) {
78
+ // Defer to the component's closest container (card, content,
79
+ // dialog, or form) if the component itself does not respond to
80
+ // `inputs`:
81
+ comp = this.closestContainer();
28
82
  }
29
83
  }
30
- // Let input components push parameters
31
- let vComp = this.component();
32
- if (vComp && typeof vComp.prepareSubmit === 'function') {
33
- vComp.prepareSubmit(params);
84
+
85
+ // If the caller requested tagged_inputs assume they only want those inputs posted and
86
+ // DO NOT include additional input from the component
87
+ // I reverted this temporarily as it caused some unintended behavior in. I am going to discuss with the dev
88
+ // team and revisit in a later release.
89
+ if (comp && comp.respondTo('inputs')) { //} && !this.options.input_tag) {
90
+ components.push(comp);
34
91
  }
92
+
93
+ // Map components to elements.
94
+ // Containers are mapped to their child elements.
95
+ // Form field components are mapped to their own element.
96
+ const elements = components.flat().flatMap((comp) => {
97
+ if (comp.respondTo('inputs')) {
98
+ return Array.from(comp.inputs());
99
+ }
100
+ else if (comp.respondTo('prepareSubmit')) {
101
+ return comp.element;
102
+ }
103
+ });
104
+
105
+ // Deduplicate:
106
+ return Array.from(new Set(elements));
107
+ }
108
+
109
+ /**
110
+ * inputComponents retrieves the Component for each of this event's
111
+ * relevant input elements.
112
+ * @return {Array<VBaseComponent>}
113
+ */
114
+ inputComponents() {
115
+ return this.inputs()
116
+ .filter((element) => element.vComponent)
117
+ .map((element) => element.vComponent);
118
+ }
119
+
120
+ /**
121
+ * inputValues retrieves submit values for each of this event's relevant
122
+ * input elements.
123
+ * @return {Array}
124
+ */
125
+ inputValues() {
126
+ const params = [];
127
+
128
+ this.inputComponents()
129
+ .filter((comp) => comp.respondTo('prepareSubmit'))
130
+ .map((comp) => comp.prepareSubmit(params));
131
+
35
132
  return params;
36
133
  }
37
134
 
38
135
  component() {
39
- let parent = this.parentElement();
136
+ const parent = this.parentElement();
137
+
40
138
  return parent ? parent.vComponent : null;
41
139
  }
42
140
 
43
- validate() {
44
- let errors = [];
45
- let comp = this.component();
46
- if (comp) {
47
- errors = comp.validate();
141
+ validate(formData) {
142
+ return this.inputComponents()
143
+ .filter((comp) => comp.respondTo('validate'))
144
+ .map((comp) => comp.validate(formData))
145
+ .filter((errors) => errors !== true && errors !== undefined);
146
+ }
147
+
148
+ closestContainer() {
149
+ const element = this.closestContainerElement();
150
+
151
+ if (!element) {
152
+ return null;
48
153
  }
49
- return errors;
154
+
155
+ return element.vComponent;
156
+ }
157
+
158
+ closestContainerElement() {
159
+ const comp = this.component();
160
+
161
+ if (!(comp && comp.element)) {
162
+ return null;
163
+ }
164
+
165
+ return comp.element.closest('[data-is-container]');
50
166
  }
51
167
  }
@@ -1,26 +1,29 @@
1
1
  export class VClears {
2
- constructor(options, params, event) {
2
+ constructor(options, params, event, root) {
3
3
  this.target = options.target;
4
4
  this.ids = params.ids;
5
5
  this.event = event;
6
+ this.root = root;
6
7
  }
7
8
 
8
9
  call(results) {
9
- let ids = this.ids;
10
- var promiseObj = new Promise(function (resolve) {
11
- console.log("Clearing");
10
+ const ids = this.ids;
11
+ const root = this.root;
12
+ return new Promise(function(resolve) {
13
+ console.debug('Clearing');
12
14
  results.push({action: 'clears', statusCode: 200});
13
- for (const id of ids){
14
- let elem = document.getElementById(id);
15
- if(elem && elem.vComponent && elem.vComponent.clear){
15
+ for (const id of ids) {
16
+ const elem = root.getElementById(id);
17
+ if (elem && elem.vComponent && elem.vComponent.clear) {
16
18
  elem.vComponent.clear();
17
- }else {
18
- console.log("Unable to clear element with id: "+id+
19
- "! Check to make sure you passed the correct id, and that the control/input can be cleared.");
19
+ }
20
+ else {
21
+ console.warn('Unable to clear element with id: ' + id +
22
+ '! Check to make sure you passed the correct id, and ' +
23
+ 'that the control/input can be cleared.');
20
24
  }
21
25
  }
22
26
  resolve(results);
23
27
  });
24
- return promiseObj;
25
28
  }
26
- }
29
+ }