primer_view_components 0.0.121 → 0.0.122

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/app/assets/styles/primer_view_components.css +2 -2
  4. data/app/assets/styles/primer_view_components.css.map +1 -1
  5. data/app/components/primer/alpha/action_list.css.json +123 -1
  6. data/app/components/primer/alpha/auto_complete.css.json +23 -1
  7. data/app/components/primer/alpha/banner.css.json +24 -1
  8. data/app/components/primer/alpha/button_marketing.css.json +33 -1
  9. data/app/components/primer/alpha/check_box.rb +74 -0
  10. data/app/components/primer/alpha/check_box_group.rb +36 -0
  11. data/app/components/primer/alpha/dialog.css.json +82 -1
  12. data/app/components/primer/alpha/dialog.rb +1 -1
  13. data/app/components/primer/alpha/dropdown.css.json +40 -1
  14. data/app/components/primer/alpha/form_button.rb +32 -0
  15. data/app/components/primer/alpha/form_control.html.erb +26 -0
  16. data/app/components/primer/alpha/form_control.rb +105 -0
  17. data/app/components/primer/alpha/layout.css.json +80 -1
  18. data/app/components/primer/alpha/menu.css.json +28 -1
  19. data/app/components/primer/alpha/multi_input.rb +81 -0
  20. data/app/components/primer/alpha/radio_button.rb +25 -0
  21. data/app/components/primer/alpha/radio_button_group.rb +36 -0
  22. data/app/components/primer/alpha/segmented_control.css +1 -1
  23. data/app/components/primer/alpha/segmented_control.css.json +31 -1
  24. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  25. data/app/components/primer/alpha/segmented_control.pcss +43 -12
  26. data/app/components/primer/alpha/select.rb +37 -0
  27. data/app/components/primer/alpha/submit_button.rb +32 -0
  28. data/app/components/primer/alpha/tab_nav.css.json +24 -1
  29. data/app/components/primer/alpha/tab_panels.rb +7 -0
  30. data/app/components/primer/alpha/text_area.rb +24 -0
  31. data/app/components/primer/alpha/text_field.css +2 -2
  32. data/app/components/primer/alpha/text_field.css.json +134 -1
  33. data/app/components/primer/alpha/text_field.css.map +1 -1
  34. data/app/components/primer/alpha/text_field.pcss +27 -0
  35. data/app/components/primer/alpha/text_field.rb +15 -20
  36. data/app/components/primer/alpha/toggle_switch.css +1 -1
  37. data/app/components/primer/alpha/toggle_switch.css.json +40 -1
  38. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  39. data/app/components/primer/alpha/toggle_switch.pcss +31 -61
  40. data/app/components/primer/alpha/underline_nav.css.json +28 -1
  41. data/app/components/primer/beta/avatar.css.json +17 -1
  42. data/app/components/primer/beta/avatar_stack.css.json +28 -1
  43. data/app/components/primer/beta/blankslate.css.json +22 -1
  44. data/app/components/primer/beta/border_box.css.json +54 -1
  45. data/app/components/primer/beta/breadcrumbs.css.json +11 -1
  46. data/app/components/primer/beta/button.css.json +71 -1
  47. data/app/components/primer/beta/counter.css.json +10 -1
  48. data/app/components/primer/beta/flash.css.json +27 -1
  49. data/app/components/primer/beta/label.css.json +25 -1
  50. data/app/components/primer/beta/link.css.json +19 -1
  51. data/app/components/primer/beta/popover.css.json +39 -1
  52. data/app/components/primer/beta/progress_bar.css.json +10 -1
  53. data/app/components/primer/beta/state.css.json +13 -1
  54. data/app/components/primer/beta/subhead.css.json +12 -1
  55. data/app/components/primer/beta/timeline_item.css.json +16 -1
  56. data/app/components/primer/beta/truncate.css.json +12 -1
  57. data/app/components/primer/component.rb +10 -2
  58. data/app/components/primer/truncate.css.json +13 -1
  59. data/app/forms/{select_list_form.rb → select_form.rb} +1 -1
  60. data/app/lib/primer/css/layout.css.json +316 -1
  61. data/app/lib/primer/css/utilities.css.json +1659 -1
  62. data/lib/primer/form_components.rb +26 -6
  63. data/lib/primer/forms/builder.rb +1 -17
  64. data/lib/primer/forms/button.rb +4 -1
  65. data/lib/primer/forms/check_box_group.html.erb +14 -9
  66. data/lib/primer/forms/check_box_group.rb +5 -0
  67. data/lib/primer/forms/dsl/check_box_group_input.rb +3 -4
  68. data/lib/primer/forms/dsl/input.rb +33 -2
  69. data/lib/primer/forms/dsl/input_methods.rb +49 -1
  70. data/lib/primer/forms/dsl/radio_button_group_input.rb +2 -3
  71. data/lib/primer/forms/dsl/{select_list_input.rb → select_input.rb} +2 -2
  72. data/lib/primer/forms/dsl/text_field_input.rb +7 -5
  73. data/lib/primer/forms/form_control.rb +0 -1
  74. data/lib/primer/forms/group.html.erb +1 -1
  75. data/lib/primer/forms/multi.html.erb +8 -6
  76. data/lib/primer/forms/multi.rb +2 -0
  77. data/lib/primer/forms/radio_button_group.html.erb +14 -9
  78. data/lib/primer/forms/radio_button_group.rb +5 -0
  79. data/lib/primer/forms/{select_list.html.erb → select.html.erb} +0 -0
  80. data/lib/primer/forms/{select_list.rb → select.rb} +2 -2
  81. data/lib/primer/forms/spacing_wrapper.html.erb +1 -1
  82. data/lib/primer/forms/text_area.rb +1 -1
  83. data/lib/primer/forms/text_field.rb +5 -1
  84. data/lib/primer/forms/utils.rb +20 -0
  85. data/lib/primer/view_components/engine.rb +1 -1
  86. data/lib/primer/view_components/version.rb +1 -1
  87. data/lib/primer/yard/backend.rb +1 -15
  88. data/lib/primer/yard/component_manifest.rb +44 -25
  89. data/lib/primer/yard/component_ref.rb +40 -0
  90. data/lib/primer/yard/docs_helper.rb +16 -2
  91. data/lib/primer/yard/legacy_gatsby_backend.rb +9 -15
  92. data/lib/primer/yard/lookbook_docs_helper.rb +32 -0
  93. data/lib/primer/yard/lookbook_pages_backend.rb +194 -0
  94. data/lib/primer/yard/registry.rb +6 -21
  95. data/lib/primer/yard/renders_many_handler.rb +1 -1
  96. data/lib/primer/yard/renders_one_handler.rb +1 -1
  97. data/lib/primer/yard.rb +14 -0
  98. data/lib/tasks/docs.rake +26 -13
  99. data/previews/pages/forms/01_introduction.md.erb +44 -0
  100. data/previews/pages/forms/02_getting_started.md.erb +125 -0
  101. data/previews/pages/forms/03_caption_templates.md.erb +30 -0
  102. data/previews/pages/forms/04_after_content.md.erb +39 -0
  103. data/previews/pages/forms/05_groups_layouts.md.erb +22 -0
  104. data/previews/pages/forms/06_miscellaneous_inputs.md.erb +43 -0
  105. data/previews/pages/forms/07_toggle_switch_forms.md.erb +58 -0
  106. data/previews/pages/forms/08_validations.md.erb +28 -0
  107. data/previews/pages/forms/09_compound_forms.md.erb +97 -0
  108. data/previews/primer/alpha/check_box_group_preview.rb +89 -0
  109. data/previews/primer/alpha/check_box_preview.rb +62 -0
  110. data/previews/primer/alpha/form_control_preview/playground.html.erb +9 -0
  111. data/previews/primer/alpha/form_control_preview.rb +106 -0
  112. data/previews/primer/alpha/multi_input_preview/playground.html.erb +41 -0
  113. data/previews/primer/alpha/multi_input_preview.rb +80 -0
  114. data/previews/primer/alpha/radio_button_group_preview.rb +83 -0
  115. data/previews/primer/alpha/radio_button_preview.rb +62 -0
  116. data/previews/primer/alpha/select_preview.rb +130 -0
  117. data/previews/primer/alpha/text_area_preview.rb +87 -0
  118. data/previews/primer/alpha/text_field_preview.rb +10 -1
  119. data/previews/primer/forms/forms_preview/example_toggle_switch_form.html.erb +2 -2
  120. data/previews/primer/forms/forms_preview/{select_list_form.html.erb → select_form.html.erb} +1 -1
  121. data/previews/primer/forms/forms_preview.rb +3 -1
  122. data/static/arguments.json +1358 -1328
  123. data/static/audited_at.json +10 -0
  124. data/static/constants.json +20 -0
  125. data/static/previews.json +218 -40
  126. data/static/statuses.json +10 -0
  127. metadata +41 -7
