openproject-primer_view_components 0.89.2 → 0.91.0

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 (102) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -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/action_bar.css.map +1 -1
  8. data/app/components/primer/alpha/action_bar.pcss +0 -3
  9. data/app/components/primer/alpha/action_list.css.map +1 -1
  10. data/app/components/primer/alpha/action_list.pcss +0 -2
  11. data/app/components/primer/alpha/auto_complete.css +1 -1
  12. data/app/components/primer/alpha/auto_complete.css.json +2 -4
  13. data/app/components/primer/alpha/auto_complete.css.map +1 -1
  14. data/app/components/primer/alpha/auto_complete.pcss +3 -10
  15. data/app/components/primer/alpha/banner.css.map +1 -1
  16. data/app/components/primer/alpha/banner.pcss +0 -1
  17. data/app/components/primer/alpha/button_marketing.css.map +1 -1
  18. data/app/components/primer/alpha/button_marketing.pcss +4 -4
  19. data/app/components/primer/alpha/layout.css +1 -1
  20. data/app/components/primer/alpha/layout.css.map +1 -1
  21. data/app/components/primer/alpha/layout.pcss +3 -1
  22. data/app/components/primer/alpha/menu.css.map +1 -1
  23. data/app/components/primer/alpha/menu.pcss +0 -6
  24. data/app/components/primer/alpha/segmented_control.css.map +1 -1
  25. data/app/components/primer/alpha/segmented_control.pcss +0 -2
  26. data/app/components/primer/alpha/tab_nav.css.map +1 -1
  27. data/app/components/primer/alpha/tab_nav.pcss +0 -5
  28. data/app/components/primer/alpha/text_field.css +1 -1
  29. data/app/components/primer/alpha/text_field.css.json +2 -1
  30. data/app/components/primer/alpha/text_field.css.map +1 -1
  31. data/app/components/primer/alpha/text_field.pcss +14 -7
  32. data/app/components/primer/alpha/toggle_switch.css +1 -1
  33. data/app/components/primer/alpha/toggle_switch.css.map +1 -1
  34. data/app/components/primer/alpha/toggle_switch.pcss +8 -6
  35. data/app/components/primer/alpha/tree_view/sub_tree_node.rb +2 -2
  36. data/app/components/primer/alpha/tree_view.css.map +1 -1
  37. data/app/components/primer/alpha/tree_view.pcss +1 -0
  38. data/app/components/primer/alpha/underline_nav.css.map +1 -1
  39. data/app/components/primer/alpha/underline_nav.pcss +0 -3
  40. data/app/components/primer/base_component.rb +1 -0
  41. data/app/components/primer/beta/blankslate.css +1 -1
  42. data/app/components/primer/beta/blankslate.css.map +1 -1
  43. data/app/components/primer/beta/blankslate.pcss +2 -53
  44. data/app/components/primer/beta/breadcrumbs.css +1 -1
  45. data/app/components/primer/beta/breadcrumbs.css.json +2 -1
  46. data/app/components/primer/beta/breadcrumbs.css.map +1 -1
  47. data/app/components/primer/beta/breadcrumbs.pcss +6 -5
  48. data/app/components/primer/beta/button.css.map +1 -1
  49. data/app/components/primer/beta/button.pcss +0 -1
  50. data/app/components/primer/beta/popover.css +1 -1
  51. data/app/components/primer/beta/popover.css.json +22 -16
  52. data/app/components/primer/beta/popover.css.map +1 -1
  53. data/app/components/primer/beta/popover.pcss +132 -101
  54. data/app/components/primer/beta/state.css.map +1 -1
  55. data/app/components/primer/beta/state.pcss +0 -1
  56. data/app/components/primer/beta/subhead.css.map +1 -1
  57. data/app/components/primer/beta/subhead.pcss +0 -2
  58. data/app/components/primer/beta/timeline_item.css.map +1 -1
  59. data/app/components/primer/beta/timeline_item.pcss +0 -5
  60. data/app/components/primer/beta/truncate.css.map +1 -1
  61. data/app/components/primer/beta/truncate.pcss +0 -1
  62. data/app/components/primer/component.rb +16 -0
  63. data/app/components/primer/open_project/border_box/collapsible_header.css.map +1 -1
  64. data/app/components/primer/open_project/border_box/collapsible_header.html.erb +1 -1
  65. data/app/components/primer/open_project/border_box/collapsible_header.pcss +3 -1
  66. data/app/components/primer/open_project/border_box/collapsible_header.rb +10 -9
  67. data/app/components/primer/open_project/border_grid.css +1 -1
  68. data/app/components/primer/open_project/border_grid.css.map +1 -1
  69. data/app/components/primer/open_project/border_grid.pcss +11 -9
  70. data/app/components/primer/open_project/collapsible.d.ts +1 -1
  71. data/app/components/primer/open_project/collapsible.js +8 -4
  72. data/app/components/primer/open_project/collapsible.ts +10 -4
  73. data/app/components/primer/open_project/collapsible_section.html.erb +6 -10
  74. data/app/components/primer/open_project/collapsible_section.rb +8 -0
  75. data/app/components/primer/open_project/filterable_tree_view.css.map +1 -1
  76. data/app/components/primer/open_project/filterable_tree_view.pcss +2 -0
  77. data/app/components/primer/open_project/page_header.css.map +1 -1
  78. data/app/components/primer/open_project/page_header.pcss +2 -0
  79. data/app/components/primer/open_project/pagination.css +1 -1
  80. data/app/components/primer/open_project/pagination.css.map +1 -1
  81. data/app/components/primer/open_project/pagination.pcss +4 -1
  82. data/app/components/primer/open_project/side_panel/section.css +1 -1
  83. data/app/components/primer/open_project/side_panel/section.css.map +1 -1
  84. data/app/components/primer/open_project/side_panel/section.pcss +3 -3
  85. data/app/controllers/primer/view_components/tree_view_items_controller.rb +2 -1
  86. data/app/lib/primer/forms/dsl/input.rb +5 -1
  87. data/app/lib/primer/safe_href_helper.rb +36 -0
  88. data/app/views/primer/view_components/tree_view_items/async_alpha.html_fragment.erb +4 -4
  89. data/lib/primer/static/generate_previews.rb +1 -1
  90. data/lib/primer/view_components/version.rb +2 -2
  91. data/previews/primer/alpha/tree_view_preview/async_alpha.html.erb +2 -2
  92. data/previews/primer/alpha/tree_view_preview/async_form_input.html.erb +16 -0
  93. data/previews/primer/alpha/tree_view_preview.rb +13 -2
  94. data/previews/primer/open_project/collapsible_section_preview/with_link_in_title.html.erb +6 -0
  95. data/previews/primer/open_project/collapsible_section_preview.rb +9 -0
  96. data/static/classes.json +21 -0
  97. data/static/classnames.cjs +507 -0
  98. data/static/classnames.d.ts +2 -0
  99. data/static/classnames.js +509 -0
  100. data/static/info_arch.json +26 -0
  101. data/static/previews.json +2404 -2378
  102. metadata +9 -3
@@ -17,6 +17,7 @@
17
17
  border-radius: var(--borderRadius-medium);
18
18
 
19
19
  /* adding !important to override utility classes used in dotcom */
20
+ /* stylelint-disable-next-line primer/box-shadow -- intentional legacy shadow var with fallback, kept for dotcom compatibility */
20
21
  box-shadow: var(--shadow-floating-legacy, var(--color-shadow-large)) !important;
