openproject-primer_view_components 0.32.1 → 0.33.1

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 (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -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/assets/styles/primer_view_components.css +1 -1
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/toggle_switch.js +1 -1
  8. data/app/components/primer/alpha/toggle_switch.rb +16 -4
  9. data/app/components/primer/alpha/toggle_switch.ts +1 -1
  10. data/app/components/primer/beta/clipboard_copy.html.erb +9 -6
  11. data/app/components/primer/beta/clipboard_copy.js +15 -0
  12. data/app/components/primer/beta/clipboard_copy.rb +2 -0
  13. data/app/components/primer/beta/clipboard_copy.ts +14 -0
  14. data/app/components/primer/beta/clipboard_copy_button.rb +2 -0
  15. data/app/components/primer/open_project/page_header.css +1 -1
  16. data/app/components/primer/open_project/page_header.css.json +3 -3
  17. data/app/components/primer/open_project/page_header.css.map +1 -1
  18. data/app/components/primer/open_project/page_header.pcss +6 -6
  19. data/app/components/primer/open_project/page_header.rb +1 -1
  20. data/app/lib/primer/attributes_helper.rb +1 -1
  21. data/lib/primer/forms/toggle_switch.html.erb +1 -9
  22. data/lib/primer/view_components/version.rb +1 -1
  23. data/previews/primer/alpha/toggle_switch_preview.rb +1 -1
  24. data/previews/primer/beta/label_preview.rb +7 -2
  25. data/previews/primer/forms_preview/example_toggle_switch_form.html.erb +2 -2
  26. data/static/classes.json +1 -4
  27. data/static/info_arch.json +2 -2
  28. metadata +2 -2
@@ -20,7 +20,7 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
20
20
  }
21
21
  get csrf() {
22
22
  const csrfElement = this.querySelector('[data-csrf]');
23
- return this.getAttribute('csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || null;
23
+ return this.getAttribute('data-csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || null;
24
24
  }
25
25
  get csrfField() {
26
26
  // the authenticity token is passed into the element and is not generated in js land
@@ -56,10 +56,6 @@ module Primer
56
56
  }
57
57
 
58
58
  @system_arguments[:src] = @src if @src
59
-
60
- return unless @src && @csrf_token
61
-
62
- @system_arguments[:csrf] = @csrf_token
63
59
  end
64
60
 
65
61
  def on?
@@ -73,6 +69,22 @@ module Primer
73
69
  def disabled?
74
70
  !enabled?
75
71
  end
72
+
73
+ private
74
+
75
+ def before_render
76
+ @csrf_token ||= view_context.form_authenticity_token(
77
+ form_options: {
78
+ method: :post,
79
+ action: @src
80
+ }
81
+ )
82
+
83
+ @system_arguments[:data] = merge_data(
84
+ @system_arguments,
85
+ { data: { csrf: @csrf_token } }
86
+ )
87
+ end
76
88
  end
77
89
  end
78
90
  end
@@ -19,7 +19,7 @@ class ToggleSwitchElement extends HTMLElement {
19
19
 
20
20
  get csrf(): string | null {
21
21
  const csrfElement = this.querySelector('[data-csrf]')
22
- return this.getAttribute('csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || null
22
+ return this.getAttribute('data-csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || null
23
23
  }
24
24
 
25
25
  get csrfField(): string {
@@ -1,8 +1,11 @@
1
- <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <% if content.present? %>
3
- <%= content %>
4
- <% else %>
5
- <%= render Primer::Beta::Octicon.new(:copy) %>
6
- <%= render Primer::Beta::Octicon.new(:check, color: :success, style: "display: none;") %>
1
+ <%= render Primer::BaseComponent.new(tag: :span) do %>
2
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
+ <% if content.present? %>
4
+ <%= content %>
5
+ <% else %>
6
+ <%= render Primer::Beta::Octicon.new(:copy) %>
7
+ <%= render Primer::Beta::Octicon.new(:check, color: :success, style: "display: none;") %>
8
+ <% end %>
7
9
  <% end %>
10
+ <div aria-live="polite" aria-atomic="true" class="sr-only" data-clipboard-copy-feedback></div>
8
11
  <% end %>
@@ -29,12 +29,27 @@ document.addEventListener('clipboard-copy', ({ target }) => {
29
29
  if (!target.hasAttribute('data-view-component'))
30
30
  return;
31
31
  const currentTimeout = clipboardCopyElementTimers.get(target);
32
+ const clipboardCopyLiveRegion = target.parentNode?.querySelector('[data-clipboard-copy-feedback]');
33
+ const copiedAnnouncement = 'Copied!';
32
34
  if (currentTimeout) {
33
35
  clearTimeout(currentTimeout);
34
36
  clipboardCopyElementTimers.delete(target);
35
37
  }
36
38
  else {
37
39
  showCheck(target);
40
+ if (clipboardCopyLiveRegion) {
41
+ if (clipboardCopyLiveRegion.textContent === copiedAnnouncement) {
42
+ /* This is a hack due to the way the aria live API works.
43
+ A screen reader will not read a live region again
44
+ if the text is the same. Adding a space character tells
45
+ the browser that the live region has updated,
46
+ which will cause it to read again, but with no audible difference. */
47
+ clipboardCopyLiveRegion.textContent = `${copiedAnnouncement}\u00A0`;
48
+ }
49
+ else {
50
+ clipboardCopyLiveRegion.textContent = copiedAnnouncement;
51
+ }
52
+ }
38
53
  }
39
54
  clipboardCopyElementTimers.set(target, setTimeout(() => {
40
55
  showCopy(target);
@@ -10,6 +10,8 @@ module Primer
10
10
  #
11
11
  # @accessibility
12
12
  # Always set an accessible label to help the user interact with the component.
13
+ #
14
+ # This component has a built-in `aria-live` region that announces "Copied!" when the copy element is pressed.
13
15
  class ClipboardCopy < Primer::Component
14
16
  status :beta
15
17
 
@@ -37,12 +37,26 @@ document.addEventListener('clipboard-copy', ({target}) => {
37
37
  if (!target.hasAttribute('data-view-component')) return
38
38
 
39
39
  const currentTimeout = clipboardCopyElementTimers.get(target)
40
+ const clipboardCopyLiveRegion = target.parentNode?.querySelector<HTMLElement>('[data-clipboard-copy-feedback]')
41
+ const copiedAnnouncement = 'Copied!'
40
42
 
41
43
  if (currentTimeout) {
42
44
  clearTimeout(currentTimeout)
43
45
  clipboardCopyElementTimers.delete(target)
44
46
  } else {
45
47
  showCheck(target)
48
+ if (clipboardCopyLiveRegion) {
49
+ if (clipboardCopyLiveRegion.textContent === copiedAnnouncement) {
50
+ /* This is a hack due to the way the aria live API works.
51
+ A screen reader will not read a live region again
52
+ if the text is the same. Adding a space character tells
53
+ the browser that the live region has updated,
54
+ which will cause it to read again, but with no audible difference. */
55
+ clipboardCopyLiveRegion.textContent = `${copiedAnnouncement}\u00A0`
56
+ } else {
57
+ clipboardCopyLiveRegion.textContent = copiedAnnouncement
58
+ }
59
+ }
46
60
  }
47
61
 
48
62
  clipboardCopyElementTimers.set(
@@ -5,6 +5,8 @@ module Primer
5
5
  # `ClipboardCopyButton` uses the `ClipboardCopy` component to copy text to the clipboard,
6
6
  # styled as a Primer button. It can be used wherever a button is desired, and works well
7
7
  # with components like `ButtonGroup`.
8
+ # @accessibility
9
+ # This component has a built-in `aria-live` region that announces "Copied!" when the copy button is pressed.
8
10
  class ClipboardCopyButton < Primer::Beta::Button
9
11
  # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Button) %> and <%= link_to_component(Primer::Beta::ClipboardCopy) %>.
10
12
  def initialize(**system_arguments)
@@ -1 +1 @@
1
- .PageHeader{border-bottom:var(--borderWidth-thin) solid var(--borderColor-muted);display:flex;flex-flow:column;margin-bottom:var(--stack-gap-normal);padding-bottom:var(--stack-padding-condensed)}.PageHeader--noBorder{border-bottom:none;padding-bottom:0}.PageHeader-contextBar{margin-bottom:var(--base-size-8)}.PageHeader-contextBar,.PageHeader-titleBar{align-items:center;display:flex;flex-flow:row;justify-content:flex-end}.PageHeader-titleBar{margin-bottom:var(--space-xsmall)}.PageHeader-title{flex:1 1 auto;font-size:var(--text-title-size-medium);font-weight:var(--base-text-weight-normal)}.PageHeader-title--large{font-size:var(--text-title-size-large)}.PageHeader-description{color:var(--fgColor-muted);flex:1 100%;font-size:var(--text-body-size-medium)}.PageHeader-actions{align-items:center;display:flex;justify-content:flex-end}.PageHeader-breadcrumbs{display:block;width:100%}.PageHeader-leadingAction{margin-right:var(--base-size-4);margin-top:2px}.PageHeader-parentLink{flex:1 1 auto}.PageHeader-tabNav{margin-bottom:0;margin-top:var(--stack-gap-normal)}
1
+ .PageHeader{border-bottom:var(--borderWidth-thin) solid var(--borderColor-muted);display:flex;flex-flow:column;margin-bottom:var(--stack-gap-normal);padding-bottom:var(--stack-padding-condensed)}.PageHeader--withTabNav{border-bottom:none;margin-bottom:0;padding-bottom:0}.PageHeader-contextBar{margin-bottom:var(--base-size-8)}.PageHeader-contextBar,.PageHeader-titleBar{align-items:center;display:flex;flex-flow:row;justify-content:flex-end}.PageHeader-titleBar{margin-bottom:var(--space-xsmall)}.PageHeader-title{flex:1 1 auto;font-size:var(--text-title-size-medium);font-weight:var(--base-text-weight-normal)}.PageHeader-title--large{font-size:var(--text-title-size-large)}.PageHeader-description{color:var(--fgColor-muted);flex:1 100%;font-size:var(--text-body-size-medium)}.PageHeader--withTabNav .PageHeader-description{margin-bottom:var(--space-xlarge)}.PageHeader-actions{align-items:center;display:flex;justify-content:flex-end}.PageHeader-breadcrumbs{display:block;width:100%}.PageHeader-leadingAction{margin-right:var(--base-size-4);margin-top:2px}.PageHeader-parentLink{flex:1 1 auto}
@@ -2,16 +2,16 @@
2
2
  "name": "open_project/page_header",
3
3
  "selectors": [
4
4
  ".PageHeader",
5
- ".PageHeader--noBorder",
5
+ ".PageHeader--withTabNav",
6
6
  ".PageHeader-contextBar",
7
7
  ".PageHeader-titleBar",
8
8
  ".PageHeader-title",
9
9
  ".PageHeader-title--large",
10
10
  ".PageHeader-description",
11
+ ".PageHeader--withTabNav .PageHeader-description",
11
12
  ".PageHeader-actions",
12
13
  ".PageHeader-breadcrumbs",
13
14
  ".PageHeader-leadingAction",
14
- ".PageHeader-parentLink",
15
- ".PageHeader-tabNav"
15
+ ".PageHeader-parentLink"
16
16
  ]
17
17
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["page_header.pcss"],"names":[],"mappings":"AAEA,YAIE,oEAAqE,CAHrE,YAAa,CAIb,gBAAiB,CAFjB,qCAAsC,CADtC,6CAIF,CAEA,sBACE,kBAAmB,CACnB,gBACF,CAEA,uBAKE,gCACF,CAEA,4CAJE,kBAAmB,CAHnB,YAAa,CACb,aAAc,CACd,wBAWF,CANA,qBAKE,iCACF,CAEA,kBAGE,aAAc,CAFd,uCAAwC,CACxC,0CAEF,CAEA,yBACE,sCACF,CAGA,wBAEE,0BAA2B,CAC3B,WAAY,CAFZ,sCAGF,CAEA,oBAGE,kBAAmB,CADnB,YAAa,CADb,wBAGF,CAEA,wBACE,aAAc,CACd,UACF,CAEA,0BAEE,+BAAgC,CADhC,cAEF,CAEA,uBACE,aACF,CAEA,mBAEE,eAAgB,CADhB,kCAEF","file":"page_header.css","sourcesContent":["/* OP PageHeader */\n\n.PageHeader {\n display: flex;\n padding-bottom: var(--stack-padding-condensed);\n margin-bottom: var(--stack-gap-normal);\n border-bottom: var(--borderWidth-thin) solid var(--borderColor-muted);\n flex-flow: column;\n}\n\n.PageHeader--noBorder {\n border-bottom: none;\n padding-bottom: 0;\n}\n\n.PageHeader-contextBar {\n display: flex;\n flex-flow: row;\n justify-content: flex-end;\n align-items: center;\n margin-bottom: var(--base-size-8);\n}\n\n.PageHeader-titleBar {\n display: flex;\n flex-flow: row;\n justify-content: flex-end;\n align-items: center; /* Keep back button vertically aligned. */\n margin-bottom: var(--space-xsmall);\n}\n\n.PageHeader-title {\n font-size: var(--text-title-size-medium);\n font-weight: var(--base-text-weight-normal);\n flex: 1 1 auto;\n}\n\n.PageHeader-title--large {\n font-size: var(--text-title-size-large);\n}\n\n/* One-liner of supporting text */\n.PageHeader-description {\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-muted);\n flex: 1 100%;\n}\n\n.PageHeader-actions {\n justify-content: flex-end;\n display: flex;\n align-items: center;\n}\n\n.PageHeader-breadcrumbs {\n display: block;\n width: 100%;\n}\n\n.PageHeader-leadingAction {\n margin-top: 2px; /* to center align with label */\n margin-right: var(--base-size-4);\n}\n\n.PageHeader-parentLink {\n flex: 1 1 auto;\n}\n\n.PageHeader-tabNav {\n margin-top: var(--stack-gap-normal);\n margin-bottom: 0;\n}\n"]}
1
+ {"version":3,"sources":["page_header.pcss"],"names":[],"mappings":"AAEA,YAIE,oEAAqE,CAHrE,YAAa,CAIb,gBAAiB,CAFjB,qCAAsC,CADtC,6CAIF,CAEA,wBACE,kBAAmB,CAEnB,eAAgB,CADhB,gBAEF,CAEA,uBAKE,gCACF,CAEA,4CAJE,kBAAmB,CAHnB,YAAa,CACb,aAAc,CACd,wBAWF,CANA,qBAKE,iCACF,CAEA,kBAGE,aAAc,CAFd,uCAAwC,CACxC,0CAEF,CAEA,yBACE,sCACF,CAGA,wBAEE,0BAA2B,CAC3B,WAAY,CAFZ,sCAGF,CAEA,gDACE,iCACF,CAEA,oBAGE,kBAAmB,CADnB,YAAa,CADb,wBAGF,CAEA,wBACE,aAAc,CACd,UACF,CAEA,0BAEE,+BAAgC,CADhC,cAEF,CAEA,uBACE,aACF","file":"page_header.css","sourcesContent":["/* OP PageHeader */\n\n.PageHeader {\n display: flex;\n padding-bottom: var(--stack-padding-condensed);\n margin-bottom: var(--stack-gap-normal);\n border-bottom: var(--borderWidth-thin) solid var(--borderColor-muted);\n flex-flow: column;\n}\n\n.PageHeader--withTabNav {\n border-bottom: none;\n padding-bottom: 0;\n margin-bottom: 0;\n}\n\n.PageHeader-contextBar {\n display: flex;\n flex-flow: row;\n justify-content: flex-end;\n align-items: center;\n margin-bottom: var(--base-size-8);\n}\n\n.PageHeader-titleBar {\n display: flex;\n flex-flow: row;\n justify-content: flex-end;\n align-items: center; /* Keep back button vertically aligned. */\n margin-bottom: var(--space-xsmall);\n}\n\n.PageHeader-title {\n font-size: var(--text-title-size-medium);\n font-weight: var(--base-text-weight-normal);\n flex: 1 1 auto;\n}\n\n.PageHeader-title--large {\n font-size: var(--text-title-size-large);\n}\n\n/* One-liner of supporting text */\n.PageHeader-description {\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-muted);\n flex: 1 100%;\n}\n\n.PageHeader--withTabNav .PageHeader-description {\n margin-bottom: var(--space-xlarge);\n}\n\n.PageHeader-actions {\n justify-content: flex-end;\n display: flex;\n align-items: center;\n}\n\n.PageHeader-breadcrumbs {\n display: block;\n width: 100%;\n}\n\n.PageHeader-leadingAction {\n margin-top: 2px; /* to center align with label */\n margin-right: var(--base-size-4);\n}\n\n.PageHeader-parentLink {\n flex: 1 1 auto;\n}\n"]}
@@ -8,9 +8,10 @@
8
8
  flex-flow: column;
9
9
  }
10
10
 
11
- .PageHeader--noBorder {
11
+ .PageHeader--withTabNav {
12
12
  border-bottom: none;
13
13
  padding-bottom: 0;
14
+ margin-bottom: 0;
14
15
  }
15
16
 
16
17
  .PageHeader-contextBar {
@@ -46,6 +47,10 @@
46
47
  flex: 1 100%;
47
48
  }
48
49
 
50
+ .PageHeader--withTabNav .PageHeader-description {
51
+ margin-bottom: var(--space-xlarge);
52
+ }
53
+
49
54
  .PageHeader-actions {
50
55
  justify-content: flex-end;
51
56
  display: flex;
@@ -65,8 +70,3 @@
65
70
  .PageHeader-parentLink {
66
71
  flex: 1 1 auto;
67
72
  }
68
-
69
- .PageHeader-tabNav {
70
- margin-top: var(--stack-gap-normal);
71
- margin-bottom: 0;
72
- }
@@ -209,7 +209,7 @@ module Primer
209
209
  #
210
210
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
211
211
  renders_one :tab_nav, lambda { |**system_arguments, &block|
212
- @system_arguments[:classes] = class_names(@system_arguments[:classes], "PageHeader--noBorder")
212
+ @system_arguments[:classes] = class_names(@system_arguments[:classes], "PageHeader--withTabNav")
213
213
 
214
214
  system_arguments = deny_tag_argument(**system_arguments)
215
215
  system_arguments[:tag] = :div
@@ -54,7 +54,7 @@ module Primer
54
54
  # It's designed to be used to normalize and merge data information from system_arguments
55
55
  # hashes. Consider using this pattern in component initializers:
56
56
  #
57
- # @system_arguments[:data] = merge_aria(
57
+ # @system_arguments[:data] = merge_data(
58
58
  # @system_arguments,
59
59
  # { data: { foo: "bar" } }
60
60
  # )
@@ -10,13 +10,5 @@
10
10
 
11
11
  <div><%= render(Caption.new(input: @input)) %></div>
12
12
  </span>
13
- <%
14
- csrf = @input.csrf || @view_context.form_authenticity_token(
15
- form_options: {
16
- method: :post,
17
- action: @input.src
18
- }
19
- )
20
- %>
21
- <%= render(Primer::Alpha::ToggleSwitch.new(src: @input.src, csrf: csrf, **@input.input_arguments)) %>
13
+ <%= render(Primer::Alpha::ToggleSwitch.new(src: @input.src, csrf_token: @input.csrf, **@input.input_arguments)) %>
22
14
  <% end %>
@@ -5,7 +5,7 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 32
8
+ MINOR = 33
9
9
  PATCH = 1
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
@@ -52,7 +52,7 @@ module Primer
52
52
  end
53
53
 
54
54
  def with_csrf_token
55
- render(Primer::Alpha::ToggleSwitch.new(src: UrlHelpers.toggle_switch_index_path, csrf_token: "let_me_in"))
55
+ render(Primer::Alpha::ToggleSwitch.new(src: UrlHelpers.toggle_switch_index_path))
56
56
  end
57
57
 
58
58
  def with_bad_csrf_token
@@ -9,8 +9,13 @@ module Primer
9
9
  # @param size [Symbol] select [medium, large]
10
10
  # @param tag [Symbol] select [span, summary, a, div]
11
11
  # @param inline [Boolean] toggle
12
- def playground(size: :medium, tag: :span, inline: false)
13
- render(Primer::Beta::Label.new(tag: tag, size: size, inline: inline)) { "Label" }
12
+ # @param href [String] URL to be used with an anchor tag
13
+ def playground(size: :medium, tag: :span, inline: false, href: nil)
14
+ if tag == :a
15
+ render(Primer::Beta::Label.new(tag: tag, size: size, inline: inline, href: href || "#")) { "Link label" }
16
+ else
17
+ render(Primer::Beta::Label.new(tag: tag, size: size, inline: inline)) { "Label" }
18
+ end
14
19
  end
15
20
 
16
21
  # @label Default Options
@@ -1,3 +1,3 @@
1
- <%= render(ExampleToggleSwitchForm.new(csrf: "let_me_in", label: "Good example", src: toggle_switch_index_path, id: "success-toggle")) %>
1
+ <%= render(ExampleToggleSwitchForm.new(label: "Good example", src: toggle_switch_index_path, id: "success-toggle")) %>
2
2
  <hr>
3
- <%= render(ExampleToggleSwitchForm.new(csrf: "a_bad_value", label: "Bad example", src: toggle_switch_index_path, id: "error-toggle")) %>
3
+ <%= render(ExampleToggleSwitchForm.new(label: "Bad example", src: toggle_switch_index_path(fail: true), id: "error-toggle")) %>
data/static/classes.json CHANGED
@@ -429,7 +429,7 @@
429
429
  "PageHeader": [
430
430
  "Primer::OpenProject::PageHeader"
431
431
  ],
432
- "PageHeader--noBorder": [
432
+ "PageHeader--withTabNav": [
433
433
  "Primer::OpenProject::PageHeader"
434
434
  ],
435
435
  "PageHeader-actions": [
@@ -450,9 +450,6 @@
450
450
  "PageHeader-parentLink": [
451
451
  "Primer::OpenProject::PageHeader"
452
452
  ],
453
- "PageHeader-tabNav": [
454
- "Primer::OpenProject::PageHeader"
455
- ],
456
453
  "PageHeader-title": [
457
454
  "Primer::OpenProject::PageHeader"
458
455
  ],
@@ -11630,7 +11630,7 @@
11630
11630
  {
11631
11631
  "fully_qualified_name": "Primer::Beta::ClipboardCopy",
11632
11632
  "description": "Use `ClipboardCopy` to copy element text content or input values to the clipboard.\n\nThis component by itself is not styled as a button, and can therefore only be used in limited circumstances.\nIf you're looking for a button, consider using {{#link_to_component}}Primer::Beta::ClipboardCopyButton{{/link_to_component}}\ninstead.",
11633
- "accessibility_docs": "Always set an accessible label to help the user interact with the component.",
11633
+ "accessibility_docs": "Always set an accessible label to help the user interact with the component.\n\nThis component has a built-in `aria-live` region that announces \"Copied!\" when the copy element is pressed.",
11634
11634
  "is_form_component": false,
11635
11635
  "is_published": true,
11636
11636
  "requires_js": true,
@@ -11797,7 +11797,7 @@
11797
11797
  {
11798
11798
  "fully_qualified_name": "Primer::Beta::ClipboardCopyButton",
11799
11799
  "description": "`ClipboardCopyButton` uses the `ClipboardCopy` component to copy text to the clipboard,\nstyled as a Primer button. It can be used wherever a button is desired, and works well\nwith components like `ButtonGroup`.",
11800
- "accessibility_docs": null,
11800
+ "accessibility_docs": "This component has a built-in `aria-live` region that announces \"Copied!\" when the copy button is pressed.",
11801
11801
  "is_form_component": false,
11802
11802
  "is_published": true,
11803
11803
  "requires_js": false,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openproject-primer_view_components
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.1
4
+ version: 0.33.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub Open Source
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-05-31 00:00:00.000000000 Z
12
+ date: 2024-06-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionview