primer_view_components 0.0.41 → 0.0.46

Sign up to get free protection for your applications and to get access to all the features.
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!