view_component_storybook 0.2.0 → 0.3.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: 156bff92fe14404e71b45c20a0b989efaa70f0c1e01212c91f8db51a9b6399a4
4
- data.tar.gz: fd5cc132d285d64bde3e742fcde2266cc4656ac67de921e54111d9d9ff0af93b
3
+ metadata.gz: 69b5a85793ed8d4ecfe45be21c90a95894f001403ea9a6c086c9822e5b4fca4d
4
+ data.tar.gz: 15b8f5b6430c46b5a3cd453602c4705dea94784b574f6d3a1a9b1ab39c40d1bb
5
5
  SHA512:
6
- metadata.gz: 6dabe9bacc42870ad37ef82a8960ed926481a9e3b68bdf6e58c2f09ba89757ede25be1564c45efcdee99a814e5c69d0fda5d29a73573f67fb42587ea8a886a04
7
- data.tar.gz: 78f94f84257b7b1ccebe85e38157bc37bc779c54cccee0909008d5e8d933f88934dabcb225fc9f2e45c4c108d2965cc0bdf2395e8b0b04d758c9afc18fb971d5
6
+ metadata.gz: '091149f57b05dc6bf82b1dac987ab6dbaaa6655e8c0833517eb575d8ce8abb05e75b8919a63799ad4efaa5da1722fbf5bee7f34c4680a12f969c6996532e53f7'
7
+ data.tar.gz: bf0f10bc68bc35197ca9485efbc3fe18bcad98b110df969f3219daeaeb4797f1c1e7c6eb4ce3aeb737246571227c91c466b4d7c63dd4ff141c0a3962b47caf29
data/README.md CHANGED
@@ -4,7 +4,7 @@ The ViewComponent::Storybook gem provides Ruby api for writing stories describin
4
4
 
5
5
  ## Features
6
6
  * A Ruby DSL for writing Stories describing View Components
7
- * A Rails controller backend for Storybook Server compatible with most Strobook Knobs Addon parameters
7
+ * A Rails controller backend for Storybook Server compatible with Strobook Controls Addon parameters
8
8
  * Coming Soon: Rake tasks to watch View Components and Stories and trigger Storybook hot reloading
9
9
 
10
10
  ## Installation
@@ -18,9 +18,9 @@ The ViewComponent::Storybook gem provides Ruby api for writing stories describin
18
18
 
19
19
  ### Storybook Installation
20
20
 
21
- 1. Add Storybook server as a dev dependedncy. The Storybook Knobs addon isn't needed but is strongly recommended
21
+ 1. Add Storybook server as a dev dependedncy. The Storybook Controls addon isn't needed but is strongly recommended
22
22
  ```sh
23
- yarn add @storybook/server @storybook/addon-knobs --dev
23
+ yarn add @storybook/server @storybook/addon-controls --dev
24
24
  ```
25
25
  2. Add an NPM script to your package.json in order to start the storybook later in this guide
26
26
  ```json
@@ -30,28 +30,27 @@ The ViewComponent::Storybook gem provides Ruby api for writing stories describin
30
30
  }
31
31
  }
32
32
  ```
33
- 3. Create the .storybook/main.js file to configure Storybook to find the json stories the gem creates. Also configure the knobs addon:
33
+ 3. Create the .storybook/main.js file to configure Storybook to find the json stories the gem creates. Also configure the Controls addon:
34
34
  ```javascript
35
35
  module.exports = {
36
36
  stories: ['../test/components/**/*.stories.json'],
37
37
  addons: [
38
- '@storybook/addon-knobs',
38
+ '@storybook/addon-controls',
39
39
  ],
40
40
  };
41
41
  ```
42
42
  4. Create the .storybook/preview.js file to configure Storybook with the Rails application url to call for the html content of the stories
43
43
  ```javascript
44
- import { addParameters } from '@storybook/server';
45
44
 
46
- addParameters({
45
+ export const parameters = {
47
46
  server: {
48
47
  url: `http://localhost:3000/rails/stories`,
49
48
  },
50
- });
49
+ };
51
50
  ```
52
51
 
53
52
 
54
- Note: `@storybook/server` will be part of the upcoming Storybook 6.0 release. Until that is released you'll need to use an [alpha release](https://github.com/storybookjs/storybook/releases/tag/v6.0.0-alpha.32)
53
+ Note: `@storybook/server` will be part of the upcoming Storybook 6.0 release. Until that is released you'll need to use an [rc release](https://github.com/storybookjs/storybook/releases/tag/v6.0.0-rc.14)
55
54
 
56
55
  ## Usage
57
56
 
@@ -74,13 +73,13 @@ We can write a stories desecibing the `ButtonComponent`
74
73
  ```ruby
