primer_view_components 0.1.4 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +30 -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 +2 -2
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_list/heading.html.erb +1 -1
  8. data/app/components/primer/alpha/action_list/heading.rb +5 -3
  9. data/app/components/primer/alpha/action_list/item.html.erb +9 -0
  10. data/app/components/primer/alpha/action_list/item.rb +32 -11
  11. data/app/components/primer/alpha/action_list.css +1 -1
  12. data/app/components/primer/alpha/action_list.css.json +4 -41
  13. data/app/components/primer/alpha/action_list.css.map +1 -1
  14. data/app/components/primer/alpha/action_list.pcss +19 -20
  15. data/app/components/primer/alpha/action_list.rb +54 -6
  16. data/app/components/primer/alpha/action_menu/action_menu_element.d.ts +23 -0
  17. data/app/components/primer/alpha/action_menu/action_menu_element.js +165 -0
  18. data/app/components/primer/alpha/action_menu/action_menu_element.ts +168 -0
  19. data/app/components/primer/alpha/action_menu/list.rb +91 -0
  20. data/app/components/primer/alpha/action_menu.html.erb +26 -0
  21. data/app/components/primer/alpha/action_menu.rb +361 -0
  22. data/app/components/primer/alpha/auto_complete.css.json +0 -11
  23. data/app/components/primer/alpha/banner.css.json +0 -14
  24. data/app/components/primer/alpha/button_marketing.css.json +0 -10
  25. data/app/components/primer/alpha/dialog.css +1 -1
  26. data/app/components/primer/alpha/dialog.css.json +0 -65
  27. data/app/components/primer/alpha/dialog.css.map +1 -1
  28. data/app/components/primer/alpha/dialog.pcss +0 -4
  29. data/app/components/primer/alpha/dialog.rb +6 -2
  30. data/app/components/primer/alpha/dropdown/menu.rb +1 -1
  31. data/app/components/primer/alpha/dropdown.css.json +0 -21
  32. data/app/components/primer/alpha/layout.css.json +0 -27
  33. data/app/components/primer/alpha/menu.css.json +0 -11
  34. data/app/components/primer/alpha/modal_dialog.js +12 -0
  35. data/app/components/primer/alpha/modal_dialog.ts +17 -0
  36. data/app/components/primer/alpha/nav_list/item.rb +5 -0
  37. data/app/components/primer/alpha/overlay.css +1 -1
  38. data/app/components/primer/alpha/overlay.css.json +0 -3
  39. data/app/components/primer/alpha/overlay.css.map +1 -1
  40. data/app/components/primer/alpha/overlay.pcss +1 -0
  41. data/app/components/primer/alpha/overlay.rb +19 -19
  42. data/app/components/primer/alpha/segmented_control.css.json +0 -15
  43. data/app/components/primer/alpha/tab_nav.css.json +0 -10
  44. data/app/components/primer/alpha/text_field.css.json +0 -38
  45. data/app/components/primer/alpha/toggle_switch.css.json +0 -16
  46. data/app/components/primer/alpha/underline_nav.css.json +0 -13
  47. data/app/components/primer/beta/auto_complete/auto_complete.html.erb +1 -1
  48. data/app/components/primer/beta/auto_complete.rb +19 -1
  49. data/app/components/primer/beta/avatar.css.json +0 -14
  50. data/app/components/primer/beta/avatar_stack.css.json +0 -9
  51. data/app/components/primer/beta/blankslate.css.json +0 -12
  52. data/app/components/primer/beta/border_box.css.json +0 -32
  53. data/app/components/primer/beta/border_box.rb +3 -3
  54. data/app/components/primer/beta/breadcrumbs.css.json +0 -4
  55. data/app/components/primer/beta/button.css +1 -1
  56. data/app/components/primer/beta/button.css.json +0 -24
  57. data/app/components/primer/beta/button.css.map +1 -1
  58. data/app/components/primer/beta/button.pcss +5 -7
  59. data/app/components/primer/beta/counter.css.json +0 -6
  60. data/app/components/primer/beta/flash.css.json +0 -15
  61. data/app/components/primer/beta/label.css.json +0 -20
  62. data/app/components/primer/beta/link.css.json +0 -8
  63. data/app/components/primer/beta/popover.css.json +0 -18
  64. data/app/components/primer/beta/progress_bar.css.json +0 -6
  65. data/app/components/primer/beta/state.css.json +0 -10
  66. data/app/components/primer/beta/subhead.css.json +0 -8
  67. data/app/components/primer/beta/timeline_item.css.json +0 -9
  68. data/app/components/primer/beta/truncate.css.json +0 -6
  69. data/app/components/primer/focus_group.d.ts +19 -0
  70. data/app/components/primer/focus_group.js +144 -0
  71. data/app/components/primer/focus_group.ts +137 -0
  72. data/app/components/primer/icon_button.rb +1 -1
  73. data/app/components/primer/primer.d.ts +2 -0
  74. data/app/components/primer/primer.js +2 -0
  75. data/app/components/primer/primer.ts +2 -0
  76. data/app/components/primer/truncate.css.json +0 -7
  77. data/app/lib/primer/css/layout.css.json +0 -263
  78. data/app/lib/primer/css/utilities.css.json +0 -1636
  79. data/lib/primer/static/generate_arguments.rb +55 -0
  80. data/lib/primer/static/generate_audited_at.rb +17 -0
  81. data/lib/primer/static/generate_constants.rb +19 -0
  82. data/lib/primer/static/generate_info_arch.rb +156 -0
  83. data/lib/primer/static/generate_previews.rb +45 -0
  84. data/lib/primer/static/generate_statuses.rb +17 -0
  85. data/lib/primer/static.rb +72 -0
  86. data/lib/primer/view_components/linters/disallow_component_css_counter.rb +43 -4
  87. data/lib/primer/view_components/version.rb +1 -1
  88. data/lib/primer/view_components.rb +0 -48
  89. data/lib/primer/yard/component_manifest.rb +1 -0
  90. data/lib/primer/yard/component_ref.rb +14 -0
  91. data/lib/primer/yard/docs_helper.rb +3 -0
  92. data/lib/primer/yard/info_arch_docs_helper.rb +31 -0
  93. data/lib/primer/yard/legacy_gatsby_backend.rb +3 -35
  94. data/lib/primer/yard/registry.rb +2 -1
  95. data/lib/primer/yard.rb +1 -0
  96. data/lib/tasks/docs.rake +10 -12
  97. data/lib/tasks/static.rake +20 -28
  98. data/previews/primer/alpha/action_list_preview.rb +4 -1
  99. data/previews/primer/alpha/action_menu_preview/align_end.html.erb +6 -0
  100. data/previews/primer/alpha/action_menu_preview/content_labels.html.erb +9 -0
  101. data/previews/primer/alpha/action_menu_preview/opens_dialog.html.erb +21 -0
  102. data/previews/primer/alpha/action_menu_preview.rb +245 -0
  103. data/previews/primer/alpha/dialog_preview/body_has_scrollbar_overflow.html.erb +2 -2
  104. data/previews/primer/alpha/dialog_preview/custom_header.html.erb +3 -3
  105. data/previews/primer/alpha/dialog_preview/nested_dialog.html.erb +4 -4
  106. data/previews/primer/alpha/dialog_preview/test.html.erb +3 -3
  107. data/previews/primer/alpha/dialog_preview/with_footer.html.erb +3 -3
  108. data/previews/primer/alpha/dialog_preview/with_form.html.erb +1 -1
  109. data/previews/primer/alpha/dialog_preview/with_text_input.html.erb +2 -2
  110. data/previews/primer/alpha/dialog_preview.rb +7 -2
  111. data/previews/primer/beta/auto_complete_item_preview.rb +1 -0
  112. data/previews/primer/beta/auto_complete_preview.rb +36 -23
  113. data/static/arguments.json +3085 -1405
  114. data/static/audited_at.json +2 -0
  115. data/static/classes.json +576 -311
  116. data/static/constants.json +53 -2
  117. data/static/info_arch.json +8888 -0
  118. data/static/previews.json +226 -101
  119. data/static/statuses.json +2 -0
  120. metadata +28 -6
