primer_view_components 0.0.33 → 0.0.38

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +102 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/components/primer/{auto_complete_component.rb → auto_complete.rb} +13 -11
  6. data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_complete.d.ts} +0 -0
  7. data/app/components/primer/{auto_complete_component.html.erb → auto_complete/auto_complete.html.erb} +0 -0
  8. data/app/components/primer/{auto_complete_component.js → auto_complete/auto_complete.js} +0 -0
  9. data/app/components/primer/{auto_complete_component.ts → auto_complete/auto_complete.ts} +0 -0
  10. data/app/components/primer/auto_complete/auto_component.d.ts +1 -0
  11. data/app/components/primer/auto_complete/auto_component.js +1 -0
  12. data/app/components/primer/auto_complete/item.rb +42 -0
  13. data/app/components/primer/avatar_stack_component.rb +2 -0
  14. data/app/components/primer/base_button.rb +47 -0
  15. data/app/components/primer/base_component.rb +115 -85
  16. data/app/components/primer/button_component.rb +37 -32
  17. data/app/components/primer/button_component.rb.orig +138 -0
  18. data/app/components/primer/{button_group_component.html.erb → button_group.html.erb} +0 -0
  19. data/app/components/primer/button_group.rb +61 -0
  20. data/app/components/primer/button_marketing_component.rb +15 -20
  21. data/app/components/primer/clipboard_copy.html.erb +8 -0
  22. data/app/components/primer/clipboard_copy.rb +26 -0
  23. data/app/components/primer/clipboard_copy_component.d.ts +1 -0
  24. data/app/components/primer/clipboard_copy_component.js +25 -0
  25. data/app/components/primer/clipboard_copy_component.ts +28 -0
  26. data/app/components/primer/close_button.rb +37 -0
  27. data/app/components/primer/component.rb +1 -0
  28. data/app/components/primer/dropdown_component.rb +1 -1
  29. data/app/components/primer/dropdown_menu_component.rb +1 -1
  30. data/app/components/primer/flash_component.rb +10 -10
  31. data/app/components/primer/foo_bar.d.ts +1 -0
  32. data/app/components/primer/foo_bar.js +1 -0
  33. data/app/components/primer/heading_component.rb +32 -4
  34. data/app/components/primer/hidden_text_expander.rb +41 -0
  35. data/app/components/primer/link_component.rb +9 -9
  36. data/app/components/primer/navigation/tab_component.html.erb +9 -7
  37. data/app/components/primer/navigation/tab_component.rb +27 -3
  38. data/app/components/primer/octicon_component.rb +0 -4
  39. data/app/components/primer/primer.d.ts +2 -1
  40. data/app/components/primer/primer.js +2 -1
  41. data/app/components/primer/primer.ts +2 -1
  42. data/app/components/primer/state_component.rb +14 -14
  43. data/app/components/primer/subhead_component.rb +1 -1
  44. data/app/components/primer/tab_nav_component.html.erb +2 -2
  45. data/app/components/primer/tab_nav_component.rb +22 -8
  46. data/app/components/primer/{truncate_component.rb → truncate.rb} +8 -6
  47. data/app/components/primer/underline_nav_component.rb +46 -14
  48. data/app/lib/primer/classify.rb +4 -13
  49. data/app/lib/primer/classify/cache.rb +14 -4
  50. data/app/lib/primer/classify/spacing.rb +63 -0
  51. data/app/lib/primer/tabbed_component_helper.rb +4 -0
  52. data/lib/primer/view_components/version.rb +1 -1
  53. data/static/statuses.json +1 -1
  54. metadata +116 -32
  55. data/app/assets/javascripts/primer_view_components.js.map.orig +0 -5
  56. data/app/assets/javascripts/primer_view_components.js.orig +0 -6
  57. data/app/components/primer/auto_complete_item_component.rb +0 -38
  58. data/app/components/primer/button_group_component.rb +0 -35
@@ -3,14 +3,19 @@
3
3
  module Primer
