Skip to content

Commit 7b50831

Browse files
committed
introduce matestack:core:component generator
This generator generates a matestack core component in app/concepts/matestack, a test file and a doc file.
1 parent 3bfbae8 commit 7b50831

File tree

8 files changed

+184
-0
lines changed

8 files changed

+184
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Description:
2+
This generates a matestack core component in app/concepts/matestack, a spec file and a docs file.
3+
4+
Pass the name of the component under_scored.
5+
6+
Example 1:
7+
`rails generate matestack:core:component NAME`
8+
9+
This will create:
10+
app/concepts/matestack/ui/core/NAME/NAME.haml
11+
app/concepts/matestack/ui/core/NAME/NAME.rb
12+
spec/usage/components/NAME_spec.rb
13+
docs/components/NAME.md
14+
15+
This will insert a link to the docs in:
16+
docs/components/README.md
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
module Matestack
4+
module Core
5+
module Generators
6+
class ComponentGenerator < Rails::Generators::NamedBase
7+
source_root File.expand_path('templates', __dir__)
8+
9+
def create_core_component
10+
template 'app/concepts/matestack/ui/core/%file_name%/%file_name%.haml'
11+
template 'app/concepts/matestack/ui/core/%file_name%/%file_name%.rb'
12+
template 'spec/usage/components/%file_name%_spec.rb'
13+
template 'docs/components/%file_name%.md'
14+
15+
inject_into_file 'docs/components/README.md', before: "\n## Dynamic Core Components\n" do <<~RUBY
16+
- [#{file_name.underscore}](/docs/components/#{file_name.underscore}.md)
17+
RUBY
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
%<%= file_name.underscore %>{@tag_attributes}
2+
- if options[:text].blank? && block_given?
3+
= yield
4+
- else
5+
= options[:text]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Matestack::Ui::Core::<%= file_name.camelcase %>
2+
class <%= file_name.camelcase %> < Matestack::Ui::Core::Component::Static
3+
end
4+
end
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# matestack core component: <%= file_name.camelcase %>
2+
3+
Show [specs](/spec/usage/components/<%= file_name.underscore %>_spec.rb)
4+
5+
The HTML `<<%= file_name.underscore %>>` tag implemented in ruby.
6+
7+
## Parameters
8+
9+
This component can take 2 optional configuration params and either yield content or display what gets passed to the `text` configuration param.
10+
11+
#### # id (optional)
12+
Expects a string with all ids the `<<%= file_name.underscore %>>` should have.
13+
14+
#### # class (optional)
15+
Expects a string with all classes the `<<%= file_name.underscore %>>` should have.
16+
17+
## Example 1: Yield a given block
18+
19+
```ruby
20+
<%= file_name.underscore %> id: 'foo', class: 'bar' do
21+
plain '<%= file_name.camelcase %> example 1' # optional content
22+
end
23+
```
24+
25+
returns
26+
27+
```html
28+
<<%= file_name.underscore %> id="foo" class="bar">
29+
<%= file_name.camelcase %> example 1
30+
</<%= file_name.underscore %>>
31+
```
32+
33+
## Example 2: Render `options[:text]` param
34+
35+
```ruby
36+
<%= file_name.underscore %> id: 'foo', class: 'bar', text: '<%= file_name.camelcase %> example 2'
37+
```
38+
39+
returns
40+
41+
```html
42+
<<%= file_name.underscore %> id="foo" class="bar">
43+
<%= file_name.camelcase %> example 2
44+
</<%= file_name.underscore %>>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require_relative '../../support/utils'
2+
include Utils
3+
4+
describe '<%= file_name.camelcase %> component', type: :feature, js: true do
5+
it 'Renders a simple and enhanced <%= file_name.underscore %> tag on a page' do
6+
class ExamplePage < Matestack::Ui::Page
7+
def response
8+
components {
9+
# Simple <%= file_name.underscore %>
10+
<%= file_name.underscore %> text: 'Simple <%= file_name.underscore %> tag'
11+
12+
# Enhanced <%= file_name.underscore %>
13+
<%= file_name.underscore %> id: 'my-id', class: 'my-class' do
14+
plain 'Enhanced <%= file_name.underscore %> tag'
15+
end
16+
}
17+
end
18+
end
19+
20+
visit '/example'
21+
22+
static_output = page.html
23+
24+
expected_static_output = <<~HTML
25+
<<%= file_name.underscore %>>Simple <%= file_name.underscore %> tag</<%= file_name.underscore %>>
26+
<<%= file_name.underscore %> id="my-id" class="my-class">Enhanced <%= file_name.underscore %> tag</<%= file_name.underscore %>>
27+
HTML
28+
29+
expect(stripped(static_output)).to include(stripped(expected_static_output))
30+
end
31+
end

spec/dummy/docs/components/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Core Components
2+
3+
matestack provides a wide set of core components, which enables you to easily build your UI.
4+
You can build your [own components](/docs/extend/custom_components.md) as well, either static or dynamic.
5+
6+
## Static Core Components
7+
8+
- [br](/docs/components/br.md)
9+
- [img](/docs/components/img.md)
10+
11+
## Dynamic Core Components
12+
13+
- [transition](/docs/components/transition.md)
14+
- [onclick](/docs/components/onclick.md)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
require 'generator_spec'
4+
require 'generators/matestack/core/component/component_generator'
5+
6+
describe Matestack::Core::Generators::ComponentGenerator, type: :generator do
7+
let(:dummy) { File.expand_path(File.join(__FILE__, '..', '..', '..', '..', '..', '..', 'dummy')) }
8+
let(:dummy_copy) { File.expand_path(File.join(__FILE__, '..', '..', '..', '..', '..', '..', 'dummy_copy')) }
9+
10+
before :each do
11+
FileUtils.cp_r dummy, dummy_copy
12+
end
13+
14+
after :each do
15+
FileUtils.rm_rf dummy
16+
FileUtils.cp_r dummy_copy, dummy
17+
FileUtils.rm_rf dummy_copy
18+
end
19+
20+
destination Rails.root
21+
22+
it 'creates a core component' do
23+
run_generator %w(div)
24+
25+
assert_file 'app/concepts/matestack/ui/core/div/div.rb', /module Matestack::Ui::Core::Div/
26+
assert_file 'app/concepts/matestack/ui/core/div/div.rb', /class Div < Matestack::Ui::Core::Component::Static/
27+
28+
assert_file 'app/concepts/matestack/ui/core/div/div.haml', /%div{@tag_attributes}/
29+
30+
assert_file 'spec/usage/components/div_spec.rb', /describe 'Div component', type: :feature, js: true do/
31+
assert_file 'spec/usage/components/div_spec.rb', /div text: 'Simple div tag'/
32+
assert_file 'spec/usage/components/div_spec.rb', %r{<div>Simple div tag</div>}
33+
assert_file 'spec/usage/components/div_spec.rb', /div id: 'my-id', class: 'my-class' do/
34+
assert_file 'spec/usage/components/div_spec.rb', %r{<div id="my-id" class="my-class">Enhanced div tag</div>}
35+
36+
assert_file 'docs/components/div.md', /# matestack core component: Div/
37+
assert_file 'docs/components/div.md', %r{Show \[specs\]\(/spec/usage/components/div_spec.rb\)}
38+
assert_file 'docs/components/div.md', /The HTML `<div>` tag implemented in ruby./
39+
assert_file 'docs/components/div.md', /Expects a string with all ids the `<div>` should have./
40+
assert_file 'docs/components/div.md', /Expects a string with all classes the `<div>` should have./
41+
assert_file 'docs/components/div.md', /div id: 'foo', class: 'bar' do/
42+
assert_file 'docs/components/div.md', /div id: 'foo', class: 'bar', text: 'Div example 2'/
43+
assert_file 'docs/components/div.md', /<div id="foo" class="bar">/
44+
45+
assert_file 'docs/components/README.md', %r{- \[div\]\(/docs/components/div.md\)}
46+
end
47+
end

0 commit comments

Comments
 (0)