matestack-ui-core 0.7.2.1 → 1.0.0.rc.1

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 (265) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +8 -0
  3. data/README.md +28 -204
  4. data/Rakefile +32 -0
  5. data/app/concepts/matestack/ui/core/abbr/abbr.haml +2 -2
  6. data/app/concepts/matestack/ui/core/abbr/abbr.rb +3 -2
  7. data/app/concepts/matestack/ui/core/action/action.js +114 -11
  8. data/app/concepts/matestack/ui/core/action/action.rb +41 -13
  9. data/app/concepts/matestack/ui/core/{component/response_dynamic.haml → actionview/dynamic.haml} +2 -3
  10. data/app/concepts/matestack/ui/core/actionview/dynamic.rb +28 -0
  11. data/app/concepts/matestack/ui/core/{component → actionview}/static.haml +0 -0
  12. data/app/concepts/matestack/ui/core/actionview/static.rb +28 -0
  13. data/app/concepts/matestack/ui/core/address/address.haml +2 -2
  14. data/app/concepts/matestack/ui/core/address/address.rb +1 -1
  15. data/app/concepts/matestack/ui/core/app/app.haml +2 -3
  16. data/app/concepts/matestack/ui/core/app/app.js +18 -4
  17. data/app/concepts/matestack/ui/core/app/app.rb +34 -81
  18. data/app/concepts/matestack/ui/core/app/location.js +9 -0
  19. data/app/concepts/matestack/ui/core/app/store.js +35 -6
  20. data/app/concepts/matestack/ui/core/area/area.haml +1 -0
  21. data/app/concepts/matestack/ui/core/area/area.rb +20 -0
  22. data/app/concepts/matestack/ui/core/aside/aside.haml +3 -0
  23. data/app/concepts/matestack/ui/core/aside/aside.rb +5 -0
  24. data/app/concepts/matestack/ui/core/async/async.haml +6 -2
  25. data/app/concepts/matestack/ui/core/async/async.js +64 -8
  26. data/app/concepts/matestack/ui/core/async/async.rb +29 -4
  27. data/app/concepts/matestack/ui/core/async/children_wrapper.haml +2 -0
  28. data/app/concepts/matestack/ui/core/{pg/pg.haml → b/b.haml} +1 -1
  29. data/app/concepts/matestack/ui/core/b/b.rb +5 -0
  30. data/app/concepts/matestack/ui/core/bdi/bdi.haml +5 -0
  31. data/app/concepts/matestack/ui/core/bdi/bdi.rb +4 -0
  32. data/app/concepts/matestack/ui/core/bdo/bdo.haml +5 -0
  33. data/app/concepts/matestack/ui/core/bdo/bdo.rb +11 -0
  34. data/app/concepts/matestack/ui/core/cite/cite.haml +5 -0
  35. data/app/concepts/matestack/ui/core/cite/cite.rb +5 -0
  36. data/app/concepts/matestack/ui/core/code/code.haml +5 -0
  37. data/app/concepts/matestack/ui/core/code/code.rb +5 -0
  38. data/app/concepts/matestack/ui/core/collection/content/content.js +4 -4
  39. data/app/concepts/matestack/ui/core/collection/content/content.rb +2 -2
  40. data/app/concepts/matestack/ui/core/collection/content/page/link/link.rb +4 -2
  41. data/app/concepts/matestack/ui/core/collection/filter/filter.js +3 -3
  42. data/app/concepts/matestack/ui/core/collection/filter/filter.rb +4 -5
  43. data/app/concepts/matestack/ui/core/collection/filter/select/select.haml +10 -0
  44. data/app/concepts/matestack/ui/core/collection/filter/select/select.rb +29 -0
  45. data/app/concepts/matestack/ui/core/collection/helper.rb +14 -6
  46. data/app/concepts/matestack/ui/core/collection/order/order.js +4 -4
  47. data/app/concepts/matestack/ui/core/collection/order/order.rb +4 -5
  48. data/app/concepts/matestack/ui/core/collection/order/toggle/indicator/indicator.rb +6 -5
  49. data/app/concepts/matestack/ui/core/component/anonym-dynamic-component.js +1 -1
  50. data/app/concepts/matestack/ui/core/component/base.rb +424 -0
  51. data/app/concepts/matestack/ui/core/component/children.haml +2 -2
  52. data/app/concepts/matestack/ui/core/component/component.js +1 -55
  53. data/app/concepts/matestack/ui/core/component/dynamic.haml +1 -1
  54. data/app/concepts/matestack/ui/core/component/dynamic.rb +24 -239
  55. data/app/concepts/matestack/ui/core/component/rerender.rb +8 -0
  56. data/app/concepts/matestack/ui/core/component/static.rb +3 -12
  57. data/app/concepts/matestack/ui/core/data/data.haml +5 -0
  58. data/app/concepts/matestack/ui/core/data/data.rb +9 -0
  59. data/app/concepts/matestack/ui/core/datalist/datalist.haml +3 -0
  60. data/app/concepts/matestack/ui/core/datalist/datalist.rb +5 -0
  61. data/app/concepts/matestack/ui/core/dd/dd.haml +5 -0
  62. data/app/concepts/matestack/ui/core/dd/dd.rb +5 -0
  63. data/app/concepts/matestack/ui/core/del/del.haml +5 -0
  64. data/app/concepts/matestack/ui/core/del/del.rb +4 -0
  65. data/app/concepts/matestack/ui/core/dfn/dfn.haml +5 -0
  66. data/app/concepts/matestack/ui/core/dfn/dfn.rb +6 -0
  67. data/app/concepts/matestack/ui/core/dialog/dialog.haml +5 -0
  68. data/app/concepts/matestack/ui/core/dialog/dialog.rb +9 -0
  69. data/app/concepts/matestack/ui/core/dl/dl.haml +5 -0
  70. data/app/concepts/matestack/ui/core/dl/dl.rb +5 -0
  71. data/app/concepts/matestack/ui/core/dt/dt.haml +5 -0
  72. data/app/concepts/matestack/ui/core/dt/dt.rb +5 -0
  73. data/app/concepts/matestack/ui/core/em/em.haml +5 -0
  74. data/app/concepts/matestack/ui/core/em/em.rb +5 -0
  75. data/app/concepts/matestack/ui/core/fieldset/fieldset.haml +5 -0
  76. data/app/concepts/matestack/ui/core/fieldset/fieldset.rb +9 -0
  77. data/app/concepts/matestack/ui/core/figure/figure.haml +3 -0
  78. data/app/concepts/matestack/ui/core/figure/figure.rb +5 -0
  79. data/app/concepts/matestack/ui/core/form/checkbox/checkbox.rb +79 -0
  80. data/app/concepts/matestack/ui/core/form/form.js +266 -96
  81. data/app/concepts/matestack/ui/core/form/form.rb +29 -2
  82. data/app/concepts/matestack/ui/core/form/has_errors.rb +54 -0
  83. data/app/concepts/matestack/ui/core/form/has_input_html_attributes.rb +13 -0
  84. data/app/concepts/matestack/ui/core/form/input/input.rb +39 -52
  85. data/app/concepts/matestack/ui/core/form/radio/radio.rb +71 -0
  86. data/app/concepts/matestack/ui/core/form/select/select.haml +9 -76
  87. data/app/concepts/matestack/ui/core/form/select/select.rb +64 -49
  88. data/app/concepts/matestack/ui/core/form/submit/submit.rb +4 -1
  89. data/app/concepts/matestack/ui/core/form/textarea/textarea.rb +28 -0
  90. data/app/concepts/matestack/ui/core/form/utils.rb +47 -0
  91. data/app/concepts/matestack/ui/core/heading/heading.rb +2 -0
  92. data/app/concepts/matestack/ui/core/iframe/iframe.haml +5 -0
  93. data/app/concepts/matestack/ui/core/iframe/iframe.rb +14 -0
  94. data/app/concepts/matestack/ui/core/img/img.rb +1 -0
  95. data/app/concepts/matestack/ui/core/input/input.haml +1 -3
  96. data/app/concepts/matestack/ui/core/input/input.rb +8 -0
  97. data/app/concepts/matestack/ui/core/ins/ins.haml +5 -0
  98. data/app/concepts/matestack/ui/core/ins/ins.rb +10 -0
  99. data/app/concepts/matestack/ui/core/isolated/children_wrapper.haml +2 -0
  100. data/app/concepts/matestack/ui/core/isolated/isolated.haml +10 -0
  101. data/app/concepts/matestack/ui/core/isolated/isolated.js +108 -0
  102. data/app/concepts/matestack/ui/core/isolated/isolated.rb +59 -0
  103. data/app/concepts/matestack/ui/core/js/core.js +43 -19
  104. data/app/concepts/matestack/ui/core/kbd/kbd.haml +5 -0
  105. data/app/concepts/matestack/ui/core/kbd/kbd.rb +4 -0
  106. data/app/concepts/matestack/ui/core/label/label.rb +6 -1
  107. data/app/concepts/matestack/ui/core/legend/legend.haml +5 -0
  108. data/app/concepts/matestack/ui/core/legend/legend.rb +5 -0
  109. data/app/concepts/matestack/ui/core/link/link.rb +7 -6
  110. data/app/concepts/matestack/ui/core/{absolute/absolute.haml → map/map.haml} +1 -1
  111. data/app/concepts/matestack/ui/core/map/map.rb +11 -0
  112. data/app/concepts/matestack/ui/core/mark/mark.haml +5 -0
  113. data/app/concepts/matestack/ui/core/mark/mark.rb +4 -0
  114. data/app/concepts/matestack/ui/core/meter/meter.haml +4 -0
  115. data/app/concepts/matestack/ui/core/meter/meter.rb +14 -0
  116. data/app/concepts/matestack/ui/core/noscript/noscript.haml +5 -0
  117. data/app/concepts/matestack/ui/core/noscript/noscript.rb +5 -0
  118. data/app/concepts/matestack/ui/core/object/object.haml +1 -0
  119. data/app/concepts/matestack/ui/core/object/object.rb +15 -0
  120. data/app/concepts/matestack/ui/core/onclick/onclick.js +2 -3
  121. data/app/concepts/matestack/ui/core/onclick/onclick.rb +1 -0
  122. data/app/concepts/matestack/ui/core/optgroup/optgroup.haml +3 -0
  123. data/app/concepts/matestack/ui/core/optgroup/optgroup.rb +10 -0
  124. data/app/concepts/matestack/ui/core/option/option.haml +5 -0
  125. data/app/concepts/matestack/ui/core/option/option.rb +12 -0
  126. data/app/concepts/matestack/ui/core/output/output.haml +5 -0
  127. data/app/concepts/matestack/ui/core/output/output.rb +11 -0
  128. data/app/concepts/matestack/ui/core/page/{content.js → content/content.js} +8 -2
  129. data/app/concepts/matestack/ui/core/page/content/content.rb +29 -0
  130. data/app/concepts/matestack/ui/core/page/page.haml +3 -9
  131. data/app/concepts/matestack/ui/core/page/page.rb +15 -160
  132. data/app/concepts/matestack/ui/core/param/param.haml +1 -0
  133. data/app/concepts/matestack/ui/core/param/param.rb +10 -0
  134. data/app/concepts/matestack/ui/core/picture/picture.haml +3 -0
  135. data/app/concepts/matestack/ui/core/picture/picture.rb +4 -0
  136. data/app/concepts/matestack/ui/core/plain/plain.rb +1 -1
  137. data/app/concepts/matestack/ui/core/pre/pre.haml +5 -0
  138. data/app/concepts/matestack/ui/core/pre/pre.rb +5 -0
  139. data/app/concepts/matestack/ui/core/progress/progress.rb +1 -1
  140. data/app/concepts/matestack/ui/core/q/q.haml +5 -0
  141. data/app/concepts/matestack/ui/core/q/q.rb +11 -0
  142. data/app/concepts/matestack/ui/core/rp/rp.haml +5 -0
  143. data/app/concepts/matestack/ui/core/rp/rp.rb +5 -0
  144. data/app/concepts/matestack/ui/core/rt/rt.haml +5 -0
  145. data/app/concepts/matestack/ui/core/rt/rt.rb +5 -0
  146. data/app/concepts/matestack/ui/core/ruby/ruby.haml +5 -0
  147. data/app/concepts/matestack/ui/core/ruby/ruby.rb +5 -0
  148. data/app/concepts/matestack/ui/core/s/s.haml +5 -0
  149. data/app/concepts/matestack/ui/core/s/s.rb +6 -0
  150. data/app/concepts/matestack/ui/core/samp/samp.haml +5 -0
  151. data/app/concepts/matestack/ui/core/samp/samp.rb +4 -0
  152. data/app/concepts/matestack/ui/core/slot/slot.rb +2 -2
  153. data/app/concepts/matestack/ui/core/sup/sup.haml +5 -0
  154. data/app/concepts/matestack/ui/core/sup/sup.rb +5 -0
  155. data/app/concepts/matestack/ui/core/template/template.haml +3 -0
  156. data/app/concepts/matestack/ui/core/template/template.rb +4 -0
  157. data/app/concepts/matestack/ui/core/textarea/textarea.haml +2 -0
  158. data/app/concepts/matestack/ui/core/textarea/textarea.rb +10 -0
  159. data/app/concepts/matestack/ui/core/toggle/toggle.haml +2 -0
  160. data/app/concepts/matestack/ui/core/toggle/toggle.js +71 -0
  161. data/app/concepts/matestack/ui/core/toggle/toggle.rb +14 -0
  162. data/app/concepts/matestack/ui/core/transition/transition.js +18 -2
  163. data/app/concepts/matestack/ui/core/transition/transition.rb +2 -1
  164. data/app/concepts/matestack/ui/core/u/u.haml +5 -0
  165. data/app/concepts/matestack/ui/core/u/u.rb +6 -0
  166. data/app/concepts/matestack/ui/core/unescaped/unescaped.rb +7 -0
  167. data/app/concepts/matestack/ui/core/var/var.haml +5 -0
  168. data/app/concepts/matestack/ui/core/var/var.rb +4 -0
  169. data/app/concepts/matestack/ui/core/video/video.haml +3 -1
  170. data/app/concepts/matestack/ui/core/video/video.rb +17 -1
  171. data/app/concepts/matestack/ui/core/view/view.haml +1 -2
  172. data/app/concepts/matestack/ui/core/view/view.rb +27 -2
  173. data/app/concepts/matestack/ui/core/wbr/wbr.haml +1 -0
  174. data/app/concepts/matestack/ui/core/wbr/wbr.rb +4 -0
  175. data/app/concepts/matestack/ui/core/youtube/youtube.rb +1 -1
  176. data/app/helpers/matestack/ui/core/application_helper.rb +89 -17
  177. data/app/javascript/matestack-ui-core/index.js +22 -0
  178. data/app/javascript/matestack-ui-core/styles/index.scss +5 -0
  179. data/app/javascript/packs/matestack-ui-core.js +8 -0
  180. data/app/lib/matestack/ui/component.rb +1 -0
  181. data/app/lib/matestack/ui/core/has_view_context.rb +14 -0
  182. data/app/lib/matestack/ui/core/html_attributes.rb +43 -0
  183. data/app/lib/matestack/ui/core/properties.rb +88 -0
  184. data/app/lib/matestack/ui/core/rendering/default_renderer_class_determiner.rb +33 -0
  185. data/app/lib/matestack/ui/core/rendering/main_renderer.rb +199 -0
  186. data/app/lib/matestack/ui/dynamic_actionview_component.rb +1 -0
  187. data/app/lib/matestack/ui/isolated_component.rb +1 -0
  188. data/app/lib/matestack/ui/static_actionview_component.rb +1 -0
  189. data/app/lib/matestack/ui/vue_js_component.rb +1 -0
  190. data/config/routes.rb +0 -1
  191. data/lib/generators/matestack/app/USAGE +21 -0
  192. data/lib/generators/matestack/app/app_generator.rb +25 -0
  193. data/lib/generators/{matestack_app/templates/matestack_app_controller.erb → matestack/app/templates/app/controllers/%file_name%_controller.rb.tt} +0 -2
  194. data/lib/generators/matestack/app/templates/app/matestack/apps/%file_name%.rb.tt +28 -0
  195. data/lib/generators/matestack/component/USAGE +20 -0
  196. data/lib/generators/matestack/component/component_generator.rb +29 -0
  197. data/lib/generators/{matestack_component/templates/matestack_component.haml.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.haml.tt} +0 -0
  198. data/lib/generators/{matestack_component/templates/matestack_component.js.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.js.tt} +2 -2
  199. data/lib/generators/matestack/component/templates/app/matestack/components/%namespace%/%file_name%.rb.tt +11 -0
  200. data/lib/generators/{matestack_component/templates/matestack_component.scss.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.scss.tt} +0 -0
  201. data/lib/generators/matestack/core/component/USAGE +16 -0
  202. data/lib/generators/matestack/core/component/component_generator.rb +23 -0
  203. data/lib/generators/matestack/core/component/templates/app/concepts/matestack/ui/core/%file_name%/%file_name%.haml.tt +5 -0
  204. data/lib/generators/matestack/core/component/templates/app/concepts/matestack/ui/core/%file_name%/%file_name%.rb.tt +4 -0
  205. data/lib/generators/matestack/core/component/templates/docs/components/%file_name%.md.tt +45 -0
  206. data/lib/generators/matestack/core/component/templates/spec/usage/components/%file_name%_spec.rb +31 -0
  207. data/lib/generators/matestack/page/USAGE +28 -0
  208. data/lib/generators/matestack/page/page_generator.rb +54 -0
  209. data/lib/generators/matestack/page/templates/app/matestack/pages/%app_name%/%namespace%/%file_name%.rb.tt +29 -0
  210. data/lib/matestack/ui/core.rb +5 -2
  211. data/lib/matestack/ui/core/cell.rb +31 -0
  212. data/lib/matestack/ui/core/component/registry.rb +47 -0
  213. data/lib/matestack/ui/core/components.rb +267 -0
  214. data/lib/matestack/ui/core/dsl.rb +6 -0
  215. data/lib/matestack/ui/core/engine.rb +16 -0
  216. data/lib/matestack/ui/core/version.rb +1 -1
  217. data/vendor/assets/javascripts/dist/manifest.json +18 -0
  218. data/vendor/assets/javascripts/dist/manifest.json.br +0 -0
  219. data/vendor/assets/javascripts/dist/manifest.json.gz +0 -0
  220. data/vendor/assets/javascripts/dist/matestack-ui-core.css +3 -0
  221. data/vendor/assets/javascripts/dist/matestack-ui-core.css.map +1 -0
  222. data/vendor/assets/javascripts/dist/matestack-ui-core.js +17060 -0
  223. data/vendor/assets/javascripts/dist/matestack-ui-core.js.map +1 -0
  224. data/vendor/assets/javascripts/dist/matestack-ui-core.min.css +0 -0
  225. data/vendor/assets/javascripts/dist/matestack-ui-core.min.js +3 -0
  226. data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.LICENSE.txt +18 -0
  227. data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.gz +0 -0
  228. data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.map +1 -0
  229. data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.map.gz +0 -0
  230. data/vendor/assets/javascripts/matestack-ui-core.js.erb +2 -0
  231. data/vendor/assets/stylesheets/dist +1 -0
  232. data/vendor/assets/stylesheets/matestack-ui-core.css.erb +2 -0
  233. metadata +188 -89
  234. data/MIT-LICENSE +0 -20
  235. data/app/concepts/matestack/ui/core/absolute/absolute.rb +0 -17
  236. data/app/concepts/matestack/ui/core/component/response.haml +0 -2
  237. data/app/concepts/matestack/ui/core/component/response_dynamic_without_rerender.haml +0 -3
  238. data/app/concepts/matestack/ui/core/form/inline/inline.haml +0 -6
  239. data/app/concepts/matestack/ui/core/form/inline/inline.rb +0 -9
  240. data/app/concepts/matestack/ui/core/form/input/input.haml +0 -27
  241. data/app/concepts/matestack/ui/core/html/html.haml +0 -3
  242. data/app/concepts/matestack/ui/core/html/html.js +0 -10
  243. data/app/concepts/matestack/ui/core/html/html.rb +0 -17
  244. data/app/concepts/matestack/ui/core/isolate/isolate.haml +0 -2
  245. data/app/concepts/matestack/ui/core/isolate/isolate.rb +0 -11
  246. data/app/concepts/matestack/ui/core/page/content.haml +0 -7
  247. data/app/concepts/matestack/ui/core/page/content.rb +0 -5
  248. data/app/concepts/matestack/ui/core/pg/pg.rb +0 -5
  249. data/app/concepts/matestack/ui/core/view/view.js +0 -42
  250. data/app/lib/matestack/ui/core/app_node.rb +0 -53
  251. data/app/lib/matestack/ui/core/component_node.rb +0 -73
  252. data/app/lib/matestack/ui/core/page_node.rb +0 -96
  253. data/app/lib/matestack/ui/core/to_cell.rb +0 -129
  254. data/lib/generators/matestack_app/USAGE +0 -21
  255. data/lib/generators/matestack_app/matestack_app_generator.rb +0 -26
  256. data/lib/generators/matestack_app/templates/matestack_app.erb +0 -26
  257. data/lib/generators/matestack_component/USAGE +0 -20
  258. data/lib/generators/matestack_component/matestack_component_generator.rb +0 -30
  259. data/lib/generators/matestack_component/templates/matestack_component.rb.erb +0 -13
  260. data/lib/generators/matestack_page/USAGE +0 -28
  261. data/lib/generators/matestack_page/matestack_page_generator.rb +0 -41
  262. data/lib/generators/matestack_page/templates/matestack_page.erb +0 -15
  263. data/vendor/assets/javascripts/manifest.json +0 -4
  264. data/vendor/assets/javascripts/matestack-ui-core.js +0 -15309
  265. data/vendor/assets/javascripts/matestack-ui-core.js.map +0 -1
