openproject-primer_view_components 0.64.0 → 0.64.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 (25) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/app/assets/javascripts/components/primer/open_project/collapsible.d.ts +2 -0
  4. data/app/assets/javascripts/primer_view_components.js +1 -1
  5. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  6. data/app/assets/styles/primer_view_components.css +1 -1
  7. data/app/assets/styles/primer_view_components.css.map +1 -1
  8. data/app/components/primer/open_project/border_box/collapsible_header.css +1 -1
  9. data/app/components/primer/open_project/border_box/collapsible_header.css.json +2 -1
  10. data/app/components/primer/open_project/border_box/collapsible_header.css.map +1 -1
  11. data/app/components/primer/open_project/border_box/collapsible_header.html.erb +12 -1
  12. data/app/components/primer/open_project/border_box/collapsible_header.pcss +4 -0
  13. data/app/components/primer/open_project/border_box/collapsible_header.rb +16 -12
  14. data/app/components/primer/open_project/collapsible.d.ts +2 -0
  15. data/app/components/primer/open_project/collapsible.js +11 -0
  16. data/app/components/primer/open_project/collapsible.ts +10 -0
  17. data/app/components/primer/open_project/collapsible_section.html.erb +14 -2
  18. data/app/components/primer/open_project/collapsible_section.rb +5 -1
  19. data/app/components/primer/open_project/danger_dialog.html.erb +4 -0
  20. data/app/components/primer/open_project/feedback_dialog.html.erb +5 -0
  21. data/lib/primer/view_components/version.rb +1 -1
  22. data/static/arguments.json +12 -0
  23. data/static/classes.json +3 -0
  24. data/static/info_arch.json +12 -0
  25. metadata +2 -2
@@ -1 +1 @@
1
- .CollapsibleHeader{align-items:center;cursor:pointer;display:flex}.Box:has(.CollapsibleHeader--collapsed){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:var(--borderWidth-thicker)}.Box:has(.CollapsibleHeader--collapsed) .Box-body,.Box:has(.CollapsibleHeader--collapsed) .Box-footer,.Box:has(.CollapsibleHeader--collapsed) .Box-row{display:none}
1
+ .CollapsibleHeader{align-items:center;cursor:pointer;display:flex}.Box:has(.CollapsibleHeader--collapsed){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:var(--borderWidth-thicker)}.Box:has(.CollapsibleHeader--collapsed) .Box-body,.Box:has(.CollapsibleHeader--collapsed) .Box-footer,.Box:has(.CollapsibleHeader--collapsed) .Box-row{display:none}.CollapsibleHeader--triggerArea{width:100%}
@@ -5,6 +5,7 @@
5
5
  ".Box:has(.CollapsibleHeader--collapsed)",
6
6
  ".Box:has(.CollapsibleHeader--collapsed) .Box-body",
7
7
  ".Box:has(.CollapsibleHeader--collapsed) .Box-footer",
8
- ".Box:has(.CollapsibleHeader--collapsed) .Box-row"
8
+ ".Box:has(.CollapsibleHeader--collapsed) .Box-row",
9
+ ".CollapsibleHeader--triggerArea"
9
10
  ]
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAEA,mBAGI,kBAAmB,CAFnB,cAAe,CACf,YAEJ,CAEA,wCACI,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOJ,CALI,uJAGI,YACJ","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n.CollapsibleHeader {\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.Box:has(.CollapsibleHeader--collapsed) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-width: var(--borderWidth-thicker);\n\n & .Box-row,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n"]}
1
+ {"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAEA,mBAGI,kBAAmB,CAFnB,cAAe,CACf,YAEJ,CAEA,wCACI,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOJ,CALI,uJAGI,YACJ,CAGJ,gCACI,UACJ","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n.CollapsibleHeader {\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.Box:has(.CollapsibleHeader--collapsed) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-width: var(--borderWidth-thicker);\n\n & .Box-row,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n\n.CollapsibleHeader--triggerArea {\n width: 100%;\n}\n"]}
@@ -1,5 +1,16 @@
1
1
  <%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