@@ -9,8 +9,6 @@
9
9
  ".Button:disabled",
10
10
  ".Button[aria-disabled=true]",
11
11
  ".Button-withTooltip",
12
- "a.Button",
13
- "summary.Button",
14
12
  "a.Button:hover",
15
13
  "summary.Button:hover",
16
14
  ".Button-content",
@@ -67,27 +65,5 @@
67
65
  ".Button--iconOnly",
68
66
  ".Button--iconOnly.Button--small",
69
67
  ".Button--iconOnly.Button--large"
70
- ],
71
- "classes": [
72
- "Button",
73
- "Button-withTooltip",
74
- "Button-content",
75
- "Button-content--alignStart",
76
- "Button-visual",
77
- "Counter",
78
- "Button-label",
79
- "Button-leadingVisual",
80
- "Button-trailingVisual",
81
- "Button-trailingAction",
82
- "Button--small",
83
- "Button--large",
84
- "Button--fullWidth",
85
- "Button--primary",
86
- "Button--secondary",
87
- "Button--invisible",
88
- "Button--invisible-noVisuals",
89
- "Button--link",
90
- "Button--danger",
91
- "Button--iconOnly"
92
68
  ]
93
69
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["button.pcss","<no source>","../../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"button.css","sourcesContent":["/* CSS for Button */\n\n/* temporary, pre primitives release */\n:root {\n --primer-duration-fast: 80ms;\n --primer-easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n font-size: var(--primer-text-body-size-medium, 14px);\n font-weight: var(--base-text-weight-medium, 500);\n cursor: pointer;\n user-select: none;\n background-color: transparent;\n border: var(--primer-borderWidth-thin, 1px) solid;\n border-color: transparent;\n border-radius: var(--primer-borderRadius-medium, 6px);\n color: var(--color-btn-text);\n transition: var(--primer-duration-fast) var(--primer-easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n text-align: center;\n height: var(--primer-control-medium-size, 32px);\n padding: 0 var(--primer-control-medium-paddingInline-normal, 12px);\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--primer-control-medium-gap, 8px);\n min-width: max-content;\n\n /* mobile friendly sizing */\n @media (pointer: coarse) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--primer-duration-fast);\n }\n\n &:active {\n transition: none;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n}\n\n.Button-withTooltip {\n position: relative;\n display: inline-block;\n}\n\na.Button,\nsummary.Button {\n display: inline-flex;\n\n &:hover {\n text-decoration: none;\n }\n}\n\n/* wrap grid content to allow trailingAction to lock-right */\n.Button-content {\n flex: 1 0 auto;\n display: grid;\n grid-template-areas: 'leadingVisual text trailingVisual';\n grid-template-columns: min-content minmax(0, auto) min-content;\n align-items: center;\n place-content: center;\n\n /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--primer-control-medium-gap, 8px);\n }\n}\n\n/* center child elements for fullWidth */\n.Button-content--alignStart {\n justify-content: start;\n}\n\n/* button child elements */\n\n/* align svg */\n.Button-visual {\n display: flex;\n pointer-events: none; /* allow click handler to work, avoiding visuals */\n\n & .Counter {\n color: inherit;\n background-color: var(--color-btn-counter-bg);\n }\n}\n\n.Button-label {\n grid-area: text;\n white-space: nowrap;\n line-height: var(--primer-text-body-lineHeight-medium, calc(20 / 14));\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4, 4px) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n font-size: var(--primer-text-body-size-small, 12px);\n height: var(--primer-control-small-size, 28px);\n padding: 0 var(--primer-control-small-paddingInline-condensed, 8px);\n gap: var(--primer-control-small-gap, 4px);\n\n & .Button-label {\n line-height: var(--primer-text-body-lineHeight-small, calc(20 / 12));\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-small-gap, 4px);\n }\n }\n}\n\n.Button--large {\n height: var(--primer-control-large-size, 40px);\n padding: 0 var(--primer-control-large-paddingInline-spacious, 16px);\n gap: var(--primer-control-large-gap, 8px);\n\n & .Button-label {\n line-height: var(--primer-text-body-lineHeight-large, calc(48 / 32));\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-large-gap, 8px);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--color-btn-primary-text);\n fill: var(--color-btn-primary-icon);\n background-color: var(--color-btn-primary-bg);\n border-color: var(--color-btn-primary-border);\n box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow);\n\n &:hover:not(:disabled) {\n background-color: var(--color-btn-primary-hover-bg);\n border-color: var(--color-btn-primary-hover-border);\n }\n\n /* fallback :focus state */\n &:focus {\n @mixin focusOutlineOnEmphasis;\n\n /* remove fallback :focus if :focus-visible is supported */\n &:not(:focus-visible) {\n outline: solid 1px transparent;\n box-shadow: none;\n }\n }\n\n /* default focus state */\n &:focus-visible {\n @mixin focusOutlineOnEmphasis;\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n background-color: var(--color-btn-primary-selected-bg);\n box-shadow: var(--color-btn-primary-selected-shadow);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-primary-disabled-text);\n background-color: var(--color-btn-primary-disabled-bg);\n border-color: var(--color-btn-primary-disabled-border);\n fill: var(--color-btn-primary-disabled-text);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--color-btn-text);\n fill: var(--color-fg-muted); /* help this */\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover:not(:disabled) {\n background-color: var(--color-btn-hover-bg);\n border-color: var(--color-btn-hover-border);\n }\n\n &:active:not(:disabled) {\n background-color: var(--color-btn-active-bg);\n border-color: var(--color-btn-active-border);\n }\n\n &[aria-pressed='true'] {\n background-color: var(--color-btn-selected-bg);\n box-shadow: var(--color-primer-shadow-inset);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n.Button--invisible {\n color: var(--color-btn-text);\n\n &:hover:not(:disabled) {\n background-color: var(--color-action-list-item-default-hover-bg);\n }\n\n &[aria-pressed='true'],\n &:active:not(:disabled) {\n background-color: var(--color-action-list-item-default-active-bg);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n\n /* if button has no visuals, use link blue for text */\n &.Button--invisible-noVisuals .Button-label {\n color: var(--color-accent-fg);\n }\n\n & .Button-visual {\n color: var(--color-fg-muted);\n }\n}\n\n.Button--link {\n color: var(--color-accent-fg);\n fill: var(--color-accent-fg);\n display: inline-block;\n font-size: inherit;\n border: none;\n height: unset;\n padding: 0;\n\n &:hover:not(:disabled) {\n text-decoration: underline;\n }\n\n &:focus-visible, &:focus {\n outline-offset: 2px;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: transparent;\n border-color: transparent;\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--color-btn-danger-text);\n fill: var(--color-btn-danger-icon);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover:not(:disabled) {\n color: var(--color-btn-danger-hover-text);\n fill: var(--color-btn-danger-hover-text);\n background-color: var(--color-btn-danger-hover-bg);\n border-color: var(--color-btn-danger-hover-border);\n box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow);\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n color: var(--color-btn-danger-selected-text);\n fill: var(--color-btn-danger-selected-text);\n background-color: var(--color-btn-danger-selected-bg);\n border-color: var(--color-btn-danger-selected-border);\n box-shadow: var(--color-btn-danger-selected-shadow);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-danger-disabled-text);\n fill: var(--color-btn-danger-disabled-text);\n background-color: var(--color-btn-danger-disabled-bg);\n border-color: var(--color-btn-border);\n }\n}\n\n\n.Button--iconOnly {\n display: grid;\n place-content: center;\n padding: unset;\n width: var(--primer-control-medium-size, 32px);\n\n &.Button--small {\n width: var(--primer-control-small-size, 28px);\n }\n\n &.Button--large {\n width: var(--primer-control-large-size, 40px);\n }\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--color-accent-fg) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);\n}\n"]}
1
+ {"version":3,"sources":["button.pcss","<no source>","../../../../lib/postcss_mixins/focusOutlineOnEmphasis.pcss"],"names":[],"mappings":"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","file":"button.css","sourcesContent":["/* CSS for Button */\n\n/* temporary, pre primitives release */\n:root {\n --primer-duration-fast: 80ms;\n --primer-easing-easeInOut: cubic-bezier(0.65, 0, 0.35, 1);\n}\n\n/* base button */\n.Button {\n position: relative;\n font-size: var(--primer-text-body-size-medium, 14px);\n font-weight: var(--base-text-weight-medium, 500);\n cursor: pointer;\n user-select: none;\n background-color: transparent;\n border: var(--primer-borderWidth-thin, 1px) solid;\n border-color: transparent;\n border-radius: var(--primer-borderRadius-medium, 6px);\n color: var(--color-btn-text);\n transition: var(--primer-duration-fast) var(--primer-easing-easeInOut);\n transition-property: color, fill, background-color, border-color;\n text-align: center;\n height: var(--primer-control-medium-size, 32px);\n padding: 0 var(--primer-control-medium-paddingInline-normal, 12px);\n display: inline-flex;\n flex-direction: row;\n justify-content: space-between;\n align-items: center;\n gap: var(--base-size-4, 4px);\n min-width: max-content;\n\n /* mobile friendly sizing */\n @media (pointer: coarse) {\n &::before {\n @mixin minTouchTarget 48px, 48px;\n }\n }\n\n /* base states */\n\n &:hover {\n transition-duration: var(--primer-duration-fast);\n }\n\n &:active {\n transition: none;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n cursor: not-allowed;\n box-shadow: none;\n }\n}\n\n.Button-withTooltip {\n position: relative;\n display: inline-block;\n}\n\na.Button,\nsummary.Button {\n &:hover {\n text-decoration: none;\n }\n}\n\n/* wrap grid content to allow trailingAction to lock-right */\n.Button-content {\n flex: 1 0 auto;\n display: grid;\n grid-template-areas: 'leadingVisual text trailingVisual';\n grid-template-columns: min-content minmax(0, auto) min-content;\n align-items: center;\n place-content: center;\n\n /* padding-bottom: 1px; optical alignment for firefox */\n\n & > :not(:last-child) {\n margin-right: var(--primer-control-medium-gap, 8px);\n }\n}\n\n/* center child elements for fullWidth */\n.Button-content--alignStart {\n justify-content: start;\n}\n\n/* button child elements */\n\n/* align svg */\n.Button-visual {\n display: flex;\n pointer-events: none; /* allow click handler to work, avoiding visuals */\n\n & .Counter {\n color: inherit;\n background-color: var(--color-btn-counter-bg);\n }\n}\n\n.Button-label {\n grid-area: text;\n white-space: nowrap;\n line-height: var(--primer-text-body-lineHeight-medium, calc(20 / 14));\n}\n\n.Button-leadingVisual {\n grid-area: leadingVisual;\n}\n\n.Button-trailingVisual {\n grid-area: trailingVisual;\n}\n\n.Button-trailingAction {\n margin-right: calc(var(--base-size-4, 4px) * -1);\n}\n\n/* sizes */\n\n.Button--small {\n font-size: var(--primer-text-body-size-small, 12px);\n height: var(--primer-control-small-size, 28px);\n padding: 0 var(--primer-control-small-paddingInline-condensed, 8px);\n gap: var(--primer-control-small-gap, 4px);\n\n & .Button-label {\n line-height: var(--primer-text-body-lineHeight-small, calc(20 / 12));\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-small-gap, 4px);\n }\n }\n}\n\n.Button--large {\n height: var(--primer-control-large-size, 40px);\n padding: 0 var(--primer-control-large-paddingInline-spacious, 16px);\n gap: var(--primer-control-large-gap, 8px);\n\n & .Button-label {\n line-height: var(--primer-text-body-lineHeight-large, calc(48 / 32));\n }\n\n & .Button-content {\n & > :not(:last-child) {\n margin-right: var(--primer-control-large-gap, 8px);\n }\n }\n}\n\n.Button--fullWidth {\n width: 100%;\n}\n\n/* variants */\n\n/* primary */\n.Button--primary {\n color: var(--color-btn-primary-text);\n fill: var(--color-btn-primary-icon);\n background-color: var(--color-btn-primary-bg);\n border-color: var(--color-btn-primary-border);\n box-shadow: var(--color-btn-primary-shadow), var(--color-btn-primary-inset-shadow);\n\n &:hover:not(:disabled) {\n background-color: var(--color-btn-primary-hover-bg);\n border-color: var(--color-btn-primary-hover-border);\n }\n\n /* fallback :focus state */\n &:focus {\n @mixin focusOutlineOnEmphasis;\n\n /* remove fallback :focus if :focus-visible is supported */\n &:not(:focus-visible) {\n outline: solid 1px transparent;\n box-shadow: none;\n }\n }\n\n /* default focus state */\n &:focus-visible {\n @mixin focusOutlineOnEmphasis;\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n background-color: var(--color-btn-primary-selected-bg);\n box-shadow: var(--color-btn-primary-selected-shadow);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-primary-disabled-text);\n background-color: var(--color-btn-primary-disabled-bg);\n border-color: var(--color-btn-primary-disabled-border);\n fill: var(--color-btn-primary-disabled-text);\n }\n}\n\n/* default (secondary) */\n.Button--secondary {\n color: var(--color-btn-text);\n fill: var(--color-fg-muted); /* help this */\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover:not(:disabled) {\n background-color: var(--color-btn-hover-bg);\n border-color: var(--color-btn-hover-border);\n }\n\n &:active:not(:disabled) {\n background-color: var(--color-btn-active-bg);\n border-color: var(--color-btn-active-border);\n }\n\n &[aria-pressed='true'] {\n background-color: var(--color-btn-selected-bg);\n box-shadow: var(--color-primer-shadow-inset);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n.Button--invisible {\n color: var(--color-btn-text);\n\n &:hover:not(:disabled) {\n background-color: var(--color-action-list-item-default-hover-bg);\n }\n\n &[aria-pressed='true'],\n &:active:not(:disabled) {\n background-color: var(--color-action-list-item-default-active-bg);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n fill: var(--color-primer-fg-disabled);\n }\n\n /* if button has no visuals, use link blue for text */\n &.Button--invisible-noVisuals .Button-label {\n color: var(--color-accent-fg);\n }\n\n & .Button-visual {\n color: var(--color-fg-muted);\n }\n}\n\n.Button--link {\n color: var(--color-accent-fg);\n fill: var(--color-accent-fg);\n display: inline-block;\n font-size: inherit;\n border: none;\n height: unset;\n padding: 0;\n\n &:hover:not(:disabled) {\n text-decoration: underline;\n }\n\n &:focus-visible,\n &:focus {\n outline-offset: 2px;\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-primer-fg-disabled);\n background-color: transparent;\n border-color: transparent;\n fill: var(--color-primer-fg-disabled);\n }\n}\n\n/* danger */\n.Button--danger {\n color: var(--color-btn-danger-text);\n fill: var(--color-btn-danger-icon);\n background-color: var(--color-btn-bg);\n border-color: var(--color-btn-border);\n box-shadow: var(--color-btn-shadow), var(--color-btn-inset-shadow);\n\n &:hover:not(:disabled) {\n color: var(--color-btn-danger-hover-text);\n fill: var(--color-btn-danger-hover-text);\n background-color: var(--color-btn-danger-hover-bg);\n border-color: var(--color-btn-danger-hover-border);\n box-shadow: var(--color-btn-danger-hover-shadow), var(--color-btn-danger-hover-inset-shadow);\n }\n\n &:active:not(:disabled),\n &[aria-pressed='true'] {\n color: var(--color-btn-danger-selected-text);\n fill: var(--color-btn-danger-selected-text);\n background-color: var(--color-btn-danger-selected-bg);\n border-color: var(--color-btn-danger-selected-border);\n box-shadow: var(--color-btn-danger-selected-shadow);\n }\n\n &:disabled,\n &[aria-disabled='true'] {\n color: var(--color-btn-danger-disabled-text);\n fill: var(--color-btn-danger-disabled-text);\n background-color: var(--color-btn-danger-disabled-bg);\n border-color: var(--color-btn-border);\n }\n}\n\n.Button--iconOnly {\n display: inline-grid;\n place-content: center;\n padding: unset;\n width: var(--primer-control-medium-size, 32px);\n\n &.Button--small {\n width: var(--primer-control-small-size, 28px);\n }\n\n &.Button--large {\n width: var(--primer-control-large-size, 40px);\n }\n}\n",null,"/* outline with fg box-shadow for buttons */\n@define-mixin focusOutlineOnEmphasis $outlineOffset: -2px, $outlineColor: var(--color-accent-fg) {\n outline: 2px solid $outlineColor;\n outline-offset: $outlineOffset;\n box-shadow: inset 0 0 0 3px var(--color-fg-on-emphasis);\n}\n"]}
@@ -23,11 +23,11 @@
23
23
  text-align: center;