21
22
 
22
23
  /* Carets */
@@ -54,26 +55,36 @@
54
55
  }
55
56
  }
56
57
 
58
+ /* The caret variants below are authored as expanded per-class selectors
59
+ ** (rather than nesting `&::before`/`&::after` under a selector list) so each
60
+ ** rule's subject buckets by its own class during style recalc. The merged
61
+ ** `:is(.Popover-message--…, …)::before` form cannot be fast-rejected by Blink
62
+ ** and shows up as pure slow-path selector matching. */
63
+
57
64
  /* Bottom-oriented carets */
58
- .Popover-message--bottom,
59
- .Popover-message--bottom-right,
60
- .Popover-message--bottom-left {
61
- &::before,
62
- &::after {
63
- top: auto;
64
- border-bottom-color: transparent;
65
- }
65
+ .Popover-message--bottom::before,
66
+ .Popover-message--bottom::after,
67
+ .Popover-message--bottom-right::before,
68
+ .Popover-message--bottom-right::after,
69
+ .Popover-message--bottom-left::before,
70
+ .Popover-message--bottom-left::after {
71
+ top: auto;
72
+ border-bottom-color: transparent;
73
+ }
66
74
 
67
- &::before {
68
- bottom: -16px;
69
- border-top-color: var(--borderColor-default);
70
- }
75
+ .Popover-message--bottom::before,
76
+ .Popover-message--bottom-right::before,
77
+ .Popover-message--bottom-left::before {
78
+ bottom: -16px;
79
+ border-top-color: var(--borderColor-default);
80
+ }
71
81
 
72
- &::after {
73
- bottom: -14px;
74
- /* stylelint-disable-next-line primer/colors */
75
- border-top-color: var(--overlay-bgColor);
76
- }
82
+ .Popover-message--bottom::after,
83
+ .Popover-message--bottom-right::after,
84
+ .Popover-message--bottom-left::after {
85
+ bottom: -14px;
86
+ /* stylelint-disable-next-line primer/colors */
87
+ border-top-color: var(--overlay-bgColor);
77
88
  }
78
89
 
79
90
  /* Top and Bottom: Right-oriented carets */
@@ -81,21 +92,25 @@
81
92
  .Popover-message--bottom-right {
82
93
  right: -9px;
83
94
  margin-right: 0;
95
+ }
84
96
 
85
- &::before,
86
- &::after {
87
- left: auto;
88
- margin-left: 0;
89
- }
97
+ .Popover-message--top-right::before,
98
+ .Popover-message--top-right::after,
99
+ .Popover-message--bottom-right::before,
100
+ .Popover-message--bottom-right::after {
101
+ left: auto;
102
+ margin-left: 0;
103
+ }
90
104
 
91
- &::before {
92
- right: var(--base-size-20);
93
- }
105
+ .Popover-message--top-right::before,
106
+ .Popover-message--bottom-right::before {
107
+ right: var(--base-size-20);
108
+ }
94
109
 
95
- &::after {
96
- right: var(--base-size-20);
97
- margin-right: 1px;
98
- }
110
+ .Popover-message--top-right::after,
111
+ .Popover-message--bottom-right::after {
112
+ right: var(--base-size-20);
113
+ margin-right: 1px;
99
114
  }
100
115
 
101
116
  /* Top and Bottom: Left-oriented carets */
@@ -103,101 +118,117 @@
103
118
  .Popover-message--bottom-left {
104
119
  left: -9px;
105
120
  margin-left: 0;
121
+ }
106
122
 
107
- &::before,
108
- &::after {
109
- left: var(--base-size-24);
110
- margin-left: 0;
111
- }
123
+ .Popover-message--top-left::before,
124
+ .Popover-message--top-left::after,
125
+ .Popover-message--bottom-left::before,
126
+ .Popover-message--bottom-left::after {
127
+ left: var(--base-size-24);
128
+ margin-left: 0;
129
+ }
112
130
 
113
- &::after {
114
- left: var(--base-size-24);
115
- margin-left: 1px;
116
- }
131
+ .Popover-message--top-left::after,
132
+ .Popover-message--bottom-left::after {
133
+ left: var(--base-size-24);
134
+ margin-left: 1px;
117
135
  }
118
136
 
119
137
  /* Right- and Left-oriented carets */
120
- .Popover-message--right,
121
- .Popover-message--right-top,
122
- .Popover-message--right-bottom,
123
- .Popover-message--left,
124
- .Popover-message--left-top,
125
- .Popover-message--left-bottom {
126
- &::before,
127
- &::after {
128
- top: 50%;
129
- left: auto;
130
- margin-left: 0;
131
- border-bottom-color: transparent;
132
- }
138
+ .Popover-message--right::before,
139
+ .Popover-message--right::after,
140
+ .Popover-message--right-top::before,
141
+ .Popover-message--right-top::after,
142
+ .Popover-message--right-bottom::before,
143
+ .Popover-message--right-bottom::after,
144
+ .Popover-message--left::before,
145
+ .Popover-message--left::after,
146
+ .Popover-message--left-top::before,
147
+ .Popover-message--left-top::after,
148
+ .Popover-message--left-bottom::before,
149
+ .Popover-message--left-bottom::after {
150
+ top: 50%;
151
+ left: auto;
152
+ margin-left: 0;
153
+ border-bottom-color: transparent;
154
+ }
133
155
 
134
- &::before {
135
- margin-top: -9px;
136
- }
156
+ .Popover-message--right::before,
157
+ .Popover-message--right-top::before,
158
+ .Popover-message--right-bottom::before,
159
+ .Popover-message--left::before,
160
+ .Popover-message--left-top::before,
161
+ .Popover-message--left-bottom::before {
162
+ margin-top: -9px;
163
+ }
137
164
 
138
- &::after {
139
- margin-top: -8px;
140
- }
165
+ .Popover-message--right::after,
166
+ .Popover-message--right-top::after,
167
+ .Popover-message--right-bottom::after,
168
+ .Popover-message--left::after,
169
+ .Popover-message--left-top::after,
170
+ .Popover-message--left-bottom::after {
171
+ margin-top: -8px;
141
172
  }
142
173
 
143
174
  /* Right-oriented carets */
144
- .Popover-message--right,
145
- .Popover-message--right-top,
146
- .Popover-message--right-bottom {
147
- &::before {
148
- right: -16px;
149
- border-left-color: var(--borderColor-default);
150
- }
175
+ .Popover-message--right::before,
176
+ .Popover-message--right-top::before,
177
+ .Popover-message--right-bottom::before {
178
+ right: -16px;
179
+ border-left-color: var(--borderColor-default);
180
+ }
151
181
 
152
- &::after {
153
- right: -14px;
154
- /* stylelint-disable-next-line primer/colors */
155
- border-left-color: var(--overlay-bgColor);
156
- }
182
+ .Popover-message--right::after,
183
+ .Popover-message--right-top::after,
184
+ .Popover-message--right-bottom::after {
185
+ right: -14px;
186
+ /* stylelint-disable-next-line primer/colors */
187
+ border-left-color: var(--overlay-bgColor);
157
188
  }
158
189
 
159
190
  /* Left-oriented carets */
160
- .Popover-message--left,
161
- .Popover-message--left-top,
162
- .Popover-message--left-bottom {
163
- &::before {
164
- left: -16px;
165
- border-right-color: var(--borderColor-default);
166
- }
191
+ .Popover-message--left::before,
192
+ .Popover-message--left-top::before,
193
+ .Popover-message--left-bottom::before {
194
+ left: -16px;
195
+ border-right-color: var(--borderColor-default);
196
+ }
167
197
 
168
- &::after {
169
- left: -14px;
170
- margin-bottom: 1px;
171
- /* stylelint-disable-next-line primer/colors */
172
- border-right-color: var(--overlay-bgColor);
173
- }
198
+ .Popover-message--left::after,
199
+ .Popover-message--left-top::after,
200
+ .Popover-message--left-bottom::after {
201
+ left: -14px;
202
+ margin-bottom: 1px;
203
+ /* stylelint-disable-next-line primer/colors */
204
+ border-right-color: var(--overlay-bgColor);
174
205
  }
175
206
 
176
207
  /* Right and Left: Top-oriented carets */
177
- .Popover-message--right-top,
178
- .Popover-message--left-top {
179
- &::before,
180
- &::after {
181
- top: var(--base-size-24);
182
- }
208
+ .Popover-message--right-top::before,
209
+ .Popover-message--right-top::after,
210
+ .Popover-message--left-top::before,
211
+ .Popover-message--left-top::after {
212
+ top: var(--base-size-24);
183
213
  }
184
214
 
185
215
  /* Right and Left: Bottom-oriented carets */
186
- .Popover-message--right-bottom,
187
- .Popover-message--left-bottom {
188
- &::before,
189
- &::after {
190
- top: auto;
191
- }
216
+ .Popover-message--right-bottom::before,
217
+ .Popover-message--right-bottom::after,
218
+ .Popover-message--left-bottom::before,
219
+ .Popover-message--left-bottom::after {
220
+ top: auto;
221
+ }
192
222
 
193
- &::before {
194
- bottom: var(--base-size-16);
195
- }
223
+ .Popover-message--right-bottom::before,
224
+ .Popover-message--left-bottom::before {
225
+ bottom: var(--base-size-16);
226
+ }
196
227
 
197
- &::after {
198
- bottom: var(--base-size-16);
199
- margin-bottom: 1px;
200
- }
228
+ .Popover-message--right-bottom::after,
229
+ .Popover-message--left-bottom::after {
230
+ bottom: var(--base-size-16);
231
+ margin-bottom: 1px;
201
232
  }
202
233
 
203
234
  @media (min-width: 544px) {
@@ -1 +1 @@
1
- {"version":3,"sources":["state.pcss"],"names":[],"mappings":"AAIA,cAEE,oBAAqB,CAErB,qEAAsE,CACtE,sCAAuC,CACvC,0CAA2C,CAE3C,+BAAgC,CAChC,iBAAkB,CAClB,kBAAmB,CAEnB,iBACF,CAEA,4BAGE,+BAAgC,CAChC,8EAAgF,CAChF,0CAAiD,CACjD,sGACF,CAEA,aAEE,wEAA0E,CAC1E,iEACF,CAEA,4BALE,+BASF,CAJA,eAEE,wEAA0E,CAC1E,iEACF,CAEA,eACE,+BAAgC,CAChC,4EAA8E,CAC9E,mEACF,CAIA,cAEE,cAAe,CACf,qCAAsC,CAEtC,+BAKF,CAHE,uBACE,SACF","file":"state.css","sourcesContent":["/* State */\n\n/* Default 32px */\n\n.state, /* TODO: Deprecate */\n.State {\n display: inline-block;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--base-size-4) var(--control-medium-paddingInline-normal);\n font-size: var(--text-body-size-medium);\n font-weight: var(--base-text-weight-medium);\n /* stylelint-disable-next-line primer/typography */\n line-height: var(--base-size-20);\n text-align: center;\n white-space: nowrap;\n /* stylelint-disable-next-line primer/borders */\n border-radius: 2em;\n}\n\n.state, /* TODO: Deprecate */\n.State,\n.State--draft {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-draft-emphasis, var(--bgColor-neutral-emphasis));\n border: var(--borderWidth-thin) solid transparent;\n box-shadow: var(--boxShadow-thin) var(--borderColor-draft-emphasis, var(--borderColor-neutral-emphasis));\n}\n\n.State--open {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-open-emphasis, var(--color-open-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-open-emphasis);\n}\n\n.State--merged {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-done-emphasis, var(--color-done-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-done-emphasis);\n}\n\n.State--closed {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-closed-emphasis, var(--color-closed-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-closed-emphasis);\n}\n\n/* Small 24px */\n\n.State--small {\n /* stylelint-disable-next-line primer/spacing */\n padding: 0 10px;\n font-size: var(--text-body-size-small);\n /* stylelint-disable-next-line primer/typography */\n line-height: var(--base-size-24);\n\n & .octicon {\n width: 1em; /* Ensures different icons don't change State indicator width */\n }\n}\n"]}
1
+ {"version":3,"sources":["state.pcss"],"names":[],"mappings":"AAIA,cAEE,oBAAqB,CACrB,qEAAsE,CACtE,sCAAuC,CACvC,0CAA2C,CAE3C,+BAAgC,CAChC,iBAAkB,CAClB,kBAAmB,CAEnB,iBACF,CAEA,4BAGE,+BAAgC,CAChC,8EAAgF,CAChF,0CAAiD,CACjD,sGACF,CAEA,aAEE,wEAA0E,CAC1E,iEACF,CAEA,4BALE,+BASF,CAJA,eAEE,wEAA0E,CAC1E,iEACF,CAEA,eACE,+BAAgC,CAChC,4EAA8E,CAC9E,mEACF,CAIA,cAEE,cAAe,CACf,qCAAsC,CAEtC,+BAKF,CAHE,uBACE,SACF","file":"state.css","sourcesContent":["/* State */\n\n/* Default 32px */\n\n.state, /* TODO: Deprecate */\n.State {\n display: inline-block;\n padding: var(--base-size-4) var(--control-medium-paddingInline-normal);\n font-size: var(--text-body-size-medium);\n font-weight: var(--base-text-weight-medium);\n /* stylelint-disable-next-line primer/typography */\n line-height: var(--base-size-20);\n text-align: center;\n white-space: nowrap;\n /* stylelint-disable-next-line primer/borders */\n border-radius: 2em;\n}\n\n.state, /* TODO: Deprecate */\n.State,\n.State--draft {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-draft-emphasis, var(--bgColor-neutral-emphasis));\n border: var(--borderWidth-thin) solid transparent;\n box-shadow: var(--boxShadow-thin) var(--borderColor-draft-emphasis, var(--borderColor-neutral-emphasis));\n}\n\n.State--open {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-open-emphasis, var(--color-open-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-open-emphasis);\n}\n\n.State--merged {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-done-emphasis, var(--color-done-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-done-emphasis);\n}\n\n.State--closed {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-closed-emphasis, var(--color-closed-emphasis));\n box-shadow: var(--boxShadow-thin) var(--borderColor-closed-emphasis);\n}\n\n/* Small 24px */\n\n.State--small {\n /* stylelint-disable-next-line primer/spacing */\n padding: 0 10px;\n font-size: var(--text-body-size-small);\n /* stylelint-disable-next-line primer/typography */\n line-height: var(--base-size-24);\n\n & .octicon {\n width: 1em; /* Ensures different icons don't change State indicator width */\n }\n}\n"]}
@@ -5,7 +5,6 @@
5
5
  .state, /* TODO: Deprecate */
6
6
  .State {
7
7
  display: inline-block;
8
- /* stylelint-disable-next-line primer/spacing */
9
8
  padding: var(--base-size-4) var(--control-medium-paddingInline-normal);
10
9
  font-size: var(--text-body-size-medium);
11
10
  font-weight: var(--base-text-weight-medium);
@@ -1 +1 @@
1
- {"version":3,"sources":["subhead.pcss"],"names":[],"mappings":"AAEA,SACE,YAAa,CAEb,6CAA8C,CAE9C,qCAAsC,CACtC,oEAAqE,CACrE,kBAAmB,CACnB,wBACF,CAGA,mBACE,8BACF,CAGA,iBACE,0CAA2C,CAC3C,aAAc,CACd,OACF,CAEA,wBAEE,6BACF,CAEA,yBACE,uCACF,CAGA,yBACE,4CAA6C,CAC7C,2BACF,CAGA,qBACE,sCAAuC,CACvC,0BAA2B,CAC3B,WAAY,CACZ,OACF,CAGA,iBACE,iEAAkE,CAClE,iBAAkB,CAClB,wBAAyB,CACzB,OAKF,CAHE,sCACE,6BACF","file":"subhead.css","sourcesContent":["/* Subhead */\n\n.Subhead {\n display: flex;\n /* stylelint-disable-next-line primer/spacing */\n padding-bottom: var(--stack-padding-condensed);\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-normal);\n border-bottom: var(--borderWidth-thin) solid var(--borderColor-muted);\n flex-flow: row wrap;\n justify-content: flex-end; /* Keep actions right aligned. */\n}\n\n/* Modifier class to give a lot of breathing room between sections of content. */\n.Subhead--spacious {\n margin-top: var(--base-size-40);\n}\n\n/* <h2> sized heading with normal font weight */\n.Subhead-heading {\n font-weight: var(--base-text-weight-normal);\n flex: 1 1 auto;\n order: 0;\n}\n\n.Subhead-heading--large {\n /* stylelint-disable-next-line primer/typography */\n font-size: var(--base-size-24);\n}\n\n.Subhead-heading--medium {\n font-size: var(--text-title-size-medium);\n}\n\n/* Make the text bold and red for dangerous content */\n.Subhead-heading--danger {\n font-weight: var(--base-text-weight-semibold);\n color: var(--fgColor-danger);\n}\n\n/* One-liner of supporting text */\n.Subhead-description {\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-muted);\n flex: 1 100%;\n order: 2;\n}\n\n/* Add 1 or 2 buttons to the right of the heading */\n.Subhead-actions {\n margin: var(--base-size-4) 0 var(--base-size-4) var(--base-size-4);\n align-self: center;\n justify-content: flex-end;\n order: 1;\n\n & + .Subhead-description {\n margin-top: var(--base-size-4);\n }\n}\n"]}
1
+ {"version":3,"sources":["subhead.pcss"],"names":[],"mappings":"AAEA,SACE,YAAa,CACb,6CAA8C,CAC9C,qCAAsC,CACtC,oEAAqE,CACrE,kBAAmB,CACnB,wBACF,CAGA,mBACE,8BACF,CAGA,iBACE,0CAA2C,CAC3C,aAAc,CACd,OACF,CAEA,wBAEE,6BACF,CAEA,yBACE,uCACF,CAGA,yBACE,4CAA6C,CAC7C,2BACF,CAGA,qBACE,sCAAuC,CACvC,0BAA2B,CAC3B,WAAY,CACZ,OACF,CAGA,iBACE,iEAAkE,CAClE,iBAAkB,CAClB,wBAAyB,CACzB,OAKF,CAHE,sCACE,6BACF","file":"subhead.css","sourcesContent":["/* Subhead */\n\n.Subhead {\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: row wrap;\n justify-content: flex-end; /* Keep actions right aligned. */\n}\n\n/* Modifier class to give a lot of breathing room between sections of content. */\n.Subhead--spacious {\n margin-top: var(--base-size-40);\n}\n\n/* <h2> sized heading with normal font weight */\n.Subhead-heading {\n font-weight: var(--base-text-weight-normal);\n flex: 1 1 auto;\n order: 0;\n}\n\n.Subhead-heading--large {\n /* stylelint-disable-next-line primer/typography */\n font-size: var(--base-size-24);\n}\n\n.Subhead-heading--medium {\n font-size: var(--text-title-size-medium);\n}\n\n/* Make the text bold and red for dangerous content */\n.Subhead-heading--danger {\n font-weight: var(--base-text-weight-semibold);\n color: var(--fgColor-danger);\n}\n\n/* One-liner of supporting text */\n.Subhead-description {\n font-size: var(--text-body-size-medium);\n color: var(--fgColor-muted);\n flex: 1 100%;\n order: 2;\n}\n\n/* Add 1 or 2 buttons to the right of the heading */\n.Subhead-actions {\n margin: var(--base-size-4) 0 var(--base-size-4) var(--base-size-4);\n align-self: center;\n justify-content: flex-end;\n order: 1;\n\n & + .Subhead-description {\n margin-top: var(--base-size-4);\n }\n}\n"]}
@@ -2,9 +2,7 @@
2
2
 
3
3
  .Subhead {
4
4
  display: flex;
5
- /* stylelint-disable-next-line primer/spacing */
6
5
  padding-bottom: var(--stack-padding-condensed);
7
- /* stylelint-disable-next-line primer/spacing */
8
6
  margin-bottom: var(--stack-gap-normal);
9
7
  border-bottom: var(--borderWidth-thin) solid var(--borderColor-muted);
10
8
  flex-flow: row wrap;
@@ -1 +1 @@
1
- {"version":3,"sources":["timeline_item.pcss"],"names":[],"mappings":"AAEA,cACE,iBAAkB,CAClB,YAAa,CAEb,qCAAsC,CAEtC,mCAoBF,CAjBE,qBACE,iBAAkB,CAClB,KAAM,CACN,QAAS,CACT,MAAO,CACP,aAAc,CACd,8BAA+B,CAC/B,UAAW,CAEX,yCACF,CAEA,yCACE,+CAAgD,CAEhD,mDACF,CAGF,oBACE,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,gCAAiC,CACjC,iCAAkC,CAElC,qDAAsD,CAEtD,qDAAwD,CACxD,0BAA2B,CAC3B,kBAAmB,CACnB,6CAA8C,CAE9C,4DAA6D,CAC7D,iBAAkB,CAClB,sBAAuB,CACvB,aACF,CAEA,6BACE,+BAAgC,CAChC,gDAAiD,CACjD,0CACF,CAEA,mBACE,WAAY,CACZ,cAAe,CAEf,yCAA0C,CAC1C,0BAA2B,CAC3B,SACF,CAEA,qBACE,iBAAkB,CAElB,UAAW,CACX,SACF,CAEA,oBACE,iBAAkB,CAClB,SAAU,CACV,gCAAiC,CACjC,QAAS,CAET,8CAAiD,CAEjD,iBAAkB,CAClB,uCAAwC,CACxC,QAAS,CACT,sEACF,CAEA,yBACE,8BAA+B,CAC/B,gBAgBF,CAbE,oCAEE,sCACF,CAEA,6CACE,0BAA2B,CAC3B,6BAA8B,CAC9B,gCAAiC,CACjC,0BAA2B,CAC3B,uCAAwC,CACxC,QACF","file":"timeline_item.css","sourcesContent":["/* TimelineItem */\n\n.TimelineItem {\n position: relative;\n display: flex;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--stack-padding-normal) 0;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--stack-gap-normal);\n\n /* The Timeline */\n &::before {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n display: block;\n width: var(--borderWidth-thick);\n content: '';\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--borderColor-muted);\n }\n\n &:target .TimelineItem-badge {\n border-color: var(--borderColor-accent-emphasis);\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: 0 0 0.2em var(--borderColor-accent-muted);\n }\n}\n\n.TimelineItem-badge {\n position: relative;\n z-index: 1;\n display: flex;\n width: var(--control-medium-size);\n height: var(--control-medium-size);\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--controlStack-medium-gap-condensed);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: calc(var(--control-medium-size) / -2 + 1px);\n color: var(--fgColor-muted);\n align-items: center;\n background-color: var(--timelineBadge-bgColor);\n /* stylelint-disable-next-line primer/colors */\n border: var(--borderWidth-thick) solid var(--bgColor-default);\n border-radius: 50%;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.TimelineItem-badge--success {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-success-emphasis);\n border: var(--borderWidth-thin) solid transparent;\n}\n\n.TimelineItem-body {\n min-width: 0;\n max-width: 100%;\n /* stylelint-disable-next-line primer/spacing */\n margin-top: calc(var(--base-size-4) + 1px);\n color: var(--fgColor-muted);\n flex: auto;\n}\n\n.TimelineItem-avatar {\n position: absolute;\n /* stylelint-disable-next-line primer/spacing */\n left: -72px;\n z-index: 1;\n}\n\n.TimelineItem-break {\n position: relative;\n z-index: 1;\n height: var(--stack-gap-spacious);\n margin: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: calc(var(--stack-gap-normal) * -1);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: -56px;\n background-color: var(--bgColor-default);\n border: 0;\n border-top: var(--borderWidth-thicker) solid var(--borderColor-default);\n}\n\n.TimelineItem--condensed {\n padding-top: var(--base-size-4);\n padding-bottom: 0;\n\n /* TimelineItem--condensed is often grouped. (commits) */\n &:last-child {\n /* stylelint-disable-next-line primer/spacing */\n padding-bottom: var(--stack-gap-normal);\n }\n\n & .TimelineItem-badge {\n height: var(--base-size-16);\n margin-top: var(--base-size-8);\n margin-bottom: var(--base-size-8);\n color: var(--fgColor-muted);\n background-color: var(--bgColor-default);\n border: 0;\n }\n}\n"]}
1
+ {"version":3,"sources":["timeline_item.pcss"],"names":[],"mappings":"AAEA,cACE,iBAAkB,CAClB,YAAa,CACb,qCAAsC,CACtC,mCAoBF,CAjBE,qBACE,iBAAkB,CAClB,KAAM,CACN,QAAS,CACT,MAAO,CACP,aAAc,CACd,8BAA+B,CAC/B,UAAW,CAEX,yCACF,CAEA,yCACE,+CAAgD,CAEhD,mDACF,CAGF,oBACE,iBAAkB,CAClB,SAAU,CACV,YAAa,CACb,gCAAiC,CACjC,iCAAkC,CAClC,qDAAsD,CAEtD,qDAAwD,CACxD,0BAA2B,CAC3B,kBAAmB,CACnB,6CAA8C,CAE9C,4DAA6D,CAC7D,iBAAkB,CAClB,sBAAuB,CACvB,aACF,CAEA,6BACE,+BAAgC,CAChC,gDAAiD,CACjD,0CACF,CAEA,mBACE,WAAY,CACZ,cAAe,CAEf,yCAA0C,CAC1C,0BAA2B,CAC3B,SACF,CAEA,qBACE,iBAAkB,CAElB,UAAW,CACX,SACF,CAEA,oBACE,iBAAkB,CAClB,SAAU,CACV,gCAAiC,CACjC,QAAS,CACT,8CAAiD,CAEjD,iBAAkB,CAClB,uCAAwC,CACxC,QAAS,CACT,sEACF,CAEA,yBACE,8BAA+B,CAC/B,gBAeF,CAZE,oCACE,sCACF,CAEA,6CACE,0BAA2B,CAC3B,6BAA8B,CAC9B,gCAAiC,CACjC,0BAA2B,CAC3B,uCAAwC,CACxC,QACF","file":"timeline_item.css","sourcesContent":["/* TimelineItem */\n\n.TimelineItem {\n position: relative;\n display: flex;\n padding: var(--stack-padding-normal) 0;\n margin-left: var(--stack-gap-normal);\n\n /* The Timeline */\n &::before {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n display: block;\n width: var(--borderWidth-thick);\n content: '';\n /* stylelint-disable-next-line primer/colors */\n background-color: var(--borderColor-muted);\n }\n\n &:target .TimelineItem-badge {\n border-color: var(--borderColor-accent-emphasis);\n /* stylelint-disable-next-line primer/box-shadow */\n box-shadow: 0 0 0.2em var(--borderColor-accent-muted);\n }\n}\n\n.TimelineItem-badge {\n position: relative;\n z-index: 1;\n display: flex;\n width: var(--control-medium-size);\n height: var(--control-medium-size);\n margin-right: var(--controlStack-medium-gap-condensed);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: calc(var(--control-medium-size) / -2 + 1px);\n color: var(--fgColor-muted);\n align-items: center;\n background-color: var(--timelineBadge-bgColor);\n /* stylelint-disable-next-line primer/colors */\n border: var(--borderWidth-thick) solid var(--bgColor-default);\n border-radius: 50%;\n justify-content: center;\n flex-shrink: 0;\n}\n\n.TimelineItem-badge--success {\n color: var(--fgColor-onEmphasis);\n background-color: var(--bgColor-success-emphasis);\n border: var(--borderWidth-thin) solid transparent;\n}\n\n.TimelineItem-body {\n min-width: 0;\n max-width: 100%;\n /* stylelint-disable-next-line primer/spacing */\n margin-top: calc(var(--base-size-4) + 1px);\n color: var(--fgColor-muted);\n flex: auto;\n}\n\n.TimelineItem-avatar {\n position: absolute;\n /* stylelint-disable-next-line primer/spacing */\n left: -72px;\n z-index: 1;\n}\n\n.TimelineItem-break {\n position: relative;\n z-index: 1;\n height: var(--stack-gap-spacious);\n margin: 0;\n margin-bottom: calc(var(--stack-gap-normal) * -1);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: -56px;\n background-color: var(--bgColor-default);\n border: 0;\n border-top: var(--borderWidth-thicker) solid var(--borderColor-default);\n}\n\n.TimelineItem--condensed {\n padding-top: var(--base-size-4);\n padding-bottom: 0;\n\n /* TimelineItem--condensed is often grouped. (commits) */\n &:last-child {\n padding-bottom: var(--stack-gap-normal);\n }\n\n & .TimelineItem-badge {\n height: var(--base-size-16);\n margin-top: var(--base-size-8);\n margin-bottom: var(--base-size-8);\n color: var(--fgColor-muted);\n background-color: var(--bgColor-default);\n border: 0;\n }\n}\n"]}
@@ -3,9 +3,7 @@
3
3
  .TimelineItem {
4
4
  position: relative;
5
5
  display: flex;
6
- /* stylelint-disable-next-line primer/spacing */
7
6
  padding: var(--stack-padding-normal) 0;
8
- /* stylelint-disable-next-line primer/spacing */
9
7
  margin-left: var(--stack-gap-normal);
10
8
 
11
9
  /* The Timeline */
@@ -34,7 +32,6 @@
34
32
  display: flex;
35
33
  width: var(--control-medium-size);
36
34
  height: var(--control-medium-size);
37
- /* stylelint-disable-next-line primer/spacing */
38
35
  margin-right: var(--controlStack-medium-gap-condensed);
39
36
  /* stylelint-disable-next-line primer/spacing */
40
37
  margin-left: calc(var(--control-medium-size) / -2 + 1px);
@@ -75,7 +72,6 @@
75
72
  z-index: 1;
76
73
  height: var(--stack-gap-spacious);
77
74
  margin: 0;
78
- /* stylelint-disable-next-line primer/spacing */
79
75
  margin-bottom: calc(var(--stack-gap-normal) * -1);
80
76
  /* stylelint-disable-next-line primer/spacing */
81
77
  margin-left: -56px;
@@ -90,7 +86,6 @@
90
86
 
91
87
  /* TimelineItem--condensed is often grouped. (commits) */
92
88
  &:last-child {
93
- /* stylelint-disable-next-line primer/spacing */
94
89
  padding-bottom: var(--stack-gap-normal);
95
90
  }
96
91
 
@@ -1 +1 @@
1
- {"version":3,"sources":["truncate.pcss"],"names":[],"mappings":"AAEA,UACE,mBAAoB,CACpB,WAAY,CACZ,cA0BF,CAxBE,yBACE,aAAc,CACd,qBAAsB,CACtB,eAAgB,CAChB,sBAAuB,CACvB,kBAkBF,CAhBE,6CAEE,oCACF,CAEA,qDACE,eACF,CAEA,2LAGE,wBAA0B,CAC1B,aAAc,CACd,cACF","file":"truncate.css","sourcesContent":["/* Truncate */\n\n.Truncate {\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n\n & > .Truncate-text {\n min-width: 1ch;\n max-width: fit-content;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n & + .Truncate-text {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-small-gap);\n }\n\n &.Truncate-text--primary {\n flex-basis: 200%;\n }\n\n &.Truncate-text--expandable:hover,\n &.Truncate-text--expandable:focus,\n &.Truncate-text--expandable:active {\n max-width: 100% !important;\n flex-shrink: 0;\n cursor: pointer;\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["truncate.pcss"],"names":[],"mappings":"AAEA,UACE,mBAAoB,CACpB,WAAY,CACZ,cAyBF,CAvBE,yBACE,aAAc,CACd,qBAAsB,CACtB,eAAgB,CAChB,sBAAuB,CACvB,kBAiBF,CAfE,6CACE,oCACF,CAEA,qDACE,eACF,CAEA,2LAGE,wBAA0B,CAC1B,aAAc,CACd,cACF","file":"truncate.css","sourcesContent":["/* Truncate */\n\n.Truncate {\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n\n & > .Truncate-text {\n min-width: 1ch;\n max-width: fit-content;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n & + .Truncate-text {\n margin-left: var(--control-small-gap);\n }\n\n &.Truncate-text--primary {\n flex-basis: 200%;\n }\n\n &.Truncate-text--expandable:hover,\n &.Truncate-text--expandable:focus,\n &.Truncate-text--expandable:active {\n max-width: 100% !important;\n flex-shrink: 0;\n cursor: pointer;\n }\n }\n}\n"]}
@@ -13,7 +13,6 @@
13
13
  white-space: nowrap;
14
14
 
15
15
  & + .Truncate-text {
16
- /* stylelint-disable-next-line primer/spacing */
17
16
  margin-left: var(--control-small-gap);
18
17
  }
19
18
 
@@ -22,6 +22,7 @@ module Primer
22
22
  include AttributesHelper
23
23
  include ClassNameHelper
24
24
  include FetchOrFallbackHelper
25
+ include SafeHrefHelper
25
26
  include TestSelectorHelper
26
27
  include JoinStyleArgumentsHelper
27
28
  include ViewHelper
@@ -137,6 +138,21 @@ module Primer
137
138
  deny_single_argument(:tag, "This component has a fixed tag.", **arguments)
138
139
  end
139
140
 
141
+ # Removes `href` values that point at disallowed URI schemes (`javascript:`,
142
+ # `vbscript:`). Raises in non-production environments so the offending call
143
+ # site gets fixed; in production we silently drop the attribute so the link
144
+ # is rendered inert rather than crashing the page.
145
+ def sanitize_href!(arguments)
146
+ return unless arguments.key?(:href)
147
+ return unless Primer::SafeHrefHelper.unsafe_href?(arguments[:href])
148
+
149
+ if should_raise_error?
150
+ raise ArgumentError, "Rejected dangerous URI scheme in `href`: #{arguments[:href].inspect}"
151
+ end
152
+
153
+ arguments[:href] = nil
154
+ end
155
+
140
156
  def should_raise_error?
141
157
  !Rails.env.production? && raise_on_invalid_options? && !ENV["PRIMER_WARNINGS_DISABLED"]
142
158
  end
@@ -1 +1 @@
1
- {"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAEA,mBACE,aAAc,CACd,2CAA4C,CAC5C,0BACF,CAEA,wCACE,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOF,CALE,6EAGE,YACF,CAGF,+BACE,cAAe,CACf,wBAAiB,CAAjB,gBAAiB,CACjB,YAAa,CACb,gBAAiB,CACjB,kBAAmB,CACnB,kCAAmC,CACnC,0BAA2B,CAC3B,eAKF,CAHE,kDACE,MACF,CAGF,wDACE,+BACE,qBAAsB,CACtB,sBACF,CAEA,kEACE,YACF,CAEA,+BACE,UACF,CACF,CAGE,8DACE,qBAAsB,CACtB,sBACF,CAEA,gGACE,YACF,CAEA,8DACE,gBAAiB,CACjB,kBAAsB,CACtB,kBAAmB,CACnB,UACF,CAGF,8BACE,cAAe,CACf,YAAa,CACb,kBAAmB,CACnB,8BAA+B,CAC/B,eAAgB,CAChB,cACF,CAEA,+BACE,MAAO,CACP,WAAY,CACZ,eAAgB,CAChB,sBAAuB,CACvB,kBAAmB,CACnB,wBAAiB,CAAjB,gBACF","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n.CollapsibleHeader {\n display: block;\n container-name: collapsible-header-container;\n container-type: inline-size;\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-list,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n\n.CollapsibleHeader-triggerArea {\n cursor: pointer;\n user-select: none;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n column-gap: var(--stack-gap-normal);\n row-gap: var(--base-size-4);\n overflow: hidden;\n\n .CollapsibleHeader > & {\n flex: 1;\n }\n}\n\n@container collapsible-header-container (width < 544px) {\n .CollapsibleHeader-triggerArea {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .CollapsibleHeader[data-collapsed] .CollapsibleHeader-description {\n display: none;\n }\n\n .CollapsibleHeader-description {\n width: 100%;\n }\n}\n\n.CollapsibleHeader--multi-line {\n .CollapsibleHeader-triggerArea {\n flex-direction: column;\n align-items: flex-start;\n }\n\n &.CollapsibleHeader[data-collapsed] .CollapsibleHeader-description {\n display: none;\n }\n\n .CollapsibleHeader-description {\n overflow: visible;\n text-overflow: initial;\n white-space: normal;\n width: 100%;\n }\n}\n\n.CollapsibleHeader-title-line {\n flex-basis: 66%;\n display: flex;\n align-items: center;\n gap: var(--stack-gap-condensed);\n overflow: hidden;\n max-width: 100%;\n}\n\n.CollapsibleHeader-description {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: text;\n}\n"]}
1
+ {"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAIA,mBACE,aAAc,CACd,2CAA4C,CAC5C,0BACF,CAEA,wCACE,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOF,CALE,6EAGE,YACF,CAGF,+BACE,cAAe,CACf,wBAAiB,CAAjB,gBAAiB,CACjB,YAAa,CACb,gBAAiB,CACjB,kBAAmB,CACnB,kCAAmC,CACnC,0BAA2B,CAC3B,eAKF,CAHE,kDACE,MACF,CAGF,wDACE,+BACE,qBAAsB,CACtB,sBACF,CAEA,kEACE,YACF,CAEA,+BACE,UACF,CACF,CAGE,8DACE,qBAAsB,CACtB,sBACF,CAEA,gGACE,YACF,CAEA,8DACE,gBAAiB,CACjB,kBAAmB,CACnB,kBAAmB,CACnB,UACF,CAGF,8BACE,cAAe,CACf,YAAa,CACb,kBAAmB,CACnB,8BAA+B,CAC/B,eAAgB,CAChB,cACF,CAEA,+BACE,MAAO,CACP,WAAY,CACZ,eAAgB,CAChB,sBAAuB,CACvB,kBAAmB,CACnB,wBAAiB,CAAjB,gBACF","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n/* stylelint-disable selector-nested-pattern -- component nests descendant class selectors (and `.X > &`) inside container queries, not &-prefixed selectors */\n\n.CollapsibleHeader {\n display: block;\n container-name: collapsible-header-container;\n container-type: inline-size;\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-list,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n\n.CollapsibleHeader-triggerArea {\n cursor: pointer;\n user-select: none;\n display: flex;\n flex-wrap: nowrap;\n align-items: center;\n column-gap: var(--stack-gap-normal);\n row-gap: var(--base-size-4);\n overflow: hidden;\n\n .CollapsibleHeader > & {\n flex: 1;\n }\n}\n\n@container collapsible-header-container (width < 544px) {\n .CollapsibleHeader-triggerArea {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .CollapsibleHeader[data-collapsed] .CollapsibleHeader-description {\n display: none;\n }\n\n .CollapsibleHeader-description {\n width: 100%;\n }\n}\n\n.CollapsibleHeader--multi-line {\n .CollapsibleHeader-triggerArea {\n flex-direction: column;\n align-items: flex-start;\n }\n\n &.CollapsibleHeader[data-collapsed] .CollapsibleHeader-description {\n display: none;\n }\n\n .CollapsibleHeader-description {\n overflow: visible;\n text-overflow: clip;\n white-space: normal;\n width: 100%;\n }\n}\n\n.CollapsibleHeader-title-line {\n flex-basis: 66%;\n display: flex;\n align-items: center;\n gap: var(--stack-gap-condensed);\n overflow: hidden;\n max-width: 100%;\n}\n\n.CollapsibleHeader-description {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n user-select: text;\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  <% if count? %>
6
6
  <%= count %>
7
7
  <% end %>
8
- <%= render(Primer::BaseComponent.new(tag: :div)) do %>
8
+ <%= render(Primer::Beta::Button.new(**@toggle_button_arguments)) do %>
9
9
  <%= render(Primer::Beta::Octicon.new(icon: "chevron-up", hidden: @collapsed, data: { target: "collapsible-header.arrowUp" })) %>
10
10
  <%= render(Primer::Beta::Octicon.new(icon: "chevron-down", hidden: !@collapsed, data: { target: "collapsible-header.arrowDown" })) %>
11
11
  <% end %>
@@ -1,5 +1,7 @@
1
1
  /* CSS for BorderBox::CollapsibleHeader */
2
2
 
3
+ /* stylelint-disable selector-nested-pattern -- component nests descendant class selectors (and `.X > &`) inside container queries, not &-prefixed selectors */
4
+
3
5
  .CollapsibleHeader {
4
6
  display: block;
5
7
  container-name: collapsible-header-container;
@@ -60,7 +62,7 @@
60
62
 
61
63
  .CollapsibleHeader-description {
62
64
  overflow: visible;
63
- text-overflow: initial;
65
+ text-overflow: clip;
64
66
  white-space: normal;
65
67
  width: 100%;
66
68
  }
@@ -16,6 +16,7 @@ module Primer
16
16
  # @param tag [Symbol] <%= one_of(Primer::OpenProject::BorderBox::CollapsibleHeader::TITLE_TAG_OPTIONS) %>
17
17
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
18
18
  renders_one :title, lambda { |tag: TITLE_TAG_DEFAULT, **system_arguments|
19
+ system_arguments[:id] ||= @heading_id
19
20
  system_arguments[:classes] = class_names(
20
21
  system_arguments[:classes],
21
22
  "CollapsibleHeader-title",
@@ -29,7 +30,6 @@ module Primer
29
30
  #
30
31
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
31
32
  renders_one :count, lambda { |**system_arguments|
32
- system_arguments[:mr] ||= 2
33
33
  system_arguments[:scheme] ||= :primary
34
34
  system_arguments[:classes] = class_names(
35
35
  system_arguments[:classes],
@@ -65,6 +65,7 @@ module Primer
65
65
 
66
66
  @collapsed = collapsed
67
67
  @collapsible_id = collapsible_id
68
+ @heading_id = "#{id}-heading"
68
69
 
69
70
  @system_arguments = deny_tag_argument(**system_arguments)
70
71
  @system_arguments[:tag] = :"collapsible-header"
@@ -87,16 +88,16 @@ module Primer
87
88
  end
88
89
 
89
90
  @trigger_area_arguments = { tag: :div }
90
- @trigger_area_arguments[:role] = "button"
91
- @trigger_area_arguments[:tabindex] = 0
92
91
  @trigger_area_arguments[:classes] = "CollapsibleHeader-triggerArea"
93
- @trigger_area_arguments[:aria] = {
94
- controls: @collapsible_id,
95
- expanded: !@collapsed
96
- }
97
92
  @trigger_area_arguments[:data] = {
98
- target: "collapsible-header.triggerElement",
99
- action: "click:collapsible-header#toggle keydown:collapsible-header#toggleViaKeyboard"
93
+ action: "click:collapsible-header#toggle"
94
+ }
95
+
96
+ @toggle_button_arguments = {
97
+ scheme: :invisible,
98
+ type: :button,
99
+ data: { target: "collapsible-header.triggerElement", "collapsible-toggle": "" },
100
+ aria: { expanded: !@collapsed, controls: @collapsible_id, labelledby: @heading_id }
100
101
  }
101
102
  end
102
103
 
@@ -1 +1 @@
1
- .BorderGrid{display:table;width:100%;margin-top:-16px;margin-bottom:-16px;table-layout:fixed;border-collapse:collapse;border-style:hidden}.BorderGrid .BorderGrid-cell{padding-top:16px;padding-bottom:16px}.BorderGrid--spacious{margin-top:-24px;margin-bottom:-24px}.BorderGrid--spacious .BorderGrid-cell{padding-top:24px;padding-bottom:24px}.BorderGrid-row{display:table-row}.BorderGrid-cell{display:table-cell;border:1px solid var(--borderColor-muted)}
1
+ .BorderGrid{display:table;width:100%;margin-top:calc(var(--base-size-16)*-1);margin-bottom:calc(var(--base-size-16)*-1);table-layout:fixed;border-collapse:collapse;border-style:hidden}.BorderGrid .BorderGrid-cell{padding-top:var(--base-size-16);padding-bottom:var(--base-size-16)}.BorderGrid--spacious{margin-top:calc(var(--base-size-24)*-1);margin-bottom:calc(var(--base-size-24)*-1)}.BorderGrid--spacious .BorderGrid-cell{padding-top:var(--base-size-24);padding-bottom:var(--base-size-24)}.BorderGrid-row{display:table-row}.BorderGrid-cell{display:table-cell;border:var(--borderWidth-thin) solid var(--borderColor-muted)}
@@ -1 +1 @@
1
- {"version":3,"sources":["border_grid.pcss"],"names":[],"mappings":"AAEA,YACI,aAAc,CACd,UAAW,CACX,gBAAiB,CACjB,mBAAoB,CACpB,kBAAmB,CACnB,wBAAyB,CACzB,mBACJ,CAEA,6BACI,gBAAiB,CACjB,mBACJ,CAEA,sBACI,gBAAiB,CACjB,mBACJ,CAEA,uCACI,gBAAiB,CACjB,mBACJ,CAEA,gBACI,iBACJ,CAEA,iBACI,kBAAmB,CACnB,yCACJ","file":"border_grid.css","sourcesContent":["/* CSS for BorderGrid */\n\n.BorderGrid {\n display: table;\n width: 100%;\n margin-top: -16px;\n margin-bottom: -16px;\n table-layout: fixed;\n border-collapse: collapse;\n border-style: hidden\n}\n\n.BorderGrid .BorderGrid-cell {\n padding-top: 16px;\n padding-bottom: 16px\n}\n\n.BorderGrid--spacious {\n margin-top: -24px;\n margin-bottom: -24px\n}\n\n.BorderGrid--spacious .BorderGrid-cell {\n padding-top: 24px;\n padding-bottom: 24px\n}\n\n.BorderGrid-row {\n display: table-row\n}\n\n.BorderGrid-cell {\n display: table-cell;\n border: 1px solid var(--borderColor-muted)\n}\n"]}
1
+ {"version":3,"sources":["border_grid.pcss"],"names":[],"mappings":"AAEA,YACI,aAAc,CACd,UAAW,CACX,uCAA0C,CAC1C,0CAA6C,CAC7C,kBAAmB,CAEnB,wBAAyB,CAEzB,mBACJ,CAEA,6BACI,+BAAgC,CAChC,kCACJ,CAEA,sBACI,uCAA0C,CAC1C,0CACJ,CAEA,uCACI,+BAAgC,CAChC,kCACJ,CAEA,gBACI,iBACJ,CAEA,iBACI,kBAAmB,CACnB,6DACJ","file":"border_grid.css","sourcesContent":["/* CSS for BorderGrid */\n\n.BorderGrid {\n display: table;\n width: 100%;\n margin-top: calc(-1 * var(--base-size-16));\n margin-bottom: calc(-1 * var(--base-size-16));\n table-layout: fixed;\n /* stylelint-disable-next-line primer/borders -- table border-collapse keyword, not a border size */\n border-collapse: collapse;\n /* stylelint-disable-next-line primer/borders -- table border-style keyword, not a border size */\n border-style: hidden\n}\n\n.BorderGrid .BorderGrid-cell {\n padding-top: var(--base-size-16);\n padding-bottom: var(--base-size-16)\n}\n\n.BorderGrid--spacious {\n margin-top: calc(-1 * var(--base-size-24));\n margin-bottom: calc(-1 * var(--base-size-24))\n}\n\n.BorderGrid--spacious .BorderGrid-cell {\n padding-top: var(--base-size-24);\n padding-bottom: var(--base-size-24)\n}\n\n.BorderGrid-row {\n display: table-row\n}\n\n.BorderGrid-cell {\n display: table-cell;\n border: var(--borderWidth-thin) solid var(--borderColor-muted)\n}\n"]}
@@ -3,26 +3,28 @@
3
3
  .BorderGrid {
4
4
  display: table;
5
5
  width: 100%;
6
- margin-top: -16px;
7
- margin-bottom: -16px;
6
+ margin-top: calc(-1 * var(--base-size-16));
7
+ margin-bottom: calc(-1 * var(--base-size-16));
8
8
  table-layout: fixed;
9
+ /* stylelint-disable-next-line primer/borders -- table border-collapse keyword, not a border size */
9
10
  border-collapse: collapse;
11
+ /* stylelint-disable-next-line primer/borders -- table border-style keyword, not a border size */
10
12
  border-style: hidden
11
13
  }
12
14
 
13
15
  .BorderGrid .BorderGrid-cell {
14
- padding-top: 16px;
15
- padding-bottom: 16px
16
+ padding-top: var(--base-size-16);
17
+ padding-bottom: var(--base-size-16)
16
18
  }
17
19
 
18
20
  .BorderGrid--spacious {
19
- margin-top: -24px;
20
- margin-bottom: -24px
21
+ margin-top: calc(-1 * var(--base-size-24));
22
+ margin-bottom: calc(-1 * var(--base-size-24))
21
23
  }
22
24
 
23
25
  .BorderGrid--spacious .BorderGrid-cell {
24
- padding-top: 24px;
25
- padding-bottom: 24px
26
+ padding-top: var(--base-size-24);
27
+ padding-bottom: var(--base-size-24)
26
28
  }
27
29
 
28
30
  .BorderGrid-row {
@@ -31,5 +33,5 @@
31
33
 
32
34
  .BorderGrid-cell {
33
35
  display: table-cell;
34
- border: 1px solid var(--borderColor-muted)
36
+ border: var(--borderWidth-thin) solid var(--borderColor-muted)
35
37
  }
@@ -5,7 +5,7 @@ export declare abstract class CollapsibleElement extends HTMLElement {
5
5
  collapsibleElements: HTMLElement[];
6
6
  collapsed: boolean;
7
7
  toggleViaKeyboard(event: KeyboardEvent): void;
8
- toggle(): void;
8
+ toggle(event?: Event): void;
9
9
  attributeChangedCallback(name: string): void;
10
10
  hideAll(): void;
11
11
  expandAll(): void;
@@ -5,7 +5,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { attr, target, targets } from '@github/catalyst';
8
- // eslint-disable-next-line custom-elements/expose-class-on-global
9
8
  export class CollapsibleElement extends HTMLElement {
10
9
  constructor() {
11
10
  super(...arguments);
@@ -13,11 +12,16 @@ export class CollapsibleElement extends HTMLElement {
13
12
  }
14
13
  toggleViaKeyboard(event) {
15
14
  if (event.code === 'Enter' || event.code === 'Space') {
16
- event.preventDefault();
17
- this.toggle();
15
+ this.toggle(event);
18
16
  }
19
17
  }
20
- toggle() {
18
+ toggle(event) {
19
+ if (event &&
20
+ event.target instanceof Element &&
21
+ !event.target.closest('[data-collapsible-toggle]') &&
22
+ event.target.closest('a, button'))
23
+ return;
24
+ event?.preventDefault();
21
25
  this.collapsed = !this.collapsed;
22
26
  }
23
27
  attributeChangedCallback(name) {