primer_view_components 0.0.42 → 0.0.43

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 84c899ab3302b9bffbfe3f0d6471a732d3f457fa8f2eec84a3e7e4b9a9e003b0
4
- data.tar.gz: b3f96f4caf1154320ebe772c3696526901ad07b9cd0b2327383b94b995c8bac4
3
+ metadata.gz: 78f4fe987616d5ab746cbd6d6a0bc79ff62ecf33eb2365af3ade87a43461d35b
4
+ data.tar.gz: 2813cf307508ab9a413d98edbba54e1d7735dc86e853a42587487c7293d42571
5
5
  SHA512:
6
- metadata.gz: 9cab0b4a7016357d29d099e07ae047a335dc4e394422250cada38c4f861900433a639b20748ae239a0962eb49c4cb0b5a1279746bfab2c5713f51647834c6056
7
- data.tar.gz: 89e0b7c38eff95e73b6e0f829153b14033644bd74553fef7a784a9d25d16b7fd52aea7305e4163c1ef294a8a758c4278d24b5f25d6bb194be994f31dd07401e5
6
+ metadata.gz: 7b13c5c05eb27d2a635396d736daa1039024bef7ddb456d20ec037f2cf270e8cb157ebd40619ca8eed4523e9cde5af2d990b428dc2ff663a42faaf01070a48ef
7
+ data.tar.gz: c5e126fcf17bf04914a2ea054ca181991a8cb0fda5659753c4e03241e6dfcfe8a5e876b915033cfc69b11c10b3b7946403fdb86f1fca3161eb1278eae29d99ed
data/CHANGELOG.md CHANGED
@@ -2,6 +2,52 @@
2
2
 
3
3
  ## main
4
4
 
5
+ ## 0.0.43
6
+
7
+ * Upgrade primer/css to 17.2.1
8
+
9
+ *Jon Rohan*
10
+
11
+ ### New
12
+
13
+ * Add `clearfix` and `container` system arguments.
14
+
15
+ *Manuel Puyol*
16
+
17
+ ### Updates
18
+
19
+ * Promote `TabNav` component to beta.
20
+
21
+ *Manuel Puyol*
22
+
23
+ * Allow customizing `TabContainer` when using `TabNav` and `UnderlineNav` components.
24
+
25
+ *Manuel Puyol*
26
+
27
+ ### Breaking changes
28
+
29
+ * Restrict `col` system arguments to only accept values between 1 and 12.
30
+
31
+ *Manuel Puyol*
32
+
33
+ ### Misc
34
+
35
+ * Raise an error if `class` is used as a system argument.
36
+
37
+ *Manuel Puyol*
38
+
39
+ * Don't commit auto-generated component previews.
40
+
41
+ *Kate Higa*
42
+
43
+ * Provide linters for component migrations.
44
+
45
+ *Manuel Puyol*
46
+
47
+ * Update docs to accept multiline descriptions.
48
+
49
+ *Manuel Puyol*
50
+
5
51
  ## 0.0.42
6
52
 
7
53
  ### New
@@ -83,7 +83,9 @@ module Primer
83
83
  #
84
84
  # | Name | Type | Description |
85
85
  # | :- | :- | :- |
86
- # | `col` | Integer | Number of columns. |
86
+ # | `clearfix` | Boolean | Wether to assign the `clearfix` class. |
87
+ # | `col` | Integer | Number of columns. <%= one_of(Primer::Classify::Grid::COL_VALUES) %> |
88
+ # | `container` | Symbol | Size of the container. <%= one_of(Primer::Classify::Grid::CONTAINER_VALUES) %> |
87
89
  #
88
90
  # ## Layout
89
91
  #
@@ -148,6 +150,8 @@ module Primer
148
150
  @tag = tag
149
151
  @system_arguments = system_arguments
150
152
 
153
+ raise ArgumentError, "`class` is an invalid argument. Use `classes` instead." if system_arguments.key?(:class) && !Rails.env.production?
154
+
151
155
  @result = Primer::Classify.call(**@system_arguments.merge(classes: classes))
152
156
 
153
157
  @system_arguments[:"data-view-component"] = true
@@ -1,3 +1,4 @@
1
+ <%# erblint:counter ButtonComponentMigrationCounter 1 %>
1
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
3
  <% if spinner.present? %>
