primer_view_components 0.0.17 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +102 -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 +8 -5
- data/app/components/primer/blankslate_component.html.erb +3 -3
- data/app/components/primer/blankslate_component.rb +18 -25
- data/app/components/primer/border_box_component.html.erb +4 -18
- data/app/components/primer/border_box_component.rb +75 -68
- 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 +16 -0
- data/app/components/primer/counter_component.rb +16 -9
- data/app/components/primer/details_component.html.erb +2 -6
- data/app/components/primer/details_component.rb +28 -37
- 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 +35 -3
- data/app/components/primer/flash_component.html.erb +4 -7
- data/app/components/primer/flash_component.rb +18 -17
- 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 +9 -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 +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 +13 -6
- data/app/components/primer/popover_component.rb +5 -3
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/components/primer/progress_bar_component.rb +6 -6
- data/app/components/primer/spinner_component.rb +8 -5
- data/app/components/primer/state_component.rb +23 -12
- data/app/components/primer/subhead_component.rb +6 -3
- 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 -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/{lib → app/lib}/primer/class_name_helper.rb +1 -0
- data/app/lib/primer/classify.rb +280 -0
- data/app/lib/primer/classify/cache.rb +125 -0
- data/{lib → app/lib}/primer/fetch_or_fallback_helper.rb +1 -0
- data/{lib → app/lib}/primer/join_style_arguments_helper.rb +1 -0
- 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 -0
- data/lib/primer/view_components/engine.rb +11 -2
- 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 +94 -24
- data/app/components/primer/view_components.rb +0 -52
- data/lib/primer/classify.rb +0 -250
@@ -1,52 +0,0 @@
|
|
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
|
-
require "primer/join_style_arguments_helper"
|
19
|
-
|
20
|
-
# Base configurations
|
21
|
-
|
22
|
-
require_relative "component"
|
23
|
-
require_relative "base_component"
|
24
|
-
require_relative "slot"
|
25
|
-
|
26
|
-
# Components
|
27
|
-
|
28
|
-
require_relative "avatar_component"
|
29
|
-
require_relative "blankslate_component"
|
30
|
-
require_relative "border_box_component"
|
31
|
-
require_relative "box_component"
|
32
|
-
require_relative "breadcrumb_component"
|
33
|
-
require_relative "button_component"
|
34
|
-
require_relative "counter_component"
|
35
|
-
require_relative "details_component"
|
36
|
-
require_relative "dropdown_menu_component"
|
37
|
-
require_relative "flash_component"
|
38
|
-
require_relative "flex_component"
|
39
|
-
require_relative "flex_item_component"
|
40
|
-
require_relative "heading_component"
|
41
|
-
require_relative "label_component"
|
42
|
-
require_relative "layout_component"
|
43
|
-
require_relative "link_component"
|
44
|
-
require_relative "octicon_component"
|
45
|
-
require_relative "popover_component"
|
46
|
-
require_relative "progress_bar_component"
|
47
|
-
require_relative "spinner_component"
|
48
|
-
require_relative "state_component"
|
49
|
-
require_relative "subhead_component"
|
50
|
-
require_relative "text_component"
|
51
|
-
require_relative "timeline_item_component"
|
52
|
-
require_relative "underline_nav_component"
|
data/lib/primer/classify.rb
DELETED
@@ -1,250 +0,0 @@
|
|
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", "-xl"]
|
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
|
-
VISIBILITY_KEY = :visibility
|
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
|
-
BORDER_MARGIN_KEYS = [:border_top, :border_bottom, :border_left, :border_right].freeze
|
82
|
-
TYPOGRAPHY_KEYS = [:font_size].freeze
|
83
|
-
VALID_KEYS = (
|
84
|
-
CONCAT_KEYS +
|
85
|
-
BOOLEAN_MAPPINGS.keys +
|
86
|
-
BORDER_KEYS +
|
87
|
-
BORDER_MARGIN_KEYS +
|
88
|
-
TYPOGRAPHY_KEYS +
|
89
|
-
TEXT_KEYS +
|
90
|
-
[
|
91
|
-
COLOR_KEY,
|
92
|
-
BG_KEY,
|
93
|
-
DISPLAY_KEY,
|
94
|
-
VERTICAL_ALIGN_KEY,
|
95
|
-
WORD_BREAK_KEY,
|
96
|
-
DIRECTION_KEY,
|
97
|
-
JUSTIFY_CONTENT_KEY,
|
98
|
-
ALIGN_ITEMS_KEY,
|
99
|
-
FLEX_KEY,
|
100
|
-
FLEX_GROW_KEY,
|
101
|
-
FLEX_SHRINK_KEY,
|
102
|
-
ALIGN_SELF_KEY,
|
103
|
-
WIDTH_KEY,
|
104
|
-
HEIGHT_KEY,
|
105
|
-
BOX_SHADOW_KEY,
|
106
|
-
VISIBILITY_KEY
|
107
|
-
]
|
108
|
-
).freeze
|
109
|
-
|
110
|
-
class << self
|
111
|
-
def call(classes: "", style: nil, **args)
|
112
|
-
extracted_results = extract_hash(args)
|
113
|
-
|
114
|
-
{
|
115
|
-
class: [validated_class_names(classes), extracted_results[:classes]].compact.join(" ").presence,
|
116
|
-
style: [extracted_results[:styles], style].compact.join("").presence,
|
117
|
-
}.merge(extracted_results.except(:classes, :styles))
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def validated_class_names(classes)
|
123
|
-
return unless classes.present?
|
124
|
-
|
125
|
-
if ENV["RAILS_ENV"] == "development"
|
126
|
-
invalid_class_names =
|
127
|
-
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
|
131
|
-
end
|
132
|
-
|
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
|
138
|
-
end
|
139
|
-
|
140
|
-
classes
|
141
|
-
end
|
142
|
-
|
143
|
-
# NOTE: This is a fairly naive implementation that we're building as we go.
|
144
|
-
# Feel free to refactor as this is thoroughly tested.
|
145
|
-
#
|
146
|
-
# Utility for mapping component configuration into Primer CSS class names
|
147
|
-
#
|
148
|
-
# styles_hash - A hash with utility keys that mimic the interface used by https://github.com/primer/components
|
149
|
-
#
|
150
|
-
# Returns a string of Primer CSS class names to be added to an HTML class attribute
|
151
|
-
#
|
152
|
-
# Example usage:
|
153
|
-
# extract_hash({ mt: 4, py: 2 }) => "mt-4 py-2"
|
154
|
-
def extract_hash(styles_hash)
|
155
|
-
out = styles_hash.each_with_object({ classes: [], styles: [] }) do |(key, value), memo|
|
156
|
-
next unless VALID_KEYS.include?(key)
|
157
|
-
|
158
|
-
if value.is_a?(Array) && !RESPONSIVE_KEYS.include?(key)
|
159
|
-
raise ArgumentError, "#{key} does not support responsive values"
|
160
|
-
end
|
161
|
-
|
162
|
-
Array(value).each_with_index do |val, index|
|
163
|
-
next if val.nil?
|
164
|
-
|
165
|
-
if SPACING_KEYS.include?(key)
|
166
|
-
if MARGIN_DIRECTION_KEYS.include?(key)
|
167
|
-
raise ArgumentError, "value of #{key} must be between -6 and 6" if (val < -6 || val > 6)
|
168
|
-
elsif !((key == :mx || key == :my) && val == :auto)
|
169
|
-
raise ArgumentError, "value of #{key} must be between 0 and 6" if (val < 0 || val > 6)
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
dasherized_val = val.to_s.dasherize
|
174
|
-
breakpoint = BREAKPOINTS[index]
|
175
|
-
|
176
|
-
if BOOLEAN_MAPPINGS.has_key?(key)
|
177
|
-
BOOLEAN_MAPPINGS[key][:mappings].map { |m| m[:css_class] if m[:value] == val }.compact.each do |css_class|
|
178
|
-
memo[:classes] << css_class
|
179
|
-
end
|
180
|
-
elsif key == BG_KEY
|
181
|
-
if val.to_s.starts_with?("#")
|
182
|
-
memo[:styles] << "background-color: #{val};"
|
183
|
-
else
|
184
|
-
memo[:classes] << "bg-#{dasherized_val}"
|
185
|
-
end
|
186
|
-
elsif key == COLOR_KEY
|
187
|
-
if val.to_s.chars.last !~ /\D/
|
188
|
-
memo[:classes] << "color-#{dasherized_val}"
|
189
|
-
else
|
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}"
|
237
|
-
else
|
238
|
-
memo[:classes] << "#{key.to_s.dasherize}#{breakpoint}-#{dasherized_val}"
|
239
|
-
end
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
{
|
244
|
-
classes: out[:classes].join(" "),
|
245
|
-
styles: out[:styles].join(" ")
|
246
|
-
}.merge(out.except(:classes, :styles))
|
247
|
-
end
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|