view_component_storybook 0.9.0 → 0.11.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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -138
  3. data/app/controllers/view_component/storybook/stories_controller.rb +9 -11
  4. data/app/views/view_component/storybook/stories/show.html.erb +8 -3
  5. data/config/locales/en.yml +1 -1
  6. data/lib/view_component/storybook/content_concern.rb +42 -0
  7. data/lib/view_component/storybook/controls/base_options_config.rb +41 -0
  8. data/lib/view_component/storybook/controls/control_config.rb +4 -0
  9. data/lib/view_component/storybook/{dsl/controls_dsl.rb → controls/controls_helpers.rb} +21 -16
  10. data/lib/view_component/storybook/controls/custom_config.rb +2 -4
  11. data/lib/view_component/storybook/controls/multi_options_config.rb +46 -0
  12. data/lib/view_component/storybook/controls/object_config.rb +3 -1
  13. data/lib/view_component/storybook/controls/options_config.rb +12 -26
  14. data/lib/view_component/storybook/controls/simple_control_config.rb +1 -1
  15. data/lib/view_component/storybook/controls.rb +3 -1
  16. data/lib/view_component/storybook/dsl/legacy_controls_dsl.rb +2 -2
  17. data/lib/view_component/storybook/dsl.rb +0 -2
  18. data/lib/view_component/storybook/engine.rb +13 -2
  19. data/lib/view_component/storybook/method_args/component_constructor_args.rb +23 -0
  20. data/lib/view_component/storybook/method_args/control_method_args.rb +15 -12
  21. data/lib/view_component/storybook/method_args/dry_initializer_component_constructor_args.rb +45 -0
  22. data/lib/view_component/storybook/method_args/method_args.rb +37 -4
  23. data/lib/view_component/storybook/method_args/method_parameters_names.rb +1 -1
  24. data/lib/view_component/storybook/method_args.rb +2 -1
  25. data/lib/view_component/storybook/slots/slot.rb +24 -0
  26. data/lib/view_component/storybook/slots/slot_config.rb +79 -0
  27. data/lib/view_component/storybook/slots.rb +14 -0
  28. data/lib/view_component/storybook/stories.rb +17 -10
  29. data/lib/view_component/storybook/story.rb +18 -0
  30. data/lib/view_component/storybook/story_config.rb +120 -26
  31. data/lib/view_component/storybook/tasks/write_stories_json.rake +1 -1
  32. data/lib/view_component/storybook/version.rb +1 -1
  33. data/lib/view_component/storybook.rb +23 -2
  34. metadata +43 -8
  35. data/lib/view_component/storybook/controls/array_config.rb +0 -37
  36. data/lib/view_component/storybook/dsl/story_dsl.rb +0 -51
  37. data/lib/view_component/storybook/method_args/validatable_method_args.rb +0 -50
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8ab883711eb6c712fcb3f654fdcb80586091f6da753e311f2609347d600391e
4
- data.tar.gz: 65ba53ff31930882f7c2a30492e5444ed438be268cfbb24291160ff38f712964
3
+ metadata.gz: d9748db108a30faac96e4e6f793cfd9b62a47c8f8e03fa83d4518f670bf7fb42
4
+ data.tar.gz: b1b6140fd9ad5dc1ff4a281a93f6d5384792ab04c5030531f23e4127854e2819
5
5
  SHA512:
