primer_view_components 0.0.18 → 0.0.23
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 +101 -0
- data/app/assets/javascripts/primer_view_components.js +2 -0
- data/app/assets/javascripts/primer_view_components.js.map +1 -0
- data/app/components/primer/avatar_component.rb +27 -9
- data/app/components/primer/avatar_stack_component.html.erb +10 -0
- data/app/components/primer/avatar_stack_component.rb +81 -0
- data/app/components/primer/base_component.rb +4 -4
- data/app/components/primer/blankslate_component.html.erb +3 -3
- data/app/components/primer/blankslate_component.rb +16 -24
- data/app/components/primer/border_box_component.html.erb +4 -18
- data/app/components/primer/border_box_component.rb +75 -72
- data/app/components/primer/box_component.rb +2 -2
- data/app/components/primer/breadcrumb_component.rb +1 -1
- data/app/components/primer/button_component.rb +2 -2
- data/app/components/primer/button_group_component.rb +4 -1
- data/app/components/primer/button_marketing_component.rb +2 -2
- data/app/components/primer/component.rb +9 -6
- data/app/components/primer/counter_component.rb +5 -1
- data/app/components/primer/details_component.html.erb +2 -6
- data/app/components/primer/details_component.rb +22 -35
- data/app/components/primer/dropdown/menu_component.html.erb +12 -0
- data/app/components/primer/dropdown/menu_component.rb +48 -0
- data/app/components/primer/dropdown_component.html.erb +9 -0
- data/app/components/primer/dropdown_component.rb +75 -0
- data/app/components/primer/dropdown_menu_component.rb +8 -4
- data/app/components/primer/flash_component.html.erb +4 -7
- data/app/components/primer/flash_component.rb +18 -18
- data/app/components/primer/flex_component.rb +38 -1
- data/app/components/primer/flex_item_component.rb +15 -1
- data/app/components/primer/heading_component.rb +3 -1
- data/app/components/primer/label_component.rb +15 -25
- data/app/components/primer/layout_component.rb +2 -2
- data/app/components/primer/link_component.rb +6 -2
- data/app/components/primer/markdown_component.rb +293 -0
- data/app/components/primer/menu_component.html.erb +6 -0
- data/app/components/primer/menu_component.rb +71 -0
- data/app/components/primer/octicon_component.rb +9 -3
- data/app/components/primer/popover_component.rb +5 -5
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/components/primer/progress_bar_component.rb +5 -5
- data/app/components/primer/spinner_component.rb +7 -3
- data/app/components/primer/state_component.rb +21 -10
- data/app/components/primer/subhead_component.html.erb +3 -15
- data/app/components/primer/subhead_component.rb +45 -61
- data/app/components/primer/tab_container_component.js +1 -0
- data/app/components/primer/tab_container_component.rb +41 -0
- data/app/components/primer/tab_container_component.ts +1 -0
- data/app/components/primer/tab_nav_component.html.erb +17 -0
- data/app/components/primer/tab_nav_component.rb +108 -0
- data/app/components/primer/text_component.rb +1 -1
- data/app/components/primer/timeline_item_component.html.erb +4 -16
- data/app/components/primer/timeline_item_component.rb +41 -52
- data/app/components/primer/tooltip_component.rb +5 -5
- data/app/components/primer/truncate_component.rb +4 -4
- data/app/components/primer/underline_nav_component.rb +2 -2
- data/{lib → app/lib}/primer/class_name_helper.rb +0 -0
- data/{lib → app/lib}/primer/classify.rb +21 -10
- data/app/lib/primer/classify/cache.rb +125 -0
- data/{lib → app/lib}/primer/fetch_or_fallback_helper.rb +1 -1
- data/{lib → app/lib}/primer/join_style_arguments_helper.rb +1 -1
- data/app/lib/primer/view_helper.rb +22 -0
- data/app/lib/primer/view_helper/dsl.rb +34 -0
- data/lib/primer/view_components.rb +32 -1
- data/lib/primer/view_components/engine.rb +11 -3
- data/lib/primer/view_components/version.rb +5 -1
- data/lib/yard/renders_many_handler.rb +19 -0
- data/lib/yard/renders_one_handler.rb +19 -0
- data/static/statuses.json +1 -0
- metadata +61 -10
- data/app/components/primer/view_components.rb +0 -56
@@ -0,0 +1 @@
|
|
1
|
+
import '@github/tab-container-element';
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use TabContainer to create tabbed content with keyboard support. This component does not add any styles.
|
5
|
+
# It only provides the tab functionality. If you want styled Tabs you can look at <%= link_to_component(Primer::TabNavComponent) %>.
|
6
|
+
#
|
7
|
+
# This component requires javascript.
|
8
|
+
class TabContainerComponent < Primer::Component
|
9
|
+
# @example Default
|
10
|
+
# <%= render(Primer::TabContainerComponent.new) do %>
|
11
|
+
# <div role="tablist">
|
12
|
+
# <button type="button" role="tab" aria-selected="true">Tab one</button>
|
13
|
+
# <button type="button" role="tab" tabindex="-1">Tab two</button>
|
14
|
+
# <button type="button" role="tab" tabindex="-1">Tab three</button>
|
15
|
+
# </div>
|
16
|
+
# <div role="tabpanel">
|
17
|
+
# Panel 1
|
18
|
+
# </div>
|
19
|
+
# <div role="tabpanel" hidden>
|
20
|
+
# Panel 2
|
21
|
+
# </div>
|
22
|
+
# <div role="tabpanel" hidden>
|
23
|
+
# Panel 3
|
24
|
+
# </div>
|
25
|
+
# <% end %>
|
26
|
+
#
|
27
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
28
|
+
def initialize(**system_arguments)
|
29
|
+
@system_arguments = system_arguments
|
30
|
+
@system_arguments[:tag] = "tab-container"
|
31
|
+
end
|
32
|
+
|
33
|
+
def call
|
34
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
35
|
+
end
|
36
|
+
|
37
|
+
def render?
|
38
|
+
content.present?
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
import '@github/tab-container-element'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= render wrapper.new(**@system_arguments) do %>
|
2
|
+
<nav role="tablist" aria-label="<%= @aria_label %>" class="tabnav-tabs">
|
3
|
+
<% tabs.each do |tab| %>
|
4
|
+
<%= tab %>
|
5
|
+
<% end %>
|
6
|
+
</nav >
|
7
|
+
|
8
|
+
<% if @with_panel %>
|
9
|
+
<% tabs.each do |tab| %>
|
10
|
+
<% if tab.panel.present? %>
|
11
|
+
<div role="tabpanel" <%= "hidden" if tab.hidden? %>>
|
12
|
+
<%= tab.panel %>
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use TabNav to style navigation with a tab-based selected state, typically used for navigation placed at the top of the page.
|
5
|
+
class TabNavComponent < Primer::Component
|
6
|
+
include ViewComponent::SlotableV2
|
7
|
+
|
8
|
+
class MultipleSelectedTabsError < StandardError; end
|
9
|
+
class NoSelectedTabsError < StandardError; end
|
10
|
+
|
11
|
+
# Tabs to be rendered.
|
12
|
+
#
|
13
|
+
# @param title [String] Text to be rendered by the tab.
|
14
|
+
# @param selected [Boolean] Whether the tab is selected.
|
15
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
16
|
+
renders_many :tabs, lambda { |**system_arguments|
|
17
|
+
return TabComponent.new(**system_arguments) unless @with_panel
|
18
|
+
|
19
|
+
TabComponent.new(tag: :button, type: :button, **system_arguments)
|
20
|
+
}
|
21
|
+
|
22
|
+
# @example Default
|
23
|
+
# <%= render(Primer::TabNavComponent.new) do |c| %>
|
24
|
+
# <% c.tab(selected: true, title: "Tab 1", href: "#") %>
|
25
|
+
# <% c.tab(title: "Tab 2", href: "#") %>
|
26
|
+
# <% c.tab(title: "Tab 3", href: "#") %>
|
27
|
+
# <% end %>
|
28
|
+
#
|
29
|
+
# @example With panels
|
30
|
+
# <%= render(Primer::TabNavComponent.new(with_panel: true)) do |c| %>
|
31
|
+
# <% c.tab(selected: true, title: "Tab 1") { "Panel 1" } %>
|
32
|
+
# <% c.tab(title: "Tab 2") { "Panel 1" } %>
|
33
|
+
# <% c.tab(title: "Tab 3") { "Panel 1" } %>
|
34
|
+
# <% end %>
|
35
|
+
#
|
36
|
+
# @param aria_label [String] Used to set the `aria-label` on the top level `<nav>` element.
|
37
|
+
# @param with_panel [Boolean] Whether the TabNav should navigate through pages or panels.
|
38
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
39
|
+
def initialize(aria_label: nil, with_panel: false, **system_arguments)
|
40
|
+
@aria_label = aria_label
|
41
|
+
@with_panel = with_panel
|
42
|
+
@system_arguments = system_arguments
|
43
|
+
@system_arguments[:tag] ||= :div
|
44
|
+
|
45
|
+
@system_arguments[:classes] = class_names(
|
46
|
+
"tabnav",
|
47
|
+
system_arguments[:classes]
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def before_render
|
52
|
+
validate_single_selected_tab
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def wrapper
|
58
|
+
@with_panel ? Primer::TabContainerComponent : Primer::BaseComponent
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_single_selected_tab
|
62
|
+
raise MultipleSelectedTabsError, "only one tab can be selected" if selected_tabs_count > 1
|
63
|
+
raise NoSelectedTabsError, "a tab must be selected" if selected_tabs_count != 1
|
64
|
+
end
|
65
|
+
|
66
|
+
def selected_tabs_count
|
67
|
+
@selected_tabs_count ||= tabs.count(&:selected)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Tabs to be rendered.
|
71
|
+
class TabComponent < Primer::Component
|
72
|
+
attr_reader :selected
|
73
|
+
|
74
|
+
def initialize(title:, selected: false, **system_arguments)
|
75
|
+
@title = title
|
76
|
+
@selected = selected
|
77
|
+
@system_arguments = system_arguments
|
78
|
+
@system_arguments[:tag] ||= :a
|
79
|
+
@system_arguments[:role] = :tab
|
80
|
+
|
81
|
+
if selected
|
82
|
+
if @system_arguments[:tag] == :a
|
83
|
+
@system_arguments[:"aria-current"] = :page
|
84
|
+
else
|
85
|
+
@system_arguments[:"aria-selected"] = true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
@system_arguments[:classes] = class_names(
|
90
|
+
"tabnav-tab",
|
91
|
+
system_arguments[:classes]
|
92
|
+
)
|
93
|
+
end
|
94
|
+
|
95
|
+
def call
|
96
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { @title }
|
97
|
+
end
|
98
|
+
|
99
|
+
def panel
|
100
|
+
content
|
101
|
+
end
|
102
|
+
|
103
|
+
def hidden?
|
104
|
+
!@selected
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Primer
|
4
4
|
# The Text component is a wrapper component that will apply typography styles to the text inside.
|
5
5
|
class TextComponent < Primer::Component
|
6
|
-
# @example
|
6
|
+
# @example Default
|
7
7
|
# <%= render(Primer::TextComponent.new(tag: :p, font_weight: :bold)) { "Bold Text" } %>
|
8
8
|
# <%= render(Primer::TextComponent.new(tag: :p, color: :red_5)) { "Red Text" } %>
|
9
9
|
#
|
@@ -1,17 +1,5 @@
|
|
1
|
-
<%= render Primer::BaseComponent.new(
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
<% if badge %>
|
7
|
-
<%= render Primer::BaseComponent.new(**badge.system_arguments) do %>
|
8
|
-
<%= octicon badge.icon %>
|
9
|
-
<% end %>
|
10
|
-
<% end %>
|
11
|
-
|
12
|
-
<% if body %>
|
13
|
-
<%= render Primer::BaseComponent.new(**body.system_arguments) do %>
|
14
|
-
<%= body.content %>
|
15
|
-
<% end %>
|
16
|
-
<% end %>
|
1
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
2
|
+
<%= avatar %>
|
3
|
+
<%= badge %>
|
4
|
+
<%= body %>
|
17
5
|
<% end %>
|
@@ -3,20 +3,45 @@
|
|
3
3
|
module Primer
|
4
4
|
# Use `TimelineItem` to display items on a vertical timeline, connected by badge elements.
|
5
5
|
class TimelineItemComponent < Primer::Component
|
6
|
-
include ViewComponent::
|
6
|
+
include ViewComponent::SlotableV2
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
# Avatar to be rendered to the left of the Badge.
|
9
|
+
#
|
10
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::AvatarComponent) %>.
|
11
|
+
renders_one :avatar, lambda { |src:, size: 40, square: true, **system_arguments|
|
12
|
+
system_arguments[:classes] = class_names(
|
13
|
+
"TimelineItem-avatar",
|
14
|
+
system_arguments[:classes]
|
15
|
+
)
|
16
|
+
|
17
|
+
Primer::AvatarComponent.new(src: src, size: size, square: square, **system_arguments)
|
18
|
+
}
|
11
19
|
|
12
|
-
|
20
|
+
# Badge that will be connected to other TimelineItems.
|
21
|
+
#
|
22
|
+
# @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
|
23
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
24
|
+
renders_one :badge, "BadgeComponent"
|
13
25
|
|
14
|
-
#
|
26
|
+
# Body to be rendered to the left of the Badge.
|
27
|
+
#
|
28
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
29
|
+
renders_one :body, lambda { |**system_arguments|
|
30
|
+
system_arguments[:tag] = :div
|
31
|
+
system_arguments[:classes] = class_names(
|
32
|
+
"TimelineItem-body",
|
33
|
+
system_arguments[:classes]
|
34
|
+
)
|
35
|
+
|
36
|
+
Primer::BaseComponent.new(**system_arguments)
|
37
|
+
}
|
38
|
+
|
39
|
+
# @example Default
|
15
40
|
# <div style="padding-left: 60px">
|
16
41
|
# <%= render(Primer::TimelineItemComponent.new) do |component| %>
|
17
|
-
# <% component.
|
18
|
-
# <% component.
|
19
|
-
# <% component.
|
42
|
+
# <% component.avatar(src: "https://github.com/github.png", alt: "github") %>
|
43
|
+
# <% component.badge(bg: :green, color: :white, icon: :check) %>
|
44
|
+
# <% component.body { "Success!" } %>
|
20
45
|
# <% end %>
|
21
46
|
# </div>
|
22
47
|
#
|
@@ -36,36 +61,9 @@ module Primer
|
|
36
61
|
avatar.present? || badge.present? || body.present?
|
37
62
|
end
|
38
63
|
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
# @param alt [String] Alt text for avatar image.
|
44
|
-
# @param src [String] Src attribute for avatar image.
|
45
|
-
# @param size [Integer] Image size.
|
46
|
-
# @param square [Boolean] Whether to round the edges of the image.
|
47
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
48
|
-
def initialize(alt: nil, src: nil, size: 40, square: true, **system_arguments)
|
49
|
-
@alt = alt
|
50
|
-
@src = src
|
51
|
-
@size = size
|
52
|
-
@square = square
|
53
|
-
|
54
|
-
@system_arguments = system_arguments
|
55
|
-
@system_arguments[:tag] = :div
|
56
|
-
@system_arguments[:classes] = class_names(
|
57
|
-
"TimelineItem-avatar",
|
58
|
-
system_arguments[:classes]
|
59
|
-
)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
# :nodoc
|
64
|
-
class Badge < Primer::Slot
|
65
|
-
attr_reader :system_arguments, :icon
|
66
|
-
|
67
|
-
# @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
|
68
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
64
|
+
# This component is part of `Primer::TimelineItemComponent` and should not be
|
65
|
+
# used as a standalone component.
|
66
|
+
class BadgeComponent < Primer::Component
|
69
67
|
def initialize(icon: nil, **system_arguments)
|
70
68
|
@icon = icon
|
71
69
|
|
@@ -76,20 +74,11 @@ module Primer
|
|
76
74
|
system_arguments[:classes]
|
77
75
|
)
|
78
76
|
end
|
79
|
-
end
|
80
|
-
|
81
|
-
# :nodoc
|
82
|
-
class Body < Primer::Slot
|
83
|
-
attr_reader :system_arguments
|
84
77
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@system_arguments[:classes] = class_names(
|
90
|
-
"TimelineItem-body",
|
91
|
-
system_arguments[:classes]
|
92
|
-
)
|
78
|
+
def call
|
79
|
+
render(Primer::BaseComponent.new(**@system_arguments)) do
|
80
|
+
render(Primer::OcticonComponent.new(icon: @icon))
|
81
|
+
end
|
93
82
|
end
|
94
83
|
end
|
95
84
|
end
|
@@ -26,29 +26,29 @@ module Primer
|
|
26
26
|
se
|
27
27
|
]
|
28
28
|
|
29
|
-
# @example
|
29
|
+
# @example Default
|
30
30
|
# <div class="pt-5">
|
31
31
|
# <%= render(Primer::TooltipComponent.new(label: "Even bolder")) { "Default Bold Text" } %>
|
32
32
|
# </div>
|
33
33
|
#
|
34
|
-
# @example
|
34
|
+
# @example Wrapping another component
|
35
35
|
# <div class="pt-5">
|
36
36
|
# <%= render(Primer::TooltipComponent.new(label: "Even bolder")) do %>
|
37
37
|
# <%= render(Primer::ButtonComponent.new) { "Bold Button" } %>
|
38
38
|
# <% end %>
|
39
39
|
# </div>
|
40
40
|
#
|
41
|
-
# @example
|
41
|
+
# @example With a direction
|
42
42
|
# <div class="pt-5">
|
43
43
|
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s)) { "Bold Text With a Direction" } %>
|
44
44
|
# </div>
|
45
45
|
#
|
46
|
-
# @example
|
46
|
+
# @example With an alignment
|
47
47
|
# <div class="pt-5">
|
48
48
|
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, alignment: :right_1)) { "Bold Text With an Alignment" } %>
|
49
49
|
# </div>
|
50
50
|
#
|
51
|
-
# @example
|
51
|
+
# @example Without a delay
|
52
52
|
# <div class="pt-5">
|
53
53
|
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, no_delay: true)) { "Bold Text without a delay" } %>
|
54
54
|
# </div>
|
@@ -3,18 +3,18 @@
|
|
3
3
|
module Primer
|
4
4
|
# Use TruncateComponent to shorten overflowing text with an ellipsis.
|
5
5
|
class TruncateComponent < Primer::Component
|
6
|
-
# @example
|
6
|
+
# @example Default
|
7
7
|
# <div class="col-2">
|
8
8
|
# <%= render(Primer::TruncateComponent.new(tag: :p)) { "branch-name-that-is-really-long" } %>
|
9
9
|
# </div>
|
10
10
|
#
|
11
|
-
# @example
|
11
|
+
# @example Inline
|
12
12
|
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true)) { "branch-name-that-is-really-long" } %>
|
13
13
|
#
|
14
|
-
# @example
|
14
|
+
# @example Expandable
|
15
15
|
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true)) { "branch-name-that-is-really-long" } %>
|
16
16
|
#
|
17
|
-
# @example
|
17
|
+
# @example Custom size
|
18
18
|
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
|
19
19
|
#
|
20
20
|
# @param inline [Boolean] Whether the element is inline (or inline-block).
|
@@ -10,7 +10,7 @@ module Primer
|
|
10
10
|
|
11
11
|
with_content_areas :body, :actions
|
12
12
|
|
13
|
-
# @example
|
13
|
+
# @example Default
|
14
14
|
# <%= render(Primer::UnderlineNavComponent.new) do |component| %>
|
15
15
|
# <% component.with(:body) do %>
|
16
16
|
# <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
|
@@ -20,7 +20,7 @@ module Primer
|
|
20
20
|
# <% end %>
|
21
21
|
# <% end %>
|
22
22
|
#
|
23
|
-
# @example
|
23
|
+
# @example Align right
|
24
24
|
# <%= render(Primer::UnderlineNavComponent.new(align: :right)) do |component| %>
|
25
25
|
# <% component.with(:body) do %>
|
26
26
|
# <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
|
File without changes
|
@@ -17,6 +17,7 @@ module Primer
|
|
17
17
|
|
18
18
|
INVALID_CLASS_NAME_PREFIXES =
|
19
19
|
(["bg-", "color-", "text-", "d-", "v-align-", "wb-", "text-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
|
20
|
+
FUNCTIONAL_COLOR_REGEX = /(primary|secondary|tertiary|link|success|warning|danger|info)/.freeze
|
20
21
|
|
21
22
|
COLOR_KEY = :color
|
22
23
|
BG_KEY = :bg
|
@@ -166,10 +167,10 @@ module Primer
|
|
166
167
|
raise ArgumentError, "#{key} does not support responsive values" unless RESPONSIVE_KEYS.include?(key)
|
167
168
|
|
168
169
|
value.each_with_index do |val, index|
|
169
|
-
extract_value(memo, key, val, BREAKPOINTS[index])
|
170
|
+
Primer::Classify::Cache.read(memo, key, val, BREAKPOINTS[index]) || extract_value(memo, key, val, BREAKPOINTS[index])
|
170
171
|
end
|
171
172
|
else
|
172
|
-
extract_value(memo, key, value, BREAKPOINTS[0])
|
173
|
+
Primer::Classify::Cache.read(memo, key, value, BREAKPOINTS[0]) || extract_value(memo, key, value, BREAKPOINTS[0])
|
173
174
|
end
|
174
175
|
end
|
175
176
|
|
@@ -179,7 +180,7 @@ module Primer
|
|
179
180
|
end
|
180
181
|
|
181
182
|
def extract_value(memo, key, val, breakpoint)
|
182
|
-
return if val.nil?
|
183
|
+
return if val.nil? || val == ""
|
183
184
|
|
184
185
|
if SPACING_KEYS.include?(key)
|
185
186
|
if MARGIN_DIRECTION_KEYS.include?(key)
|
@@ -194,7 +195,7 @@ module Primer
|
|
194
195
|
memo[:classes] << css_class
|
195
196
|
end
|
196
197
|
elsif key == BG_KEY
|
197
|
-
if val.to_s.
|
198
|
+
if val.to_s.start_with?("#")
|
198
199
|
memo[:styles] << "background-color: #{val};"
|
199
200
|
else
|
200
201
|
memo[:classes] << "bg-#{val.to_s.dasherize}"
|
@@ -202,11 +203,13 @@ module Primer
|
|
202
203
|
elsif key == COLOR_KEY
|
203
204
|
char_code = val[-1].ord
|
204
205
|
# Does this string end in a character that is NOT a number?
|
205
|
-
memo[:classes] <<
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
206
|
+
memo[:classes] <<
|
207
|
+
if (char_code >= 48 && char_code <= 57) || # 48 is the charcode for 0; 57 is the charcode for 9
|
208
|
+
FUNCTIONAL_COLOR_REGEX.match?(val)
|
209
|
+
"color-#{val.to_s.dasherize}"
|
210
|
+
else
|
211
|
+
"text-#{val.to_s.dasherize}"
|
212
|
+
end
|
210
213
|
elsif key == DISPLAY_KEY
|
211
214
|
memo[:classes] << "d#{breakpoint}-#{val.to_s.dasherize}"
|
212
215
|
elsif key == VERTICAL_ALIGN_KEY
|
@@ -214,7 +217,13 @@ module Primer
|
|
214
217
|
elsif key == WORD_BREAK_KEY
|
215
218
|
memo[:classes] << "wb-#{val.to_s.dasherize}"
|
216
219
|
elsif BORDER_KEYS.include?(key)
|
217
|
-
|
220
|
+
border_value = if val == true
|
221
|
+
"border"
|
222
|
+
else
|
223
|
+
"border-#{val.to_s.dasherize}"
|
224
|
+
end
|
225
|
+
|
226
|
+
memo[:classes] << border_value
|
218
227
|
elsif BORDER_MARGIN_KEYS.include?(key)
|
219
228
|
memo[:classes] << "#{key.to_s.dasherize}-#{val}"
|
220
229
|
elsif key == BORDER_RADIUS_KEY
|
@@ -265,5 +274,7 @@ module Primer
|
|
265
274
|
end
|
266
275
|
end
|
267
276
|
end
|
277
|
+
|
278
|
+
Cache.preload!
|
268
279
|
end
|
269
280
|
end
|