2
- <%= render(Primer::OpenProject::FlexLayout.new) do |flex| %>
2
+ <%= render(Primer::OpenProject::FlexLayout.new(
3
+ data: {
4
+ target: "collapsible-header.triggerElement",
5
+ action: "click:collapsible-header#toggle keydown:collapsible-header#toggleViaKeyboard"
6
+ },
7
+ tabindex: 0,
8
+ role: "button",
9
+ aria: {
10
+ expanded: !@collapsed,
11
+ },
12
+ classes: "CollapsibleHeader--triggerArea"
13
+ )) do |flex| %>
3
14
  <%= flex.with_row do %>
4
15
  <%= title %>
5
16
  <% if count? %>
@@ -17,3 +17,7 @@
17
17
  display: none;
18
18
  }
19
19
  }
20
+
21
+ .CollapsibleHeader--triggerArea {
22
+ width: 100%;
23
+ }
@@ -32,39 +32,43 @@ module Primer
32
32
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
33
33
  renders_one :description, lambda { |**system_arguments, &block|
34
34
  system_arguments[:color] ||= :subtle
35
+ system_arguments[:hidden] = @collapsed
36
+
35
37
  system_arguments[:data] = merge_data(
36
38
  system_arguments, {
37
- data: {
39
+ data: {
38
40
  targets: "collapsible-header.collapsibleElements"
39
41
  }
40
42
  }
41
43
  )
42
- system_arguments[:hidden] = @collapsed
43
44
 
44
45
  Primer::Beta::Text.new(**system_arguments, &block)
45
46
  }
46
47
 
47
-
48
+ # @param id [String] The unique ID of the collapsible header.
48
49
  # @param collapsed [Boolean] Whether the header is collapsed on initial render.
49
50
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
50
- def initialize(collapsed: false, box:, **system_arguments)
51
+ def initialize(id: self.class.generate_id, collapsed: false, box:, **system_arguments)
51
52
  @collapsed = collapsed
52
53
  @box = box
53
54
  @system_arguments = system_arguments
54
-
55
+ @system_arguments[:id] = id
55
56
  @system_arguments[:tag] = "collapsible-header"
56
57
  @system_arguments[:classes] = class_names(
57
58
  system_arguments[:classes],
58
59
  "CollapsibleHeader",
59
60
  "CollapsibleHeader--collapsed" => @collapsed
60
61
  )
61
- @system_arguments[:data] = merge_data(
62
- @system_arguments, {
63
- data: {
64
- action: "click:collapsible-header#toggle"
65
- } }
66
- )
67
- @system_arguments[:data][:collapsed] = true if @collapsed
62
+ if @collapsed
63
+ @system_arguments[:data] = merge_data(
64
+ @system_arguments, {
65
+ data: {
66
+ collapsed: @collapsed
67
+ }
68
+ }
69
+ )
70
+ end
71
+
68
72
  end
69
73
 
70
74
  private
@@ -1,8 +1,10 @@
1
1
  export declare abstract class CollapsibleElement extends HTMLElement {
2
2
  arrowDown: Element;
3
3
  arrowUp: Element;
4
+ triggerElement: HTMLElement;
4
5
  collapsibleElements: HTMLElement[];
5
6
  collapsed: boolean;
7
+ toggleViaKeyboard(event: KeyboardEvent): void;
6
8
  toggle(): void;
7
9
  attributeChangedCallback(name: string): void;
8
10
  hideAll(): void;
@@ -11,6 +11,12 @@ export class CollapsibleElement extends HTMLElement {
11
11
  super(...arguments);
12
12
  this.collapsed = false;
13
13
  }
14
+ toggleViaKeyboard(event) {
15
+ if (event.code === 'Enter' || event.code === 'Space') {
16
+ event.preventDefault();
17
+ this.toggle();
18
+ }
19
+ }
14
20
  toggle() {
15
21
  this.collapsed = !this.collapsed;
16
22
  }
@@ -28,6 +34,7 @@ export class CollapsibleElement extends HTMLElement {
28
34
  // For whatever reason, setting `hidden` directly does not work on the SVGs
29
35
  this.arrowDown?.removeAttribute('hidden');
30
36
  this.arrowUp?.setAttribute('hidden', '');
37
+ this.triggerElement.setAttribute('aria-expanded', 'false');
31
38
  for (const el of this.collapsibleElements) {
32
39
  el.hidden = true;
33
40
  }
@@ -36,6 +43,7 @@ export class CollapsibleElement extends HTMLElement {
36
43
  expandAll() {
37
44
  this.arrowUp?.removeAttribute('hidden');
38
45
  this.arrowDown?.setAttribute('hidden', '');
46
+ this.triggerElement.setAttribute('aria-expanded', 'true');
39
47
  for (const el of this.collapsibleElements) {
40
48
  el.hidden = false;
41
49
  }
@@ -48,6 +56,9 @@ __decorate([
48
56
  __decorate([
49
57
  target
50
58
  ], CollapsibleElement.prototype, "arrowUp", void 0);
59
+ __decorate([
60
+ target
61
+ ], CollapsibleElement.prototype, "triggerElement", void 0);
51
62
  __decorate([
52
63
  targets
53
64
  ], CollapsibleElement.prototype, "collapsibleElements", void 0);
@@ -4,10 +4,18 @@ import {attr, target, targets} from '@github/catalyst'
4
4
  export abstract class CollapsibleElement extends HTMLElement {
5
5
  @target arrowDown: Element
6
6
  @target arrowUp: Element
7
+ @target triggerElement: HTMLElement
7
8
  @targets collapsibleElements: HTMLElement[]
8
9
 
9
10
  @attr collapsed = false
10
11
 
12
+ toggleViaKeyboard(event: KeyboardEvent) {
13
+ if (event.code === 'Enter' || event.code === 'Space') {
14
+ event.preventDefault()
15
+ this.toggle()
16
+ }
17
+ }
18
+
11
19
  toggle() {
12
20
  this.collapsed = !this.collapsed
13
21
  }
@@ -26,6 +34,7 @@ export abstract class CollapsibleElement extends HTMLElement {
26
34
  // For whatever reason, setting `hidden` directly does not work on the SVGs
27
35
  this.arrowDown?.removeAttribute('hidden')
28
36
  this.arrowUp?.setAttribute('hidden', '')
37
+ this.triggerElement.setAttribute('aria-expanded', 'false')
29
38
 
30
39
  for (const el of this.collapsibleElements) {
31
40
  el.hidden = true
@@ -37,6 +46,7 @@ export abstract class CollapsibleElement extends HTMLElement {
37
46
  expandAll() {
38
47
  this.arrowUp?.removeAttribute('hidden')
39
48
  this.arrowDown?.setAttribute('hidden', '')
49
+ this.triggerElement.setAttribute('aria-expanded', 'true')
40
50
 
41
51
  for (const el of this.collapsibleElements) {
42
52
  el.hidden = false
@@ -1,7 +1,14 @@
1
1
  <%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
2
2
  <%= render(Primer::OpenProject::FlexLayout.new) do |flex| %>
3
3
  <%= flex.with_row(classes: "CollapsibleSection--triggerArea",
4
- data: { action: "click:collapsible-section#toggle" }) do %>
4
+ id: @title_id,
5
+ tabindex: 0,
6
+ role: "button",
7
+ data: {
8
+ action: "click:collapsible-section#toggle keydown:collapsible-section#toggleViaKeyboard",
9
+ target: "collapsible-section.triggerElement"
10
+ },
11
+ aria: { expanded: !@collapsed, controls: @content_id }) do %>
5
12
  <%= render(Primer::OpenProject::FlexLayout.new(display: :flex, align_items: :center)) do |header| %>
6
13
  <%= header.with_column do %>
7
14
  <%= title %>
@@ -18,7 +25,12 @@
18
25
  <% end %>
19
26
  <% end %>
20
27
  <% end %>
21
- <%= flex.with_row(hidden: @collapsed, mt: 3, data: { targets: "collapsible-section.collapsibleElements" }) do %>
28
+ <%= flex.with_row(hidden: @collapsed,
29
+ mt: 3,
30
+ role: "region",
31
+ id: @content_id,
32
+ data: { targets: "collapsible-section.collapsibleElements" },
33
+ aria: { labelledby: @title_id }) do %>
22
34
  <%= collapsible_content %>
23
35
  <% end %>
24
36
  <% end %>
@@ -47,13 +47,17 @@ module Primer
47
47
  Primer::BaseComponent.new(tag: :div, **system_arguments)
48
48
  }
49
49
 
50
+ # @param id [String] The unique ID of the collapsible section.
50
51
  # @param collapsed [Boolean] Whether the section is collapsed on initial render.
51
52
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
52
- def initialize(collapsed: false, **system_arguments)
53
+ def initialize(id: self.class.generate_id, collapsed: false, **system_arguments)
54
+ @title_id = "#{id}-title"
55
+ @content_id = "#{id}-content"
53
56
  @collapsed = collapsed
54
57
 
55
58
  @system_arguments = deny_tag_argument(**system_arguments)
56
59
  @system_arguments[:tag] = "collapsible-section"
60
+ @system_arguments[:id] = id
57
61
  @system_arguments[:classes] = class_names(
58
62
  @system_arguments[:classes],
59
63
  "CollapsibleSection",
@@ -1,4 +1,8 @@
1
1
  <%= render @dialog do |dialog| %>
2
+ <% unless header.present? %>
3
+ <% dialog.with_header(close_label: I18n.t("button_close")) %>
4
+ <% end %>
5
+
2
6
  <danger-dialog-form-helper>
3
7
  <%= render(@form_wrapper) do %>
4
8
  <scrollable-region data-labelled-by="<%= labelledby %>">
@@ -1,10 +1,15 @@
1
1
  <%= render @dialog do |dialog| %>
2
+ <% unless header.present? %>
3
+ <% dialog.with_header(close_label: I18n.t("button_close")) %>
4
+ <% end %>
5
+
2
6
  <% dialog.with_body do %>
3
7
  <%= feedback_message %>
4
8
  <% if additional_details.present? %>
5
9
  <%= additional_details %>
6
10
  <% end %>
7
11
  <% end %>
12
+
8
13
  <% dialog.with_footer do %>
9
14
  <% if footer.present? %>
10
15
  <%= footer %>
@@ -6,7 +6,7 @@ module Primer
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 64
9
- PATCH = 0
9
+ PATCH = 1
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -5174,6 +5174,12 @@
5174
5174
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/border_box/collapsible_header.rb",
5175
5175
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/border_box/collapsible_header/default/",
5176
5176
  "parameters": [
5177
+ {
5178
+ "name": "id",
5179
+ "type": "String",
5180
+ "default": "`self.class.generate_id`",
5181
+ "description": "The unique ID of the collapsible header."
5182
+ },
5177
5183
  {
5178
5184
  "name": "collapsed",
5179
5185
  "type": "Boolean",
@@ -5234,6 +5240,12 @@
5234
5240
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/collapsible_section.rb",
5235
5241
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/collapsible_section/default/",
5236
5242
  "parameters": [
5243
+ {
5244
+ "name": "id",
5245
+ "type": "String",
5246
+ "default": "`self.class.generate_id`",
5247
+ "description": "The unique ID of the collapsible section."
5248
+ },
5237
5249
  {
5238
5250
  "name": "collapsed",
5239
5251
  "type": "Boolean",
data/static/classes.json CHANGED
@@ -243,6 +243,9 @@
243
243
  "CollapsibleHeader": [
244
244
  "Primer::OpenProject::BorderBox::CollapsibleHeader"
245
245
  ],
246
+ "CollapsibleHeader--triggerArea": [
247
+ "Primer::OpenProject::BorderBox::CollapsibleHeader"
248
+ ],
246
249
  "CollapsibleSection--triggerArea": [
247
250
  "Primer::OpenProject::CollapsibleSection"
248
251
  ],
@@ -17690,6 +17690,12 @@
17690
17690
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/border_box/collapsible_header.rb",
17691
17691
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/border_box/collapsible_header/default/",
17692
17692
  "parameters": [
17693
+ {
17694
+ "name": "id",
17695
+ "type": "String",
17696
+ "default": "`self.class.generate_id`",
17697
+ "description": "The unique ID of the collapsible header."
17698
+ },
17693
17699
  {
17694
17700
  "name": "collapsed",
17695
17701
  "type": "Boolean",
@@ -17952,6 +17958,12 @@
17952
17958
  "source": "https://github.com/primer/view_components/tree/main/app/components/primer/open_project/collapsible_section.rb",
17953
17959
  "lookbook": "https://primer.style/view-components/lookbook/inspect/primer/open_project/collapsible_section/default/",
17954
17960
  "parameters": [
17961
+ {
17962
+ "name": "id",
17963
+ "type": "String",
17964
+ "default": "`self.class.generate_id`",
17965
+ "description": "The unique ID of the collapsible section."
17966
+ },
17955
17967
  {
17956
17968
  "name": "collapsed",
17957
17969
  "type": "Boolean",
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.64.0
4
+ version: 0.64.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: 2025-04-29 00:00:00.000000000 Z
12
+ date: 2025-04-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionview