primer_view_components 0.49.0 → 0.51.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 (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +20 -1
  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/alpha/action_bar_element.js +1 -1
  9. data/app/components/primer/alpha/action_bar_element.ts +1 -1
  10. data/app/components/primer/alpha/action_list/item.rb +2 -1
  11. data/app/components/primer/alpha/action_list.js +1 -1
  12. data/app/components/primer/alpha/action_list.ts +1 -1
  13. data/app/components/primer/alpha/action_menu/action_menu_element.js +1 -1
  14. data/app/components/primer/alpha/action_menu/action_menu_element.ts +1 -1
  15. data/app/components/primer/alpha/layout.rb +6 -2
  16. data/app/components/primer/alpha/segmented_control.js +1 -1
  17. data/app/components/primer/alpha/segmented_control.ts +1 -1
  18. data/app/components/primer/alpha/select_panel.rb +1 -1
  19. data/app/components/primer/alpha/select_panel_element.js +4 -2
  20. data/app/components/primer/alpha/select_panel_element.ts +5 -2
  21. data/app/components/primer/alpha/stack.rb +1 -0
  22. data/app/components/primer/alpha/tab_nav.css +1 -1
  23. data/app/components/primer/alpha/tab_nav.css.json +1 -0
  24. data/app/components/primer/alpha/tab_nav.css.map +1 -1
  25. data/app/components/primer/alpha/tab_nav.pcss +7 -1
  26. data/app/components/primer/alpha/toggle_switch.js +1 -1
  27. data/app/components/primer/alpha/toggle_switch.rb +3 -0
  28. data/app/components/primer/alpha/toggle_switch.ts +1 -1
  29. data/app/components/primer/alpha/tree_view/tree_view.js +1 -1
  30. data/app/components/primer/alpha/tree_view/tree_view.ts +1 -1
  31. data/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.js +1 -1
  32. data/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.ts +1 -1
  33. data/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.js +1 -1
  34. data/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.ts +1 -1
  35. data/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.js +25 -2
  36. data/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.ts +27 -1
  37. data/app/components/primer/alpha/x_banner.js +1 -1
  38. data/app/components/primer/alpha/x_banner.ts +1 -1
  39. data/app/components/primer/beta/blankslate.css +1 -1
  40. data/app/components/primer/beta/blankslate.css.json +1 -0
  41. data/app/components/primer/beta/blankslate.css.map +1 -1
  42. data/app/components/primer/beta/blankslate.pcss +5 -0
  43. data/app/components/primer/beta/blankslate.rb +1 -0
  44. data/app/components/primer/beta/details_toggle_element.js +1 -1
  45. data/app/components/primer/beta/details_toggle_element.ts +1 -1
  46. data/app/components/primer/beta/nav_list.js +1 -1
  47. data/app/components/primer/beta/nav_list.ts +1 -1
  48. data/app/components/primer/beta/nav_list_group_element.js +1 -1
  49. data/app/components/primer/beta/nav_list_group_element.ts +1 -1
  50. data/app/components/primer/dialog_helper.js +17 -8
  51. data/app/components/primer/dialog_helper.ts +17 -8
  52. data/app/components/primer/scrollable_region.js +1 -1
  53. data/app/components/primer/scrollable_region.ts +1 -1
  54. data/app/controllers/primer/view_components/toggle_switch_controller.rb +2 -2
  55. data/app/forms/check_box_with_nested_form.rb +9 -5
  56. data/app/lib/primer/forms/check_box.rb +28 -0
  57. data/app/lib/primer/forms/dsl/multi_input.rb +3 -1
  58. data/app/lib/primer/forms/dsl/text_field_input.rb +2 -1
  59. data/app/lib/primer/forms/form_control.html.erb +2 -1
  60. data/app/lib/primer/forms/primer_multi_input.js +1 -1
  61. data/app/lib/primer/forms/primer_multi_input.ts +1 -1
  62. data/app/lib/primer/forms/primer_text_area.js +1 -1
  63. data/app/lib/primer/forms/primer_text_area.ts +1 -1
  64. data/app/lib/primer/forms/primer_text_field.js +1 -1
  65. data/app/lib/primer/forms/primer_text_field.ts +1 -1
  66. data/app/lib/primer/forms/text_field.html.erb +1 -1
  67. data/app/lib/primer/forms/toggle_switch_input.js +1 -1
  68. data/app/lib/primer/forms/toggle_switch_input.ts +1 -1
  69. data/lib/primer/accessibility.rb +9 -3
  70. data/lib/primer/view_components/engine.rb +1 -4
  71. data/lib/primer/view_components/version.rb +1 -1
  72. data/previews/primer/alpha/form_control_preview/playground.html.erb +4 -2
  73. data/previews/primer/alpha/octicon_symbols_preview/playground.html.erb +1 -1
  74. data/previews/primer/alpha/overlay_preview.rb +0 -25
  75. data/previews/primer/alpha/text_area_preview.rb +11 -11
  76. data/previews/primer/alpha/text_field_preview.rb +9 -0
  77. data/previews/primer/alpha/toggle_switch_preview.rb +14 -14
  78. data/previews/primer/beta/button_preview/all_schemes.html.erb +1 -1
  79. data/previews/primer/beta/button_preview/invisible_all_visuals.html.erb +1 -1
  80. data/previews/primer/beta/button_preview/summary_as_button.html.erb +9 -1
  81. data/static/arguments.json +7 -1
  82. data/static/info_arch.json +24 -17
  83. data/static/previews.json +15 -14
  84. metadata +2 -2
@@ -165,6 +165,6 @@ __decorate([
165
165
  target
166
166
  ], ActionBarElement.prototype, "moreMenu", void 0);
167
167
  ActionBarElement = __decorate([
168
- controller
168
+ controller('action-bar')
169
169
  ], ActionBarElement);
170
170
  window.ActionBarElement = ActionBarElement;
@@ -27,7 +27,7 @@ enum ItemType {
27
27
  Divider,
28
28
  }
29
29
 
30
- @controller
30
+ @controller('action-bar')
31
31
  class ActionBarElement extends HTMLElement {
32
32
  @targets items: HTMLElement[]
33
33
  @target itemContainer: HTMLElement
@@ -302,7 +302,8 @@ module Primer
302
302
  if @list.allows_selection?
303
303
  @content_arguments[:aria] = merge_aria(
304
304
  @content_arguments,
305
- { aria: @list.aria_selection_variant == :selected ? { selected: active? } : { checked: active? } }
305
+ # Always use aria-selected for listbox (role="option" requires aria-selected per WAI-ARIA 1.2)
306
+ { aria: @list.acts_as_listbox? || @list.aria_selection_variant == :selected ? { selected: active? } : { checked: active? } }
306
307
  )
307
308
  end
308
309
 
@@ -65,6 +65,6 @@ let ActionListElement = class ActionListElement extends HTMLElement {
65
65
  };
66
66
  _ActionListElement_truncationObserver = new WeakMap();
67
67
  ActionListElement = __decorate([
68
- controller
68
+ controller('action-list')
69
69
  ], ActionListElement);
70
70
  export { ActionListElement };
@@ -39,7 +39,7 @@ export class ActionListTruncationObserver {
39
39
  }
40
40
  }
41
41
 
42
- @controller
42
+ @controller('action-list')
43
43
  export class ActionListElement extends HTMLElement {
44
44
  #truncationObserver: ActionListTruncationObserver
45
45
 
@@ -485,7 +485,7 @@ __decorate([
485
485
  target
486
486
  ], ActionMenuElement.prototype, "overlay", void 0);
487
487
  ActionMenuElement = __decorate([
488
- controller
488
+ controller('action-menu')
489
489
  ], ActionMenuElement);
490
490
  export { ActionMenuElement };
491
491
  if (!window.customElements.get('action-menu')) {
@@ -14,7 +14,7 @@ type SelectedItem = {
14
14
  const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
15
15
  const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`)
16
16
 
17
- @controller
17
+ @controller('action-menu')
18
18
  export class ActionMenuElement extends HTMLElement {
19
19
  @target
20
20
  includeFragment: IncludeFragmentElement
@@ -12,7 +12,11 @@ module Primer
12
12
  #
13
13
  # @accessibility
14
14
  # Keyboard navigation follows the markup order. Decide carefully how the focus order should be be by deciding whether
15
- # `main` or `sidebar` comes first in code. The code order wont affect the visual position.
15
+ # `main` or `sidebar` comes first in code. The code order won't affect the visual position.
16
+ #
17
+ # When using `row_placement: :none` on the sidebar, the sidebar content will be hidden at narrow viewports.
18
+ # This may cause WCAG 1.4.10 Reflow failures if the sidebar contains essential content. Only use `:none`
19
+ # when the sidebar content is non-essential or available elsewhere on the page.
16
20
  class Layout < Primer::Component
17
21
  status :alpha
18
22
 
@@ -60,7 +64,7 @@ module Primer
60
64
  #
61
65
  # @param width [Symbol] <%= one_of(Primer::Alpha::Layout::SIDEBAR_WIDTH_OPTIONS) %>
62
66
  # @param col_placement [Symbol] Sidebar placement when `Layout` is in column modes. <%= one_of(Primer::Alpha::Layout::SIDEBAR_COL_PLACEMENT_OPTIONS) %>
63
- # @param row_placement [Symbol] Sidebar placement when `Layout` is in row mode. <%= one_of(Primer::Alpha::Layout::SIDEBAR_ROW_PLACEMENT_OPTIONS) %>
67
+ # @param row_placement [Symbol] Sidebar placement when `Layout` is in row mode. <%= one_of(Primer::Alpha::Layout::SIDEBAR_ROW_PLACEMENT_OPTIONS) %> **Note:** Using `:none` hides the sidebar at narrow viewports, which may cause WCAG 1.4.10 Reflow issues if the sidebar contains essential content.
64
68
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
65
69
  renders_one :sidebar, lambda { |
66
70
  width: SIDEBAR_WIDTH_DEFAULT,
@@ -39,7 +39,7 @@ __decorate([
39
39
  targets
40
40
  ], SegmentedControlElement.prototype, "items", void 0);
41
41
  SegmentedControlElement = __decorate([
42
- controller
42
+ controller('segmented-control')
43
43
  ], SegmentedControlElement);
44
44
  if (!window.customElements.get('segmented-control')) {
45
45
  window.SegmentedControlElement = SegmentedControlElement;
@@ -1,6 +1,6 @@
1
1
  import {controller, targets} from '@github/catalyst'
2
2
 
3
- @controller
3
+ @controller('segmented-control')
4
4
  class SegmentedControlElement extends HTMLElement {
5
5
  @targets items: HTMLElement[]
6
6
 
@@ -256,7 +256,7 @@ module Primer
256
256
  super(
257
257
  p: 2,
258
258
  role: "listbox",
259
- aria_selection_variant: select_variant == :single ? :selected : :checked,
259
+ aria_selection_variant: :selected,
260
260
  select_variant: select_variant == :multiple ? :multiple_checkbox : :single,
261
261
  **system_arguments
262
262
  )
@@ -84,7 +84,7 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
84
84
  return this.getAttribute('data-select-variant');
85
85
  }
86
86
  get ariaSelectionType() {
87
- return this.selectVariant === 'multiple' ? 'aria-checked' : 'aria-selected';
87
+ return 'aria-selected';
88
88
  }
89
89
  set selectVariant(variant) {
90
90
  if (variant) {
@@ -775,6 +775,8 @@ _SelectPanelElement_performFilteringLocally = function _SelectPanelElement_perfo
775
775
  return __classPrivateFieldGet(this, _SelectPanelElement_instances, "a", _SelectPanelElement_fetchStrategy_get) === FetchStrategy.LOCAL || __classPrivateFieldGet(this, _SelectPanelElement_instances, "a", _SelectPanelElement_fetchStrategy_get) === FetchStrategy.EVENTUALLY_LOCAL;
776
776
  };
777
777
  _SelectPanelElement_handleInvokerActivated = function _SelectPanelElement_handleInvokerActivated(event) {
778
+ // Let listeners observe the invoker was clicked
779
+ this.invokerElement?.dispatchEvent(new CustomEvent('invokerClicked', { bubbles: true }));
778
780
  event.preventDefault();
779
781
  // eslint-disable-next-line no-restricted-syntax
780
782
  event.stopPropagation();
@@ -987,7 +989,7 @@ __decorate([
987
989
  target
988
990
  ], SelectPanelElement.prototype, "liveRegion", void 0);
989
991
  SelectPanelElement = __decorate([
990
- controller
992
+ controller('select-panel')
991
993
  ], SelectPanelElement);
992
994
  export { SelectPanelElement };
993
995
  if (!window.customElements.get('select-panel')) {
@@ -64,7 +64,7 @@ const updateWhenVisible = (() => {
64
64
  }
65
65
  })()
66
66
 
67
- @controller
67
+ @controller('select-panel')
68
68
  export class SelectPanelElement extends HTMLElement {
69
69
  @target includeFragment: IncludeFragmentElement
70
70
  @target dialog: HTMLDialogElement
@@ -97,7 +97,7 @@ export class SelectPanelElement extends HTMLElement {
97
97
  }
98
98
 
99
99
  get ariaSelectionType(): string {
100
- return this.selectVariant === 'multiple' ? 'aria-checked' : 'aria-selected'
100
+ return 'aria-selected'
101
101
  }
102
102
 
103
103
  set selectVariant(variant: SelectVariant) {
@@ -813,6 +813,9 @@ export class SelectPanelElement extends HTMLElement {
813
813
  }
814
814
 
815
815
  #handleInvokerActivated(event: Event) {
816
+ // Let listeners observe the invoker was clicked
817
+ this.invokerElement?.dispatchEvent(new CustomEvent('invokerClicked', {bubbles: true}))
818
+
816
819
  event.preventDefault()
817
820
 
818
821
  // eslint-disable-next-line no-restricted-syntax
@@ -117,6 +117,7 @@ module Primer
117
117
  DEFAULT = nil
118
118
  OPTIONS = [
119
119
  DEFAULT,
120
+ :none,
120
121
  :condensed,
121
122
  :normal,
122
123
  :spacious
@@ -1 +1 @@
1
- .tabnav{border-bottom:var(--borderWidth-thin) solid var(--borderColor-default);margin-bottom:var(--stack-gap-normal);margin-top:0}.tabnav-tabs{display:flex;margin-bottom:calc(var(--borderWidth-thin)*-1);overflow:hidden}.tabnav-tab{background-color:initial;border:var(--borderWidth-thin) solid #0000;border-bottom:0;color:var(--fgColor-muted);display:inline-block;flex-shrink:0;font-size:var(--text-body-size-medium);line-height:23px;padding:var(--base-size-8) var(--control-medium-paddingInline-spacious);-webkit-text-decoration:none;text-decoration:none;transition:color .2s cubic-bezier(.3,0,.5,1)}.tabnav-tab.selected,.tabnav-tab[aria-current]:not([aria-current=false]),.tabnav-tab[aria-selected=true]{background-color:var(--bgColor-default);border-color:var(--borderColor-default);border-radius:var(--borderRadius-medium) var(--borderRadius-medium) 0 0;color:var(--fgColor-default)}:is(.tabnav-tab.selected,.tabnav-tab[aria-selected=true],.tabnav-tab[aria-current]:not([aria-current=false])) .octicon{color:inherit}.tabnav-tab:hover{color:var(--fgColor-default);-webkit-text-decoration:none;text-decoration:none;transition-duration:.1s}.tabnav-tab:focus,.tabnav-tab:focus-visible{border-radius:var(--borderRadius-medium) var(--borderRadius-medium) 0 0!important;outline-offset:-6px}.tabnav-tab .octicon,.tabnav-tab:active{color:var(--fgColor-muted)}.tabnav-tab .octicon{margin-right:var(--control-small-gap)}.tabnav-tab .Counter{color:inherit;margin-left:var(--control-small-gap)}.tabnav-extra{color:var(--fgColor-muted);display:inline-block;font-size:var(--text-body-size-small);margin-left:10px;padding-top:10px}.tabnav-extra>.octicon{margin-right:var(--base-size-2)}a.tabnav-extra:hover{color:var(--fgColor-accent);-webkit-text-decoration:none;text-decoration:none}.tabnav-btn{margin-left:var(--controlStack-medium-gap-condensed)}
1
+ .tabnav{border-bottom:var(--borderWidth-thin) solid var(--borderColor-default);margin-bottom:var(--stack-gap-normal);margin-top:0}.tabnav-tabs{display:flex;margin-bottom:calc(var(--borderWidth-thin)*-1);overflow-x:auto;overflow-y:hidden}.tabnav-tab,.tabnav-tabs>li{flex-shrink:0}.tabnav-tab{background-color:initial;border:var(--borderWidth-thin) solid #0000;border-bottom:0;color:var(--fgColor-muted);display:inline-block;font-size:var(--text-body-size-medium);line-height:23px;padding:var(--base-size-8) var(--control-medium-paddingInline-spacious);-webkit-text-decoration:none;text-decoration:none;transition:color .2s cubic-bezier(.3,0,.5,1)}.tabnav-tab.selected,.tabnav-tab[aria-current]:not([aria-current=false]),.tabnav-tab[aria-selected=true]{background-color:var(--bgColor-default);border-color:var(--borderColor-default);border-radius:var(--borderRadius-medium) var(--borderRadius-medium) 0 0;color:var(--fgColor-default)}:is(.tabnav-tab.selected,.tabnav-tab[aria-selected=true],.tabnav-tab[aria-current]:not([aria-current=false])) .octicon{color:inherit}.tabnav-tab:hover{color:var(--fgColor-default);-webkit-text-decoration:none;text-decoration:none;transition-duration:.1s}.tabnav-tab:focus,.tabnav-tab:focus-visible{border-radius:var(--borderRadius-medium) var(--borderRadius-medium) 0 0!important;outline-offset:-6px}.tabnav-tab .octicon,.tabnav-tab:active{color:var(--fgColor-muted)}.tabnav-tab .octicon{margin-right:var(--control-small-gap)}.tabnav-tab .Counter{color:inherit;margin-left:var(--control-small-gap)}.tabnav-extra{color:var(--fgColor-muted);display:inline-block;font-size:var(--text-body-size-small);margin-left:10px;padding-top:10px}.tabnav-extra>.octicon{margin-right:var(--base-size-2)}a.tabnav-extra:hover{color:var(--fgColor-accent);-webkit-text-decoration:none;text-decoration:none}.tabnav-btn{margin-left:var(--controlStack-medium-gap-condensed)}
@@ -4,6 +4,7 @@
4
4
  ".tabnav",
5
5
  ".tabnav-tabs",
6
6
  ".tabnav-tab",
7
+ ".tabnav-tabs>li",
7
8
  ".tabnav-tab.selected",
8
9
  ".tabnav-tab[aria-current]:not([aria-current=false])",
9
10
  ".tabnav-tab[aria-selected=true]",
@@ -1 +1 @@
1
- {"version":3,"sources":["tab_nav.pcss"],"names":[],"mappings":"AAGA,QAIE,sEAAuE,CADvE,qCAAsC,CAFtC,YAIF,CAEA,aACE,YAAa,CAEb,8CAAiD,CACjD,eACF,CAEA,YAUE,wBAA6B,CAE7B,0CAAgB,CAAhB,eAAgB,CAJhB,0BAA2B,CAP3B,oBAAqB,CACrB,aAAc,CAGd,sCAAuC,CAEvC,gBAAiB,CAHjB,uEAAwE,CAKxE,4BAAqB,CAArB,oBAAqB,CAIrB,4CA0CF,CAxCE,yGAIE,uCAAwC,CACxC,uCAAwC,CACxC,uEAAwE,CAHxE,4BAQF,CAHE,uHACE,aACF,CAGF,kBACE,4BAA6B,CAC7B,4BAAqB,CAArB,oBAAqB,CACrB,uBACF,CAEA,4CAEE,iFAAmF,CACnF,mBACF,CAMA,wCAHE,0BAOF,CAJA,qBAEE,qCAEF,CAEA,qBAGE,aAAc,CADd,oCAEF,CAQF,cAOE,0BAA2B,CAN3B,oBAAqB,CAKrB,qCAAsC,CADtC,gBAAiB,CAFjB,gBASF,CAHE,uBACE,+BACF,CAKF,qBACE,2BAA4B,CAC5B,4BAAqB,CAArB,oBACF,CAOA,YAEE,oDACF","file":"tab_nav.css","sourcesContent":["/* tabnav */\n\n/* Outer wrapper */\n.tabnav {\n margin-top: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-normal);\n border-bottom: var(--borderWidth-thin) solid var(--borderColor-default);\n}\n\n.tabnav-tabs {\n display: flex;\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: calc(var(--borderWidth-thin) * -1);\n overflow: hidden;\n}\n\n.tabnav-tab {\n display: inline-block;\n flex-shrink: 0;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--base-size-8) var(--control-medium-paddingInline-spacious);\n font-size: var(--text-body-size-medium);\n /* stylelint-disable-next-line primer/typography */\n line-height: 23px;\n color: var(--fgColor-muted);\n text-decoration: none;\n background-color: transparent;\n border: var(--borderWidth-thin) solid transparent;\n border-bottom: 0;\n transition: color 0.2s cubic-bezier(0.3, 0, 0.5, 1);\n\n &.selected,\n &[aria-selected='true'],\n &[aria-current]:not([aria-current='false']) {\n color: var(--fgColor-default);\n background-color: var(--bgColor-default); /* cover bottom border */\n border-color: var(--borderColor-default);\n border-radius: var(--borderRadius-medium) var(--borderRadius-medium) 0 0;\n\n & .octicon {\n color: inherit;\n }\n }\n\n &:hover {\n color: var(--fgColor-default);\n text-decoration: none;\n transition-duration: 0.1s;\n }\n\n &:focus,\n &:focus-visible {\n border-radius: var(--borderRadius-medium) var(--borderRadius-medium) 0 0 !important;\n outline-offset: -6px;\n }\n\n &:active {\n color: var(--fgColor-muted);\n }\n\n & .octicon {\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--control-small-gap);\n color: var(--fgColor-muted);\n }\n\n & .Counter {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-small-gap);\n color: inherit;\n }\n}\n\n/* Tabnav extras\n**\n** Tabnav extras are non-tab elements that sit in the tabnav. Usually they're\n** inline text or links. */\n\n.tabnav-extra {\n display: inline-block;\n /* stylelint-disable-next-line primer/spacing */\n padding-top: 10px;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: 10px;\n font-size: var(--text-body-size-small);\n color: var(--fgColor-muted);\n\n & > .octicon {\n margin-right: var(--base-size-2);\n }\n}\n\n/* When tabnav-extra are anchors */\n/* stylelint-disable-next-line selector-no-qualifying-type, selector-max-type */\na.tabnav-extra:hover {\n color: var(--fgColor-accent);\n text-decoration: none;\n}\n\n/* Tabnav buttons\n**\n** For when there are multiple buttons, space them out appropriately. Requires\n** the buttons to be floated or inline-block. */\n\n.tabnav-btn {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--controlStack-medium-gap-condensed);\n}\n"]}
1
+ {"version":3,"sources":["tab_nav.pcss"],"names":[],"mappings":"AAGA,QAIE,sEAAuE,CADvE,qCAAsC,CAFtC,YAIF,CAEA,aACE,YAAa,CAEb,8CAAiD,CACjD,eAAgB,CAChB,iBAMF,CAEA,4BAJI,aA2DJ,CAvDA,YAUE,wBAA6B,CAE7B,0CAAgB,CAAhB,eAAgB,CAJhB,0BAA2B,CAP3B,oBAAqB,CAIrB,sCAAuC,CAEvC,gBAAiB,CAHjB,uEAAwE,CAKxE,4BAAqB,CAArB,oBAAqB,CAIrB,4CA0CF,CAxCE,yGAIE,uCAAwC,CACxC,uCAAwC,CACxC,uEAAwE,CAHxE,4BAQF,CAHE,uHACE,aACF,CAGF,kBACE,4BAA6B,CAC7B,4BAAqB,CAArB,oBAAqB,CACrB,uBACF,CAEA,4CAEE,iFAAmF,CACnF,mBACF,CAMA,wCAHE,0BAOF,CAJA,qBAEE,qCAEF,CAEA,qBAGE,aAAc,CADd,oCAEF,CAQF,cAOE,0BAA2B,CAN3B,oBAAqB,CAKrB,qCAAsC,CADtC,gBAAiB,CAFjB,gBASF,CAHE,uBACE,+BACF,CAKF,qBACE,2BAA4B,CAC5B,4BAAqB,CAArB,oBACF,CAOA,YAEE,oDACF","file":"tab_nav.css","sourcesContent":["/* tabnav */\n\n/* Outer wrapper */\n.tabnav {\n margin-top: 0;\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-normal);\n border-bottom: var(--borderWidth-thin) solid var(--borderColor-default);\n}\n\n.tabnav-tabs {\n display: flex;\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: calc(var(--borderWidth-thin) * -1);\n overflow-x: auto;\n overflow-y: hidden;\n\n /* stylelint-disable-next-line selector-max-type */\n & > li {\n flex-shrink: 0;\n }\n}\n\n.tabnav-tab {\n display: inline-block;\n flex-shrink: 0;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--base-size-8) var(--control-medium-paddingInline-spacious);\n font-size: var(--text-body-size-medium);\n /* stylelint-disable-next-line primer/typography */\n line-height: 23px;\n color: var(--fgColor-muted);\n text-decoration: none;\n background-color: transparent;\n border: var(--borderWidth-thin) solid transparent;\n border-bottom: 0;\n transition: color 0.2s cubic-bezier(0.3, 0, 0.5, 1);\n\n &.selected,\n &[aria-selected='true'],\n &[aria-current]:not([aria-current='false']) {\n color: var(--fgColor-default);\n background-color: var(--bgColor-default); /* cover bottom border */\n border-color: var(--borderColor-default);\n border-radius: var(--borderRadius-medium) var(--borderRadius-medium) 0 0;\n\n & .octicon {\n color: inherit;\n }\n }\n\n &:hover {\n color: var(--fgColor-default);\n text-decoration: none;\n transition-duration: 0.1s;\n }\n\n &:focus,\n &:focus-visible {\n border-radius: var(--borderRadius-medium) var(--borderRadius-medium) 0 0 !important;\n outline-offset: -6px;\n }\n\n &:active {\n color: var(--fgColor-muted);\n }\n\n & .octicon {\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--control-small-gap);\n color: var(--fgColor-muted);\n }\n\n & .Counter {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-small-gap);\n color: inherit;\n }\n}\n\n/* Tabnav extras\n**\n** Tabnav extras are non-tab elements that sit in the tabnav. Usually they're\n** inline text or links. */\n\n.tabnav-extra {\n display: inline-block;\n /* stylelint-disable-next-line primer/spacing */\n padding-top: 10px;\n /* stylelint-disable-next-line primer/spacing */\n margin-left: 10px;\n font-size: var(--text-body-size-small);\n color: var(--fgColor-muted);\n\n & > .octicon {\n margin-right: var(--base-size-2);\n }\n}\n\n/* When tabnav-extra are anchors */\n/* stylelint-disable-next-line selector-no-qualifying-type, selector-max-type */\na.tabnav-extra:hover {\n color: var(--fgColor-accent);\n text-decoration: none;\n}\n\n/* Tabnav buttons\n**\n** For when there are multiple buttons, space them out appropriately. Requires\n** the buttons to be floated or inline-block. */\n\n.tabnav-btn {\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--controlStack-medium-gap-condensed);\n}\n"]}
@@ -12,7 +12,13 @@
12
12
  display: flex;
13
13
  /* stylelint-disable-next-line primer/spacing */
14
14
  margin-bottom: calc(var(--borderWidth-thin) * -1);
15
- overflow: hidden;
15
+ overflow-x: auto;
16
+ overflow-y: hidden;
17
+
18
+ /* stylelint-disable-next-line selector-max-type */
19
+ & > li {
20
+ flex-shrink: 0;
21
+ }
16
22
  }
17
23
 
18
24
  .tabnav-tab {
@@ -171,7 +171,7 @@ __decorate([
171
171
  attr
172
172
  ], ToggleSwitchElement.prototype, "turbo", void 0);
173
173
  ToggleSwitchElement = __decorate([
174
- controller
174
+ controller('toggle-switch')
175
175
  ], ToggleSwitchElement);
176
176
  if (!window.customElements.get('toggle-switch')) {
177
177
  window.ToggleSwitchElement = ToggleSwitchElement;
@@ -39,6 +39,7 @@ module Primer
39
39
  # Only customize this label if it makes the toggle’s state more meaningful
40
40
  # in its specific context. For example, for a "Show images" setting,
41
41
  # you might use "Show" when the switch is OFF.
42
+ # @param button_type [Symbol] The type attribute for the underlying button element. If `nil`, the button will not have a type attribute, which means it will default to "submit" if it's inside a form and "button" otherwise.
42
43
 
43
44
  def initialize(
44
45
  src: nil,
@@ -51,6 +52,7 @@ module Primer
51
52
  autofocus: nil,
52
53
  on_label: nil,
53
54
  off_label: nil,
55
+ button_type: nil,
54
56
  **system_arguments
55
57
  )
56
58
  @src = src
@@ -75,6 +77,7 @@ module Primer
75
77
  )
76
78
 
77
79
  @button_arguments = {
80
+ type: button_type,
78
81
  aria: merge_aria(
79
82
  @system_arguments,
80
83
  aria: { pressed: on? }
@@ -1,6 +1,6 @@
1
1
  import {controller, target, attr} from '@github/catalyst'
2
2
 
3
- @controller
3
+ @controller('toggle-switch')
4
4
  class ToggleSwitchElement extends HTMLElement {
5
5
  @target switch: HTMLElement
6
6
  @target loadingSpinner: HTMLElement
@@ -354,7 +354,7 @@ __decorate([
354
354
  target
355
355
  ], TreeViewElement.prototype, "formInputPrototype", void 0);
356
356
  TreeViewElement = __decorate([
357
- controller
357
+ controller('tree-view')
358
358
  ], TreeViewElement);
359
359
  export { TreeViewElement };
360
360
  if (!window.customElements.get('tree-view')) {
@@ -3,7 +3,7 @@ import {TreeViewSubTreeNodeElement} from './tree_view_sub_tree_node_element'
3
3
  import {useRovingTabIndex} from './tree_view_roving_tab_index'
4
4
  import type {TreeViewNodeType, TreeViewCheckedValue, TreeViewNodeInfo} from '../../shared_events'
5
5
 
6
- @controller
6
+ @controller('tree-view')
7
7
  export class TreeViewElement extends HTMLElement {
8
8
  @target formInputContainer: HTMLElement
9
9
  @target formInputPrototype: HTMLInputElement
@@ -53,7 +53,7 @@ __decorate([
53
53
  target
54
54
  ], TreeViewIconPairElement.prototype, "collapsedIcon", void 0);
55
55
  TreeViewIconPairElement = __decorate([
56
- controller
56
+ controller('tree-view-icon-pair')
57
57
  ], TreeViewIconPairElement);
58
58
  export { TreeViewIconPairElement };
59
59
  if (!window.customElements.get('tree-view-icon-pair')) {
@@ -1,7 +1,7 @@
1
1
  import {controller, target} from '@github/catalyst'
2
2
  import {observeMutationsUntilConditionMet} from '../../utils'
3
3
 
4
- @controller
4
+ @controller('tree-view-icon-pair')
5
5
  export class TreeViewIconPairElement extends HTMLElement {
6
6
  @target expandedIcon: HTMLElement
7
7
  @target collapsedIcon: HTMLElement
@@ -19,7 +19,7 @@ let TreeViewIncludeFragmentElement = class TreeViewIncludeFragmentElement extend
19
19
  }
20
20
  };
21
21
  TreeViewIncludeFragmentElement = __decorate([
22
- controller
22
+ controller('tree-view-include-fragment')
23
23
  ], TreeViewIncludeFragmentElement);
24
24
  export { TreeViewIncludeFragmentElement };
25
25
  if (!window.customElements.get('tree-view-include-fragment')) {
@@ -1,7 +1,7 @@
1
1
  import {controller} from '@github/catalyst'
2
2
  import {IncludeFragmentElement} from '@github/include-fragment-element'
3
3
 
4
- @controller
4
+ @controller('tree-view-include-fragment')
5
5
  export class TreeViewIncludeFragmentElement extends IncludeFragmentElement {
6
6
  request(): Request {
7
7
  const originalRequest = super.request()
@@ -15,7 +15,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
15
15
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
16
16
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
17
17
  };
18
- var _TreeViewSubTreeNodeElement_instances, _TreeViewSubTreeNodeElement_expanded, _TreeViewSubTreeNodeElement_loadingState, _TreeViewSubTreeNodeElement_abortController, _TreeViewSubTreeNodeElement_activeElementIsLoader, _TreeViewSubTreeNodeElement_handleToggleEvent, _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent, _TreeViewSubTreeNodeElement_handleRetryButtonEvent, _TreeViewSubTreeNodeElement_handleKeyboardEvent, _TreeViewSubTreeNodeElement_handleCheckboxEvent, _TreeViewSubTreeNodeElement_update, _TreeViewSubTreeNodeElement_checkboxElement_get;
18
+ var _TreeViewSubTreeNodeElement_instances, _TreeViewSubTreeNodeElement_expanded, _TreeViewSubTreeNodeElement_loadingState, _TreeViewSubTreeNodeElement_abortController, _TreeViewSubTreeNodeElement_activeElementIsLoader, _TreeViewSubTreeNodeElement_handleToggleEvent, _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent, _TreeViewSubTreeNodeElement_handleRetryButtonEvent, _TreeViewSubTreeNodeElement_handleKeyboardEvent, _TreeViewSubTreeNodeElement_handleCheckboxEvent, _TreeViewSubTreeNodeElement_update, _TreeViewSubTreeNodeElement_isIncludeFragment, _TreeViewSubTreeNodeElement_checkboxElement_get;
19
19
  import { controller, target } from '@github/catalyst';
20
20
  import { observeMutationsUntilConditionMet } from '../../utils';
21
21
  let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLElement {
@@ -134,6 +134,10 @@ let TreeViewSubTreeNodeElement = class TreeViewSubTreeNodeElement extends HTMLEl
134
134
  // sub-tree and no node in the entire tree can be focused
135
135
  const previousNode = this.subTree.querySelector("[tabindex='0']");
136
136
  previousNode?.setAttribute('tabindex', '-1');
137
+ // Also check if the subtree element itself is an include-fragment with role="treeitem" and has focus
138
+ if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_isIncludeFragment).call(this) && this.subTree.getAttribute('tabindex') === '0') {
139
+ this.subTree.setAttribute('tabindex', '-1');
140
+ }
137
141
  this.node.setAttribute('tabindex', '0');
138
142
  this.treeView.dispatchEvent(new CustomEvent('treeViewNodeCollapsed', {
139
143
  bubbles: true,
@@ -237,6 +241,10 @@ _TreeViewSubTreeNodeElement_handleIncludeFragmentEvent = function _TreeViewSubTr
237
241
  // request succeeded but element has not yet been replaced
238
242
  case 'include-fragment-replace':
239
243
  __classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, document.activeElement === this.loadingIndicator.closest('[role=treeitem]'), "f");
244
+ // Also check if the include-fragment itself has focus (when it has role="treeitem")
245
+ if (!__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, "f") && document.activeElement === this.subTree && __classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_isIncludeFragment).call(this)) {
246
+ __classPrivateFieldSet(this, _TreeViewSubTreeNodeElement_activeElementIsLoader, true, "f");
247
+ }
240
248
  this.loadingState = 'success';
241
249
  break;
242
250
  case 'include-fragment-replaced':
@@ -332,6 +340,13 @@ _TreeViewSubTreeNodeElement_update = function _TreeViewSubTreeNodeElement_update
332
340
  if (this.expanded) {
333
341
  if (this.subTree)
334
342
  this.subTree.hidden = false;
343
+ if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_isIncludeFragment).call(this)) {
344
+ this.subTree.setAttribute('role', 'treeitem');
345
+ // Ensure the include-fragment can participate in roving tab index
346
+ if (!this.subTree.hasAttribute('tabindex')) {
347
+ this.subTree.setAttribute('tabindex', '-1');
348
+ }
349
+ }
335
350
  this.node.setAttribute('aria-expanded', 'true');
336
351
  this.treeView?.expandAncestorsForNode(this);
337
352
  if (this.iconPair) {
@@ -345,6 +360,11 @@ _TreeViewSubTreeNodeElement_update = function _TreeViewSubTreeNodeElement_update
345
360
  else {
346
361
  if (this.subTree)
347
362
  this.subTree.hidden = true;
363
+ if (__classPrivateFieldGet(this, _TreeViewSubTreeNodeElement_instances, "m", _TreeViewSubTreeNodeElement_isIncludeFragment).call(this)) {
364
+ this.subTree.removeAttribute('role');
365
+ // Remove tabindex when role is removed
366
+ this.subTree.removeAttribute('tabindex');
367
+ }
348
368
  this.node.setAttribute('aria-expanded', 'false');
349
369
  if (this.iconPair) {
350
370
  this.iconPair.showCollapsed();
@@ -375,6 +395,9 @@ _TreeViewSubTreeNodeElement_update = function _TreeViewSubTreeNodeElement_update
375
395
  this.loadingFailureMessage.hidden = true;
376
396
  }
377
397
  };
398
+ _TreeViewSubTreeNodeElement_isIncludeFragment = function _TreeViewSubTreeNodeElement_isIncludeFragment() {
399
+ return this.subTree?.getAttribute('data-target')?.includes('tree-view-sub-tree-node.includeFragment') ?? false;
400
+ };
378
401
  _TreeViewSubTreeNodeElement_checkboxElement_get = function _TreeViewSubTreeNodeElement_checkboxElement_get() {
379
402
  return this.querySelector('.TreeViewItemCheckbox');
380
403
  };
@@ -409,7 +432,7 @@ __decorate([
409
432
  target
410
433
  ], TreeViewSubTreeNodeElement.prototype, "retryButton", void 0);
411
434
  TreeViewSubTreeNodeElement = __decorate([
412
- controller
435
+ controller('tree-view-sub-tree-node')
413
436
  ], TreeViewSubTreeNodeElement);
414
437
  export { TreeViewSubTreeNodeElement };
415
438
  if (!window.customElements.get('tree-view-sub-tree-node')) {
@@ -9,7 +9,7 @@ type LoadingState = 'loading' | 'error' | 'success'
9
9
 
10
10
  export type SelectStrategy = 'self' | 'descendants' | 'mixed_descendants'
11
11
 
12
- @controller
12
+ @controller('tree-view-sub-tree-node')
13
13
  export class TreeViewSubTreeNodeElement extends HTMLElement {
14
14
  @target node: HTMLElement
15
15
  @target subTree: HTMLElement
@@ -178,6 +178,12 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
178
178
  // sub-tree and no node in the entire tree can be focused
179
179
  const previousNode = this.subTree.querySelector("[tabindex='0']")
180
180
  previousNode?.setAttribute('tabindex', '-1')
181
+
182
+ // Also check if the subtree element itself is an include-fragment with role="treeitem" and has focus
183
+ if (this.#isIncludeFragment() && this.subTree.getAttribute('tabindex') === '0') {
184
+ this.subTree.setAttribute('tabindex', '-1')
185
+ }
186
+
181
187
  this.node.setAttribute('tabindex', '0')
182
188
 
183
189
  this.treeView.dispatchEvent(
@@ -263,6 +269,10 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
263
269
  // request succeeded but element has not yet been replaced
264
270
  case 'include-fragment-replace':
265
271
  this.#activeElementIsLoader = document.activeElement === this.loadingIndicator.closest('[role=treeitem]')
272
+ // Also check if the include-fragment itself has focus (when it has role="treeitem")
273
+ if (!this.#activeElementIsLoader && document.activeElement === this.subTree && this.#isIncludeFragment()) {
274
+ this.#activeElementIsLoader = true
275
+ }
266
276
  this.loadingState = 'success'
267
277
  break
268
278
 
@@ -410,6 +420,13 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
410
420
  #update() {
411
421
  if (this.expanded) {
412
422
  if (this.subTree) this.subTree.hidden = false
423
+ if (this.#isIncludeFragment()) {
424
+ this.subTree.setAttribute('role', 'treeitem')
425
+ // Ensure the include-fragment can participate in roving tab index
426
+ if (!this.subTree.hasAttribute('tabindex')) {
427
+ this.subTree.setAttribute('tabindex', '-1')
428
+ }
429
+ }
413
430
  this.node.setAttribute('aria-expanded', 'true')
414
431
  this.treeView?.expandAncestorsForNode(this)
415
432
 
@@ -423,6 +440,11 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
423
440
  }
424
441
  } else {
425
442
  if (this.subTree) this.subTree.hidden = true
443
+ if (this.#isIncludeFragment()) {
444
+ this.subTree.removeAttribute('role')
445
+ // Remove tabindex when role is removed
446
+ this.subTree.removeAttribute('tabindex')
447
+ }
426
448
  this.node.setAttribute('aria-expanded', 'false')
427
449
 
428
450
  if (this.iconPair) {
@@ -453,6 +475,10 @@ export class TreeViewSubTreeNodeElement extends HTMLElement {
453
475
  }
454
476
  }
455
477
 
478
+ #isIncludeFragment(): boolean {
479
+ return this.subTree?.getAttribute('data-target')?.includes('tree-view-sub-tree-node.includeFragment') ?? false
480
+ }
481
+
456
482
  get #checkboxElement(): HTMLElement | null {
457
483
  return this.querySelector('.TreeViewItemCheckbox')
458
484
  }
@@ -43,7 +43,7 @@ __decorate([
43
43
  target
44
44
  ], XBannerElement.prototype, "titleText", void 0);
45
45
  XBannerElement = __decorate([
46
- controller
46
+ controller('x-banner')
47
47
  ], XBannerElement);
48
48
  if (!window.customElements.get('x-banner')) {
49
49
  window.XBannerElement = XBannerElement;
@@ -6,7 +6,7 @@ declare global {
6
6
  }
7
7
  }
8
8
 
9
- @controller
9
+ @controller('x-banner')
10
10
  class XBannerElement extends HTMLElement {
11
11
  @target titleText: HTMLElement
12
12
 
@@ -1 +1 @@
1
- .blankslate-container{container-type:inline-size;width:100%}.blankslate{--blankslate-outer-padding-block:var(--base-size-32);--blankslate-outer-padding-inline:var(--base-size-32);padding:var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);position:relative;text-align:center}.blankslate p{color:var(--fgColor-muted);font-size:var(--text-body-size-large)}.blankslate code{background:var(--bgColor-default);border:var(--borderWidth-thin) solid var(--borderColor-muted);border-radius:var(--borderRadius-medium);font-size:var(--text-body-size-medium);padding:var(--base-size-2) var(--base-size-4) var(--base-size-4)}.blankslate img{height:56px;width:56px}.blankslate-icon{color:var(--fgColor-muted);margin-bottom:var(--stack-gap-condensed);margin-left:var(--control-small-gap);margin-right:var(--control-small-gap)}.blankslate-image{margin-bottom:var(--stack-gap-normal)}.blankslate-heading{font-size:var(--text-title-size-medium);font-weight:var(--text-title-weight-medium);margin-bottom:var(--base-size-4)}.blankslate-action{margin-top:var(--stack-gap-normal)}.blankslate-action:first-of-type{margin-top:var(--stack-gap-spacious)}.blankslate-action:last-of-type{margin-bottom:var(--stack-gap-condensed)}.blankslate-capped{border-radius:0 0 var(--borderRadius-medium) var(--borderRadius-medium)}.blankslate-spacious{--blankslate-outer-padding-block:var(--base-size-80);--blankslate-outer-padding-inline:var(--base-size-40)}.blankslate-narrow{margin:0 auto;max-width:485px}.blankslate-large img{height:80px;width:80px}.blankslate-large h3{font-size:24px;margin:var(--stack-gap-normal) 0}.blankslate-large p{font-size:var(--text-body-size-large)}.blankslate-clean-background{border:0}@container (max-width: 34rem){.blankslate{--blankslate-outer-padding-block:var(--base-size-20);--blankslate-outer-padding-inline:var(--base-size-20)}.blankslate-spacious{--blankslate-outer-padding-block:var(--base-size-44);--blankslate-outer-padding-inline:var(--base-size-28)}.blankslate-icon{margin-bottom:var(--stack-gap-condensed)}.blankslate-heading{font-size:var(--text-title-size-small)}.blankslate p{font-size:var(--text-body-size-medium)}.blankslate-action{margin-top:var(--stack-gap-condensed)}.blankslate-action:first-of-type{margin-top:var(--stack-gap-normal)}.blankslate-action:last-of-type{margin-bottom:calc(var(--stack-gap-condensed)/2)}}
1
+ .blankslate-container{container-type:inline-size;width:100%}.blankslate{--blankslate-outer-padding-block:var(--base-size-32);--blankslate-outer-padding-inline:var(--base-size-32);padding:var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);position:relative;text-align:center}.blankslate p{color:var(--fgColor-muted);font-size:var(--text-body-size-large)}.blankslate code{background:var(--bgColor-default);border:var(--borderWidth-thin) solid var(--borderColor-muted);border-radius:var(--borderRadius-medium);font-size:var(--text-body-size-medium);padding:var(--base-size-2) var(--base-size-4) var(--base-size-4)}.blankslate img{height:56px;width:56px}.blankslate-icon{color:var(--fgColor-muted);margin-bottom:var(--stack-gap-condensed);margin-left:var(--control-small-gap);margin-right:var(--control-small-gap)}.blankslate-image{margin-bottom:var(--stack-gap-normal)}.blankslate-heading{font-size:var(--text-title-size-medium);font-weight:var(--text-title-weight-medium);margin-bottom:var(--base-size-4);text-wrap:balance}.blankslate-description{text-wrap:balance}.blankslate-action{margin-top:var(--stack-gap-normal)}.blankslate-action:first-of-type{margin-top:var(--stack-gap-spacious)}.blankslate-action:last-of-type{margin-bottom:var(--stack-gap-condensed)}.blankslate-capped{border-radius:0 0 var(--borderRadius-medium) var(--borderRadius-medium)}.blankslate-spacious{--blankslate-outer-padding-block:var(--base-size-80);--blankslate-outer-padding-inline:var(--base-size-40)}.blankslate-narrow{margin:0 auto;max-width:485px}.blankslate-large img{height:80px;width:80px}.blankslate-large h3{font-size:24px;margin:var(--stack-gap-normal) 0}.blankslate-large p{font-size:var(--text-body-size-large)}.blankslate-clean-background{border:0}@container (max-width: 34rem){.blankslate{--blankslate-outer-padding-block:var(--base-size-20);--blankslate-outer-padding-inline:var(--base-size-20)}.blankslate-spacious{--blankslate-outer-padding-block:var(--base-size-44);--blankslate-outer-padding-inline:var(--base-size-28)}.blankslate-icon{margin-bottom:var(--stack-gap-condensed)}.blankslate-heading{font-size:var(--text-title-size-small)}.blankslate p{font-size:var(--text-body-size-medium)}.blankslate-action{margin-top:var(--stack-gap-condensed)}.blankslate-action:first-of-type{margin-top:var(--stack-gap-normal)}.blankslate-action:last-of-type{margin-bottom:calc(var(--stack-gap-condensed)/2)}}
@@ -9,6 +9,7 @@
9
9
  ".blankslate-icon",
10
10
  ".blankslate-image",
11
11
  ".blankslate-heading",
12
+ ".blankslate-description",
12
13
  ".blankslate-action",
13
14
  ".blankslate-action:first-of-type",
14
15
  ".blankslate-action:last-of-type",
@@ -1 +1 @@
1
- {"version":3,"sources":["blankslate.pcss"],"names":[],"mappings":"AAEA,sBACE,0BAA2B,CAC3B,UACF,CAEA,YACE,oDAAqD,CACrD,qDAAsD,CAItD,oFAAqF,CAFrF,iBAAkB,CAGlB,iBAsBF,CAnBE,cAEE,0BAA2B,CAD3B,qCAEF,CAGA,iBAGE,iCAAkC,CAClC,6DAA8D,CAC9D,wCAAyC,CAHzC,sCAAuC,CADvC,gEAKF,CAGA,gBAEE,WAAY,CADZ,UAEF,CAGF,iBAOE,0BAA2B,CAH3B,wCAAyC,CAEzC,oCAAqC,CAJrC,qCAMF,CAEA,kBAEE,qCACF,CAEA,oBAEE,uCAAwC,CACxC,2CAA4C,CAF5C,gCAGF,CAEA,mBAEE,kCAWF,CATE,iCAEE,oCACF,CAEA,gCAEE,wCACF,CAGF,mBACE,uEACF,CAEA,qBACE,oDAAqD,CACrD,qDACF,CAEA,mBAEE,aAAc,CADd,eAEF,CAME,sBAEE,WAAY,CADZ,UAEF,CAGA,qBAME,cAAe,CAJf,gCAKF,CAGA,oBACE,qCACF,CAKF,6BACE,QACF,CAIA,8BACE,YACE,oDAAqD,CACrD,qDACF,CAEA,qBACE,oDAAqD,CACrD,qDACF,CAEA,iBAEE,wCACF,CAEA,oBACE,sCACF,CAGA,cACE,sCACF,CAEA,mBAEE,qCAWF,CATE,iCAEE,kCACF,CAEA,gCAEE,gDACF,CAEJ","file":"blankslate.css","sourcesContent":["/* blankslate */\n\n.blankslate-container {\n container-type: inline-size;\n width: 100%;\n}\n\n.blankslate {\n --blankslate-outer-padding-block: var(--base-size-32);\n --blankslate-outer-padding-inline: var(--base-size-32);\n\n position: relative;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);\n text-align: center;\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-large);\n color: var(--fgColor-muted);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & code {\n padding: var(--base-size-2) var(--base-size-4) var(--base-size-4);\n font-size: var(--text-body-size-medium);\n background: var(--bgColor-default);\n border: var(--borderWidth-thin) solid var(--borderColor-muted);\n border-radius: var(--borderRadius-medium);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 56px;\n height: 56px;\n }\n}\n\n.blankslate-icon {\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--control-small-gap);\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-small-gap);\n color: var(--fgColor-muted);\n}\n\n.blankslate-image {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-normal);\n}\n\n.blankslate-heading {\n margin-bottom: var(--base-size-4);\n font-size: var(--text-title-size-medium);\n font-weight: var(--text-title-weight-medium);\n}\n\n.blankslate-action {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-normal);\n\n &:first-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-spacious);\n }\n\n &:last-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n }\n}\n\n.blankslate-capped {\n border-radius: 0 0 var(--borderRadius-medium) var(--borderRadius-medium);\n}\n\n.blankslate-spacious {\n --blankslate-outer-padding-block: var(--base-size-80);\n --blankslate-outer-padding-inline: var(--base-size-40);\n}\n\n.blankslate-narrow {\n max-width: 485px;\n margin: 0 auto;\n}\n\n/* was .large-format\n** QUESTION: should we deprecate this? */\n.blankslate-large {\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 80px;\n height: 80px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & h3 {\n /* stylelint-disable-next-line primer/spacing */\n margin: var(--stack-gap-normal) 0;\n\n /* font-size: $h3-size; // This doesn't actually make the text larger. Should this be $h2-size? */\n /* stylelint-disable-next-line primer/typography */\n font-size: 24px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-large);\n }\n}\n\n/* was .clean-background\n** TO DO: deprecate this and use utility instead */\n.blankslate-clean-background {\n border: 0;\n}\n\n/* At the time these styles were written,\n `34rem` was our \"small\" breakpoint width */\n@container (max-width: 34rem) {\n .blankslate {\n --blankslate-outer-padding-block: var(--base-size-20);\n --blankslate-outer-padding-inline: var(--base-size-20);\n }\n\n .blankslate-spacious {\n --blankslate-outer-padding-block: var(--base-size-44);\n --blankslate-outer-padding-inline: var(--base-size-28);\n }\n\n .blankslate-icon {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n }\n\n .blankslate-heading {\n font-size: var(--text-title-size-small);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n .blankslate p {\n font-size: var(--text-body-size-medium);\n }\n\n .blankslate-action {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-condensed);\n\n &:first-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-normal);\n }\n\n &:last-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: calc(var(--stack-gap-condensed) / 2);\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["blankslate.pcss"],"names":[],"mappings":"AAEA,sBACE,0BAA2B,CAC3B,UACF,CAEA,YACE,oDAAqD,CACrD,qDAAsD,CAItD,oFAAqF,CAFrF,iBAAkB,CAGlB,iBAsBF,CAnBE,cAEE,0BAA2B,CAD3B,qCAEF,CAGA,iBAGE,iCAAkC,CAClC,6DAA8D,CAC9D,wCAAyC,CAHzC,sCAAuC,CADvC,gEAKF,CAGA,gBAEE,WAAY,CADZ,UAEF,CAGF,iBAOE,0BAA2B,CAH3B,wCAAyC,CAEzC,oCAAqC,CAJrC,qCAMF,CAEA,kBAEE,qCACF,CAEA,oBAEE,uCAAwC,CACxC,2CAA4C,CAF5C,gCAAiC,CAGjC,iBACF,CAEA,wBACE,iBACF,CAEA,mBAEE,kCAWF,CATE,iCAEE,oCACF,CAEA,gCAEE,wCACF,CAGF,mBACE,uEACF,CAEA,qBACE,oDAAqD,CACrD,qDACF,CAEA,mBAEE,aAAc,CADd,eAEF,CAME,sBAEE,WAAY,CADZ,UAEF,CAGA,qBAME,cAAe,CAJf,gCAKF,CAGA,oBACE,qCACF,CAKF,6BACE,QACF,CAIA,8BACE,YACE,oDAAqD,CACrD,qDACF,CAEA,qBACE,oDAAqD,CACrD,qDACF,CAEA,iBAEE,wCACF,CAEA,oBACE,sCACF,CAGA,cACE,sCACF,CAEA,mBAEE,qCAWF,CATE,iCAEE,kCACF,CAEA,gCAEE,gDACF,CAEJ","file":"blankslate.css","sourcesContent":["/* blankslate */\n\n.blankslate-container {\n container-type: inline-size;\n width: 100%;\n}\n\n.blankslate {\n --blankslate-outer-padding-block: var(--base-size-32);\n --blankslate-outer-padding-inline: var(--base-size-32);\n\n position: relative;\n /* stylelint-disable-next-line primer/spacing */\n padding: var(--blankslate-outer-padding-block) var(--blankslate-outer-padding-inline);\n text-align: center;\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-large);\n color: var(--fgColor-muted);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & code {\n padding: var(--base-size-2) var(--base-size-4) var(--base-size-4);\n font-size: var(--text-body-size-medium);\n background: var(--bgColor-default);\n border: var(--borderWidth-thin) solid var(--borderColor-muted);\n border-radius: var(--borderRadius-medium);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 56px;\n height: 56px;\n }\n}\n\n.blankslate-icon {\n /* stylelint-disable-next-line primer/spacing */\n margin-right: var(--control-small-gap);\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n /* stylelint-disable-next-line primer/spacing */\n margin-left: var(--control-small-gap);\n color: var(--fgColor-muted);\n}\n\n.blankslate-image {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-normal);\n}\n\n.blankslate-heading {\n margin-bottom: var(--base-size-4);\n font-size: var(--text-title-size-medium);\n font-weight: var(--text-title-weight-medium);\n text-wrap: balance;\n}\n\n.blankslate-description {\n text-wrap: balance;\n}\n\n.blankslate-action {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-normal);\n\n &:first-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-spacious);\n }\n\n &:last-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n }\n}\n\n.blankslate-capped {\n border-radius: 0 0 var(--borderRadius-medium) var(--borderRadius-medium);\n}\n\n.blankslate-spacious {\n --blankslate-outer-padding-block: var(--base-size-80);\n --blankslate-outer-padding-inline: var(--base-size-40);\n}\n\n.blankslate-narrow {\n max-width: 485px;\n margin: 0 auto;\n}\n\n/* was .large-format\n** QUESTION: should we deprecate this? */\n.blankslate-large {\n /* stylelint-disable-next-line selector-max-type */\n & img {\n width: 80px;\n height: 80px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & h3 {\n /* stylelint-disable-next-line primer/spacing */\n margin: var(--stack-gap-normal) 0;\n\n /* font-size: $h3-size; // This doesn't actually make the text larger. Should this be $h2-size? */\n /* stylelint-disable-next-line primer/typography */\n font-size: 24px;\n }\n\n /* stylelint-disable-next-line selector-max-type */\n & p {\n font-size: var(--text-body-size-large);\n }\n}\n\n/* was .clean-background\n** TO DO: deprecate this and use utility instead */\n.blankslate-clean-background {\n border: 0;\n}\n\n/* At the time these styles were written,\n `34rem` was our \"small\" breakpoint width */\n@container (max-width: 34rem) {\n .blankslate {\n --blankslate-outer-padding-block: var(--base-size-20);\n --blankslate-outer-padding-inline: var(--base-size-20);\n }\n\n .blankslate-spacious {\n --blankslate-outer-padding-block: var(--base-size-44);\n --blankslate-outer-padding-inline: var(--base-size-28);\n }\n\n .blankslate-icon {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: var(--stack-gap-condensed);\n }\n\n .blankslate-heading {\n font-size: var(--text-title-size-small);\n }\n\n /* stylelint-disable-next-line selector-max-type */\n .blankslate p {\n font-size: var(--text-body-size-medium);\n }\n\n .blankslate-action {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-condensed);\n\n &:first-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-top: var(--stack-gap-normal);\n }\n\n &:last-of-type {\n /* stylelint-disable-next-line primer/spacing */\n margin-bottom: calc(var(--stack-gap-condensed) / 2);\n }\n }\n}\n"]}
@@ -55,6 +55,11 @@
55
55
  margin-bottom: var(--base-size-4);
56
56
  font-size: var(--text-title-size-medium);
57
57
  font-weight: var(--text-title-weight-medium);
58
+ text-wrap: balance;
59
+ }
60
+
61
+ .blankslate-description {
62
+ text-wrap: balance;
58
63
  }
59
64
 
60
65
  .blankslate-action {
@@ -65,6 +65,7 @@ module Primer
65
65
  renders_one :description, lambda { |**system_arguments|
66
66
  deny_tag_argument(**system_arguments)
67
67
  system_arguments[:tag] = :p
68
+ system_arguments[:classes] = class_names("blankslate-description", system_arguments[:classes])
68
69
 
69
70
  Primer::BaseComponent.new(**system_arguments)
70
71
  }
@@ -60,6 +60,6 @@ __decorate([
60
60
  target
61
61
  ], DetailsToggleElement.prototype, "summaryTarget", void 0);
62
62
  DetailsToggleElement = __decorate([
63
- controller
63
+ controller('details-toggle')
64
64
  ], DetailsToggleElement);
65
65
  window.DetailsToggleElement = DetailsToggleElement;
@@ -30,7 +30,7 @@ import {controller, target} from '@github/catalyst'
30
30
  * ```
31
31
  */
32
32
 
33
- @controller
33
+ @controller('details-toggle')
34
34
  class DetailsToggleElement extends HTMLElement {
35
35
  @target detailsTarget!: HTMLDetailsElement
36
36
  @target summaryTarget!: HTMLElement
@@ -187,6 +187,6 @@ __decorate([
187
187
  target
188
188
  ], NavListElement.prototype, "topLevelList", void 0);
189
189
  NavListElement = __decorate([
190
- controller
190
+ controller('nav-list')
191
191
  ], NavListElement);
192
192
  export { NavListElement };
@@ -1,7 +1,7 @@
1
1
  import {controller, target, targets} from '@github/catalyst'
2
2
  import {ActionListTruncationObserver} from '../alpha/action_list'
3
3
 
4
- @controller
4
+ @controller('nav-list')
5
5
  export class NavListElement extends HTMLElement {
6
6
  @targets items: HTMLElement[]
7
7
  @target topLevelList: HTMLElement