75
74
  class ButtonComponentStories < ViewComponent::Storybook::Stories
76
75
  story(:with_short_text) do
77
- knobs do
76
+ controls do
78
77
  text(:button_text, 'OK')
79
78
  end
80
79
  end
81
80
 
82
81
  story(:with_long_text) do
83
- knobs do
82
+ controls do
84
83
  text(:button_text, 'Push Me Please!')
85
84
  end
86
85
  end
@@ -121,7 +120,7 @@ Coming Soon
121
120
 
122
121
  #### Parameters
123
122
  #### Layout
124
- #### Knobs
123
+ #### Controls
125
124
 
126
125
 
127
126
  ## Development
@@ -8,7 +8,7 @@ module ViewComponent
8
8
  module Storybook
9
9
  extend ActiveSupport::Autoload
10
10
 
11
- autoload :Knobs
11
+ autoload :Controls
12
12
  autoload :Stories
13
13
  autoload :StoryConfig
14
14
  autoload :Dsl
@@ -4,10 +4,10 @@ require "active_support/dependencies/autoload"
4
4
 
5
5
  module ViewComponent
6
6
  module Storybook
7
- module Knobs
7
+ module Controls
8
8
  extend ActiveSupport::Autoload
9
9
 
10
- autoload :KnobConfig
10
+ autoload :ControlConfig
11
11
  autoload :SimpleConfig
12
12
  autoload :NumberConfig
13
13
  autoload :OptionsConfig
@@ -2,21 +2,17 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class ArrayConfig < KnobConfig
5
+ module Controls
6
+ class ArrayConfig < ControlConfig
7
7
  attr_reader :separator
8
8
 
9
9
  validates :value, :separator, presence: true
10
10
 
11
- def initialize(component, param, value, separator = ",", name: nil, group_id: nil)
12
- super(component, param, value, name: name, group_id: group_id)
11
+ def initialize(component, param, value, separator = ",", name: nil)
12
+ super(component, param, value, name: name)
13
13
  @separator = separator
14
14
  end
15
15
 
16
- def to_csf_params
17
- super.merge(value: value, separator: separator)
18
- end
19
-
20
16
  def type
21
17
  :array
22
18
  end
@@ -28,6 +24,12 @@ module ViewComponent
28
24
  super(param)
29
25
  end
30
26
  end
27
+
28
+ private
29
+
30
+ def csf_control_params
31
+ super.merge(separator: separator)
32
+ end
31
33
  end
32
34
  end
33
35
  end
@@ -2,28 +2,28 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class KnobConfig
5
+ module Controls
6
+ class ControlConfig
7
7
  include ActiveModel::Validations
8
8
 
9
- attr_reader :component, :param, :value, :name, :group_id
9
+ attr_reader :component, :param, :value, :name
10
10
 
11
11
  validates :component, :param, presence: true
12
12
  validates :param, inclusion: { in: ->(knob_config) { knob_config.component_params } }, unless: -> { component.nil? }
13
13
 
14
- def initialize(component, param, value, name: nil, group_id: nil)
14
+ def initialize(component, param, value, name: nil)
15
15
  @component = component
16
16
  @param = param
17
17
  @value = value
18
18
  @name = name || param.to_s.humanize.titlecase
19
- @group_id = group_id
20
19
  end
21
20
 
22
21
  def to_csf_params
23
22
  validate!
24
- params = { type: type, param: param, name: name, value: value }
25
- params[:group_id] = group_id if group_id
26
- params
23
+ {
24
+ args: { param => csf_value },
25
+ argTypes: { param => { control: csf_control_params, name: name } }
26
+ }
27
27
  end
28
28
 
29
29
  def value_from_param(param)
@@ -33,6 +33,17 @@ module ViewComponent
33
33
  def component_params
34
34
  @component_params ||= component && component.instance_method(:initialize).parameters.map(&:last)
35
35
  end
36
+
37
+ private
38
+
39
+ # provide extension points for subclasses to vary the value
40
+ def csf_value
41
+ value
42
+ end
43
+
44
+ def csf_control_params
45
+ { type: type }
46
+ end
36
47
  end
37
48
  end
38
49
  end
@@ -2,21 +2,12 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class DateConfig < KnobConfig
5
+ module Controls
6
+ class DateConfig < ControlConfig
7
7
  validates :value, presence: true
8
8
 
