primer_view_components 0.0.1 → 0.0.7
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 +92 -2
- data/README.md +149 -0
- data/app/components/primer/avatar_component.rb +28 -0
- data/app/components/primer/base_component.rb +42 -0
- data/app/components/primer/blankslate_component.html.erb +27 -0
- data/app/components/primer/blankslate_component.rb +164 -0
- data/app/components/primer/border_box_component.html.erb +26 -0
- data/app/components/primer/border_box_component.rb +77 -0
- data/app/components/primer/box_component.rb +14 -0
- data/app/components/primer/breadcrumb_component.html.erb +8 -0
- data/app/components/primer/breadcrumb_component.rb +52 -0
- data/app/components/primer/button_component.rb +58 -0
- data/app/components/primer/component.rb +9 -0
- data/app/components/primer/counter_component.rb +85 -0
- data/app/components/primer/details_component.html.erb +8 -0
- data/app/components/primer/details_component.rb +63 -0
- data/app/components/primer/dropdown_menu_component.html.erb +8 -0
- data/app/components/primer/dropdown_menu_component.rb +28 -0
- data/app/components/primer/flex_component.rb +81 -0
- data/app/components/primer/flex_item_component.rb +21 -0
- data/app/components/primer/heading_component.rb +14 -0
- data/app/components/primer/label_component.rb +48 -0
- data/app/components/primer/layout_component.html.erb +17 -0
- data/app/components/primer/layout_component.rb +28 -0
- data/app/components/primer/link_component.rb +19 -0
- data/app/components/primer/popover_component.html.erb +10 -0
- data/app/components/primer/popover_component.rb +75 -0
- data/app/components/primer/progress_bar_component.html.erb +5 -0
- data/app/components/primer/progress_bar_component.rb +66 -0
- data/app/components/primer/slot.rb +8 -0
- data/app/components/primer/state_component.rb +53 -0
- data/app/components/primer/subhead_component.html.erb +17 -0
- data/app/components/primer/subhead_component.rb +89 -0
- data/app/components/primer/text_component.rb +14 -0
- data/app/components/primer/timeline_item_component.html.erb +17 -0
- data/app/components/primer/timeline_item_component.rb +69 -0
- data/app/components/primer/underline_nav_component.html.erb +11 -0
- data/app/components/primer/underline_nav_component.rb +22 -0
- data/app/components/primer/view_components.rb +48 -0
- data/lib/primer/class_name_helper.rb +27 -0
- data/lib/primer/classify.rb +245 -0
- data/lib/primer/fetch_or_fallback_helper.rb +41 -0
- data/lib/primer/view_components.rb +3 -0
- data/lib/primer/view_components/engine.rb +11 -0
- data/lib/primer/view_components/version.rb +1 -1
- metadata +203 -4
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= render Primer::BaseComponent.new(**@kwargs) do %>
|
2
|
+
<% if heading.present? %>
|
3
|
+
<%= render Primer::BaseComponent.new(**heading.kwargs) do %>
|
4
|
+
<%= heading.content %>
|
5
|
+
<% end %>
|
6
|
+
<% end %>
|
7
|
+
<% if actions.present? %>
|
8
|
+
<%= render Primer::BaseComponent.new(**actions.kwargs) do %>
|
9
|
+
<%= actions.content %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% if description.present? %>
|
13
|
+
<%= render Primer::BaseComponent.new(**description.kwargs) do %>
|
14
|
+
<%= description.content %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This component consists of a .Subhead container, which has a light gray bottom border.
|
4
|
+
|
5
|
+
# Use a heading element whenever possible as they can be
|
6
|
+
# used as navigation for assistive technologies, and avoid skipping levels.
|
7
|
+
|
8
|
+
# ## Basic example
|
9
|
+
|
10
|
+
# The `Primer::SubheadComponent` can take the following arguments:
|
11
|
+
|
12
|
+
# 1. `heading` (string). The heading to be rendered.
|
13
|
+
# 2. `actions` (content). Slot to render any actions to the right of heading.
|
14
|
+
# 3. `description` (string). Slot to render description under the heading.
|
15
|
+
|
16
|
+
# ```erb
|
17
|
+
# <%= Primer::SubheadComponent.new(heading: "Hello world")) do |component| %>
|
18
|
+
# <% component.slot(:actions) do %>
|
19
|
+
# My Actions
|
20
|
+
# <% end %>
|
21
|
+
# <% end %>
|
22
|
+
# ```
|
23
|
+
module Primer
|
24
|
+
class SubheadComponent < Primer::Component
|
25
|
+
include ViewComponent::Slotable
|
26
|
+
|
27
|
+
with_slot :heading, class_name: "Heading"
|
28
|
+
with_slot :actions, class_name: "Actions"
|
29
|
+
with_slot :description, class_name: "Description"
|
30
|
+
|
31
|
+
def initialize(spacious: false, hide_border: false, **kwargs)
|
32
|
+
@kwargs = kwargs
|
33
|
+
|
34
|
+
@kwargs[:tag] = :div
|
35
|
+
@kwargs[:classes] =
|
36
|
+
class_names(
|
37
|
+
@kwargs[:classes],
|
38
|
+
"Subhead hx_Subhead--responsive",
|
39
|
+
"Subhead--spacious": spacious,
|
40
|
+
"border-bottom-0": hide_border
|
41
|
+
)
|
42
|
+
@kwargs[:mb] ||= hide_border ? 0 : nil
|
43
|
+
end
|
44
|
+
|
45
|
+
def render?
|
46
|
+
heading.present?
|
47
|
+
end
|
48
|
+
|
49
|
+
class Heading < ViewComponent::Slot
|
50
|
+
include ClassNameHelper
|
51
|
+
|
52
|
+
attr_reader :kwargs
|
53
|
+
|
54
|
+
def initialize(danger: false, **kwargs)
|
55
|
+
@kwargs = kwargs
|
56
|
+
@kwargs[:tag] ||= :div
|
57
|
+
@kwargs[:classes] = class_names(
|
58
|
+
@kwargs[:classes],
|
59
|
+
"Subhead-heading",
|
60
|
+
"Subhead-heading--danger": danger
|
61
|
+
)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Actions < ViewComponent::Slot
|
66
|
+
include ClassNameHelper
|
67
|
+
|
68
|
+
attr_reader :kwargs
|
69
|
+
|
70
|
+
def initialize(**kwargs)
|
71
|
+
@kwargs = kwargs
|
72
|
+
@kwargs[:tag] = :div
|
73
|
+
@kwargs[:classes] = class_names(@kwargs[:classes], "Subhead-actions")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class Description < ViewComponent::Slot
|
78
|
+
include ClassNameHelper
|
79
|
+
|
80
|
+
attr_reader :kwargs
|
81
|
+
|
82
|
+
def initialize(**kwargs)
|
83
|
+
@kwargs = kwargs
|
84
|
+
@kwargs[:tag] = :div
|
85
|
+
@kwargs[:classes] = class_names(@kwargs[:classes], "Subhead-description")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
class TextComponent < Primer::Component
|
5
|
+
def initialize(**kwargs)
|
6
|
+
@kwargs = kwargs
|
7
|
+
@kwargs[:tag] ||= :span
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
render(Primer::BaseComponent.new(**@kwargs)) { content }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<%= render Primer::BaseComponent.new(**kwargs) do %>
|
2
|
+
<% if avatar %>
|
3
|
+
<%= render Primer::AvatarComponent.new(alt: avatar.alt, src: avatar.src, size: avatar.size, square: avatar.square, **avatar.kwargs) %>
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<% if badge %>
|
7
|
+
<%= render Primer::BaseComponent.new(**badge.kwargs) do %>
|
8
|
+
<%= octicon badge.icon %>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<% if body %>
|
13
|
+
<%= render Primer::BaseComponent.new(**body.kwargs) do %>
|
14
|
+
<%= body.content %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
class TimelineItemComponent < Primer::Component
|
5
|
+
include ViewComponent::Slotable
|
6
|
+
|
7
|
+
with_slot :avatar, class_name: "Avatar"
|
8
|
+
with_slot :badge, class_name: "Badge"
|
9
|
+
with_slot :body, class_name: "Body"
|
10
|
+
|
11
|
+
attr_reader :kwargs
|
12
|
+
def initialize(condensed: false, **kwargs)
|
13
|
+
@kwargs = kwargs
|
14
|
+
@kwargs[:tag] = :div
|
15
|
+
@kwargs[:classes] = class_names(
|
16
|
+
"TimelineItem",
|
17
|
+
condensed ? "TimelineItem--condensed" : "",
|
18
|
+
kwargs[:classes]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def render?
|
23
|
+
avatar.present? || badge.present? || body.present?
|
24
|
+
end
|
25
|
+
|
26
|
+
class Avatar < Primer::Slot
|
27
|
+
attr_reader :kwargs, :alt, :src, :size, :square
|
28
|
+
def initialize(alt: nil, src: nil, size: 40, square: true, **kwargs)
|
29
|
+
@alt = alt
|
30
|
+
@src = src
|
31
|
+
@size = size
|
32
|
+
@square = square
|
33
|
+
|
34
|
+
@kwargs = kwargs
|
35
|
+
@kwargs[:tag] = :div
|
36
|
+
@kwargs[:classes] = class_names(
|
37
|
+
"TimelineItem-avatar",
|
38
|
+
kwargs[:classes]
|
39
|
+
)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class Badge < Primer::Slot
|
44
|
+
attr_reader :kwargs, :icon
|
45
|
+
def initialize(icon: nil, **kwargs)
|
46
|
+
@icon = icon
|
47
|
+
|
48
|
+
@kwargs = kwargs
|
49
|
+
@kwargs[:tag] = :div
|
50
|
+
@kwargs[:classes] = class_names(
|
51
|
+
"TimelineItem-badge",
|
52
|
+
kwargs[:classes]
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Body < Primer::Slot
|
58
|
+
attr_reader :kwargs
|
59
|
+
def initialize(**kwargs)
|
60
|
+
@kwargs = kwargs
|
61
|
+
@kwargs[:tag] = :div
|
62
|
+
@kwargs[:classes] = class_names(
|
63
|
+
"TimelineItem-body",
|
64
|
+
kwargs[:classes]
|
65
|
+
)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%= render Primer::BaseComponent.new(**@kwargs) do %>
|
2
|
+
<% if actions && @align == :right %>
|
3
|
+
<%= actions %>
|
4
|
+
<% end %>
|
5
|
+
<%= render Primer::BaseComponent.new(tag: :ul, classes: "UnderlineNav-body list-style-none") do %>
|
6
|
+
<%= body %>
|
7
|
+
<% end %>
|
8
|
+
<% if actions && @align == :left %>
|
9
|
+
<%= actions %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
class UnderlineNavComponent < Primer::Component
|
5
|
+
ALIGN_DEFAULT = :left
|
6
|
+
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right]
|
7
|
+
|
8
|
+
with_content_areas :body, :actions
|
9
|
+
|
10
|
+
def initialize(align: ALIGN_DEFAULT, **kwargs)
|
11
|
+
@align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
|
12
|
+
|
13
|
+
@kwargs = kwargs
|
14
|
+
@kwargs[:tag] = :nav
|
15
|
+
@kwargs[:classes] = class_names(
|
16
|
+
@kwargs[:classes],
|
17
|
+
"UnderlineNav",
|
18
|
+
"UnderlineNav--right" => @align == :right
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext"
|
4
|
+
|
5
|
+
# ViewComponent
|
6
|
+
|
7
|
+
require "view_component/engine"
|
8
|
+
|
9
|
+
# Octicons
|
10
|
+
|
11
|
+
require "octicons_helper/helper"
|
12
|
+
|
13
|
+
# Helpers
|
14
|
+
|
15
|
+
require "primer/class_name_helper"
|
16
|
+
require "primer/classify"
|
17
|
+
require "primer/fetch_or_fallback_helper"
|
18
|
+
|
19
|
+
# Base configurations
|
20
|
+
|
21
|
+
require_relative "component"
|
22
|
+
require_relative "base_component"
|
23
|
+
require_relative "slot"
|
24
|
+
|
25
|
+
# Components
|
26
|
+
|
27
|
+
require_relative "avatar_component"
|
28
|
+
require_relative "blankslate_component"
|
29
|
+
require_relative "border_box_component"
|
30
|
+
require_relative "box_component"
|
31
|
+
require_relative "breadcrumb_component"
|
32
|
+
require_relative "button_component"
|
33
|
+
require_relative "counter_component"
|
34
|
+
require_relative "details_component"
|
35
|
+
require_relative "dropdown_menu_component"
|
36
|
+
require_relative "flex_component"
|
37
|
+
require_relative "flex_item_component"
|
38
|
+
require_relative "heading_component"
|
39
|
+
require_relative "label_component"
|
40
|
+
require_relative "layout_component"
|
41
|
+
require_relative "link_component"
|
42
|
+
require_relative "popover_component"
|
43
|
+
require_relative "progress_bar_component"
|
44
|
+
require_relative "state_component"
|
45
|
+
require_relative "subhead_component"
|
46
|
+
require_relative "text_component"
|
47
|
+
require_relative "timeline_item_component"
|
48
|
+
require_relative "underline_nav_component"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Inspired by https://github.com/JedWatson/classnames
|
4
|
+
#
|
5
|
+
# Helps build a list of conditional class names
|
6
|
+
module Primer
|
7
|
+
module ClassNameHelper
|
8
|
+
def class_names(*args)
|
9
|
+
classes = []
|
10
|
+
|
11
|
+
args.each do |class_name|
|
12
|
+
case class_name
|
13
|
+
when String
|
14
|
+
classes << class_name if class_name.present?
|
15
|
+
when Hash
|
16
|
+
class_name.each do |key, val|
|
17
|
+
classes << key if val
|
18
|
+
end
|
19
|
+
when Array
|
20
|
+
classes << class_names(*class_name).presence
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
classes.compact.uniq.join(" ")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,245 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
class Classify
|
5
|
+
MARGIN_DIRECTION_KEYS = [:mt, :ml, :mb, :mr]
|
6
|
+
SPACING_KEYS = ([:m, :my, :mx, :p, :py, :px, :pt, :pl, :pb, :pr] + MARGIN_DIRECTION_KEYS).freeze
|
7
|
+
DIRECTION_KEY = :direction
|
8
|
+
JUSTIFY_CONTENT_KEY = :justify_content
|
9
|
+
ALIGN_ITEMS_KEY = :align_items
|
10
|
+
DISPLAY_KEY = :display
|
11
|
+
RESPONSIVE_KEYS = ([DISPLAY_KEY, DIRECTION_KEY, JUSTIFY_CONTENT_KEY, ALIGN_ITEMS_KEY, :col, :float] + SPACING_KEYS).freeze
|
12
|
+
BREAKPOINTS = ["", "-sm", "-md", "-lg"]
|
13
|
+
|
14
|
+
# Keys where we can simply translate { key: value } into ".key-value"
|
15
|
+
CONCAT_KEYS = SPACING_KEYS + [:hide, :position, :v, :float, :col, :text, :box_shadow].freeze
|
16
|
+
|
17
|
+
INVALID_CLASS_NAME_PREFIXES =
|
18
|
+
(["bg-", "color-", "text-", "d-", "v-align-", "wb-", "text-", "box-shadow-"] + CONCAT_KEYS.map { |k| "#{k}-" }).freeze
|
19
|
+
|
20
|
+
COLOR_KEY = :color
|
21
|
+
BG_KEY = :bg
|
22
|
+
VERTICAL_ALIGN_KEY = :vertical_align
|
23
|
+
WORD_BREAK_KEY = :word_break
|
24
|
+
TEXT_KEYS = [:text_align, :font_weight]
|
25
|
+
FLEX_KEY = :flex
|
26
|
+
FLEX_GROW_KEY = :flex_grow
|
27
|
+
FLEX_SHRINK_KEY = :flex_shrink
|
28
|
+
ALIGN_SELF_KEY = :align_self
|
29
|
+
WIDTH_KEY = :width
|
30
|
+
HEIGHT_KEY = :height
|
31
|
+
BOX_SHADOW_KEY = :box_shadow
|
32
|
+
|
33
|
+
|
34
|
+
BOOLEAN_MAPPINGS = {
|
35
|
+
underline: {
|
36
|
+
mappings: [
|
37
|
+
{
|
38
|
+
value: true,
|
39
|
+
css_class: "text-underline",
|
40
|
+
},
|
41
|
+
{
|
42
|
+
value: false,
|
43
|
+
css_class: "no-underline",
|
44
|
+
},
|
45
|
+
],
|
46
|
+
},
|
47
|
+
top: {
|
48
|
+
mappings: [
|
49
|
+
{
|
50
|
+
value: false,
|
51
|
+
css_class: "top-0"
|
52
|
+
}
|
53
|
+
]
|
54
|
+
},
|
55
|
+
bottom: {
|
56
|
+
mappings: [
|
57
|
+
{
|
58
|
+
value: false,
|
59
|
+
css_class: "bottom-0"
|
60
|
+
}
|
61
|
+
]
|
62
|
+
},
|
63
|
+
left: {
|
64
|
+
mappings: [
|
65
|
+
{
|
66
|
+
value: false,
|
67
|
+
css_class: "left-0"
|
68
|
+
}
|
69
|
+
]
|
70
|
+
},
|
71
|
+
right: {
|
72
|
+
mappings: [
|
73
|
+
{
|
74
|
+
value: false,
|
75
|
+
css_class: "right-0"
|
76
|
+
}
|
77
|
+
]
|
78
|
+
}
|
79
|
+
}.freeze
|
80
|
+
BORDER_KEYS = [:border, :border_color].freeze
|
81
|
+
TYPOGRAPHY_KEYS = [:font_size].freeze
|
82
|
+
VALID_KEYS = (
|
83
|
+
CONCAT_KEYS +
|
84
|
+
BOOLEAN_MAPPINGS.keys +
|
85
|
+
BORDER_KEYS +
|
86
|
+
TYPOGRAPHY_KEYS +
|
87
|
+
TEXT_KEYS +
|
88
|
+
[
|
89
|
+
COLOR_KEY,
|
90
|
+
BG_KEY,
|
91
|
+
DISPLAY_KEY,
|
92
|
+
VERTICAL_ALIGN_KEY,
|
93
|
+
WORD_BREAK_KEY,
|
94
|
+
DIRECTION_KEY,
|
95
|
+
JUSTIFY_CONTENT_KEY,
|
96
|
+
ALIGN_ITEMS_KEY,
|
97
|
+
FLEX_KEY,
|
98
|
+
FLEX_GROW_KEY,
|
99
|
+
FLEX_SHRINK_KEY,
|
100
|
+
ALIGN_SELF_KEY,
|
101
|
+
WIDTH_KEY,
|
102
|
+
HEIGHT_KEY,
|
103
|
+
BOX_SHADOW_KEY
|
104
|
+
]
|
105
|
+
).freeze
|
106
|
+
|
107
|
+
class << self
|
108
|
+
def call(classes: "", style: nil, **args)
|
109
|
+
extracted_results = extract_hash(args)
|
110
|
+
|
111
|
+
{
|
112
|
+
class: [validated_class_names(classes), extracted_results[:classes]].compact.join(" ").presence,
|
113
|
+
style: [extracted_results[:styles], style].compact.join("").presence,
|
114
|
+
}.merge(extracted_results.except(:classes, :styles))
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def validated_class_names(classes)
|
120
|
+
return unless classes.present?
|
121
|
+
|
122
|
+
if ENV["RAILS_ENV"] == "development"
|
123
|
+
invalid_class_names =
|
124
|
+
classes.split(" ").each_with_object([]) do |class_name, memo|
|
125
|
+
if INVALID_CLASS_NAME_PREFIXES.any? { |prefix| class_name.start_with?(prefix) }
|
126
|
+
memo << class_name
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if invalid_class_names.any?
|
131
|
+
raise ArgumentError.new(
|
132
|
+
"Primer CSS class #{'name'.pluralize(invalid_class_names.length)} \
|
133
|
+
#{invalid_class_names.to_sentence} #{'is'.pluralize(invalid_class_names.length)} \
|
134
|
+
not allowed, use style arguments instead (https://github.com/primer/view_components#built-in-styling-arguments). This warning will not be raised in production.",
|
135
|
+
)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
classes
|
140
|
+
end
|
141
|
+
|
142
|
+
# NOTE: This is a fairly naive implementation that we're building as we go.
|
143
|
+
# Feel free to refactor as this is thoroughly tested.
|
144
|
+
#
|
145
|
+
# Utility for mapping component configuration into Primer CSS class names
|
146
|
+
#
|
147
|
+
# styles_hash - A hash with utility keys that mimic the interface used by https://github.com/primer/components
|
148
|
+
#
|
149
|
+
# Returns a string of Primer CSS class names to be added to an HTML class attribute
|
150
|
+
#
|
151
|
+
# Example usage:
|
152
|
+
# extract_hash({ mt: 4, py: 2 }) => "mt-4 py-2"
|
153
|
+
def extract_hash(styles_hash)
|
154
|
+
out = styles_hash.each_with_object({ classes: [], styles: [] }) do |(key, value), memo|
|
155
|
+
next unless VALID_KEYS.include?(key)
|
156
|
+
|
157
|
+
if value.is_a?(Array) && !RESPONSIVE_KEYS.include?(key)
|
158
|
+
raise ArgumentError, "#{key} does not support responsive values"
|
159
|
+
end
|
160
|
+
|
161
|
+
Array(value).each_with_index do |val, index|
|
162
|
+
next if val.nil?
|
163
|
+
|
164
|
+
if SPACING_KEYS.include?(key)
|
165
|
+
if MARGIN_DIRECTION_KEYS.include?(key)
|
166
|
+
raise ArgumentError, "value of #{key} must be between -6 and 6" if (val < -6 || val > 6)
|
167
|
+
elsif !((key == :mx || key == :my) && val == :auto)
|
168
|
+
raise ArgumentError, "value of #{key} must be between 0 and 6" if (val < 0 || val > 6)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
dasherized_val = val.to_s.dasherize
|
173
|
+
breakpoint = BREAKPOINTS[index]
|
174
|
+
|
175
|
+
if BOOLEAN_MAPPINGS.has_key?(key)
|
176
|
+
BOOLEAN_MAPPINGS[key][:mappings].map { |m| m[:css_class] if m[:value] == val }.compact.each do |css_class|
|
177
|
+
memo[:classes] << css_class
|
178
|
+
end
|
179
|
+
elsif key == BG_KEY
|
180
|
+
if val.to_s.starts_with?("#")
|
181
|
+
memo[:styles] << "background-color: #{val};"
|
182
|
+
else
|
183
|
+
memo[:classes] << "bg-#{dasherized_val}"
|
184
|
+
end
|
185
|
+
elsif key == COLOR_KEY
|
186
|
+
if val.to_s.chars.last !~ /\D/
|
187
|
+
memo[:classes] << "color-#{dasherized_val}"
|
188
|
+
else
|
189
|
+
memo[:classes] << "text-#{dasherized_val}"
|
190
|
+
end
|
191
|
+
elsif key == DISPLAY_KEY
|
192
|
+
memo[:classes] << "d#{breakpoint}-#{dasherized_val}"
|
193
|
+
elsif key == VERTICAL_ALIGN_KEY
|
194
|
+
memo[:classes] << "v-align-#{dasherized_val}"
|
195
|
+
elsif key == WORD_BREAK_KEY
|
196
|
+
memo[:classes] << "wb-#{dasherized_val}"
|
197
|
+
elsif BORDER_KEYS.include?(key)
|
198
|
+
memo[:classes] << "border-#{dasherized_val}"
|
199
|
+
elsif key == DIRECTION_KEY
|
200
|
+
memo[:classes] << "flex#{breakpoint}-#{dasherized_val}"
|
201
|
+
elsif key == JUSTIFY_CONTENT_KEY
|
202
|
+
formatted_value = val.to_s.gsub(/(flex\_|space\_)/, "")
|
203
|
+
memo[:classes] << "flex#{breakpoint}-justify-#{formatted_value}"
|
204
|
+
elsif key == ALIGN_ITEMS_KEY
|
205
|
+
memo[:classes] << "flex#{breakpoint}-items-#{val.to_s.gsub("flex_", "")}"
|
206
|
+
elsif key == FLEX_KEY
|
207
|
+
memo[:classes] << "flex-#{val}"
|
208
|
+
elsif key == FLEX_GROW_KEY
|
209
|
+
memo[:classes] << "flex-grow-#{val}"
|
210
|
+
elsif key == FLEX_SHRINK_KEY
|
211
|
+
memo[:classes] << "flex-shrink-#{val}"
|
212
|
+
elsif key == ALIGN_SELF_KEY
|
213
|
+
memo[:classes] << "flex-self-#{val}"
|
214
|
+
elsif key == WIDTH_KEY || key == HEIGHT_KEY
|
215
|
+
if val == :fit || val == :fill
|
216
|
+
memo[:classes] << "#{key}-#{val}"
|
217
|
+
else
|
218
|
+
memo[key] = val
|
219
|
+
end
|
220
|
+
elsif TEXT_KEYS.include?(key)
|
221
|
+
memo[:classes] << "text-#{dasherized_val}"
|
222
|
+
elsif TYPOGRAPHY_KEYS.include?(key)
|
223
|
+
memo[:classes] << "f#{dasherized_val}"
|
224
|
+
elsif MARGIN_DIRECTION_KEYS.include?(key) && val < 0
|
225
|
+
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-n#{val.abs}"
|
226
|
+
elsif key == BOX_SHADOW_KEY
|
227
|
+
if val == true
|
228
|
+
memo[:classes] << "box-shadow"
|
229
|
+
else
|
230
|
+
memo[:classes] << "box-shadow-#{dasherized_val}"
|
231
|
+
end
|
232
|
+
else
|
233
|
+
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-#{dasherized_val}"
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
{
|
239
|
+
classes: out[:classes].join(" "),
|
240
|
+
styles: out[:styles].join(" ")
|
241
|
+
}.merge(out.except(:classes, :styles))
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|