3
4
  <%= spinner %>
@@ -23,56 +23,74 @@ module Primer
23
23
  # description: "Description",
24
24
  # ) %>
25
25
  #
26
- # @example Icon|Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
27
- # <%= render Primer::BlankslateComponent.new(
28
- # icon: :globe,
29
- # title: "Title",
30
- # description: "Description",
31
- # ) %>
26
+ # @example Icon
27
+ # @description
28
+ # Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
29
+ # @code
30
+ # <%= render Primer::BlankslateComponent.new(
31
+ # icon: :globe,
32
+ # title: "Title",
33
+ # description: "Description",
34
+ # ) %>
32
35
  #
33
- # @example Loading|Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
34
- # <%= render Primer::BlankslateComponent.new(
35
- # title: "Title",
36
- # description: "Description",
37
- # ) do |component| %>
38
- # <% component.spinner(size: :large) %>
39
- # <% end %>
36
+ # @example Loading
37
+ # @description
38
+ # Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
39
+ # @code
40
+ # <%= render Primer::BlankslateComponent.new(
41
+ # title: "Title",
42
+ # description: "Description",
43
+ # ) do |component| %>
44
+ # <% component.spinner(size: :large) %>
45
+ # <% end %>
40
46
  #
41
- # @example Custom content|Pass custom content as a block in place of `description`.
42
- # <%= render Primer::BlankslateComponent.new(
43
- # title: "Title",
44
- # ) do %>
45
- # <em>Your custom content here</em>
46
- # <% end %>
47
+ # @example Custom content
48
+ # @description
49
+ # Pass custom content as a block in place of `description`.
50
+ # @code
51
+ # <%= render Primer::BlankslateComponent.new(
52
+ # title: "Title",
53
+ # ) do %>
54
+ # <em>Your custom content here</em>
55
+ # <% end %>
47
56
  #
48
- # @example Action button|Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
49
- # <%= render Primer::BlankslateComponent.new(
50
- # icon: :book,
51
- # title: "Welcome to the mona wiki!",
52
- # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
57
+ # @example Action button
58
+ # @description
59
+ # Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
60
+ # @code
61
+ # <%= render Primer::BlankslateComponent.new(
62
+ # icon: :book,
63
+ # title: "Welcome to the mona wiki!",
64
+ # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
53
65
  #
54
- # button_text: "Create the first page",
55
- # button_url: "https://github.com/monalisa/mona/wiki/_new",
56
- # ) %>
66
+ # button_text: "Create the first page",
67
+ # button_url: "https://github.com/monalisa/mona/wiki/_new",
68
+ # ) %>
57
69
  #
58
- # @example Link|Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
59
- # <%= render Primer::BlankslateComponent.new(
60
- # icon: :book,
61
- # title: "Welcome to the mona wiki!",
62
- # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
63
- # link_text: "Learn more about wikis",
64
- # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
65
- # ) %>
70
+ # @example Link
71
+ # @description
72
+ # Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
73
+ # @code
74
+ # <%= render Primer::BlankslateComponent.new(
75
+ # icon: :book,
76
+ # title: "Welcome to the mona wiki!",
77
+ # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
78
+ # link_text: "Learn more about wikis",
79
+ # link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
80
+ # ) %>
66
81
  #
67
- # @example Variations|There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding.
68
- # <%= render Primer::BlankslateComponent.new(
69
- # icon: :book,
70
- # title: "Welcome to the mona wiki!",
71
- # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
72
- # narrow: true,
73
- # large: true,
74
- # spacious: true,
75
- # ) %>
82
+ # @example Variations
83
+ # @description
84
+ # There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding.
85
+ # @code
86
+ # <%= render Primer::BlankslateComponent.new(
87
+ # icon: :book,
88
+ # title: "Welcome to the mona wiki!",
89
+ # description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
90
+ # narrow: true,
91
+ # large: true,
92
+ # spacious: true,
93
+ # ) %>
76
94
  #
77
95
  # @param title [String] Text that appears in a larger bold font.
78
96
  # @param title_tag [Symbol] HTML tag to use for title.
@@ -1,4 +1,4 @@
1
- <%= wrapper do %>
1
+ <%= wrapper(**@wrapper_arguments) do %>
2
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
3
  <%= extra if @align == :left %>
