primer_view_components 0.0.44 → 0.0.48

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +187 -0
  3. data/app/components/primer/avatar_stack_component.rb +9 -3
  4. data/app/components/primer/base_component.rb +52 -23
  5. data/app/components/primer/beta/auto_complete.rb +159 -0
  6. data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
  7. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
  8. data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
  9. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
  10. data/app/components/primer/beta/auto_complete/item.rb +44 -0
  11. data/app/components/primer/beta/avatar.rb +77 -0
  12. data/app/components/primer/border_box_component.rb +3 -0
  13. data/app/components/primer/clipboard_copy.rb +25 -7
  14. data/app/components/primer/component.rb +9 -1
  15. data/app/components/primer/details_component.rb +12 -8
  16. data/app/components/primer/image_crop.rb +1 -1
  17. data/app/components/primer/markdown.rb +9 -9
  18. data/app/components/primer/menu_component.rb +7 -3
  19. data/app/components/primer/navigation/tab_component.rb +19 -5
  20. data/app/components/primer/popover_component.rb +6 -3
  21. data/app/components/primer/primer.d.ts +1 -1
  22. data/app/components/primer/primer.js +1 -1
  23. data/app/components/primer/primer.ts +1 -1
  24. data/app/components/primer/tab_nav_component.rb +8 -6
  25. data/app/components/primer/timeline_item_component.rb +2 -2
  26. data/app/components/primer/tooltip.rb +1 -1
  27. data/app/components/primer/truncate.rb +5 -0
  28. data/app/components/primer/underline_nav_component.rb +12 -6
  29. data/{app/lib → lib}/primer/classify.rb +16 -33
  30. data/{app/lib → lib}/primer/classify/cache.rb +6 -40
  31. data/{app/lib → lib}/primer/classify/flex.rb +0 -0
  32. data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
  33. data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
  34. data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
  35. data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
  36. data/{app/lib → lib}/primer/classify/grid.rb +0 -0
  37. data/lib/primer/classify/utilities.rb +148 -0
  38. data/lib/primer/classify/utilities.yml +1271 -0
  39. data/lib/primer/view_components.rb +1 -0
  40. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +5 -4
  41. data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -5
  42. data/lib/primer/view_components/linters/helpers.rb +132 -17
  43. data/lib/primer/view_components/statuses.rb +14 -0
  44. data/lib/primer/view_components/version.rb +1 -1
  45. data/lib/rubocop/config/default.yml +12 -0
  46. data/lib/rubocop/cop/primer.rb +4 -0
  47. data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
  48. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
  49. data/lib/tasks/docs.rake +72 -18
  50. data/lib/tasks/utilities.rake +105 -0
  51. data/lib/yard/docs_helper.rb +1 -1
  52. data/static/statuses.json +4 -4
  53. metadata +30 -21
  54. data/app/components/primer/auto_complete.rb +0 -156
  55. data/app/components/primer/auto_complete/item.rb +0 -42
  56. data/app/components/primer/avatar_component.rb +0 -75
  57. data/app/lib/primer/classify/spacing.rb +0 -63
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :utilities do
4
+ task :build do
5
+ require "yaml"
6
+ require "json"
7
+ require File.expand_path("./../../demo/config/environment.rb", __dir__)
8
+
9
+ # Keys that are looked for to be included in the utilities.yml file
10
+ SUPPORTED_KEYS = %i[
11
+ anim
12
+ d
13
+ float
14
+ hide
15
+ m mt mr mb ml mx my
16
+ p pt pr pb pl px py
17
+ position
18
+ wb
19
+ v
20
+ ].freeze
21
+
22
+ # Replacements for some classnames that end up being a different argument key
23
+ REPLACEMENT_KEYS = {
24
+ "^anim" => "animation",
25
+ "^v-align" => "vertical_align",
26
+ "^d" => "display",
27
+ "^wb" => "word_break",
28
+ "^v" => "visibility"
29
+ }.freeze
30
+
31
+ BREAKPOINTS = [nil, "sm", "md", "lg", "xl"].freeze
32
+
33
+ css_data =
34
+ JSON.parse(
35
+ File.read(
36
+ File.join(
37
+ __FILE__.split("lib/tasks/utilities.rake")[0], "/node_modules/@primer/css/dist/stats/utilities.json"
38
+ )
39
+ )
40
+ )["selectors"]["values"]
41
+
42
+ output = {}
43
+
44
+ css_data.each do |selector|
45
+ selector.sub!(/^./, "")
46
+ # Next if selector has ancestors or sibling selectors
47
+ next if selector.match?(/[:><~\[\.]/)
48
+ next unless SUPPORTED_KEYS.any? { |key| selector.start_with?("#{key}-") }
49
+
50
+ # Dupe so we still have the selector at the end of slicing it up
51
+ classname = selector.dup
52
+ key = ""
53
+
54
+ # Look for a replacement key
55
+ REPLACEMENT_KEYS.each do |k, v|
56
+ next unless classname.match?(Regexp.new(k))
57
+
58
+ key = v
59
+ classname.sub!(Regexp.new(k + "-"), "")
60
+ end
61
+
62
+ # If we didn't find a replacement, grab the first text before hyphen
63
+ if classname == selector
64
+ key = classname.split("-").first
65
+ classname.sub!(/^[^-]+-/, "")
66
+ end
67
+
68
+ # Check if the next bit of the classname is a breakpoint
69
+ if classname.match?(/^(sm-|md-|lg-|xl-)/)
70
+ breakpoint = classname.split("-").first
71
+ classname.sub!(/^[^-]+-/, "")
72
+ end
73
+
74
+ # Change the rest from hypens to underscores
75
+ classname.sub!(/\-/, "_")
76
+
77
+ # convert padding/margin negative values ie n7 to -7
78
+ classname.sub!(/^n/, "-") if classname.match?(/^n[0-9]/)
79
+
80
+ key = key.to_sym
81
+
82
+ classname = if classname.match?(/\A[-+]?[0-9]+\z/)
83
+ classname.to_i
84
+ else
85
+ classname.to_sym
86
+ end
87
+
88
+ if output[key].nil?
89
+ output[key] = { classname => Array.new(5, nil) }
90
+ elsif output[key][classname].nil?
91
+ output[key][classname] = Array.new(5, nil)
92
+ end
93
+
94
+ output[key][classname][BREAKPOINTS.index(breakpoint)] = selector
95
+ end
96
+
97
+ output.transform_values! do |x|
98
+ x.transform_values { |y| y.reverse.drop_while(&:nil?).reverse }
99
+ end
100
+
101
+ File.open("lib/primer/classify/utilities.yml", "w") do |f|
102
+ f.puts YAML.dump(output)
103
+ end
104
+ end
105
+ end
@@ -41,7 +41,7 @@ module YARD
41
41
  end
42
42
 
43
43
  def link_to_component(component)
44
- short_name = component.name.gsub(/Primer|::|Component/, "")
44
+ short_name = component.name.gsub(/Primer|::|Alpha|Beta|Component/, "")
45
45
  "[#{short_name}](/components/#{short_name.downcase})"
46
46
  end
47
47
 
data/static/statuses.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "Primer::Alpha::ButtonMarketing": "alpha",
3
- "Primer::AutoComplete": "beta",
4
- "Primer::AutoComplete::Input": "alpha",
5
- "Primer::AutoComplete::Item": "beta",
6
- "Primer::AvatarComponent": "beta",
7
3
  "Primer::AvatarStackComponent": "beta",
8
4
  "Primer::BaseButton": "beta",
9
5
  "Primer::BaseComponent": "beta",
6
+ "Primer::Beta::AutoComplete": "beta",
7
+ "Primer::Beta::AutoComplete::Input": "alpha",
8
+ "Primer::Beta::AutoComplete::Item": "beta",
9
+ "Primer::Beta::Avatar": "beta",
10
10
  "Primer::Beta::Text": "beta",
11
11
  "Primer::BlankslateComponent": "beta",
12
12
  "Primer::BorderBoxComponent": "beta",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.44
4
+ version: 0.0.48
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-10 00:00:00.000000000 Z
11
+ date: 2021-07-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -338,7 +338,7 @@ dependencies:
338
338
  - - "~>"
339
339
  - !ruby/object:Gem::Version
340
340
  version: 0.9.25
341
- description:
341
+ description:
342
342
  email:
343
343
  - opensource+primer_view_components@github.com
344
344
  executables: []
@@ -351,19 +351,21 @@ files:
351
351
  - app/assets/javascripts/primer_view_components.js
352
352
  - app/assets/javascripts/primer_view_components.js.map
353
353
  - app/components/primer/alpha/button_marketing.rb
354
- - app/components/primer/auto_complete.rb
355
354
  - app/components/primer/auto_complete/auto_complete.d.ts
356
- - app/components/primer/auto_complete/auto_complete.html.erb
357
355
  - app/components/primer/auto_complete/auto_complete.js
358
- - app/components/primer/auto_complete/auto_complete.ts
359
356
  - app/components/primer/auto_complete/auto_component.d.ts
360
357
  - app/components/primer/auto_complete/auto_component.js
361
- - app/components/primer/auto_complete/item.rb
362
- - app/components/primer/avatar_component.rb
363
358
  - app/components/primer/avatar_stack_component.html.erb
364
359
  - app/components/primer/avatar_stack_component.rb
365
360
  - app/components/primer/base_button.rb
366
361
  - app/components/primer/base_component.rb
362
+ - app/components/primer/beta/auto_complete.rb
363
+ - app/components/primer/beta/auto_complete/auto_complete.d.ts
364
+ - app/components/primer/beta/auto_complete/auto_complete.html.erb
365
+ - app/components/primer/beta/auto_complete/auto_complete.js
366
+ - app/components/primer/beta/auto_complete/auto_complete.ts
367
+ - app/components/primer/beta/auto_complete/item.rb
368
+ - app/components/primer/beta/avatar.rb
367
369
  - app/components/primer/beta/text.rb
368
370
  - app/components/primer/blankslate_component.html.erb
369
371
  - app/components/primer/blankslate_component.rb
@@ -457,15 +459,6 @@ files:
457
459
  - app/components/primer/underline_nav_component.html.erb
458
460
  - app/components/primer/underline_nav_component.rb
459
461
  - app/lib/primer/class_name_helper.rb
460
- - app/lib/primer/classify.rb
461
- - app/lib/primer/classify/cache.rb
462
- - app/lib/primer/classify/flex.rb
463
- - app/lib/primer/classify/functional_background_colors.rb
464
- - app/lib/primer/classify/functional_border_colors.rb
465
- - app/lib/primer/classify/functional_colors.rb
466
- - app/lib/primer/classify/functional_text_colors.rb
467
- - app/lib/primer/classify/grid.rb
468
- - app/lib/primer/classify/spacing.rb
469
462
  - app/lib/primer/fetch_or_fallback_helper.rb
470
463
  - app/lib/primer/join_style_arguments_helper.rb
471
464
  - app/lib/primer/octicon/cache.rb
@@ -473,6 +466,16 @@ files:
473
466
  - app/lib/primer/tabbed_component_helper.rb
474
467
  - app/lib/primer/test_selector_helper.rb
475
468
  - app/lib/primer/view_helper.rb
469
+ - lib/primer/classify.rb
470
+ - lib/primer/classify/cache.rb
471
+ - lib/primer/classify/flex.rb
472
+ - lib/primer/classify/functional_background_colors.rb
473
+ - lib/primer/classify/functional_border_colors.rb
474
+ - lib/primer/classify/functional_colors.rb
475
+ - lib/primer/classify/functional_text_colors.rb
476
+ - lib/primer/classify/grid.rb
477
+ - lib/primer/classify/utilities.rb
478
+ - lib/primer/classify/utilities.yml
476
479
  - lib/primer/view_components.rb
477
480
  - lib/primer/view_components/engine.rb
478
481
  - lib/primer/view_components/linters.rb
@@ -482,10 +485,16 @@ files:
482
485
  - lib/primer/view_components/linters/button_component_migration_counter.rb
483
486
  - lib/primer/view_components/linters/flash_component_migration_counter.rb
484
487
  - lib/primer/view_components/linters/helpers.rb
488
+ - lib/primer/view_components/statuses.rb
485
489
  - lib/primer/view_components/version.rb
490
+ - lib/rubocop/config/default.yml
491
+ - lib/rubocop/cop/primer.rb
492
+ - lib/rubocop/cop/primer/no_tag_memoize.rb
493
+ - lib/rubocop/cop/primer/system_argument_instead_of_class.rb
486
494
  - lib/tasks/coverage.rake
487
495
  - lib/tasks/docs.rake
488
496
  - lib/tasks/statuses.rake
497
+ - lib/tasks/utilities.rake
489
498
  - lib/yard/docs_helper.rb
490
499
  - lib/yard/renders_many_handler.rb
491
500
  - lib/yard/renders_one_handler.rb
@@ -495,7 +504,7 @@ licenses:
495
504
  - MIT
496
505
  metadata:
497
506
  allowed_push_host: https://rubygems.org
498
- post_install_message:
507
+ post_install_message:
499
508
  rdoc_options: []
500
509
  require_paths:
501
510
  - lib
@@ -510,8 +519,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
510
519
  - !ruby/object:Gem::Version
511
520
  version: '0'
512
521
  requirements: []
513
- rubygems_version: 3.0.3
514
- signing_key:
522
+ rubygems_version: 3.1.2
523
+ signing_key:
515
524
  specification_version: 4
516
525
  summary: ViewComponents for the Primer Design System
517
526
  test_files: []
@@ -1,156 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Primer
4
- # Use `AutoComplete` to provide a user with a list of selectable suggestions that appear when they type into the
5
- # input field. This list is populated by server search results.
6
- # @accessibility
7
- # Always set an accessible label to help the user interact with the component.
8
- #
9
- # * Set the `label` slot to render a visible label. Alternatively, associate an existing visible text element
10
- # as a label by setting `aria-labelledby`.
11
- # * If you must use a non-visible label, set `:"aria-label"` on `AutoComplete` and Primer
12
- # will apply it to the correct elements. However, please note that a visible label should almost
13
- # always be used unless there is compelling reason not to. A placeholder is not a label.
14
- class AutoComplete < Primer::Component
15
- status :beta
16
-
17
- # Optionally render a visible label. See <%= link_to_accessibility %>
18
- #
19
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
20
- renders_one :label, lambda { |**system_arguments|
21
- system_arguments[:for] = @input_id
22
- system_arguments[:tag] = :label
23
- Primer::BaseComponent.new(**system_arguments)
24
- }
25
-
26
- # Required input used to search for results
27
- #
28
- # @param type [Symbol] <%= one_of(Primer::AutoComplete::Input::TYPE_OPTIONS) %>
29
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
30
- renders_one :input, lambda { |**system_arguments|
31
- aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label) || @aria_label
32
- if aria_label.present?
33
- system_arguments[:"aria-label"] = aria_label
34
- system_arguments[:aria]&.delete(:label)
35
- end
36
-
37
- Input.new(id: @input_id, **system_arguments)
38
- }
39
-
40
- # Optional icon to be rendered before the input. Has the same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
41
- #
42
- renders_one :icon, Primer::OcticonComponent
43
-
44
- # Customizable results list.
45
- #
46
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
47
- renders_one :results, lambda { |**system_arguments|
48
- system_arguments[:tag] = :ul
49
- system_arguments[:id] = @list_id
50
- system_arguments[:classes] = class_names(
51
- "autocomplete-results",
52
- system_arguments[:classes]
53
- )
54
-
55
- aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label) || @aria_label
56
- system_arguments[:"aria-label"] = aria_label if aria_label.present?
57
- system_arguments[:aria]&.delete(:label)
58
-
59
- Primer::BaseComponent.new(**system_arguments)
60
- }
61
-
62
- # @example Default
63
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-1", list_id: "fruits-popup-1", position: :relative)) do |c| %>
64
- # <% c.label(classes:"").with_content("Fruits") %>
65
- # <% c.input(type: :text) %>
66
- # <% end %>
67
- #
68
- # @example With `aria-label`
69
- # <%= render(Primer::AutoComplete.new("aria-label": "Fruits", src: "/auto_complete", input_id: "fruits-input-2", list_id: "fruits-popup-2", position: :relative)) do |c| %>
70
- # <% c.input(type: :text) %>
71
- # <% end %>
72
- #
73
- # @example With `aria-labelledby`
74
- # <%= render(Primer::HeadingComponent.new(tag: :h2, id: "search-1")) { "Search" } %>
75
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-3", list_id: "fruits-popup-2", position: :relative)) do |c| %>
76
- # <% c.input("aria-labelledby": "search-1") %>
77
- # <% end %>
78
- #
79
- # @example With custom classes for the results
80
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-4", list_id: "fruits-popup-3", position: :relative)) do |c| %>
81
- # <% c.label(classes:"").with_content("Fruits") %>
82
- # <% c.input(type: :text) %>
83
- # <% c.results(classes: "custom-class") do %>
84
- # <%= render(Primer::AutoComplete::Item.new(selected: true, value: "apple")) do |c| %>
85
- # Apple
86
- # <% end %>
87
- # <%= render(Primer::AutoComplete::Item.new(value: "orange")) do |c| %>
88
- # Orange
89
- # <% end %>
90
- # <% end %>
91
- # <% end %>
92
- #
93
- # @example With Icon
94
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", list_id: "fruits-popup-4", input_id: "fruits-input-4", position: :relative)) do |c| %>
95
- # <% c.label(classes:"").with_content("Fruits") %>
96
- # <% c.input(type: :text) %>
97
- # <% c.icon(icon: :search) %>
98
- # <% end %>
99
- #
100
- # @param src [String] The route to query.
101
- # @param input_id [String] Id of the input element.
102
- # @param list_id [String] Id of the list element.
103
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
104
- def initialize(src:, list_id:, input_id:, **system_arguments)
105
- @list_id = list_id
106
- @input_id = input_id
107
- @aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label)
108
-
109
- system_arguments.delete(:"aria-label") && system_arguments[:aria]&.delete(:label)
110
-
111
- @system_arguments = system_arguments
112
- @system_arguments[:tag] = "auto-complete"
113
- @system_arguments[:src] = src
114
- @system_arguments[:for] = list_id
115
- end
116
-
117
- # add `results` without needing to explicitly call it in the view
118
- def before_render
119
- raise ArgumentError, "Missing `input` slot" if input.blank?
120
- raise ArgumentError, "Accessible label is required." if label.blank? && input.missing_label?
121
-
122
- results(classes: "") unless results
123
- end
124
-
125
- # This component is part of `Primer::AutoCompleteComponent` and should not be
126
- # used as a standalone component.
127
- class Input < Primer::Component
128
- DEFAULT_TYPE = :text
129
- TYPE_OPTIONS = [DEFAULT_TYPE, :search].freeze
130
-
131
- # @param type [Symbol] <%= one_of(Primer::AutoComplete::Input::TYPE_OPTIONS) %>
132
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
133
- def initialize(type: DEFAULT_TYPE, **system_arguments)
134
- @system_arguments = system_arguments
135
- @system_arguments[:tag] = :input
136
-
137
- @aria_label = system_arguments[:"aria-label"]
138
- @aria_labelledby = system_arguments[:"aria-labelledby"] || system_arguments.dig(:aria, :labelledby)
139
-
140
- @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
141
- @system_arguments[:classes] = class_names(
142
- "form-control",
143
- system_arguments[:classes]
144
- )
145
- end
146
-
147
- def missing_label?
148
- @aria_label.blank? && @aria_labelledby.blank?
149
- end
150
-
151
- def call
152
- render(Primer::BaseComponent.new(**@system_arguments))
153
- end
154
- end
155
- end
156
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Primer
4
- class AutoComplete
5
- # Use `AutoCompleteItem` to list results of an auto-completed search.
6
- class Item < Primer::Component
7
- status :beta
8
-
9
- # @example Default
10
- # <%= render(Primer::AutoComplete::Item.new(selected: true, value: "value")) do |c| %>
11
- # Selected
12
- # <% end %>
13
- # <%= render(Primer::AutoComplete::Item.new(value: "value")) do |c| %>
14
- # Not selected
15
- # <% end %>
16
- #
17
- # @param value [String] Value of the item.
18
- # @param selected [Boolean] Whether the item is selected.
19
- # @param disabled [Boolean] Whether the item is disabled.
20
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
21
- def initialize(value:, selected: false, disabled: false, **system_arguments)
22
- @system_arguments = system_arguments
23
- @system_arguments[:tag] = :li
24
- @system_arguments[:role] = :option
25
- @system_arguments[:"data-autocomplete-value"] = value
26
-
27
- @system_arguments[:"aria-selected"] = true if selected
28
- @system_arguments[:"aria-disabled"] = true if disabled
29
-
30
- @system_arguments[:classes] = class_names(
31
- "autocomplete-item",
32
- system_arguments[:classes],
33
- "disabled" => disabled
34
- )
35
- end
36
-
37
- def call
38
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
39
- end
40
- end
41
- end
42
- end