primer_view_components 0.0.44 → 0.0.48

Sign up to get free protection for your applications and to get access to all the features.
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