superview 0.1.3 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95b73938446d68225ef15422d94071e4cdf77856aedb64f9f9b96aca8dd75217
4
- data.tar.gz: 27e686bdfacf05a9d265ba919cf5a2ad2d87a074975ccc33871f2f20498555df
3
+ metadata.gz: bf2d8ead19d68999eccbddbbfa0ea8b93ef447588c28f202d326d74044658168
4
+ data.tar.gz: 6812b0c74b9940484b547439da76a7bba4b7286ada32bd9a5144a1f71bace544
5
5
  SHA512:
6
- metadata.gz: 6e7ddd62b1cbb25eb2e5a3f45f1b161c2973bb8ba33af94469141d2bad9f27f6925d2f3d6af3e777f338e1b9943111277e8250ff56ad7a7ee255ed8ad416ca95
7
- data.tar.gz: 14549c8278d4d55f0f497c27ef26a7b5208d83e7b3c9e4d3cb98a175856986713109d3f630ba8feada62ea6da269f4bc9b006a58c0ac00b62329f49feeb11974
6
+ metadata.gz: 8c9582849a4511fc9b23f049adee0f04a9a3b53837cdaf4621475d27e8757f2e1158482318871269c6b74684faf75778ef11f478830bd5a172de290586601308
7
+ data.tar.gz: 659e0d17f9ac6c335438fb42040c24817ba0313b29f9a0610cb83e0f2daf44d7c01b50ff90f2f29292229fb35d6e6ae6b23f521714a3c8c9d909c32dc65e9ade
data/Gemfile.lock CHANGED
@@ -1,30 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- superview (0.1.3)
5
- phlex-rails (>= 1.0, < 3.0)
4
+ superview (1.0.1)
6
5
  zeitwerk (~> 2.0)
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
10
9
  specs:
11
- actionpack (8.0.1)
12
- actionview (= 8.0.1)
13
- activesupport (= 8.0.1)
10
+ actionpack (7.2.2.1)
11
+ actionview (= 7.2.2.1)
12
+ activesupport (= 7.2.2.1)
14
13
  nokogiri (>= 1.8.5)
15
- rack (>= 2.2.4)
14
+ racc
15
+ rack (>= 2.2.4, < 3.2)
16
16
  rack-session (>= 1.0.1)
17
17
  rack-test (>= 0.6.3)
18
18
  rails-dom-testing (~> 2.2)
19
19
  rails-html-sanitizer (~> 1.6)
20
20
  useragent (~> 0.16)
21
- actionview (8.0.1)
22
- activesupport (= 8.0.1)
21
+ actionview (7.2.2.1)
22
+ activesupport (= 7.2.2.1)
23
23
  builder (~> 3.1)
24
24
  erubi (~> 1.11)
25
25
  rails-dom-testing (~> 2.2)
26
26
  rails-html-sanitizer (~> 1.6)
27
- activesupport (8.0.1)
27
+ activesupport (7.2.2.1)
28
28
  base64
29
29
  benchmark (>= 0.3)
30
30
  bigdecimal
@@ -36,7 +36,6 @@ GEM
36
36
  minitest (>= 5.1)
37
37
  securerandom (>= 0.3)
38
38
  tzinfo (~> 2.0, >= 2.0.5)
39
- uri (>= 0.13.1)
40
39
  base64 (0.2.0)
41
40
  benchmark (0.4.0)
42
41
  bigdecimal (3.1.8)
@@ -58,10 +57,11 @@ GEM
58
57
  loofah (2.23.1)
59
58
  crass (~> 1.0.2)
60
59
  nokogiri (>= 1.12.0)
60
+ method_source (1.1.0)
61
61
  minitest (5.25.4)
62
- nokogiri (1.17.2-arm64-darwin)
62
+ nokogiri (1.18.0-arm64-darwin)
63
63
  racc (~> 1.4)
64
- nokogiri (1.17.2-x86_64-linux)
64
+ nokogiri (1.18.0-x86_64-linux-gnu)
65
65
  racc (~> 1.4)
66
66
  phlex (1.11.0)