9
- def initialize(component, param, value, name: nil, group_id: nil)
10
- super(component, param, value, name: name, group_id: group_id)
11
- end
12
-
13
- def to_csf_params
14
- csf_params = super
15
- params_value = value
16
- params_value = params_value.in_time_zone if params_value.is_a?(Date)
17
- params_value = params_value.iso8601 if params_value.is_a?(Time)
18
- csf_params[:value] = params_value
19
- csf_params
9
+ def initialize(component, param, value, name: nil)
10
+ super(component, param, value, name: name)
20
11
  end
21
12
 
22
13
  def type
@@ -30,6 +21,15 @@ module ViewComponent
30
21
  super(param)
31
22
  end
32
23
  end
24
+
25
+ private
26
+
27
+ def csf_value
28
+ params_value = value
29
+ params_value = params_value.in_time_zone if params_value.is_a?(Date)
30
+ params_value = params_value.iso8601 if params_value.is_a?(Time)
31
+ params_value
32
+ end
33
33
  end
34
34
  end
35
35
  end
@@ -2,14 +2,14 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class NumberConfig < KnobConfig
5
+ module Controls
6
+ class NumberConfig < ControlConfig
7
7
  attr_reader :options
8
8
 
9
9
  validates :value, presence: true
10
10
 
11
- def initialize(component, param, value, options = {}, name: nil, group_id: nil)
12
- super(component, param, value, name: name, group_id: group_id)
11
+ def initialize(component, param, value, options = {}, name: nil)
12
+ super(component, param, value, name: name)
13
13
  @options = options
14
14
  end
15
15
 
@@ -17,12 +17,6 @@ module ViewComponent
17
17
  :number
18
18
  end
19
19
 
20
- def to_csf_params
21
- params = super
22
- params[:options] = options unless options.empty?
23
- params
24
- end
25
-
26
20
  def value_from_param(param)
27
21
  if param.is_a?(String) && param.present?
28
22
  (param.to_f % 1) > 0 ? param.to_f : param.to_i
@@ -30,6 +24,14 @@ module ViewComponent
30
24
  super(param)
31
25
  end
32
26
  end
27
+
28
+ private
29
+
30
+ def csf_control_params
31
+ params = super
32
+ params[:options] = options unless options.empty?
33
+ params
34
+ end
33
35
  end
34
36
  end
35
37
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class ObjectConfig < KnobConfig
5
+ module Controls
6
+ class ObjectConfig < ControlConfig
7
7
  validates :value, presence: true
8
8
 
9
9
  def type
@@ -2,8 +2,8 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class OptionsConfig < KnobConfig
5
+ module Controls
6
+ class OptionsConfig < ControlConfig
7
7
  TYPES = %i[select radios].freeze
8
8
 
9
9
  attr_reader :type, :options
@@ -12,13 +12,15 @@ module ViewComponent
12
12
  validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
13
13
  validates :value, inclusion: { in: ->(config) { config.options.values } }, unless: -> { options.nil? || value.nil? }
14
14
 
15
- def initialize(type, component, param, options, default_value, name: nil, group_id: nil)
16
- super(component, param, default_value, name: name, group_id: group_id)
15
+ def initialize(type, component, param, options, default_value, name: nil)
16
+ super(component, param, default_value, name: name)
17
17
  @type = type
18
18
  @options = options
19
19
  end
20
20
 
21
- def to_csf_params
21
+ private
22
+
23
+ def csf_control_params
22
24
  super.merge(options: options)
23
25
  end
24
26
  end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Knobs
6
- class SimpleConfig < KnobConfig
5
+ module Controls
6
+ class SimpleConfig < ControlConfig
7
7
  TYPES = %i[text boolean color].freeze
8
8
  BOOLEAN_VALUES = [true, false].freeze
9
9
 
@@ -15,8 +15,8 @@ module ViewComponent
15
15
  validates :type, presence: true
16
16
  validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
17
17
 
18
- def initialize(type, component, param, value, name: nil, group_id: nil)
19
- super(component, param, value, name: name, group_id: group_id)
18
+ def initialize(type, component, param, value, name: nil)
19
+ super(component, param, value, name: name)
20
20
  @type = type
21
21
  end
22
22
 
@@ -8,7 +8,7 @@ module ViewComponent
8
8
  extend ActiveSupport::Autoload
9
9
 
10
10
  autoload :StoryDsl
11
- autoload :KnobsDsl
11
+ autoload :ControlsDsl
12
12
  end
13
13
  end