4
4
 
@@ -5,6 +5,8 @@ module Primer
5
5
  class TabNavComponent < Primer::Component
6
6
  include Primer::TabbedComponentHelper
7
7
 
8
+ status :beta
9
+
8
10
  DEFAULT_EXTRA_ALIGN = :left
9
11
  EXTRA_ALIGN_OPTIONS = [DEFAULT_EXTRA_ALIGN, :right].freeze
10
12
 
@@ -102,15 +104,31 @@ module Primer
102
104
  # <% end %>
103
105
  # <% end %>
104
106
  #
107
+ # @example Customizing the body
108
+ # <%= render(Primer::TabNavComponent.new(label: "Default", body_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
109
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
110
+ # <% c.tab(href: "#") { "Tab 2" } %>
111
+ # <% c.tab(href: "#") { "Tab 3" } %>
112
+ # <% end %>
113
+ #
114
+ # @example Customizing the wrapper
115
+ # <%= render(Primer::TabNavComponent.new(label: "Default", wrapper_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
116
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
117
+ # <% c.tab(href: "#") { "Tab 2" } %>
118
+ # <% c.tab(href: "#") { "Tab 3" } %>
119
+ # <% end %>
120
+ #
105
121
  # @param label [String] Used to set the `aria-label` on the top level `<nav>` element.
106
122
  # @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
107
123
  # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
124
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
108
125
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
109
- def initialize(label:, with_panel: false, body_arguments: {}, **system_arguments)
126
+ def initialize(label:, with_panel: false, body_arguments: {}, wrapper_arguments: {}, **system_arguments)
110
127
  @align = DEFAULT_EXTRA_ALIGN
111
128
  @with_panel = with_panel
112
129
  @system_arguments = system_arguments
113
130
  @body_arguments = body_arguments
131
+ @wrapper_arguments = wrapper_arguments
114
132
 
115
133
  @system_arguments[:tag] ||= :div
