primer_view_components 0.0.41 → 0.0.46

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +265 -1
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/alpha/button_marketing.rb +70 -0
  6. data/app/components/primer/auto_complete.rb +99 -42
  7. data/app/components/primer/auto_complete/auto_complete.html.erb +1 -0
  8. data/app/components/primer/avatar_stack_component.rb +7 -1
  9. data/app/components/primer/base_component.rb +62 -26
  10. data/app/components/primer/beta/text.rb +27 -0
  11. data/app/components/primer/blankslate_component.html.erb +1 -0
  12. data/app/components/primer/blankslate_component.rb +64 -45
  13. data/app/components/primer/border_box_component.rb +3 -0
  14. data/app/components/primer/button_component.rb +3 -2
  15. data/app/components/primer/button_group.rb +1 -1
  16. data/app/components/primer/clipboard_copy.rb +25 -7
  17. data/app/components/primer/component.rb +5 -1
  18. data/app/components/primer/details_component.rb +18 -3
  19. data/app/components/primer/dropdown.d.ts +1 -0
  20. data/app/components/primer/{dropdown_component.html.erb → dropdown.html.erb} +2 -1
  21. data/app/components/primer/dropdown.js +1 -0
  22. data/app/components/primer/dropdown.rb +149 -0
  23. data/app/components/primer/dropdown.ts +1 -0
  24. data/app/components/primer/dropdown/menu.d.ts +1 -0
  25. data/app/components/primer/dropdown/menu.html.erb +25 -0
  26. data/app/components/primer/dropdown/menu.js +1 -0
  27. data/app/components/primer/dropdown/menu.rb +99 -0
  28. data/app/components/primer/dropdown/menu.ts +1 -0
  29. data/app/components/primer/heading_component.rb +1 -1
  30. data/app/components/primer/hidden_text_expander.rb +2 -2
  31. data/app/components/primer/icon_button.rb +1 -1
  32. data/app/components/primer/image_crop.rb +2 -2
  33. data/app/components/primer/markdown.rb +6 -2
  34. data/app/components/primer/menu_component.rb +7 -3
  35. data/app/components/primer/navigation/tab_component.rb +6 -6
  36. data/app/components/primer/octicon_component.rb +4 -3
  37. data/app/components/primer/popover_component.rb +2 -2
  38. data/app/components/primer/primer.d.ts +1 -0
  39. data/app/components/primer/primer.js +1 -0
  40. data/app/components/primer/primer.ts +1 -0
  41. data/app/components/primer/spinner_component.rb +2 -0
  42. data/app/components/primer/tab_nav_component.html.erb +4 -2
  43. data/app/components/primer/tab_nav_component.rb +48 -6
  44. data/app/components/primer/tooltip.rb +1 -1
  45. data/app/components/primer/truncate.rb +6 -2
  46. data/app/components/primer/underline_nav_component.html.erb +1 -1
  47. data/app/components/primer/underline_nav_component.rb +27 -5
  48. data/app/lib/primer/tabbed_component_helper.rb +2 -2
  49. data/{app/lib → lib}/primer/classify.rb +41 -35
  50. data/{app/lib → lib}/primer/classify/cache.rb +16 -35
  51. data/{app/lib → lib}/primer/classify/flex.rb +0 -0
  52. data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
  53. data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
  54. data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
  55. data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
  56. data/lib/primer/classify/grid.rb +45 -0
  57. data/lib/primer/classify/utilities.rb +137 -0
  58. data/lib/primer/classify/utilities.yml +1271 -0
  59. data/lib/primer/view_components.rb +1 -0
  60. data/lib/primer/view_components/engine.rb +2 -0
  61. data/lib/primer/view_components/linters.rb +3 -0
  62. data/lib/primer/view_components/linters/argument_mappers/button.rb +82 -0
  63. data/lib/primer/view_components/linters/argument_mappers/conversion_error.rb +10 -0
  64. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +47 -0
  65. data/lib/primer/view_components/linters/button_component_migration_counter.rb +39 -0
  66. data/lib/primer/view_components/linters/flash_component_migration_counter.rb +16 -0
  67. data/lib/primer/view_components/linters/helpers.rb +191 -0
  68. data/lib/primer/view_components/version.rb +1 -1
  69. data/lib/tasks/docs.rake +180 -108
  70. data/lib/tasks/utilities.rake +105 -0
  71. data/lib/yard/docs_helper.rb +12 -2
  72. data/static/statuses.json +7 -5
  73. metadata +50 -20
  74. data/app/components/primer/button_marketing_component.rb +0 -68
  75. data/app/components/primer/dropdown/menu_component.html.erb +0 -12
  76. data/app/components/primer/dropdown/menu_component.rb +0 -46
  77. data/app/components/primer/dropdown_component.rb +0 -73
  78. data/app/components/primer/text_component.rb +0 -25
  79. data/app/lib/primer/classify/spacing.rb +0 -63