@@ -2,7 +2,7 @@
2
2
 
3
3
  # :nocov:
4
4
  module Primer
5
- module YARD
5
+ module Yard
6
6
  # The set of documented components (and associated metadata).
7
7
  class ComponentManifest
8
8
  COMPONENTS = {
@@ -77,42 +77,61 @@ module Primer
77
77
  Primer::Alpha::ActionList::Item => { examples: false },
78
78
 
79
79
  # Forms
80
- Primer::Alpha::TextField => { form_component: true }
80
+ Primer::Alpha::TextField => { form_component: true },
81
+ Primer::Alpha::TextArea => { form_component: true, published: false },
82
+ Primer::Alpha::Select => { form_component: true, published: false },
83
+ Primer::Alpha::MultiInput => { form_component: true, js: true, published: false },
84
+ Primer::Alpha::RadioButton => { form_component: true, published: false },
85
+ Primer::Alpha::RadioButtonGroup => { form_component: true, published: false },
86
+ Primer::Alpha::CheckBox => { form_component: true, published: false },
87
+ Primer::Alpha::CheckBoxGroup => { form_component: true, published: false },
88
+ Primer::Alpha::SubmitButton => { form_component: true, published: false },
89
+ Primer::Alpha::FormButton => { form_component: true, published: false }
81
90
  }.freeze
82
91
 
83
- class << self
84
- def each(&block)
85
- COMPONENTS.keys.each(&block)
86
- end
92
+ include Enumerable
87
93
 
88
- def components_with_docs
89
- @components_with_docs ||= COMPONENTS.keys
90
- end
94
+ def initialize(components)
95
+ @components = components
96
+ end
97
+
98
+ def each
99
+ return to_enum(__method__) unless block_given?
91
100
 
92
- def all_components
93
- @all_components ||= Primer::Component.descendants - [Primer::BaseComponent]
101
+ @components.each do |klass|
102
+ yield self.class.ref_for(klass)
94
103
  end
104
+ end
95
105
 
96
- def components_without_docs
97
- @components_without_docs ||= all_components - components_with_docs
106
+ def where(**attrs)
107
+ self.class.where(@components, **attrs)
108
+ end
109
+
110
+ class << self
111
+ def where(components = COMPONENTS, **desired_attrs)
112
+ new(
113
+ components.each_with_object([]) do |(klass, component_attrs), memo|
114
+ matches = desired_attrs.all? do |name, desired_value|
115
+ component_attrs.fetch(name, ComponentRef::ATTR_DEFAULTS[name]) == desired_value
116
+ end
117
+
118
+ memo << klass if matches
119
+ end
120
+ )
98
121
  end
99
122
 
100
- def components_with_examples
101
- @components_with_examples ||= COMPONENTS.keys.select do |c|
102
- COMPONENTS[c].fetch(:examples, true)
103
- end
123
+ def all
124
+ new(COMPONENTS.keys)
104
125
  end
105
126
 
106
- def components_requiring_js
107
- @components_requiring_js ||= COMPONENTS.keys.select do |c|
108
- COMPONENTS[c].fetch(:js, false)
109
- end
127
+ def ref_for(klass)
128
+ ref_cache[klass] ||= ComponentRef.new(klass, COMPONENTS[klass])
110
129
  end
111
130
 
112
- def form_components
113
- @form_components ||= COMPONENTS.keys.select do |c|
114
- COMPONENTS[c].fetch(:form_component, false)
115
- end
131
+ private
132
+
133
+ def ref_cache
134
+ @ref_cache ||= {}
116
135
  end
