rails-storybook 0.1.0 → 0.2.0

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: 83b229f8189dd57281db3c891bb6b36b8a437777bdb964ea059a652c8c2c9aad
4
- data.tar.gz: 616420336b4acf5a60967d24498ebeeb004d31169ca7f5de85a309d4795c0ca2
3
+ metadata.gz: 458c8b46779f2ff4f95162603bbef83351fa665f74abb0ad05c964c001695807
4
+ data.tar.gz: aabbc888656b99c56c3d1bb337c8291d7dec9497ca0ed00724c01977f3bc1dbb
5
5
  SHA512:
6
- metadata.gz: 941d4806670ba38473617ecab1a385788da1d56de11267c9372d884c47bf6b45fd191d6b5d40816858f247b70242e1cb089a2bf1ac16da2633be49fbb8a92587
7
- data.tar.gz: 9cc2e89ded7fd27eec72f7b3127acdf854bc6de168e8ffbfe1409ea168ca2bb869702e016ae18e9752cd13657bf96ceb59b624f30cc0102563eb16d59463cb34
6
+ metadata.gz: fb49d7e4d163b9ce723dfaa28c9fa22d67c53279e5364ba86af01e895a3059f526af125f427e95c4ab5b18674beb7f1c654031981de62219e24ea759f97fd8df
7
+ data.tar.gz: e8892db80deae244450745ed86ca751731f9d62c2e51905ad12a80593c840fbdab1a55111a3ba92e63f5177fc0d5dbbc29e2dbb6d9814f3ca5e36a89becd301b
data/Gemfile.lock CHANGED
@@ -3,6 +3,8 @@ PATH
3
3
  specs:
4
4
  rails-storybook (0.1.0)
5
5
  rails (~> 7.0)
6
+ rails-previews (~> 0.1.0)
7
+ react_on_rails (~> 14.0)
6
8
  slim (~> 5.2)
7
9
 
8
10
  GEM
@@ -82,6 +84,8 @@ GEM
82
84
  minitest (>= 5.1)
83
85
  mutex_m
84
86
  tzinfo (~> 2.0)
87
+ addressable (2.8.7)
88
+ public_suffix (>= 2.0.2, < 7.0)
85
89
  ast (2.4.2)
86
90
  base64 (0.2.0)
87
91
  bigdecimal (3.1.8)
@@ -96,6 +100,7 @@ GEM
96
100
  diff-lcs (1.5.1)
97
101
  drb (2.2.1)
98
102
  erubi (1.13.0)
103
+ execjs (2.9.1)
99
104
  globalid (1.2.1)
100
105
  activesupport (>= 6.1)
101
106
  i18n (1.14.5)
@@ -140,6 +145,7 @@ GEM
140
145
  racc
141
146
  psych (5.1.2)
142
147
  stringio
148
+ public_suffix (6.0.1)
143
149
  racc (1.8.1)
144
150
  rack (3.1.7)
145
151
  rack-session (2.0.0)
@@ -170,6 +176,8 @@ GEM
170
176
  rails-html-sanitizer (1.6.0)
171
177
  loofah (~> 2.21)
172
178
  nokogiri (~> 1.14)
179
+ rails-previews (0.1.0)
180
+ slim (~> 5.2)
173
181
  railties (7.1.3.4)
174
182
  actionpack (= 7.1.3.4)
175
183
  activesupport (= 7.1.3.4)
@@ -182,6 +190,12 @@ GEM
182
190
  rake (13.2.1)
183
191
  rdoc (6.7.0)
184
192
  psych (>= 4.0.0)
193
+ react_on_rails (14.0.5)
194
+ addressable
195
+ connection_pool
196
+ execjs (~> 2.5)
197
+ rails (>= 5.2)
198
+ rainbow (~> 3.0)
185
199
  regexp_parser (2.9.2)
186
200
  reline (0.5.9)
187
201
  io-console (~> 0.5)
data/README.md CHANGED
@@ -21,33 +21,36 @@ rails g storybook:install
21
21
 