24
24
  height: var(--primer-control-medium-size, 32px);
25
25
  padding: 0 var(--primer-control-medium-paddingInline-normal, 12px);
26
- display: flex;
26
+ display: inline-flex;
27
27
  flex-direction: row;
28
28
  justify-content: space-between;
29
29
  align-items: center;
30
- gap: var(--primer-control-medium-gap, 8px);
30
+ gap: var(--base-size-4, 4px);
31
31
  min-width: max-content;
32
32
 
33
33
  /* mobile friendly sizing */
@@ -61,8 +61,6 @@
61
61
 
62
62
  a.Button,
63
63
  summary.Button {
64
- display: inline-flex;
65
-
66
64
  &:hover {
67
65
  text-decoration: none;
68
66
  }
@@ -280,7 +278,8 @@ summary.Button {
280
278
  text-decoration: underline;
281
279
  }
282
280
 
283
- &:focus-visible, &:focus {
281
+ &:focus-visible,
282
+ &:focus {
284
283
  outline-offset: 2px;
285
284
  }
286
285
 
@@ -327,9 +326,8 @@ summary.Button {
327
326
  }
328
327
  }
329
328
 
330
-
331
329
  .Button--iconOnly {
332
- display: grid;
330
+ display: inline-grid;
333
331
  place-content: center;
334
332
  padding: unset;
335
333
  width: var(--primer-control-medium-size, 32px);
@@ -6,11 +6,5 @@
6
6
  ".Counter .octicon",
7
7
  ".Counter--primary",
8
8
  ".Counter--secondary"
9
- ],
10
- "classes": [
11
- "Counter",
12
- "octicon",
13
- "Counter--primary",
14
- "Counter--secondary"
15
9
  ]
16
10
  }
