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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 185e73cab73c23d8de233721cde393cb453868e1cf3a6f5ef8b322b9b613ff32
4
- data.tar.gz: 6bca9e94731ecd625cf20f904f0cac42fe969ac63ac72913de75f6a176f18a1e
3
+ metadata.gz: 76c8014ae40d2045b7ad8f93e8005aa7f3af1cfc7568579e2dea783c16c94840
4
+ data.tar.gz: db2d98cf482c7c8055a58758b3c409f6f48694fd6b114fe5045803cbac53cf96
5
5
  SHA512:
6
- metadata.gz: a4dfdc42e1697576ac22f8af14c0d6f75be71b198b19a5c6e3097c895db0eb114401af25cf30c39e3615999f4bb41907bde50bc70e22aa6520c1c9805a8eb230
7
- data.tar.gz: d00f990562345a341b69ac4c86ef72bf0deef57defbe4dcdfdfa0b9759079f8e43f57005d59c8058cec368fefa886090814517de823efc2dd7b94b84601dd896
6
+ metadata.gz: 92697e127638e7ca678b97ca776131a9e4ca1ccae741b62bab41deea80e6e6d268fb7d37abff2dc0dbae9004e0a6973ff56c51fa1bbb6a7a40d1cd1f7c82d4ba
7
+ data.tar.gz: a806923fbf0f9048b9deafe38a8eb1f5f2ed933acb0095c38c222f17c01e0378c6518931018ece0d41b41d70659e519dae641d467f6f6d04bebc041c0ea23bcf
data/Gemfile CHANGED
@@ -7,6 +7,4 @@ gemspec
7
7
 
8
8
  gem "rake", "~> 13.0"
9
9
 
10
- gem "rspec", "~> 3.0"
11
-
12
- gem "rails", "~> 7.0"
10
+ gem "rspec-rails", "~> 7.0"
data/Gemfile.lock CHANGED
@@ -1,190 +1,144 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- superview (0.1.2)
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
- actioncable (7.0.7)
12
- actionpack (= 7.0.7)
13
- activesupport (= 7.0.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
- actionview (7.0.7)
51
- activesupport (= 7.0.7)
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.4)
54
- rails-dom-testing (~> 2.0)
55
- rails-html-sanitizer (~> 1.1, >= 1.2.0)
56
- activejob (7.0.7)
57
- activesupport (= 7.0.7)
58
- globalid (>= 0.3.6)
59
- activemodel (7.0.7)
60
- activesupport (= 7.0.7)
61
- activerecord (7.0.7)
62
- activemodel (= 7.0.7)
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
- tzinfo (~> 2.0)
76
- builder (3.2.4)
77
- cgi (0.3.6)
78
- concurrent-ruby (1.2.2)
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.3.3)
81
- diff-lcs (1.5.0)
82
- erb (4.0.2)
83
- cgi (>= 0.3.3)
84
- erubi (1.12.0)
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
- loofah (2.21.3)
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
- mail (2.8.1)
93
- mini_mime (>= 0.1.1)
94
- net-imap
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
- phlex (1.8.1)
116
- concurrent-ruby (~> 1.2)
117
- erb (>= 4)
118
- zeitwerk (~> 2.6)
119
- phlex-rails (1.0.0)
120
- phlex (~> 1.7)
121
- rails (>= 6.1, < 8)
122
- zeitwerk (~> 2.6)
123
- racc (1.7.1)
124
- rack (2.2.8)
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
- rails (7.0.7)
128
- actioncable (= 7.0.7)
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.0)
85
+ rails-html-sanitizer (1.6.2)
146
86
  loofah (~> 2.21)
147
- nokogiri (~> 1.14)
148
- railties (7.0.7)
149
- actionpack (= 7.0.7)
150
- activesupport (= 7.0.7)
151
- method_source
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.5)
155
- rake (13.0.6)
156
- rspec (3.12.0)
157
- rspec-core (~> 3.12.0)
158
- rspec-expectations (~> 3.12.0)
159
- rspec-mocks (~> 3.12.0)
160
- rspec-core (3.12.2)
161
- rspec-support (~> 3.12.0)
162
- rspec-expectations (3.12.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.12.0)
165
- rspec-mocks (3.12.6)
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.12.0)
168
- rspec-support (3.12.1)
169
- thor (1.2.2)
170
- timeout (0.4.0)
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
- websocket-driver (0.7.6)
174
- websocket-extensions (>= 0.1.0)
175
- websocket-extensions (0.1.5)
176
- zeitwerk (2.6.11)
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 (~> 7.0)
137
+ phlex-rails (>= 1.0, < 3.0)
185
138
  rake (~> 13.0)
186
- rspec (~> 3.0)
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 template(&)
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
- Install `phlex-rails` in your Rails application.
60
+ Add `include Superview::Actions` to any controllers you'd like to render components as controller actions.
45
61
 
46
- $ bin/rails generate phlex:install
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 `include Superview::Actions` to any controllers you'd like to render Phlex components.
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 template(&)
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
- The `Show` class will render when the `PostsController#show` action is called. To use along side other formats or render manually, you can define the `PostsController#show` as you'd expect:
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
- before_action :load_post
121
+ # Your code...
79
122
 
80
123
  class Show < ApplicationComponent
81
124
  attr_accessor :post
82
125
 
83
- def template(&)
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
- format.html { render Show.new.tap { _1.post = @post } }
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
- private
97
- def load_post
98
- @post = Post.find(params[:id])
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 template(&)
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
- include Posts # Add this to your controller 🚨
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.
@@ -16,7 +16,7 @@ module Superview
16
16
  # class Show < ApplicationComponent
17
17
  # attr_accessor :post
18
18
  #
19
- # def template(&)
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 phlex_action_class(action:)
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 assign_phlex_accessors(phlex_view)
53
- phlex_view.tap do |view|
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, then assigns `view_assigns`
62
- # to the view.
63
- def phlex_action(action)
64
- assign_phlex_accessors self.class.phlex_action_class(action: action).new
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 phlex
69
- phlex_action(action_name)
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
- # Try rendering with the regular Rails rendering methods; if those don't work
73
- # then try finding the Phlex class that corresponds with the action_name. If that's
74
- # found then tell Rails to call `default_phlex_render`.
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 self.class.phlex_action_class action: action_name
77
- "default_phlex_render"
78
- end
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 default_phlex_render
83
- render phlex
99
+ def default_component_render
100
+ render component
84
101
  end
85
102
  end
86
- end
103
+ end
@@ -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: :has_parent_model?
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 model_scope
72
- if has_parent_model?
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).scope
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 parent_model_scope
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(items: @posts) do |table|
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
- include Phlex::DeferredRender
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 template(&)
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 template
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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Superview
4
- VERSION = "0.1.2"
4
+ VERSION = "1.0.0"
5
5
  end
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.1.2
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: 2024-02-28 00:00:00.000000000 Z
11
+ date: 2025-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: phlex-rails
14
+ name: zeitwerk
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
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: '1.0'
26
+ version: '2.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: zeitwerk
28
+ name: view_component
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.0'
34
- type: :runtime
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: '2.0'
41
- description: Build Rails applications entirely out of Phlex components.
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.3
109
+ rubygems_version: 3.5.22
89
110
  signing_key:
90
111
  specification_version: 4
91
- summary: Build Rails applications entirely out of Phlex components.
112
+ summary: Build Rails applications entirely from Phlex, ViewComponents, or any object
113
+ that responds to `#render_in`
92
114
  test_files: []