@@ -1,16 +1,15 @@
1
1
  module Matestack::Ui::Core::Collection::Order
2
2
  class Order < Matestack::Ui::Core::Component::Dynamic
3
+ vue_js_component_name 'matestack-ui-core-collection-order'
3
4
 
4
5
  def setup
5
6
  @component_config = @component_config.except(:data, :paginated_data)
6
7
  end
7
8
 
8
9
  def response
9
- components {
10
- div @tag_attributes do
11
- yield_components
12
- end
13
- }
10
+ div @tag_attributes do
11
+ yield_components
12
+ end
14
13
  end
15
14
 
16
15
  end
@@ -2,11 +2,12 @@ module Matestack::Ui::Core::Collection::Order::Toggle::Indicator
2
2
  class Indicator < Matestack::Ui::Core::Component::Static
3
3
 
4
4
  def response
5
- components {
6
- span @tag_attributes do
7
- plain "{{orderIndicator( '#{@component_config[:key]}', {asc: '#{@component_config[:asc]}', desc: '#{@component_config[:desc]}'} ) }}"
8
- end
9
- }
5
+ span @tag_attributes do
6
+ span attributes: {"v-if": "ordering['#{@component_config[:key]}'] === undefined"}, text: @component_config[:default]
7
+ unescaped "{{
8
+ orderIndicator('#{@component_config[:key]}', { asc: '#{@component_config[:asc]}', desc: '#{@component_config[:desc]}'})
9
+ }}"
10
+ end
10
11
  end