117
136
  end
118
137
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ module Primer
5
+ module Yard
6
+ # :nodoc:
7
+ class ComponentRef
8
+ ATTR_DEFAULTS = {
9
+ js: false,
10
+ examples: true,
11
+ published: true,
12
+ form_component: false
13
+ }.freeze
14
+
15
+ attr_reader :klass, :attrs
16
+
17
+ def initialize(klass, attrs)
18
+ @klass = klass
19
+ @attrs = attrs
20
+ end
21
+
22
+ def requires_js?
23
+ @attrs.fetch(:js, ATTR_DEFAULTS[:js])
24
+ end
25
+
26
+ def should_have_examples?
27
+ @attrs.fetch(:examples, ATTR_DEFAULTS[:examples])
28
+ end
29
+
30
+ def published?
31
+ @attrs.fetch(:published, ATTR_DEFAULTS[:published])
32
+ end
33
+
34
+ def form_component?
35
+ @attrs.fetch(:form_component, ATTR_DEFAULTS[:form_component])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ # :nocov:
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # :nocov:
4
-
5
4
  module Primer
6
- module YARD
5
+ module Yard
7
6
  # Helper methods to use for yard documentation
8
7
  module DocsHelper
9
8
  def one_of(enumerable, lower: false, sort: true)
@@ -66,6 +65,20 @@ module Primer
66
65
  [m[:status]&.downcase, m[:name].gsub("::", ""), m[:name]]
67
66
  end
68
67
 
68
+ def pretty_default_value(tag, component)
69
+ params = tag.object.parameters.find { |param| [tag.name.to_s, "#{tag.name}:"].include?(param[0]) }
70
+ default = tag.defaults&.first || params&.second
71
+
72
+ return "N/A" unless default
73
+
74
+ constant_name = "#{component.name}::#{default}"
75
+ constant_value = default.safe_constantize || constant_name.safe_constantize
76
+
77
+ return pretty_value(default) if constant_value.nil?
78
+
79
+ pretty_value(constant_value)
80
+ end
81
+
69
82
  def pretty_value(val)
70
83
  case val
71
84
  when nil
@@ -79,3 +92,4 @@ module Primer
79
92
  end
80
93
  end
81
94
  end
95
+ # :nocov:
@@ -3,12 +3,8 @@
3
3
  # rubocop:disable Naming/MethodParameterName
4
4
 
5
5
  # :nocov:
6
-
7
- require "primer/yard/component_manifest"
8
- require "primer/yard/backend"
9
-
10
6
  module Primer
11
- module YARD
7
+ module Yard
12
8
  # Backend that generates documentation for the legacy, Gatsby-powered PVC docsite.
13
9
  class LegacyGatsbyBackend < Backend
14
10
  class << self
@@ -29,17 +25,19 @@ module Primer
29
25
  end
30
26
  end
31
27
 
32
- attr_reader :registry
28
+ attr_reader :registry, :manifest
33
29
 
34
- def initialize(registry)
30
+ def initialize(registry, manifest)
35
31
  @registry = registry
32
+ @manifest = manifest
36
33
  end
37
34
 
38
35
  def generate
39
36
  args_for_components = []
40
37
  errors = []
41
38
 
42
- each_component do |component|
39
+ each_component do |component_ref|
40
+ component = component_ref.klass
43
41
  docs = registry.find(component)
44
42
  status_path = docs.status_module.nil? ? "" : "#{docs.status_module}/"
45
43
 
@@ -66,7 +64,7 @@ module Primer
66
64
  f.puts
67
65
  f.puts("import Example from '#{metadata[:example_path]}'")
68
66
 
69
- if docs.requires_js?
67
+ if component_ref.requires_js?
70
68
  f.puts("import RequiresJSFlash from '#{metadata[:require_js_path]}'")
71
69
  f.puts
72
70
  f.puts("<RequiresJSFlash />")
@@ -170,7 +168,7 @@ module Primer
170
168
  f.puts(code.to_s)
171
169
  f.puts("```")
172
170
  end
