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.
- checksums.yaml +4 -4
- data/LICENSE +8 -0
- data/README.md +28 -204
- data/Rakefile +32 -0
- data/app/concepts/matestack/ui/core/abbr/abbr.haml +2 -2
- data/app/concepts/matestack/ui/core/abbr/abbr.rb +3 -2
- data/app/concepts/matestack/ui/core/action/action.js +114 -11
- data/app/concepts/matestack/ui/core/action/action.rb +41 -13
- data/app/concepts/matestack/ui/core/{component/response_dynamic.haml → actionview/dynamic.haml} +2 -3
- data/app/concepts/matestack/ui/core/actionview/dynamic.rb +28 -0
- data/app/concepts/matestack/ui/core/{component → actionview}/static.haml +0 -0
- data/app/concepts/matestack/ui/core/actionview/static.rb +28 -0
- data/app/concepts/matestack/ui/core/address/address.haml +2 -2
- data/app/concepts/matestack/ui/core/address/address.rb +1 -1
- data/app/concepts/matestack/ui/core/app/app.haml +2 -3
- data/app/concepts/matestack/ui/core/app/app.js +18 -4
- data/app/concepts/matestack/ui/core/app/app.rb +34 -81
- data/app/concepts/matestack/ui/core/app/location.js +9 -0
- data/app/concepts/matestack/ui/core/app/store.js +35 -6
- data/app/concepts/matestack/ui/core/area/area.haml +1 -0
- data/app/concepts/matestack/ui/core/area/area.rb +20 -0
- data/app/concepts/matestack/ui/core/aside/aside.haml +3 -0
- data/app/concepts/matestack/ui/core/aside/aside.rb +5 -0
- data/app/concepts/matestack/ui/core/async/async.haml +6 -2
- data/app/concepts/matestack/ui/core/async/async.js +64 -8
- data/app/concepts/matestack/ui/core/async/async.rb +29 -4
- data/app/concepts/matestack/ui/core/async/children_wrapper.haml +2 -0
- data/app/concepts/matestack/ui/core/{pg/pg.haml → b/b.haml} +1 -1
- data/app/concepts/matestack/ui/core/b/b.rb +5 -0
- data/app/concepts/matestack/ui/core/bdi/bdi.haml +5 -0
- data/app/concepts/matestack/ui/core/bdi/bdi.rb +4 -0
- data/app/concepts/matestack/ui/core/bdo/bdo.haml +5 -0
- data/app/concepts/matestack/ui/core/bdo/bdo.rb +11 -0
- data/app/concepts/matestack/ui/core/cite/cite.haml +5 -0
- data/app/concepts/matestack/ui/core/cite/cite.rb +5 -0
- data/app/concepts/matestack/ui/core/code/code.haml +5 -0
- data/app/concepts/matestack/ui/core/code/code.rb +5 -0
- data/app/concepts/matestack/ui/core/collection/content/content.js +4 -4
- data/app/concepts/matestack/ui/core/collection/content/content.rb +2 -2
- data/app/concepts/matestack/ui/core/collection/content/page/link/link.rb +4 -2
- data/app/concepts/matestack/ui/core/collection/filter/filter.js +3 -3
- data/app/concepts/matestack/ui/core/collection/filter/filter.rb +4 -5
- data/app/concepts/matestack/ui/core/collection/filter/select/select.haml +10 -0
- data/app/concepts/matestack/ui/core/collection/filter/select/select.rb +29 -0
- data/app/concepts/matestack/ui/core/collection/helper.rb +14 -6
- data/app/concepts/matestack/ui/core/collection/order/order.js +4 -4
- data/app/concepts/matestack/ui/core/collection/order/order.rb +4 -5
- data/app/concepts/matestack/ui/core/collection/order/toggle/indicator/indicator.rb +6 -5
- data/app/concepts/matestack/ui/core/component/anonym-dynamic-component.js +1 -1
- data/app/concepts/matestack/ui/core/component/base.rb +424 -0
- data/app/concepts/matestack/ui/core/component/children.haml +2 -2
- data/app/concepts/matestack/ui/core/component/component.js +1 -55
- data/app/concepts/matestack/ui/core/component/dynamic.haml +1 -1
- data/app/concepts/matestack/ui/core/component/dynamic.rb +24 -239
- data/app/concepts/matestack/ui/core/component/rerender.rb +8 -0
- data/app/concepts/matestack/ui/core/component/static.rb +3 -12
- data/app/concepts/matestack/ui/core/data/data.haml +5 -0
- data/app/concepts/matestack/ui/core/data/data.rb +9 -0
- data/app/concepts/matestack/ui/core/datalist/datalist.haml +3 -0
- data/app/concepts/matestack/ui/core/datalist/datalist.rb +5 -0
- data/app/concepts/matestack/ui/core/dd/dd.haml +5 -0
- data/app/concepts/matestack/ui/core/dd/dd.rb +5 -0
- data/app/concepts/matestack/ui/core/del/del.haml +5 -0
- data/app/concepts/matestack/ui/core/del/del.rb +4 -0
- data/app/concepts/matestack/ui/core/dfn/dfn.haml +5 -0
- data/app/concepts/matestack/ui/core/dfn/dfn.rb +6 -0
- data/app/concepts/matestack/ui/core/dialog/dialog.haml +5 -0
- data/app/concepts/matestack/ui/core/dialog/dialog.rb +9 -0
- data/app/concepts/matestack/ui/core/dl/dl.haml +5 -0
- data/app/concepts/matestack/ui/core/dl/dl.rb +5 -0
- data/app/concepts/matestack/ui/core/dt/dt.haml +5 -0
- data/app/concepts/matestack/ui/core/dt/dt.rb +5 -0
- data/app/concepts/matestack/ui/core/em/em.haml +5 -0
- data/app/concepts/matestack/ui/core/em/em.rb +5 -0
- data/app/concepts/matestack/ui/core/fieldset/fieldset.haml +5 -0
- data/app/concepts/matestack/ui/core/fieldset/fieldset.rb +9 -0
- data/app/concepts/matestack/ui/core/figure/figure.haml +3 -0
- data/app/concepts/matestack/ui/core/figure/figure.rb +5 -0
- data/app/concepts/matestack/ui/core/form/checkbox/checkbox.rb +79 -0
- data/app/concepts/matestack/ui/core/form/form.js +266 -96
- data/app/concepts/matestack/ui/core/form/form.rb +29 -2
- data/app/concepts/matestack/ui/core/form/has_errors.rb +54 -0
- data/app/concepts/matestack/ui/core/form/has_input_html_attributes.rb +13 -0
- data/app/concepts/matestack/ui/core/form/input/input.rb +39 -52
- data/app/concepts/matestack/ui/core/form/radio/radio.rb +71 -0
- data/app/concepts/matestack/ui/core/form/select/select.haml +9 -76
- data/app/concepts/matestack/ui/core/form/select/select.rb +64 -49
- data/app/concepts/matestack/ui/core/form/submit/submit.rb +4 -1
- data/app/concepts/matestack/ui/core/form/textarea/textarea.rb +28 -0
- data/app/concepts/matestack/ui/core/form/utils.rb +47 -0
- data/app/concepts/matestack/ui/core/heading/heading.rb +2 -0
- data/app/concepts/matestack/ui/core/iframe/iframe.haml +5 -0
- data/app/concepts/matestack/ui/core/iframe/iframe.rb +14 -0
- data/app/concepts/matestack/ui/core/img/img.rb +1 -0
- data/app/concepts/matestack/ui/core/input/input.haml +1 -3
- data/app/concepts/matestack/ui/core/input/input.rb +8 -0
- data/app/concepts/matestack/ui/core/ins/ins.haml +5 -0
- data/app/concepts/matestack/ui/core/ins/ins.rb +10 -0
- data/app/concepts/matestack/ui/core/isolated/children_wrapper.haml +2 -0
- data/app/concepts/matestack/ui/core/isolated/isolated.haml +10 -0
- data/app/concepts/matestack/ui/core/isolated/isolated.js +108 -0
- data/app/concepts/matestack/ui/core/isolated/isolated.rb +59 -0
- data/app/concepts/matestack/ui/core/js/core.js +43 -19
- data/app/concepts/matestack/ui/core/kbd/kbd.haml +5 -0
- data/app/concepts/matestack/ui/core/kbd/kbd.rb +4 -0
- data/app/concepts/matestack/ui/core/label/label.rb +6 -1
- data/app/concepts/matestack/ui/core/legend/legend.haml +5 -0
- data/app/concepts/matestack/ui/core/legend/legend.rb +5 -0
- data/app/concepts/matestack/ui/core/link/link.rb +7 -6
- data/app/concepts/matestack/ui/core/{absolute/absolute.haml → map/map.haml} +1 -1
- data/app/concepts/matestack/ui/core/map/map.rb +11 -0
- data/app/concepts/matestack/ui/core/mark/mark.haml +5 -0
- data/app/concepts/matestack/ui/core/mark/mark.rb +4 -0
- data/app/concepts/matestack/ui/core/meter/meter.haml +4 -0
- data/app/concepts/matestack/ui/core/meter/meter.rb +14 -0
- data/app/concepts/matestack/ui/core/noscript/noscript.haml +5 -0
- data/app/concepts/matestack/ui/core/noscript/noscript.rb +5 -0
- data/app/concepts/matestack/ui/core/object/object.haml +1 -0
- data/app/concepts/matestack/ui/core/object/object.rb +15 -0
- data/app/concepts/matestack/ui/core/onclick/onclick.js +2 -3
- data/app/concepts/matestack/ui/core/onclick/onclick.rb +1 -0
- data/app/concepts/matestack/ui/core/optgroup/optgroup.haml +3 -0
- data/app/concepts/matestack/ui/core/optgroup/optgroup.rb +10 -0
- data/app/concepts/matestack/ui/core/option/option.haml +5 -0
- data/app/concepts/matestack/ui/core/option/option.rb +12 -0
- data/app/concepts/matestack/ui/core/output/output.haml +5 -0
- data/app/concepts/matestack/ui/core/output/output.rb +11 -0
- data/app/concepts/matestack/ui/core/page/{content.js → content/content.js} +8 -2
- data/app/concepts/matestack/ui/core/page/content/content.rb +29 -0
- data/app/concepts/matestack/ui/core/page/page.haml +3 -9
- data/app/concepts/matestack/ui/core/page/page.rb +15 -160
- data/app/concepts/matestack/ui/core/param/param.haml +1 -0
- data/app/concepts/matestack/ui/core/param/param.rb +10 -0
- data/app/concepts/matestack/ui/core/picture/picture.haml +3 -0
- data/app/concepts/matestack/ui/core/picture/picture.rb +4 -0
- data/app/concepts/matestack/ui/core/plain/plain.rb +1 -1
- data/app/concepts/matestack/ui/core/pre/pre.haml +5 -0
- data/app/concepts/matestack/ui/core/pre/pre.rb +5 -0
- data/app/concepts/matestack/ui/core/progress/progress.rb +1 -1
- data/app/concepts/matestack/ui/core/q/q.haml +5 -0
- data/app/concepts/matestack/ui/core/q/q.rb +11 -0
- data/app/concepts/matestack/ui/core/rp/rp.haml +5 -0
- data/app/concepts/matestack/ui/core/rp/rp.rb +5 -0
- data/app/concepts/matestack/ui/core/rt/rt.haml +5 -0
- data/app/concepts/matestack/ui/core/rt/rt.rb +5 -0
- data/app/concepts/matestack/ui/core/ruby/ruby.haml +5 -0
- data/app/concepts/matestack/ui/core/ruby/ruby.rb +5 -0
- data/app/concepts/matestack/ui/core/s/s.haml +5 -0
- data/app/concepts/matestack/ui/core/s/s.rb +6 -0
- data/app/concepts/matestack/ui/core/samp/samp.haml +5 -0
- data/app/concepts/matestack/ui/core/samp/samp.rb +4 -0
- data/app/concepts/matestack/ui/core/slot/slot.rb +2 -2
- data/app/concepts/matestack/ui/core/sup/sup.haml +5 -0
- data/app/concepts/matestack/ui/core/sup/sup.rb +5 -0
- data/app/concepts/matestack/ui/core/template/template.haml +3 -0
- data/app/concepts/matestack/ui/core/template/template.rb +4 -0
- data/app/concepts/matestack/ui/core/textarea/textarea.haml +2 -0
- data/app/concepts/matestack/ui/core/textarea/textarea.rb +10 -0
- data/app/concepts/matestack/ui/core/toggle/toggle.haml +2 -0
- data/app/concepts/matestack/ui/core/toggle/toggle.js +71 -0
- data/app/concepts/matestack/ui/core/toggle/toggle.rb +14 -0
- data/app/concepts/matestack/ui/core/transition/transition.js +18 -2
- data/app/concepts/matestack/ui/core/transition/transition.rb +2 -1
- data/app/concepts/matestack/ui/core/u/u.haml +5 -0
- data/app/concepts/matestack/ui/core/u/u.rb +6 -0
- data/app/concepts/matestack/ui/core/unescaped/unescaped.rb +7 -0
- data/app/concepts/matestack/ui/core/var/var.haml +5 -0
- data/app/concepts/matestack/ui/core/var/var.rb +4 -0
- data/app/concepts/matestack/ui/core/video/video.haml +3 -1
- data/app/concepts/matestack/ui/core/video/video.rb +17 -1
- data/app/concepts/matestack/ui/core/view/view.haml +1 -2
- data/app/concepts/matestack/ui/core/view/view.rb +27 -2
- data/app/concepts/matestack/ui/core/wbr/wbr.haml +1 -0
- data/app/concepts/matestack/ui/core/wbr/wbr.rb +4 -0
- data/app/concepts/matestack/ui/core/youtube/youtube.rb +1 -1
- data/app/helpers/matestack/ui/core/application_helper.rb +89 -17
- data/app/javascript/matestack-ui-core/index.js +22 -0
- data/app/javascript/matestack-ui-core/styles/index.scss +5 -0
- data/app/javascript/packs/matestack-ui-core.js +8 -0
- data/app/lib/matestack/ui/component.rb +1 -0
- data/app/lib/matestack/ui/core/has_view_context.rb +14 -0
- data/app/lib/matestack/ui/core/html_attributes.rb +43 -0
- data/app/lib/matestack/ui/core/properties.rb +88 -0
- data/app/lib/matestack/ui/core/rendering/default_renderer_class_determiner.rb +33 -0
- data/app/lib/matestack/ui/core/rendering/main_renderer.rb +199 -0
- data/app/lib/matestack/ui/dynamic_actionview_component.rb +1 -0
- data/app/lib/matestack/ui/isolated_component.rb +1 -0
- data/app/lib/matestack/ui/static_actionview_component.rb +1 -0
- data/app/lib/matestack/ui/vue_js_component.rb +1 -0
- data/config/routes.rb +0 -1
- data/lib/generators/matestack/app/USAGE +21 -0
- data/lib/generators/matestack/app/app_generator.rb +25 -0
- data/lib/generators/{matestack_app/templates/matestack_app_controller.erb → matestack/app/templates/app/controllers/%file_name%_controller.rb.tt} +0 -2
- data/lib/generators/matestack/app/templates/app/matestack/apps/%file_name%.rb.tt +28 -0
- data/lib/generators/matestack/component/USAGE +20 -0
- data/lib/generators/matestack/component/component_generator.rb +29 -0
- data/lib/generators/{matestack_component/templates/matestack_component.haml.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.haml.tt} +0 -0
- data/lib/generators/{matestack_component/templates/matestack_component.js.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.js.tt} +2 -2
- data/lib/generators/matestack/component/templates/app/matestack/components/%namespace%/%file_name%.rb.tt +11 -0
- data/lib/generators/{matestack_component/templates/matestack_component.scss.erb → matestack/component/templates/app/matestack/components/%namespace%/%file_name%.scss.tt} +0 -0
- data/lib/generators/matestack/core/component/USAGE +16 -0
- data/lib/generators/matestack/core/component/component_generator.rb +23 -0
- data/lib/generators/matestack/core/component/templates/app/concepts/matestack/ui/core/%file_name%/%file_name%.haml.tt +5 -0
- data/lib/generators/matestack/core/component/templates/app/concepts/matestack/ui/core/%file_name%/%file_name%.rb.tt +4 -0
- data/lib/generators/matestack/core/component/templates/docs/components/%file_name%.md.tt +45 -0
- data/lib/generators/matestack/core/component/templates/spec/usage/components/%file_name%_spec.rb +31 -0
- data/lib/generators/matestack/page/USAGE +28 -0
- data/lib/generators/matestack/page/page_generator.rb +54 -0
- data/lib/generators/matestack/page/templates/app/matestack/pages/%app_name%/%namespace%/%file_name%.rb.tt +29 -0
- data/lib/matestack/ui/core.rb +5 -2
- data/lib/matestack/ui/core/cell.rb +31 -0
- data/lib/matestack/ui/core/component/registry.rb +47 -0
- data/lib/matestack/ui/core/components.rb +267 -0
- data/lib/matestack/ui/core/dsl.rb +6 -0
- data/lib/matestack/ui/core/engine.rb +16 -0
- data/lib/matestack/ui/core/version.rb +1 -1
- data/vendor/assets/javascripts/dist/manifest.json +18 -0
- data/vendor/assets/javascripts/dist/manifest.json.br +0 -0
- data/vendor/assets/javascripts/dist/manifest.json.gz +0 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.css +3 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.css.map +1 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.js +17060 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.js.map +1 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.css +0 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.js +3 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.LICENSE.txt +18 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.gz +0 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.map +1 -0
- data/vendor/assets/javascripts/dist/matestack-ui-core.min.js.map.gz +0 -0
- data/vendor/assets/javascripts/matestack-ui-core.js.erb +2 -0
- data/vendor/assets/stylesheets/dist +1 -0
- data/vendor/assets/stylesheets/matestack-ui-core.css.erb +2 -0
- metadata +188 -89
- data/MIT-LICENSE +0 -20
- data/app/concepts/matestack/ui/core/absolute/absolute.rb +0 -17
- data/app/concepts/matestack/ui/core/component/response.haml +0 -2
- data/app/concepts/matestack/ui/core/component/response_dynamic_without_rerender.haml +0 -3
- data/app/concepts/matestack/ui/core/form/inline/inline.haml +0 -6
- data/app/concepts/matestack/ui/core/form/inline/inline.rb +0 -9
- data/app/concepts/matestack/ui/core/form/input/input.haml +0 -27
- data/app/concepts/matestack/ui/core/html/html.haml +0 -3
- data/app/concepts/matestack/ui/core/html/html.js +0 -10
- data/app/concepts/matestack/ui/core/html/html.rb +0 -17
- data/app/concepts/matestack/ui/core/isolate/isolate.haml +0 -2
- data/app/concepts/matestack/ui/core/isolate/isolate.rb +0 -11
- data/app/concepts/matestack/ui/core/page/content.haml +0 -7
- data/app/concepts/matestack/ui/core/page/content.rb +0 -5
- data/app/concepts/matestack/ui/core/pg/pg.rb +0 -5
- data/app/concepts/matestack/ui/core/view/view.js +0 -42
- data/app/lib/matestack/ui/core/app_node.rb +0 -53
- data/app/lib/matestack/ui/core/component_node.rb +0 -73
- data/app/lib/matestack/ui/core/page_node.rb +0 -96
- data/app/lib/matestack/ui/core/to_cell.rb +0 -129
- data/lib/generators/matestack_app/USAGE +0 -21
- data/lib/generators/matestack_app/matestack_app_generator.rb +0 -26
- data/lib/generators/matestack_app/templates/matestack_app.erb +0 -26
- data/lib/generators/matestack_component/USAGE +0 -20
- data/lib/generators/matestack_component/matestack_component_generator.rb +0 -30
- data/lib/generators/matestack_component/templates/matestack_component.rb.erb +0 -13
- data/lib/generators/matestack_page/USAGE +0 -28
- data/lib/generators/matestack_page/matestack_page_generator.rb +0 -41
- data/lib/generators/matestack_page/templates/matestack_page.erb +0 -15
- data/vendor/assets/javascripts/manifest.json +0 -4
- data/vendor/assets/javascripts/matestack-ui-core.js +0 -15309
- 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
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
6
|
-
span @
|
7
|
-
|
8
|
-
|
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
|
@@ -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
|