@@ -23,20 +23,5 @@
23
23
  ".flash-banner",
24
24
  ".flash-full",
25
25
  ".warning"
26
- ],
27
- "classes": [
28
- "flash",
29
- "octicon",
30
- "flash-messages",
31
- "flash-close",
32
- "flash-action",
33
- "btn",
34
- "btn-primary",
35
- "flash-warn",
36
- "flash-error",
37
- "flash-success",
38
- "flash-full",
39
- "flash-banner",
40
- "warning"
41
26
  ]
42
27
  }
@@ -21,25 +21,5 @@
21
21
  ".Label--closed",
22
22
  ".Label--done",
23
23
  ".Label--sponsors"
24
- ],
25
- "classes": [
26
- "labels",
27
- "Label",
28
- "label",
29
- "Label--large",
30
- "Label--inline",
31
- "Label--primary",
32
- "Label--secondary",
33
- "Label--accent",
34
- "Label--info",
35
- "Label--success",
36
- "Label--attention",
37
- "Label--warning",
38
- "Label--severe",
39
- "Label--danger",
40
- "Label--open",
41
- "Label--closed",
42
- "Label--done",
43
- "Label--sponsors"
44
24
  ]
45
25
  }
@@ -15,13 +15,5 @@
15
15
  ".Link--muted:hover [class*=color-fg]",