173
- elsif manifest.components_with_examples.include?(component)
171
+ elsif component_ref.should_have_examples?
174
172
  errors << { component.name => { example: "No examples found" } }
175
173
  end
176
174
  end
@@ -219,11 +217,7 @@ module Primer
219
217
  end
220
218
 
221
219
  def each_component(&block)
222
- manifest.components_with_docs.sort_by(&:name).each(&block)
223
- end
224
-
225
- def manifest
226
- Primer::YARD::ComponentManifest
220
+ manifest.each(&block)
227
221
  end
228
222
 
229
223
  def source_url(component)
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ module Primer
5
+ module Yard
6
+ # Helper methods for documentation generated in Lookbook pages.
7
+ module LookbookDocsHelper
8
+ # Adheres to the same signature as Primer::Yard::DocsHelper#link_to_component so link_to_component
9
+ # may be used in a Gatsby or Lookbook context and produce the correct link for each platform.
10
+ #
11
+ # @param component [Class] The component class to link to.
12
+ # @return [String] The link, either in HTML or markdown format.
13
+ def link_to_component(component)
14
+ backend = Primer::Yard::LookbookPagesBackend.new(Primer::Yard::Registry.make, nil)
15
+ component_ref = Primer::Yard::ComponentManifest.ref_for(component)
16
+ page = backend.page_for(component_ref)
17
+
18
+ # If the page_path method is available, we're being rendered into HTML by Lookbook
19
+ # and should emit an HTML <a> tag. No page_path means we're being rendered into
20
+ # markdown by LookbookPagesBackend and should emit a markdown + ERB link that
21
+ # Lookbook will eventually render on page load.
22
+ if respond_to?(:page_path)
23
+ link_to(page.docs.short_name, page_path(page.page_id.to_sym.inspect))
24
+ else
25
+ # rubocop:disable Rails/OutputSafety
26
+ "[#{page.docs.short_name}](<%= page_path(#{page.page_id.to_sym.inspect}) %>)".html_safe
27
+ # rubocop:enable Rails/OutputSafety
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ module Primer
5
+ module Yard
6
+ # A single Lookbook page.
7
+ class LookbookPage
8
+ include DocsHelper
9
+
10
+ PREVIEW_MAP = {
11
+ Primer::Alpha::TextField => [:single_text_field_form, :multi_text_field_form],
12
+ Primer::Alpha::TextArea => [],
13
+ Primer::Alpha::Select => [:select_list_form],
14
+ Primer::Alpha::MultiInput => [:multi_input_form],
15
+ Primer::Alpha::RadioButton => [:radio_button_with_nested_form],
16
+ Primer::Alpha::RadioButtonGroup => [:radio_button_group_form],
17
+ Primer::Alpha::CheckBox => [:check_box_with_nested_form],
18
+ Primer::Alpha::CheckBoxGroup => [:check_box_group_form],
19
+ Primer::Alpha::SubmitButton => [:submit_button_form],
20
+ Primer::Alpha::FormButton => [:submit_button_form]
21
+ }.freeze
22
+
23
+ attr_reader :component_ref, :backend, :docs
24
+
25
+ def initialize(component_ref, backend, docs)
26
+ @component_ref = component_ref
27
+ @backend = backend
28
+ @docs = docs
29
+ end
30
+
31
+ def page_id
32
+ @page_id ||= docs.short_name.dasherize.underscore.tap do |page_id|
33
+ page_id << "_input" unless page_id.end_with?("_input")
34
+ end
35
+ end
36
+
37
+ def generate
38
+ path = File.expand_path(
39
+ File.join(
40
+ *%w[.. .. .. previews pages forms inputs],
41
+ "#{docs.short_name.dasherize.underscore}.md.erb"
42
+ ), __dir__
43
+ )
44
+
45
+ # rubocop:disable Lint/UselessAssignment
46
+ documented_methods = docs.non_slot_methods.select do |mtd|
47
+ [component.name, "Primer::Forms::Dsl::InputMethods"].include?(mtd.parent.title)
48
+ end
49
+
50
+ preview_methods = PREVIEW_MAP[component]
51
+ preview_erbs = preview_methods.map do |preview_method|
52
+ "<%= embed Primer::Forms::FormsPreview, #{preview_method.inspect} %>"
53
+ end
54
+ # rubocop:enable Lint/UselessAssignment
55
+
56
+ # rubocop:disable Security/Eval
57
+ File.open(path, "w") do |f|
58
+ f.write(eval(Erubi::Engine.new(<<~ERB, trim: true).src))
59
+ ---
60
+ title: <%= docs.title.underscore.titleize %>
61
+ id: <%= page_id %>
62
+ ---
63
+
64
+ <%= docs.base_docstring %>
65
+
66
+ ## Usage
67
+
68
+ ```ruby
69
+ <%= docs.tags(:form_usage).first.text %>
70
+ ```
71
+
72
+ <% specific_args = specific_args_from(docs.params) %>
73
+ <% unless specific_args.empty? %>
74
+ ## Arguments
75
+
76
+ <%= generate_args_table(specific_args) %>
77
+ <% end %>
78
+
79
+ ## Common arguments
80
+
81
+ <%= generate_args_table(common_args_from(docs.params)) %>
82
+
83
+ <% unless documented_methods.empty? %>
84
+ ## Methods
85
+
86
+ <% documented_methods.each do |method_docs| %>
87
+ ### `#<%= method_docs.signature.sub(/def /, "") %>`
88
+
89
+ <%= method_docs.base_docstring %>
90
+
91
+ <% param_tags = method_docs.tags(:param) %>
92
+
93
+ <% if param_tags.any? %>
94
+
95
+ <%= generate_args_table(param_tags) %>
96
+ <% end %>
97
+ <% end %>
98
+ <% end %>
99
+
100
+ <% unless preview_methods.empty? %>
101
+ ## Examples
102
+
103
+ <%= preview_erbs.join("\n") %>
104
+ <% end %>
105
+ ERB
106
+ end
107
+ # rubocop:enable Security/Eval
108
+ end
109
+
110
+ private
111
+
112
+ def registry
113
+ backend.registry
114
+ end
115
+
116
+ def generate_args_table(params)
117
+ rows = params.map do |tag|
118
+ description = backend.view_context.render(inline: tag.text.squish)
119
+ parts = [
120
+ "`#{tag.name}`",
121
+ tag.types.join(", "),
122
+ description
123
+ ]
124
+
125
+ "| #{parts.join(' | ')} |"
126
+ end
127
+
128
+ <<~MARKDOWN
129
+ | Name | Type | Description |
130
+ | :- | :- | :- |
131
+ #{rows.join("\n")}
132
+ MARKDOWN
133
+ end
134
+
135
+ def common_args_from(params)
136
+ params.select { |param| common_form_input_argument_names.include?(param.name) }
137
+ end
138
+
139
+ def specific_args_from(params)
140
+ params.reject { |param| common_form_input_argument_names.include?(param.name) }
141
+ end
142
+
143
+ def common_form_input_argument_names
144
+ @common_form_input_argument_names ||= begin
145
+ macro = registry.yard_registry[".macro.form_input_arguments"]
146
+ parser = ::YARD::Docstring.parser
147
+ parser.parse(macro.macro_data)
148
+ parser
149
+ .tags
150
+ .select { |tag| tag.tag_name == "param" }
151
+ .map(&:name)
152
+ end
153
+ end
154
+
155
+ def component
156
+ component_ref.klass
157
+ end
158
+ end
159
+
160
+ # Backend that generates Lookbook pages.
161
+ class LookbookPagesBackend < Backend
162
+ attr_reader :registry, :manifest
163
+
164
+ def initialize(registry, manifest)
165
+ @registry = registry
166
+ @manifest = manifest
167
+ end
168
+
169
+ def generate
170
+ each_component do |component_ref|
171
+ page_for(component_ref).generate
172
+ end
173
+ end
174
+
175
+ def page_for(component_ref)
176
+ docs = registry.find(component_ref.klass)
177
+ LookbookPage.new(component_ref, self, docs)
178
+ end
179
+
180
+ def view_context
181
+ @view_context ||= super.tap do |vc|
182
+ vc.singleton_class.include(LookbookDocsHelper)
183
+ end
184
+ end
185
+
186
+ private
187
+
188
+ def each_component(&block)
189
+ manifest.each(&block)
190
+ end
191
+ end
192
+ end
193
+ end
194
+ # :nocov:
@@ -2,12 +2,10 @@
2
2
 
