primer_view_components 0.0.32 → 0.0.37
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 +82 -0
- data/README.md +1 -1
- data/app/components/primer/{auto_complete_component.rb → auto_complete.rb} +13 -11
- data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_complete.d.ts} +0 -0
- data/app/components/primer/{auto_complete_component.html.erb → auto_complete/auto_complete.html.erb} +0 -0
- data/app/components/primer/{auto_complete_component.js → auto_complete/auto_complete.js} +0 -0
- data/app/components/primer/{auto_complete_component.ts → auto_complete/auto_complete.ts} +0 -0
- data/app/components/primer/auto_complete/auto_component.d.ts +1 -0
- data/app/components/primer/auto_complete/auto_component.js +1 -0
- data/app/components/primer/auto_complete/item.rb +42 -0
- data/app/components/primer/avatar_stack_component.rb +2 -0
- data/app/components/primer/base_component.rb +115 -85
- data/app/components/primer/button_component.rb +37 -16
- data/app/components/primer/button_group_component.rb +3 -3
- data/app/components/primer/button_marketing_component.rb +12 -12
- data/app/components/primer/close_button.rb +30 -0
- data/app/components/primer/component.rb +1 -0
- data/app/components/primer/dropdown_component.rb +1 -1
- data/app/components/primer/dropdown_menu_component.rb +1 -1
- data/app/components/primer/flash_component.rb +10 -10
- data/app/components/primer/foo_bar.d.ts +1 -0
- data/app/components/primer/foo_bar.js +1 -0
- data/app/components/primer/hidden_text_expander.rb +43 -0
- data/app/components/primer/link_component.rb +9 -9
- data/app/components/primer/navigation/tab_component.html.erb +9 -7
- data/app/components/primer/navigation/tab_component.rb +27 -3
- data/app/components/primer/octicon_component.rb +0 -4
- 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/state_component.rb +13 -13
- data/app/components/primer/subhead_component.rb +1 -1
- data/app/components/primer/tab_nav_component.html.erb +2 -2
- data/app/components/primer/tab_nav_component.rb +22 -8
- data/app/components/primer/{truncate_component.rb → truncate.rb} +8 -6
- data/app/components/primer/underline_nav_component.rb +46 -14
- data/app/lib/primer/classify.rb +3 -12
- data/app/lib/primer/classify/cache.rb +14 -4
- data/app/lib/primer/classify/spacing.rb +63 -0
- data/app/lib/primer/tabbed_component_helper.rb +4 -2
- data/lib/primer/view_components/version.rb +1 -1
- data/static/statuses.json +1 -1
- metadata +107 -30
- data/app/assets/javascripts/primer_view_components.js.map.orig +0 -5
- data/app/assets/javascripts/primer_view_components.js.orig +0 -6
- data/app/components/primer/auto_complete_item_component.rb +0 -38
@@ -5,21 +5,21 @@ module Primer
|
|
5
5
|
class StateComponent < Primer::Component
|
6
6
|
status :beta
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
SCHEME_DEFAULT = :default
|
9
|
+
NEW_SCHEME_MAPPINGS = {
|
10
10
|
open: "State--open",
|
11
11
|
closed: "State--closed",
|
12
12
|
merged: "State--merged"
|
13
13
|
}.freeze
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
DEPRECATED_SCHEME_MAPPINGS = {
|
16
|
+
SCHEME_DEFAULT => "",
|
17
17
|
:green => "State--open",
|
18
18
|
:red => "State--closed",
|
19
19
|
:purple => "State--merged"
|
20
20
|
}.freeze
|
21
|
-
|
22
|
-
|
21
|
+
SCHEME_MAPPINGS = NEW_SCHEME_MAPPINGS.merge(DEPRECATED_SCHEME_MAPPINGS)
|
22
|
+
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
|
23
23
|
|
24
24
|
SIZE_DEFAULT = :default
|
25
25
|
SIZE_MAPPINGS = {
|
@@ -34,24 +34,24 @@ module Primer
|
|
34
34
|
# @example Default
|
35
35
|
# <%= render(Primer::StateComponent.new(title: "title")) { "State" } %>
|
36
36
|
#
|
37
|
-
# @example
|
37
|
+
# @example Schemes
|
38
38
|
# <%= render(Primer::StateComponent.new(title: "title")) { "Default" } %>
|
39
|
-
# <%= render(Primer::StateComponent.new(title: "title",
|
40
|
-
# <%= render(Primer::StateComponent.new(title: "title",
|
41
|
-
# <%= render(Primer::StateComponent.new(title: "title",
|
39
|
+
# <%= render(Primer::StateComponent.new(title: "title", scheme: :open)) { "Open" } %>
|
40
|
+
# <%= render(Primer::StateComponent.new(title: "title", scheme: :closed)) { "Closed" } %>
|
41
|
+
# <%= render(Primer::StateComponent.new(title: "title", scheme: :merged)) { "Merged" } %>
|
42
42
|
#
|
43
43
|
# @example Sizes
|
44
44
|
# <%= render(Primer::StateComponent.new(title: "title")) { "Default" } %>
|
45
45
|
# <%= render(Primer::StateComponent.new(title: "title", size: :small)) { "Small" } %>
|
46
46
|
#
|
47
47
|
# @param title [String] `title` HTML attribute.
|
48
|
-
# @param
|
48
|
+
# @param scheme [Symbol] Background color. <%= one_of(Primer::StateComponent::SCHEME_OPTIONS) %>
|
49
49
|
# @param tag [Symbol] HTML tag for element. <%= one_of(Primer::StateComponent::TAG_OPTIONS) %>
|
50
50
|
# @param size [Symbol] <%= one_of(Primer::StateComponent::SIZE_OPTIONS) %>
|
51
51
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
52
52
|
def initialize(
|
53
53
|
title:,
|
54
|
-
|
54
|
+
scheme: SCHEME_DEFAULT,
|
55
55
|
tag: TAG_DEFAULT,
|
56
56
|
size: SIZE_DEFAULT,
|
57
57
|
**system_arguments
|
@@ -62,7 +62,7 @@ module Primer
|
|
62
62
|
@system_arguments[:classes] = class_names(
|
63
63
|
@system_arguments[:classes],
|
64
64
|
"State",
|
65
|
-
|
65
|
+
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, SCHEME_DEFAULT)],
|
66
66
|
SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
|
67
67
|
)
|
68
68
|
end
|
@@ -71,7 +71,7 @@ module Primer
|
|
71
71
|
# <% component.actions do %>
|
72
72
|
# <%= render(
|
73
73
|
# Primer::ButtonComponent.new(
|
74
|
-
# tag: :a, href: "http://www.google.com",
|
74
|
+
# tag: :a, href: "http://www.google.com", scheme: :danger
|
75
75
|
# )
|
76
76
|
# ) { "Action" } %>
|
77
77
|
# <% end %>
|
@@ -1,10 +1,10 @@
|
|
1
1
|
<%= wrapper do %>
|
2
2
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
3
|
-
|
3
|
+
<%= render Primer::BaseComponent.new(**@body_arguments) do %>
|
4
4
|
<% tabs.each do |tab| %>
|
5
5
|
<%= tab %>
|
6
6
|
<% end %>
|
7
|
-
|
7
|
+
<% end %>
|
8
8
|
<% end %>
|
9
9
|
|
10
10
|
<% if @with_panel %>
|
@@ -14,18 +14,23 @@ module Primer
|
|
14
14
|
"tabnav-tab",
|
15
15
|
system_arguments[:classes]
|
16
16
|
)
|
17
|
-
|
17
|
+
|
18
|
+
Primer::Navigation::TabComponent.new(
|
19
|
+
selected: selected,
|
20
|
+
with_panel: @with_panel,
|
21
|
+
**system_arguments
|
22
|
+
)
|
18
23
|
}
|
19
24
|
|
20
25
|
# @example Default
|
21
|
-
# <%= render(Primer::TabNavComponent.new) do |c| %>
|
26
|
+
# <%= render(Primer::TabNavComponent.new(label: "Default")) do |c| %>
|
22
27
|
# <% c.tab(selected: true, href: "#") { "Tab 1" }%>
|
23
28
|
# <% c.tab(href: "#") { "Tab 2" } %>
|
24
29
|
# <% c.tab(href: "#") { "Tab 3" } %>
|
25
30
|
# <% end %>
|
26
31
|
#
|
27
32
|
# @example With icons and counters
|
28
|
-
# <%= render(Primer::TabNavComponent.new) do |component| %>
|
33
|
+
# <%= render(Primer::TabNavComponent.new(label: "With icons and counters")) do |component| %>
|
29
34
|
# <% component.tab(href: "#", selected: true) do |t| %>
|
30
35
|
# <% t.icon(icon: :star) %>
|
31
36
|
# <% t.text { "Item 1" } %>
|
@@ -42,7 +47,7 @@ module Primer
|
|
42
47
|
# <% end %>
|
43
48
|
#
|
44
49
|
# @example With panels
|
45
|
-
# <%= render(Primer::TabNavComponent.new(with_panel: true)) do |c| %>
|
50
|
+
# <%= render(Primer::TabNavComponent.new(label: "With panels", with_panel: true)) do |c| %>
|
46
51
|
# <% c.tab(selected: true) do |t| %>
|
47
52
|
# <% t.text { "Tab 1" } %>
|
48
53
|
# <% t.panel do %>
|
@@ -63,19 +68,28 @@ module Primer
|
|
63
68
|
# <% end %>
|
64
69
|
# <% end %>
|
65
70
|
#
|
66
|
-
# @param
|
71
|
+
# @param label [String] Used to set the `aria-label` on the top level `<nav>` element.
|
67
72
|
# @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
|
68
73
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
69
|
-
def initialize(
|
70
|
-
@aria_label = aria_label
|
74
|
+
def initialize(label:, with_panel: false, **system_arguments)
|
71
75
|
@with_panel = with_panel
|
72
76
|
@system_arguments = system_arguments
|
73
|
-
@system_arguments[:tag] ||= :div
|
74
77
|
|
78
|
+
@system_arguments[:tag] ||= :div
|
75
79
|
@system_arguments[:classes] = class_names(
|
76
80
|
"tabnav",
|
77
81
|
system_arguments[:classes]
|
78
82
|
)
|
83
|
+
|
84
|
+
@body_arguments = {
|
85
|
+
tag: navigation_tag(with_panel),
|
86
|
+
classes: "tabnav-tabs",
|
87
|
+
aria: {
|
88
|
+
label: label
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
@body_arguments[:role] = :tablist if @with_panel
|
79
93
|
end
|
80
94
|
end
|
81
95
|
end
|
@@ -1,21 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
# Use
|
5
|
-
class
|
4
|
+
# Use Truncate to shorten overflowing text with an ellipsis.
|
5
|
+
class Truncate < Primer::Component
|
6
|
+
status :beta
|
7
|
+
|
6
8
|
# @example Default
|
7
9
|
# <div class="col-2">
|
8
|
-
# <%= render(Primer::
|
10
|
+
# <%= render(Primer::Truncate.new(tag: :p)) { "branch-name-that-is-really-long" } %>
|
9
11
|
# </div>
|
10
12
|
#
|
11
13
|
# @example Inline
|
12
|
-
# <%= render(Primer::
|
14
|
+
# <%= render(Primer::Truncate.new(tag: :span, inline: true)) { "branch-name-that-is-really-long" } %>
|
13
15
|
#
|
14
16
|
# @example Expandable
|
15
|
-
# <%= render(Primer::
|
17
|
+
# <%= render(Primer::Truncate.new(tag: :span, inline: true, expandable: true)) { "branch-name-that-is-really-long" } %>
|
16
18
|
#
|
17
19
|
# @example Custom size
|
18
|
-
# <%= render(Primer::
|
20
|
+
# <%= render(Primer::Truncate.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
|
19
21
|
#
|
20
22
|
# @param inline [Boolean] Whether the element is inline (or inline-block).
|
21
23
|
# @param expandable [Boolean] Whether the entire string should be revealed on hover. Can only be used in conjunction with `inline`.
|
@@ -10,6 +10,9 @@ module Primer
|
|
10
10
|
ALIGN_DEFAULT = :left
|
11
11
|
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
|
12
12
|
|
13
|
+
BODY_TAG_DEFAULT = :div
|
14
|
+
BODY_TAG_OPTIONS = [BODY_TAG_DEFAULT, :ul].freeze
|
15
|
+
|
13
16
|
# Use the tabs to list navigation items. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
|
14
17
|
#
|
15
18
|
# @param selected [Boolean] Whether the tab is selected.
|
@@ -19,7 +22,9 @@ module Primer
|
|
19
22
|
"UnderlineNav-item",
|
20
23
|
system_arguments[:classes]
|
21
24
|
)
|
25
|
+
|
22
26
|
Primer::Navigation::TabComponent.new(
|
27
|
+
list: list?,
|
23
28
|
selected: selected,
|
24
29
|
with_panel: @with_panel,
|
25
30
|
icon_classes: "UnderlineNav-octicon",
|
@@ -38,7 +43,7 @@ module Primer
|
|
38
43
|
}
|
39
44
|
|
40
45
|
# @example Default
|
41
|
-
# <%= render(Primer::UnderlineNavComponent.new) do |component| %>
|
46
|
+
# <%= render(Primer::UnderlineNavComponent.new(label: "Default")) do |component| %>
|
42
47
|
# <% component.tab(href: "#", selected: true) { "Item 1" } %>
|
43
48
|
# <% component.tab(href: "#") { "Item 2" } %>
|
44
49
|
# <% component.actions do %>
|
@@ -47,7 +52,7 @@ module Primer
|
|
47
52
|
# <% end %>
|
48
53
|
#
|
49
54
|
# @example With icons and counters
|
50
|
-
# <%= render(Primer::UnderlineNavComponent.new) do |component| %>
|
55
|
+
# <%= render(Primer::UnderlineNavComponent.new(label: "With icons and counters")) do |component| %>
|
51
56
|
# <% component.tab(href: "#", selected: true) do |t| %>
|
52
57
|
# <% t.icon(icon: :star) %>
|
53
58
|
# <% t.text { "Item 1" } %>
|
@@ -67,7 +72,20 @@ module Primer
|
|
67
72
|
# <% end %>
|
68
73
|
#
|
69
74
|
# @example Align right
|
70
|
-
# <%= render(Primer::UnderlineNavComponent.new(align: :right)) do |component| %>
|
75
|
+
# <%= render(Primer::UnderlineNavComponent.new(label: "Align right", align: :right)) do |component| %>
|
76
|
+
# <% component.tab(href: "#", selected: true) do |t| %>
|
77
|
+
# <% t.text { "Item 1" } %>
|
78
|
+
# <% end %>
|
79
|
+
# <% component.tab(href: "#") do |t| %>
|
80
|
+
# <% t.text { "Item 2" } %>
|
81
|
+
# <% end %>
|
82
|
+
# <% component.actions do %>
|
83
|
+
# <%= render(Primer::ButtonComponent.new) { "Button!" } %>
|
84
|
+
# <% end %>
|
85
|
+
# <% end %>
|
86
|
+
#
|
87
|
+
# @example As a list
|
88
|
+
# <%= render(Primer::UnderlineNavComponent.new(label: "As a list", body_arguments: { tag: :ul })) do |component| %>
|
71
89
|
# <% component.tab(href: "#", selected: true) do |t| %>
|
72
90
|
# <% t.text { "Item 1" } %>
|
73
91
|
# <% end %>
|
@@ -80,7 +98,7 @@ module Primer
|
|
80
98
|
# <% end %>
|
81
99
|
#
|
82
100
|
# @example With panels
|
83
|
-
# <%= render(Primer::UnderlineNavComponent.new(with_panel: true)) do |component| %>
|
101
|
+
# <%= render(Primer::UnderlineNavComponent.new(label: "With panels", with_panel: true)) do |component| %>
|
84
102
|
# <% component.tab(selected: true) do |t| %>
|
85
103
|
# <% t.text { "Item 1" } %>
|
86
104
|
# <% t.panel do %>
|
@@ -98,33 +116,47 @@ module Primer
|
|
98
116
|
# <% end %>
|
99
117
|
# <% end %>
|
100
118
|
#
|
119
|
+
# @param label [String] The `aria-label` on top level `<nav>` element.
|
101
120
|
# @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
|
102
121
|
# @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
|
122
|
+
# @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
|
103
123
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
104
|
-
def initialize(with_panel: false, align: ALIGN_DEFAULT,
|
124
|
+
def initialize(label:, with_panel: false, align: ALIGN_DEFAULT, body_arguments: { tag: BODY_TAG_DEFAULT }, **system_arguments)
|
105
125
|
@with_panel = with_panel
|
106
126
|
@align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
|
107
127
|
|
108
128
|
@system_arguments = system_arguments
|
109
|
-
@system_arguments[:tag] =
|
110
|
-
@system_arguments[:role] = :tablist
|
129
|
+
@system_arguments[:tag] = navigation_tag(with_panel)
|
111
130
|
@system_arguments[:classes] = class_names(
|
112
131
|
@system_arguments[:classes],
|
113
132
|
"UnderlineNav",
|
114
133
|
"UnderlineNav--right" => @align == :right
|
115
134
|
)
|
116
135
|
|
117
|
-
@body_arguments =
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
136
|
+
@body_arguments = body_arguments
|
137
|
+
@body_tag = fetch_or_fallback(BODY_TAG_OPTIONS, body_arguments[:tag]&.to_sym, BODY_TAG_DEFAULT)
|
138
|
+
|
139
|
+
@body_arguments[:tag] = @body_tag
|
140
|
+
@body_arguments[:classes] = class_names(
|
141
|
+
"UnderlineNav-body",
|
142
|
+
@body_arguments[:classes],
|
143
|
+
"list-style-none" => list?
|
144
|
+
)
|
145
|
+
|
146
|
+
if with_panel
|
147
|
+
@body_arguments[:role] = :tablist
|
148
|
+
@body_arguments[:"aria-label"] = label
|
149
|
+
else
|
150
|
+
@system_arguments[:"aria-label"] = label
|
151
|
+
end
|
124
152
|
end
|
125
153
|
|
126
154
|
private
|
127
155
|
|
156
|
+
def list?
|
157
|
+
@body_tag == :ul
|
158
|
+
end
|
159
|
+
|
128
160
|
def body
|
129
161
|
Primer::BaseComponent.new(**@body_arguments)
|
130
162
|
end
|
data/app/lib/primer/classify.rb
CHANGED
@@ -3,12 +3,11 @@
|
|
3
3
|
module Primer
|
4
4
|
# :nodoc:
|
5
5
|
class Classify
|
6
|
-
MARGIN_DIRECTION_KEYS = %i[mt ml mb mr].freeze
|
7
|
-
SPACING_KEYS = (%i[m my mx p py px pt pl pb pr] + MARGIN_DIRECTION_KEYS).freeze
|
8
6
|
DIRECTION_KEY = :direction
|
9
7
|
JUSTIFY_CONTENT_KEY = :justify_content
|
10
8
|
ALIGN_ITEMS_KEY = :align_items
|
11
9
|
DISPLAY_KEY = :display
|
10
|
+
SPACING_KEYS = Primer::Classify::Spacing::KEYS
|
12
11
|
RESPONSIVE_KEYS = ([DISPLAY_KEY, DIRECTION_KEY, JUSTIFY_CONTENT_KEY, ALIGN_ITEMS_KEY, :col, :float] + SPACING_KEYS).freeze
|
13
12
|
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
14
13
|
|
@@ -184,14 +183,8 @@ module Primer
|
|
184
183
|
return if val.nil? || val == ""
|
185
184
|
|
186
185
|
if SPACING_KEYS.include?(key)
|
187
|
-
|
188
|
-
|
189
|
-
elsif !((key == :mx || key == :my) && val == :auto)
|
190
|
-
raise ArgumentError, "value of #{key} must be between 0 and 6" if val.negative? || val > 6
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
if BOOLEAN_MAPPINGS.key?(key)
|
186
|
+
memo[:classes] << Primer::Classify::Spacing.spacing(key, val, breakpoint)
|
187
|
+
elsif BOOLEAN_MAPPINGS.key?(key)
|
195
188
|
BOOLEAN_MAPPINGS[key][:mappings].each do |m|
|
196
189
|
memo[:classes] << m[:css_class] if m[:value] == val && m[:css_class].present?
|
197
190
|
end
|
@@ -248,8 +241,6 @@ module Primer
|
|
248
241
|
memo[:classes] << "text-#{val.to_s.dasherize}"
|
249
242
|
elsif TYPOGRAPHY_KEYS.include?(key)
|
250
243
|
memo[:classes] << "f#{val.to_s.dasherize}"
|
251
|
-
elsif MARGIN_DIRECTION_KEYS.include?(key) && val.negative?
|
252
|
-
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-n#{val.abs}"
|
253
244
|
elsif key == BOX_SHADOW_KEY
|
254
245
|
memo[:classes] << if val == true
|
255
246
|
"color-shadow-small"
|
@@ -20,13 +20,23 @@ module Primer
|
|
20
20
|
|
21
21
|
def preload!
|
22
22
|
preload(
|
23
|
-
keys: Primer::Classify::
|
24
|
-
values:
|
23
|
+
keys: Primer::Classify::Spacing::MARGIN_DIRECTION_MAPPINGS.keys,
|
24
|
+
values: Primer::Classify::Spacing::MARGIN_DIRECTION_OPTIONS
|
25
25
|
)
|
26
26
|
|
27
27
|
preload(
|
28
|
-
keys:
|
29
|
-
values:
|
28
|
+
keys: Primer::Classify::Spacing::BASE_MAPPINGS.keys,
|
29
|
+
values: Primer::Classify::Spacing::BASE_OPTIONS
|
30
|
+
)
|
31
|
+
|
32
|
+
preload(
|
33
|
+
keys: Primer::Classify::Spacing::AUTO_MAPPINGS.keys,
|
34
|
+
values: Primer::Classify::Spacing::AUTO_OPTIONS
|
35
|
+
)
|
36
|
+
|
37
|
+
preload(
|
38
|
+
keys: Primer::Classify::Spacing::RESPONSIVE_MAPPINGS.keys,
|
39
|
+
values: Primer::Classify::Spacing::RESPONSIVE_OPTIONS
|
30
40
|
)
|
31
41
|
|
32
42
|
preload(
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
class Classify
|
5
|
+
# Handler for PrimerCSS spacing classes.
|
6
|
+
class Spacing
|
7
|
+
BASE_OPTIONS = (0..6).to_a.freeze
|
8
|
+
BASE_MAPPINGS = {
|
9
|
+
my: BASE_OPTIONS,
|
10
|
+
pb: BASE_OPTIONS,
|
11
|
+
pl: BASE_OPTIONS,
|
12
|
+
pr: BASE_OPTIONS,
|
13
|
+
pt: BASE_OPTIONS,
|
14
|
+
px: BASE_OPTIONS,
|
15
|
+
py: BASE_OPTIONS
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
MARGIN_DIRECTION_OPTIONS = [*(-6..-1), *BASE_OPTIONS].freeze
|
19
|
+
MARGIN_DIRECTION_MAPPINGS = {
|
20
|
+
mb: MARGIN_DIRECTION_OPTIONS,
|
21
|
+
ml: MARGIN_DIRECTION_OPTIONS,
|
22
|
+
mr: MARGIN_DIRECTION_OPTIONS,
|
23
|
+
mt: MARGIN_DIRECTION_OPTIONS
|
24
|
+
}.freeze
|
25
|
+
|
26
|
+
AUTO_OPTIONS = [*BASE_OPTIONS, :auto].freeze
|
27
|
+
AUTO_MAPPINGS = {
|
28
|
+
m: AUTO_OPTIONS,
|
29
|
+
mx: AUTO_OPTIONS
|
30
|
+
}.freeze
|
31
|
+
|
32
|
+
RESPONSIVE_OPTIONS = [*BASE_OPTIONS, :responsive].freeze
|
33
|
+
RESPONSIVE_MAPPINGS = {
|
34
|
+
p: RESPONSIVE_OPTIONS
|
35
|
+
}.freeze
|
36
|
+
|
37
|
+
MAPPINGS = {
|
38
|
+
**BASE_MAPPINGS,
|
39
|
+
**MARGIN_DIRECTION_MAPPINGS,
|
40
|
+
**AUTO_MAPPINGS,
|
41
|
+
**RESPONSIVE_MAPPINGS
|
42
|
+
}.freeze
|
43
|
+
KEYS = MAPPINGS.keys.freeze
|
44
|
+
|
45
|
+
class << self
|
46
|
+
def spacing(key, val, breakpoint)
|
47
|
+
validate(key, val) unless Rails.env.production?
|
48
|
+
|
49
|
+
return "#{key.to_s.dasherize}#{breakpoint}-n#{val.abs}" if val.is_a?(Numeric) && val.negative?
|
50
|
+
|
51
|
+
"#{key.to_s.dasherize}#{breakpoint}-#{val.to_s.dasherize}"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def validate(key, val)
|
57
|
+
raise ArgumentError, "#{key} is not a spacing key" unless KEYS.include?(key)
|
58
|
+
raise ArgumentError, "#{val} is not a valid value for :#{key}. Use one of #{MAPPINGS[key]}" unless MAPPINGS[key].include?(val)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|