67
67
  phlex-rails (1.2.2)
@@ -85,9 +85,9 @@ GEM
85
85
  rails-html-sanitizer (1.6.2)
86
86
  loofah (~> 2.21)
87
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 (8.0.1)
89
- actionpack (= 8.0.1)
90
- activesupport (= 8.0.1)
88
+ railties (7.2.2.1)
89
+ actionpack (= 7.2.2.1)
90
+ activesupport (= 7.2.2.1)
91
91
  irb (~> 1.13)
92
92
  rackup (>= 1.0.0)
93
93
  rake (>= 12.2)
@@ -120,8 +120,11 @@ GEM
120
120
  thor (1.3.2)
121
121
  tzinfo (2.0.6)
122
122
  concurrent-ruby (~> 1.0)
123
- uri (1.0.2)
124
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)
125
128
  zeitwerk (2.7.1)
126
129
 
127
130
  PLATFORMS
@@ -131,9 +134,11 @@ PLATFORMS
131
134
  x86_64-linux
132
135
 
133
136
  DEPENDENCIES
137
+ phlex-rails (>= 1.0, < 3.0)
134
138
  rake (~> 13.0)
135
139
  rspec-rails (~> 7.0)
136
140
  superview!
141
+ view_component (~> 3.0.0)
137
142
 
138
143
  BUNDLED WITH
139
144
  2.4.8
data/README.md CHANGED
@@ -1,14 +1,15 @@
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
 
9
10
  before_action :load_post
10
11
 
11
- class Show < ApplicationComponent
12
+ class Show < Components::Base
12
13
  attr_accessor :post
13
14
 
14
15
  def view_template(&)
@@ -17,6 +18,21 @@ class PostsController < ApplicationController
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,19 +57,28 @@ 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
47
67
 
48
- Then add `include Superview::Actions` to any controllers you'd like to render Phlex components.
68
+ # Your code...
69
+ end
70
+ ```
71
+
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
 
54
79
  before_action :load_post
55
80
 
56
- class Show < ApplicationComponent
81
+ class Show < Components::Base
57
82
  attr_accessor :post
58
83
 
59
84
  def view_template(&)
@@ -62,6 +87,21 @@ class PostsController < ApplicationController
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,15 +109,18 @@ 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
- class Show < ApplicationComponent
123
+ class Show < Components::Base
81
124
  attr_accessor :post
82
125
 
83
126
  def view_template(&)
@@ -88,28 +131,28 @@ class PostsController < ApplicationController
88
131
 
89
132
  def show
90
133
  respond_to do |format|
91
- format.html { render phlex }
92
- # These would also work...
134
+ # 👋 Renders the Show component
135
+ format.html { render component }
136
+
137
+ # 👉 These would also work...
93
138
  # format.html { render Show.new.tap { _1.post = @post } }
94
- # format.html { render phlex Show.new }
95
- # format.html { render phlex Show }
96
- # format.html { render phlex :show }
139
+ # format.html { render component Show.new }
140
+ # format.html { render component Show }
141
+ # format.html { render component :show }
97
142
  format.json { render json: @post }
98
143
  end
99
144
  end
100
145
 
101
- private
102
- def load_post
103
- @post = Post.find(params[:id])
104
- end
146
+ # Your code...
105
147
  end
106
148
  ```
107
149
 
108
- ### Rendering other Phlex actions from different actions
150
+ ### Rendering other classes from different actions
109
151
 
110
- It's common to have to render form actions from other actions when forms are saved. In this example the `create` method renders the `phlex New` view when the form is invalid.
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.
111
153
 
112
154
  ```ruby
155
+ # ./app/controllers/posts_controller.rb
113
156
  class PostsController < ApplicationController
114
157
  include Superview::Actions
115
158
 
@@ -119,21 +162,19 @@ class PostsController < ApplicationController
119
162
  if @post.save
120
163
  redirect_to @post
121
164
  else
122
- render phlex New
123
- # These would also work...
165
+ # 👋 Renders the New component from the create action.
166
+ render component New
167
+
168
+ # 👉 These would also work...
124
169
  # render New.new.tap { _1.post = @post }
125
- # render phlex New.new
126
- # render phlex New
127
- # render phlex :new
170
+ # render component New.new
171
+ # render component New
172
+ # render component :new
128
173
  end
129
174
  end
130
175
 
131
- private
132
- def load_post
133
- @post = Post.find(params[:id])
134
- end
176
+ # Your code...
135
177
  end
136
-
137
178
  ```