14
14
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ module Storybook
5
+ module Dsl
6
+ class ControlsDsl
7
+ attr_reader :component, :controls
8
+
9
+ def initialize(component)
10
+ @component = component
11
+ @controls = []
12
+ end
13
+
14
+ def text(param, value, name: nil)
15
+ controls << Controls::SimpleConfig.new(:text, component, param, value, name: name)
16
+ end
17
+
18
+ def boolean(param, value, name: nil)
19
+ controls << Controls::SimpleConfig.new(:boolean, component, param, value, name: name)
20
+ end
21
+
22
+ def number(param, value, options = {}, name: nil)
23
+ controls << Controls::NumberConfig.new(component, param, value, options, name: name)
24
+ end
25
+
26
+ def color(param, value, name: nil)
27
+ controls << Controls::SimpleConfig.new(:color, component, param, value, name: name)
28
+ end
29
+
30
+ def object(param, value, name: nil)
31
+ controls << Controls::ObjectConfig.new(component, param, value, name: name)
32
+ end
33
+
34
+ def select(param, options, value, name: nil)
35
+ controls << Controls::OptionsConfig.new(:select, component, param, options, value, name: name)
36
+ end
37
+
38
+ def radios(param, options, value, name: nil)
39
+ controls << Controls::OptionsConfig.new(:radios, component, param, options, value, name: name)
40
+ end
41
+
42
+ def array(param, value, separator = ",", name: nil)
43
+ controls << Controls::ArrayConfig.new(component, param, value, separator, name: name)
44
+ end
45
+
46
+ def date(param, value, name: nil)
47
+ controls << Controls::DateConfig.new(component, param, value, name: name)
48
+ end
49
+
50
+ def respond_to_missing?(_method)
51
+ true
52
+ end
53
+
54
+ def method_missing(method, *args)
55
+ value = args.first
56
+ knob_method = case value
57
+ when Date
58
+ :date
59
+ when Array
60
+ :array
61
+ when Hash
62
+ :object
63
+ when Numeric
64
+ :number
65
+ when TrueClass, FalseClass
66
+ :boolean
67
+ when String
68
+ :text
69
+ end
70
+ if knob_method
71
+ send(knob_method, method, *args)
72
+ else
73
+ super
74
+ end
75
+ end
76
+
77
+ Controls = ViewComponent::Storybook::Controls
78
+ end
79
+ end
80
+ end
81
+ end
@@ -12,10 +12,10 @@ module ViewComponent
12
12
  @story_config.parameters = params
13
13
  end
14
14
 
15
- def knobs(&block)
16
- knobs_dsl = KnobsDsl.new(story_config.component)
17
- knobs_dsl.instance_eval(&block)
18
- @story_config.knobs = knobs_dsl.knobs
15
+ def controls(&block)
16
+ controls_dsl = ControlsDsl.new(story_config.component)
17
+ controls_dsl.instance_eval(&block)
18
+ @story_config.controls = controls_dsl.controls
19
19
  end
20
20
 
21
21
  def layout(layout)
@@ -26,10 +26,7 @@ module ViewComponent
26
26
  end
27
27
 
28
28
  def to_csf_params
29
- stories_csf = story_configs.map(&:to_csf_params)
30
-
31
29
  csf_params = { title: title }
32
- csf_params[:addons] = ["knobs"] if stories_csf.any? { |csf| csf.key?(:knobs) }
33
30
  csf_params[:parameters] = parameters if parameters.present?
34
31
  csf_params[:stories] = story_configs.map(&:to_csf_params)
35
32
  csf_params
@@ -6,28 +6,30 @@ module ViewComponent
6
6
  include ActiveModel::Validations
7
7
 
8
8
  attr_reader :id, :name, :component
9
- attr_accessor :knobs, :parameters, :layout, :content_block
9
+ attr_accessor :controls, :parameters, :layout, :content_block
10
10
 
11
11
  def initialize(id, name, component, layout)
12
12
  @id = id
13
13
  @name = name
14
14
  @component = component
15
15
  @layout = layout
16
- @knobs = []
16
+ @controls = []
17
17
  end
18
18
 
19
19
  def to_csf_params
20
20
  csf_params = { name: name, parameters: { server: { id: id } } }
21
21
  csf_params.deep_merge!(parameters: parameters) if parameters.present?
22
- csf_params[:knobs] = knobs.map(&:to_csf_params) if knobs.present?
22
+ controls.each do |control|
23
+ csf_params.deep_merge!(control.to_csf_params)
24
+ end
23
25
  csf_params
24
26
  end
25
27
 
26
28
  def values_from_params(params)
27
- knobs.map do |knob|
28
- value = knob.value_from_param(params[knob.param])
29
- value = knob.value if value.nil? # nil only not falsey
30
- [knob.param, value]
29
+ controls.map do |control|
30
+ value = control.value_from_param(params[control.param])
31
+ value = control.value if value.nil? # nil only not falsey
32
+ [control.param, value]
31
33
  end.to_h