16
16
  ".Link--primary:hover [class*=color-fg]",
17
17
  ".Link--secondary:hover [class*=color-fg]"
18
- ],
19
- "classes": [
20
- "Link",
21
- "Link--primary",
22
- "Link--secondary",
23
- "Link--muted",
24
- "Link--onHover",
25
- "color-fg"
26
18
  ]
27
19
  }
@@ -35,23 +35,5 @@
35
35
  ".Popover-message--right:before",
36
36
  ".Popover-message--large",
37
37
  ".Popover-message>.btn-octicon"
38
- ],
39
- "classes": [
40
- "Popover",
41
- "Popover-message",
42
- "Popover-message--no-caret",
43
- "Popover-message--bottom-left",
44
- "Popover-message--bottom-right",
45
- "Popover-message--bottom",
46
- "Popover-message--top-right",
47
- "Popover-message--top-left",
48
- "Popover-message--left-bottom",
49
- "Popover-message--left-top",
50
- "Popover-message--left",
51
- "Popover-message--right-bottom",
52
- "Popover-message--right-top",
53
- "Popover-message--right",
54
- "Popover-message--large",
55
- "btn-octicon"
56
38
  ]
57
39
  }
@@ -6,11 +6,5 @@
6
6
  ".Progress--small",
7
7
  ".Progress-item",