3
3
  # :nocov:
4
4
 
5
- require "primer/view_components"
6
- require "primer/yard/docs_helper"
7
5
  require "view_component/test_helpers"
8
6
 
9
7
  module Primer
10
- module YARD
8
+ module Yard
11
9
  # A wrapper around a YARD class reference that provides convenience methods
12
10
  # for extracting component parameters, accessibility status, etc.
13
11
  class RegistryEntry
@@ -62,8 +60,9 @@ module Primer
62
60
  def public_methods
63
61
  # Returns: only public methods that belong to this class (i.e. no inherited methods)
64
62
  # excluding the constructor
65
- @public_methods ||=
66
- docs.meths.reject { |mtd| mtd.tag(:private) || mtd.name == :initialize }
63
+ @public_methods ||= docs.meths.reject do |mtd|
64
+ mtd.tag(:private) || mtd.name == :initialize
65
+ end
67
66
  end
68
67
 
69
68
  def title
@@ -89,20 +88,6 @@ module Primer
89
88
  def a11y_reviewed?
90
89
  metadata[:a11y_reviewed]
91
90
  end
92
-
93
- def requires_js?
94
- manifest.components_requiring_js.include?(component)
95
- end
96
-
97
- def includes_examples?
98
- manifest.components_with_examples.include?(component)
99
- end
100
-
101
- private
102
-
103
- def manifest
104
- Primer::YARD::ComponentManifest
105
- end
106
91
  end
