primer_view_components 0.0.45 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +194 -0
- data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_component.d.ts} +0 -0
- data/app/components/primer/{auto_complete_component.js → auto_complete/auto_component.js} +0 -0
- data/app/components/primer/base_component.rb +36 -7
- data/app/components/primer/beta/auto_complete.rb +159 -0
- data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
- data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
- data/app/components/primer/beta/auto_complete/item.rb +44 -0
- data/app/components/primer/beta/avatar.rb +77 -0
- data/app/components/primer/{avatar_stack_component.html.erb → beta/avatar_stack.html.erb} +0 -0
- data/app/components/primer/beta/avatar_stack.rb +92 -0
- data/app/components/primer/border_box_component.rb +3 -0
- data/app/components/primer/component.rb +9 -1
- data/app/components/primer/details_component.rb +12 -8
- data/app/components/primer/image_crop.html.erb +4 -4
- data/app/components/primer/image_crop.rb +1 -1
- data/app/components/primer/markdown.rb +9 -9
- data/app/components/primer/menu_component.rb +7 -3
- data/app/components/primer/navigation/tab_component.rb +34 -6
- data/app/components/primer/popover_component.rb +6 -3
- data/app/components/primer/primer.d.ts +1 -1
- data/app/components/primer/primer.js +1 -1
- data/app/components/primer/primer.ts +1 -1
- data/app/components/primer/tab_nav_component.rb +9 -6
- data/app/components/primer/timeline_item_component.rb +2 -2
- data/app/components/primer/tooltip.rb +1 -1
- data/app/components/primer/truncate.rb +6 -1
- data/app/components/primer/underline_nav_component.rb +13 -6
- data/{app/lib → lib}/primer/classify.rb +12 -39
- data/{app/lib → lib}/primer/classify/cache.rb +6 -20
- data/{app/lib → lib}/primer/classify/flex.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/grid.rb +0 -0
- data/{app/lib → lib}/primer/classify/utilities.rb +54 -22
- data/{app/lib → lib}/primer/classify/utilities.yml +124 -0
- data/lib/primer/view_components.rb +35 -6
- data/lib/primer/view_components/constants.rb +55 -0
- data/lib/primer/view_components/linters/argument_mappers/base.rb +39 -0
- data/lib/primer/view_components/linters/argument_mappers/button.rb +35 -44
- data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +25 -0
- data/lib/primer/view_components/linters/argument_mappers/label.rb +56 -0
- data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +1 -2
- data/lib/primer/view_components/linters/autocorrectable.rb +30 -0
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -23
- data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +21 -0
- data/lib/primer/view_components/linters/helpers.rb +56 -38
- data/lib/primer/view_components/linters/label_component_migration_counter.rb +25 -0
- data/lib/primer/view_components/statuses.rb +14 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/config/default.yml +12 -0
- data/lib/rubocop/cop/primer.rb +4 -0
- data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
- data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
- data/lib/tasks/constants.rake +12 -0
- data/lib/tasks/docs.rake +89 -34
- data/lib/tasks/utilities.rake +9 -11
- data/lib/yard/docs_helper.rb +12 -3
- data/static/arguments.yml +977 -0
- data/static/assets/view-components.svg +18 -0
- data/static/classes.yml +174 -0
- data/static/constants.json +628 -0
- data/static/statuses.json +5 -5
- metadata +44 -27
- data/app/components/primer/auto_complete.rb +0 -156
- data/app/components/primer/auto_complete/item.rb +0 -42
- data/app/components/primer/avatar_component.rb +0 -75
- data/app/components/primer/avatar_stack_component.rb +0 -84
- data/app/components/primer/details_menu_component.d.ts +0 -1
- data/app/components/primer/details_menu_component.js +0 -1
@@ -23,12 +23,15 @@ module Primer
|
|
23
23
|
:top_right => "Popover-message--top-right"
|
24
24
|
}.freeze
|
25
25
|
|
26
|
+
DEFAULT_HEADING_TAG = :h4
|
27
|
+
|
26
28
|
# The heading
|
27
29
|
#
|
30
|
+
# @param tag [Symbol] (Primer::PopoverComponent::DEFAULT_HEADING_TAG) <%= one_of(Primer::HeadingComponent::TAG_OPTIONS) %>
|
28
31
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
29
|
-
renders_one :heading, lambda {
|
32
|
+
renders_one :heading, lambda { |tag: DEFAULT_HEADING_TAG, **system_arguments|
|
33
|
+
system_arguments[:tag] = tag
|
30
34
|
system_arguments[:mb] ||= 2
|
31
|
-
system_arguments[:tag] ||= :h4
|
32
35
|
|
33
36
|
Primer::HeadingComponent.new(**system_arguments)
|
34
37
|
}
|
@@ -106,7 +109,7 @@ module Primer
|
|
106
109
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
107
110
|
def initialize(**system_arguments)
|
108
111
|
@system_arguments = system_arguments
|
109
|
-
@system_arguments[:tag]
|
112
|
+
@system_arguments[:tag] = :div
|
110
113
|
@system_arguments[:classes] = class_names(
|
111
114
|
system_arguments[:classes],
|
112
115
|
"Popover"
|
@@ -10,8 +10,10 @@ module Primer
|
|
10
10
|
DEFAULT_EXTRA_ALIGN = :left
|
11
11
|
EXTRA_ALIGN_OPTIONS = [DEFAULT_EXTRA_ALIGN, :right].freeze
|
12
12
|
|
13
|
-
# Tabs to be rendered.
|
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) %>.
|
14
15
|
#
|
16
|
+
# @param panel_id [String] Only applies if `with_panel` is `true`. Unique ID of panel.
|
15
17
|
# @param selected [Boolean] Whether the tab is selected.
|
16
18
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
17
19
|
renders_many :tabs, lambda { |selected: false, **system_arguments|
|
@@ -62,19 +64,19 @@ module Primer
|
|
62
64
|
#
|
63
65
|
# @example With panels
|
64
66
|
# <%= render(Primer::TabNavComponent.new(label: "With panels", with_panel: true)) do |c| %>
|
65
|
-
# <% c.tab(selected: true) do |t| %>
|
67
|
+
# <% c.tab(selected: true, panel_id: "panel-1", id: "tab-1") do |t| %>
|
66
68
|
# <% t.text { "Tab 1" } %>
|
67
69
|
# <% t.panel do %>
|
68
70
|
# Panel 1
|
69
71
|
# <% end %>
|
70
72
|
# <% end %>
|
71
|
-
# <% c.tab do |t| %>
|
73
|
+
# <% c.tab(id: "tab-2", panel_id: "panel-2") do |t| %>
|
72
74
|
# <% t.text { "Tab 2" } %>
|
73
75
|
# <% t.panel do %>
|
74
76
|
# Panel 2
|
75
77
|
# <% end %>
|
76
78
|
# <% end %>
|
77
|
-
# <% c.tab do |t| %>
|
79
|
+
# <% c.tab(id: "tab-3", panel_id: "panel-3") do |t| %>
|
78
80
|
# <% t.text { "Tab 3" } %>
|
79
81
|
# <% t.panel do %>
|
80
82
|
# Panel 3
|
@@ -119,7 +121,8 @@ module Primer
|
|
119
121
|
# <% end %>
|
120
122
|
#
|
121
123
|
# @param label [String] Used to set the `aria-label` on the top level `<nav>` element.
|
122
|
-
# @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
|
124
|
+
# @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels. When true, <%= link_to_component(Primer::TabContainerComponent) %>
|
125
|
+
# is rendered along with JavaScript behavior. Additionally, the `tab` slot will render as a button as opposed to an anchor.
|
123
126
|
# @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
|
124
127
|
# @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
|
125
128
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -130,7 +133,7 @@ module Primer
|
|
130
133
|
@body_arguments = body_arguments
|
131
134
|
@wrapper_arguments = wrapper_arguments
|
132
135
|
|
133
|
-
@system_arguments[:tag]
|
136
|
+
@system_arguments[:tag] = :div
|
134
137
|
@system_arguments[:classes] = class_names(
|
135
138
|
"tabnav",
|
136
139
|
system_arguments[:classes]
|
@@ -7,14 +7,14 @@ module Primer
|
|
7
7
|
|
8
8
|
# Avatar to be rendered to the left of the Badge.
|
9
9
|
#
|
10
|
-
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::
|
10
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::Beta::Avatar) %>.
|
11
11
|
renders_one :avatar, lambda { |src:, size: 40, square: true, **system_arguments|
|
12
12
|
system_arguments[:classes] = class_names(
|
13
13
|
"TimelineItem-avatar",
|
14
14
|
system_arguments[:classes]
|
15
15
|
)
|
16
16
|
|
17
|
-
Primer::
|
17
|
+
Primer::Beta::Avatar.new(src: src, size: size, square: square, **system_arguments)
|
18
18
|
}
|
19
19
|
|
20
20
|
# Badge that will be connected to other TimelineItems.
|
@@ -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(
|
@@ -6,7 +6,7 @@ module Primer
|
|
6
6
|
status :beta
|
7
7
|
|
8
8
|
DEFAULT_TAG = :div
|
9
|
-
TAG_OPTIONS = [DEFAULT_TAG, :span, :p].freeze
|
9
|
+
TAG_OPTIONS = [DEFAULT_TAG, :span, :p, :strong].freeze
|
10
10
|
|
11
11
|
# @example Default
|
12
12
|
# <div class="col-2">
|
@@ -22,6 +22,11 @@ module Primer
|
|
22
22
|
# @example Custom size
|
23
23
|
# <%= render(Primer::Truncate.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
|
24
24
|
#
|
25
|
+
# @example With HTML content
|
26
|
+
# <%= render(Primer::Truncate.new(tag: :span, inline: true, expandable: true, max_width: 100)) do %>
|
27
|
+
# <span>branch-name-that-is-really-long</span>
|
28
|
+
# <% end %>
|
29
|
+
#
|
25
30
|
# @param tag [Symbol] <%= one_of(Primer::Truncate::TAG_OPTIONS) %>
|
26
31
|
# @param inline [Boolean] Whether the element is inline (or inline-block).
|
27
32
|
# @param expandable [Boolean] Whether the entire string should be revealed on hover. Can only be used in conjunction with `inline`.
|
@@ -13,8 +13,13 @@ module Primer
|
|
13
13
|
BODY_TAG_DEFAULT = :div
|
14
14
|
BODY_TAG_OPTIONS = [BODY_TAG_DEFAULT, :ul].freeze
|
15
15
|
|
16
|
-
|
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
|
#
|
22
|
+
# @param panel_id [String] Only applies if `with_panel` is `true`. Unique id of panel.
|
18
23
|
# @param selected [Boolean] Whether the tab is selected.
|
19
24
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
20
25
|
renders_many :tabs, lambda { |selected: false, **system_arguments|
|
@@ -34,9 +39,10 @@ module Primer
|
|
34
39
|
|
35
40
|
# Use actions for a call to action.
|
36
41
|
#
|
42
|
+
# @param tag [Symbol] (Primer::UnderlineNavComponent::ACTIONS_TAG_DEFAULT) <%= one_of(Primer::UnderlineNavComponent::ACTIONS_TAG_OPTIONS) %>
|
37
43
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
38
|
-
renders_one :actions, lambda {
|
39
|
-
system_arguments[:tag]
|
44
|
+
renders_one :actions, lambda { |tag: ACTIONS_TAG_DEFAULT, **system_arguments|
|
45
|
+
system_arguments[:tag] = fetch_or_fallback(ACTIONS_TAG_OPTIONS, tag, ACTIONS_TAG_DEFAULT)
|
40
46
|
system_arguments[:classes] = class_names("UnderlineNav-actions", system_arguments[:classes])
|
41
47
|
|
42
48
|
Primer::BaseComponent.new(**system_arguments)
|
@@ -99,13 +105,13 @@ module Primer
|
|
99
105
|
#
|
100
106
|
# @example With panels
|
101
107
|
# <%= render(Primer::UnderlineNavComponent.new(label: "With panels", with_panel: true)) do |component| %>
|
102
|
-
# <% component.tab(selected: true) do |t| %>
|
108
|
+
# <% component.tab(selected: true, id: "tab-1", panel_id: "panel-1") do |t| %>
|
103
109
|
# <% t.text { "Item 1" } %>
|
104
110
|
# <% t.panel do %>
|
105
111
|
# Panel 1
|
106
112
|
# <% end %>
|
107
113
|
# <% end %>
|
108
|
-
# <% component.tab do |t| %>
|
114
|
+
# <% component.tab(id: "tab-2", panel_id: "panel-2") do |t| %>
|
109
115
|
# <% t.text { "Item 2" } %>
|
110
116
|
# <% t.panel do %>
|
111
117
|
# Panel 2
|
@@ -131,7 +137,8 @@ module Primer
|
|
131
137
|
# <% end %>
|
132
138
|
#
|
133
139
|
# @param label [String] The `aria-label` on top level `<nav>` element.
|
134
|
-
# @param with_panel [Boolean] Whether the
|
140
|
+
# @param with_panel [Boolean] Whether the `UnderlineNav` should navigate through pages or panels. When true, <%= link_to_component(Primer::TabContainerComponent) %> is
|
141
|
+
# rendered along with JavaScript behavior.
|
135
142
|
# @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
|
136
143
|
# @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
|
137
144
|
# @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper. Only applies if `with_panel` is `true`.
|
@@ -1,40 +1,32 @@
|
|
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
|
-
# Load the utilities.yml file.
|
7
|
-
# Disabling because we want to load symbols, strings, and integers from the .yml file
|
8
|
-
# rubocop:disable Security/YAMLLoad
|
9
|
-
UTILITIES = YAML.load(
|
10
|
-
File.read(
|
11
|
-
File.join(File.dirname(__FILE__), "./classify/utilities.yml")
|
12
|
-
)
|
13
|
-
).freeze
|
14
|
-
# rubocop:enable Security/YAMLLoad
|
15
|
-
|
16
|
-
DISPLAY_KEY = :display
|
17
|
-
|
18
14
|
# Keys where we can simply translate { key: value } into ".key-value"
|
19
|
-
CONCAT_KEYS = %i[
|
15
|
+
CONCAT_KEYS = %i[text box_shadow].freeze
|
20
16
|
|
21
17
|
INVALID_CLASS_NAME_PREFIXES =
|
22
|
-
(["bg-", "color-", "text-", "
|
18
|
+
(["bg-", "color-", "text-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
|
23
19
|
|
24
20
|
COLOR_KEY = :color
|
25
21
|
BG_KEY = :bg
|
26
|
-
VERTICAL_ALIGN_KEY = :vertical_align
|
27
|
-
WORD_BREAK_KEY = :word_break
|
28
22
|
TEXT_KEYS = %i[font_family font_style font_weight text_align text_transform].freeze
|
29
23
|
WIDTH_KEY = :width
|
30
24
|
HEIGHT_KEY = :height
|
31
25
|
BOX_SHADOW_KEY = :box_shadow
|
32
|
-
VISIBILITY_KEY = :visibility
|
33
|
-
ANIMATION_KEY = :animation
|
34
26
|
CONTAINER_KEY = :container
|
35
27
|
|
36
28
|
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
37
|
-
RESPONSIVE_KEYS = ([
|
29
|
+
RESPONSIVE_KEYS = ([Primer::Classify::Grid::COL_KEY] + Primer::Classify::Flex::RESPONSIVE_KEYS).freeze
|
38
30
|
|
39
31
|
BOOLEAN_MAPPINGS = {
|
40
32
|
underline: {
|
@@ -88,7 +80,7 @@ module Primer
|
|
88
80
|
BORDER_RADIUS_KEY = :border_radius
|
89
81
|
TYPOGRAPHY_KEYS = [:font_size].freeze
|
90
82
|
VALID_KEYS = (
|
91
|
-
UTILITIES.keys +
|
83
|
+
Primer::Classify::Utilities::UTILITIES.keys +
|
92
84
|
CONCAT_KEYS +
|
93
85
|
BOOLEAN_MAPPINGS.keys +
|
94
86
|
BORDER_MARGIN_KEYS +
|
@@ -102,14 +94,9 @@ module Primer
|
|
102
94
|
BORDER_RADIUS_KEY,
|
103
95
|
COLOR_KEY,
|
104
96
|
BG_KEY,
|
105
|
-
DISPLAY_KEY,
|
106
|
-
VERTICAL_ALIGN_KEY,
|
107
|
-
WORD_BREAK_KEY,
|
108
97
|
WIDTH_KEY,
|
109
98
|
HEIGHT_KEY,
|
110
99
|
BOX_SHADOW_KEY,
|
111
|
-
VISIBILITY_KEY,
|
112
|
-
ANIMATION_KEY,
|
113
100
|
CONTAINER_KEY
|
114
101
|
]
|
115
102
|
).freeze
|
@@ -197,12 +184,6 @@ module Primer
|
|
197
184
|
end
|
198
185
|
elsif key == COLOR_KEY
|
199
186
|
memo[:classes] << Primer::Classify::FunctionalTextColors.color(val)
|
200
|
-
elsif key == DISPLAY_KEY
|
201
|
-
memo[:classes] << "d#{breakpoint}-#{val.to_s.dasherize}"
|
202
|
-
elsif key == VERTICAL_ALIGN_KEY
|
203
|
-
memo[:classes] << "v-align-#{val.to_s.dasherize}"
|
204
|
-
elsif key == WORD_BREAK_KEY
|
205
|
-
memo[:classes] << "wb-#{val.to_s.dasherize}"
|
206
187
|
elsif key == BORDER_KEY
|
207
188
|
border_value = if val == true
|
208
189
|
"border"
|
@@ -243,14 +224,6 @@ module Primer
|
|
243
224
|
else
|
244
225
|
"color-shadow-#{val.to_s.dasherize}"
|
245
226
|
end
|
246
|
-
elsif key == VISIBILITY_KEY
|
247
|
-
memo[:classes] << "v-#{val.to_s.dasherize}"
|
248
|
-
elsif key == ANIMATION_KEY
|
249
|
-
memo[:classes] << if val == :grow
|
250
|
-
"hover-grow"
|
251
|
-
else
|
252
|
-
"anim-#{val.to_s.dasherize}"
|
253
|
-
end
|
254
227
|
else
|
255
228
|
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-#{val.to_s.dasherize}"
|
256
229
|
end
|
@@ -1,5 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "flex"
|
4
|
+
require_relative "functional_background_colors"
|
5
|
+
require_relative "functional_border_colors"
|
6
|
+
require_relative "functional_text_colors"
|
7
|
+
require_relative "grid"
|
8
|
+
|
3
9
|
module Primer
|
4
10
|
class Classify
|
5
11
|
# :nodoc:
|
@@ -49,11 +55,6 @@ module Primer
|
|
49
55
|
values: Primer::Classify::Grid::COL_VALUES
|
50
56
|
)
|
51
57
|
|
52
|
-
preload(
|
53
|
-
keys: Primer::Classify::DISPLAY_KEY,
|
54
|
-
values: [:flex, :block, :inline_block, :inline_flex, :none, :table, :table_cell]
|
55
|
-
)
|
56
|
-
|
57
58
|
preload(
|
58
59
|
keys: [Primer::Classify::COLOR_KEY],
|
59
60
|
values: Primer::Classify::FunctionalTextColors::OPTIONS
|
@@ -64,16 +65,6 @@ module Primer
|
|
64
65
|
values: Primer::Classify::FunctionalBackgroundColors::OPTIONS
|
65
66
|
)
|
66
67
|
|
67
|
-
preload(
|
68
|
-
keys: Primer::Classify::VERTICAL_ALIGN_KEY,
|
69
|
-
values: [:baseline, :top, :middle, :bottom, :text_top, :text_bottom]
|
70
|
-
)
|
71
|
-
|
72
|
-
preload(
|
73
|
-
keys: Primer::Classify::WORD_BREAK_KEY,
|
74
|
-
values: [:break_all]
|
75
|
-
)
|
76
|
-
|
77
68
|
preload(
|
78
69
|
keys: :text_align,
|
79
70
|
values: [:left, :center, :right]
|
@@ -113,11 +104,6 @@ module Primer
|
|
113
104
|
keys: Primer::Classify::BOX_SHADOW_KEY,
|
114
105
|
values: [true, :small, :medium, :large, :extra_large, :none]
|
115
106
|
)
|
116
|
-
|
117
|
-
preload(
|
118
|
-
keys: Primer::Classify::VISIBILITY_KEY,
|
119
|
-
values: [:hidden, :visible]
|
120
|
-
)
|
121
107
|
end
|
122
108
|
|
123
109
|
def preload(keys:, values:)
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,17 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "yaml"
|
4
|
+
|
3
5
|
# :nodoc:
|
4
6
|
module Primer
|
5
7
|
class Classify
|
6
8
|
# Handler for PrimerCSS utility classes loaded from utilities.rake
|
7
9
|
class Utilities
|
10
|
+
# Load the utilities.yml file.
|
11
|
+
# Disabling because we want to load symbols, strings, and integers from the .yml file
|
12
|
+
# rubocop:disable Security/YAMLLoad
|
13
|
+
UTILITIES = YAML.load(
|
14
|
+
File.read(
|
15
|
+
File.join(File.dirname(__FILE__), "./utilities.yml")
|
16
|
+
)
|
17
|
+
).freeze
|
18
|
+
# rubocop:enable Security/YAMLLoad
|
19
|
+
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
20
|
+
|
21
|
+
# Replacements for some classnames that end up being a different argument key
|
22
|
+
REPLACEMENT_KEYS = {
|
23
|
+
"^anim" => "animation",
|
24
|
+
"^v-align" => "vertical_align",
|
25
|
+
"^d" => "display",
|
26
|
+
"^wb" => "word_break",
|
27
|
+
"^v" => "visibility"
|
28
|
+
}.freeze
|
29
|
+
|
8
30
|
class << self
|
9
31
|
def classname(key, val, breakpoint = "")
|
10
32
|
if (valid = validate(key, val, breakpoint))
|
11
33
|
valid
|
12
34
|
else
|
13
35
|
# Get selector
|
14
|
-
|
36
|
+
UTILITIES[key][val][BREAKPOINTS.index(breakpoint)]
|
15
37
|
end
|
16
38
|
end
|
17
39
|
|
@@ -19,14 +41,14 @@ module Primer
|
|
19
41
|
#
|
20
42
|
# returns Boolean
|
21
43
|
def supported_key?(key)
|
22
|
-
|
44
|
+
UTILITIES[key].present?
|
23
45
|
end
|
24
46
|
|
25
47
|
# Does the Utilitiy class support the given key and value
|
26
48
|
#
|
27
49
|
# returns Boolean
|
28
50
|
def supported_value?(key, val)
|
29
|
-
supported_key?(key) &&
|
51
|
+
supported_key?(key) && UTILITIES[key][val].present?
|
30
52
|
end
|
31
53
|
|
32
54
|
# Does the given selector exist in the utilities file
|
@@ -34,7 +56,7 @@ module Primer
|
|
34
56
|
# returns Boolean
|
35
57
|
def supported_selector?(selector)
|
36
58
|
# This method is too slow to run in production
|
37
|
-
return false if
|
59
|
+
return false if ENV["RAILS_ENV"] == "production"
|
38
60
|
|
39
61
|
find_selector(selector).present?
|
40
62
|
end
|
@@ -43,7 +65,7 @@ module Primer
|
|
43
65
|
#
|
44
66
|
# returns Boolean
|
45
67
|
def responsive?(key, val)
|
46
|
-
supported_value?(key, val) &&
|
68
|
+
supported_value?(key, val) && UTILITIES[key][val].count > 1
|
47
69
|
end
|
48
70
|
|
49
71
|
# Get the options for the given key
|
@@ -52,13 +74,13 @@ module Primer
|
|
52
74
|
def mappings(key)
|
53
75
|
return unless supported_key?(key)
|
54
76
|
|
55
|
-
|
77
|
+
UTILITIES[key].keys
|
56
78
|
end
|
57
79
|
|
58
80
|
# Extract hash from classes ie. "mr-1 mb-2 foo" => { mr: 1, mb: 2, classes: "foo" }
|
59
81
|
def classes_to_hash(classes)
|
60
82
|
# This method is too slow to run in production
|
61
|
-
return { classes: classes } if
|
83
|
+
return { classes: classes } if ENV["RAILS_ENV"] == "production"
|
62
84
|
|
63
85
|
obj = {}
|
64
86
|
classes = classes.split(" ")
|
@@ -93,38 +115,48 @@ module Primer
|
|
93
115
|
private
|
94
116
|
|
95
117
|
def find_selector(selector)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
118
|
+
key = infer_selector_key(selector)
|
119
|
+
value_hash = UTILITIES[key]
|
120
|
+
|
121
|
+
return nil if value_hash.blank?
|
122
|
+
|
123
|
+
# Each value hash will also contain an array of classnames for breakpoints
|
124
|
+
# Key argument `0`, classes `[ "mr-0", "mr-sm-0", "mr-md-0", "mr-lg-0", "mr-xl-0" ]`
|
125
|
+
value_hash.each do |key_argument, classnames|
|
126
|
+
# Skip each value hash until we get one with the selector
|
127
|
+
next unless classnames.include?(selector)
|
128
|
+
|
129
|
+
# Return [:mr, 0, 1]
|
130
|
+
# has index of classname, so we can match it up with responsvie array `mr: [nil, 0]`
|
131
|
+
return [key, key_argument, classnames.index(selector)]
|
108
132
|
end
|
109
133
|
|
110
134
|
nil
|
111
135
|
end
|
112
136
|
|
137
|
+
def infer_selector_key(selector)
|
138
|
+
REPLACEMENT_KEYS.each do |k, v|
|
139
|
+
return v.to_sym if selector.match?(Regexp.new(k))
|
140
|
+
end
|
141
|
+
|
142
|
+
selector.split("-").first.to_sym
|
143
|
+
end
|
144
|
+
|
113
145
|
def validate(key, val, breakpoint)
|
114
146
|
unless supported_key?(key)
|
115
|
-
raise ArgumentError, "#{key} is not a valid Primer utility key" unless
|
147
|
+
raise ArgumentError, "#{key} is not a valid Primer utility key" unless ENV["RAILS_ENV"] == "production"
|
116
148
|
|
117
149
|
return ""
|
118
150
|
end
|
119
151
|
|
120
152
|
unless breakpoint.empty? || responsive?(key, val)
|
121
|
-
raise ArgumentError, "#{key} does not support responsive values" unless
|
153
|
+
raise ArgumentError, "#{key} does not support responsive values" unless ENV["RAILS_ENV"] == "production"
|
122
154
|
|
123
155
|
return ""
|
124
156
|
end
|
125
157
|
|
126
158
|
unless supported_value?(key, val)
|
127
|
-
raise ArgumentError, "#{val} is not a valid value for :#{key}. Use one of #{mappings(key)}" unless
|
159
|
+
raise ArgumentError, "#{val} is not a valid value for :#{key}. Use one of #{mappings(key)}" unless ENV["RAILS_ENV"] == "production"
|
128
160
|
|
129
161
|
return ""
|
130
162
|
end
|