primer_view_components 0.0.46 → 0.0.50

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +144 -0
  3. data/app/components/primer/base_component.rb +2 -2
  4. data/app/components/primer/beta/auto_complete.rb +159 -0
  5. data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
  6. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
  7. data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
  8. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
  9. data/app/components/primer/beta/auto_complete/item.rb +44 -0
  10. data/app/components/primer/beta/avatar.rb +77 -0
  11. data/app/components/primer/{avatar_stack_component.html.erb → beta/avatar_stack.html.erb} +0 -0
  12. data/app/components/primer/beta/avatar_stack.rb +92 -0
  13. data/app/components/primer/clipboard_copy.html.erb +2 -2
  14. data/app/components/primer/component.rb +5 -1
  15. data/app/components/primer/details_component.rb +7 -7
  16. data/app/components/primer/image_crop.html.erb +4 -4
  17. data/app/components/primer/label_component.rb +13 -12
  18. data/app/components/primer/markdown.rb +9 -9
  19. data/app/components/primer/navigation/tab_component.rb +30 -2
  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 +4 -3
  25. data/app/components/primer/timeline_item_component.rb +2 -2
  26. data/app/components/primer/truncate.rb +6 -1
  27. data/app/components/primer/underline_nav_component.rb +4 -3
  28. data/app/lib/primer/octicon/cache.rb +1 -1
  29. data/lib/primer/classify.rb +4 -18
  30. data/lib/primer/classify/cache.rb +0 -5
  31. data/lib/primer/classify/utilities.rb +54 -22
  32. data/lib/primer/classify/utilities.yml +16 -0
  33. data/lib/primer/view_components.rb +34 -6
  34. data/lib/primer/view_components/constants.rb +55 -0
  35. data/lib/primer/view_components/linters/argument_mappers/base.rb +74 -0
  36. data/lib/primer/view_components/linters/argument_mappers/button.rb +32 -44
  37. data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +20 -0
  38. data/lib/primer/view_components/linters/argument_mappers/helpers/erb_block.rb +24 -0
  39. data/lib/primer/view_components/linters/argument_mappers/label.rb +50 -0
  40. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +4 -1
  41. data/lib/primer/view_components/linters/autocorrectable.rb +30 -0
  42. data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -23
  43. data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +21 -0
  44. data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +16 -0
  45. data/lib/primer/view_components/linters/helpers.rb +56 -38
  46. data/lib/primer/view_components/linters/label_component_migration_counter.rb +25 -0
  47. data/lib/primer/view_components/statuses.rb +14 -0
  48. data/lib/primer/view_components/version.rb +1 -1
  49. data/lib/rubocop/config/default.yml +12 -0
  50. data/lib/rubocop/cop/primer.rb +4 -0
  51. data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
  52. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
  53. data/lib/tasks/constants.rake +12 -0
  54. data/lib/tasks/docs.rake +87 -32
  55. data/lib/tasks/utilities.rake +4 -10
  56. data/lib/yard/docs_helper.rb +12 -3
  57. data/static/arguments.yml +973 -0
  58. data/static/assets/view-components.svg +18 -0
  59. data/static/classes.yml +174 -0
  60. data/static/constants.json +628 -0
  61. data/static/statuses.json +5 -5
  62. metadata +34 -13
  63. data/app/components/primer/auto_complete.rb +0 -157
  64. data/app/components/primer/auto_complete/item.rb +0 -42
  65. data/app/components/primer/avatar_component.rb +0 -75
  66. data/app/components/primer/avatar_stack_component.rb +0 -90
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
- "Primer::AvatarStackComponent": "beta",
8
3
  "Primer::BaseButton": "beta",
9
4
  "Primer::BaseComponent": "beta",
5
+ "Primer::Beta::AutoComplete": "beta",
6
+ "Primer::Beta::AutoComplete::Input": "alpha",
7
+ "Primer::Beta::AutoComplete::Item": "beta",
8
+ "Primer::Beta::Avatar": "beta",
9
+ "Primer::Beta::AvatarStack": "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.46
4
+ version: 0.0.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-29 00:00:00.000000000 Z
11
+ date: 2021-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: octicons
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 13.0.0
47
+ version: '15'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 13.0.0
54
+ version: '15'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: view_component
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -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
- - app/components/primer/avatar_stack_component.html.erb
364
- - app/components/primer/avatar_stack_component.rb
365
358
  - app/components/primer/base_button.rb
366
359
  - app/components/primer/base_component.rb
360
+ - app/components/primer/beta/auto_complete.rb
361
+ - app/components/primer/beta/auto_complete/auto_complete.d.ts
362
+ - app/components/primer/beta/auto_complete/auto_complete.html.erb
363
+ - app/components/primer/beta/auto_complete/auto_complete.js
364
+ - app/components/primer/beta/auto_complete/auto_complete.ts
365
+ - app/components/primer/beta/auto_complete/item.rb
366
+ - app/components/primer/beta/avatar.rb
367
+ - app/components/primer/beta/avatar_stack.html.erb
368
+ - app/components/primer/beta/avatar_stack.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
@@ -475,15 +477,30 @@ files:
475
477
  - lib/primer/classify/utilities.rb
476
478
  - lib/primer/classify/utilities.yml
477
479
  - lib/primer/view_components.rb
480
+ - lib/primer/view_components/constants.rb
478
481
  - lib/primer/view_components/engine.rb
479
482
  - lib/primer/view_components/linters.rb
483
+ - lib/primer/view_components/linters/argument_mappers/base.rb
480
484
  - lib/primer/view_components/linters/argument_mappers/button.rb
485
+ - lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb
481
486
  - lib/primer/view_components/linters/argument_mappers/conversion_error.rb
487
+ - lib/primer/view_components/linters/argument_mappers/helpers/erb_block.rb
488
+ - lib/primer/view_components/linters/argument_mappers/label.rb
482
489
  - lib/primer/view_components/linters/argument_mappers/system_arguments.rb
490
+ - lib/primer/view_components/linters/autocorrectable.rb
483
491
  - lib/primer/view_components/linters/button_component_migration_counter.rb
492
+ - lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb
493
+ - lib/primer/view_components/linters/close_button_component_migration_counter.rb
484
494
  - lib/primer/view_components/linters/flash_component_migration_counter.rb
485
495
  - lib/primer/view_components/linters/helpers.rb
496
+ - lib/primer/view_components/linters/label_component_migration_counter.rb
497
+ - lib/primer/view_components/statuses.rb
486
498
  - lib/primer/view_components/version.rb
499
+ - lib/rubocop/config/default.yml
500
+ - lib/rubocop/cop/primer.rb
501
+ - lib/rubocop/cop/primer/no_tag_memoize.rb
502
+ - lib/rubocop/cop/primer/system_argument_instead_of_class.rb
503
+ - lib/tasks/constants.rake
487
504
  - lib/tasks/coverage.rake
488
505
  - lib/tasks/docs.rake
489
506
  - lib/tasks/statuses.rake
@@ -491,6 +508,10 @@ files:
491
508
  - lib/yard/docs_helper.rb
492
509
  - lib/yard/renders_many_handler.rb
493
510
  - lib/yard/renders_one_handler.rb
511
+ - static/arguments.yml
512
+ - static/assets/view-components.svg
513
+ - static/classes.yml
514
+ - static/constants.json
494
515
  - static/statuses.json
495
516
  homepage: https://github.com/primer/view_components
496
517
  licenses:
@@ -1,157 +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
- name = system_arguments[:name] || @input_id
38
- Input.new(id: @input_id, name: name, **system_arguments)
39
- }
40
-
41
- # Optional icon to be rendered before the input. Has the same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
42
- #
43
- renders_one :icon, Primer::OcticonComponent
44
-
45
- # Customizable results list.
46
- #
47
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
48
- renders_one :results, lambda { |**system_arguments|
49
- system_arguments[:tag] = :ul
50
- system_arguments[:id] = @list_id
51
- system_arguments[:classes] = class_names(
52
- "autocomplete-results",
53
- system_arguments[:classes]
54
- )
55
-
56
- aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label) || @aria_label
57
- system_arguments[:"aria-label"] = aria_label if aria_label.present?
58
- system_arguments[:aria]&.delete(:label)
59
-
60
- Primer::BaseComponent.new(**system_arguments)
61
- }
62
-
63
- # @example Default
64
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-1", list_id: "fruits-popup-1", position: :relative)) do |c| %>
65
- # <% c.label(classes:"").with_content("Fruits") %>
66
- # <% c.input(type: :text) %>
67
- # <% end %>
68
- #
69
- # @example With `aria-label`
70
- # <%= render(Primer::AutoComplete.new("aria-label": "Fruits", src: "/auto_complete", input_id: "fruits-input-2", list_id: "fruits-popup-2", position: :relative)) do |c| %>
71
- # <% c.input(type: :text) %>
72
- # <% end %>
73
- #
74
- # @example With `aria-labelledby`
75
- # <%= render(Primer::HeadingComponent.new(tag: :h2, id: "search-1")) { "Search" } %>
76
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-3", list_id: "fruits-popup-2", position: :relative)) do |c| %>
77
- # <% c.input("aria-labelledby": "search-1") %>
78
- # <% end %>
79
- #
80
- # @example With custom classes for the results
81
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-4", list_id: "fruits-popup-3", position: :relative)) do |c| %>
82
- # <% c.label(classes:"").with_content("Fruits") %>
83
- # <% c.input(type: :text) %>
84
- # <% c.results(classes: "custom-class") do %>
85
- # <%= render(Primer::AutoComplete::Item.new(selected: true, value: "apple")) do |c| %>
86
- # Apple
87
- # <% end %>
88
- # <%= render(Primer::AutoComplete::Item.new(value: "orange")) do |c| %>
89
- # Orange
90
- # <% end %>
91
- # <% end %>
92
- # <% end %>
93
- #
94
- # @example With Icon
95
- # <%= render(Primer::AutoComplete.new(src: "/auto_complete", list_id: "fruits-popup-4", input_id: "fruits-input-4", position: :relative)) do |c| %>
96
- # <% c.label(classes:"").with_content("Fruits") %>
97
- # <% c.input(type: :text) %>
98
- # <% c.icon(icon: :search) %>
99
- # <% end %>
100
- #
101
- # @param src [String] The route to query.
102
- # @param input_id [String] Id of the input element.
103
- # @param list_id [String] Id of the list element.
104
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
105
- def initialize(src:, list_id:, input_id:, **system_arguments)
106
- @list_id = list_id
107
- @input_id = input_id
108
- @aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label)
109
-
110
- system_arguments.delete(:"aria-label") && system_arguments[:aria]&.delete(:label)
111
-
112
- @system_arguments = system_arguments
113
- @system_arguments[:tag] = "auto-complete"
114
- @system_arguments[:src] = src
115
- @system_arguments[:for] = list_id
116
- end
117
-
118
- # add `results` without needing to explicitly call it in the view
119
- def before_render
120
- raise ArgumentError, "Missing `input` slot" if input.blank?
121
- raise ArgumentError, "Accessible label is required." if label.blank? && input.missing_label?
122
-
123
- results(classes: "") unless results
124
- end
125
-
126
- # This component is part of `Primer::AutoCompleteComponent` and should not be
127
- # used as a standalone component.
128
- class Input < Primer::Component
129
- DEFAULT_TYPE = :text
130
- TYPE_OPTIONS = [DEFAULT_TYPE, :search].freeze
131
-
132
- # @param type [Symbol] <%= one_of(Primer::AutoComplete::Input::TYPE_OPTIONS) %>
133
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
134
- def initialize(type: DEFAULT_TYPE, **system_arguments)
135
- @system_arguments = system_arguments
136
- @system_arguments[:tag] = :input
137
-
138
- @aria_label = system_arguments[:"aria-label"]
139
- @aria_labelledby = system_arguments[:"aria-labelledby"] || system_arguments.dig(:aria, :labelledby)
140
-
141
- @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
142
- @system_arguments[:classes] = class_names(
143
- "form-control",
144
- system_arguments[:classes]
145
- )
146
- end
147
-
148
- def missing_label?
149
- @aria_label.blank? && @aria_labelledby.blank?
150
- end
151
-
152
- def call
153
- render(Primer::BaseComponent.new(**@system_arguments))
154
- end
155
- end
156
- end
157
- 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
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Primer
4
- # `Avatar` can be used to represent users and organizations on GitHub.
5
- #
6
- # - Use the default round avatar for users, and the `square` argument
7
- # for organizations or any other non-human avatars.
8
- # - By default, `Avatar` will render a static `<img>`. To have `Avatar` function as a link, set the `href` which will wrap the `<img>` in a `<a>`.
9
- # - Set `size` to update the height and width of the `Avatar` in pixels.
10
- # - To stack multiple avatars together, use <%= link_to_component(Primer::AvatarStackComponent) %>.
11
- #
12
- # @accessibility
13
- # Images should have text alternatives that describe the information or function represented.
14
- # If the avatar functions as a link, provide alt text that helps convey the function. For instance,
15
- # if `Avatar` is a link to a user profile, the alt attribute should be `@kittenuser profile`
16
- # rather than `@kittenuser`.
17
- # [Learn more about best image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/)
18
- class AvatarComponent < Primer::Component
19
- status :beta
20
-
21
- SMALL_THRESHOLD = 24
22
-
23
- # @example Default
24
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser")) %>
25
- #
26
- # @example Square
27
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", square: true)) %>
28
- #
29
- # @example Link
30
- # <%= render(Primer::AvatarComponent.new(href: "#", src: "http://placekitten.com/200/200", alt: "@kittenuser profile")) %>
31
- #
32
- # @example With size
33
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 16)) %>
34
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 20)) %>
35
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 24)) %>
36
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 28)) %>
37
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 32)) %>
38
- # <%= render(Primer::AvatarComponent.new(src: "http://placekitten.com/200/200", alt: "@kittenuser", size: 36)) %>
39
- #
40
- # @param src [String] The source url of the avatar image.
41
- # @param alt [String] Passed through to alt on img tag.
42
- # @param size [Integer] Adds the avatar-small class if less than 24.
43
- # @param square [Boolean] Used to create a square avatar.
44
- # @param href [String] The URL to link to. If used, component will be wrapped by an `<a>` tag.
45
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
46
- def initialize(src:, alt:, size: 20, square: false, href: nil, **system_arguments)
47
- @href = href
48
- @system_arguments = system_arguments
49
- @system_arguments[:tag] = :img
50
- @system_arguments[:src] = src
51
- @system_arguments[:alt] = alt
52
- @system_arguments[:size] = size
53
- @system_arguments[:height] = size
54
- @system_arguments[:width] = size
55
-
56
- @system_arguments[:classes] = class_names(
57
- system_arguments[:classes],
58
- "avatar",
59
- "avatar-small" => size < SMALL_THRESHOLD,
60
- "circle" => !square,
61
- "lh-0" => href # Addresses an overflow issue with linked avatars
62
- )
63
- end
64
-
65
- def call
66
- if @href
67
- render(Primer::LinkComponent.new(href: @href, classes: @system_arguments[:classes])) do
68
- render(Primer::BaseComponent.new(**@system_arguments.except(:classes))) { content }
69
- end
70
- else
71
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
72
- end
73
- end
74
- end
75
- end
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Primer
4
- # Use `AvatarStack` to stack multiple avatars together.
5
- class AvatarStackComponent < Primer::Component
6
- status :beta
7
-
8
- ALIGN_DEFAULT = :left
9
- ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
10
-
11
- DEFAULT_TAG = :div
12
- TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
13
-
14
- DEFAULT_BODY_TAG = :div
15
- BODY_TAG_OPTIONS = TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
16
- # Required list of stacked avatars.
17
- #
18
- # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::AvatarComponent) %>.
19
- renders_many :avatars, Primer::AvatarComponent
20
-
21
- # @example Default
22
- # <%= render(Primer::AvatarStackComponent.new) do |c| %>
23
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
24
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
25
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
26
- # <% end %>
27
- #
28
- # @example Align right
29
- # <%= render(Primer::AvatarStackComponent.new(align: :right)) do |c| %>
30
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
31
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
32
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
33
- # <% end %>
34
- #
35
- # @example With tooltip
36
- # <%= render(Primer::AvatarStackComponent.new(tooltipped: true, body_arguments: { label: 'This is a tooltip!' })) do |c| %>
37
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
38
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
39
- # <%= c.avatar(src: "http://placekitten.com/200/200", alt: "@kittenuser") %>
40
- # <% end %>
41
- #
42
- # @param tag [Symbol] <%= one_of(Primer::AvatarStackComponent::TAG_OPTIONS) %>
43
- # @param align [Symbol] <%= one_of(Primer::AvatarStackComponent::ALIGN_OPTIONS) %>
44
- # @param tooltipped [Boolean] Whether to add a tooltip to the stack or not.
45
- # @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::Tooltip) %>.
46
- # The default tag is <%= pretty_value(Primer::AvatarStackComponent::DEFAULT_BODY_TAG) %> but can be changed using `tag:`
47
- # to <%= one_of(Primer::AvatarStackComponent::BODY_TAG_OPTIONS, lower: true) %>
48
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
49
- def initialize(tag: DEFAULT_TAG, align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
50
- @align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
51
- @system_arguments = system_arguments
52
- @tooltipped = tooltipped
53
- @body_arguments = body_arguments
54
-
55
- body_tag = @body_arguments[:tag] || DEFAULT_BODY_TAG
56
- @body_arguments[:tag] = fetch_or_fallback(BODY_TAG_OPTIONS, body_tag, DEFAULT_BODY_TAG)
57
- @body_arguments[:classes] = class_names(
58
- "AvatarStack-body",
59
- @body_arguments[:classes]
60
- )
61
-
62
- @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
63
- @system_arguments[:classes] = class_names(
64
- "AvatarStack",
65
- system_arguments[:classes],
66
- "AvatarStack--right" => @align == :right
67
- )
68
- end
69
-
70
- def body_component
71
- if @tooltipped
72
- Primer::Tooltip.new(**@body_arguments)
73
- else
74
- Primer::BaseComponent.new(**@body_arguments)
75
- end
76
- end
77
-
78
- def before_render
79
- @system_arguments[:classes] = class_names(
80
- @system_arguments[:classes],
81
- "AvatarStack--two" => avatars.size == 2,
82
- "AvatarStack--three-plus" => avatars.size > 2
83
- )
84
- end
85
-
86
- def render?
87
- avatars.any?
88
- end
89
- end
90
- end