8
8
  ".Progress-item+.Progress-item"
9
- ],
10
- "classes": [
11
- "Progress",
12
- "Progress--large",
13
- "Progress--small",
14
- "Progress-item"
15
9
  ]
16
10
  }
@@ -9,15 +9,5 @@
9
9
  ".State--closed",
10
10
  ".State--small",
11
11
  ".State--small .octicon"
12
- ],
13
- "classes": [
14
- "State",
15
- "state",
16
- "State--draft",
17
- "State--open",
18
- "State--merged",
19
- "State--closed",
20
- "State--small",
21
- "octicon"
22
12
  ]
23
13
  }
@@ -8,13 +8,5 @@
8
8
  ".Subhead-description",
9
9
  ".Subhead-actions",
10
10
  ".Subhead-actions+.Subhead-description"
11
- ],
12
- "classes": [
13
- "Subhead",
14
- "Subhead--spacious",
15
- "Subhead-heading",
16
- "Subhead-heading--danger",
17
- "Subhead-description",
18
- "Subhead-actions"
19
11
  ]
20
12
  }
@@ -12,14 +12,5 @@
12
12
  ".TimelineItem--condensed",
13
13
  ".TimelineItem--condensed:last-child",
14
14
  ".TimelineItem--condensed .TimelineItem-badge"
15
- ],
16
- "classes": [
17
- "TimelineItem",
18
- "TimelineItem-badge",
19
- "TimelineItem-badge--success",
20
- "TimelineItem-body",
21
- "TimelineItem-avatar",
22
- "TimelineItem-break",
23
- "TimelineItem--condensed"
24
15
  ]
25
16
  }
@@ -8,11 +8,5 @@
8
8
  ".Truncate>.Truncate-text.Truncate-text--expandable:active",
9
9
  ".Truncate>.Truncate-text.Truncate-text--expandable:focus",
10
10
  ".Truncate>.Truncate-text.Truncate-text--expandable:hover"
11
- ],
12
- "classes": [
13
- "Truncate",
14
- "Truncate-text",
15
- "Truncate-text--primary",
16
- "Truncate-text--expandable"
17
11
  ]
18
12
  }