11
12
 
12
13
  end
@@ -1,5 +1,5 @@
1
1
  import Vue from 'vue/dist/vue.esm'
2
- import componentMixin from 'component/component'
2
+ import componentMixin from './component'
3
3
 
4
4
  const componentDef = {
5
5
  mixins: [componentMixin]
@@ -0,0 +1,424 @@
1
+ module Matestack::Ui::Core::Component
2
+ class Base < Trailblazer::Cell
3
+ include Matestack::Ui::Core::Cell
4
+ include Matestack::Ui::Core::HasViewContext
5
+ include Matestack::Ui::Core::HtmlAttributes
6
+ include Matestack::Ui::Core::Properties
7
+
8
+ # define html global attributes
9
+ html_attributes *HTML_GLOBAL_ATTRIBUTES, *HTML_EVENT_ATTRIBUTES
10
+
11
+ # probably need to remove for other tests to be green again
12
+ include Matestack::Ui::Core::DSL
13
+
14
+ view_paths << "#{Matestack::Ui::Core::Engine.root}/app/concepts"
15
+ view_paths << "#{::Rails.root}#{'/' unless ::Rails.root.nil?}app/matestack"
16
+
17
+ extend ViewName::Flat
18
+
19
+ attr_reader :children, :yield_components_to, :argument, :options
20
+
21
+ # TODO: Seems the `context` method is defined in Cells, would be
22
+ # easy to move up - question really is how much of cells we're still using?
23
+ def initialize(model = nil, options = {})
24
+ # @model also exists with the same content? Is there any reason we wouldn't
25
+ # wanna use it instead of @argument? There's even a `model` accessor for it
26
+ # TODO
27
+ @argument = model
28
+ @options = options
29
+
30
+ # TODO works around a semantic where if just a hash is passed apparently
31
+ # those are the options
32
+ @options = model.dup if @options.empty? && model.is_a?(Hash)
33
+
34
+ super(model, @options)
35
+ # DSL-relevant
36
+ @children = []
37
+ @current_parent_context = self
38
+ # remember where we need to insert components on yield_components_for usage
39
+ @yield_components_to = nil
40
+
41
+ # TODO: everything beyond this point is probably not needed for the
42
+ # Page subclass
43
+
44
+ # TODO: potentially only used in form like components
45
+ # Suggestion: Introduce a new super class to remove this complexity
46
+ # from the base class.
47
+ @included_config = @options[:included_config]
48
+ # p self.class.name
49
+ # p @included_config
50
+
51
+ # TODO seemingly never accessed? (at least by us)
52
+ # but probably good to expose to have access to current_user & friends
53
+ # #context is defined in `Cell::ViewModel`
54
+ # and it just grabs @options[:context]
55
+ @controller_context = context&.fetch(:controller_context, nil)
56
+
57
+ # Add matestack context, containing controller etc.
58
+ @matestack_context = options.dig(:matestack_context)
59
+
60
+ # TODO: technically only relevant for Dynamic, however it relies on
61
+ # @options being set but must be set before `setup` is called.
62
+ # As both happen in this controller it isn't possible to squeeze
63
+ # it inbetween the super calls in the Dynamic super class.
64
+ #
65
+ # This is the configuration for the VueJS component
66
+ @component_config = @options.except(:context, :children, :url_params, :included_config, :matestack_context, :slots)
67
+
68
+ # TODO: no idea why this is called `url_params` it contains
69
+ # much more than this e.g. almost all params so maybe rename it?
70
+ # will be deprecated in future releases. use the `params` method in order to access query params
71
+ @url_params = context&.[](:params)&.except(:action, :controller, :component_key, :matestack_context)
72
+
73
+ # used when creating the child component tree
74
+ # if true, the block of an async component with a defer value will not be processed
75
+ # this saves serverside computation time on initial page requests where some components
76
+ # should only be resolved in a subsequent component rendering call
77
+ # whithin this subsequent component rendering call, the value is set to false via
78
+ # matestack_set_skip_defer(false)
79
+ @matestack_skip_defer = true
80
+
81
+ # TODO: do we realy have to call this every time on initialize or should
82
+ # it maybe be called more dynamically like its dynamic_tag_attributes
83
+ # equivalent in Dynamic?
84
+ set_tag_attributes
85
+ setup
86
+ validate_options
87
+ end
88
+
89
+ # whithin subsequent component rendering calls, the value is set to false in order to render
90
+ # the content of deferred components
91
+ def matestack_set_skip_defer bool
92
+ @matestack_skip_defer = bool
93
+ end
94
+
95
+ def set_included_config config
96
+ @included_config = config
97
+ end
98
+
99
+ def get_included_config
100
+ @included_config
101
+ end
102
+
103
+ # TODO: modifies/recreates view lookup paths on every invocation?!
104
+ # At least memoize it I guess...
105
+ # better even maybe/probably give a component an (automatic) way to know
106
+ # exactly where its template is probably based on its own file location.
107
+ # Then no lookup/search has to happen.
108
+ def self.prefixes
109
+ _prefixes = super
110
+ modified_prefixes = _prefixes.map do |prefix|
111
+ prefix_parts = prefix.split("/")
112
+ if prefix_parts.last.include?(self.name.split("::")[-1].underscore)
113
+ prefix_parts[0..-2].join("/") + '/'
114
+ else
115
+ prefix
116
+ end
117
+ end
118
+ return modified_prefixes + _prefixes
119
+ end
120
+
121
+ def self.views_dir
122
+ return ""
123
+ end
124
+
125
+ # Special validation logic
126
+ def validate_options
127
+ if defined? self.class::REQUIRED_KEYS
128
+ ActiveSupport::Deprecation.warn("REQUIRED_KEYS is deprecated. Use `require :foo` instead.")
129
+ self.class::REQUIRED_KEYS.each do |key|
130
+ raise "#{self.class.name}: required key '#{key}' is missing" if options[key].nil?
131
+ end
132
+ end
133
+ custom_options_validation
134
+ end
135
+
136
+ def custom_options_validation
137
+ true
138
+ end
139
+
140
+ # custom component setup that doesn't seem to be documented
141
+ # but lots of components use it
142
+ def setup
143
+ true
144
+ end
145
+
146
+ # Setup meant to be overridden to setup data from DB or what not
147
+ # why not just call these functions at the beginning of whatever
148
+ # we'll call the method like:
149
+ #
150
+ # def respone
151
+ # result = i_call_stuff
152
+ # plain result
153
+ # end
154
+ #
155
+ # Seems like it might be more complicated? Not sure probably missing something.
156
+ def prepare
157
+ true
158
+ end
159
+
160
+ # access params like you would do on rails views and controllers
161
+ def params
162
+ if @matestack_context.present? && @matestack_context[:controller].present?
163
+ @matestack_context[:controller].params
164
+ else
165
+ context[:params]
166
+ end
167
+ end
168
+
169
+ ## ------------------ Rendering ----------------
170
+ # Invoked by Cell::ViewModel from Rendering#call
171
+ #
172
+ def show
173
+ raise "subclass responsibility"
174
+ end
175
+
176
+ def to_html
177
+ show
178
+ end
179
+
180
+ def render_content
181
+ # When/if we implement response then our display purely relies on that
182
+ # of our children
183
+ # TODO: this might be another sub class or module for the difference
184
+ # Like Native Component vs. composed component? Unsure. Might also not be worth it.
185
+ if respond_to? :response
186
+ render :children
187
+ else
188
+ # We got a template render it around our children
189
+ render do
190
+ render :children
191
+ end
192
+ end
193
+ end
194
+
195
+ def component_id
196
+ options[:id] ||= nil
197
+ end
198
+
199
+ def js_action name, arguments
200
+ argumentString = arguments.join('", "')
201
+ argumentString = '"' + argumentString + '"'
202
+ [name, '(', argumentString, ')'].join("")
203
+ end
204
+
205
+ def navigate_to path
206
+ js_action("navigateTo", [path])
207
+ end
208
+
209
+ def get_children
210
+ return options[:children]
211
+ end
212
+
213
+ ## ---------------------- DSL ------------------------------
214
+ # Add a new child when building the component tree.
215
+ #
216
+ # Invoked in 2 ways
217
+ # * directly ass add_child class, args, block
218
+ # * as defined by the DSL methods in `Matestack::Ui::Core::Component::Registry`
219
+ # which does the same but allows the nicer DSL methods on top of it
220
+ #
221
+ # add_child only builds up the whole ruby component structure. Rendering is done
222
+ # in a later step by calling `#show` on the component where you want to start
223
+ # rendering.
224
+ def add_child(child_class, *args, &block)
225
+
226
+ # when the child is an async or isolate component like shown below, only render its wrapper
227
+ # and skip its content on normal page rendering call indicated by @matestack_skip_defer == true
228
+ # Example: async defer: 1000 { plain "I should be deferred" }
229
+ # the component will triger a subsequent component rendering call after 1000ms
230
+ # the main renderer will then set @matestack_skip_defer to false which allows processing
231
+ # the childs content in order to respond to the subsequent component rendering call with
232
+ # the childs content. In this case: "I should be deferred"
233
+ skip_deferred_child_response = false
234
+ if child_class <= Matestack::Ui::Core::Async::Async || child_class < Matestack::Ui::Core::Isolated::Isolated
235
+ if args.any? { |arg| arg[:defer].present? } && @matestack_skip_defer == true
236
+ skip_deferred_child_response = true
237
+ end
238
+ end
239
+
240
+ # check only allowed keys are passed to isolated components
241
+ if child_class < Matestack::Ui::Core::Isolated::Isolated
242
+ unless args.empty? || args[0].keys.all? { |key| [:defer, :public_options, :rerender_on, :init_on, :rerender_delay, :matestack_context].include? key }
243
+ raise "isolated components can only take params in a public_options hash, which will be exposed to the client side in order to perform an async request with these params."
244
+ end
245
+ if args.any? { |arg| arg[:init_on].present? } && @matestack_skip_defer == true
246
+ skip_deferred_child_response = true
247
+ end
248
+ end
249
+
250
+ if self.class < Matestack::Ui::Core::Isolated::Isolated
251
+ parent_context_included_config = @current_parent_context.get_included_config || {}
252
+ parent_context_included_config.merge!({ isolated_parent_class: self.class.name })
253
+ args_with_context = add_context_to_options(args,parent_context_included_config)
254
+ else
255
+ args_with_context = add_context_to_options(args, @current_parent_context.get_included_config)
256
+ end
257
+
258
+ child = child_class.new(*args_with_context)
259
+
260
+ # set the current @matestack_skip_defer state on the child instance
261
+ # otherwise nested deferred components would never be rendered as
262
+ # @matestack_skip_defer is true by default
263
+ child.matestack_set_skip_defer(@matestack_skip_defer)
264
+
265
+ @current_parent_context.children << child
266
+
267
+ # skip childs body if it should be deferred
268
+ # only the wrapping structure is rendered in this case
269
+ unless skip_deferred_child_response
270
+ child.prepare
271
+ child.response if child.respond_to?(:response)
272
+
273
+ if child_class == Matestack::Ui::Core::Form::Form
274
+ included_config = args.select { |arg| arg.is_a?(Hash) ? arg[:for] : nil }[0]
275
+ end
276
+ execute_child_block(child, included_config, block) if block
277
+ end
278
+
279
+ child
280
+ end
281
+
282
+ # compatibility layer to old-school (not needed anymore)
283
+ def components(&block)
284
+ instance_eval &block
285
+ end
286
+
287
+ # TODO: partial is weird, I highly recommend removing it
288
+ # it exists in basically 2 forms, one that is basically `send`
289
+ # the other just executes the block it's given.
290
+ # Same thing can now be achieved through simple method calls
291
+ def partial(*args)
292
+ if block_given?
293
+ yield
294
+ else
295
+ send(*args)
296
+ end
297
+ end
298
+
299
+ # slot allows generating content in one component and passing it to another
300
+ #
301
+ # It's a 2 purpose method (might be redone):
302
+ # * with a block creates the children to be inserted
303
+ # * without a block it inserts the children at the current point
304
+ #
305
+ #
306
+ def slot(slot_content = [], &block)
307
+ if block_given?
308
+ create_slot_children_to_be_inserted(block)
309
+ else
310
+ # at this point the children are completely built, we just need
311
+ # to insert them into the tree at the right spot (which is marked
312
+ # by where we are currently called hence @current_parent_context)
313
+ @current_parent_context.children.concat(slot_content)
314
+ end
315
+ end
316
+
317
+ # TODO the implementation is simple, but reasoning about is quite
318
+ # complex imo. The main reason is that `yield_components` has no
319
+ # access to the block. Of course that could be solved by making
320
+ # it an instance variable. Might be nicer if we could do
321
+ # `def response(&block)`
322
+ # Also:
323
+ # * right now only works with one yield_components, would break with
324
+ # two that might be nice to raise/warn about
325
+ #
326
+ # The biggest trick this pulls is in execte_child_block where the
327
+ # parent context is shifted to whatever this points to, so that it's
328
+ # inserted at the right point.
329
+ def yield_components
330
+ @yield_components_to = @current_parent_context
331
+ end
332
+
333
+ private
334
+
335
+ # This should be simpler, all it does is try to figure out where the hash/option
336
+ # argument goes and put context in it
337
+ # Partially caused by the behavior that we have 2 initialize args and it's unclear
338
+ # which one should be an options hash as both `plain "hello"` and `div id: "lala"`
339
+ # should work currently
340
+ def add_context_to_options(args, included_config=nil)
341
+ case args.size
342
+ when 0 then [
343
+ {
344
+ context: context,
345
+ included_config: included_config,
346
+ }
347
+ ]
348
+ when 1 then
349
+ arg = args.first
350
+ if arg.is_a?(Hash)
351
+ arg[:context] = context
352
+ arg[:included_config] = included_config
353
+ arg[:matestack_context] = @matestack_context
354
+ [arg]
355
+ else
356
+ [arg, {context: context, included_config: included_config, matestack_context: @matestack_context}]
357
+ end
358
+ when 2 then
359
+ if args[1] == :include
360
+ if args.first.is_a?(Hash)
361
+ args.first[:context] = context
362
+ args.first[:included_config] = included_config
363
+ args.first[:matestack_context] = @matestack_context
364
+ [args.first]
365
+ end
366
+ else
367
+ args[1][:context] = context
368
+ args[1][:included_config] = included_config
369
+ args[1][:matestack_context] = @matestack_context
370
+ [args.first, args[1]]
371
+ end
372
+ else
373
+ raise "too many child arguments what are you doing?"
374
+ end
375
+ end
376
+
377
+ def execute_child_block(child, included_config=nil, block)
378
+ previous_parent_context = @current_parent_context
379
+ begin
380
+ @current_parent_context = child.yield_components_to || child
381
+ @current_parent_context.set_included_config(included_config) if included_config.present?
382
+ instance_eval(&block)
383
+ ensure
384
+ @current_parent_context = previous_parent_context
385
+ end
386
+ end
387
+
388
+ def create_slot_children_to_be_inserted(block)
389
+ # Basically works through:
390
+ # 1. create a fake parent (execution_parent_proxy)
391
+ # 2. set it as the current parrent
392
+ # 3. evaluate the block in the context in which it was defined
393
+ # to have access to methods/instance variables
394
+ # 4. make sure parent context is the previous one again
395
+ # 5. return the children we added to our "fake parent" so
396
+ # that they can be inserted wherever again
397
+ execution_parent_proxy = Base.new()
398
+ previous_parent_context = @current_parent_context
399
+ @current_parent_context = execution_parent_proxy
400
+
401
+ begin
402
+ instance_eval(&block)
403
+ ensure
404
+ @current_parent_context = previous_parent_context
405
+ end
406
+
407
+ execution_parent_proxy.children
408
+ end
409
+
410
+ ## ------------------------ Also Rendering ---------------------
411
+ # common attribute handling for tags/components
412
+ def set_tag_attributes
413
+ default_attributes = {
414
+ id: component_id,
415
+ class: options[:class]
416
+ }
417
+ unless options[:attributes].nil?
418
+ default_attributes.merge!(options[:attributes])
419
+ end
420
+
421
+ @tag_attributes = default_attributes
422
+ end
423
+ end
424
+ end