primer_view_components 0.0.16 → 0.0.21
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/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 +8 -4
- data/app/components/primer/blankslate_component.html.erb +1 -1
- data/app/components/primer/blankslate_component.rb +18 -25
- data/app/components/primer/border_box_component.rb +29 -13
- data/app/components/primer/box_component.rb +10 -0
- data/app/components/primer/breadcrumb_component.rb +3 -2
- data/app/components/primer/button_component.rb +3 -3
- data/app/components/primer/button_group_component.html.erb +5 -0
- data/app/components/primer/button_group_component.rb +37 -0
- data/app/components/primer/button_marketing_component.rb +73 -0
- data/app/components/primer/component.rb +13 -0
- data/app/components/primer/counter_component.rb +16 -9
- data/app/components/primer/details_component.rb +10 -6
- 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 +77 -0
- data/app/components/primer/dropdown_menu_component.rb +35 -3
- data/app/components/primer/flash_component.html.erb +2 -5
- data/app/components/primer/flash_component.rb +18 -19
- data/app/components/primer/flex_component.rb +47 -9
- data/app/components/primer/flex_item_component.rb +16 -1
- data/app/components/primer/heading_component.rb +7 -0
- data/app/components/primer/label_component.rb +6 -6
- data/app/components/primer/layout_component.rb +2 -2
- data/app/components/primer/link_component.rb +7 -3
- 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 +11 -6
- data/app/components/primer/popover_component.rb +6 -4
- data/app/components/primer/progress_bar_component.rb +9 -9
- data/app/components/primer/slot.rb +1 -0
- data/app/components/primer/spinner_component.rb +10 -7
- data/app/components/primer/state_component.rb +6 -6
- data/app/components/primer/subhead_component.rb +6 -3
- 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 -49
- data/app/components/primer/tooltip_component.rb +88 -0
- data/app/components/primer/truncate_component.rb +41 -0
- data/app/components/primer/underline_nav_component.rb +26 -1
- data/app/components/primer/view_components.rb +9 -0
- data/lib/primer/class_name_helper.rb +1 -0
- data/lib/primer/classify.rb +139 -107
- data/lib/primer/classify/cache.rb +125 -0
- data/lib/primer/fetch_or_fallback_helper.rb +9 -0
- data/lib/primer/join_style_arguments_helper.rb +14 -0
- data/lib/primer/view_components.rb +32 -0
- data/lib/primer/view_components/engine.rb +1 -0
- data/lib/primer/view_components/version.rb +1 -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 +80 -19
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# The Tooltip component is a wrapper component that will apply a tooltip to the provided content.
|
5
|
+
class TooltipComponent < Primer::Component
|
6
|
+
DIRECTION_DEFAULT = :n
|
7
|
+
ALIGN_DEFAULT = :default
|
8
|
+
MULTILINE_DEFAULT = false
|
9
|
+
DELAY_DEFAULT = false
|
10
|
+
|
11
|
+
ALIGN_MAPPING = {
|
12
|
+
ALIGN_DEFAULT => "",
|
13
|
+
:left_1 => "tooltipped-align-left-1",
|
14
|
+
:right_1 => "tooltipped-align-right-1",
|
15
|
+
:left_2 => "tooltipped-align-left-2",
|
16
|
+
:right_2 => "tooltipped-align-right-2"
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
DIRECTION_OPTIONS = [DIRECTION_DEFAULT] + %i[
|
20
|
+
nw
|
21
|
+
ne
|
22
|
+
w
|
23
|
+
e
|
24
|
+
sw
|
25
|
+
s
|
26
|
+
se
|
27
|
+
]
|
28
|
+
|
29
|
+
# @example 55|Default
|
30
|
+
# <div class="pt-5">
|
31
|
+
# <%= render(Primer::TooltipComponent.new(label: "Even bolder")) { "Default Bold Text" } %>
|
32
|
+
# </div>
|
33
|
+
#
|
34
|
+
# @example 65|Wrapping another component
|
35
|
+
# <div class="pt-5">
|
36
|
+
# <%= render(Primer::TooltipComponent.new(label: "Even bolder")) do %>
|
37
|
+
# <%= render(Primer::ButtonComponent.new) { "Bold Button" } %>
|
38
|
+
# <% end %>
|
39
|
+
# </div>
|
40
|
+
#
|
41
|
+
# @example 65|With a direction
|
42
|
+
# <div class="pt-5">
|
43
|
+
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s)) { "Bold Text With a Direction" } %>
|
44
|
+
# </div>
|
45
|
+
#
|
46
|
+
# @example 65|With an alignment
|
47
|
+
# <div class="pt-5">
|
48
|
+
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, alignment: :right_1)) { "Bold Text With an Alignment" } %>
|
49
|
+
# </div>
|
50
|
+
#
|
51
|
+
# @example 65|Without a delay
|
52
|
+
# <div class="pt-5">
|
53
|
+
# <%= render(Primer::TooltipComponent.new(label: "Even bolder", direction: :s, no_delay: true)) { "Bold Text without a delay" } %>
|
54
|
+
# </div>
|
55
|
+
#
|
56
|
+
# @param label [String] the text to appear in the tooltip
|
57
|
+
# @param direction [String] Direction of the tooltip. <%= one_of(Primer::TooltipComponent::DIRECTION_OPTIONS) %>
|
58
|
+
# @param align [String] Align tooltips to the left or right of an element, combined with a `direction` to specify north or south. <%= one_of(Primer::TooltipComponent::ALIGN_MAPPING.keys) %>
|
59
|
+
# @param multiline [Boolean] Use this when you have long content
|
60
|
+
# @param no_delay [Boolean] By default the tooltips have a slight delay before appearing. Set true to override this
|
61
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
62
|
+
def initialize(
|
63
|
+
label:,
|
64
|
+
direction: DIRECTION_DEFAULT,
|
65
|
+
align: ALIGN_DEFAULT,
|
66
|
+
multiline: MULTILINE_DEFAULT,
|
67
|
+
no_delay: DELAY_DEFAULT,
|
68
|
+
**system_arguments
|
69
|
+
)
|
70
|
+
@system_arguments = system_arguments
|
71
|
+
@system_arguments[:tag] ||= :span
|
72
|
+
@system_arguments[:aria] = { label: label }
|
73
|
+
|
74
|
+
@system_arguments[:classes] = class_names(
|
75
|
+
@system_arguments[:classes],
|
76
|
+
"tooltipped",
|
77
|
+
"tooltipped-#{fetch_or_fallback(DIRECTION_OPTIONS, direction, DIRECTION_DEFAULT)}",
|
78
|
+
ALIGN_MAPPING[fetch_or_fallback(ALIGN_MAPPING.keys, align, ALIGN_DEFAULT)],
|
79
|
+
"tooltipped-no-delay" => fetch_or_fallback_boolean(no_delay, DELAY_DEFAULT),
|
80
|
+
"tooltipped-multiline" => fetch_or_fallback_boolean(multiline, MULTILINE_DEFAULT)
|
81
|
+
)
|
82
|
+
end
|
83
|
+
|
84
|
+
def call
|
85
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use TruncateComponent to shorten overflowing text with an ellipsis.
|
5
|
+
class TruncateComponent < Primer::Component
|
6
|
+
# @example auto|Default
|
7
|
+
# <div class="col-2">
|
8
|
+
# <%= render(Primer::TruncateComponent.new(tag: :p)) { "branch-name-that-is-really-long" } %>
|
9
|
+
# </div>
|
10
|
+
#
|
11
|
+
# @example auto|Inline
|
12
|
+
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true)) { "branch-name-that-is-really-long" } %>
|
13
|
+
#
|
14
|
+
# @example auto|Expandable
|
15
|
+
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true)) { "branch-name-that-is-really-long" } %>
|
16
|
+
#
|
17
|
+
# @example auto|Custom size
|
18
|
+
# <%= render(Primer::TruncateComponent.new(tag: :span, inline: true, expandable: true, max_width: 100)) { "branch-name-that-is-really-long" } %>
|
19
|
+
#
|
20
|
+
# @param inline [Boolean] Whether the element is inline (or inline-block).
|
21
|
+
# @param expandable [Boolean] Whether the entire string should be revealed on hover. Can only be used in conjunction with `inline`.
|
22
|
+
# @param max_width [Integer] Sets the max-width of the text.
|
23
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
24
|
+
def initialize(inline: false, expandable: false, max_width: nil, **system_arguments)
|
25
|
+
@system_arguments = system_arguments
|
26
|
+
@system_arguments[:tag] ||= :div
|
27
|
+
@system_arguments[:classes] = class_names(
|
28
|
+
@system_arguments[:classes],
|
29
|
+
"css-truncate",
|
30
|
+
"css-truncate-overflow" => !inline,
|
31
|
+
"css-truncate-target" => inline,
|
32
|
+
"expandable" => inline && expandable
|
33
|
+
)
|
34
|
+
@system_arguments[:style] = join_style_arguments(@system_arguments[:style], "max-width: #{max_width}px;") unless max_width.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def call
|
38
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,12 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use the UnderlineNav component to style navigation with a minimal
|
5
|
+
# underlined selected state, typically used for navigation placed at the top
|
6
|
+
# of the page.
|
4
7
|
class UnderlineNavComponent < Primer::Component
|
5
8
|
ALIGN_DEFAULT = :left
|
6
|
-
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right]
|
9
|
+
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
|
7
10
|
|
8
11
|
with_content_areas :body, :actions
|
9
12
|
|
13
|
+
# @example auto|Default
|
14
|
+
# <%= render(Primer::UnderlineNavComponent.new) do |component| %>
|
15
|
+
# <% component.with(:body) do %>
|
16
|
+
# <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
|
17
|
+
# <% end %>
|
18
|
+
# <% component.with(:actions) do %>
|
19
|
+
# <%= render(Primer::ButtonComponent.new) { "Button!" } %>
|
20
|
+
# <% end %>
|
21
|
+
# <% end %>
|
22
|
+
#
|
23
|
+
# @example auto|Align right
|
24
|
+
# <%= render(Primer::UnderlineNavComponent.new(align: :right)) do |component| %>
|
25
|
+
# <% component.with(:body) do %>
|
26
|
+
# <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
|
27
|
+
# <% end %>
|
28
|
+
# <% component.with(:actions) do %>
|
29
|
+
# <%= render(Primer::ButtonComponent.new) { "Button!" } %>
|
30
|
+
# <% end %>
|
31
|
+
# <% end %>
|
32
|
+
#
|
33
|
+
# @param align [Symbol] <%= one_of(Primer::UnderlineNavComponent::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavComponent::ALIGN_DEFAULT %>
|
34
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
10
35
|
def initialize(align: ALIGN_DEFAULT, **system_arguments)
|
11
36
|
@align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
|
12
37
|
|
@@ -15,6 +15,7 @@ require "octicons_helper/helper"
|
|
15
15
|
require "primer/class_name_helper"
|
16
16
|
require "primer/classify"
|
17
17
|
require "primer/fetch_or_fallback_helper"
|
18
|
+
require "primer/join_style_arguments_helper"
|
18
19
|
|
19
20
|
# Base configurations
|
20
21
|
|
@@ -25,13 +26,17 @@ require_relative "slot"
|
|
25
26
|
# Components
|
26
27
|
|
27
28
|
require_relative "avatar_component"
|
29
|
+
require_relative "avatar_stack_component"
|
28
30
|
require_relative "blankslate_component"
|
29
31
|
require_relative "border_box_component"
|
30
32
|
require_relative "box_component"
|
31
33
|
require_relative "breadcrumb_component"
|
32
34
|
require_relative "button_component"
|
35
|
+
require_relative "button_group_component"
|
36
|
+
require_relative "button_marketing_component"
|
33
37
|
require_relative "counter_component"
|
34
38
|
require_relative "details_component"
|
39
|
+
require_relative "dropdown_component"
|
35
40
|
require_relative "dropdown_menu_component"
|
36
41
|
require_relative "flash_component"
|
37
42
|
require_relative "flex_component"
|
@@ -40,6 +45,8 @@ require_relative "heading_component"
|
|
40
45
|
require_relative "label_component"
|
41
46
|
require_relative "layout_component"
|
42
47
|
require_relative "link_component"
|
48
|
+
require_relative "markdown_component"
|
49
|
+
require_relative "menu_component"
|
43
50
|
require_relative "octicon_component"
|
44
51
|
require_relative "popover_component"
|
45
52
|
require_relative "progress_bar_component"
|
@@ -48,4 +55,6 @@ require_relative "state_component"
|
|
48
55
|
require_relative "subhead_component"
|
49
56
|
require_relative "text_component"
|
50
57
|
require_relative "timeline_item_component"
|
58
|
+
require_relative "tooltip_component"
|
59
|
+
require_relative "truncate_component"
|
51
60
|
require_relative "underline_nav_component"
|
data/lib/primer/classify.rb
CHANGED
@@ -1,27 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "classify/cache"
|
4
|
+
|
3
5
|
module Primer
|
6
|
+
# :nodoc:
|
4
7
|
class Classify
|
5
|
-
MARGIN_DIRECTION_KEYS = [
|
6
|
-
SPACING_KEYS = ([
|
8
|
+
MARGIN_DIRECTION_KEYS = %i[mt ml mb mr].freeze
|
9
|
+
SPACING_KEYS = (%i[m my mx p py px pt pl pb pr] + MARGIN_DIRECTION_KEYS).freeze
|
7
10
|
DIRECTION_KEY = :direction
|
8
11
|
JUSTIFY_CONTENT_KEY = :justify_content
|
9
12
|
ALIGN_ITEMS_KEY = :align_items
|
10
13
|
DISPLAY_KEY = :display
|
11
14
|
RESPONSIVE_KEYS = ([DISPLAY_KEY, DIRECTION_KEY, JUSTIFY_CONTENT_KEY, ALIGN_ITEMS_KEY, :col, :float] + SPACING_KEYS).freeze
|
12
|
-
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"]
|
15
|
+
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
13
16
|
|
14
17
|
# Keys where we can simply translate { key: value } into ".key-value"
|
15
|
-
CONCAT_KEYS = SPACING_KEYS + [
|
18
|
+
CONCAT_KEYS = SPACING_KEYS + %i[hide position v float col text box_shadow].freeze
|
16
19
|
|
17
20
|
INVALID_CLASS_NAME_PREFIXES =
|
18
21
|
(["bg-", "color-", "text-", "d-", "v-align-", "wb-", "text-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
|
22
|
+
FUNCTIONAL_COLOR_REGEX = /(primary|secondary|tertiary|link|success|warning|danger|info)/.freeze
|
19
23
|
|
20
24
|
COLOR_KEY = :color
|
21
25
|
BG_KEY = :bg
|
22
26
|
VERTICAL_ALIGN_KEY = :vertical_align
|
23
27
|
WORD_BREAK_KEY = :word_break
|
24
|
-
TEXT_KEYS = [
|
28
|
+
TEXT_KEYS = %i[text_align font_weight].freeze
|
25
29
|
FLEX_KEY = :flex
|
26
30
|
FLEX_GROW_KEY = :flex_grow
|
27
31
|
FLEX_SHRINK_KEY = :flex_shrink
|
@@ -30,19 +34,20 @@ module Primer
|
|
30
34
|
HEIGHT_KEY = :height
|
31
35
|
BOX_SHADOW_KEY = :box_shadow
|
32
36
|
VISIBILITY_KEY = :visibility
|
37
|
+
ANIMATION_KEY = :animation
|
33
38
|
|
34
39
|
BOOLEAN_MAPPINGS = {
|
35
40
|
underline: {
|
36
41
|
mappings: [
|
37
42
|
{
|
38
43
|
value: true,
|
39
|
-
css_class: "text-underline"
|
44
|
+
css_class: "text-underline"
|
40
45
|
},
|
41
46
|
{
|
42
47
|
value: false,
|
43
|
-
css_class: "no-underline"
|
44
|
-
}
|
45
|
-
]
|
48
|
+
css_class: "no-underline"
|
49
|
+
}
|
50
|
+
]
|
46
51
|
},
|
47
52
|
top: {
|
48
53
|
mappings: [
|
@@ -77,8 +82,9 @@ module Primer
|
|
77
82
|
]
|
78
83
|
}
|
79
84
|
}.freeze
|
80
|
-
BORDER_KEYS = [
|
81
|
-
BORDER_MARGIN_KEYS = [
|
85
|
+
BORDER_KEYS = %i[border border_color].freeze
|
86
|
+
BORDER_MARGIN_KEYS = %i[border_top border_bottom border_left border_right].freeze
|
87
|
+
BORDER_RADIUS_KEY = :border_radius
|
82
88
|
TYPOGRAPHY_KEYS = [:font_size].freeze
|
83
89
|
VALID_KEYS = (
|
84
90
|
CONCAT_KEYS +
|
@@ -88,6 +94,7 @@ module Primer
|
|
88
94
|
TYPOGRAPHY_KEYS +
|
89
95
|
TEXT_KEYS +
|
90
96
|
[
|
97
|
+
BORDER_RADIUS_KEY,
|
91
98
|
COLOR_KEY,
|
92
99
|
BG_KEY,
|
93
100
|
DISPLAY_KEY,
|
@@ -103,7 +110,8 @@ module Primer
|
|
103
110
|
WIDTH_KEY,
|
104
111
|
HEIGHT_KEY,
|
105
112
|
BOX_SHADOW_KEY,
|
106
|
-
VISIBILITY_KEY
|
113
|
+
VISIBILITY_KEY,
|
114
|
+
ANIMATION_KEY
|
107
115
|
]
|
108
116
|
).freeze
|
109
117
|
|
@@ -111,30 +119,31 @@ module Primer
|
|
111
119
|
def call(classes: "", style: nil, **args)
|
112
120
|
extracted_results = extract_hash(args)
|
113
121
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
122
|
+
extracted_results[:class] = [
|
123
|
+
validated_class_names(classes),
|
124
|
+
extracted_results.delete(:classes)
|
125
|
+
].compact.join(" ").presence
|
126
|
+
|
127
|
+
extracted_results[:style] = [
|
128
|
+
extracted_results.delete(:styles),
|
129
|
+
style
|
130
|
+
].compact.join("").presence
|
131
|
+
|
132
|
+
extracted_results
|
118
133
|
end
|
119
134
|
|
120
135
|
private
|
121
136
|
|
122
137
|
def validated_class_names(classes)
|
123
|
-
return
|
138
|
+
return if classes.blank?
|
124
139
|
|
125
140
|
if ENV["RAILS_ENV"] == "development"
|
126
141
|
invalid_class_names =
|
127
142
|
classes.split(" ").each_with_object([]) do |class_name, memo|
|
128
|
-
if INVALID_CLASS_NAME_PREFIXES.any? { |prefix| class_name.start_with?(prefix) }
|
129
|
-
memo << class_name
|
130
|
-
end
|
143
|
+
memo << class_name if INVALID_CLASS_NAME_PREFIXES.any? { |prefix| class_name.start_with?(prefix) }
|
131
144
|
end
|
132
145
|
|
133
|
-
if invalid_class_names.any?
|
134
|
-
raise ArgumentError.new(
|
135
|
-
"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.",
|
136
|
-
)
|
137
|
-
end
|
146
|
+
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." if invalid_class_names.any?
|
138
147
|
end
|
139
148
|
|
140
149
|
classes
|
@@ -152,99 +161,122 @@ module Primer
|
|
152
161
|
# Example usage:
|
153
162
|
# extract_hash({ mt: 4, py: 2 }) => "mt-4 py-2"
|
154
163
|
def extract_hash(styles_hash)
|
155
|
-
|
164
|
+
memo = { classes: [], styles: +"" }
|
165
|
+
styles_hash.each do |key, value|
|
156
166
|
next unless VALID_KEYS.include?(key)
|
157
167
|
|
158
|
-
if value.is_a?(Array)
|
159
|
-
raise ArgumentError, "#{key} does not support responsive values"
|
168
|
+
if value.is_a?(Array)
|
169
|
+
raise ArgumentError, "#{key} does not support responsive values" unless RESPONSIVE_KEYS.include?(key)
|
170
|
+
|
171
|
+
value.each_with_index do |val, index|
|
172
|
+
Primer::Classify::Cache.read(memo, key, val, BREAKPOINTS[index]) || extract_value(memo, key, val, BREAKPOINTS[index])
|
173
|
+
end
|
174
|
+
else
|
175
|
+
Primer::Classify::Cache.read(memo, key, value, BREAKPOINTS[0]) || extract_value(memo, key, value, BREAKPOINTS[0])
|
160
176
|
end
|
177
|
+
end
|
161
178
|
|
162
|
-
|
163
|
-
next if val.nil?
|
179
|
+
memo[:classes] = memo[:classes].join(" ")
|
164
180
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
181
|
+
memo
|
182
|
+
end
|
183
|
+
|
184
|
+
def extract_value(memo, key, val, breakpoint)
|
185
|
+
return if val.nil? || val == ""
|
186
|
+
|
187
|
+
if SPACING_KEYS.include?(key)
|
188
|
+
if MARGIN_DIRECTION_KEYS.include?(key)
|
189
|
+
raise ArgumentError, "value of #{key} must be between -6 and 6" if val < -6 || val > 6
|
190
|
+
elsif !((key == :mx || key == :my) && val == :auto)
|
191
|
+
raise ArgumentError, "value of #{key} must be between 0 and 6" if val.negative? || val > 6
|
192
|
+
end
|
193
|
+
end
|
172
194
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
memo[:classes] << "text-#{dasherized_val}"
|
191
|
-
end
|
192
|
-
elsif key == DISPLAY_KEY
|
193
|
-
memo[:classes] << "d#{breakpoint}-#{dasherized_val}"
|
194
|
-
elsif key == VERTICAL_ALIGN_KEY
|
195
|
-
memo[:classes] << "v-align-#{dasherized_val}"
|
196
|
-
elsif key == WORD_BREAK_KEY
|
197
|
-
memo[:classes] << "wb-#{dasherized_val}"
|
198
|
-
elsif BORDER_KEYS.include?(key)
|
199
|
-
memo[:classes] << "border-#{dasherized_val}"
|
200
|
-
elsif BORDER_MARGIN_KEYS.include?(key)
|
201
|
-
memo[:classes] << "#{key.to_s.dasherize}-#{val}"
|
202
|
-
elsif key == DIRECTION_KEY
|
203
|
-
memo[:classes] << "flex#{breakpoint}-#{dasherized_val}"
|
204
|
-
elsif key == JUSTIFY_CONTENT_KEY
|
205
|
-
formatted_value = val.to_s.gsub(/(flex\_|space\_)/, "")
|
206
|
-
memo[:classes] << "flex#{breakpoint}-justify-#{formatted_value}"
|
207
|
-
elsif key == ALIGN_ITEMS_KEY
|
208
|
-
memo[:classes] << "flex#{breakpoint}-items-#{val.to_s.gsub("flex_", "")}"
|
209
|
-
elsif key == FLEX_KEY
|
210
|
-
memo[:classes] << "flex-#{val}"
|
211
|
-
elsif key == FLEX_GROW_KEY
|
212
|
-
memo[:classes] << "flex-grow-#{val}"
|
213
|
-
elsif key == FLEX_SHRINK_KEY
|
214
|
-
memo[:classes] << "flex-shrink-#{val}"
|
215
|
-
elsif key == ALIGN_SELF_KEY
|
216
|
-
memo[:classes] << "flex-self-#{val}"
|
217
|
-
elsif key == WIDTH_KEY || key == HEIGHT_KEY
|
218
|
-
if val == :fit || val == :fill
|
219
|
-
memo[:classes] << "#{key}-#{val}"
|
220
|
-
else
|
221
|
-
memo[key] = val
|
222
|
-
end
|
223
|
-
elsif TEXT_KEYS.include?(key)
|
224
|
-
memo[:classes] << "text-#{dasherized_val}"
|
225
|
-
elsif TYPOGRAPHY_KEYS.include?(key)
|
226
|
-
memo[:classes] << "f#{dasherized_val}"
|
227
|
-
elsif MARGIN_DIRECTION_KEYS.include?(key) && val < 0
|
228
|
-
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-n#{val.abs}"
|
229
|
-
elsif key == BOX_SHADOW_KEY
|
230
|
-
if val == true
|
231
|
-
memo[:classes] << "box-shadow"
|
232
|
-
else
|
233
|
-
memo[:classes] << "box-shadow-#{dasherized_val}"
|
234
|
-
end
|
235
|
-
elsif key == VISIBILITY_KEY
|
236
|
-
memo[:classes] << "v-#{dasherized_val}"
|
195
|
+
if BOOLEAN_MAPPINGS.key?(key)
|
196
|
+
BOOLEAN_MAPPINGS[key][:mappings].map { |m| m[:css_class] if m[:value] == val }.compact.each do |css_class|
|
197
|
+
memo[:classes] << css_class
|
198
|
+
end
|
199
|
+
elsif key == BG_KEY
|
200
|
+
if val.to_s.start_with?("#")
|
201
|
+
memo[:styles] << "background-color: #{val};"
|
202
|
+
else
|
203
|
+
memo[:classes] << "bg-#{val.to_s.dasherize}"
|
204
|
+
end
|
205
|
+
elsif key == COLOR_KEY
|
206
|
+
char_code = val[-1].ord
|
207
|
+
# Does this string end in a character that is NOT a number?
|
208
|
+
memo[:classes] <<
|
209
|
+
if (char_code >= 48 && char_code <= 57) || # 48 is the charcode for 0; 57 is the charcode for 9
|
210
|
+
FUNCTIONAL_COLOR_REGEX.match?(val)
|
211
|
+
"color-#{val.to_s.dasherize}"
|
237
212
|
else
|
238
|
-
|
213
|
+
"text-#{val.to_s.dasherize}"
|
239
214
|
end
|
215
|
+
elsif key == DISPLAY_KEY
|
216
|
+
memo[:classes] << "d#{breakpoint}-#{val.to_s.dasherize}"
|
217
|
+
elsif key == VERTICAL_ALIGN_KEY
|
218
|
+
memo[:classes] << "v-align-#{val.to_s.dasherize}"
|
219
|
+
elsif key == WORD_BREAK_KEY
|
220
|
+
memo[:classes] << "wb-#{val.to_s.dasherize}"
|
221
|
+
elsif BORDER_KEYS.include?(key)
|
222
|
+
border_value = if val == true
|
223
|
+
"border"
|
224
|
+
else
|
225
|
+
"border-#{val.to_s.dasherize}"
|
226
|
+
end
|
227
|
+
|
228
|
+
memo[:classes] << border_value
|
229
|
+
elsif BORDER_MARGIN_KEYS.include?(key)
|
230
|
+
memo[:classes] << "#{key.to_s.dasherize}-#{val}"
|
231
|
+
elsif key == BORDER_RADIUS_KEY
|
232
|
+
memo[:classes] << "rounded-#{val}"
|
233
|
+
elsif key == DIRECTION_KEY
|
234
|
+
memo[:classes] << "flex#{breakpoint}-#{val.to_s.dasherize}"
|
235
|
+
elsif key == JUSTIFY_CONTENT_KEY
|
236
|
+
formatted_value = val.to_s.gsub(/(flex\_|space\_)/, "")
|
237
|
+
memo[:classes] << "flex#{breakpoint}-justify-#{formatted_value}"
|
238
|
+
elsif key == ALIGN_ITEMS_KEY
|
239
|
+
memo[:classes] << "flex#{breakpoint}-items-#{val.to_s.gsub('flex_', '')}"
|
240
|
+
elsif key == FLEX_KEY
|
241
|
+
memo[:classes] << "flex-#{val}"
|
242
|
+
elsif key == FLEX_GROW_KEY
|
243
|
+
memo[:classes] << "flex-grow-#{val}"
|
244
|
+
elsif key == FLEX_SHRINK_KEY
|
245
|
+
memo[:classes] << "flex-shrink-#{val}"
|
246
|
+
elsif key == ALIGN_SELF_KEY
|
247
|
+
memo[:classes] << "flex-self-#{val}"
|
248
|
+
elsif key == WIDTH_KEY || key == HEIGHT_KEY
|
249
|
+
if val == :fit || val == :fill
|
250
|
+
memo[:classes] << "#{key}-#{val}"
|
251
|
+
else
|
252
|
+
memo[key] = val
|
240
253
|
end
|
254
|
+
elsif TEXT_KEYS.include?(key)
|
255
|
+
memo[:classes] << "text-#{val.to_s.dasherize}"
|
256
|
+
elsif TYPOGRAPHY_KEYS.include?(key)
|
257
|
+
memo[:classes] << "f#{val.to_s.dasherize}"
|
258
|
+
elsif MARGIN_DIRECTION_KEYS.include?(key) && val.negative?
|
259
|
+
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-n#{val.abs}"
|
260
|
+
elsif key == BOX_SHADOW_KEY
|
261
|
+
memo[:classes] << if val == true
|
262
|
+
"box-shadow"
|
263
|
+
else
|
264
|
+
"box-shadow-#{val.to_s.dasherize}"
|
265
|
+
end
|
266
|
+
elsif key == VISIBILITY_KEY
|
267
|
+
memo[:classes] << "v-#{val.to_s.dasherize}"
|
268
|
+
elsif key == ANIMATION_KEY
|
269
|
+
memo[:classes] << if val == :grow
|
270
|
+
"hover-grow"
|
271
|
+
else
|
272
|
+
"anim-#{val.to_s.dasherize}"
|
273
|
+
end
|
274
|
+
else
|
275
|
+
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-#{val.to_s.dasherize}"
|
241
276
|
end
|
242
|
-
|
243
|
-
{
|
244
|
-
classes: out[:classes].join(" "),
|
245
|
-
styles: out[:styles].join(" ")
|
246
|
-
}.merge(out.except(:classes, :styles))
|
247
277
|
end
|
248
278
|
end
|
279
|
+
|
280
|
+
Cache.preload!
|
249
281
|
end
|
250
282
|
end
|