4
4
  # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonComponent < Primer::Component
6
- DEFAULT_BUTTON_TYPE = :default
7
- BUTTON_TYPE_MAPPINGS = {
8
- DEFAULT_BUTTON_TYPE => "",
6
+ status :beta
7
+
8
+ DEFAULT_SCHEME = :default
9
+ LINK_SCHEME = :link
10
+ SCHEME_MAPPINGS = {
11
+ DEFAULT_SCHEME => "",
9
12
  :primary => "btn-primary",
10
13
  :danger => "btn-danger",
11
- :outline => "btn-outline"
14
+ :outline => "btn-outline",
15
+ :invisible => "btn-invisible",
16
+ LINK_SCHEME => "btn-link"
12
17
  }.freeze
13
- BUTTON_TYPE_OPTIONS = BUTTON_TYPE_MAPPINGS.keys
18
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
14
19
 
15
20
  DEFAULT_VARIANT = :medium
16
21
  VARIANT_MAPPINGS = {
@@ -20,56 +25,56 @@ module Primer
20
25
  }.freeze
21
26
  VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
22
27
 
23
- DEFAULT_TAG = :button
24
- TAG_OPTIONS = [DEFAULT_TAG, :a, :summary].freeze
25
-
26
- DEFAULT_TYPE = :button
27
- TYPE_OPTIONS = [DEFAULT_TYPE, :reset, :submit].freeze
28
-
29
- # @example Button types
28
+ # @example Schemes
30
29
  # <%= render(Primer::ButtonComponent.new) { "Default" } %>
31
- # <%= render(Primer::ButtonComponent.new(button_type: :primary)) { "Primary" } %>
32
- # <%= render(Primer::ButtonComponent.new(button_type: :danger)) { "Danger" } %>
33
- # <%= render(Primer::ButtonComponent.new(button_type: :outline)) { "Outline" } %>
30
+ # <%= render(Primer::ButtonComponent.new(scheme: :primary)) { "Primary" } %>
31
+ # <%= render(Primer::ButtonComponent.new(scheme: :danger)) { "Danger" } %>
32
+ # <%= render(Primer::ButtonComponent.new(scheme: :outline)) { "Outline" } %>
33
+ # <%= render(Primer::ButtonComponent.new(scheme: :invisible)) { "Invisible" } %>
34
+ # <%= render(Primer::ButtonComponent.new(scheme: :link)) { "Link" } %>
34
35
  #
35
36
  # @example Variants
36
37
  # <%= render(Primer::ButtonComponent.new(variant: :small)) { "Small" } %>
37
38
  # <%= render(Primer::ButtonComponent.new(variant: :medium)) { "Medium" } %>
38
39
  # <%= render(Primer::ButtonComponent.new(variant: :large)) { "Large" } %>
39
40
  #
40
- # @param button_type [Symbol] <%= one_of(Primer::ButtonComponent::BUTTON_TYPE_OPTIONS) %>
41
+ # @example Block
42
+ # <%= render(Primer::ButtonComponent.new(block: :true)) { "Block" } %>
43
+ # <%= render(Primer::ButtonComponent.new(block: :true, scheme: :primary)) { "Primary block" } %>
44
+ #
45
+ # @param scheme [Symbol] <%= one_of(Primer::ButtonComponent::SCHEME_OPTIONS) %>
41
46
  # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
42
- # @param tag [Symbol] <%= one_of(Primer::ButtonComponent::TAG_OPTIONS) %>
43
- # @param type [Symbol] <%= one_of(Primer::ButtonComponent::TYPE_OPTIONS) %>
47
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
48
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
44
49
  # @param group_item [Boolean] Whether button is part of a ButtonGroup.
50
+ # @param block [Boolean] Whether button is full-width with `display: block`.
45
51
  def initialize(
46
- button_type: DEFAULT_BUTTON_TYPE,
52
+ scheme: DEFAULT_SCHEME,
47
53
  variant: DEFAULT_VARIANT,
48
- tag: DEFAULT_TAG,
49
- type: DEFAULT_TYPE,
50
54
  group_item: false,
55
+ block: false,
51
56
  **system_arguments
52
57
  )
58
+ @scheme = scheme
53
59
  @system_arguments = system_arguments
54
- @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
55
-
56
- if @system_arguments[:tag] == :a
57
- @system_arguments[:role] = :button
58
- else
59
- @system_arguments[:type] = type
60
- end
61
-
62
60
  @system_arguments[:classes] = class_names(
63
- "btn",
64
61
  system_arguments[:classes],
65
- BUTTON_TYPE_MAPPINGS[fetch_or_fallback(BUTTON_TYPE_OPTIONS, button_type, DEFAULT_BUTTON_TYPE)],
62
+ SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
66
63
  VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
64
+ "btn" => !link?,
65
+ "btn-block" => block,
67
66
  "BtnGroup-item" => group_item
68
67
  )
69
68
  end
70
69
 
71
70
  def call
72
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
71
+ render(Primer::BaseButton.new(**@system_arguments)) { content }
72
+ end
73
+
74
+ private
75
+
76
+ def link?
77
+ @scheme == LINK_SCHEME
73
78
  end
74
79
  end
75
80
  end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
+ class ButtonComponent < Primer::Component
6
+ status :beta
7
+
8
+ DEFAULT_SCHEME = :default
9
+ LINK_SCHEME = :link
10
+ SCHEME_MAPPINGS = {
11
+ DEFAULT_SCHEME => "",
12
+ :primary => "btn-primary",
13
+ :danger => "btn-danger",
14
+ :outline => "btn-outline",
15
+ :invisible => "btn-invisible",
16
+ LINK_SCHEME => "btn-link"
17
+ }.freeze
18
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
19
+
20
+ DEFAULT_VARIANT = :medium
21
+ VARIANT_MAPPINGS = {
22
+ :small => "btn-sm",
23
+ DEFAULT_VARIANT => "",
24
+ :large => "btn-large"
25
+ }.freeze
26
+ VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
27
+
28
+ <<<<<<< HEAD
29
+ =======
30
+ DEFAULT_TAG = :button
31
+ TAG_OPTIONS = [DEFAULT_TAG, :a, :summary].freeze
32
+
33
+ DEFAULT_TYPE = :button
34
+ TYPE_OPTIONS = [DEFAULT_TYPE, :reset, :submit].freeze
35
+
36
+ DEFAULT_ICON_ALIGN = :left
37
+ ICON_ALIGN_OPTIONS = [DEFAULT_ICON_ALIGN, :right].freeze
38
+
39
+ # Icon to be rendered in the button.
40
+ #
41
+ # @param align [Symbol] <%= one_of(Primer::ButtonComponent::ICON_ALIGN_OPTIONS) %>
42
+ # @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
43
+ renders_one :icon, lambda { |align: DEFAULT_ICON_ALIGN, **system_arguments|
44
+ @icon_align = fetch_or_fallback(ICON_ALIGN_OPTIONS, align, DEFAULT_ICON_ALIGN)
45
+
46
+ Primer::OcticonComponent.new(**system_arguments)
47
+ }
48
+
49
+ # Counter to be rendered in the button.
50
+ #
51
+ # @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::CounterComponent) %>.
52
+ renders_one :counter, Primer::CounterComponent
53
+
54
+ >>>>>>> 05bacd3 (add icon and counter slots to button)
55
+ # @example Schemes
56
+ # <%= render(Primer::ButtonComponent.new) { "Default" } %>
57
+ # <%= render(Primer::ButtonComponent.new(scheme: :primary)) { "Primary" } %>
58
+ # <%= render(Primer::ButtonComponent.new(scheme: :danger)) { "Danger" } %>
59
+ # <%= render(Primer::ButtonComponent.new(scheme: :outline)) { "Outline" } %>
60
+ # <%= render(Primer::ButtonComponent.new(scheme: :invisible)) { "Invisible" } %>
61
+ # <%= render(Primer::ButtonComponent.new(scheme: :link)) { "Link" } %>
62
+ #
63
+ # @example Variants
64
+ # <%= render(Primer::ButtonComponent.new(variant: :small)) { "Small" } %>
65
+ # <%= render(Primer::ButtonComponent.new(variant: :medium)) { "Medium" } %>
66
+ # <%= render(Primer::ButtonComponent.new(variant: :large)) { "Large" } %>
67
+ #
68
+ # @example Block
69
+ # <%= render(Primer::ButtonComponent.new(block: :true)) { "Block" } %>
70
+ # <%= render(Primer::ButtonComponent.new(block: :true, scheme: :primary)) { "Primary block" } %>
71
+ #
72
+ # @example With icons
73
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
74
+ # <% c.icon(icon: :star) %>
75
+ # Button
76
+ # <% end %>
77
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
78
+ # <% c.icon(icon: :star, align: :right) %>
79
+ # Button
80
+ # <% end %>
81
+ #
82
+ # @example With counter
83
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
84
+ # <% c.counter(count: 15) %>
85
+ # Button
86
+ # <% end %>
87
+ #
88
+ # @example With icons and counter
89
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
90
+ # <% c.icon(icon: :star) %>
91
+ # <% c.counter(count: 15) %>
92
+ # Button
93
+ # <% end %>
94
+ # <%= render(Primer::ButtonComponent.new) do |c| %>
95
+ # <% c.icon(icon: :star, align: :right) %>
96
+ # <% c.counter(count: 15) %>
97
+ # Button
98
+ # <% end %>
99
+ #
100
+ # @param scheme [Symbol] <%= one_of(Primer::ButtonComponent::SCHEME_OPTIONS) %>
101
+ # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
102
+ # @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
103
+ # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
104
+ # @param group_item [Boolean] Whether button is part of a ButtonGroup.
105
+ # @param block [Boolean] Whether button is full-width with `display: block`.
106
+ def initialize(
107
+ scheme: DEFAULT_SCHEME,
108
+ variant: DEFAULT_VARIANT,
109
+ group_item: false,
110
+ block: false,
111
+ **system_arguments
112
+ )
113
+ @scheme = scheme
114
+ @system_arguments = system_arguments
115
+ @system_arguments[:classes] = class_names(
116
+ system_arguments[:classes],
117
+ SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
118
+ VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
119
+ "btn" => !link?,
120
+ "btn-block" => block,
121
+ "BtnGroup-item" => group_item
122
+ )
123
+ end
124
+
125
+ <<<<<<< HEAD
126
+ def call
127
+ render(Primer::BaseButton.new(**@system_arguments)) { content }
128
+ end
129
+
130
+ =======
131
+ >>>>>>> 05bacd3 (add icon and counter slots to button)
132
+ private
133
+
134
+ def link?
135
+ @scheme == LINK_SCHEME
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use ButtonGroup to render a series of buttons.
5
+ class ButtonGroup < Primer::Component
6
+ status :beta
7
+
8
+ # Required list of buttons to be rendered.
9
+ #
10
+ # @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::ButtonComponent) %> except for `variant` and `group_item`.
11
+ renders_many :buttons, lambda { |**kwargs|
12
+ kwargs[:group_item] = true
13
+ kwargs[:variant] = @variant
14
+
15
+ Primer::ButtonComponent.new(**kwargs)
16
+ }
17
+
18
+ # @example Default
19
+ #
20
+ # <%= render(Primer::ButtonGroup.new) do |component| %>
21
+ # <% component.button { "Default" } %>
22
+ # <% component.button(scheme: :primary) { "Primary" } %>
23
+ # <% component.button(scheme: :danger) { "Danger" } %>
24
+ # <% component.button(scheme: :outline) { "Outline" } %>
25
+ # <% component.button(classes: "my-class") { "Custom class" } %>
26
+ # <% end %>
27
+ #
28
+ # @example Variants
29
+ #
30
+ # <%= render(Primer::ButtonGroup.new(variant: :small)) do |component| %>
31
+ # <% component.button { "Default" } %>
32
+ # <% component.button(scheme: :primary) { "Primary" } %>
33
+ # <% component.button(scheme: :danger) { "Danger" } %>
34
+ # <% component.button(scheme: :outline) { "Outline" } %>
35
+ # <% end %>
36
+ #
37
+ # <%= render(Primer::ButtonGroup.new(variant: :large)) do |component| %>
38
+ # <% component.button { "Default" } %>
39
+ # <% component.button(scheme: :primary) { "Primary" } %>
40
+ # <% component.button(scheme: :danger) { "Danger" } %>
41
+ # <% component.button(scheme: :outline) { "Outline" } %>
42
+ # <% end %>
43
+ #
44
+ # @param variant [Symbol] <%= one_of(Primer::ButtonComponent::VARIANT_OPTIONS) %>
45
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
46
+ def initialize(variant: Primer::ButtonComponent::DEFAULT_VARIANT, **system_arguments)
47
+ @variant = variant
48
+ @system_arguments = system_arguments
49
+ @system_arguments[:tag] ||= :div
50
+
51
+ @system_arguments[:classes] = class_names(
52
+ "BtnGroup",
53
+ system_arguments[:classes]
54
+ )
55
+ end
56
+
57
+ def render?
58
+ buttons.any?
59
+ end
60
+ end
61
+ end
@@ -3,14 +3,14 @@
3
3
  module Primer
4
4
  # Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
5
5
  class ButtonMarketingComponent < Primer::Component
6
- DEFAULT_BUTTON_TYPE = :default
7
- BUTTON_TYPE_MAPPINGS = {
8
- DEFAULT_BUTTON_TYPE => "",
6
+ DEFAULT_SCHEME = :default
7
+ SCHEME_MAPPINGS = {
8
+ DEFAULT_SCHEME => "",
9
9
  :primary => "btn-primary-mktg",
10
10
  :outline => "btn-outline-mktg",
11
11
  :transparent => "btn-transparent"
12
12
  }.freeze
13
- BUTTON_TYPE_OPTIONS = BUTTON_TYPE_MAPPINGS.keys
13
+ SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
14
14
 
15
15
  DEFAULT_VARIANT = :default
16
16
  VARIANT_MAPPINGS = {
@@ -25,49 +25,44 @@ module Primer
25
25
  DEFAULT_TYPE = :button
26
26
  TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
27
27
 
28
- # @example Button types
28
+ # @example Schemes
29
29
  # <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
30
- # <%= render(Primer::ButtonMarketingComponent.new(button_type: :primary, mr: 2)) { "Primary" } %>
31
- # <%= render(Primer::ButtonMarketingComponent.new(button_type: :outline)) { "Outline" } %>
32
- # <div class="bg-gray-dark">
33
- # <%= render(Primer::ButtonMarketingComponent.new(button_type: :transparent)) { "Transparent" } %>
30
+ # <%= render(Primer::ButtonMarketingComponent.new(scheme: :primary, mr: 2)) { "Primary" } %>
31
+ # <%= render(Primer::ButtonMarketingComponent.new(scheme: :outline)) { "Outline" } %>
32
+ # <div class="color-bg-canvas-inverse">
33
+ # <%= render(Primer::ButtonMarketingComponent.new(scheme: :transparent)) { "Transparent" } %>
34
34
  # </div>
35
35
  #
36
36
  # @example Sizes
37
37
  # <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
38
38
  # <%= render(Primer::ButtonMarketingComponent.new(variant: :large)) { "Large" } %>
39
39
  #
40
- # @param button_type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::BUTTON_TYPE_OPTIONS) %>
40
+ # @param scheme [Symbol] <%= one_of(Primer::ButtonMarketingComponent::SCHEME_OPTIONS) %>
41
41
  # @param variant [Symbol] <%= one_of(Primer::ButtonMarketingComponent::VARIANT_OPTIONS) %>
42
42
  # @param tag [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TAG_OPTIONS) %>
43
43
  # @param type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TYPE_OPTIONS) %>
44
44
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
45
45
  def initialize(
46
- button_type: DEFAULT_BUTTON_TYPE,
46
+ scheme: DEFAULT_SCHEME,
47
47
  variant: DEFAULT_VARIANT,
48
48
  tag: DEFAULT_TAG,
49
49
  type: DEFAULT_TYPE,
50
50
  **system_arguments
51
51
  )
52
52
  @system_arguments = system_arguments
53
+ @system_arguments[:block] = false
53
54
  @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
54
-
55
- if @system_arguments[:tag] == :a
56
- @system_arguments[:role] = :button
57
- else
58
- @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
59
- end
60
-
55
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
61
56
  @system_arguments[:classes] = class_names(
62
57
  "btn-mktg",
63
- BUTTON_TYPE_MAPPINGS[fetch_or_fallback(BUTTON_TYPE_OPTIONS, button_type, DEFAULT_BUTTON_TYPE)],
58
+ SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
64
59
  VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
65
60
  system_arguments[:classes]
66
61
  )
67
62
  end
68
63
 
69
64
  def call
70
- render(Primer::BaseComponent.new(**@system_arguments)) { content }
65
+ render(Primer::BaseButton.new(**@system_arguments)) { content }
71
66
  end
72
67
  end
73
68
  end
@@ -0,0 +1,8 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <% if content.present? %>
3
+ <%= content %>
4
+ <% else %>
5
+ <%= render Primer::OcticonComponent.new("clippy") %>
6
+ <%= render Primer::OcticonComponent.new("check", color: :icon_success, style: "display: none;") %>
7
+ <% end %>
8
+ <% end %>
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use ClipboardCopy to copy element text content or input values to the clipboard.
5
+ class ClipboardCopy < Primer::Component
6
+ status :alpha
7
+
8
+ # @example Default
9
+ # <%= render(Primer::ClipboardCopy.new(value: "Text to copy", label: "Copy text to the system clipboard")) %>
10
+ #
11
+ # @example With text instead of icons
12
+ # <%= render(Primer::ClipboardCopy.new(value: "Text to copy", label: "Copy text to the system clipboard")) do %>
13
+ # Click to copy!
14
+ # <% end %>
15
+ #
16
+ # @param label [String] String that will be read to screenreaders when the component is focused
17
+ # @param value [String] Text to copy into the users clipboard when they click the component
18
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
19
+ def initialize(label:, value:, **system_arguments)
20
+ @system_arguments = system_arguments
21
+ @system_arguments[:tag] = "clipboard-copy"
22
+ @system_arguments[:value] = value
23
+ @system_arguments[:"aria-label"] = label
24
+ end
25
+ end
26
+ end
@@ -0,0 +1 @@
1
+ import '@github/clipboard-copy-element';
@@ -0,0 +1,25 @@
1
+ import '@github/clipboard-copy-element';
2
+ function toggleSVG(svg) {
3
+ if (svg.style.display === '' || svg.style.display === 'block') {
4
+ svg.style.display = 'none';
5
+ }
6
+ else {
7
+ svg.style.display = 'block';
8
+ }
9
+ }
10
+ // Toggle a copy button.
11
+ function toggleCopyButton(button) {
12
+ const [clippyIcon, checkIcon] = button.querySelectorAll('.octicon');
13
+ if (clippyIcon) {
14
+ toggleSVG(clippyIcon);
15
+ }
16
+ if (checkIcon) {
17
+ toggleSVG(checkIcon);
18
+ }
19
+ }
20
+ document.addEventListener('clipboard-copy', function ({ target }) {
21
+ if (!(target instanceof HTMLElement))
22
+ return;
23
+ toggleCopyButton(target);
24
+ setTimeout(toggleCopyButton, 2000, target);
25
+ });