showcase-rails 0.3.2 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +254 -84
- data/app/assets/builds/showcase.css +47 -580
- data/app/assets/stylesheets/showcase.tailwind.css +44 -0
- data/app/models/showcase/path.rb +4 -0
- data/app/models/showcase/preview.rb +1 -1
- data/app/views/showcase/engine/_options.html.erb +3 -3
- data/app/views/showcase/engine/_preview.html.erb +4 -4
- data/app/views/showcase/engine/_root.html.erb +3 -3
- data/app/views/showcase/engine/_sample.html.erb +6 -6
- data/app/views/showcase/engine/index.html.erb +10 -10
- data/app/views/showcase/engine/path/_tree.html.erb +3 -3
- data/config/tailwind.config.js +4 -5
- data/lib/showcase/version.rb +1 -1
- data/lib/showcase.rb +11 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c5d33100bd6414501e65b9739978d060032490a480bcf17cac74b689c556605
|
4
|
+
data.tar.gz: ac2cf1b91db211cce86ad10ac4b9acc9dbfd5c19a7d4fdda17e853b3e81ebade
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 754d2bfcd10de161792834a56b470dc88652ac393429295d794e05b6c97b8da6a309af9aad284456742f34fde3faa6f7de50583f43f341178e2a0f22f13e314d
|
7
|
+
data.tar.gz: 2bb6891dd5236ce84728bb6c86db146de9724152f471b5e7f71fd1149941866572e9e2d5fd23e575e87019db5c62eb4597ef3807e28b3c20c33265cc896c479d
|
data/README.md
CHANGED
@@ -2,20 +2,32 @@
|
|
2
2
|
|
3
3
|
Showcase lets you build previews for your partials, components, view helpers, Stimulus controllers and more — Rails engines included!
|
4
4
|
|
5
|
-
Add a partial to `app/views/showcase/previews` and it'll show up in Showcase's menu.
|
5
|
+
Add a partial to `app/views/showcase/previews` and it'll show up in Showcase's menu.
|
6
6
|
|
7
|
-
|
7
|
+
| Light Mode | Dark Mode |
|
8
|
+
| --- | --- |
|
9
|
+
| ![](/readme/example-light.png?raw=true "Showcase showing a button component") | ![](/readme/example-dark.png?raw=true "Showcase showing a button component") |
|
10
|
+
|
11
|
+
Each sample shows the render time in milliseconds and the allocation count so it's easier to spot if there's something different happening between your samples.
|
12
|
+
|
13
|
+
## What can I showcase?
|
14
|
+
|
15
|
+
### Rails partials
|
16
|
+
|
17
|
+
Here's how to showcase a standard button component written with standard Rails partials:
|
18
|
+
|
19
|
+
```erb
|
8
20
|
<%# app/views/showcase/previews/components/_button.html.erb %>
|
9
21
|
<% showcase.title "Button" %> <%# `title` is optional and inferred from the filename, by default. %>
|
10
22
|
<% showcase.badge :partial, :component %> <%# Optional badges you can add to further clarify the type of the showcase. %>
|
11
23
|
<% showcase.description "This button component handles what we click on" %>
|
12
24
|
|
13
25
|
<% showcase.sample "Basic" do %>
|
14
|
-
<%= render "
|
26
|
+
<%= render "components/button", content: "Button content", mode: :small %>
|
15
27
|
<% end %>
|
16
28
|
|
17
29
|
<% showcase.sample "Large", description: "This is our larger button" do %>
|
18
|
-
<%= render "
|
30
|
+
<%= render "components/button", content: "Button content", mode: :large %>
|
19
31
|
<% end %>
|
20
32
|
|
21
33
|
<% showcase.options do |o| %>
|
@@ -24,70 +36,173 @@ Add a partial to `app/views/showcase/previews` and it'll show up in Showcase's m
|
|
24
36
|
<% end %>
|
25
37
|
```
|
26
38
|
|
27
|
-
|
39
|
+
### Components with ViewComponent
|
28
40
|
|
29
|
-
|
30
|
-
| --- | --- |
|
31
|
-
| ![](/readme/example-light.png?raw=true "Showcase showing a button component") | ![](/readme/example-dark.png?raw=true "Showcase showing a button component") |
|
41
|
+
If we take the `MessageComponent` as seen on [https://viewcomponent.org](https://viewcomponent.org):
|
32
42
|
|
33
|
-
|
43
|
+
```ruby
|
44
|
+
# app/components/message_component.rb
|
45
|
+
class MessageComponent < ViewComponent::Base
|
46
|
+
def initialize(name:)
|
47
|
+
@name = name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
34
51
|
|
35
|
-
|
52
|
+
```erb
|
53
|
+
<%# app/components/message_component.html.erb %>
|
54
|
+
<h1>Hello, <%= @name %>!</h1>
|
55
|
+
```
|
36
56
|
|
37
|
-
|
57
|
+
We can showcase it just by rendering it:
|
38
58
|
|
39
59
|
```erb
|
40
|
-
|
41
|
-
<% showcase.sample "Basic"
|
42
|
-
|
60
|
+
<%# app/views/showcase/previews/components/_message_component.html.erb %>
|
61
|
+
<% showcase.sample "Basic" do %>
|
62
|
+
<%= render MessageComponent.new(name: "World") %>
|
63
|
+
<% end %>
|
64
|
+
|
65
|
+
<% showcase.options do |o| %>
|
66
|
+
<% o.required :name, "The name to say hello to" %>
|
43
67
|
<% end %>
|
44
68
|
```
|
45
69
|
|
46
|
-
|
70
|
+
### Components with Phlex
|
47
71
|
|
48
|
-
|
72
|
+
Given this [phlex-rails](https://www.phlex.fun/rails/) component:
|
49
73
|
|
50
74
|
```ruby
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
75
|
+
# app/views/components/article.rb
|
76
|
+
class Components::Article < Phlex::HTML
|
77
|
+
def initialize(article) = @article = article
|
78
|
+
|
79
|
+
def template
|
80
|
+
h1 { @article.title }
|
55
81
|
end
|
56
82
|
end
|
57
83
|
```
|
58
84
|
|
59
|
-
|
85
|
+
We can use Rails' `render` method to showcase it:
|
60
86
|
|
61
|
-
|
87
|
+
```erb
|
88
|
+
<%# app/views/showcase/previews/components/_article.html.erb %>
|
89
|
+
<% showcase.sample "Basic" do %>
|
90
|
+
<%= render Components::Article.new(Article.first) %>
|
91
|
+
<% end %>
|
92
|
+
```
|
93
|
+
|
94
|
+
### View helpers
|
95
|
+
|
96
|
+
Any application helpers defined in `app/helpers` are automatically available in Showcase's engine, so given a helper like this:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
# app/helpers/upcase_helper.rb
|
100
|
+
module UpcaseHelper
|
101
|
+
def upcase_string(string)
|
102
|
+
string.upcase
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
You can showcase it like this:
|
108
|
+
|
109
|
+
```erb
|
110
|
+
<%# app/views/showcase/previews/helpers/_upcase_helper.html.erb %>
|
111
|
+
<% showcase.sample "Basic" do %>
|
112
|
+
<%= upcase_string "hello" %>
|
113
|
+
<% end %>
|
114
|
+
```
|
115
|
+
|
116
|
+
### JavaScript with Stimulus controllers
|
117
|
+
|
118
|
+
Assuming we have a Stimulus controller like this:
|
119
|
+
|
120
|
+
```javascript
|
121
|
+
// app/assets/javascripts/controllers/welcome_controller.js
|
122
|
+
import { Controller } from "@hotwired/stimulus"
|
123
|
+
|
124
|
+
export default class extends Controller {
|
125
|
+
static targets = [ "greeter" ]
|
126
|
+
static values = { yell: Boolean }
|
62
127
|
|
63
|
-
|
128
|
+
connect() {
|
129
|
+
let greeting = this.hasGreeterTarget ? `Welcome, ${this.greeterTarget.textContent}!` : "Welcome!"
|
130
|
+
if (this.yellValue) greeting = greeting.toUpperCase()
|
131
|
+
|
132
|
+
console.log(greeting)
|
133
|
+
this.dispatch("greeting", { detail: { greeting } })
|
134
|
+
}
|
135
|
+
})
|
136
|
+
```
|
137
|
+
|
138
|
+
We can then render it to showcase it:
|
64
139
|
|
65
140
|
```erb
|
141
|
+
<% showcase.description "The welcome controller says hello when it enters the screen" %>
|
142
|
+
|
143
|
+
<% showcase.sample "Basic", events: "welcome:greeting" do %>
|
144
|
+
<div data-controller="welcome">I've just said welcome!</div>
|
145
|
+
<% end %>
|
146
|
+
|
147
|
+
<% showcase.sample "With greeter", events: "welcome:greeting" do %>
|
148
|
+
<div data-controller="welcome">
|
149
|
+
<div data-welcome-target="greeter">Somebody</div>
|
150
|
+
</div>
|
151
|
+
<% end %>
|
152
|
+
|
153
|
+
<% showcase.sample "Yelling!!!", events: "welcome:greeting" do %>
|
154
|
+
<div data-controller="welcome" data-welcome-yell-value="true">
|
155
|
+
<% end %>
|
156
|
+
|
157
|
+
<%# We're using the built-in Stimulus context here to output `data-` attributes correctly, and save some typing. %>
|
66
158
|
<% showcase.options.context :stimulus, controller: :welcome do |o| %>
|
67
159
|
<% o.optional.targets :greeter, "If the id of the target element must be printed" %>
|
160
|
+
<% o.required.values :yell, "Whether the hello is to be YELLED", default: false %>
|
161
|
+
|
162
|
+
<%# We support the other Stimulus declarations too: %>
|
163
|
+
<% o.required.classes :success, "The success class to append after greeting" %>
|
164
|
+
<% o.required.outlet :list, "An outlet to append each yelled greeter to" %>
|
165
|
+
<% o.optional.action :greet, "An action to repeat the greeting, if need be" %>
|
68
166
|
<% end %>
|
69
167
|
```
|
70
168
|
|
71
|
-
|
169
|
+
Note that by adding `events: "welcome:greeting"` we're listening for any time that event is dispatched. Events are logged with `console.log`, but also output alongside the sample in the browser.
|
170
|
+
|
171
|
+
## Installation
|
172
|
+
|
173
|
+
Add these lines to your application's Gemfile. See next section for why Showcase is in the test group.
|
72
174
|
|
73
175
|
```ruby
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def targets(name, ...)
|
78
|
-
option(%(data-#{@controller}-target="#{name}"), ...)
|
79
|
-
end
|
80
|
-
end
|
176
|
+
group :development, :test do
|
177
|
+
gem "showcase-rails"
|
178
|
+
gem "rouge" # Optional. For out-of-the-box syntax highlighting.
|
81
179
|
end
|
82
180
|
```
|
83
181
|
|
84
|
-
|
182
|
+
And then execute:
|
183
|
+
|
184
|
+
```bash
|
185
|
+
$ bundle
|
186
|
+
```
|
187
|
+
|
188
|
+
Or install it yourself as:
|
189
|
+
```bash
|
190
|
+
$ gem install showcase-rails
|
191
|
+
```
|
192
|
+
|
193
|
+
Then add the following in your `config/routes.rb` within the block passed to `Rails.application.routes.draw`:
|
85
194
|
|
86
|
-
|
195
|
+
```ruby
|
196
|
+
mount Showcase::Engine, at: "/docs/showcase" if defined?(Showcase::Engine)
|
197
|
+
```
|
87
198
|
|
88
|
-
|
199
|
+
### Automatic previews testing
|
89
200
|
|
90
|
-
|
201
|
+
To have Showcase generate tests to exercise all your previews on CI, run `bin/rails showcase:install:previews_test` to add `test/views/showcase_test.rb`.
|
202
|
+
|
203
|
+
There you can add `setup` and `teardown` hooks, plus override the provided `assert_showcase_preview` to add custom assertions for any preview.
|
204
|
+
|
205
|
+
If you need custom assertions for specific previews, you can use the `test` helper:
|
91
206
|
|
92
207
|
```ruby
|
93
208
|
# test/views/showcase_test.rb
|
@@ -111,7 +226,78 @@ class ShowcaseTest < Showcase::PreviewsTest
|
|
111
226
|
end
|
112
227
|
```
|
113
228
|
|
114
|
-
|
229
|
+
### Syntax Highlighting
|
230
|
+
|
231
|
+
Add `gem "rouge"` to your Gemfile and Showcase will set syntax highlighting up for you. Any denoted syntaxes in your samples are then highlighted, e.g.:
|
232
|
+
|
233
|
+
```erb
|
234
|
+
# app/views/showcase/previews/_plain_ruby.ruby
|
235
|
+
<% showcase.sample "Basic", syntax: :ruby do %>
|
236
|
+
concat "hello".upcase
|
237
|
+
<% end %>
|
238
|
+
```
|
239
|
+
|
240
|
+
By default, `syntax: :erb` is used, so you don't need to mark the majority of your samples.
|
241
|
+
|
242
|
+
#### Replacing the highlighter
|
243
|
+
|
244
|
+
To use a different syntax highlighter, assign your own Proc to `sample_renderer` like this:
|
245
|
+
|
246
|
+
```ruby
|
247
|
+
# config/initializers/showcase.rb
|
248
|
+
return unless defined?(Showcase)
|
249
|
+
|
250
|
+
Showcase.sample_renderer = ->(source, syntax) do
|
251
|
+
# Return a String of lexed and formatted code.
|
252
|
+
end
|
253
|
+
```
|
254
|
+
|
255
|
+
#### Replacing the theme
|
256
|
+
|
257
|
+
By default, Showcase's syntax highlighting runs on Rouge's `"github"` theme.
|
258
|
+
|
259
|
+
To use a different theme, override [showcase/engine/_stylesheets.html.erb](app/views/showcase/engine/_stylesheets.html.erb) with the following, replacing `:magritte` with a [valid theme](rouge-themes):
|
260
|
+
|
261
|
+
```erb
|
262
|
+
<%= stylesheet_link_tag "showcase" %> <%# We've removed the default showcase.highlights file here. %>
|
263
|
+
<%= tag.style Rouge::Theme.find(:magritte).render(scope: ".sc-highlight") %>
|
264
|
+
```
|
265
|
+
|
266
|
+
[rouge-themes]: https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes
|
267
|
+
|
268
|
+
## Taking Showcase further
|
269
|
+
|
270
|
+
### View examples
|
271
|
+
|
272
|
+
Clone the repository, run `bundle install`, then run `bin/rails server`, and visit localhost:3000 in your browser. You'll see the examples from [test/dummy/app/views/showcase/previews](test/dummy/app/views/showcase/previews).
|
273
|
+
|
274
|
+
### Configuring what trees to open
|
275
|
+
|
276
|
+
Showcase's sidebar mirrors your `app/views/showcase/previews` directory with their paths, and then trees at each directory level.
|
277
|
+
|
278
|
+
So a `showcase/previews` directory with `_top_level.html.erb`, `components/_button.html.erb`, `deeply/nested/_partial.html.erb`, will generate a sidebar like this:
|
279
|
+
|
280
|
+
- Previews
|
281
|
+
- Top Level
|
282
|
+
- Components
|
283
|
+
- Button
|
284
|
+
- Deeply
|
285
|
+
- Nested
|
286
|
+
- Partial
|
287
|
+
|
288
|
+
Internally, Showcase renders an open `details` element for each tree. You can control that with this:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
# config/initializers/showcase.rb
|
292
|
+
return unless defined?(Showcase)
|
293
|
+
|
294
|
+
Showcase.tree_opens = true # All trees are open (the default).
|
295
|
+
Showcase.tree_opens = false # All trees are closed.
|
296
|
+
Showcase.tree_opens = ->(tree) { tree.root? } # Only open the root level trees (Previews, Components, Deeply but not Nested).
|
297
|
+
Showcase.tree_opens = ->(tree) { tree.id.start_with? ".", "components" } # Just open the top-level tree and the components tree.
|
298
|
+
```
|
299
|
+
|
300
|
+
### Linking to previews
|
115
301
|
|
116
302
|
Call `showcase.link_to` with the URL path to the other Showcase:
|
117
303
|
|
@@ -123,7 +309,34 @@ Call `showcase.link_to` with the URL path to the other Showcase:
|
|
123
309
|
<%= showcase.link_to id: "extra-large" %>
|
124
310
|
```
|
125
311
|
|
126
|
-
|
312
|
+
### Adding options contexts
|
313
|
+
|
314
|
+
Showcase also supports custom options contexts. They're useful for cases where the options have a very specific format and it would be nice to keep them standardized.
|
315
|
+
|
316
|
+
By default, Showcase ships Nice Partials and Stimulus contexts out of the box. See [lib/showcase.rb](lib/showcase.rb) for how they're defined.
|
317
|
+
|
318
|
+
To add a new context, you can do this:
|
319
|
+
|
320
|
+
```ruby
|
321
|
+
# config/initializers/showcase.rb
|
322
|
+
return unless defined?(Showcase)
|
323
|
+
|
324
|
+
Showcase.options.define :some_context do
|
325
|
+
def targets(name, ...)
|
326
|
+
option("data-#{@prefix}-#{name}", ...)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
```
|
330
|
+
|
331
|
+
And now we can use it, here passing in `prefix:` which becomes an instance variable available in the `define` block.
|
332
|
+
|
333
|
+
```erb
|
334
|
+
<% showcase.options.context :some_context, prefix: "super-" do |o| %>
|
335
|
+
<% o.required.targets :title %>
|
336
|
+
<% end %>
|
337
|
+
```
|
338
|
+
|
339
|
+
### Full Rails engine support
|
127
340
|
|
128
341
|
Any Rails engines in your app that ships previews in their `app/views/showcase/previews` directory will automatically be surfaced in your app. Here's an example from the [bullet_train-themes-light Rails engine](https://github.com/bullet-train-co/bullet_train-core/tree/main/bullet_train-themes-light/app/views/showcase/previews).
|
129
342
|
|
@@ -131,11 +344,7 @@ Showcase respects the Rails views rendering order, allowing you to override a sp
|
|
131
344
|
|
132
345
|
_📖 How does this work? 📖_ Internally, Showcase leverages Rails controllers' ordered set of `view_paths` — which each engine automatically prepends their app/views directory to by calling something like [`ActionController::Base.prepend_view_path`](https://github.com/rails/rails/blob/e78ed07e008676752b2ed2cff97e74b31ffacaf5/railties/lib/rails/engine.rb#L606) when initializing.
|
133
346
|
|
134
|
-
|
135
|
-
|
136
|
-
Clone the repository, run `bundle install`, then run `bin/rails server`, visit localhost:3000 in your browser.
|
137
|
-
|
138
|
-
## Overriding Showcase's default rendering
|
347
|
+
### Overriding Showcase's default rendering
|
139
348
|
|
140
349
|
Showcase's rendering happens through two controllers:
|
141
350
|
|
@@ -179,48 +388,9 @@ partials, make sure to include `"showcase"` in your list of assets.
|
|
179
388
|
|
180
389
|
[javascript_include_tag]: https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-javascript_include_tag
|
181
390
|
[stylesheet_link_tag]: https://edgeapi.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-stylesheet_link_tag
|
182
|
-
[showcase/engine/_head.html.erb]:
|
183
|
-
[showcase/engine/_javascripts.html.erb]:
|
184
|
-
[showcase/engine/_stylesheets.html.erb]:
|
185
|
-
|
186
|
-
### Loading your own syntax highlighting theme
|
187
|
-
|
188
|
-
By default, Showcase's syntax highlighting runs on Rouge's "github" theme.
|
189
|
-
|
190
|
-
To use a different theme, override [showcase/engine/_stylesheets.html.erb][] with the following, replacing `:magritte` with a [valid theme](rouge-themes):
|
191
|
-
|
192
|
-
```erb
|
193
|
-
<%= stylesheet_link_tag "showcase" %> # We've removed the default showcase.highlights file here.
|
194
|
-
<%= tag.style Rouge::Theme.find(:magritte).render(scope: ".sc-highlight") %>
|
195
|
-
```
|
196
|
-
|
197
|
-
[rouge-themes]: https://github.com/rouge-ruby/rouge/tree/master/lib/rouge/themes
|
198
|
-
|
199
|
-
## Installation
|
200
|
-
|
201
|
-
Add this line to your application's Gemfile. To get the previews testing make sure the `showcase-rails` gem is available to your test environment:
|
202
|
-
|
203
|
-
```ruby
|
204
|
-
group :development, :test do
|
205
|
-
gem "showcase-rails"
|
206
|
-
end
|
207
|
-
```
|
208
|
-
|
209
|
-
And then execute:
|
210
|
-
```bash
|
211
|
-
$ bundle
|
212
|
-
```
|
213
|
-
|
214
|
-
Or install it yourself as:
|
215
|
-
```bash
|
216
|
-
$ gem install showcase-rails
|
217
|
-
```
|
218
|
-
|
219
|
-
Then add the following in your `config/routes.rb` within the block passed to `Rails.application.routes.draw`:
|
220
|
-
|
221
|
-
```ruby
|
222
|
-
mount Showcase::Engine, at: "/docs/showcase" if defined?(Showcase::Engine)
|
223
|
-
```
|
391
|
+
[showcase/engine/_head.html.erb]: app/views/showcase/engine/_head.html.erb
|
392
|
+
[showcase/engine/_javascripts.html.erb]: app/views/showcase/engine/_javascripts.html.erb
|
393
|
+
[showcase/engine/_stylesheets.html.erb]: app/views/showcase/engine/_stylesheets.html.erb
|
224
394
|
|
225
395
|
## Contributing
|
226
396
|
Contribution directions go here.
|