138
179
 
139
180
  ### Extracting inline views into the `./app/views` folder
@@ -145,7 +186,7 @@ First let's extract the `Show` class into `./app/views/posts/show.rb`
145
186
  ```ruby
146
187
  # ./app/views/posts/show.rb
147
188
  module Posts
148
- class Show < ApplicationComponent
189
+ class Show < Components::Base
149
190
  attr_accessor :post
150
191
 
151
192
  def view_template(&)
@@ -159,9 +200,11 @@ end
159
200
  Then include the `Posts` module in the controllers you'd like to use the views:
160
201
 
161
202
  ```ruby
203
+ # ./app/controllers/posts_controller.rb
162
204
  class PostsController < ApplicationController
163
205
  include Superview::Actions
164
- include Posts # Add this to your controller 🚨
206
+ # 🚨 Add this 👇 to your controller 🚨
207
+ include Posts
165
208
 
166
209
  before_action :load_post
167
210
 
@@ -181,6 +224,24 @@ end
181
224
 
182
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.
183
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
+
184
245
  ## Development
185
246
 
186
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.
@@ -13,7 +13,7 @@ module Superview
13
13
  #
14
14
  # before_action :load_post
15
15
  #
16
- # class Show < ApplicationComponent
16
+ # class Show < Phlex::HTML
17
17
  # attr_accessor :post
18
18
  #
19
19
  # def view_template(&)
@@ -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,7 +49,7 @@ 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(view)
52
+ def assign_component_accessors(view)
53
53
  view.tap do |view|
54
54
  view_assigns.each do |variable, value|
55
55
  attr_writer_name = "#{variable}="
@@ -59,44 +59,54 @@ module Superview
59
59
  end
60
60
 
61
61
  # Initializers a Phlex view based on the action name and assigns accessors
62
- def phlex_action(action)
63
- phlex_view self.class.phlex_action_class(action: action)
62
+ def component_action(action)
63
+ component_view self.class.component_action_class(action: action)
64
64
  end
65
65
 
66
- # Initializes a phlex view class and assigns accessors.
67
- def phlex_view(view_class)
68
- assign_phlex_accessors view_class.new
66
+ # Initializes a component view class and assigns accessors.
67
+ def component_view(view_class)
68
+ assign_component_accessors view_class.new
69
69
  end
70
70
 
71
71
  # Phlex action for the current action.
72
- def phlex(target = action_name)
73
- case target
74
- when Phlex::HTML
75
- assign_phlex_accessors target
76
- when Symbol, String
77
- phlex_action target
78
- when Class
79
- phlex_view target
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
80
79
  end
81
80
  end
82
81
 
82
+ alias :phlex :component
83
+
83
84
  # Checks if a Phlex class name is present for a controller action name
84
- def phlex_action_exists?(action)
85
- self.class.phlex_action_class(action: action).present?
85
+ def component_action_exists?(action)
86
+ self.class.component_action_class(action: action).present?
86
87
  end
87
88
 
88
89
  # This is a built-in Rails method resolves the method to call for an action.
89
90
  # If it resolves a Phlex class in the controller, it will render that. If it's
90
91
  # not found it continues with Rails method of resolving action names.
91
92
  def method_for_action(action_name)
92
- super || if phlex_action_exists? action_name
93
- "default_phlex_render"
94
- end
93
+ # Yep. `super` calls this, but we have to call it here to cover the
94
+ # situation where the person uas a `./app/views/users/*.rb` file with a Ruby
95
+ # class in it that might be included in the controller via `include Views::Users`.
96
+ # If we call super first, it will tink that `./app/views/users/show.rb` is a template
97
+ # and raise an error that it doesn't have a format.
98
+ if action_method?(action_name)
99
+ action_name
100
+ elsif component_action_exists? action_name
101
+ "default_component_render"
102
+ else
103
+ super
104
+ end
95
105
  end
