view_component_storybook 0.3.0 → 0.9.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 +4 -4
- data/README.md +22 -11
- data/app/controllers/view_component/storybook/stories_controller.rb +3 -2
- data/app/views/view_component/storybook/stories/show.html.erb +3 -1
- data/config/locales/en.yml +32 -0
- data/lib/view_component/storybook.rb +2 -1
- data/lib/view_component/storybook/controls.rb +5 -1
- data/lib/view_component/storybook/controls/array_config.rb +9 -8
- data/lib/view_component/storybook/controls/boolean_config.rb +31 -0
- data/lib/view_component/storybook/controls/color_config.rb +26 -0
- data/lib/view_component/storybook/controls/control_config.rb +22 -26
- data/lib/view_component/storybook/controls/custom_config.rb +54 -0
- data/lib/view_component/storybook/controls/date_config.rb +14 -13
- data/lib/view_component/storybook/controls/number_config.rb +17 -16
- data/lib/view_component/storybook/controls/object_config.rb +11 -7
- data/lib/view_component/storybook/controls/options_config.rb +29 -7
- data/lib/view_component/storybook/controls/simple_control_config.rb +48 -0
- data/lib/view_component/storybook/controls/text_config.rb +13 -0
- data/lib/view_component/storybook/dsl.rb +1 -0
- data/lib/view_component/storybook/dsl/controls_dsl.rb +36 -46
- data/lib/view_component/storybook/dsl/legacy_controls_dsl.rb +98 -0
- data/lib/view_component/storybook/dsl/story_dsl.rb +17 -5
- data/lib/view_component/storybook/method_args.rb +16 -0
- data/lib/view_component/storybook/method_args/control_method_args.rb +88 -0
- data/lib/view_component/storybook/method_args/method_args.rb +19 -0
- data/lib/view_component/storybook/method_args/method_parameters_names.rb +97 -0
- data/lib/view_component/storybook/method_args/validatable_method_args.rb +50 -0
- data/lib/view_component/storybook/stories.rb +44 -7
- data/lib/view_component/storybook/story_config.rb +43 -9
- data/lib/view_component/storybook/tasks/write_stories_json.rake +6 -0
- data/lib/view_component/storybook/version.rb +1 -1
- metadata +43 -18
- data/lib/view_component/storybook/controls/simple_config.rb +0 -38
@@ -3,34 +3,35 @@
|
|
3
3
|
module ViewComponent
|
4
4
|
module Storybook
|
5
5
|
module Controls
|
6
|
-
class NumberConfig <
|
7
|
-
|
6
|
+
class NumberConfig < SimpleControlConfig
|
7
|
+
TYPES = %i[number range].freeze
|
8
8
|
|
9
|
-
|
9
|
+
attr_reader :type, :min, :max, :step
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
@options = options
|
14
|
-
end
|
11
|
+
validates :type, presence: true
|
12
|
+
validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
|
15
13
|
|
16
|
-
def type
|
17
|
-
:
|
14
|
+
def initialize(type, default_value, min: nil, max: nil, step: nil, param: nil, name: nil)
|
15
|
+
super(default_value, param: param, name: name)
|
16
|
+
@type = type
|
17
|
+
@min = min
|
18
|
+
@max = max
|
19
|
+
@step = step
|
18
20
|
end
|
19
21
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
22
|
+
def value_from_params(params)
|
23
|
+
params_value = super(params)
|
24
|
+
if params_value.is_a?(String) && params_value.present?
|
25
|
+
(params_value.to_f % 1) > 0 ? params_value.to_f : params_value.to_i
|
23
26
|
else
|
24
|
-
|
27
|
+
params_value
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
28
31
|
private
|
29
32
|
|
30
33
|
def csf_control_params
|
31
|
-
|
32
|
-
params[:options] = options unless options.empty?
|
33
|
-
params
|
34
|
+
super.merge(min: min, max: max, step: step).compact
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -3,18 +3,22 @@
|
|
3
3
|
module ViewComponent
|
4
4
|
module Storybook
|
5
5
|
module Controls
|
6
|
-
class ObjectConfig <
|
7
|
-
validates :value, presence: true
|
8
|
-
|
6
|
+
class ObjectConfig < SimpleControlConfig
|
9
7
|
def type
|
10
8
|
:object
|
11
9
|
end
|
12
10
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
11
|
+
def value_from_params(params)
|
12
|
+
params_value = super(params)
|
13
|
+
if params_value.is_a?(String)
|
14
|
+
parsed_json = JSON.parse(params_value)
|
15
|
+
if parsed_json.is_a?(Array)
|
16
|
+
parsed_json.map(&:deep_symbolize_keys)
|
17
|
+
else
|
18
|
+
parsed_json.deep_symbolize_keys
|
19
|
+
end
|
16
20
|
else
|
17
|
-
|
21
|
+
params_value
|
18
22
|
end
|
19
23
|
end
|
20
24
|
end
|
@@ -3,19 +3,41 @@
|
|
3
3
|
module ViewComponent
|
4
4
|
module Storybook
|
5
5
|
module Controls
|
6
|
-
class OptionsConfig <
|
7
|
-
|
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
|
8
20
|
|
9
|
-
attr_reader :type, :options
|
21
|
+
attr_reader :type, :options, :symbol_value
|
10
22
|
|
11
|
-
validates :
|
23
|
+
validates :type, :options, presence: true
|
12
24
|
validates :type, inclusion: { in: TYPES }, unless: -> { type.nil? }
|
13
|
-
validates :
|
25
|
+
validates :default_value, inclusion: { in: method(:inclusion_in) }, unless: -> { options.nil? || default_value.nil? }
|
14
26
|
|
15
|
-
def initialize(type,
|
16
|
-
super(
|
27
|
+
def initialize(type, options, default_value, param: nil, name: nil)
|
28
|
+
super(default_value, param: param, name: name)
|
17
29
|
@type = type
|
18
30
|
@options = options
|
31
|
+
@symbol_value = default_value.is_a?(Symbol)
|
32
|
+
end
|
33
|
+
|
34
|
+
def value_from_params(params)
|
35
|
+
params_value = super(params)
|
36
|
+
if params_value.is_a?(String) && symbol_value
|
37
|
+
params_value.to_sym
|
38
|
+
else
|
39
|
+
params_value
|
40
|
+
end
|
19
41
|
end
|
20
42
|
|
21
43
|
private
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponent
|
4
|
+
module Storybook
|
5
|
+
module Controls
|
6
|
+
##
|
7
|
+
# A simple Control Config maps to one Storybook Control
|
8
|
+
# It has a value and pulls its value from params by key
|
9
|
+
class SimpleControlConfig < ControlConfig
|
10
|
+
attr_reader :default_value
|
11
|
+
|
12
|
+
def initialize(default_value, param: nil, name: nil)
|
13
|
+
super(param: param, name: name)
|
14
|
+
@default_value = default_value
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_csf_params
|
18
|
+
validate!
|
19
|
+
{
|
20
|
+
args: { param => csf_value },
|
21
|
+
argTypes: { param => { control: csf_control_params, name: name } }
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def value_from_params(params)
|
26
|
+
params[param]
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# provide extension points for subclasses to vary the value
|
32
|
+
def type
|
33
|
+
# :nocov:
|
34
|
+
raise NotImplementedError
|
35
|
+
# :nocov:
|
36
|
+
end
|
37
|
+
|
38
|
+
def csf_value
|
39
|
+
default_value
|
40
|
+
end
|
41
|
+
|
42
|
+
def csf_control_params
|
43
|
+
{ type: type }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -3,75 +3,65 @@
|
|
3
3
|
module ViewComponent
|
4
4
|
module Storybook
|
5
5
|
module Dsl
|
6
|
-
|
7
|
-
|
6
|
+
module ControlsDsl
|
7
|
+
def text(default_value)
|
8
|
+
Controls::TextConfig.new(default_value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def boolean(default_value)
|
12
|
+
Controls::BooleanConfig.new(default_value)
|
13
|
+
end
|
14
|
+
|
15
|
+
def number(default_value, min: nil, max: nil, step: nil)
|
16
|
+
Controls::NumberConfig.new(:number, default_value, min: min, max: max, step: step)
|
17
|
+
end
|
8
18
|
|
9
|
-
def
|
10
|
-
|
11
|
-
@controls = []
|
19
|
+
def range(default_value, min: nil, max: nil, step: nil)
|
20
|
+
Controls::NumberConfig.new(:range, default_value, min: min, max: max, step: step)
|
12
21
|
end
|
13
22
|
|
14
|
-
def
|
15
|
-
|
23
|
+
def color(default_value, preset_colors: nil)
|
24
|
+
Controls::ColorConfig.new(default_value, preset_colors: preset_colors)
|
16
25
|
end
|
17
26
|
|
18
|
-
def
|
19
|
-
|
27
|
+
def object(default_value)
|
28
|
+
Controls::ObjectConfig.new(default_value)
|
20
29
|
end
|
21
30
|
|
22
|
-
def
|
23
|
-
|
31
|
+
def select(options, default_value)
|
32
|
+
Controls::OptionsConfig.new(:select, options, default_value)
|
24
33
|
end
|
25
34
|
|
26
|
-
def
|
27
|
-
|
35
|
+
def multi_select(options, default_value)
|
36
|
+
Controls::OptionsConfig.new(:'multi-select', options, default_value)
|
28
37
|
end
|
29
38
|
|
30
|
-
def
|
31
|
-
|
39
|
+
def radio(options, default_value)
|
40
|
+
Controls::OptionsConfig.new(:radio, options, default_value)
|
32
41
|
end
|
33
42
|
|
34
|
-
def
|
35
|
-
|
43
|
+
def inline_radio(options, default_value)
|
44
|
+
Controls::OptionsConfig.new(:'inline-radio', options, default_value)
|
36
45
|
end
|
37
46
|
|
38
|
-
def
|
39
|
-
|
47
|
+
def check(options, default_value)
|
48
|
+
Controls::OptionsConfig.new(:check, options, default_value)
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
|
51
|
+
def inline_check(options, default_value)
|
52
|
+
Controls::OptionsConfig.new(:'inline-check', options, default_value)
|
44
53
|
end
|
45
54
|
|
46
|
-
def
|
47
|
-
|
55
|
+
def array(default_value, separator = ",")
|
56
|
+
Controls::ArrayConfig.new(default_value, separator)
|
48
57
|
end
|
49
58
|
|
50
|
-
def
|
51
|
-
|
59
|
+
def date(default_value)
|
60
|
+
Controls::DateConfig.new(default_value)
|
52
61
|
end
|
53
62
|
|
54
|
-
def
|
55
|
-
|
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
|
63
|
+
def custom(*args, **kwargs, &block)
|
64
|
+
Controls::CustomConfig.new.with_value(*args, **kwargs, &block)
|
75
65
|
end
|
76
66
|
|
77
67
|
Controls = ViewComponent::Storybook::Controls
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewComponent
|
4
|
+
module Storybook
|
5
|
+
module Dsl
|
6
|
+
class LegacyControlsDsl
|
7
|
+
def controls
|
8
|
+
@controls ||= []
|
9
|
+
end
|
10
|
+
|
11
|
+
def text(param, value, name: nil)
|
12
|
+
controls << Controls::TextConfig.new(value, param: param, name: name)
|
13
|
+
end
|
14
|
+
|
15
|
+
def boolean(param, value, name: nil)
|
16
|
+
controls << Controls::BooleanConfig.new(value, param: param, name: name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def number(param, value, name: nil, min: nil, max: nil, step: nil)
|
20
|
+
controls << Controls::NumberConfig.new(:number, value, param: param, name: name, min: min, max: max, step: step)
|
21
|
+
end
|
22
|
+
|
23
|
+
def range(param, value, name: nil, min: nil, max: nil, step: nil)
|
24
|
+
controls << Controls::NumberConfig.new(:range, value, param: param, name: name, min: min, max: max, step: step)
|
25
|
+
end
|
26
|
+
|
27
|
+
def color(param, value, name: nil, preset_colors: nil)
|
28
|
+
controls << Controls::ColorConfig.new(value, param: param, name: name, preset_colors: preset_colors)
|
29
|
+
end
|
30
|
+
|
31
|
+
def object(param, value, name: nil)
|
32
|
+
controls << Controls::ObjectConfig.new(value, param: param, name: name)
|
33
|
+
end
|
34
|
+
|
35
|
+
def select(param, options, value, name: nil)
|
36
|
+
controls << Controls::OptionsConfig.new(:select, options, value, param: param, name: name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def multi_select(param, options, value, name: nil)
|
40
|
+
controls << Controls::OptionsConfig.new(:'multi-select', options, value, param: param, name: name)
|
41
|
+
end
|
42
|
+
|
43
|
+
def radio(param, options, value, name: nil)
|
44
|
+
controls << Controls::OptionsConfig.new(:radio, options, value, param: param, name: name)
|
45
|
+
end
|
46
|
+
|
47
|
+
def inline_radio(param, options, value, name: nil)
|
48
|
+
controls << Controls::OptionsConfig.new(:'inline-radio', options, value, param: param, name: name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def check(param, options, value, name: nil)
|
52
|
+
controls << Controls::OptionsConfig.new(:check, options, value, param: param, name: name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def inline_check(param, options, value, name: nil)
|
56
|
+
controls << Controls::OptionsConfig.new(:'inline-check', options, value, param: param, name: name)
|
57
|
+
end
|
58
|
+
|
59
|
+
def array(param, value, separator = ",", name: nil)
|
60
|
+
controls << Controls::ArrayConfig.new(value, separator, param: param, name: name)
|
61
|
+
end
|
62
|
+
|
63
|
+
def date(param, value, name: nil)
|
64
|
+
controls << Controls::DateConfig.new(value, param: param, name: name)
|
65
|
+
end
|
66
|
+
|
67
|
+
def respond_to_missing?(_method, *)
|
68
|
+
true
|
69
|
+
end
|
70
|
+
|
71
|
+
def method_missing(method, *args)
|
72
|
+
value = args.first
|
73
|
+
control_method = case value
|
74
|
+
when Date
|
75
|
+
:date
|
76
|
+
when Array
|
77
|
+
:array
|
78
|
+
when Hash
|
79
|
+
:object
|
80
|
+
when Numeric
|
81
|
+
:number
|
82
|
+
when TrueClass, FalseClass
|
83
|
+
:boolean
|
84
|
+
when String
|
85
|
+
:text
|
86
|
+
end
|
87
|
+
if control_method
|
88
|
+
send(control_method, method, *args)
|
89
|
+
else
|
90
|
+
super
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
Controls = ViewComponent::Storybook::Controls
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -4,28 +4,40 @@ module ViewComponent
|
|
4
4
|
module Storybook
|
5
5
|
module Dsl
|
6
6
|
class StoryDsl
|
7
|
+
include ControlsDsl
|
8
|
+
|
7
9
|
def self.evaluate!(story_config, &block)
|
8
10
|
new(story_config).instance_eval(&block)
|
9
11
|
end
|
10
12
|
|
11
13
|
def parameters(**params)
|
12
|
-
|
14
|
+
story_config.parameters = params
|
13
15
|
end
|
14
16
|
|
15
17
|
def controls(&block)
|
16
|
-
|
18
|
+
ActiveSupport::Deprecation.warn("`controls` will be removed in v1.0.0. Use `#constructor` instead.")
|
19
|
+
controls_dsl = LegacyControlsDsl.new
|
17
20
|
controls_dsl.instance_eval(&block)
|
18
|
-
|
21
|
+
|
22
|
+
controls_hash = controls_dsl.controls.index_by(&:param)
|
23
|
+
story_config.constructor_args(**controls_hash)
|
19
24
|
end
|
20
25
|
|
21
26
|
def layout(layout)
|
22
|
-
|
27
|
+
story_config.layout = layout
|
23
28
|
end
|
24
29
|
|
25
30
|
def content(&block)
|
26
|
-
|
31
|
+
story_config.content_block = block
|
27
32
|
end
|
28
33
|
|
34
|
+
def constructor(*args, **kwargs, &block)
|
35
|
+
story_config.constructor_args(*args, **kwargs)
|
36
|
+
story_config.content_block = block
|
37
|
+
end
|
38
|
+
|
39
|
+
delegate :component, to: :story_config
|
40
|
+
|
29
41
|
private
|
30
42
|
|
31
43
|
attr_reader :story_config
|