32
34
  end
33
35
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- VERSION = "0.2.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: view_component_storybook
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Palmer
@@ -162,18 +162,18 @@ files:
162
162
  - app/controllers/view_component/storybook/stories_controller.rb
163
163
  - app/views/view_component/storybook/stories/show.html.erb
164
164
  - lib/view_component/storybook.rb
165
+ - lib/view_component/storybook/controls.rb
166
+ - lib/view_component/storybook/controls/array_config.rb
167
+ - lib/view_component/storybook/controls/control_config.rb
168
+ - lib/view_component/storybook/controls/date_config.rb
169
+ - lib/view_component/storybook/controls/number_config.rb
170
+ - lib/view_component/storybook/controls/object_config.rb
171
+ - lib/view_component/storybook/controls/options_config.rb
172
+ - lib/view_component/storybook/controls/simple_config.rb
165
173
  - lib/view_component/storybook/dsl.rb
166
- - lib/view_component/storybook/dsl/knobs_dsl.rb
174
+ - lib/view_component/storybook/dsl/controls_dsl.rb
167
175
  - lib/view_component/storybook/dsl/story_dsl.rb
168
176
  - lib/view_component/storybook/engine.rb
169
- - lib/view_component/storybook/knobs.rb
170
- - lib/view_component/storybook/knobs/array_config.rb
171
- - lib/view_component/storybook/knobs/date_config.rb
172
- - lib/view_component/storybook/knobs/knob_config.rb
173
- - lib/view_component/storybook/knobs/number_config.rb
174
- - lib/view_component/storybook/knobs/object_config.rb
175
- - lib/view_component/storybook/knobs/options_config.rb
176
- - lib/view_component/storybook/knobs/simple_config.rb
177
177
  - lib/view_component/storybook/stories.rb
178
178
  - lib/view_component/storybook/story_config.rb
179
179
  - lib/view_component/storybook/tasks/write_stories_json.rake
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ViewComponent
4
- module Storybook
5
- module Dsl
6
- class KnobsDsl
7
- attr_reader :component, :knobs
8
-
9
- def initialize(component)
10
- @component = component
11
- @knobs = []
12
- end
13
-
14
- def text(param, value, group_id: nil, name: nil)
15
- knobs << Knobs::SimpleConfig.new(:text, component, param, value, group_id: group_id, name: name)
16
- end
17
-
18
- def boolean(param, value, group_id: nil, name: nil)
19
- knobs << Knobs::SimpleConfig.new(:boolean, component, param, value, group_id: group_id, name: name)
20
- end
21
-
22
- def number(param, value, options = {}, group_id: nil, name: nil)
23
- knobs << Knobs::NumberConfig.new(component, param, value, options, group_id: group_id, name: name)
24
- end
25
-
26
- def color(param, value, group_id: nil, name: nil)
27
- knobs << Knobs::SimpleConfig.new(:color, component, param, value, group_id: group_id, name: name)
28
- end
29
-
30
- def object(param, value, group_id: nil, name: nil)
31
- knobs << Knobs::ObjectConfig.new(component, param, value, group_id: group_id, name: name)
32
- end
33
-
34
- def select(param, options, value, group_id: nil, name: nil)
35
- knobs << Knobs::OptionsConfig.new(:select, component, param, options, value, group_id: group_id, name: name)
36
- end
37
-
38
- def radios(param, options, value, group_id: nil, name: nil)
39
- knobs << Knobs::OptionsConfig.new(:radios, component, param, options, value, group_id: group_id, name: name)
40
- end
41
-
42
- def array(param, value, separator = ",", group_id: nil, name: nil)
43
- knobs << Knobs::ArrayConfig.new(component, param, value, separator, group_id: group_id, name: name)
44
- end
45
-
46
- def date(param, value, group_id: nil, name: nil)
47
- knobs << Knobs::DateConfig.new(component, param, value, group_id: group_id, name: name)
48
- end
49
-
50
- def respond_to_missing?(_method)
51
- true
52
- end
53
-
54
- def method_missing(method, *args)
55
- value = args.first
56
- knob_method = case value
57
- when Date
58
- :date
59
- when Array
60
- :array
61
- when Hash
62
- :object
63
- when Numeric
64
- :number
65
- when TrueClass, FalseClass
66
- :boolean
67
- when String
68
- :text
69
- end
70
- if knob_method
71
- send(knob_method, method, *args)
72
- else
73
- super
74
- end
75
- end
76
-
77
- Knobs = ViewComponent::Storybook::Knobs
78
- end
79
- end
80
- end
81
- end