96
106
 
97
107
  # Renders a Phlex view for the given action, if it's present.
98
- def default_phlex_render
99
- render phlex
108
+ def default_component_render
109
+ render component
100
110
  end
101
111
  end
102
112
  end
@@ -20,7 +20,7 @@ module Superview::Components
20
20
  # end
21
21
  # ```
22
22
 
23
- class TableComponent < ApplicationComponent
23
+ class TableComponent < Phlex::HTML
24
24
  if Phlex.const_defined?(:DeferredRender)
25
25
  # Phlex 1.0
26
26
  include Phlex::DeferredRender
@@ -2,7 +2,7 @@ module Superview
2
2
  module Helpers
3
3
  module Turbo
4
4
  # Renders the metatags for setting up Turbo Drive.
5
- class MetaTags < ApplicationComponent
5
+ class MetaTags < Phlex::HTML
6
6
  attr_accessor \
7
7
  :method,
8
8
  :scroll,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Superview
4
- VERSION = "0.1.3"
4
+ VERSION = "1.0.1"
5
5
  end
metadata CHANGED
@@ -1,50 +1,64 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superview
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brad Gessler
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2024-12-14 00:00:00.000000000 Z
10
+ date: 2025-10-03 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
- name: phlex-rails
13
+ name: zeitwerk
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '1.0'
20
- - - "<"
16
+ - - "~>"
21
17
  - !ruby/object:Gem::Version
22
- version: '3.0'
18
+ version: '2.0'
23
19
  type: :runtime
24
20
  prerelease: false
25
21
  version_requirements: !ruby/object:Gem::Requirement
26
22
  requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- version: '1.0'
30
- - - "<"
23
+ - - "~>"
31
24
  - !ruby/object:Gem::Version
32
- version: '3.0'
25
+ version: '2.0'
33
26
  - !ruby/object:Gem::Dependency
34
- name: zeitwerk
27
+ name: view_component
35
28
  requirement: !ruby/object:Gem::Requirement
36
29
  requirements:
37
30
  - - "~>"
38
31
  - !ruby/object:Gem::Version
39
- version: '2.0'
40
- type: :runtime
32
+ version: 3.0.0
33
+ type: :development
41
34
  prerelease: false
42
35
  version_requirements: !ruby/object:Gem::Requirement
43
36
  requirements:
44
37
  - - "~>"
45
38
  - !ruby/object:Gem::Version
46
- version: '2.0'
47
- description: Build Rails applications entirely out of Phlex components.
39
+ version: 3.0.0
40
+ - !ruby/object:Gem::Dependency
41
+ name: phlex-rails
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '1.0'
47
+ - - "<"
48
+ - !ruby/object:Gem::Version
49
+ version: '3.0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '1.0'
57
+ - - "<"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.0'
60
+ description: Build Rails applications entirely from Phlex, ViewComponents, or any
61
+ object that responds to `#render_in`
48
62
  email:
49
63
  - bradgessler@gmail.com
50
64
  executables: []
@@ -76,7 +90,6 @@ metadata:
76
90
  homepage_uri: https://github.com/rubymonolith/superview
77
91
  source_code_uri: https://github.com/rubymonolith/superview
78
92
  changelog_uri: https://github.com/rubymonolith/superview
79
- post_install_message:
80
93
  rdoc_options: []
81
94
  require_paths:
82
95
  - lib
@@ -91,8 +104,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
104
  - !ruby/object:Gem::Version
92
105
  version: '0'
93
106
  requirements: []
94
- rubygems_version: 3.5.16
95
- signing_key:
107
+ rubygems_version: 3.6.2
96
108
  specification_version: 4
97
- summary: Build Rails applications entirely out of Phlex components.
109
+ summary: Build Rails applications entirely from Phlex, ViewComponents, or any object
110
+ that responds to `#render_in`
98
111
  test_files: []