voom-presenters 0.2.0 → 2.0.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 (440) 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 +39 -0
  7. data/.gitignore +3 -2
  8. data/.releaserc +8 -0
  9. data/.ruby-version +2 -1
  10. data/CHANGELOG.md +64 -114
  11. data/CONTRIBUTING.md +60 -0
  12. data/Gemfile +12 -3
  13. data/Gemfile.lock +83 -45
  14. data/Procfile +1 -0
  15. data/README.md +41 -39
  16. data/app/demo/component_status.pom +1 -1
  17. data/app/demo/components/avatars.pom +40 -0
  18. data/app/demo/components/cards.pom +11 -4
  19. data/app/demo/components/chips.pom +61 -54
  20. data/app/demo/components/content.pom +96 -16
  21. data/app/demo/components/dialogs.pom +175 -6
  22. data/app/demo/components/file_inputs.pom +38 -2
  23. data/app/demo/components/google_maps.pom +6 -1
  24. data/app/demo/components/headers.pom +80 -20
  25. data/app/demo/components/icons.pom +86 -55
  26. data/app/demo/components/image_lists.pom +100 -0
  27. data/app/demo/components/images.pom +45 -0
  28. data/app/demo/components/layouts.pom +3 -25
  29. data/app/demo/components/lists.pom +24 -4
  30. data/app/demo/components/menus.pom +14 -4
  31. data/app/demo/components/nav/menu.pom +38 -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 +44 -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/nav/top_nav.pom +12 -0
  56. data/app/demo/patterns/drag_drop.pom +89 -0
  57. data/app/demo/patterns/floating_card.pom +29 -0
  58. data/app/demo/patterns/search_select.pom +9 -7
  59. data/app/demo/plugins/chart.pom +254 -0
  60. data/app/demo/plugins/image_crop.pom +44 -0
  61. data/app/demo/plugins/index.pom +29 -0
  62. data/app/demo/plugins/nav/drawer.pom +19 -0
  63. data/app/demo/shared/context_list.pom +1 -1
  64. data/app/demo/styles.pom +3 -1
  65. data/bin/console +4 -4
  66. data/bin/presenters +3 -0
  67. data/component-status.yml +15 -15
  68. data/config.ru +20 -10
  69. data/docs/settings.md +81 -0
  70. data/lib/hash_ext/traverse.rb +14 -0
  71. data/lib/voom.rb +25 -0
  72. data/lib/voom/container_methods.rb +2 -2
  73. data/lib/voom/engine.rb +5 -0
  74. data/lib/voom/presenters/api/app.rb +31 -11
  75. data/lib/voom/presenters/api/router.rb +3 -49
  76. data/lib/voom/presenters/app.rb +3 -3
  77. data/lib/voom/presenters/cli.rb +28 -0
  78. data/lib/voom/presenters/demo/dragon_drop.rb +48 -0
  79. data/lib/voom/presenters/demo/echo.rb +2 -0
  80. data/lib/voom/presenters/demo/slow.rb +18 -0
  81. data/lib/voom/presenters/dsl/components/actions/autocomplete.rb +15 -0
  82. data/lib/voom/presenters/dsl/components/actions/base.rb +36 -8
  83. data/lib/voom/presenters/dsl/components/actions/clear.rb +0 -2
  84. data/lib/voom/presenters/dsl/components/actions/close_dialog.rb +17 -0
  85. data/lib/voom/presenters/dsl/components/actions/deletes.rb +0 -2
  86. data/lib/voom/presenters/dsl/components/actions/dialog.rb +0 -2
  87. data/lib/voom/presenters/dsl/components/actions/loads.rb +5 -6
  88. data/lib/voom/presenters/dsl/components/actions/navigates.rb +0 -2
  89. data/lib/voom/presenters/dsl/components/actions/post_message.rb +17 -0
  90. data/lib/voom/presenters/dsl/components/actions/posts.rb +5 -2
  91. data/lib/voom/presenters/dsl/components/actions/prompt_if_dirty.rb +15 -0
  92. data/lib/voom/presenters/dsl/components/actions/remove.rb +0 -2
  93. data/lib/voom/presenters/dsl/components/actions/replaces.rb +4 -4
  94. data/lib/voom/presenters/dsl/components/actions/snackbar.rb +0 -2
  95. data/lib/voom/presenters/dsl/components/actions/stepper.rb +0 -2
  96. data/lib/voom/presenters/dsl/components/actions/toggle_disabled.rb +15 -0
  97. data/lib/voom/presenters/dsl/components/actions/toggle_visibility.rb +0 -2
  98. data/lib/voom/presenters/dsl/components/actions/updates.rb +5 -2
  99. data/lib/voom/presenters/dsl/components/avatar.rb +4 -8
  100. data/lib/voom/presenters/dsl/components/badge.rb +0 -2
  101. data/lib/voom/presenters/dsl/components/base.rb +25 -18
  102. data/lib/voom/presenters/dsl/components/button.rb +15 -11
  103. data/lib/voom/presenters/dsl/components/card.rb +49 -36
  104. data/lib/voom/presenters/dsl/components/checkbox.rb +0 -2
  105. data/lib/voom/presenters/dsl/components/chip.rb +5 -7
  106. data/lib/voom/presenters/dsl/components/chipset.rb +33 -0
  107. data/lib/voom/presenters/dsl/components/content.rb +28 -18
  108. data/lib/voom/presenters/dsl/components/datetime_base.rb +0 -2
  109. data/lib/voom/presenters/dsl/components/datetime_field.rb +0 -2
  110. data/lib/voom/presenters/dsl/components/dialog.rb +36 -12
  111. data/lib/voom/presenters/dsl/components/drawer.rb +9 -6
  112. data/lib/voom/presenters/dsl/components/event.rb +106 -65
  113. data/lib/voom/presenters/dsl/components/event_base.rb +1 -3
  114. data/lib/voom/presenters/dsl/components/expansion_panel.rb +0 -3
  115. data/lib/voom/presenters/dsl/components/file_input.rb +18 -6
  116. data/lib/voom/presenters/dsl/components/footer.rb +2 -2
  117. data/lib/voom/presenters/dsl/components/form.rb +2 -17
  118. data/lib/voom/presenters/dsl/components/grid.rb +52 -50
  119. data/lib/voom/presenters/dsl/components/header.rb +17 -1
  120. data/lib/voom/presenters/dsl/components/hidden_field.rb +0 -2
  121. data/lib/voom/presenters/dsl/components/icon.rb +2 -4
  122. data/lib/voom/presenters/dsl/components/icon_base.rb +5 -7
  123. data/lib/voom/presenters/dsl/components/icon_toggle.rb +2 -4
  124. data/lib/voom/presenters/dsl/components/image.rb +61 -13
  125. data/lib/voom/presenters/dsl/components/image_list.rb +43 -0
  126. data/lib/voom/presenters/dsl/components/input.rb +14 -5
  127. data/lib/voom/presenters/dsl/components/link.rb +33 -0
  128. data/lib/voom/presenters/dsl/components/list.rb +6 -13
  129. data/lib/voom/presenters/dsl/components/lists/action.rb +9 -11
  130. data/lib/voom/presenters/dsl/components/lists/actions.rb +0 -3
  131. data/lib/voom/presenters/dsl/components/lists/line.rb +27 -15
  132. data/lib/voom/presenters/dsl/components/menu.rb +51 -9
  133. data/lib/voom/presenters/dsl/components/mixins/append.rb +2 -2
  134. data/lib/voom/presenters/dsl/components/mixins/attaches.rb +0 -2
  135. data/lib/voom/presenters/dsl/components/mixins/avatar.rb +1 -3
  136. data/lib/voom/presenters/dsl/components/mixins/chips.rb +0 -2
  137. data/lib/voom/presenters/dsl/components/mixins/chipset.rb +19 -0
  138. data/lib/voom/presenters/dsl/components/mixins/common.rb +13 -14
  139. data/lib/voom/presenters/dsl/components/mixins/dialogs.rb +0 -2
  140. data/lib/voom/presenters/dsl/components/mixins/event.rb +0 -2
  141. data/lib/voom/presenters/dsl/components/mixins/image_lists.rb +15 -0
  142. data/lib/voom/presenters/dsl/components/mixins/last_response.rb +48 -0
  143. data/lib/voom/presenters/dsl/components/mixins/padding.rb +42 -0
  144. data/lib/voom/presenters/dsl/components/mixins/progress.rb +16 -0
  145. data/lib/voom/presenters/dsl/components/mixins/tab_bars.rb +2 -0
  146. data/lib/voom/presenters/dsl/components/mixins/tables.rb +15 -0
  147. data/lib/voom/presenters/dsl/components/mixins/text_fields.rb +5 -0
  148. data/lib/voom/presenters/dsl/components/mixins/toggles.rb +0 -2
  149. data/lib/voom/presenters/dsl/components/mixins/typography.rb +55 -8
  150. data/lib/voom/presenters/dsl/components/mixins/yield_to.rb +2 -2
  151. data/lib/voom/presenters/dsl/components/number_field.rb +20 -0
  152. data/lib/voom/presenters/dsl/components/page_title.rb +31 -0
  153. data/lib/voom/presenters/dsl/components/progress.rb +27 -0
  154. data/lib/voom/presenters/dsl/components/radio_button.rb +0 -1
  155. data/lib/voom/presenters/dsl/components/rich_text_area.rb +5 -11
  156. data/lib/voom/presenters/dsl/components/select.rb +21 -9
  157. data/lib/voom/presenters/dsl/components/separator.rb +21 -0
  158. data/lib/voom/presenters/dsl/components/slider.rb +6 -7
  159. data/lib/voom/presenters/dsl/components/stepper.rb +0 -10
  160. data/lib/voom/presenters/dsl/components/switch.rb +0 -2
  161. data/lib/voom/presenters/dsl/components/tab_bar.rb +0 -3
  162. data/lib/voom/presenters/dsl/components/table.rb +39 -20
  163. data/lib/voom/presenters/dsl/components/text_area.rb +1 -3
  164. data/lib/voom/presenters/dsl/components/text_field.rb +54 -11
  165. data/lib/voom/presenters/dsl/components/time_field.rb +0 -2
  166. data/lib/voom/presenters/dsl/components/toggle_base.rb +8 -6
  167. data/lib/voom/presenters/dsl/components/typography.rb +4 -4
  168. data/lib/voom/presenters/dsl/components/unordered_list.rb +50 -0
  169. data/lib/voom/presenters/dsl/definer.rb +0 -4
  170. data/lib/voom/presenters/dsl/definition.rb +6 -5
  171. data/lib/voom/presenters/dsl/protect_from_forgery.rb +43 -0
  172. data/lib/voom/presenters/dsl/user_interface.rb +37 -22
  173. data/lib/voom/presenters/errors.rb +1 -0
  174. data/lib/voom/presenters/errors/invalid_dsl.rb +8 -0
  175. data/lib/voom/presenters/errors/parameter_validation.rb +1 -3
  176. data/lib/voom/presenters/generators/inflectors.rb +59 -0
  177. data/lib/voom/presenters/generators/plugin.rb +115 -0
  178. data/lib/voom/presenters/generators/templates/plugin/.gitignore +12 -0
  179. data/lib/voom/presenters/generators/templates/plugin/Gemfile +6 -0
  180. data/lib/voom/presenters/generators/templates/plugin/LICENSE.txt.tt +21 -0
  181. data/lib/voom/presenters/generators/templates/plugin/README.md +253 -0
  182. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/action.rb.tt +16 -0
  183. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/actions/dsl.rb.tt +22 -0
  184. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/component.rb.tt +18 -0
  185. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/components/dsl.rb.tt +19 -0
  186. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/helpers/helper.rb.tt +15 -0
  187. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/plugin.rb.tt +9 -0
  188. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/actions/data.rb.tt +17 -0
  189. data/lib/voom/presenters/generators/templates/plugin/lib/voom/presenters/plugins/web_client/components/render.rb.tt +23 -0
  190. data/lib/voom/presenters/generators/templates/plugin/presenter_plugin.gemspec.tt +21 -0
  191. data/lib/voom/presenters/generators/templates/plugin/views/assets/css/components/component.css.tt +21 -0
  192. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/actions/action.js.tt +15 -0
  193. data/lib/voom/presenters/generators/templates/plugin/views/assets/js/components/component.js.tt +39 -0
  194. data/lib/voom/presenters/generators/templates/plugin/views/components/component.erb.tt +14 -0
  195. data/lib/voom/presenters/generators/templates/plugin/views/components/component_header.erb.tt +20 -0
  196. data/lib/voom/presenters/helpers.rb +2 -8
  197. data/lib/voom/presenters/helpers/inflector.rb +1 -1
  198. data/lib/voom/presenters/helpers/rails.rb +15 -8
  199. data/lib/voom/presenters/helpers/redact.rb +13 -0
  200. data/lib/voom/presenters/helpers/route.rb +12 -5
  201. data/lib/voom/presenters/pluggable.rb +37 -0
  202. data/lib/voom/presenters/plugins.rb +7 -0
  203. data/lib/voom/presenters/plugins/google_maps.rb +24 -0
  204. data/lib/voom/presenters/plugins/google_maps/google_map.erb +10 -0
  205. data/lib/voom/presenters/{dsl/components → plugins/google_maps}/google_map.rb +4 -3
  206. data/lib/voom/presenters/{dsl.rb → registry.rb} +13 -15
  207. data/lib/voom/presenters/router.rb +59 -0
  208. data/lib/voom/presenters/settings.rb +18 -8
  209. data/lib/voom/presenters/version.rb +1 -1
  210. data/lib/voom/presenters/web_client/app.rb +86 -29
  211. data/lib/voom/presenters/web_client/component_decorator_factory.rb +27 -0
  212. data/lib/voom/presenters/web_client/component_html_decorator.rb +50 -0
  213. data/lib/voom/presenters/web_client/component_renderer.rb +49 -0
  214. data/lib/voom/presenters/web_client/custom_css.rb +65 -0
  215. data/lib/voom/presenters/web_client/{markdown_render.rb → custom_render.rb} +5 -3
  216. data/lib/voom/presenters/web_client/helpers/expand_hash.rb +19 -0
  217. data/lib/voom/presenters/web_client/helpers/form_helpers.rb +14 -0
  218. data/lib/voom/presenters/web_client/helpers/padding_helpers.rb +21 -0
  219. data/lib/voom/presenters/web_client/plugin_headers.rb +37 -0
  220. data/lib/voom/presenters/web_client/router.rb +3 -54
  221. data/lib/voom/railtie.rb +37 -0
  222. data/lib/voom/symbol/to_str.rb +3 -3
  223. data/lib/voom/trace.rb +0 -2
  224. data/presenters.gemspec +8 -4
  225. data/public/bundle.css +18221 -0
  226. data/public/bundle.js +59949 -0
  227. data/public/img/demo/avatar.jpg +0 -0
  228. data/public/presenters/custom_css.css +26 -0
  229. data/public/wc.js +52704 -0
  230. data/scripts/build.sh +10 -0
  231. data/views/mdc/.eslintrc.yml +1 -0
  232. data/views/mdc/.nvmrc +1 -0
  233. data/views/mdc/assets/js/app.js +13 -2
  234. data/views/mdc/assets/js/components/base-component.js +147 -12
  235. data/views/mdc/assets/js/components/base-container.js +54 -14
  236. data/views/mdc/assets/js/components/base-toggle.js +56 -0
  237. data/views/mdc/assets/js/components/button.js +74 -5
  238. data/views/mdc/assets/js/components/cards.js +3 -3
  239. data/views/mdc/assets/js/components/checkboxes.js +7 -30
  240. data/views/mdc/assets/js/components/chips.js +76 -12
  241. data/views/mdc/assets/js/components/content.js +5 -4
  242. data/views/mdc/assets/js/components/data-tables.js +11 -34
  243. data/views/mdc/assets/js/components/datetime.js +29 -6
  244. data/views/mdc/assets/js/components/dialogs.js +128 -31
  245. data/views/mdc/assets/js/components/drag_n_drop.js +182 -0
  246. data/views/mdc/assets/js/components/drawer.js +43 -0
  247. data/views/mdc/assets/js/components/events.js +190 -73
  248. data/views/mdc/assets/js/components/events/action_parameter.js +62 -0
  249. data/views/mdc/assets/js/components/events/action_parameter.test.js +62 -0
  250. data/views/mdc/assets/js/components/events/autocomplete.js +94 -0
  251. data/views/mdc/assets/js/components/events/base.js +139 -23
  252. data/views/mdc/assets/js/components/events/clears.js +15 -12
  253. data/views/mdc/assets/js/components/events/close_dialog.js +50 -0
  254. data/views/mdc/assets/js/components/events/dialog.js +32 -14
  255. data/views/mdc/assets/js/components/events/encode.js +8 -0
  256. data/views/mdc/assets/js/components/events/errors.js +175 -92
  257. data/views/mdc/assets/js/components/events/loads.js +50 -11
  258. data/views/mdc/assets/js/components/events/navigates.js +17 -15
  259. data/views/mdc/assets/js/components/events/plugin.js +18 -0
  260. data/views/mdc/assets/js/components/events/post_message.js +21 -0
  261. data/views/mdc/assets/js/components/events/posts.js +147 -65
  262. data/views/mdc/assets/js/components/events/prompt_if_dirty.js +67 -0
  263. data/views/mdc/assets/js/components/events/removes.js +7 -6
  264. data/views/mdc/assets/js/components/events/replaces.js +87 -33
  265. data/views/mdc/assets/js/components/events/snackbar.js +10 -10
  266. data/views/mdc/assets/js/components/events/stepper.js +8 -10
  267. data/views/mdc/assets/js/components/events/toggle_disabled.js +41 -0
  268. data/views/mdc/assets/js/components/events/toggle_visibility.js +57 -15
  269. data/views/mdc/assets/js/components/file-inputs.js +68 -21
  270. data/views/mdc/assets/js/components/form-fields.js +16 -0
  271. data/views/mdc/assets/js/components/forms.js +3 -3
  272. data/views/mdc/assets/js/components/get_event_target.js +15 -0
  273. data/views/mdc/assets/js/components/grid.js +7 -6
  274. data/views/mdc/assets/js/components/header.js +20 -0
  275. data/views/mdc/assets/js/components/hidden-fields.js +19 -8
  276. data/views/mdc/assets/js/components/icon-toggles.js +7 -7
  277. data/views/mdc/assets/js/components/images.js +19 -0
  278. data/views/mdc/assets/js/components/initialize.js +52 -27
  279. data/views/mdc/assets/js/components/lists.js +9 -4
  280. data/views/mdc/assets/js/components/menus.js +60 -13
  281. data/views/mdc/assets/js/components/mixins/dirtyable.js +22 -0
  282. data/views/mdc/assets/js/components/mixins/event-handler.js +7 -7
  283. data/views/mdc/assets/js/components/mixins/visibility-observer.js +22 -21
  284. data/views/mdc/assets/js/components/plugins.js +86 -0
  285. data/views/mdc/assets/js/components/progress.js +31 -0
  286. data/views/mdc/assets/js/components/radios.js +6 -31
  287. data/views/mdc/assets/js/components/rich-text-area.js +217 -33
  288. data/views/mdc/assets/js/components/rich-text-area/horizontal-rule-blot.js +23 -0
  289. data/views/mdc/assets/js/components/root_document.js +5 -0
  290. data/views/mdc/assets/js/components/selects.js +18 -8
  291. data/views/mdc/assets/js/components/sliders.js +23 -12
  292. data/views/mdc/assets/js/components/snackbar.js +11 -8
  293. data/views/mdc/assets/js/components/steppers.js +3 -3
  294. data/views/mdc/assets/js/components/switches.js +6 -29
  295. data/views/mdc/assets/js/components/tab-bars.js +18 -4
  296. data/views/mdc/assets/js/components/text-fields.js +94 -22
  297. data/views/mdc/assets/js/components/tooltip.js +17 -0
  298. data/views/mdc/assets/js/components/typography.js +28 -0
  299. data/views/mdc/assets/js/components/uninitialize.js +7 -0
  300. data/views/mdc/assets/js/wc.js +111 -0
  301. data/views/mdc/assets/scss/app.scss +12 -5
  302. data/views/mdc/assets/scss/components/avatar.scss +51 -7
  303. data/views/mdc/assets/scss/components/button.scss +7 -9
  304. data/views/mdc/assets/scss/components/card.scss +6 -5
  305. data/views/mdc/assets/scss/components/chip.scss +4 -0
  306. data/views/mdc/assets/scss/components/content.scss +25 -0
  307. data/views/mdc/assets/scss/components/data-table.scss +12 -1
  308. data/views/mdc/assets/scss/components/datetime.scss +1 -2
  309. data/views/mdc/assets/scss/components/dialog.scss +7 -2
  310. data/views/mdc/assets/scss/components/drag_n_drop.scss +17 -0
  311. data/views/mdc/assets/scss/components/drawer.scss +82 -0
  312. data/views/mdc/assets/scss/components/expansion-panel.scss +2 -2
  313. data/views/mdc/assets/scss/components/fab.scss +23 -5
  314. data/views/mdc/assets/scss/components/file-input.scss +10 -14
  315. data/views/mdc/assets/scss/components/grid.scss +32 -17
  316. data/views/mdc/assets/scss/components/header.scss +21 -0
  317. data/views/mdc/assets/scss/components/icon-button-toggles.scss +2 -0
  318. data/views/mdc/assets/scss/components/icon.scss +23 -0
  319. data/views/mdc/assets/scss/components/image-list.scss +18 -0
  320. data/views/mdc/assets/scss/components/image.scss +13 -21
  321. data/views/mdc/assets/scss/components/list.scss +9 -3
  322. data/views/mdc/assets/scss/components/menu.scss +13 -3
  323. data/views/mdc/assets/scss/components/progress.scss +1 -0
  324. data/views/mdc/assets/scss/components/rich-text-area.scss +38 -2
  325. data/views/mdc/assets/scss/components/select.scss +6 -3
  326. data/views/mdc/assets/scss/components/separator.scss +3 -0
  327. data/views/mdc/assets/scss/components/switch.scss +10 -0
  328. data/views/mdc/assets/scss/components/textfield.scss +8 -4
  329. data/views/mdc/assets/scss/components/tooltip.scss +3 -0
  330. data/views/mdc/assets/scss/components/typography.scss +6 -0
  331. data/views/mdc/assets/scss/components/unordered-lists.scss +17 -0
  332. data/views/mdc/assets/scss/material.blue_grey-orange.min.css +1 -1
  333. data/views/mdc/assets/scss/media.scss +39 -0
  334. data/views/mdc/assets/scss/palette.scss +16 -0
  335. data/views/mdc/assets/scss/styles.scss +39 -1
  336. data/views/mdc/assets/scss/theme.scss +19 -2
  337. data/views/mdc/body/dismissable-drawer.erb +34 -0
  338. data/views/mdc/body/drawer/divider.erb +1 -0
  339. data/views/mdc/body/drawer/item.erb +13 -0
  340. data/views/mdc/body/drawer/label.erb +1 -0
  341. data/views/mdc/body/drawers/menu.erb +1 -1
  342. data/views/mdc/body/footers/menu_item.erb +2 -2
  343. data/views/mdc/body/header.erb +38 -31
  344. data/views/mdc/body/modal-drawer.erb +35 -0
  345. data/views/mdc/body/snackbar.erb +11 -5
  346. data/views/mdc/components/actions/autocomplete.rb +8 -0
  347. data/views/mdc/components/actions/close_dialog.rb +10 -0
  348. data/views/mdc/components/actions/loads.rb +7 -1
  349. data/views/mdc/components/actions/navigates.rb +1 -1
  350. data/views/mdc/components/actions/post.rb +4 -7
  351. data/views/mdc/components/actions/post_message.rb +10 -0
  352. data/views/mdc/components/actions/prompt_if_dirty.rb +17 -0
  353. data/views/mdc/components/actions/replaces.rb +5 -1
  354. data/views/mdc/components/actions/resolver.rb +39 -0
  355. data/views/mdc/components/actions/snackbar.rb +3 -1
  356. data/views/mdc/components/actions/toggle_disabled.rb +10 -0
  357. data/views/mdc/components/avatar.erb +12 -7
  358. data/views/mdc/components/badge.erb +1 -1
  359. data/views/mdc/components/button.erb +2 -3
  360. data/views/mdc/components/buttons/button.erb +12 -12
  361. data/views/mdc/components/buttons/fab.erb +3 -2
  362. data/views/mdc/components/buttons/icon.erb +5 -5
  363. data/views/mdc/components/buttons/image.erb +4 -3
  364. data/views/mdc/components/card.erb +67 -44
  365. data/views/mdc/components/checkbox.erb +32 -35
  366. data/views/mdc/components/chip.erb +38 -30
  367. data/views/mdc/components/chipset.erb +18 -0
  368. data/views/mdc/components/content.erb +35 -14
  369. data/views/mdc/components/datetime.erb +6 -19
  370. data/views/mdc/components/dialog.erb +45 -25
  371. data/views/mdc/components/drag_and_drop/drag_and_drop.rb +16 -0
  372. data/views/mdc/components/event.erb +3 -5
  373. data/views/mdc/components/expansion_panel.erb +8 -6
  374. data/views/mdc/components/file_input.erb +14 -10
  375. data/views/mdc/components/form.erb +4 -19
  376. data/views/mdc/components/grid.erb +20 -17
  377. data/views/mdc/components/hidden_field.erb +3 -4
  378. data/views/mdc/components/icon.erb +7 -5
  379. data/views/mdc/components/icon_toggle.erb +9 -8
  380. data/views/mdc/components/image.erb +23 -5
  381. data/views/mdc/components/image_list.erb +38 -0
  382. data/views/mdc/components/link.erb +3 -13
  383. data/views/mdc/components/list.erb +4 -2
  384. data/views/mdc/components/list/avatar.erb +2 -1
  385. data/views/mdc/components/list/header.erb +5 -3
  386. data/views/mdc/components/list/hidden_field.erb +3 -0
  387. data/views/mdc/components/list/icon.erb +2 -1
  388. data/views/mdc/components/list/line.erb +19 -9
  389. data/views/mdc/components/list/menu.erb +7 -2
  390. data/views/mdc/components/list/separator.erb +1 -1
  391. data/views/mdc/components/menu.erb +14 -6
  392. data/views/mdc/components/number_field.erb +38 -0
  393. data/views/mdc/components/page_title.erb +2 -2
  394. data/views/mdc/components/progress.erb +11 -0
  395. data/views/mdc/components/radio_button.erb +5 -6
  396. data/views/mdc/components/render.erb +2 -3
  397. data/views/mdc/components/rich_text_area.erb +13 -10
  398. data/views/mdc/components/select.erb +28 -12
  399. data/views/mdc/components/separator.erb +3 -0
  400. data/views/mdc/components/shared/hint_error_display.erb +9 -0
  401. data/views/mdc/components/shared/input_label.erb +7 -0
  402. data/views/mdc/components/slider.erb +3 -1
  403. data/views/mdc/components/stepper.erb +1 -1
  404. data/views/mdc/components/stepper/step.erb +1 -1
  405. data/views/mdc/components/switch.erb +8 -7
  406. data/views/mdc/components/tab_bar.erb +7 -1
  407. data/views/mdc/components/table.erb +26 -13
  408. data/views/mdc/components/table/checkbox.erb +6 -3
  409. data/views/mdc/components/table/column.erb +18 -0
  410. data/views/mdc/components/table/footer.erb +8 -0
  411. data/views/mdc/components/table/header.erb +5 -4
  412. data/views/mdc/components/table/pagination.erb +2 -6
  413. data/views/mdc/components/table/row.erb +5 -5
  414. data/views/mdc/components/text_area.erb +9 -11
  415. data/views/mdc/components/text_field.erb +29 -37
  416. data/views/mdc/components/tooltip.erb +2 -2
  417. data/views/mdc/components/typography.erb +7 -5
  418. data/views/mdc/components/unordered_list.erb +10 -0
  419. data/views/mdc/components/unordered_list/icon.erb +3 -0
  420. data/views/mdc/components/unordered_list/list_item.erb +7 -0
  421. data/views/mdc/layout.erb +41 -29
  422. data/views/mdc/package-lock.json +2222 -1327
  423. data/views/mdc/package.json +47 -29
  424. data/views/mdc/web.erb +4 -0
  425. data/views/mdc/webpack.config.js +13 -1
  426. metadata +218 -26
  427. data/lib/voom-presenters.rb +0 -9
  428. data/lib/voom/presenters-engine.rb +0 -44
  429. data/lib/voom/presenters.rb +0 -19
  430. data/public/.gitignore +0 -2
  431. data/scripts/bump.sh +0 -5
  432. data/scripts/changelog.sh +0 -5
  433. data/scripts/deploy-demo.sh +0 -3
  434. data/scripts/release.sh +0 -5
  435. data/scripts/tag.sh +0 -5
  436. data/views/mdc/assets/js/dialog-polyfill.js +0 -738
  437. data/views/mdc/assets/scss/components/icon-toggles.scss +0 -9
  438. data/views/mdc/assets/scss/components/vendor/flatpickr.min.css +0 -13
  439. data/views/mdc/body/drawer.erb +0 -18
  440. data/views/mdc/components/google_map.erb +0 -9
data/config.ru CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
- if ENV['VOOM_ENV']=='integration_testing'
2
+ if ENV['VOOM_ENV'] == 'integration_testing'
3
3
  require 'simplecov'
4
4
  if ENV['CIRCLE_ARTIFACTS']
5
5
  dir = File.join(ENV['CIRCLE_ARTIFACTS'], "coverage")
@@ -10,22 +10,32 @@ end
10
10
 
11
11
  ENV['VOOM_ROOT'] = File.expand_path(__dir__)
12
12
  ENV['GOOGLE_API_KEY'] = 'AIzaSyDhSgj9XSBLY5E9Rx5pP2ILQ7IXnD4uX2Q'
13
- libdir = File.join(ENV['VOOM_ROOT'], 'lib')
14
- $:.unshift(libdir) unless $:.include?(libdir)
15
- require 'voom/presenters/api/app'
16
- require 'voom/presenters/web_client/app'
17
- require 'voom/presenters/demo/search'
18
- require 'voom/presenters/demo/echo'
13
+ require 'voom'
14
+
15
+ require 'rack/cors'
16
+ use Rack::Cors do
17
+ allow do
18
+ origins '*'
19
+ resource '*', headers: :any, methods: [:get, :post, :options]
20
+ end
21
+ end
22
+
23
+ Voom::Presenters::Settings.configure do |config|
24
+ config.presenters.root = File.join(ENV['VOOM_ROOT'], 'app')
25
+ config.presenters.web_client.prepare_context << ->(context, session, _env) {
26
+ context.merge(session: session)
27
+ }
28
+ end
19
29
 
20
30
  use Voom::Presenters::Demo::Search
21
31
  use Voom::Presenters::Demo::Echo
32
+ use Voom::Presenters::Demo::Slow
33
+ use Voom::Presenters::Demo::DragonDrop
22
34
 
23
35
  use Voom::Presenters::WebClient::App
24
36
  run Voom::Presenters::Api::App
25
37
 
26
- Voom::Presenters::Settings.configure do |config|
27
- config.presenters.root = File.join(ENV['VOOM_ROOT'], 'app')
28
- end
38
+
29
39
  Voom::Presenters::App.boot!
30
40
 
31
41
 
@@ -0,0 +1,81 @@
1
+ # Configuration
2
+ Presenters can be configured via settings set in e.g. Rails initializers.
3
+
4
+ ## Overview
5
+ Configuration is handled via [dry-configurable](https://github.com/dry-rb/dry-configurable).
6
+
7
+ ```ruby
8
+ Voom::Presenters::Settings.configure do |config|
9
+ config.presenters.helpers << SomeHelperClass
10
+ end
11
+ ```
12
+
13
+ ## Table of Contents
14
+ * [`before_render`](#before_render)
15
+
16
+ ## Settings
17
+ ### `before_render`
18
+ `before_render` is an array of things which respond to `#call/1`. The items in
19
+ the array are lazily invoked with the current request prior to a Presenter
20
+ being rendered.
21
+
22
+ If an item returns a non-`nil` Presenter name, this Presenter will be rendered
23
+ instead of the Presenter that was about to be rendered. In this case, subsequent
24
+ `before_render` items will not be invoked.
25
+
26
+ ```ruby
27
+ # request: /foos/foo?id=1
28
+
29
+ Voom::Presenters::Settings.configure do |config|
30
+ config.presenters.before_render << lambda do |req|
31
+ if some_predicate?
32
+ return :render_me_instead
33
+ # /render_me_instead?id=1 will be rendered instead of /foos/foo?id=1.
34
+ end
35
+
36
+ # return nil will not intercept rendering and the next lambda will be
37
+ # invoked.
38
+ end
39
+
40
+ # this lambda will be invoked only if all previous lambdas returned nil.
41
+ config.presenters.before_render << lambda do |req|
42
+ puts 'if you see me, some_predicate? returned true'
43
+
44
+ # return nil will not intercept rendering and the next lambda will be
45
+ # invoked.
46
+ end
47
+ end
48
+ ```
49
+
50
+ If all items return `nil`, the original Presenter is rendered unintercepted.
51
+
52
+ #### Returning context
53
+
54
+ A `before_render` item may optionally return a context hash. This hash will be
55
+ passed to the rendered presenter and merged with existing context at render
56
+ time. **Key names in a returned context hash will overwrite the request's
57
+ context, so use with caution.**
58
+
59
+ ```ruby
60
+ # request: /foos/foo?id=1
61
+
62
+ class AuthenticationCheck
63
+ def initialize; end
64
+
65
+ def call(req)
66
+ unless authenticated?(req)
67
+ return ['auth:login', { timestamp: Time.current.to_i }]
68
+ # /auth/login?id=1&timestamp=1579535489 will be rendered instead of
69
+ # /foos/foo?id=1.
70
+ # /auth/login will have context { id: 1, timestamp: 1579535489 }
71
+ end
72
+
73
+ # return nil will not intercept rendering and the next lambda will be
74
+ # invoked.
75
+ end
76
+ end
77
+
78
+ Voom::Presenters::Settings.configure do |config|
79
+ config.presenters.before_render << AuthenticationCheck.new
80
+ end
81
+ ```
@@ -0,0 +1,14 @@
1
+ module HashExt
2
+ module Traverse
3
+ def self.traverse(hash, &block)
4
+ hash.inject({}) do |h,(k,v)|
5
+ if Hash === v
6
+ v = traverse(v,&block)
7
+ end
8
+ nk, nv = block.call(k,v)
9
+ h[nk] = nv unless nk.nil?
10
+ h
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,25 @@
1
+ require 'zeitwerk'
2
+
3
+ class MyInflector < Zeitwerk::GemInflector
4
+ def camelize(basename, _abspath)
5
+ case basename
6
+ when "dsl"
7
+ "DSL"
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+
14
+ loader = Zeitwerk::Loader.for_gem
15
+ loader.inflector = MyInflector.new(__FILE__)
16
+ #loader.logger = Logger.new($stderr)
17
+ loader.setup
18
+
19
+ module Voom
20
+ end
21
+
22
+ if defined?(::Rails)
23
+ # loader.logger = Rails.logger
24
+ load 'voom/railtie.rb'
25
+ end
@@ -1,8 +1,8 @@
1
- require 'voom/symbol/to_str'
1
+ require 'dry-container'
2
2
 
3
3
  module Voom
4
4
  module ContainerMethods
5
- include Voom::Symbol
5
+ include Voom::Symbol::ToStr
6
6
 
7
7
  def registered_keys
8
8
  @registered_keys ||= []
@@ -0,0 +1,5 @@
1
+ module Voom
2
+ class Engine < ::Rails::Engine
3
+ config.eager_load_paths += Dir["#{config.root}/lib"]
4
+ end
5
+ end
@@ -1,7 +1,6 @@
1
1
  require 'sinatra'
2
+ require 'honeybadger' if ENV.fetch('HONEYBADGER_API_KEY'){false}
2
3
  require 'json'
3
- require 'voom/presenters'
4
- require 'voom/presenters/api/router'
5
4
 
6
5
  module Voom
7
6
  module Presenters
@@ -31,23 +30,44 @@ module Voom
31
30
 
32
31
  private
33
32
 
33
+ # analogous to Voom::Presenters::WebClient::App#render_presenter
34
34
  def render_presenter(presenter)
35
- # puts "/presenters/api/#{params[:version]}/#{params[:presenter]}/"
36
- # puts "Parameters: #{params.inspect}"
37
- presenter = Voom::Presenters::App[presenter].call
38
- pom = presenter.expand(router: router, context: prepare_context)
39
- content_type :json
40
- JSON.dump(pom.to_hash)
35
+ begin
36
+ before_render = Presenters::Settings.config.presenters.before_render
37
+ render_instead, ctx = before_render
38
+ .lazy
39
+ .map { |p| p.call(request) }
40
+ .detect(&:itself)
41
+
42
+ if Presenters::App.registered?(render_instead)
43
+ presenter = render_instead
44
+ end
45
+
46
+ p = params.merge(ctx || {})
47
+ presenter = Voom::Presenters::App[presenter].call
48
+ pom = presenter.expand(router: router, context: prepare_context(p))
49
+ content_type :json
50
+ JSON.dump(pom.to_hash)
51
+ rescue StandardError => e
52
+ presenter_name = presenter.respond_to?(:name) ? presenter.name : '(unknown)'
53
+ Presenters::Settings.config.presenters.error_logger.call(
54
+ @env['rack.errors'],
55
+ e,
56
+ params,
57
+ presenter_name
58
+ )
59
+ raise e
60
+ end
41
61
  end
42
62
 
43
63
  def router
44
64
  settings.router_.new(base_url: "#{request.base_url}#{env['SCRIPT_NAME']}")
45
65
  end
46
66
 
47
- def prepare_context
67
+ def prepare_context(base_params = params)
48
68
  prepare_context = Presenters::Settings.config.presenters.web_client.prepare_context.dup
49
69
  prepare_context.push(method(:scrub_context))
50
- context = params.dup
70
+ context = base_params.dup
51
71
  prepare_context.reduce(context) do |params, context_proc|
52
72
  context_proc.call(params, session, env)
53
73
  end
@@ -63,4 +83,4 @@ module Voom
63
83
  end
64
84
  end
65
85
  end
66
- end
86
+ end
@@ -1,56 +1,10 @@
1
- require 'rack'
1
+ require 'voom/presenters/router'
2
2
 
3
3
  module Voom
4
4
  module Presenters
5
5
  module Api
6
- class Router
7
-
8
- attr_reader :base_url
9
-
10
- def initialize(base_url: nil)
11
- @base_url = base_url
12
- end
13
-
14
- def url(command: nil, render: nil, context:)
15
- _params_ = context.dup
16
- return build_render_url(render, _params_) unless command
17
- _params_[:redirect]=build_render_url(render, _params_) if render
18
- build_command_url(command, _params_)
19
- end
20
-
21
- def scrub_params(_params_)
22
- _params_.delete('presenter')
23
- _params_.delete('action')
24
- _params_.delete('errors')
25
- _params_
26
- end
27
-
28
- private
29
-
30
- def build_command_url(command, params)
31
- return '' unless command
32
- seperator = command.include?('?') ? '&' : '?'
33
- "#{command}#{seperator}#{build_params(params)}"
34
- end
35
-
36
- def build_render_url(render_, params)
37
- return '#' unless render_
38
- render = render_.to_s
39
- return render if render.start_with?('http')
40
- seperator = render.start_with?('/') ? '' : '/'
41
- url = "#{base_url}#{seperator}#{render}"
42
- query_params = build_params(params)
43
- if(query_params)
44
- query_seperator = render.include?('?') ? '&' : '?'
45
- url = "#{url}#{query_seperator}#{query_params}"
46
- end
47
- url
48
- end
49
-
50
- def build_params(params)
51
- Rack::Utils.build_nested_query(scrub_params(params))
52
- end
6
+ class Router < Presenters::Router
53
7
  end
54
8
  end
55
9
  end
56
- end
10
+ end
@@ -34,13 +34,13 @@ module Voom
34
34
  def load(dir='app', root=ENV['VOOM_ROOT']||File.expand_path("../../../", __FILE__))
35
35
  path = File.expand_path(dir, root)
36
36
  trace {"Loading Presenters from: #{path}"}
37
- Presenters::DSL.load(File.expand_path(dir, root))
38
- Presenters::DSL.finalize
37
+ Presenters::Registry.load(File.expand_path(dir, root))
38
+ Presenters::Registry.finalize
39
39
  end
40
40
 
41
41
  def reset!
42
42
  super
43
- Presenters::DSL.reset!
43
+ Presenters::Registry.reset!
44
44
  end
45
45
 
46
46
  private
@@ -0,0 +1,28 @@
1
+ require 'thor'
2
+ require_relative 'generators/plugin'
3
+
4
+ module Voom
5
+ module Presenters
6
+ class SubCommandBase < Thor
7
+ def self.banner(command, namespace = nil, subcommand = false)
8
+ "#{basename} #{subcommand_prefix} #{command.usage}"
9
+ end
10
+
11
+ def self.subcommand_prefix
12
+ self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
13
+ end
14
+ end
15
+
16
+ class Generate < SubCommandBase
17
+ desc "plugin", "generates a plugin"
18
+ def plugin(name)
19
+ Generators::Plugin.start([name])
20
+ end
21
+ end
22
+ class Cli < Thor
23
+ desc "generate", "generate a plugin"
24
+ subcommand "generate", Generate
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,48 @@
1
+ require 'sinatra/base'
2
+
3
+ module Voom
4
+ module Presenters
5
+ module Demo
6
+ class DragonDrop < Sinatra::Base
7
+ include Voom::Presenters::WebClient::Helpers::ExpandHash
8
+
9
+ configure do
10
+ enable :sessions
11
+ set :session_secret, '0e53ba1da13aa8eb8cf3d361e67b70d79265edca'
12
+ end
13
+
14
+ post('/_dragon_drop_change_order_') do
15
+ content_type :json
16
+ source_id = JSON.parse(params[:source_id]) if params[:source_id]
17
+ target_id = JSON.parse(params[:target_id]) if params[:target_id]
18
+ dragons = fetch_dragons
19
+ unless source_id == target_id
20
+ source = dragons.select {|d| d.id == source_id}.first
21
+ target = dragons.select {|d| d.id == target_id}.first
22
+
23
+ if source && target
24
+ starting_sort = target.sort
25
+ source.sort = starting_sort
26
+ dragons.each do |dragon|
27
+ next if dragon.id == source.id || dragon.sort < starting_sort
28
+ dragon.sort += 1
29
+ end
30
+ end
31
+ save(dragons)
32
+ end
33
+ end
34
+
35
+ def fetch_dragons
36
+ JSON.parse(session[:dragons], object_class: OpenStruct)
37
+ end
38
+
39
+ def save(dragons)
40
+ session[:dragons] = dragons.map {|d| expand_hash(d)}.to_json
41
+ end
42
+
43
+ # start the server if ruby file executed directly
44
+ run! if app_file == $0
45
+ end
46
+ end
47
+ end
48
+ end
@@ -8,6 +8,8 @@ module Voom
8
8
  class Echo < Sinatra::Base
9
9
  post('/_echo_') do
10
10
  content_type :json
11
+ params[:echo] = JSON.parse(params[:echo]) if params[:echo]
12
+ status(params[:status]) if params[:status]
11
13
  JSON.dump(params)
12
14
  end
13
15
 
@@ -0,0 +1,18 @@
1
+ require 'sinatra/base'
2
+
3
+ module Voom
4
+ module Presenters
5
+ module Demo
6
+ class Slow < Sinatra::Base
7
+ post('/_slow_') do
8
+ sleep(Integer(params.fetch('seconds',5)))
9
+ content_type :json
10
+ JSON.dump(params)
11
+ end
12
+
13
+ # start the server if ruby file executed directly
14
+ run! if app_file == $0
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Voom
2
+ module Presenters
3
+ module DSL
4
+ module Components
5
+ module Actions
6
+ class Autocomplete < Actions::Base
7
+ def initialize(**attribs_, &block)
8
+ super(type: :autocomplete, **attribs_, &block)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end