@@ -18,7 +18,7 @@ module Primer
18
18
  #
19
19
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
20
20
  renders_one :panel, lambda { |**system_arguments|
21
- system_arguments[:tag] ||= :div
21
+ system_arguments[:tag] = :div
22
22
  system_arguments[:role] ||= :tabpanel
23
23
  system_arguments[:hidden] = true unless @selected
24
24
 
@@ -38,8 +38,8 @@ module Primer
38
38
 
39
39
  # The Tab's text.
40
40
  #
41
- # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::TextComponent) %>.
42
- renders_one :text, Primer::TextComponent
41
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::Beta::Text) %>.
42
+ renders_one :text, Primer::Beta::Text
43
43
 
44
44
  # Counter to be rendered in the Tab right.
45
45
  #
@@ -96,12 +96,12 @@ module Primer
96
96
 
97
97
  @system_arguments = system_arguments
98
98
 
99
- if with_panel
100
- @system_arguments[:tag] ||= :button
99
+ if with_panel || @system_arguments[:tag] == :button
100
+ @system_arguments[:tag] = :button
101
101
  @system_arguments[:type] = :button
102
102
  @system_arguments[:role] = :tab
103
103
  else
104
- @system_arguments[:tag] ||= :a
104
+ @system_arguments[:tag] = :a
105
105
  end
106
106
 
107
107
  @wrapper_arguments = wrapper_arguments
@@ -27,15 +27,16 @@ module Primer
27
27
  # @example Helper
28
28
  # <%= primer_octicon(:check) %>
29
29
  #
30
- # @param icon [Symbol] Name of <%= link_to_octicons %> to use.
31
- # @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
30
+ # @param icon_name [Symbol, String] Name of <%= link_to_octicons %> to use.
31
+ # @param icon [Symbol, String] Name of <%= link_to_octicons %> to use.
32
+ # @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS, sort: false) %>
32
33
  # @param use_symbol [Boolean] EXPERIMENTAL (May change or be removed) - Set to true when using with <%= link_to_component(Primer::OcticonSymbolsComponent) %>.
33
34
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
34
35
  def initialize(icon_name = nil, icon: nil, size: SIZE_DEFAULT, use_symbol: false, **system_arguments)
35
36
  icon_key = icon_name || icon
36
37
 
37
38
  # Don't allow sizes under 16px
38
- if system_arguments[:height].present? && system_arguments[:height] < 16 || system_arguments[:width].present? && system_arguments[:width] < 16
39
+ if system_arguments[:height].present? && system_arguments[:height].to_i < 16 || system_arguments[:width].present? && system_arguments[:width].to_i < 16
39
40
  system_arguments.delete(:height)
40
41
  system_arguments.delete(:width)
41
42
  end
@@ -28,7 +28,7 @@ module Primer
28
28
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
29
  renders_one :heading, lambda { |**system_arguments|
30
30
  system_arguments[:mb] ||= 2
31
- system_arguments[:tag] ||= :h4
31
+ system_arguments[:tag] ||= :h4 # rubocop:disable Primer/NoTagMemoize
32
32
 
33
33
  Primer::HeadingComponent.new(**system_arguments)
34
34
  }
@@ -106,7 +106,7 @@ module Primer
106
106
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
107
107
  def initialize(**system_arguments)
108
108
  @system_arguments = system_arguments
109
- @system_arguments[:tag] ||= :div
109
+ @system_arguments[:tag] ||= :div # rubocop:disable Primer/NoTagMemoize
110
110
  @system_arguments[:classes] = class_names(
111
111
  system_arguments[:classes],
112
112
  "Popover"
@@ -4,3 +4,4 @@ import './tab_container_component';
4
4
  import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
+ import './dropdown';
@@ -4,3 +4,4 @@ import './tab_container_component';
4
4
  import './time_ago_component';
5
5
  import './local_time';
6
6
  import './image_crop';
7
+ import './dropdown';
@@ -4,3 +4,4 @@ import './tab_container_component'
4
4
  import './time_ago_component'
5
5
  import './local_time'
6
6
  import './image_crop'
7
+ import './dropdown'
@@ -27,6 +27,8 @@ module Primer
27
27
  # <%= render(Primer::SpinnerComponent.new(size: :large)) %>
28
28
  #
29
29
  # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_MAPPINGS) %>
30
+ # @param style [String] Custom element styles.
31
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
30
32
  def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **system_arguments)
31
33
  @system_arguments = system_arguments
32
34
  @system_arguments[:tag] = :svg
@@ -1,12 +1,14 @@
1
- <%= wrapper do %>
1
+ <%= wrapper(**@wrapper_arguments) do %>
2
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
- <%= extra %>
3
+ <%= extra if @align == :left %>
4
4
 
5
5
  <%= render Primer::BaseComponent.new(**@body_arguments) do %>
6
6
  <% tabs.each do |tab| %>
7
7
  <%= tab %>
8
8
  <% end %>
9
9
  <% end %>
10
+
11
+ <%= extra if @align == :right %>
10
12
  <% end %>
11
13
 
12
14
  <% if @with_panel %>
@@ -5,7 +5,13 @@ module Primer
5
5
  class TabNavComponent < Primer::Component
6
6
  include Primer::TabbedComponentHelper
7
7
 
8
- # Tabs to be rendered. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
8
+ status :beta
9
+
10
+ DEFAULT_EXTRA_ALIGN = :left
11
+ EXTRA_ALIGN_OPTIONS = [DEFAULT_EXTRA_ALIGN, :right].freeze
12
+
13
+ # Tabs to be rendered. When `with_panel` is set on the parent, a button is rendered for panel navigation. Otherwise,
14
+ # an anchor tag is rendered for page navigation. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
9
15
  #
10
16
  # @param selected [Boolean] Whether the tab is selected.
11
17
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -23,7 +29,13 @@ module Primer
23
29
  }
24
30
 
25
31
  # Renders extra content to the `TabNav`. This will be rendered after the tabs.
26
- renders_one :extra
32
+ #
33
+ # @param align [Symbol] <%= one_of(Primer::TabNavComponent::EXTRA_ALIGN_OPTIONS) %>
34
+ renders_one :extra, lambda { |align: DEFAULT_EXTRA_ALIGN, &block|
35
+ @align = fetch_or_fallback(EXTRA_ALIGN_OPTIONS, align, DEFAULT_EXTRA_ALIGN)
36
+
37
+ view_context.capture { block&.call }
38
+ }
27
39
 
28
40
  # @example Default
29
41
  # <%= render(Primer::TabNavComponent.new(label: "Default")) do |c| %>
@@ -72,7 +84,7 @@ module Primer
72
84
  # <% end %>
73
85
  #
74
86
  # @example With extra content
75
- # <%= render(Primer::TabNavComponent.new(label: "Default")) do |c| %>
87
+ # <%= render(Primer::TabNavComponent.new(label: "With extra content")) do |c| %>
76
88
  # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
77
89
  # <% c.tab(href: "#") { "Tab 2" } %>
78
90
  # <% c.tab(href: "#") { "Tab 3" } %>
@@ -81,16 +93,46 @@ module Primer
81
93
  # <% end %>
82
94
  # <% end %>
83
95
  #
96
+ # @example Adding extra content after the tabs
97
+ # <%= render(Primer::TabNavComponent.new(label: "Adding extra content after the tabs", display: :flex, body_arguments: { flex: 1 })) do |c| %>
98
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
99
+ # <% c.tab(href: "#") { "Tab 2" } %>
100
+ # <% c.tab(href: "#") { "Tab 3" } %>
101
+ # <% c.extra(align: :right) do %>
102
+ # <div>
103
+ # <%= render(Primer::ButtonComponent.new) { "Button" } %>
104
+ # </div>
105
+ # <% end %>
106
+ # <% end %>
107
+ #
108
+ # @example Customizing the body
109
+ # <%= render(Primer::TabNavComponent.new(label: "Default", body_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
110
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
111
+ # <% c.tab(href: "#") { "Tab 2" } %>
112
+ # <% c.tab(href: "#") { "Tab 3" } %>
113
+ # <% end %>
114
+ #
115
+ # @example Customizing the wrapper
116
+ # <%= render(Primer::TabNavComponent.new(label: "Default", wrapper_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
117
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
118
+ # <% c.tab(href: "#") { "Tab 2" } %>
119
+ # <% c.tab(href: "#") { "Tab 3" } %>
120
+ # <% end %>
121
+ #
84
122
  # @param label [String] Used to set the `aria-label` on the top level `<nav>` element.
85
- # @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
123
+ # @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels. When true, <%= link_to_component(Primer::TabContainerComponent) %>
124
+ # is rendered along with JavaScript behavior. Additionally, the `tab` slot will render as a button as opposed to an anchor.
86
125
  # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
126
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
87
127
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
88
- def initialize(label:, with_panel: false, body_arguments: {}, **system_arguments)
128
+ def initialize(label:, with_panel: false, body_arguments: {}, wrapper_arguments: {}, **system_arguments)
129
+ @align = DEFAULT_EXTRA_ALIGN
89
130
  @with_panel = with_panel
90
131
  @system_arguments = system_arguments
91
132
  @body_arguments = body_arguments
133
+ @wrapper_arguments = wrapper_arguments
92
134
 
93
- @system_arguments[:tag] ||= :div
135
+ @system_arguments[:tag] = :div
94
136
  @system_arguments[:classes] = class_names(
95
137
  "tabnav",
96
138
  system_arguments[:classes]
@@ -70,7 +70,7 @@ module Primer
70
70
  **system_arguments
71
71
  )
72
72
  @system_arguments = system_arguments
73
- @system_arguments[:tag] ||= :span
73
+ @system_arguments[:tag] ||= :span # rubocop:disable Primer/NoTagMemoize
74
74
  @system_arguments[:aria] = { label: label }
75
75
 
76
76
  @system_arguments[:classes] = class_names(
@@ -5,6 +5,9 @@ module Primer
5
5
  class Truncate < Primer::Component
6
6
  status :beta
7
7
 
8
+ DEFAULT_TAG = :div
9
+ TAG_OPTIONS = [DEFAULT_TAG, :span, :p].freeze
10
+
8
11
  # @example Default
9
12
  # <div class="col-2">
10
13
  # <%= render(Primer::Truncate.new(tag: :p)) { "branch-name-that-is-really-long" } %>
@@ -19,13 +22,14 @@ module Primer
19
22
  # @example Custom size
20
23
  # <%= render(Primer::Truncate.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
21
24
  #
25
+ # @param tag [Symbol] <%= one_of(Primer::Truncate::TAG_OPTIONS) %>
22
26
  # @param inline [Boolean] Whether the element is inline (or inline-block).
23
27
  # @param expandable [Boolean] Whether the entire string should be revealed on hover. Can only be used in conjunction with `inline`.
24
28
  # @param max_width [Integer] Sets the max-width of the text.
25
29
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
26
- def initialize(inline: false, expandable: false, max_width: nil, **system_arguments)
30
+ def initialize(tag: DEFAULT_TAG, inline: false, expandable: false, max_width: nil, **system_arguments)
27
31
  @system_arguments = system_arguments
28
- @system_arguments[:tag] ||= :div
32
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
29
33
  @system_arguments[:classes] = class_names(
30
34
  @system_arguments[:classes],
31
35
  "css-truncate",
@@ -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 %>
@@ -13,7 +13,11 @@ module Primer
13
13
  BODY_TAG_DEFAULT = :div
14
14
  BODY_TAG_OPTIONS = [BODY_TAG_DEFAULT, :ul].freeze
15
15
 
16
- # Use the tabs to list navigation items. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
16
+ ACTIONS_TAG_DEFAULT = :div
17
+ ACTIONS_TAG_OPTIONS = [ACTIONS_TAG_DEFAULT, :span].freeze
18
+
19
+ # Use the tabs to list navigation items. When `with_panel` is set on the parent, a button is rendered for panel navigation. Otherwise,
20
+ # an anchor tag is rendered for page navigation. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
17
21
  #
18
22
  # @param selected [Boolean] Whether the tab is selected.
19
23
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -34,9 +38,10 @@ module Primer
34
38
 
35
39
  # Use actions for a call to action.
36
40
  #
41
+ # @param tag [String] (Primer::UnderlineNavComponent::ACTIONS_TAG_DEFAULT) <%= one_of(Primer::UnderlineNavComponent::ACTIONS_TAG_OPTIONS) %>
37
42
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
38
- renders_one :actions, lambda { |**system_arguments|
39
- system_arguments[:tag] ||= :div
43
+ renders_one :actions, lambda { |tag: ACTIONS_TAG_DEFAULT, **system_arguments|
44
+ system_arguments[:tag] = fetch_or_fallback(ACTIONS_TAG_OPTIONS, tag, ACTIONS_TAG_DEFAULT)
40
45
  system_arguments[:classes] = class_names("UnderlineNav-actions", system_arguments[:classes])
41
46
 
42
47
  Primer::BaseComponent.new(**system_arguments)
@@ -116,14 +121,31 @@ module Primer
116
121
  # <% end %>
117
122
  # <% end %>
118
123
  #
124
+ # @example Customizing the body
125
+ # <%= render(Primer::UnderlineNavComponent.new(label: "Default", body_arguments: { tag: :ul, classes: "custom-class", border: true, border_color: :info })) do |c| %>
126
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
127
+ # <% c.tab(href: "#") { "Tab 2" } %>
128
+ # <% c.tab(href: "#") { "Tab 3" } %>
129
+ # <% end %>
130
+ #
131
+ # @example Customizing the wrapper
132
+ # <%= render(Primer::UnderlineNavComponent.new(label: "Default", wrapper_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
133
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
134
+ # <% c.tab(href: "#") { "Tab 2" } %>
135
+ # <% c.tab(href: "#") { "Tab 3" } %>
136
+ # <% end %>
137
+ #
119
138
  # @param label [String] The `aria-label` on top level `<nav>` element.
120
- # @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
139
+ # @param with_panel [Boolean] Whether the `UnderlineNav` should navigate through pages or panels. When true, <%= link_to_component(Primer::TabContainerComponent) %> is
140
+ # rendered along with JavaScript behavior.
121
141
  # @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
122
142
  # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
143
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
123
144
  # @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)
145
+ def initialize(label:, with_panel: false, align: ALIGN_DEFAULT, body_arguments: { tag: BODY_TAG_DEFAULT }, wrapper_arguments: {}, **system_arguments)
125
146
  @with_panel = with_panel
126
147
  @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
148
+ @wrapper_arguments = wrapper_arguments
127
149
 
128
150
  @system_arguments = system_arguments
129
151
  @system_arguments[:tag] = navigation_tag(with_panel)
@@ -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
@@ -1,30 +1,42 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "classify/cache"
4
+ require_relative "classify/flex"
5
+ require_relative "classify/functional_background_colors"
6
+ require_relative "classify/functional_border_colors"
7
+ require_relative "classify/functional_text_colors"
8
+ require_relative "classify/grid"
9
+ require_relative "classify/utilities"
10
+
3
11
  module Primer
4
12
  # :nodoc:
5
13
  class Classify
6
- DISPLAY_KEY = :display
7
- SPACING_KEYS = Primer::Classify::Spacing::KEYS
14
+ # Load the utilities.yml file.
15
+ # Disabling because we want to load symbols, strings, and integers from the .yml file
16
+ # rubocop:disable Security/YAMLLoad
17
+ UTILITIES = YAML.load(
18
+ File.read(
19
+ File.join(File.dirname(__FILE__), "./classify/utilities.yml")
20
+ )
21
+ ).freeze
22
+ # rubocop:enable Security/YAMLLoad
8
23
 
9
24
  # 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
25
+ CONCAT_KEYS = %i[text box_shadow].freeze
11
26
 
12
27
  INVALID_CLASS_NAME_PREFIXES =
13
- (["bg-", "color-", "text-", "d-", "v-align-", "wb-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
28
+ (["bg-", "color-", "text-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
14
29
 
15
30
  COLOR_KEY = :color
16
31
  BG_KEY = :bg
17
- VERTICAL_ALIGN_KEY = :vertical_align
18
- WORD_BREAK_KEY = :word_break
19
- TEXT_KEYS = %i[text_align font_weight].freeze
32
+ TEXT_KEYS = %i[font_family font_style font_weight text_align text_transform].freeze
20
33
  WIDTH_KEY = :width
21
34
  HEIGHT_KEY = :height
22
35
  BOX_SHADOW_KEY = :box_shadow
23
- VISIBILITY_KEY = :visibility
24
- ANIMATION_KEY = :animation
36
+ CONTAINER_KEY = :container
25
37
 
26
38
  BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
27
- RESPONSIVE_KEYS = ([DISPLAY_KEY, :col, :float] + SPACING_KEYS + Primer::Classify::Flex::RESPONSIVE_KEYS).freeze
39
+ RESPONSIVE_KEYS = ([Primer::Classify::Grid::COL_KEY] + Primer::Classify::Flex::RESPONSIVE_KEYS).freeze
28
40
 
29
41
  BOOLEAN_MAPPINGS = {
30
42
  underline: {
@@ -78,26 +90,24 @@ module Primer
78
90
  BORDER_RADIUS_KEY = :border_radius
79
91
  TYPOGRAPHY_KEYS = [:font_size].freeze
80
92
  VALID_KEYS = (
93
+ UTILITIES.keys +
81
94
  CONCAT_KEYS +
82
95
  BOOLEAN_MAPPINGS.keys +
83
96
  BORDER_MARGIN_KEYS +
84
97
  TYPOGRAPHY_KEYS +
85
98
  TEXT_KEYS +
86
99
  Primer::Classify::Flex::KEYS +
100
+ Primer::Classify::Grid::KEYS +
87
101
  [
88
102
  BORDER_KEY,
89
103
  BORDER_COLOR_KEY,
90
104
  BORDER_RADIUS_KEY,
91
105
  COLOR_KEY,
92
106
  BG_KEY,
93
- DISPLAY_KEY,
94
- VERTICAL_ALIGN_KEY,
95
- WORD_BREAK_KEY,
96
107
  WIDTH_KEY,
97
108
  HEIGHT_KEY,
98
109
  BOX_SHADOW_KEY,
99
- VISIBILITY_KEY,
100
- ANIMATION_KEY
110
+ CONTAINER_KEY
101
111
  ]
102
112
  ).freeze
103
113
 
@@ -123,10 +133,10 @@ module Primer
123
133
  def validated_class_names(classes)
124
134
  return if classes.blank?
125
135
 
126
- if ENV["RAILS_ENV"] == "development" && !ENV["PRIMER_WARNINGS_DISABLED"]
136
+ if force_system_arguments? && !ENV["PRIMER_WARNINGS_DISABLED"]
127
137
  invalid_class_names =
128
138
  classes.split(" ").each_with_object([]) do |class_name, memo|
129
- memo << class_name if INVALID_CLASS_NAME_PREFIXES.any? { |prefix| class_name.start_with?(prefix) }
139
+ memo << class_name if INVALID_CLASS_NAME_PREFIXES.any? { |prefix| class_name.start_with?(prefix) } || Primer::Classify::Utilities.supported_selector?(class_name)
130
140
  end
131
141
 
132
142
  raise ArgumentError, "Use System Arguments (https://primer.style/view-components/system-arguments) instead of Primer CSS class #{'name'.pluralize(invalid_class_names.length)} #{invalid_class_names.to_sentence}. This warning will not be raised in production. Set PRIMER_WARNINGS_DISABLED=1 to disable this warning." if invalid_class_names.any?
@@ -152,7 +162,7 @@ module Primer
152
162
  next unless VALID_KEYS.include?(key)
153
163
 
154
164
  if value.is_a?(Array)
155
- raise ArgumentError, "#{key} does not support responsive values" unless RESPONSIVE_KEYS.include?(key)
165
+ raise ArgumentError, "#{key} does not support responsive values" unless RESPONSIVE_KEYS.include?(key) || Primer::Classify::Utilities.supported_key?(key)
156
166
 
157
167
  value.each_with_index do |val, index|
158
168
  Primer::Classify::Cache.read(memo, key, val, BREAKPOINTS[index]) || extract_value(memo, key, val, BREAKPOINTS[index])
@@ -170,8 +180,8 @@ module Primer
170
180
  def extract_value(memo, key, val, breakpoint)
171
181
  return if val.nil? || val == ""
172
182
 
173
- if SPACING_KEYS.include?(key)
174
- memo[:classes] << Primer::Classify::Spacing.spacing(key, val, breakpoint)
183
+ if Primer::Classify::Utilities.supported_key?(key)
184
+ memo[:classes] << Primer::Classify::Utilities.classname(key, val, breakpoint)
175
185
  elsif BOOLEAN_MAPPINGS.key?(key)
176
186
  BOOLEAN_MAPPINGS[key][:mappings].each do |m|
177
187
  memo[:classes] << m[:css_class] if m[:value] == val && m[:css_class].present?
@@ -184,12 +194,6 @@ module Primer
184
194
  end
185
195
  elsif key == COLOR_KEY
186
196
  memo[:classes] << Primer::Classify::FunctionalTextColors.color(val)
187
- elsif key == DISPLAY_KEY
188
- memo[:classes] << "d#{breakpoint}-#{val.to_s.dasherize}"
189
- elsif key == VERTICAL_ALIGN_KEY
190
- memo[:classes] << "v-align-#{val.to_s.dasherize}"
191
- elsif key == WORD_BREAK_KEY
192
- memo[:classes] << "wb-#{val.to_s.dasherize}"
193
197
  elsif key == BORDER_KEY
194
198
  border_value = if val == true
195
199
  "border"
@@ -206,6 +210,8 @@ module Primer
206
210
  memo[:classes] << "rounded-#{val}"
207
211
  elsif Primer::Classify::Flex::KEYS.include?(key)
208
212
  memo[:classes] << Primer::Classify::Flex.classes(key, val, breakpoint)
213
+ elsif Primer::Classify::Grid::KEYS.include?(key)
214
+ memo[:classes] << Primer::Classify::Grid.classes(key, val, breakpoint)
209
215
  elsif key == WIDTH_KEY || key == HEIGHT_KEY
210
216
  if val == :fit
211
217
  memo[:classes] << "#{key}-#{val}"
@@ -215,7 +221,11 @@ module Primer
215
221
  elsif TEXT_KEYS.include?(key)
216
222
  memo[:classes] << "text-#{val.to_s.dasherize}"
217
223
  elsif TYPOGRAPHY_KEYS.include?(key)
218
- memo[:classes] << "f#{val.to_s.dasherize}"
224
+ memo[:classes] << if val == :small || val == :normal
225
+ "text-#{val.to_s.dasherize}"
226
+ else
227
+ "f#{val.to_s.dasherize}"
228
+ end
219
229
  elsif key == BOX_SHADOW_KEY
220
230
  memo[:classes] << if val == true
221
231
  "color-shadow-small"
@@ -224,18 +234,14 @@ module Primer
224
234
  else
225
235
  "color-shadow-#{val.to_s.dasherize}"
226
236
  end
227
- elsif key == VISIBILITY_KEY
228
- memo[:classes] << "v-#{val.to_s.dasherize}"
229
- elsif key == ANIMATION_KEY
230
- memo[:classes] << if val == :grow
231
- "hover-grow"
232
- else
233
- "anim-#{val.to_s.dasherize}"
234
- end
235
237
  else
236
238
  memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-#{val.to_s.dasherize}"
237
239
  end
238
240
  end
241
+
242
+ def force_system_arguments?
243
+ Rails.application.config.primer_view_components.force_system_arguments
244
+ end
239
245
  end
240
246
 
241
247
  Cache.preload!