Skip to content

Commit 5092d2e

Browse files
Update documentation, add another test
1 parent c465e4c commit 5092d2e

File tree

5 files changed

+133
-11
lines changed

5 files changed

+133
-11
lines changed

docs/concepts/component.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Show [specs](/spec/usage/base/component_spec.rb).
44

5-
Components are used to define reusable UI elements. The `matestack-ui-core` contains a number of generic, so-called `core components`, but anyone can extend them and write `custom components` that live within a his or her application and cater a specific or unique need.
5+
Components are used to define reusable UI elements. The `matestack-ui-core` contains a number of generic, so-called `core components`, but anyone can extend them and write `custom components` that live within his or her application and cater a specific or unique need.
66

77
This document aims to give a brief introducing to the different kinds of components (with links to further sources) and serves as a manual on [how to configure your components](#component-configuration).
88

@@ -18,7 +18,7 @@ To extend the available core components, just fork [the repo](https://github.com
1818

1919
## Custom Components
2020

21-
By definition, `custom components` only live within your application. In Rails applications, they are put into the `app/matestack/components/` directory. To use them on your `apps` and `pages`, you need to add a *prefixed 'custom_'*. This clearly differentiates them from the vanilla `core components`.
21+
By definition, `custom components` only live within your application. In Rails applications, they are put into the `app/matestack/components/` directory. To use them on your `apps` and `pages`, you need to add a *prefixed 'custom_'*. This way, one can clearly differentiate between `custom components` and `core components`.
2222

2323
### Static Components
2424

docs/extend/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ Matestack provides you with a lot of functionality out of the box. But at certai
44

55
## Custom Components
66

7-
See below for a list of guides on how to create your own project-specific custom components:
7+
The different component concepts are explained [here](/docs/concepts/component.md). See below for a list of guides on how to create your own project-specific custom components:
88

99
1. [Custom static components](/docs/extend/custom_static_components.md)
10+
- [Custom static actionview components](/docs/extend/custom_actionview_components.md)
1011
2. [Custom dynamic components](/docs/extend/custom_dynamic_components.md)
11-
3. [Custom actionview components](/docs/extend/custom_actionview_components.md)
12+
- [Custom dynamic actionview components](/docs/extend/custom_actionview_components.md)

docs/extend/custom_dynamic_components.md

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,58 @@
11
# Custom dynamic components
22

3-
To create dynamic behavior, you got to choose: Either you wrap a bunch of `core components` and/or `custom components` inside an `dynamic core component`, or you go the whole way and create a `custom dynamic component` with a corresponding Vue.js counterpart.
3+
To create dynamic behavior, you got either:
4+
5+
- use a bunch of `dynamic core components` (like async, emit ...) inside a `custom static component` ([examp below](#dynamic-core-components-inside-a-custom-static_component))
6+
- wrap a `custom static component` in a `dynamic core component` ([example below](#async-wrapper-around-static-components))
7+
- create a custom dynamic component with a corresponding Vue.js counterpart ([example below](#dynamic-components-with-custom-))
8+
9+
10+
## Dynamic core components inside a custom static component
11+
12+
Create a `custom static component` in `app/matestack/components/some/component.rb`
13+
14+
```ruby
15+
class Components::Some::Component < Matestack::Ui::StaticComponent
16+
17+
def response
18+
components {
19+
div id: "my-component" do
20+
async rerender_on: "my_event" do
21+
plain DateTime.now.strftime('%Q')
22+
end
23+
end
24+
}
25+
end
26+
27+
end
28+
```
29+
30+
and add it to the Example Page.
31+
32+
Since we've put a `dynamic core component` inside our `custom static component`, the timestamp inside our custom component gets updated whenever *\"my_event\"* happens - for example by an `onclick` component, as shown below:
33+
34+
```ruby
35+
class Pages::ExamplePage < Matestack::Ui::Page
36+
37+
def response
38+
components {
39+
div id: "div-on-page" do
40+
custom_some_component
41+
42+
onclick emit "my_event"
43+
end
44+
}
45+
end
46+
47+
end
48+
```
449

550
## Async wrapper around static components
651

7-
Create a `custom static component` in `app/matestack/components/static/component.rb`
52+
Create a `custom static component` in `app/matestack/components/some/component.rb`
853

954
```ruby
10-
class Components::Static::Component < Matestack::Ui::StaticComponent
55+
class Components::Some::Component < Matestack::Ui::StaticComponent
1156

1257
def response
1358
components {
@@ -50,7 +95,7 @@ To create a custom dynamic component (we will call our example one *FancyCompone
5095
While `custom static components` inherit from `Matestack::Ui::StaticComponent`, `custom dynamic component` inherit from *a different class*, namely `Matestack::Ui::DynamicComponent`:
5196

5297
```ruby
53-
class Fancy::Component < Matestack::Ui::DynamicComponent
98+
class Components::Fancy::Component < Matestack::Ui::DynamicComponent
5499

55100
def response
56101
components {

docs/extend/custom_static_components.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ The output looks like this:
113113

114114
## Camelcased module or class names
115115

116-
Components named in camelcase are referenced to with their downcased counterpart!
116+
Components named in camelcase are referenced with their downcased counterpart!
117117
As an example, define the camelcased component in `app/matestack/components/my_component.rb`
118118

119119
```ruby

spec/usage/extend/custom_component_spec.rb

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def my_action
2929

3030
end
3131

32-
it 'by orchestrating existing core components' do
32+
it 'by orchestrating existing static core components' do
3333

3434
module Components end
3535

@@ -61,6 +61,75 @@ def response
6161

6262
expect(page).to have_xpath('//div[@id="div-on-page"]/div[@id="my-component-1" and contains(.,"I\'m a static component!")]')
6363

64+
end
65+
66+
it 'by orchestrating existing dynamic core components' do
67+
68+
module Components end
69+
70+
class Components::Demo < Matestack::Ui::DynamicComponent
71+
72+
def response
73+
components {
74+
div id: 'my-component-1' do
75+
plain "{{dynamic_value}}"
76+
end
77+
}
78+
end
79+
80+
end
81+
82+
component_definition = <<~javascript
83+
84+
MatestackUiCore.Vue.component('custom-demo', {
85+
mixins: [MatestackUiCore.componentMixin],
86+
data: function data() {
87+
return {
88+
dynamic_value: "Show on pageview"
89+
};
90+
},
91+
mounted(){
92+
const self = this
93+
setTimeout(function () {
94+
self.dynamic_value = "Show after 300ms"
95+
}, 300);
96+
}
97+
});
98+
99+
javascript
100+
101+
class Pages::ExamplePage < Matestack::Ui::Page
102+
103+
def response
104+
components {
105+
div id: 'div-on-page' do
106+
# The async rerender is only used in this test
107+
# because we add the Vue.js component definition
108+
# during runtime and therefore need to
109+
# re-initialize this DOM-part to trigger
110+
# Vue.js to mount the component properly.
111+
async rerender_on: "refresh" do
112+
custom_demo
113+
end
114+
end
115+
}
116+
end
117+
118+
end
119+
120+
visit '/custom_component_test'
121+
122+
page.execute_script(component_definition)
123+
124+
# refresh script only needed in tests, see explanation on page definition above
125+
page.execute_script('MatestackUiCore.matestackEventHub.$emit("refresh")')
126+
127+
expect(page).to have_content('Show on pageview')
128+
sleep 0.5
129+
expect(page).to have_content('Show after 300ms')
130+
131+
132+
64133
end
65134

66135
it 'by extending actionview components - static' do
@@ -107,7 +176,7 @@ def response
107176
module Components end
108177

109178
class Components::TimeClick < Matestack::Ui::DynamicActionviewComponent
110-
# class Components::TimeClick < Matestack::Ui::Core::Actionview::Dynamic # without alias
179+
# class Components::TimeClick < Matestack::Ui::Core::Actionview::Dynamic # without alias
111180

112181
def prepare
113182
@start_time = Time.now
@@ -147,6 +216,11 @@ class Pages::ExamplePage < Matestack::Ui::Page
147216
def response
148217
components {
149218
div id: 'div-on-page' do
219+
# The async rerender is only used in this test
220+
# because we add the Vue.js component definition
221+
# during runtime and therefore need to
222+
# re-initialize this DOM-part to trigger
223+
# Vue.js to mount the component properly.
150224
async rerender_on: "refresh" do
151225
custom_timeClick
152226
end
@@ -159,6 +233,8 @@ def response
159233
visit '/custom_component_test'
160234

161235
page.execute_script(component_definition)
236+
237+
# refresh script only needed in tests, see explanation on page definition above
162238
page.execute_script('MatestackUiCore.matestackEventHub.$emit("refresh")')
163239

164240
expect(page).to have_content('Now I show: less than 5 seconds')

0 commit comments

Comments
 (0)