primer_view_components 0.0.17 → 0.0.22

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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -0
  3. data/app/assets/javascripts/primer_view_components.js +2 -0
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -0
  5. data/app/components/primer/avatar_component.rb +27 -9
  6. data/app/components/primer/avatar_stack_component.html.erb +10 -0
  7. data/app/components/primer/avatar_stack_component.rb +81 -0
  8. data/app/components/primer/base_component.rb +8 -5
  9. data/app/components/primer/blankslate_component.html.erb +3 -3
  10. data/app/components/primer/blankslate_component.rb +18 -25
  11. data/app/components/primer/border_box_component.html.erb +4 -18
  12. data/app/components/primer/border_box_component.rb +75 -68
  13. data/app/components/primer/box_component.rb +10 -0
  14. data/app/components/primer/breadcrumb_component.rb +3 -2
  15. data/app/components/primer/button_component.rb +3 -3
  16. data/app/components/primer/button_group_component.html.erb +5 -0
  17. data/app/components/primer/button_group_component.rb +37 -0
  18. data/app/components/primer/button_marketing_component.rb +73 -0
  19. data/app/components/primer/component.rb +16 -0
  20. data/app/components/primer/counter_component.rb +16 -9
  21. data/app/components/primer/details_component.html.erb +2 -6
  22. data/app/components/primer/details_component.rb +28 -37
  23. data/app/components/primer/dropdown/menu_component.html.erb +12 -0
  24. data/app/components/primer/dropdown/menu_component.rb +48 -0
  25. data/app/components/primer/dropdown_component.html.erb +9 -0
  26. data/app/components/primer/dropdown_component.rb +75 -0
  27. data/app/components/primer/dropdown_menu_component.rb +35 -3
  28. data/app/components/primer/flash_component.html.erb +4 -7
  29. data/app/components/primer/flash_component.rb +18 -17
  30. data/app/components/primer/flex_component.rb +47 -9
  31. data/app/components/primer/flex_item_component.rb +16 -1
  32. data/app/components/primer/heading_component.rb +9 -0
  33. data/app/components/primer/label_component.rb +6 -6
  34. data/app/components/primer/layout_component.rb +2 -2
  35. data/app/components/primer/link_component.rb +6 -2
  36. data/app/components/primer/markdown_component.rb +293 -0
  37. data/app/components/primer/menu_component.html.erb +6 -0
  38. data/app/components/primer/menu_component.rb +71 -0
  39. data/app/components/primer/octicon_component.rb +13 -6
  40. data/app/components/primer/popover_component.rb +5 -3
  41. data/app/components/primer/primer.js +1 -0
  42. data/app/components/primer/primer.ts +1 -0
  43. data/app/components/primer/progress_bar_component.rb +6 -6
  44. data/app/components/primer/spinner_component.rb +8 -5
  45. data/app/components/primer/state_component.rb +23 -12
  46. data/app/components/primer/subhead_component.rb +6 -3
  47. data/app/components/primer/tab_container_component.js +1 -0
  48. data/app/components/primer/tab_container_component.rb +41 -0
  49. data/app/components/primer/tab_container_component.ts +1 -0
  50. data/app/components/primer/tab_nav_component.html.erb +17 -0
  51. data/app/components/primer/tab_nav_component.rb +108 -0
  52. data/app/components/primer/text_component.rb +1 -1
  53. data/app/components/primer/timeline_item_component.html.erb +4 -16
  54. data/app/components/primer/timeline_item_component.rb +41 -49
  55. data/app/components/primer/tooltip_component.rb +88 -0
  56. data/app/components/primer/truncate_component.rb +41 -0
  57. data/app/components/primer/underline_nav_component.rb +26 -1
  58. data/{lib → app/lib}/primer/class_name_helper.rb +1 -0
  59. data/app/lib/primer/classify.rb +280 -0
  60. data/app/lib/primer/classify/cache.rb +125 -0
  61. data/{lib → app/lib}/primer/fetch_or_fallback_helper.rb +1 -0
  62. data/{lib → app/lib}/primer/join_style_arguments_helper.rb +1 -0
  63. data/app/lib/primer/view_helper.rb +22 -0
  64. data/app/lib/primer/view_helper/dsl.rb +34 -0
  65. data/lib/primer/view_components.rb +32 -0
  66. data/lib/primer/view_components/engine.rb +11 -2
  67. data/lib/primer/view_components/version.rb +5 -1
  68. data/lib/yard/renders_many_handler.rb +19 -0
  69. data/lib/yard/renders_one_handler.rb +19 -0
  70. data/static/statuses.json +1 -0
  71. metadata +94 -24
  72. data/app/components/primer/view_components.rb +0 -52
  73. 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"
@@ -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