107
92
 
108
93
  # Wrapper around an instance of YARD::Registry that provides easy access to component
@@ -111,11 +96,11 @@ module Primer
111
96
  class << self
112
97
  include ViewComponent::TestHelpers
113
98
  include Primer::ViewHelper
114
- include Primer::YARD::DocsHelper
99
+ include Primer::Yard::DocsHelper
115
100
 
116
101
  def make
117
102
  registry = ::YARD::RegistryStore.new
118
- registry.load!(".yardoc")
103
+ registry.load!(File.expand_path(File.join("..", "..", "..", ".yardoc"), __dir__))
119
104
 
120
105
  new(registry)
121
106
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # :nocov:
4
4
  module Primer
5
- module YARD
5
+ module Yard
6
6
  # YARD Handler to parse `renders_many` calls.
7
7
  class RendersManyHandler < ::YARD::Handlers::Ruby::Base
8
8
  handles method_call(:renders_many)
@@ -2,7 +2,7 @@
2
2
 
3
3
  # :nocov:
4
4
  module Primer
5
- module YARD
5
+ module Yard
6
6
  # YARD Handler to parse `renders_one` calls.
7
7
  class RendersOneHandler < ::YARD::Handlers::Ruby::Base
8
8
  handles method_call(:renders_one)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Yard
5
+ autoload :Backend, "primer/yard/backend"
6
+ autoload :ComponentManifest, "primer/yard/component_manifest"
7
+ autoload :ComponentRef, "primer/yard/component_ref"
8
+ autoload :DocsHelper, "primer/yard/docs_helper"
9
+ autoload :LegacyGatsbyBackend, "primer/yard/legacy_gatsby_backend"
10
+ autoload :Registry, "primer/yard/registry"
11
+ autoload :RendersManyHandler, "primer/yard/renders_many_handler"
12
+ autoload :RendersOneHandler, "primer/yard/renders_one_handler"
13
+ end
14
+ end
data/lib/tasks/docs.rake CHANGED
@@ -21,12 +21,15 @@ namespace :docs do
21
21
  sleep
22
22
  end
23
23
 
24
- task build: [:build_gatsby, :build_gatsby_adrs]
24
+ task build: [:build_gatsby_pages, :build_gatsby_adrs, :build_lookbook_pages]
25
25
 
26
- task build_gatsby: :build_yard_registry do
27
- registry = Primer::YARD::Registry.make
26
+ task build_gatsby_pages: :build_yard_registry do
27
+ require "primer/yard"
28
+
29
+ registry = Primer::Yard::Registry.make
28
30
 