22
22
  Then, optionally:
23
23
  ```bash
24
- rails g storybook:example
24
+ rails g storybook:examples
25
25
  ```
26
26
 
27
27
  Restart your processes (stop and restart `./bin/dev`) and viola! Opens up a Storybook connected to your Rails server, and if you've also generated the example, will have a simple View Component showing up in Storybook.
28
28
 
29
29
  ## Usage
30
30
 
31
- Today, write a JSON to describe your View Component's "story":
32
- ```
33
- {
34
- "title": "ExampleComponent",
35
- "stories": [
36
- {
37
- "name": "default",
38
- "parameters": {
39
- "server": { "id": "example_component/default" }
40
- }
41
- }
42
- ]
43
- }
31
+ Write a preview for your component, just like normal - but include the StoryBook::Preview module. You can also use the `PartialPreviewComponent` to render regular Rails partials as previews.
32
+ ```ruby
33
+ class ExampleComponentPreview < ViewComponent::Preview
34
+ include Storybook::Preview
35
+ def default
36
+ render(ExampleComponent.new(title: "title"))
37
+ end
38
+
39
+ def default
40
+ render(PartialPreviewComponent.new(partial: "application/example"))
41
+ end
42
+ end
44
43
  ```
44
+ Note that the module will set the preview's layout to `storybook`, as there's steps to be done to make it look good (and work!) inside of Storybook.
45
+
46
+ Then run `rake storybook:stories` to generate the CSF JSON that Storybook uses to find your previews.
47
+
48
+ And... that's it! :D
45
49
 
46
- Tomorrow(tm), run a rake task to generate those stories for you.
47
50
 
48
51
  ## Development
49
52
 
50
- Inspired by [gem view_component-storybook](https://github.com/jonspalmer/view_component-storybook), but, I want to accomplish things in a different way (using the existing view component previews), to aim higher (handling view components, partials, *and* React components), and to aim specifically at integration with Chromatic.
53
+ Inspired by [gem view_component-storybook](https://github.com/jonspalmer/view_component-storybook), but, I want to accomplish things in a different way, to aim higher (handling ~~view components~~, ~~partials~~, *and* React components), and to aim specifically at integration with Chromatic.
51
54
 
52
55
  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.
53
56
 
@@ -0,0 +1,144 @@
1
+ require "rails/generators"
2
+
3
+ class Storybook::ExamplesGenerator < Rails::Generators::Base
4
+ def create_example_partial
5
+ create_file "app/views/application/_example.html.slim", <<~SLIM
6
+ h3 Example Partial
7
+ span= @title
8
+ SLIM
9
+ end
10
+
11
+ def create_example_partial_preview
12
+ create_file "spec/previews/example_partial.rb", <<~RUBY
13
+ # frozen_string_literal: true
14
+ module Previews
15
+ class ExamplePartial < Rails::Previews::Preview
16
+ def default
17
+ render_partial "application/example", locals: { title: "Hello, World!" }
18
+ end
19
+ end
20
+ end
21
+ RUBY
22
+ end
23
+
24
+ def install_view_components
25
+ insert_into_file "Gemfile", "gem \"view_component\""
26
+ system "bundle install"
27
+ end
28
+
29
+ def create_example_view_component
30
+ create_file "app/components/example_component.rb", <<~RUBY
31
+ # frozen_string_literal: true
32
+
33
+ class ExampleComponent < ViewComponent::Base
34
+ slim_template <<~SLIM
35
+ h3 Example Component
36
+ span= @title
37
+ SLIM
38
+
39
+ def initialize(title:)
40
+ @title = title
41
+ end
42
+ end
43
+ RUBY
44
+ end
45
+
46
+ def create_example_view_component_preview
47
+ create_file "spec/previews/example_view_component.rb", <<~RUBY
48
+ # frozen_string_literal: true
49
+
50
+ module Previews
51
+ class ExampleViewComponent < Rails::Previews::Preview
52
+ def default
53
+ ExampleComponent.new(title: "Hello, World!")
54
+ end
55
+
56
+ # TODO - This doesn't work with the current Previews implementation
57
+ # def with_content_block
58
+ # render(ExampleComponent.new(title: "This component accepts a block of content")) do
59
+ # tag.div do
60
+ # content_tag(:span, "Hello")
61
+ # end
62
+ # end
63
+ # end
64
+ end
65
+ end
66
+ RUBY
67
+ end
68
+
69
+ def install_react_on_rails
70
+ insert_into_file "Gemfile", "\ngem \"react_on_rails\""
71
+ system "bundle install"
72
+ end
73
+
74
+ def setup_application_bundle
75
+ # TODO: I have my pack in not the default location
76
+ end
77
+
78
+ def create_example_react_component
79
+ create_file "client/bundles/application/components/HelloWorld.jsx", <<~JSX
80
+ import PropTypes from 'prop-types';
81
+ import React, { useState } from 'react';
82
+ import * as style from './HelloWorld.module.css';
83
+
84
+ const HelloWorld = (props) => {
85
+ return (
86
+ <div>
87
+ <h3>Example React Component</h3>
88
+ <span>{props.name}</span>
89
+ </div>
90
+ );
91
+ };
92
+
93
+ HelloWorld.propTypes = {
94
+ name: PropTypes.string.isRequired, // this is passed from the Rails view
95
+ };
96
+
97
+ export default HelloWorld;
98
+ JSX
99
+
100
+ create_file "client/bundles/application/components/HelloWorld.module.css", <<~CSS
101
+ .bright {
102
+ color: green;
103
+ font-weight: bold;
104
+ }#{' '}
105
+ CSS
106
+
107
+ # TODO: Is this necessary?
108
+ create_file "client/bundles/application/components/HelloWorldServer.js", <<~JS
109
+ import HelloWorld from './HelloWorldServer';
110
+ export default HelloWorld;
111
+ JS
112
+
113
+ create_file "client/packs/application.js", <<~JS
114
+ import ReactOnRails from 'react-on-rails';
115
+ import HelloWorld from '../bundles/application/components/HelloWorld';
116
+ ReactOnRails.register({ HelloWorld });
117
+ JS
118
+
119
+ # TODO: Is this necessary?
120
+ create_file "client/packs/server-bundle.js", <<~JS
121
+ import ReactOnRails from 'react-on-rails';
122
+ import HelloWorld from '../bundles/application/components/HelloWorld';
123
+ ReactOnRails.register({ HelloWorld });
124
+ JS
125
+ end
126
+
127
+ def create_example_react_component_preview
128
+ create_file "spec/previews/example_react_component.rb", <<~RUBY
129
+ # frozen_string_literal: true
130
+
131
+ module Previews
132
+ class ExampleReactComponent < Rails::Previews::Preview
133
+ def default
134
+ render_react_on_rails "HelloWorld", props: { name: "Hello, World!" }
135
+ end
136
+ end
137
+ end
138
+ RUBY
139
+ end
140
+
141
+ def generate_stories
142
+ `rails storybook:stories`
143
+ end
144
+ end
@@ -2,6 +2,7 @@ require "rails/generators"
2
2
 
3
3
  class Storybook::InstallGenerator < Rails::Generators::Base
4
4
  def install_storybook
5
+ # TODO: Tell storybook not to install it's examples
5
6
  system "npx storybook@latest init --yes --dev --no-dev --builder webpack5"
6
7
  system "yarn add @storybook/server --dev"
7
8
  system "yarn add @storybook/server-webpack5 --dev"
@@ -10,7 +11,7 @@ class Storybook::InstallGenerator < Rails::Generators::Base
10
11
  end
11
12
 
12
13
  def install_rack_cors
13
- insert_into_file "Gemfile", " gem 'rack-cors'\n", after: "group :development do\n"
14
+ insert_into_file "Gemfile", " gem \"rack-cors\"\n", after: "group :development do\n"
14
15
  system "bundle install"
15
16
  create_file "config/initializers/cors.rb", <<~RUBY
16
17
  Rails.application.config.middleware.insert_before 0, Rack::Cors do
@@ -22,36 +23,31 @@ class Storybook::InstallGenerator < Rails::Generators::Base
22
23
  RUBY
23
24
  end
24
25
 
25
- def create_storybook_layout_slim
26
- create_file "app/views/layouts/storybook.html.slim", <<~SLIM
27
- doctype html
28
- html lang='en'
29
- head
30
- title Trainyard
31
- meta charset="UTF-8"
32
- meta[name="viewport" content="width=device-width,initial-scale=1"]
33
- = csrf_meta_tags
34
- = csp_meta_tag
35
- = stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload"
36
- = stylesheet_link_tag "application"
37
- = javascript_pack_tag "application"
38
- body
39
- div
40
- main.ml-64.p-8
41
- == yield
42
- SLIM
43
- end
44
-
45
26
  def update_storybook
46
27
  # Main.js
47
28
  insert_into_file ".storybook/main.js", "\n \"@storybook/server\",", after: "addons: ["
48
- gsub_file ".storybook/main.js", "*.stories.@(js|jsx|mjs|ts|tsx)", "*.stories.@(js|jsx|mjs|ts|tsx|json)"
29
+ gsub_file ".storybook/main.js", "*.stories.@(js|jsx|mjs|ts|tsx)", "*.stories.json"
49
30
  gsub_file ".storybook/main.js", "@storybook/react-webpack5", "@storybook/server-webpack5"
50
31
 
51
32
  # Preview.js
52
- base_url = "http://localhost:3000/rails/view_components"
33
+ # TODO: Server & port
34
+ base_url = "http://localhost:3000/previews"
35
+
36
+ # Preferred method to get the styling loaded in:
37
+ # insert_into_file ".storybook/preview.js", "\nimport '../public/assets/tailwind-0c2ceb08e52f57602c2ff891790dee8451074b84335e77f107abdb57f99a2c37.css'", before: "export default preview;"
38
+ # insert_into_file ".storybook/preview.js", "\nimport '../public/assets/application-9f334b542cffee1084a19870f2b1f16b1ef66ff68bfa765286993d260bc9556a.css'", before: "export default preview;"
39
+
53
40
  insert_into_file ".storybook/preview.js", "\n server: { url: \"#{base_url}\", },", after: "parameters: {"
54
41
 
55
42
  # insert_into_file ".storybook/main.js", "@storybook/addon-controls", after: "addons: ["
43
+
44
+ # Stylesheets so Storybook can find them
45
+ # TODO: TailwindCSS / JS packs name, etc
46
+ # TODO: Server & port
47
+ create_file ".storybook/.preview-head.html", <<~HTML
48
+ <link rel="stylesheet" href="http://localhost:3000/assets/tailwind.css" data-turbo-track="reload">
49
+ <link rel="stylesheet" href="http://localhost:3000/assets/inter-font.css" data-turbo-track="reload">
50
+ <link rel="stylesheet" href="http://localhost:3000/assets/application.css" data-turbo-track="reload">
51
+ HTML
56
52
  end
57
53
  end
@@ -0,0 +1,2 @@
1
+ require_relative "../storybook.rb"
2
+ # TODO: Fix the gem naming, etc
@@ -0,0 +1,17 @@
1
+
2
+ module Rails::Previews
3
+ # Re-open the class to add the Storybook methods
4
+ class Preview
5
+ class << self
6
+ def to_csf
7
+ { title: preview_name, stories: stories }
8
+ end
9
+
10
+ def stories
11
+ examples.collect do |name|
12
+ { name:, parameters: { server: { id: "#{preview_name}/#{name}" } } }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ require "storybook"
2
+ require "rails"
3
+
4
+ # https://gist.github.com/ntamvl/7a6658b4cd82d6fbd15434f0a9953411
5
+ module Storybook
6
+ class Railtie < Rails::Railtie
7
+ railtie_name :storybook
8
+
9
+ rake_tasks do
10
+ path = File.expand_path(__dir__)
11
+ Dir.glob("#{path}/tasks/**/*.rake").each { |f| load f }
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ namespace :storybook do
2
+ desc "Write CSF JSON stories for all Stories"
3
+ task stories: :environment do
4
+ stories_dir = "stories"
5
+ Rails::Previews::Preview.all.map do |preview|
6
+ filename = Rails.root.join("#{stories_dir}/#{preview.preview_name}.stories.json")
7
+ stories_json = JSON.pretty_generate(preview.to_csf)
8
+ File.open(filename, "w") { |f| f.write(stories_json) }
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Storybook
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0"
4
4
  end
data/lib/storybook.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "storybook/version"
2
+ require "storybook/preview"
3
+ require "storybook/railtie" if defined?(Rails::Railtie)
2
4
 
3
- module Storybook
4
- class Error < StandardError; end
5
- # Your code goes here...
6
- end
5
+ module Storybook; end
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.add_dependency "rails", "~> 7.0"
28
28
  spec.add_dependency "slim", "~> 5.2"
29
+ spec.add_dependency "rails-previews", "~> 0.1.0"
29
30
  spec.add_development_dependency "rails", "~> 7.0"
30
31
 
31
32
  spec.add_development_dependency "bundler", "~> 2.5"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-storybook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Barone
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-08 00:00:00.000000000 Z
11
+ date: 2024-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails-previews
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.0
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rails
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -157,9 +171,13 @@ files:
157
171
  - Rakefile
158
172
  - bin/console
159
173
  - bin/setup
160
- - lib/generators/storybook/example_generator.rb
174
+ - lib/generators/storybook/examples_generator.rb
161
175
  - lib/generators/storybook/install_generator.rb
176
+ - lib/rails/storybook.rb
162
177
  - lib/storybook.rb
178
+ - lib/storybook/preview.rb
179
+ - lib/storybook/railtie.rb
180
+ - lib/storybook/tasks/stories.rake
163
181
  - lib/storybook/version.rb
164
182
  - rails-storybook.gemspec
165
183
  homepage: https://github.com/rangerscience/rails-storybook
@@ -1,62 +0,0 @@
1
- require "rails/generators"
2
-
3
- class Storybook::ExampleGenerator < Rails::Generators::Base
4
- def install_view_components
5
- insert_into_file "Gemfile", "gem 'view_component'"
6
- system "bundle install"
7
- end
8
-
9
- def create_example_component
10
- create_file "app/components/example_component.rb", <<~RUBY
11
- # frozen_string_literal: true
12
-
13
- class ExampleComponent < ViewComponent::Base
14
- slim_template <<~SLIM
15
- span
16
- = @title
17
- SLIM
18
-
19
- def initialize(title:)
20
- @title = title
21
- end
22
- end
23
- RUBY
24
- end
25
-
26
- def create_example_component_preview
27
- create_file "test/components/previews/example_component_preview.rb", <<~RUBY
28
- # frozen_string_literal: true
29
-
30
- class ExampleComponentPreview < ViewComponent::Preview
31
- layout "storybook"
32
- def default
33
- render(ExampleComponent.new(title: "title"))
34
- end
35
-
36
- def with_content_block
37
- render(ExampleComponent.new(title: "This component accepts a block of content")) do
38
- tag.div do
39
- content_tag(:span, "Hello")
40
- end
41
- end
42
- end
43
- end
44
- RUBY
45
- end
46
-
47
- def create_example_story
48
- create_file "stories/example_component.stories.json", <<~JSON
49
- {
50
- "title": "ExampleComponent",
51
- "stories": [
52
- {
53
- "name": "default",
54
- "parameters": {
55
- "server": { "id": "example_component/default" }
56
- }
57
- }
58
- ]
59
- }
60
- JSON
61
- end
62
- end