116
134
  @system_arguments[:classes] = class_names(
@@ -1,4 +1,4 @@
1
- <%= wrapper do %>
1
+ <%= wrapper(**@wrapper_arguments) do %>
2
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
3
  <% if @align == :right %>
4
4
  <%= actions %>
@@ -116,14 +116,30 @@ module Primer
116
116
  # <% end %>
117
117
  # <% end %>
118
118
  #
119
+ # @example Customizing the body
120
+ # <%= render(Primer::UnderlineNavComponent.new(label: "Default", body_arguments: { tag: :ul, classes: "custom-class", border: true, border_color: :info })) do |c| %>
121
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
122
+ # <% c.tab(href: "#") { "Tab 2" } %>
123
+ # <% c.tab(href: "#") { "Tab 3" } %>
124
+ # <% end %>
125
+ #
126
+ # @example Customizing the wrapper
127
+ # <%= render(Primer::UnderlineNavComponent.new(label: "Default", wrapper_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
128
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
129
+ # <% c.tab(href: "#") { "Tab 2" } %>
130
+ # <% c.tab(href: "#") { "Tab 3" } %>
131
+ # <% end %>
132
+ #
119
133
  # @param label [String] The `aria-label` on top level `<nav>` element.
120
134
  # @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
121
135
  # @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
122
136
  # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
137
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
123
138
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
124
- def initialize(label:, with_panel: false, align: ALIGN_DEFAULT, body_arguments: { tag: BODY_TAG_DEFAULT }, **system_arguments)
139
+ def initialize(label:, with_panel: false, align: ALIGN_DEFAULT, body_arguments: { tag: BODY_TAG_DEFAULT }, wrapper_arguments: {}, **system_arguments)
125
140
  @with_panel = with_panel
126
141
  @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
142
+ @wrapper_arguments = wrapper_arguments
127
143
 
128
144
  @system_arguments = system_arguments
129
145
  @system_arguments[:tag] = navigation_tag(with_panel)
@@ -7,7 +7,7 @@ module Primer
7
7
  SPACING_KEYS = Primer::Classify::Spacing::KEYS
8
8
 
9
9
  # Keys where we can simply translate { key: value } into ".key-value"
10
- CONCAT_KEYS = SPACING_KEYS + %i[hide position v float col text box_shadow].freeze
10
+ CONCAT_KEYS = SPACING_KEYS + %i[hide position v float text box_shadow].freeze
11
11
 
12
12
  INVALID_CLASS_NAME_PREFIXES =
13
13
  (["bg-", "color-", "text-", "d-", "v-align-", "wb-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
@@ -22,9 +22,10 @@ module Primer
22
22
  BOX_SHADOW_KEY = :box_shadow
23
23
  VISIBILITY_KEY = :visibility
24
24
  ANIMATION_KEY = :animation
25
+ CONTAINER_KEY = :container
25
26
 
26
27
  BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
27
- RESPONSIVE_KEYS = ([DISPLAY_KEY, :col, :float] + SPACING_KEYS + Primer::Classify::Flex::RESPONSIVE_KEYS).freeze
28
+ RESPONSIVE_KEYS = ([DISPLAY_KEY, :float, Primer::Classify::Grid::COL_KEY] + SPACING_KEYS + Primer::Classify::Flex::RESPONSIVE_KEYS).freeze
28
29
 
29
30
  BOOLEAN_MAPPINGS = {
30
31
  underline: {
@@ -84,6 +85,7 @@ module Primer
84
85
  TYPOGRAPHY_KEYS +
85
86
  TEXT_KEYS +
86
87
  Primer::Classify::Flex::KEYS +
88
+ Primer::Classify::Grid::KEYS +
87
89
  [
88
90
  BORDER_KEY,
89
91
  BORDER_COLOR_KEY,
@@ -97,7 +99,8 @@ module Primer
97
99
  HEIGHT_KEY,
98
100
  BOX_SHADOW_KEY,
99
101
  VISIBILITY_KEY,
100
- ANIMATION_KEY
102
+ ANIMATION_KEY,
103
+ CONTAINER_KEY
101
104
  ]
102
105
  ).freeze
103
106
 
@@ -206,6 +209,8 @@ module Primer
206
209
  memo[:classes] << "rounded-#{val}"
207
210
  elsif Primer::Classify::Flex::KEYS.include?(key)
208
211
  memo[:classes] << Primer::Classify::Flex.classes(key, val, breakpoint)
212
+ elsif Primer::Classify::Grid::KEYS.include?(key)
213
+ memo[:classes] << Primer::Classify::Grid.classes(key, val, breakpoint)
209
214
  elsif key == WIDTH_KEY || key == HEIGHT_KEY
210
215
  if val == :fit
211
216
  memo[:classes] << "#{key}-#{val}"
@@ -54,6 +54,21 @@ module Primer
54
54
  values: Primer::Classify::Flex::ALIGN_ITEMS_VALUES
55
55
  )
56
56
 
57
+ preload(
58
+ keys: Primer::Classify::Grid::CONTAINER_KEY,
59
+ values: Primer::Classify::Grid::CONTAINER_VALUES
60
+ )
61
+
62
+ preload(
63
+ keys: Primer::Classify::Grid::CLEARFIX_KEY,
64
+ values: [true]
65
+ )
66
+
67
+ preload(
68
+ keys: Primer::Classify::Grid::COL_KEY,
69
+ values: Primer::Classify::Grid::COL_VALUES
70
+ )
71
+
57
72
  preload(
58
73
  keys: Primer::Classify::DISPLAY_KEY,
59
74
  values: [:flex, :block, :inline_block, :inline_flex, :none, :table, :table_cell]
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ class Classify
5
+ # Handler for PrimerCSS grid classes.
6
+ class Grid
7
+ extend Primer::FetchOrFallbackHelper
8
+
9
+ CONTAINER_KEY = :container
10
+ CONTAINER_VALUES = [:xl, :lg, :md, :sm].freeze
11
+
12
+ CLEARFIX_KEY = :clearfix
13
+ CLEARFIX_VALUES = [true, false].freeze
14
+
15
+ COL_KEY = :col
16
+ COL_VALUES = (1..12).to_a.freeze
17
+
18
+ KEYS = [CONTAINER_KEY, CLEARFIX_KEY, COL_KEY].freeze
19
+
20
+ class << self
21
+ def classes(key, value, breakpoint)
22
+ send(key, value, breakpoint)
23
+ end
24
+
25
+ private
26
+
27
+ def container(value, _breakpoint)
28
+ val = fetch_or_fallback(CONTAINER_VALUES, value)
29
+
30
+ "container-#{val}"
31
+ end
32
+
33
+ def clearfix(value, _breakpoint)
34
+ "clearfix" if fetch_or_fallback(CLEARFIX_VALUES, value)
35
+ end
36
+
37
+ def col(value, breakpoint)
38
+ val = fetch_or_fallback(COL_VALUES, value.to_i)
39
+
40
+ "col#{breakpoint}-#{val}"
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -20,10 +20,10 @@ module Primer
20
20
  with_panel ? :div : :nav
21
21
  end
22
22
 
23
- def wrapper
23
+ def wrapper(**system_arguments)
24
24
  return yield unless @with_panel
25
25
 
26
- render Primer::TabContainerComponent.new do
26
+ render Primer::TabContainerComponent.new(**system_arguments) do
27
27
  yield
28
28
  end
29
29
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.join(__dir__, "linters", "*.rb")].sort.each { |file| require file }
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Counts the number of times a HTML button is used instead of the component.
8
+ class ButtonComponentMigrationCounter < Linter
9
+ include Helpers
10
+
11
+ TAGS = %w[button summary a].freeze
12
+ CLASS = "btn"
13
+ MESSAGE = "We are migrating buttons to use [Primer::ButtonComponent](https://primer.style/view-components/components/button), please try to use that instead of raw HTML."
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "helpers"
4
+
5
+ module ERBLint
6
+ module Linters
7
+ # Counts the number of times a HTML flash is used instead of the component.
8
+ class FlashComponentMigrationCounter < Linter
9
+ include Helpers
10
+
11
+ TAGS = %w[div].freeze
12
+ CLASS = "flash"
13
+ MESSAGE = "We are migrating flashes to use [Primer::FlashComponent](https://primer.style/view-components/components/flash), please try to use that instead of raw HTML."
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "openssl"
5
+
6
+ module ERBLint
7
+ module Linters
8
+ # Helper methods for linting ERB.
9
+ module Helpers
10
+ def self.included(base)
11
+ base.include(LinterRegistry)
12
+
13
+ define_method "run" do |processed_source|
14
+ tags(processed_source).each do |tag|
15
+ next if tag.closing?
16
+ next unless self.class::TAGS&.include?(tag.name)
17
+
18
+ classes = tag.attributes["class"]&.value&.split(" ")
19
+
20
+ next unless !self.class::CLASS || classes&.include?(self.class::CLASS)
21
+
22
+ generate_offense(self.class, processed_source, tag, self.class::MESSAGE)
23
+ end
24
+
25
+ counter_correct?(processed_source)
26
+ end
27
+
28
+ define_method "autocorrect" do |processed_source, offense|
29
+ return unless offense.context
30
+
31
+ lambda do |corrector|
32
+ if processed_source.file_content.include?("erblint:counter #{self.class.name.demodulize}")
33
+ # update the counter if exists
34
+ corrector.replace(offense.source_range, offense.context)
35
+ else
36
+ # add comment with counter if none
37
+ corrector.insert_before(processed_source.source_buffer.source_range, "#{offense.context}\n")
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def tags(processed_source)
46
+ processed_source.parser.nodes_with_type(:tag).map { |tag_node| BetterHtml::Tree::Tag.from_node(tag_node) }
47
+ end
48
+
49
+ def counter_correct?(processed_source)
50
+ comment_node = nil
51
+ expected_count = 0
52
+ rule_name = self.class.name.match(/:?:?(\w+)\Z/)[1]
53
+ offenses_count = @offenses.length
54
+
55
+ processed_source.parser.ast.descendants(:erb).each do |node|
56
+ indicator_node, _, code_node, = *node
57
+ indicator = indicator_node&.loc&.source
58
+ comment = code_node&.loc&.source&.strip
59
+
60
+ if indicator == "#" && comment.start_with?("erblint:count") && comment.match(rule_name)
61
+ comment_node = code_node
62
+ expected_count = comment.match(/\s(\d+)\s?$/)[1].to_i
63
+ end
64
+ end
65
+
66
+ if offenses_count.zero?
67
+ add_offense(processed_source.to_source_range(comment_node.loc), "Unused erblint:count comment for #{rule_name}") if comment_node
68
+ return
69
+ end
70
+
71
+ first_offense = @offenses[0]
72
+
73
+ if comment_node.nil?
74
+ add_offense(processed_source.to_source_range(first_offense.source_range), "#{rule_name}: If you must, add <%# erblint:counter #{rule_name} #{offenses_count} %> to bypass this check.", "<%# erblint:counter #{rule_name} #{offenses_count} %>")
75
+ else
76
+ clear_offenses
77
+ add_offense(processed_source.to_source_range(comment_node.loc), "Incorrect erblint:counter number for #{rule_name}. Expected: #{expected_count}, actual: #{offenses_count}.", " erblint:counter #{rule_name} #{offenses_count} ") if expected_count != offenses_count
78
+ end
79
+ end
80
+
81
+ def generate_offense(klass, processed_source, tag, message = nil, replacement = nil)
82
+ message ||= klass::MESSAGE
83
+ klass_name = klass.name.split("::")[-1]
84
+ offense = ["#{klass_name}:#{message}", tag.node.loc.source].join("\n")
85
+ add_offense(processed_source.to_source_range(tag.loc), offense, replacement)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -5,7 +5,7 @@ module Primer
5
5
  module VERSION
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 42
8
+ PATCH = 43
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end
data/lib/tasks/docs.rake CHANGED
@@ -20,32 +20,12 @@ namespace :docs do
20
20
  end
21
21
 
22
22
  task :build do
23
- require File.expand_path("./../../demo/config/environment.rb", __dir__)
24
- require "primer/view_components"
25
- require "yard/docs_helper"
26
- require "view_component/test_helpers"
27
- include ViewComponent::TestHelpers
28
- include Primer::ViewHelper
29
- include YARD::DocsHelper
30
-
31
- Dir["./app/components/primer/**/*.rb"].sort.each { |file| require file }
32
-
33
- YARD::Rake::YardocTask.new
34
-
35
- # Custom tags for yard
36
- YARD::Tags::Library.define_tag("Accessibility", :accessibility)
37
- YARD::Tags::Library.define_tag("Deprecation", :deprecation)
38
-
39
- puts "Building YARD documentation."
40
- Rake::Task["yard"].execute
23
+ registry = generate_yard_registry
41
24
 
42
25
  puts "Converting YARD documentation to Markdown files."
43
26
 
44
27
  # Rails controller for rendering arbitrary ERB
45
28
  view_context = ApplicationController.new.tap { |c| c.request = ActionDispatch::TestRequest.create }.view_context
46
-
47
- registry = YARD::RegistryStore.new
48
- registry.load!(".yardoc")
49
29
  components = [
50
30
  Primer::Image,
51
31
  Primer::LocalTime,
@@ -172,7 +152,18 @@ namespace :docs do
172
152
  end
173
153
 
174
154
  initialize_method.tags(:example).each do |tag|
175
- (name, description) = tag.name.split("|")
155
+ name = tag.name
156
+ description = nil
157
+ code = nil
158
+
159
+ if tag.text.include?("@description")
160
+ splitted = tag.text.split(/@description|@code/)
161
+ description = splitted.second.gsub(/^[ \t]{2}/, "").strip
162
+ code = splitted.last.gsub(/^[ \t]{2}/, "").strip
163
+ else
164
+ code = tag.text
165
+ end
166
+
176
167
  f.puts
177
168
  f.puts("### #{name}")
178
169
  if description
@@ -180,14 +171,14 @@ namespace :docs do
180
171
  f.puts(description)
181
172
  end
182
173
  f.puts
183
- html = view_context.render(inline: tag.text)
174
+ html = view_context.render(inline: code)
184
175
  html.scan(/class="([^"]*)"/) do |classnames|
185
176
  classes_found_in_examples.concat(classnames[0].split(" ").reject { |c| c.starts_with?("octicon", "js", "my-") }.map { ".#{_1}"})
186
177
  end
187
178
  f.puts("<Example src=\"#{html.tr('"', "\'").delete("\n")}\" />")
188
179
  f.puts
189
180
  f.puts("```erb")
190
- f.puts(tag.text.to_s)
181
+ f.puts(code.to_s)
191
182
  f.puts("```")
192
183
  end
193
184
 
@@ -302,6 +293,22 @@ namespace :docs do
302
293
 
303
294
  puts "Markdown compiled."
304
295
 
296
+ if components_without_examples.any?
297
+ puts
298
+ puts "The following components have no examples defined: #{components_without_examples.map(&:name).join(', ')}. Consider adding an example?"
299
+ end
300
+
301
+ if components_needing_docs.any?
302
+ puts
303
+ puts "The following components needs docs. Care to contribute them? #{components_needing_docs.map(&:name).join(', ')}"
304
+ end
305
+ end
306
+
307
+ task :preview do
308
+ registry = generate_yard_registry
309
+
310
+ components = Primer::Component.descendants
311
+
305
312
  # Generate previews from documentation examples
306
313
  components.each do |component|
307
314
  documentation = registry.get(component.name)
@@ -336,15 +343,30 @@ namespace :docs do
336
343
  f.puts("end")
337
344
  end
338
345
  end
346
+ end
339
347
 
340
- if components_without_examples.any?
341
- puts
342
- puts "The following components have no examples defined: #{components_without_examples.map(&:name).join(', ')}. Consider adding an example?"
343
- end
348
+ def generate_yard_registry
349
+ require File.expand_path("./../../demo/config/environment.rb", __dir__)
350
+ require "primer/view_components"
351
+ require "yard/docs_helper"
352
+ require "view_component/test_helpers"
353
+ include ViewComponent::TestHelpers
354
+ include Primer::ViewHelper
355
+ include YARD::DocsHelper
344
356
 
345
- if components_needing_docs.any?
346
- puts
347
- puts "The following components needs docs. Care to contribute them? #{components_needing_docs.map(&:name).join(', ')}"
348
- end
357
+ Dir["./app/components/primer/**/*.rb"].sort.each { |file| require file }
358
+
359
+ YARD::Rake::YardocTask.new
360
+
361
+ # Custom tags for yard
362
+ YARD::Tags::Library.define_tag("Accessibility", :accessibility)
363
+ YARD::Tags::Library.define_tag("Deprecation", :deprecation)
364
+
365
+ puts "Building YARD documentation."
366
+ Rake::Task["yard"].execute
367
+
368
+ registry = YARD::RegistryStore.new
369
+ registry.load!(".yardoc")
370
+ registry
349
371
  end
350
372
  end
data/static/statuses.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "Primer::StateComponent": "beta",
44
44
  "Primer::SubheadComponent": "beta",
45
45
  "Primer::TabContainerComponent": "alpha",
46
- "Primer::TabNavComponent": "alpha",
46
+ "Primer::TabNavComponent": "beta",
47
47
  "Primer::TextComponent": "beta",
48
48
  "Primer::TimeAgoComponent": "beta",
49
49
  "Primer::TimelineItemComponent": "beta",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.42
4
+ version: 0.0.43
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2021-06-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -142,6 +142,20 @@ dependencies:
142
142
  - - '='
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0.13'
145
+ - !ruby/object:Gem::Dependency
146
+ name: erb_lint
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
145
159
  - !ruby/object:Gem::Dependency
146
160
  name: listen
147
161
  requirement: !ruby/object:Gem::Requirement
@@ -444,6 +458,7 @@ files:
444
458
  - app/lib/primer/classify/functional_border_colors.rb
445
459
  - app/lib/primer/classify/functional_colors.rb
446
460
  - app/lib/primer/classify/functional_text_colors.rb
461
+ - app/lib/primer/classify/grid.rb
447
462
  - app/lib/primer/classify/spacing.rb
448
463
  - app/lib/primer/fetch_or_fallback_helper.rb
449
464
  - app/lib/primer/join_style_arguments_helper.rb
@@ -454,6 +469,10 @@ files:
454
469
  - app/lib/primer/view_helper.rb
455
470
  - lib/primer/view_components.rb
456
471
  - lib/primer/view_components/engine.rb
472
+ - lib/primer/view_components/linters.rb
473
+ - lib/primer/view_components/linters/button_component_migration_counter.rb
474
+ - lib/primer/view_components/linters/flash_component_migration_counter.rb
475
+ - lib/primer/view_components/linters/helpers.rb
457
476
  - lib/primer/view_components/version.rb
458
477
  - lib/tasks/coverage.rake
459
478
  - lib/tasks/docs.rake