29
31
  require "primer/yard/legacy_gatsby_backend"
32
+ require "primer/yard/component_manifest"
30
33
 
31
34
  puts "Converting YARD documentation to Markdown files."
32
35
 
@@ -34,7 +37,8 @@ namespace :docs do
34
37
  components_content_glob = File.join(*%w[docs content components ** *.md])
35
38
  FileUtils.rm_rf(components_content_glob)
36
39
 
37
- backend = Primer::YARD::LegacyGatsbyBackend.new(registry)
40
+ manifest = Primer::Yard::ComponentManifest.where(published: true)
41
+ backend = Primer::Yard::LegacyGatsbyBackend.new(registry, manifest)
38
42
  args_for_components, errors = backend.generate
39
43
 
40
44
  unless errors.empty?
@@ -55,7 +59,8 @@ namespace :docs do
55
59
 
56
60
  puts "Markdown compiled."
57
61
 
58
- components_needing_docs = Primer::YARD::ComponentManifest.components_without_docs
62
+ all_components = Primer::Component.descendants - [Primer::BaseComponent]
63
+ components_needing_docs = all_components - Primer::Yard::ComponentManifest::COMPONENTS.keys
59
64
 
60
65
  if components_needing_docs.any?
61
66
  puts
@@ -63,6 +68,15 @@ namespace :docs do
63
68
  end
64
69
  end
65
70
 
71
+ task build_lookbook_pages: :build_yard_registry do
72
+ require "primer/yard"
73
+
74
+ registry = Primer::Yard::Registry.make
75
+ manifest = Primer::Yard::ComponentManifest.where(form_component: true)
76
+ backend = Primer::Yard::LookbookPagesBackend.new(registry, manifest)
77
+ backend.generate
78
+ end
79
+
66
80
  task :build_gatsby_adrs do
67
81
  adr_content_dir = File.join(*%w[docs content adr])
68
82
 
@@ -109,16 +123,15 @@ namespace :docs do
109
123
  end
110
124
 
111
125
  task preview: :build_yard_registry do
112
- registry = Primer::YARD::Registry.make
113
-
114
- require "primer/yard/legacy_gatsby_backend"
126
+ require "primer/yard"
115
127
 
116
128
  FileUtils.rm_rf("previews/primer/docs/")
117
129
 
118
- manifest = Primer::YARD::ComponentManifest
130
+ registry = Primer::Yard::Registry.make
119
131
 
120
132
  # Generate previews from documentation examples
121
- manifest.all_components.each do |component|
133
+ Primer::Yard::ComponentManifest.all.each do |component_ref|
134
+ component = component_ref.klass
122
135
  docs = registry.find(component)
123
136
  next unless docs.constructor&.tags(:example)&.any?
124
137
 
@@ -132,7 +145,7 @@ namespace :docs do
132
145
  f.puts(" class #{docs.short_name}Preview < ViewComponent::Preview")
133
146
 
134
147
  yard_example_tags.each_with_index do |tag, index|
135
- name, _, code = Primer::YARD::LegacyGatsbyBackend.parse_example_tag(tag)
148
+ name, _, code = Primer::Yard::LegacyGatsbyBackend.parse_example_tag(tag)
136
149
  method_name = name.split("|").first.downcase.parameterize.underscore
137
150
  f.puts(" def #{method_name}; end")
138
151
  f.puts unless index == yard_example_tags.size - 1
@@ -152,11 +165,11 @@ namespace :docs do
152
165
  task :init_pvc do
153
166
  ENV["RAILS_ENV"] = "test"
154
167
  require File.expand_path("./../../demo/config/environment.rb", __dir__)
155
- Dir["./app/components/primer/**/*.rb"].sort.each { |file| require file }
168
+ Dir[File.expand_path("../../app/components/primer/**/*.rb", __dir__)].sort.each { |file| require file }
156
169
  end
157
170
 
158
171
  task build_yard_registry: :init_pvc do
159
- require "primer/yard/registry"
172
+ require "primer/yard"
160
173
 
161
174
  ::YARD::Rake::YardocTask.new do |task|
162
175
  task.options << "--no-output"