6
- metadata.gz: 24bf672f2214344c1d5b9e1af7bbe8ef51ddb8ba6065eca4b12b14e0c8b73f69381168b39d3f4339e953a086ec11d69f716f3fce7dfb8acd7efaabd3678cb578
7
- data.tar.gz: 0df0d064cccf1ed1d625ba1d9cb439d8c3fb65f56a7671e3d65650dc85604ea89990e578ca4550863388d7cfc201b7cd33b7add24f294deb6646b1753062c03a
6
+ metadata.gz: a8bd26bfe7ccb8c2b30b1f989056c7b294ea99b6ae3e53a7b5bb87ef85a667e169dbc362f7681887bb8a8a6ab57d022afaa164b7846d8d667b63efaef4bfbb97
7
+ data.tar.gz: c04e250070f402802fb94e3807a0c65e1e9af54534f03480fc0e5abc46781f3e9d34c54da282bc81cec944be3c8a5585c690ac4f6d68ac4597a429f82627fd4f
data/README.md CHANGED
@@ -3,151 +3,19 @@
3
3
  The ViewComponent::Storybook gem provides Ruby api for writing stories describing [View Components](https://github.com/github/view_component) and allowing them to be previewed and tested in [Storybook](https://github.com/storybookjs/storybook/) via its [Server](https://github.com/storybookjs/storybook/tree/next/app/server) support.
4
4
 
5
5
  ## Features
6
- * A Ruby DSL for writing Stories describing View Components
7
- * A Rails controller backend for Storybook Server compatible with Storybook Controls Addon parameters
8
- * Coming Soon: Rake tasks to watch View Components and Stories and trigger Storybook hot reloading
9
6
 
10
- ## Installation
7
+ - A Ruby DSL for writing Stories describing View Components
8
+ - A Rails controller backend for Storybook Server compatible with Storybook Controls Addon parameters
9
+ - Coming Soon: Rake tasks to watch View Components and Stories and trigger Storybook hot reloading
11
10
 
12
- ### Rails Installation
11
+ ## Documentation
13
12
 
14
- 1. Add the `view_component_storybook` gem, to your Gemfile: `gem 'view_component_storybook'`
15
- 2. Run `bundle install`.
16
- 3. Add `require "view_component/storybook/engine"` to `config/application.rb`
17
- 4. Add `**/*.stories.json` to `.gitignore`
18
-
19
- #### Configure Asset Hosts
20
-
21
- If your view components depend on Javascript, CSS or other assets served by the Rails application you will need to configure `asset_hosts`
22
- apporpriately for your various environments. For local development this is a simple as adding to `config/development.rb`:
23
- ```ruby
24
- Rails.application.configure do
25
- ...
26
- config.action_controller.asset_host = 'http://localhost:3000'
27
- ...
28
- end
29
- ```
30
- Equivalent configuration will be necessary in `config/production.rb` or `application.rb` based you your deployment environments.
31
-
32
- ### Storybook Installation
33
-
34
- 1. Add Storybook server as a dev dependedncy. The Storybook Controls addon isn't needed but is strongly recommended
35
- ```sh
36
- yarn add @storybook/server @storybook/addon-controls --dev
37
- ```
38
- 2. Add an NPM script to your package.json in order to start the storybook later in this guide
39
- ```json
40
- {
41
- "scripts": {
42
- "storybook": "start-storybook"
43
- }
44
- }
45
- ```
46
- 3. Create the .storybook/main.js file to configure Storybook to find the json stories the gem creates. Also configure the Controls addon:
47
- ```javascript
48
- module.exports = {
49
- stories: ['../test/components/**/*.stories.json'],
50
- addons: [
51
- '@storybook/addon-controls',
52
- ],
53
- };
54
- ```
55
- 4. Create the .storybook/preview.js file to configure Storybook with the Rails application url to call for the html content of the stories
56
- ```javascript
57
-
58
- export const parameters = {
59
- server: {
60
- url: `http://localhost:3000/rails/stories`,
61
- },
62
- };
63
- ```
64
-
65
-
66
- ## Usage
67
-
68
- ### Writing Stories
69
-
70
- `ViewComponent::Storybook::Stories` provides a way to preview components in Storybook.
71
-
72
- Suppose our app has a `ButtonComponent` that takes a `button_text` parameter:
73
-
74
- ```ruby
75
- class ButtonComponent < ViewComponent::Base
76
- def initialize(button_text:)
77
- @button_text = button_text
78
- end
79
- end
80
- ```
81
-
82
- We can write a stories describing the `ButtonComponent`
83
-
84
- ```ruby
85
- class ButtonComponentStories < ViewComponent::Storybook::Stories
86
- story(:with_short_text) do
87
- controls do
88
- text(:button_text, 'OK')
89
- end
90
- end
91
-
92
- story(:with_long_text) do
93
- controls do
94
- text(:button_text, 'Push Me Please!')
95
- end
96
- end
97
- end
98
- ```
99
-
100
- ### Generating Storybook Stories JSON
101
-
102
- Generate the Storybook JSON stories by running the rake task:
103
- ```sh
104
- rake view_component_storybook:write_stories_json
105
- ```
106
-
107
- ### Start the Rails app and Storybook
108
-
109
- In separate shells start the Rails app and Storybook
110
-
111
- ```sh
112
- rails s
113
- ```
114
- ```sh
115
- yarn storybook
116
- ```
117
-
118
- Alternatively you can use tools like [Foreman](https://github.com/ddollar/foreman) to start both Rails and Storybook with one command.
119
-
120
- ### Configuration
121
-
122
- By Default ViewComponent::Storybook expects to find stories in the folder `test/components/stories`. This can be configured by setting `stories_path` in `config/application.rb`. For example if you're using RSpec you might set the following configuration:
123
-
124
- ```ruby
125
- config.view_component_storybook.stories_path = Rails.root.join("spec/components/stories")
126
- ```
127
-
128
- ### The Story DSL
129
-
130
- Coming Soon
131
-
132
- #### Parameters
133
- #### Layout
134
- #### Controls
135
-
136
-
137
- ## Development
138
-
139
- 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.
140
-
141
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
13
+ See [jonspalmer.github.io/view_component_storybook](https://jonspalmer.github.io/view_component_storybook) for documentation.
142
14
 
143
15
  ## Contributing
144
16
 
145
- Bug reports and pull requests are welcome on GitHub at https://github.com/jonspalmer/view_component_storybook. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
17
+ This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./docs/CONTRIBUTING.md) as well.
146
18
 
147
19
  ## License
148
20
 
149
21
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
150
-
151
- ## Code of Conduct
152
-
153
- Everyone interacting in the ViewComponent::Storybook project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/jonspalmer/view_component_storybook/blob/master/CODE_OF_CONDUCT.md).
@@ -8,20 +8,18 @@ module ViewComponent
8
8
  prepend_view_path File.expand_path("../../../views", __dir__)
9
9
  prepend_view_path Rails.root.join("app/views") if defined?(Rails.root)
10
10
 
11
- before_action :find_stories, :find_story, only: :show
11
+ before_action :find_story_configs, :find_story_config, only: :show
12
12
  before_action :require_local!, unless: :show_stories?
13
13
 
14
14
  content_security_policy(false) if respond_to?(:content_security_policy)
15
15
 
16
16
  def show
17
17
  params_hash = params.permit!.to_h
18
- method_args = @story.constructor_args.resolve_method_args(params_hash)
19
18
 
20
- @content_block = @story.content_block
19
+ @story = @story_config.story(params_hash)
21
20
 
22
- @component = @story.component.new(*method_args.args, **method_args.kwargs)
21
+ layout = @story_config.layout
23
22
 
24
- layout = @story.layout
25
23
  render layout: layout unless layout.nil?
26
24
  end
27
25
 
@@ -31,17 +29,17 @@ module ViewComponent
31
29
  ViewComponent::Storybook.show_stories
32
30
  end
33
31
 
34
- def find_stories
32
+ def find_story_configs
35
33
  stories_name = params[:stories]
36
- @stories = ViewComponent::Storybook::Stories.find_stories(stories_name)
34
+ @story_configs = Stories.find_story_configs(stories_name)
37
35
 
38
- head :not_found unless @stories
36
+ head :not_found unless @story_configs
39
37
  end
40
38
 
41
- def find_story
39
+ def find_story_config
42
40
  story_name = params[:story]
43
- @story = @stories.find_story(story_name)
44
- head :not_found unless @story
41
+ @story_config = @story_configs.find_story_config(story_name)
42
+ head :not_found unless @story_config
45
43
  end
46
44
  end
47
45
  end
@@ -1,3 +1,8 @@
1
- <%= render(@component) do -%>
2
- <%= instance_eval(&@content_block) -%>
3
- <% end %>
1
+ <%= render(@story.component) do |c| -%>
2
+ <% @story.slots.each do |slot| -%>
3
+ <%- slot.call do -%>
4
+ <%= instance_eval(&slot.content_block) if slot.content_block -%>
5
+ <%- end -%>
6
+ <%- end -%>
7
+ <%- instance_eval(&@story.content_block) if @story.content_block -%>
8
+ <%- end -%>
@@ -2,7 +2,7 @@ en:
2
2
  activemodel:
3
3
  errors:
4
4
  models:
5
- view_component/storybook/method_args/validatable_method_args:
5
+ view_component/storybook/method_args/method_args:
6
6
  attributes:
7
7
  args:
8
8
  too_few: expected at least %{min} but found %{count}
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ module Storybook
5
+ module ContentConcern
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ attr_reader :content_control, :content_block
10
+ end
11
+
12
+ def content(content = nil, &block)
13
+ case content
14
+ when Storybook::Controls::ControlConfig
15
+ @content_control = content.param(content_param)
16
+ @content_block = nil
17
+ when String
18
+ @content_control = nil
19
+ @content_block = proc { content }
20
+ else
21
+ @content_control = nil
22
+ @content_block = block
23
+ end
24
+ end
25
+
26
+ def resolve_content_block(params)
27
+ if content_control
28
+ content = content_control.value_from_params(params)
29
+ proc { content }
30
+ else
31
+ content_block
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def content_param
38
+ :content
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ module Storybook
5
+ module Controls
6
+ class BaseOptionsConfig < SimpleControlConfig
7
+ attr_reader :type, :options, :labels
8
+
9
+ validates :type, :options, presence: true
10
+
11
+ def initialize(type, options, default_value, labels: nil, param: nil, name: nil)
12
+ super(default_value, param: param, name: name)
13
+ @type = type
14
+ @options = options
15
+ @labels = labels
16
+ normalize_options
17
+ end
18
+
19
+ def to_csf_params
20
+ super.deep_merge(argTypes: { param => { options: options } })
21
+ end
22
+
23
+ private
24
+
25
+ def csf_control_params
26
+ labels.nil? ? super : super.merge(labels: labels)
27
+ end
28
+
29
+ def normalize_options
30
+ return unless options.is_a?(Hash)
31
+
32
+ warning = "Hash options is deprecated and will be removed in v1.0.0. Use array options and `labels` instead."
33
+ ActiveSupport::Deprecation.warn(warning)
34
+
35
+ @labels = options.invert
36
+ @options = options.values
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -29,6 +29,10 @@ module ViewComponent
29
29
  self
30
30
  end
31
31
 
32
+ def prefix_param(prefix)
33
+ param("#{prefix}__#{@param}".to_sym)
34
+ end
35
+
32
36
  def to_csf_params
33
37
  # :nocov:
34
38
  raise NotImplementedError
@@ -2,8 +2,8 @@
2
2
 
3
3
  module ViewComponent
4
4
  module Storybook
5
- module Dsl
6
- module ControlsDsl
5
+ module Controls
6
+ module ControlsHelpers
7
7
  def text(default_value)
8
8
  Controls::TextConfig.new(default_value)
9
9
  end
@@ -28,32 +28,33 @@ module ViewComponent
28
28
  Controls::ObjectConfig.new(default_value)
29
29
  end
30
30
 
31
- def select(options, default_value)
32
- Controls::OptionsConfig.new(:select, options, default_value)
31
+ def select(options, default_value, labels: nil)
32
+ Controls::OptionsConfig.new(:select, options, default_value, labels: labels)
33
33
  end
34
34
 
35
- def multi_select(options, default_value)
36
- Controls::OptionsConfig.new(:'multi-select', options, default_value)
35
+ def multi_select(options, default_value, labels: nil)
36
+ Controls::MultiOptionsConfig.new(:'multi-select', options, default_value, labels: labels)
37
37
  end
38
38
 
39
- def radio(options, default_value)
40
- Controls::OptionsConfig.new(:radio, options, default_value)
39
+ def radio(options, default_value, labels: nil)
40
+ Controls::OptionsConfig.new(:radio, options, default_value, labels: labels)
41
41
  end
42
42
 
43
- def inline_radio(options, default_value)
44
- Controls::OptionsConfig.new(:'inline-radio', options, default_value)
43
+ def inline_radio(options, default_value, labels: nil)
44
+ Controls::OptionsConfig.new(:'inline-radio', options, default_value, labels: labels)
45
45
  end
46
46
 
47
- def check(options, default_value)
48
- Controls::OptionsConfig.new(:check, options, default_value)
47
+ def check(options, default_value, labels: nil)
48
+ Controls::MultiOptionsConfig.new(:check, options, default_value, labels: labels)
49
49
  end
50
50
 
51
51
  def inline_check(options, default_value)
52
- Controls::OptionsConfig.new(:'inline-check', options, default_value)
52
+ Controls::MultiOptionsConfig.new(:'inline-check', options, default_value)
53
53
  end
54
54
 
55
- def array(default_value, separator = ",")
56
- Controls::ArrayConfig.new(default_value, separator)
55
+ def array(default_value, separator = nil)
56
+ ActiveSupport::Deprecation.warn("`array` `separator` argument will be removed in v1.0.0.") if separator
57
+ Controls::ObjectConfig.new(default_value)
57
58
  end
58
59
 
59
60
  def date(default_value)
@@ -64,7 +65,11 @@ module ViewComponent
64
65
  Controls::CustomConfig.new.with_value(*args, **kwargs, &block)
65
66
  end
66
67
 
67
- Controls = ViewComponent::Storybook::Controls
68
+ def klazz(value_class, *args, **kwargs)
69
+ Controls::CustomConfig.new.with_value(*args, **kwargs) do |*a, **kwa|
70
+ value_class.new(*a, **kwa)
71
+ end
72
+ end
68
73
  end
69
74
  end
70
75
  end
@@ -9,7 +9,7 @@ module ViewComponent
9
9
  validate :validate_value_method_args
10
10
 
11
11
  def with_value(*args, **kwargs, &block)
12
- @value_method_args = ViewComponent::Storybook::MethodArgs::ControlMethodArgs.new(block, *args, **kwargs, &block)
12
+ @value_method_args = MethodArgs::ControlMethodArgs.new(block, *args, **kwargs)
13
13
  @value_method_args.with_param_prefix(param)
14
14
  self
15
15
  end
@@ -35,9 +35,7 @@ module ViewComponent
35
35
  end
36
36
 
37
37
  def value_from_params(params)
38
- method_args = value_method_args.resolve_method_args(params)
39
-
40
- method_args.block.call(*method_args.args, **method_args.kwargs)
38
+ value_method_args.call(params)
41
39
  end
42
40
 
43
41
  private
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ module Storybook
5
+ module Controls
6
+ class MultiOptionsConfig < BaseOptionsConfig
7
+ TYPES = %i[multi-select check inline-check].freeze
8
+
9
+ validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
10
+ validate :validate_default_value, unless: -> { options.nil? || default_value.nil? }
11
+
12
+ def initialize(type, options, default_value, labels: nil, param: nil, name: nil)
13
+ super(type, options, Array.wrap(default_value), labels: labels, param: param, name: name)
14
+ end
15
+
16
+ def value_from_params(params)
17
+ params_value = super(params)
18
+
19
+ if params_value.is_a?(String)
20
+ params_value = params_value.split(',')
21
+ params_value = params_value.map(&:to_sym) if symbol_values
22
+ end
23
+ params_value
24
+ end
25
+
26
+ def to_csf_params
27
+ super.deep_merge(argTypes: { param => { options: options } })
28
+ end
29
+
30
+ private
31
+
32
+ def csf_control_params
33
+ labels.nil? ? super : super.merge(labels: labels)
34
+ end
35
+
36
+ def symbol_values
37
+ @symbol_values ||= default_value.first.is_a?(Symbol)
38
+ end
39
+
40
+ def validate_default_value
41
+ errors.add(:default_value, :inclusion) unless default_value.to_set <= options.to_set
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -13,7 +13,9 @@ module ViewComponent
13
13
  if params_value.is_a?(String)
14
14
  parsed_json = JSON.parse(params_value)
15
15
  if parsed_json.is_a?(Array)
16
- parsed_json.map(&:deep_symbolize_keys)
16
+ parsed_json.map do |item|
17
+ item.is_a?(Hash) ? item.deep_symbolize_keys : item
18
+ end
17
19
  else
18
20
  parsed_json.deep_symbolize_keys
19
21
  end
@@ -3,33 +3,11 @@
3
3
  module ViewComponent
4
4
  module Storybook
5
5
  module Controls
6
- class OptionsConfig < SimpleControlConfig
7
- class << self
8
- # support the options being a Hash or an Array. Storybook supports either.
9
- def inclusion_in(config)
10
- case config.options
11
- when Hash
12
- config.options.values
13
- when Array
14
- config.options
15
- end
16
- end
17
- end
18
-
19
- TYPES = %i[select multi-select radio inline-radio check inline-check].freeze
6
+ class OptionsConfig < BaseOptionsConfig
7
+ TYPES = %i[select radio inline-radio].freeze
20
8
 
21
- attr_reader :type, :options, :symbol_value
22
-
23
- validates :type, :options, presence: true
24
9
  validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
25
- validates :default_value, inclusion: { in: method(:inclusion_in) }, unless: -> { options.nil? || default_value.nil? }
26
-
27
- def initialize(type, options, default_value, param: nil, name: nil)
28
- super(default_value, param: param, name: name)
29
- @type = type
30
- @options = options
31
- @symbol_value = default_value.is_a?(Symbol)
32
- end
10
+ validates :default_value, inclusion: { in: ->(config) { config.options } }, unless: -> { options.nil? || default_value.nil? }
33
11
 
34
12
  def value_from_params(params)
35
13
  params_value = super(params)
@@ -40,10 +18,18 @@ module ViewComponent
40
18
  end
41
19
  end
42
20
 
21
+ def to_csf_params
22
+ super.deep_merge(argTypes: { param => { options: options } })
23
+ end
24
+
43
25
  private
44
26
 
45
27
  def csf_control_params
46
- super.merge(options: options)
28
+ labels.nil? ? super : super.merge(labels: labels)
29
+ end
30
+
31
+ def symbol_value
32
+ @symbol_value ||= default_value.is_a?(Symbol)
47
33
  end
48
34
  end
49
35
  end
@@ -23,7 +23,7 @@ module ViewComponent
23
23
  end
24
24
 
25
25
  def value_from_params(params)
26
- params[param]
26
+ params.key?(param) ? params[param] : default_value
27
27
  end
28
28
 
29
29
  private
@@ -13,11 +13,13 @@ module ViewComponent
13
13
  autoload :BooleanConfig
14
14
  autoload :ColorConfig
15
15
  autoload :NumberConfig
16
+ autoload :BaseOptionsConfig
16
17
  autoload :OptionsConfig
17
- autoload :ArrayConfig
18
+ autoload :MultiOptionsConfig
18
19
  autoload :DateConfig
19
20
  autoload :ObjectConfig
20
21
  autoload :CustomConfig
22
+ autoload :ControlsHelpers
21
23
  end
22
24
  end
23
25
  end
@@ -56,8 +56,8 @@ module ViewComponent
56
56
  controls << Controls::OptionsConfig.new(:'inline-check', options, value, param: param, name: name)
57
57
  end
58
58
 
59
- def array(param, value, separator = ",", name: nil)
60
- controls << Controls::ArrayConfig.new(value, separator, param: param, name: name)
59
+ def array(param, value, _separator = nil, name: nil)
60
+ controls << Controls::ObjectConfig.new(value, param: param, name: name)
61
61
  end
62
62
 
63
63
  def date(param, value, name: nil)
@@ -7,8 +7,6 @@ module ViewComponent
7
7
  module Dsl
8
8
  extend ActiveSupport::Autoload
9
9
 
10
- autoload :StoryDsl
11
- autoload :ControlsDsl
12
10
  autoload :LegacyControlsDsl
13
11
  end
14
12
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails"
4
- require "view_component/storybook"
5
4
 
6
5
  module ViewComponent
7
6
  module Storybook
@@ -12,6 +11,7 @@ module ViewComponent
12
11
  options = app.config.view_component_storybook
13
12
 
14
13
  options.show_stories = Rails.env.development? if options.show_stories.nil?
14
+ options.stories_route ||= "/rails/stories"
15
15
 
16
16
  if options.show_stories
17
17
  options.stories_path ||= defined?(Rails.root) ? Rails.root.join("test/components/stories") : nil
@@ -33,7 +33,7 @@ module ViewComponent
33
33
 
34
34
  if options.show_stories
35
35
  app.routes.prepend do
36
- get "/rails/stories/*stories/:story" => "view_component/storybook/stories#show", :internal => true
36
+ get "#{options.stories_route}/*stories/:story" => "view_component/storybook/stories#show", :internal => true
37
37
  end
38
38
  end
39
39
  end
@@ -44,3 +44,14 @@ module ViewComponent
44
44
  end
45
45
  end
46
46
  end
47
+
48
+ # :nocov:
49
+ unless defined?(ViewComponent::Storybook::Stories)
50
+ ActiveSupport::Deprecation.warn(
51
+ "This manually engine loading is deprecated and will be removed in v1.0.0. " \
52
+ "Remove `require \"view_component/storybook/engine\"`."
53
+ )
54
+
55
+ require "view_component/storybook"
56
+ end
57
+ # :nocov:
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ViewComponent
4
+ module Storybook
5
+ module MethodArgs
6
+ ##
7
+ # Class representing the constructor args for a Component
8
+ class ComponentConstructorArgs < ControlMethodArgs
9
+ def self.from_component_class(component_class, *args, **kwargs)
10
+ if DryInitializerComponentConstructorArgs.dry_initialize?(component_class)
11
+ DryInitializerComponentConstructorArgs.new(component_class, *args, **kwargs)
12
+ else
13
+ new(component_class, *args, **kwargs)
14
+ end
15
+ end
16
+
17
+ def initialize(component_class, *args, **kwargs)
18
+ super(component_class.instance_method(:initialize), *args, **kwargs)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end