superview 0.1.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -3
- data/Gemfile.lock +103 -149
- data/README.md +112 -15
- data/lib/superview/actions.rb +36 -19
- data/lib/superview/assignable.rb +27 -7
- data/lib/superview/components/table_component.rb +17 -6
- data/lib/superview/helpers/turbo/meta_tags.rb +2 -2
- data/lib/superview/helpers/turbo.rb +0 -11
- data/lib/superview/version.rb +1 -1
- metadata +34 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76c8014ae40d2045b7ad8f93e8005aa7f3af1cfc7568579e2dea783c16c94840
|
4
|
+
data.tar.gz: db2d98cf482c7c8055a58758b3c409f6f48694fd6b114fe5045803cbac53cf96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92697e127638e7ca678b97ca776131a9e4ca1ccae741b62bab41deea80e6e6d268fb7d37abff2dc0dbae9004e0a6973ff56c51fa1bbb6a7a40d1cd1f7c82d4ba
|
7
|
+
data.tar.gz: a806923fbf0f9048b9deafe38a8eb1f5f2ed933acb0095c38c222f17c01e0378c6518931018ece0d41b41d70659e519dae641d467f6f6d04bebc041c0ea23bcf
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,190 +1,144 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
superview (0.
|
5
|
-
phlex-rails (~> 1.0)
|
4
|
+
superview (1.0.0)
|
6
5
|
zeitwerk (~> 2.0)
|
7
6
|
|
8
7
|
GEM
|
9
8
|
remote: https://rubygems.org/
|
10
9
|
specs:
|
11
|
-
|
12
|
-
|
13
|
-
activesupport (= 7.
|
14
|
-
nio4r (~> 2.0)
|
15
|
-
websocket-driver (>= 0.6.1)
|
16
|
-
actionmailbox (7.0.7)
|
17
|
-
actionpack (= 7.0.7)
|
18
|
-
activejob (= 7.0.7)
|
19
|
-
activerecord (= 7.0.7)
|
20
|
-
activestorage (= 7.0.7)
|
21
|
-
activesupport (= 7.0.7)
|
22
|
-
mail (>= 2.7.1)
|
23
|
-
net-imap
|
24
|
-
net-pop
|
25
|
-
net-smtp
|
26
|
-
actionmailer (7.0.7)
|
27
|
-
actionpack (= 7.0.7)
|
28
|
-
actionview (= 7.0.7)
|
29
|
-
activejob (= 7.0.7)
|
30
|
-
activesupport (= 7.0.7)
|
31
|
-
mail (~> 2.5, >= 2.5.4)
|
32
|
-
net-imap
|
33
|
-
net-pop
|
34
|
-
net-smtp
|
35
|
-
rails-dom-testing (~> 2.0)
|
36
|
-
actionpack (7.0.7)
|
37
|
-
actionview (= 7.0.7)
|
38
|
-
activesupport (= 7.0.7)
|
39
|
-
rack (~> 2.0, >= 2.2.4)
|
40
|
-
rack-test (>= 0.6.3)
|
41
|
-
rails-dom-testing (~> 2.0)
|
42
|
-
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
43
|
-
actiontext (7.0.7)
|
44
|
-
actionpack (= 7.0.7)
|
45
|
-
activerecord (= 7.0.7)
|
46
|
-
activestorage (= 7.0.7)
|
47
|
-
activesupport (= 7.0.7)
|
48
|
-
globalid (>= 0.6.0)
|
10
|
+
actionpack (7.2.2.1)
|
11
|
+
actionview (= 7.2.2.1)
|
12
|
+
activesupport (= 7.2.2.1)
|
49
13
|
nokogiri (>= 1.8.5)
|
50
|
-
|
51
|
-
|
14
|
+
racc
|
15
|
+
rack (>= 2.2.4, < 3.2)
|
16
|
+
rack-session (>= 1.0.1)
|
17
|
+
rack-test (>= 0.6.3)
|
18
|
+
rails-dom-testing (~> 2.2)
|
19
|
+
rails-html-sanitizer (~> 1.6)
|
20
|
+
useragent (~> 0.16)
|
21
|
+
actionview (7.2.2.1)
|
22
|
+
activesupport (= 7.2.2.1)
|
52
23
|
builder (~> 3.1)
|
53
|
-
erubi (~> 1.
|
54
|
-
rails-dom-testing (~> 2.
|
55
|
-
rails-html-sanitizer (~> 1.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
activesupport (= 7.0.7)
|
64
|
-
activestorage (7.0.7)
|
65
|
-
actionpack (= 7.0.7)
|
66
|
-
activejob (= 7.0.7)
|
67
|
-
activerecord (= 7.0.7)
|
68
|
-
activesupport (= 7.0.7)
|
69
|
-
marcel (~> 1.0)
|
70
|
-
mini_mime (>= 1.1.0)
|
71
|
-
activesupport (7.0.7)
|
72
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
24
|
+
erubi (~> 1.11)
|
25
|
+
rails-dom-testing (~> 2.2)
|
26
|
+
rails-html-sanitizer (~> 1.6)
|
27
|
+
activesupport (7.2.2.1)
|
28
|
+
base64
|
29
|
+
benchmark (>= 0.3)
|
30
|
+
bigdecimal
|
31
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
32
|
+
connection_pool (>= 2.2.5)
|
33
|
+
drb
|
73
34
|
i18n (>= 1.6, < 2)
|
35
|
+
logger (>= 1.4.2)
|
74
36
|
minitest (>= 5.1)
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
37
|
+
securerandom (>= 0.3)
|
38
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
39
|
+
base64 (0.2.0)
|
40
|
+
benchmark (0.4.0)
|
41
|
+
bigdecimal (3.1.8)
|
42
|
+
builder (3.3.0)
|
43
|
+
concurrent-ruby (1.3.4)
|
44
|
+
connection_pool (2.4.1)
|
79
45
|
crass (1.0.6)
|
80
|
-
date (3.
|
81
|
-
diff-lcs (1.5.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
globalid (1.1.0)
|
86
|
-
activesupport (>= 5.0)
|
87
|
-
i18n (1.14.1)
|
46
|
+
date (3.4.1)
|
47
|
+
diff-lcs (1.5.1)
|
48
|
+
drb (2.2.1)
|
49
|
+
erubi (1.13.0)
|
50
|
+
i18n (1.14.6)
|
88
51
|
concurrent-ruby (~> 1.0)
|
89
|
-
|
52
|
+
io-console (0.8.0)
|
53
|
+
irb (1.14.2)
|
54
|
+
rdoc (>= 4.0.0)
|
55
|
+
reline (>= 0.4.2)
|
56
|
+
logger (1.6.3)
|
57
|
+
loofah (2.23.1)
|
90
58
|
crass (~> 1.0.2)
|
91
59
|
nokogiri (>= 1.12.0)
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
net-pop
|
96
|
-
net-smtp
|
97
|
-
marcel (1.0.2)
|
98
|
-
method_source (1.0.0)
|
99
|
-
mini_mime (1.1.5)
|
100
|
-
mini_portile2 (2.8.5)
|
101
|
-
minitest (5.19.0)
|
102
|
-
net-imap (0.3.7)
|
103
|
-
date
|
104
|
-
net-protocol
|
105
|
-
net-pop (0.1.2)
|
106
|
-
net-protocol
|
107
|
-
net-protocol (0.2.1)
|
108
|
-
timeout
|
109
|
-
net-smtp (0.3.3)
|
110
|
-
net-protocol
|
111
|
-
nio4r (2.5.9)
|
112
|
-
nokogiri (1.15.4)
|
113
|
-
mini_portile2 (~> 2.8.2)
|
60
|
+
method_source (1.1.0)
|
61
|
+
minitest (5.25.4)
|
62
|
+
nokogiri (1.18.0-arm64-darwin)
|
114
63
|
racc (~> 1.4)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
64
|
+
nokogiri (1.18.0-x86_64-linux-gnu)
|
65
|
+
racc (~> 1.4)
|
66
|
+
phlex (1.11.0)
|
67
|
+
phlex-rails (1.2.2)
|
68
|
+
phlex (>= 1.10, < 2)
|
69
|
+
railties (>= 6.1, < 9)
|
70
|
+
psych (5.2.1)
|
71
|
+
date
|
72
|
+
stringio
|
73
|
+
racc (1.8.1)
|
74
|
+
rack (3.1.8)
|
75
|
+
rack-session (2.0.0)
|
76
|
+
rack (>= 3.0.0)
|
125
77
|
rack-test (2.1.0)
|
126
78
|
rack (>= 1.3)
|
127
|
-
|
128
|
-
|
129
|
-
actionmailbox (= 7.0.7)
|
130
|
-
actionmailer (= 7.0.7)
|
131
|
-
actionpack (= 7.0.7)
|
132
|
-
actiontext (= 7.0.7)
|
133
|
-
actionview (= 7.0.7)
|
134
|
-
activejob (= 7.0.7)
|
135
|
-
activemodel (= 7.0.7)
|
136
|
-
activerecord (= 7.0.7)
|
137
|
-
activestorage (= 7.0.7)
|
138
|
-
activesupport (= 7.0.7)
|
139
|
-
bundler (>= 1.15.0)
|
140
|
-
railties (= 7.0.7)
|
79
|
+
rackup (2.2.1)
|
80
|
+
rack (>= 3)
|
141
81
|
rails-dom-testing (2.2.0)
|
142
82
|
activesupport (>= 5.0.0)
|
143
83
|
minitest
|
144
84
|
nokogiri (>= 1.6)
|
145
|
-
rails-html-sanitizer (1.6.
|
85
|
+
rails-html-sanitizer (1.6.2)
|
146
86
|
loofah (~> 2.21)
|
147
|
-
nokogiri (
|
148
|
-
railties (7.
|
149
|
-
actionpack (= 7.
|
150
|
-
activesupport (= 7.
|
151
|
-
|
87
|
+
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
|
88
|
+
railties (7.2.2.1)
|
89
|
+
actionpack (= 7.2.2.1)
|
90
|
+
activesupport (= 7.2.2.1)
|
91
|
+
irb (~> 1.13)
|
92
|
+
rackup (>= 1.0.0)
|
152
93
|
rake (>= 12.2)
|
153
|
-
thor (~> 1.0)
|
154
|
-
zeitwerk (~> 2.
|
155
|
-
rake (13.
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
rspec-core (3.
|
161
|
-
rspec-support (~> 3.
|
162
|
-
rspec-expectations (3.
|
94
|
+
thor (~> 1.0, >= 1.2.2)
|
95
|
+
zeitwerk (~> 2.6)
|
96
|
+
rake (13.2.1)
|
97
|
+
rdoc (6.9.0)
|
98
|
+
psych (>= 4.0.0)
|
99
|
+
reline (0.5.12)
|
100
|
+
io-console (~> 0.5)
|
101
|
+
rspec-core (3.13.2)
|
102
|
+
rspec-support (~> 3.13.0)
|
103
|
+
rspec-expectations (3.13.3)
|
163
104
|
diff-lcs (>= 1.2.0, < 2.0)
|
164
|
-
rspec-support (~> 3.
|
165
|
-
rspec-mocks (3.
|
105
|
+
rspec-support (~> 3.13.0)
|
106
|
+
rspec-mocks (3.13.2)
|
166
107
|
diff-lcs (>= 1.2.0, < 2.0)
|
167
|
-
rspec-support (~> 3.
|
168
|
-
rspec-
|
169
|
-
|
170
|
-
|
108
|
+
rspec-support (~> 3.13.0)
|
109
|
+
rspec-rails (7.1.0)
|
110
|
+
actionpack (>= 7.0)
|
111
|
+
activesupport (>= 7.0)
|
112
|
+
railties (>= 7.0)
|
113
|
+
rspec-core (~> 3.13)
|
114
|
+
rspec-expectations (~> 3.13)
|
115
|
+
rspec-mocks (~> 3.13)
|
116
|
+
rspec-support (~> 3.13)
|
117
|
+
rspec-support (3.13.2)
|
118
|
+
securerandom (0.4.0)
|
119
|
+
stringio (3.1.2)
|
120
|
+
thor (1.3.2)
|
171
121
|
tzinfo (2.0.6)
|
172
122
|
concurrent-ruby (~> 1.0)
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
123
|
+
useragent (0.16.11)
|
124
|
+
view_component (3.0.0)
|
125
|
+
activesupport (>= 5.2.0, < 8.0)
|
126
|
+
concurrent-ruby (~> 1.0)
|
127
|
+
method_source (~> 1.0)
|
128
|
+
zeitwerk (2.7.1)
|
177
129
|
|
178
130
|
PLATFORMS
|
179
131
|
arm64-darwin-22
|
180
132
|
arm64-darwin-23
|
133
|
+
arm64-darwin-24
|
181
134
|
x86_64-linux
|
182
135
|
|
183
136
|
DEPENDENCIES
|
184
|
-
rails (
|
137
|
+
phlex-rails (>= 1.0, < 3.0)
|
185
138
|
rake (~> 13.0)
|
186
|
-
rspec (~>
|
139
|
+
rspec-rails (~> 7.0)
|
187
140
|
superview!
|
141
|
+
view_component (~> 3.0.0)
|
188
142
|
|
189
143
|
BUNDLED WITH
|
190
144
|
2.4.8
|
data/README.md
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# Superview
|
2
2
|
|
3
|
-
Build Rails applications, from the ground up, using [Phlex](https://www.phlex.fun/) components, like this.
|
3
|
+
Build Rails applications, from the ground up, using [Phlex](https://www.phlex.fun/) or [ViewComponent](https://viewcomponent.org/) components, like this.
|
4
4
|
|
5
5
|
```ruby
|
6
|
+
# ./app/controllers/posts_controller.rb
|
6
7
|
class PostsController < ApplicationController
|
7
8
|
include Superview::Actions
|
8
9
|
|
@@ -11,12 +12,27 @@ class PostsController < ApplicationController
|
|
11
12
|
class Show < ApplicationComponent
|
12
13
|
attr_accessor :post
|
13
14
|
|
14
|
-
def
|
15
|
+
def view_template(&)
|
15
16
|
h1 { @post.title }
|
16
17
|
div(class: "prose") { @post.body }
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
21
|
+
class Edit < ViewComponent::Base
|
22
|
+
attr_accessor :post
|
23
|
+
|
24
|
+
def call
|
25
|
+
<<~HTML
|
26
|
+
<h1>Edit #{@post.title}</h1>
|
27
|
+
<form action="<%= post_path(@post) %>" method="post">
|
28
|
+
<input type="text" name="title" value="<%= @post.title %>">
|
29
|
+
<textarea name="body"><%= @post.body %></textarea>
|
30
|
+
<button type="submit">Save</button>
|
31
|
+
</form>
|
32
|
+
HTML
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
20
36
|
private
|
21
37
|
def load_post
|
22
38
|
@post = Post.find(params[:id])
|
@@ -41,13 +57,22 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
41
57
|
|
42
58
|
## Usage
|
43
59
|
|
44
|
-
|
60
|
+
Add `include Superview::Actions` to any controllers you'd like to render components as controller actions.
|
45
61
|
|
46
|
-
|
62
|
+
```ruby
|
63
|
+
# ./app/controllers/posts_controller.rb
|
64
|
+
class PostsController < ApplicationController
|
65
|
+
# 🚨 Add this 👇 to your controller 🚨
|
66
|
+
include Superview::Actions
|
67
|
+
|
68
|
+
# Your code...
|
69
|
+
end
|
70
|
+
```
|
47
71
|
|
48
|
-
Then add
|
72
|
+
Then add classes to your controller that map to the actions you'd like to render. The `Show` class will render when the `PostsController#show` action is called and the `Edit` class will render when the `PostsController#edit` action is called.
|
49
73
|
|
50
74
|
```ruby
|
75
|
+
# ./app/controllers/posts_controller.rb
|
51
76
|
class PostsController < ApplicationController
|
52
77
|
include Superview::Actions
|
53
78
|
|
@@ -56,12 +81,27 @@ class PostsController < ApplicationController
|
|
56
81
|
class Show < ApplicationComponent
|
57
82
|
attr_accessor :post
|
58
83
|
|
59
|
-
def
|
84
|
+
def view_template(&)
|
60
85
|
h1 { @post.title }
|
61
86
|
div(class: "prose") { @post.body }
|
62
87
|
end
|
63
88
|
end
|
64
89
|
|
90
|
+
class Edit < ViewComponent::Base
|
91
|
+
attr_accessor :post
|
92
|
+
|
93
|
+
def call
|
94
|
+
<<~HTML
|
95
|
+
<h1>Edit #{@post.title}</h1>
|
96
|
+
<form action="<%= post_path(@post) %>" method="post">
|
97
|
+
<input type="text" name="title" value="<%= @post.title %>">
|
98
|
+
<textarea name="body"><%= @post.body %></textarea>
|
99
|
+
<button type="submit">Save</button>
|
100
|
+
</form>
|
101
|
+
HTML
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
65
105
|
private
|
66
106
|
def load_post
|
67
107
|
@post = Post.find(params[:id])
|
@@ -69,18 +109,21 @@ class PostsController < ApplicationController
|
|
69
109
|
end
|
70
110
|
```
|
71
111
|
|
72
|
-
|
112
|
+
### Explicit rendering
|
113
|
+
|
114
|
+
You can explicitly render a component in a controller action method. In this example, we needed to render a the `Show` component in the `html` format and a JSON response in the `json` format.
|
73
115
|
|
74
116
|
```ruby
|
117
|
+
# ./app/controllers/posts_controller.rb
|
75
118
|
class PostsController < ApplicationController
|
76
119
|
include Superview::Actions
|
77
120
|
|
78
|
-
|
121
|
+
# Your code...
|
79
122
|
|
80
123
|
class Show < ApplicationComponent
|
81
124
|
attr_accessor :post
|
82
125
|
|
83
|
-
def
|
126
|
+
def view_template(&)
|
84
127
|
h1 { @post.title }
|
85
128
|
div(class: "prose") { @post.body }
|
86
129
|
end
|
@@ -88,15 +131,49 @@ class PostsController < ApplicationController
|
|
88
131
|
|
89
132
|
def show
|
90
133
|
respond_to do |format|
|
91
|
-
|
134
|
+
# 👋 Renders the Show component
|
135
|
+
format.html { render component }
|
136
|
+
|
137
|
+
# 👉 These would also work...
|
138
|
+
# format.html { render Show.new.tap { _1.post = @post } }
|
139
|
+
# format.html { render component Show.new }
|
140
|
+
# format.html { render component Show }
|
141
|
+
# format.html { render component :show }
|
92
142
|
format.json { render json: @post }
|
93
143
|
end
|
94
144
|
end
|
95
145
|
|
96
|
-
|
97
|
-
|
98
|
-
|
146
|
+
# Your code...
|
147
|
+
end
|
148
|
+
```
|
149
|
+
|
150
|
+
### Rendering other classes from different actions
|
151
|
+
|
152
|
+
It's common to have to render form actions from other actions when forms are saved. In this example the `create` method renders the `component New` view when the form is invalid.
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
# ./app/controllers/posts_controller.rb
|
156
|
+
class PostsController < ApplicationController
|
157
|
+
include Superview::Actions
|
158
|
+
|
159
|
+
def create
|
160
|
+
@post = Post.new(post_params)
|
161
|
+
|
162
|
+
if @post.save
|
163
|
+
redirect_to @post
|
164
|
+
else
|
165
|
+
# 👋 Renders the New component from the create action.
|
166
|
+
render component New
|
167
|
+
|
168
|
+
# 👉 These would also work...
|
169
|
+
# render New.new.tap { _1.post = @post }
|
170
|
+
# render component New.new
|
171
|
+
# render component New
|
172
|
+
# render component :new
|
99
173
|
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# Your code...
|
100
177
|
end
|
101
178
|
```
|
102
179
|
|
@@ -112,7 +189,7 @@ module Posts
|
|
112
189
|
class Show < ApplicationComponent
|
113
190
|
attr_accessor :post
|
114
191
|
|
115
|
-
def
|
192
|
+
def view_template(&)
|
116
193
|
h1 { @post.title }
|
117
194
|
div(class: "prose") { @post.body }
|
118
195
|
end
|
@@ -123,9 +200,11 @@ end
|
|
123
200
|
Then include the `Posts` module in the controllers you'd like to use the views:
|
124
201
|
|
125
202
|
```ruby
|
203
|
+
# ./app/controllers/posts_controller.rb
|
126
204
|
class PostsController < ApplicationController
|
127
205
|
include Superview::Actions
|
128
|
-
|
206
|
+
# 🚨 Add this 👇 to your controller 🚨
|
207
|
+
include Posts
|
129
208
|
|
130
209
|
before_action :load_post
|
131
210
|
|
@@ -145,6 +224,24 @@ end
|
|
145
224
|
|
146
225
|
That's it! Ruby includes all the classes in the `Posts` module, which Superview picks up and renders in the controller. If you have an `Index`, `Edit`, `New`, etc. class in the `Posts` namespace, those would be implicitly rendered for their respective action.
|
147
226
|
|
227
|
+
### View path class mappings
|
228
|
+
|
229
|
+
Not all component libraries are integrated into Rails views, so you might have to manually configure the view paths in your Rails application. This instructs the Rails code reloader, Zeitwerk, to load the components.
|
230
|
+
|
231
|
+
```ruby
|
232
|
+
# ./config/application.rb
|
233
|
+
module MyApp
|
234
|
+
class Application < Rails::Application
|
235
|
+
config.autoload_paths << "#{root}/app/views"
|
236
|
+
config.autoload_paths << "#{root}/app/views/layouts"
|
237
|
+
config.autoload_paths << "#{root}/app/views/components"
|
238
|
+
# Your code
|
239
|
+
end
|
240
|
+
end
|
241
|
+
```
|
242
|
+
|
243
|
+
For example, the `Show` component in the `Posts` module would be loaded from `./app/views/posts/show.rb` and the `Layout` component in the `Layouts` module would be loaded from `./app/views/layouts/layout.rb`.
|
244
|
+
|
148
245
|
## Development
|
149
246
|
|
150
247
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/superview/actions.rb
CHANGED
@@ -16,7 +16,7 @@ module Superview
|
|
16
16
|
# class Show < ApplicationComponent
|
17
17
|
# attr_accessor :post
|
18
18
|
#
|
19
|
-
# def
|
19
|
+
# def view_template(&)
|
20
20
|
# h1 { @post.title }
|
21
21
|
# div(class: "prose") { @post.body }
|
22
22
|
# end
|
@@ -37,7 +37,7 @@ module Superview
|
|
37
37
|
# Finds a class on the controller with the same name as the action. For example,
|
38
38
|
# `def index` would find the `Index` constant on the controller class to render
|
39
39
|
# for the action `index`.
|
40
|
-
def
|
40
|
+
def component_action_class(action:)
|
41
41
|
action_class = action.to_s.camelcase
|
42
42
|
const_get action_class if const_defined? action_class
|
43
43
|
end
|
@@ -49,8 +49,8 @@ module Superview
|
|
49
49
|
# on Phlex. For example, if a controller defines @users and a Phlex class has
|
50
50
|
# `attr_writer :users`, `attr_accessor :user`, or `def users=`, it will be automatically
|
51
51
|
# set by this method.
|
52
|
-
def
|
53
|
-
|
52
|
+
def assign_component_accessors(view)
|
53
|
+
view.tap do |view|
|
54
54
|
view_assigns.each do |variable, value|
|
55
55
|
attr_writer_name = "#{variable}="
|
56
56
|
view.send attr_writer_name, value if view.respond_to? attr_writer_name
|
@@ -58,29 +58,46 @@ module Superview
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# Initializers a Phlex view based on the action name
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
# Initializers a Phlex view based on the action name and assigns accessors
|
62
|
+
def component_action(action)
|
63
|
+
component_view self.class.component_action_class(action: action)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Initializes a component view class and assigns accessors.
|
67
|
+
def component_view(view_class)
|
68
|
+
assign_component_accessors view_class.new
|
65
69
|
end
|
66
70
|
|
67
71
|
# Phlex action for the current action.
|
68
|
-
def
|
69
|
-
|
72
|
+
def component(target = action_name)
|
73
|
+
if target.is_a? Class
|
74
|
+
component_view target
|
75
|
+
elsif target.respond_to? :render_in
|
76
|
+
assign_component_accessors target
|
77
|
+
else
|
78
|
+
component_action target
|
79
|
+
end
|
70
80
|
end
|
71
81
|
|
72
|
-
|
73
|
-
|
74
|
-
#
|
82
|
+
alias :phlex :component
|
83
|
+
|
84
|
+
# Checks if a Phlex class name is present for a controller action name
|
85
|
+
def component_action_exists?(action)
|
86
|
+
self.class.component_action_class(action: action).present?
|
87
|
+
end
|
88
|
+
|
89
|
+
# This is a built-in Rails method resolves the method to call for an action.
|
90
|
+
# If it resolves a Phlex class in the controller, it will render that. If it's
|
91
|
+
# not found it continues with Rails method of resolving action names.
|
75
92
|
def method_for_action(action_name)
|
76
|
-
super || if
|
77
|
-
|
78
|
-
|
93
|
+
super || if component_action_exists? action_name
|
94
|
+
"default_component_render"
|
95
|
+
end
|
79
96
|
end
|
80
97
|
|
81
98
|
# Renders a Phlex view for the given action, if it's present.
|
82
|
-
def
|
83
|
-
render
|
99
|
+
def default_component_render
|
100
|
+
render component
|
84
101
|
end
|
85
102
|
end
|
86
|
-
end
|
103
|
+
end
|
data/lib/superview/assignable.rb
CHANGED
@@ -53,9 +53,9 @@ module Superview
|
|
53
53
|
class_attribute :model, :parent_model, :context_method_name
|
54
54
|
|
55
55
|
before_action :assign_parent_collection, if: :has_parent_model?
|
56
|
-
before_action :assign_parent_member, if: :
|
57
|
-
before_action :assign_collection
|
58
|
-
before_action :assign_member
|
56
|
+
before_action :assign_parent_member, if: :has_parent_model_instance?
|
57
|
+
before_action :assign_collection, if: :has_model?
|
58
|
+
before_action :assign_member, if: :has_model?
|
59
59
|
end
|
60
60
|
|
61
61
|
protected
|
@@ -68,19 +68,31 @@ module Superview
|
|
68
68
|
instance_variable_set "@#{parent_model.model_name.plural}", parent_model_scope
|
69
69
|
end
|
70
70
|
|
71
|
-
def
|
72
|
-
if
|
71
|
+
def model_association
|
72
|
+
if has_parent_model_instance?
|
73
73
|
parent_model_instance.association(model.model_name.collection)
|
74
74
|
elsif has_assignable_context?
|
75
|
-
assignable_context.association(model.model_name.collection)
|
75
|
+
assignable_context.association(model.model_name.collection)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def model_scope
|
80
|
+
if association = model_association
|
81
|
+
association.scope
|
76
82
|
else
|
77
83
|
model.scope_for_association
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
81
|
-
def
|
87
|
+
def parent_model_association
|
82
88
|
if has_assignable_context?
|
83
89
|
assignable_context.association(parent_model.model_name.collection)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def parent_model_scope
|
94
|
+
if association = parent_model_association
|
95
|
+
association.scope
|
84
96
|
else
|
85
97
|
parent_model.scope_for_association
|
86
98
|
end
|
@@ -98,6 +110,14 @@ module Superview
|
|
98
110
|
parent_model.present?
|
99
111
|
end
|
100
112
|
|
113
|
+
def has_parent_model_instance?
|
114
|
+
has_parent_model? && params.key?(parent_model_param_key)
|
115
|
+
end
|
116
|
+
|
117
|
+
def has_model?
|
118
|
+
model.present?
|
119
|
+
end
|
120
|
+
|
101
121
|
def assign_member
|
102
122
|
instance_variable_set "@#{model.model_name.singular}", model_instance
|
103
123
|
end
|
@@ -3,7 +3,7 @@ module Superview::Components
|
|
3
3
|
# collection of the table.
|
4
4
|
#
|
5
5
|
# ```ruby
|
6
|
-
# render TableComponent.new(
|
6
|
+
# render TableComponent.new(@posts) do |table|
|
7
7
|
# # This is how you'd usually render a table.
|
8
8
|
# table.column("Title") { show(_1, :title) }
|
9
9
|
#
|
@@ -19,8 +19,18 @@ module Superview::Components
|
|
19
19
|
# end
|
20
20
|
# end
|
21
21
|
# ```
|
22
|
+
|
22
23
|
class TableComponent < ApplicationComponent
|
23
|
-
|
24
|
+
if Phlex.const_defined?(:DeferredRender)
|
25
|
+
# Phlex 1.0
|
26
|
+
include Phlex::DeferredRender
|
27
|
+
else
|
28
|
+
# Phlex 2.0
|
29
|
+
def before_template(&)
|
30
|
+
vanish(&)
|
31
|
+
super
|
32
|
+
end
|
33
|
+
end
|
24
34
|
|
25
35
|
class Column
|
26
36
|
attr_accessor :title_template, :item_template
|
@@ -41,13 +51,14 @@ module Superview::Components
|
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
44
|
-
def initialize(items
|
54
|
+
def initialize(items = [], **attributes)
|
45
55
|
@items = items
|
56
|
+
@attributes = attributes
|
46
57
|
@columns = []
|
47
58
|
end
|
48
59
|
|
49
|
-
def
|
50
|
-
table do
|
60
|
+
def view_template(&)
|
61
|
+
table(**@attributes) do
|
51
62
|
thead do
|
52
63
|
tr do
|
53
64
|
@columns.each do |column|
|
@@ -75,4 +86,4 @@ module Superview::Components
|
|
75
86
|
end
|
76
87
|
end
|
77
88
|
end
|
78
|
-
end
|
89
|
+
end
|
@@ -20,7 +20,7 @@ module Superview
|
|
20
20
|
@page_requires_reload = page_requires_reload
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
23
|
+
def view_template
|
24
24
|
meta(name: "turbo-refresh-method", content: @method)
|
25
25
|
meta(name: "turbo-refresh-scroll", content: @scroll)
|
26
26
|
meta(name: "turbo-cache-control", content: "no-cache") if @exempts_page_from_cache
|
@@ -45,4 +45,4 @@ module Superview
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
-
end
|
48
|
+
end
|
@@ -7,17 +7,6 @@ module Superview
|
|
7
7
|
register_element :turbo_cable_stream_source
|
8
8
|
end
|
9
9
|
|
10
|
-
class_methods do
|
11
|
-
def turbo(*args, **kwargs, &block)
|
12
|
-
@turbo_meta_tags = MetaTags.new(*args, **kwargs)
|
13
|
-
define_method(:turbo, &block) if block
|
14
|
-
end
|
15
|
-
|
16
|
-
def turbo_meta_tags
|
17
|
-
@turbo_meta_tags ||= MetaTags.new
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
10
|
def turbo_stream_from(*streamables, **attributes)
|
22
11
|
attributes[:channel] = attributes[:channel]&.to_s || "Turbo::StreamsChannel"
|
23
12
|
attributes[:"signed-stream-name"] = ::Turbo::StreamsChannel.signed_stream_name(streamables)
|
data/lib/superview/version.rb
CHANGED
metadata
CHANGED
@@ -1,44 +1,65 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: superview
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brad Gessler
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: zeitwerk
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: view_component
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
34
|
-
type: :
|
33
|
+
version: 3.0.0
|
34
|
+
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
41
|
-
|
40
|
+
version: 3.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: phlex-rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.0'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '3.0'
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '1.0'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
61
|
+
description: Build Rails applications entirely from Phlex, ViewComponents, or any
|
62
|
+
object that responds to `#render_in`
|
42
63
|
email:
|
43
64
|
- bradgessler@gmail.com
|
44
65
|
executables: []
|
@@ -85,8 +106,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
106
|
- !ruby/object:Gem::Version
|
86
107
|
version: '0'
|
87
108
|
requirements: []
|
88
|
-
rubygems_version: 3.5.
|
109
|
+
rubygems_version: 3.5.22
|
89
110
|
signing_key:
|
90
111
|
specification_version: 4
|
91
|
-
summary: Build Rails applications entirely
|
112
|
+
summary: Build Rails applications entirely from Phlex, ViewComponents, or any object
|
113
|
+
that responds to `#render_in`
|
92
114
|
test_files: []
|