@@ -0,0 +1,19 @@
1
+ import '@oddbird/popover-polyfill';
2
+ export default class FocusGroupElement extends HTMLElement {
3
+ #private;
4
+ get nowrap(): boolean;
5
+ set nowrap(value: boolean);
6
+ get direction(): 'horizontal' | 'vertical' | 'both';
7
+ set direction(value: 'horizontal' | 'vertical' | 'both');
8
+ get retain(): boolean;
9
+ set retain(value: boolean);
10
+ get mnemonics(): boolean;
11
+ connectedCallback(): void;
12
+ disconnectedCallback(): void;
13
+ handleEvent(event: Event): void;
14
+ }
15
+ declare global {
16
+ interface Window {
17
+ FocusGroupElement: typeof FocusGroupElement;
18
+ }
19
+ }
@@ -0,0 +1,144 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ 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");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _FocusGroupElement_instances, _FocusGroupElement_abortController, _FocusGroupElement_items_get;
13
+ import '@oddbird/popover-polyfill';
14
+ const menuItemSelector = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]';
15
+ const popoverSelector = (() => {
16
+ try {
17
+ document.querySelector(':open');
18
+ return ':open';
19
+ }
20
+ catch (_a) {
21
+ return '.\\:open';
22
+ }
23
+ })();
24
+ const getMnemonicFor = (item) => { var _a; return (_a = item.textContent) === null || _a === void 0 ? void 0 : _a.trim()[0].toLowerCase(); };
25
+ const printable = /^\S$/;
26
+ export default class FocusGroupElement extends HTMLElement {
27
+ constructor() {
28
+ super(...arguments);
29
+ _FocusGroupElement_instances.add(this);
30
+ _FocusGroupElement_abortController.set(this, null);
31
+ }
32
+ get nowrap() {
33
+ return this.hasAttribute('nowrap');
34
+ }
35
+ set nowrap(value) {
36
+ this.toggleAttribute('nowrap', value);
37
+ }
38
+ get direction() {
39
+ if (this.getAttribute('direction') === 'horizontal')
40
+ return 'horizontal';
41
+ return 'vertical';
42
+ }
43
+ set direction(value) {
44
+ this.setAttribute('direction', `${value}`);
45
+ }
46
+ get retain() {
47
+ return this.hasAttribute('retain');
48
+ }
49
+ set retain(value) {
50
+ this.toggleAttribute('retain', value);
51
+ }
52
+ get mnemonics() {
53
+ return this.hasAttribute('mnemonics');
54
+ }
55
+ connectedCallback() {
56
+ __classPrivateFieldSet(this, _FocusGroupElement_abortController, new AbortController(), "f");
57
+ const { signal } = __classPrivateFieldGet(this, _FocusGroupElement_abortController, "f");
58
+ this.addEventListener('keydown', this, { signal });
59
+ this.addEventListener('click', this, { signal });
60
+ this.addEventListener('mouseover', this, { signal });
61
+ this.addEventListener('focusin', this, { signal });
62
+ }
63
+ disconnectedCallback() {
64
+ var _a;
65
+ (_a = __classPrivateFieldGet(this, _FocusGroupElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
66
+ }
67
+ handleEvent(event) {
68
+ const { direction, nowrap } = this;
69
+ if (event.type === 'focusin') {
70
+ if (this.retain && event.target instanceof Element && event.target.matches(menuItemSelector)) {
71
+ for (const item of __classPrivateFieldGet(this, _FocusGroupElement_instances, "a", _FocusGroupElement_items_get)) {
72
+ item.setAttribute('tabindex', item === event.target ? '0' : '-1');
73
+ }
74
+ }
75
+ }
76
+ else if (event instanceof KeyboardEvent) {
77
+ const items = Array.from(__classPrivateFieldGet(this, _FocusGroupElement_instances, "a", _FocusGroupElement_items_get));
78
+ let index = items.indexOf(event.target);
79
+ const key = event.key;
80
+ if (key === 'Up' || key === 'ArrowUp') {
81
+ if (direction === 'vertical' || direction === 'both') {
82
+ index -= index < 0 ? 0 : 1;
83
+ }
84
+ }
85
+ else if (key === 'Down' || key === 'ArrowDown') {
86
+ if (direction === 'vertical' || direction === 'both') {
87
+ index += 1;
88
+ }
89
+ }
90
+ else if (event.key === 'Left' || event.key === 'ArrowLeft') {
91
+ if (direction === 'horizontal' || direction === 'both') {
92
+ index -= 1;
93
+ }
94
+ }
95
+ else if (event.key === 'Right' || event.key === 'ArrowRight') {
96
+ if (direction === 'horizontal' || direction === 'both') {
97
+ index += 1;
98
+ }
99
+ }
100
+ else if (event.key === 'Home' || event.key === 'PageUp') {
101
+ index = 0;
102
+ }
103
+ else if (event.key === 'End' || event.key === 'PageDown') {
104
+ index = items.length - 1;
105
+ }
106
+ else if (this.mnemonics && printable.test(key)) {
107
+ const mnemonic = key.toLowerCase();
108
+ const offset = index > 0 && getMnemonicFor(event.target) === mnemonic ? index : 0;
109
+ index = items.findIndex((item, i) => i > offset && getMnemonicFor(item) === mnemonic);
110
+ if (index < 0 && !nowrap) {
111
+ index = items.findIndex(item => getMnemonicFor(item) === mnemonic);
112
+ }
113
+ }
114
+ else {
115
+ return;
116
+ }
117
+ if (nowrap && index < 0)
118
+ index = 0;
119
+ if (!nowrap && index >= items.length)
120
+ index = 0;
121
+ const focusEl = items.at(Math.min(index, items.length - 1));
122
+ {
123
+ let el = focusEl;
124
+ do {
125
+ el = el.closest(`[popover]:not(${popoverSelector})`);
126
+ if ((el === null || el === void 0 ? void 0 : el.popover) === 'auto') {
127
+ el.showPopover();
128
+ }
129
+ else {
130
+ el = (el === null || el === void 0 ? void 0 : el.parentElement) || null;
131
+ }
132
+ } while (el);
133
+ }
134
+ focusEl === null || focusEl === void 0 ? void 0 : focusEl.focus();
135
+ }
136
+ }
137
+ }
138
+ _FocusGroupElement_abortController = new WeakMap(), _FocusGroupElement_instances = new WeakSet(), _FocusGroupElement_items_get = function _FocusGroupElement_items_get() {
139
+ return this.querySelectorAll(menuItemSelector);
140
+ };
141
+ if (!customElements.get('focus-group')) {
142
+ window.FocusGroupElement = FocusGroupElement;
143
+ customElements.define('focus-group', FocusGroupElement);
144
+ }
@@ -0,0 +1,137 @@
1
+ import '@oddbird/popover-polyfill'
2
+
3
+ const menuItemSelector = '[role="menuitem"],[role="menuitemcheckbox"],[role="menuitemradio"]'
4
+
5
+ const popoverSelector = (() => {
6
+ try {
7
+ document.querySelector(':open')
8
+ return ':open'
9
+ } catch {
10
+ return '.\\:open'
11
+ }
12
+ })()
13
+
14
+ const getMnemonicFor = (item: Element) => item.textContent?.trim()[0].toLowerCase()
15
+
16
+ const printable = /^\S$/
17
+
18
+ export default class FocusGroupElement extends HTMLElement {
19
+ get nowrap(): boolean {
20
+ return this.hasAttribute('nowrap')
21
+ }
22
+
23
+ set nowrap(value: boolean) {
24
+ this.toggleAttribute('nowrap', value)
25
+ }
26
+
27
+ get direction(): 'horizontal' | 'vertical' | 'both' {
28
+ if (this.getAttribute('direction') === 'horizontal') return 'horizontal'
29
+ return 'vertical'
30
+ }
31
+
32
+ set direction(value: 'horizontal' | 'vertical' | 'both') {
33
+ this.setAttribute('direction', `${value}`)
34
+ }
35
+
36
+ get retain() {
37
+ return this.hasAttribute('retain')
38
+ }
39
+
40
+ set retain(value: boolean) {
41
+ this.toggleAttribute('retain', value)
42
+ }
43
+
44
+ get mnemonics() {
45
+ return this.hasAttribute('mnemonics')
46
+ }
47
+
48
+ #abortController: AbortController | null = null
49
+ connectedCallback() {
50
+ this.#abortController = new AbortController()
51
+ const {signal} = this.#abortController
52
+
53
+ this.addEventListener('keydown', this, {signal})
54
+ this.addEventListener('click', this, {signal})
55
+ this.addEventListener('mouseover', this, {signal})
56
+ this.addEventListener('focusin', this, {signal})
57
+ }
58
+
59
+ disconnectedCallback() {
60
+ this.#abortController?.abort()
61
+ }
62
+
63
+ get #items() {
64
+ return this.querySelectorAll(menuItemSelector)
65
+ }
66
+
67
+ handleEvent(event: Event) {
68
+ const {direction, nowrap} = this
69
+ if (event.type === 'focusin') {
70
+ if (this.retain && event.target instanceof Element && event.target.matches(menuItemSelector)) {
71
+ for (const item of this.#items) {
72
+ item.setAttribute('tabindex', item === event.target ? '0' : '-1')
73
+ }
74
+ }
75
+ } else if (event instanceof KeyboardEvent) {
76
+ const items = Array.from(this.#items)
77
+ let index = items.indexOf(event.target as Element)
78
+ const key = event.key
79
+ if (key === 'Up' || key === 'ArrowUp') {
80
+ if (direction === 'vertical' || direction === 'both') {
81
+ index -= index < 0 ? 0 : 1
82
+ }
83
+ } else if (key === 'Down' || key === 'ArrowDown') {
84
+ if (direction === 'vertical' || direction === 'both') {
85
+ index += 1
86
+ }
87
+ } else if (event.key === 'Left' || event.key === 'ArrowLeft') {
88
+ if (direction === 'horizontal' || direction === 'both') {
89
+ index -= 1
90
+ }
91
+ } else if (event.key === 'Right' || event.key === 'ArrowRight') {
92
+ if (direction === 'horizontal' || direction === 'both') {
93
+ index += 1
94
+ }
95
+ } else if (event.key === 'Home' || event.key === 'PageUp') {
96
+ index = 0
97
+ } else if (event.key === 'End' || event.key === 'PageDown') {
98
+ index = items.length - 1
99
+ } else if (this.mnemonics && printable.test(key)) {
100
+ const mnemonic = key.toLowerCase()
101
+ const offset = index > 0 && getMnemonicFor(event.target as Element) === mnemonic ? index : 0
102
+ index = items.findIndex((item, i) => i > offset && getMnemonicFor(item) === mnemonic)
103
+ if (index < 0 && !nowrap) {
104
+ index = items.findIndex(item => getMnemonicFor(item) === mnemonic)
105
+ }
106
+ } else {
107
+ return
108
+ }
109
+ if (nowrap && index < 0) index = 0
110
+ if (!nowrap && index >= items.length) index = 0
111
+ const focusEl = items.at(Math.min(index, items.length - 1)) as HTMLElement
112
+ {
113
+ let el: HTMLElement | null = focusEl
114
+ do {
115
+ el = el.closest(`[popover]:not(${popoverSelector})`)
116
+ if (el?.popover === 'auto') {
117
+ el.showPopover()
118
+ } else {
119
+ el = el?.parentElement || null
120
+ }
121
+ } while (el)
122
+ }
123
+ focusEl?.focus()
124
+ }
125
+ }
126
+ }
127
+
128
+ if (!customElements.get('focus-group')) {
129
+ window.FocusGroupElement = FocusGroupElement
130
+ customElements.define('focus-group', FocusGroupElement)
131
+ }
132
+
133
+ declare global {
134
+ interface Window {
135
+ FocusGroupElement: typeof FocusGroupElement
136
+ }
137
+ }
@@ -33,7 +33,7 @@ module Primer
33
33
  # @example In a BorderBox
34
34
  #
35
35
  # <%= render(Primer::Beta::BorderBox.new) do |component| %>
36
- # <% component.body do %>
36
+ # <% component.with_body do %>
37
37
  # <%= render(Primer::Beta::Text.new(pr: 2)) { "Body" } %>
38
38
  # <%= render(Primer::IconButton.new(icon: :pencil, box: true, "aria-label": "Edit")) %>
39
39
  # <% end %>
@@ -1,6 +1,7 @@
1
1
  import '@oddbird/popover-polyfill';
2
2
  import './alpha/dropdown';
3
3
  import './anchored_position';
4
+ import './focus_group';
4
5
  import './alpha/image_crop';
5
6
  import './alpha/modal_dialog';
6
7
  import './alpha/nav_list';
@@ -15,3 +16,4 @@ import './alpha/tab_container';
15
16
  import '../../../lib/primer/forms/primer_multi_input';
16
17
  import '../../../lib/primer/forms/primer_text_field';
17
18
  import '../../../lib/primer/forms/toggle_switch_input';
19
+ import './alpha/action_menu/action_menu_element';
@@ -1,6 +1,7 @@
1
1
  import '@oddbird/popover-polyfill';
2
2
  import './alpha/dropdown';
3
3
  import './anchored_position';
4
+ import './focus_group';
4
5
  import './alpha/image_crop';
5
6
  import './alpha/modal_dialog';
6
7
  import './alpha/nav_list';
@@ -15,3 +16,4 @@ import './alpha/tab_container';
15
16
  import '../../../lib/primer/forms/primer_multi_input';
16
17
  import '../../../lib/primer/forms/primer_text_field';
17
18
  import '../../../lib/primer/forms/toggle_switch_input';
19
+ import './alpha/action_menu/action_menu_element';
@@ -1,6 +1,7 @@
1
1
  import '@oddbird/popover-polyfill'
2
2
  import './alpha/dropdown'
3
3
  import './anchored_position'
4
+ import './focus_group'
4
5
  import './alpha/image_crop'
5
6
  import './alpha/modal_dialog'
6
7
  import './alpha/nav_list'
@@ -15,3 +16,4 @@ import './alpha/tab_container'
15
16
  import '../../../lib/primer/forms/primer_multi_input'
16
17
  import '../../../lib/primer/forms/primer_text_field'
17
18
  import '../../../lib/primer/forms/toggle_switch_input'
19
+ import './alpha/action_menu/action_menu_element'