diff --git a/.changeset/rotten-horses-applaud.md b/.changeset/rotten-horses-applaud.md
new file mode 100644
index 00000000000..489b592235a
--- /dev/null
+++ b/.changeset/rotten-horses-applaud.md
@@ -0,0 +1,6 @@
+---
+"@primer/react": patch
+"docs": patch
+---
+
+ActionBar: Add new component for submenu
diff --git a/packages/react/src/drafts/ActionBar/ActionBar.docs.json b/packages/react/src/drafts/ActionBar/ActionBar.docs.json
index 0a18045f525..bd3542378da 100644
--- a/packages/react/src/drafts/ActionBar/ActionBar.docs.json
+++ b/packages/react/src/drafts/ActionBar/ActionBar.docs.json
@@ -54,6 +54,19 @@
{
"name": "ActionBar.Divider",
"props": []
+ },
+ {
+ "name": "ActionBar.SubMenu",
+ "description": "Component to be used when having a menu in the actionbar. This facilitates smooth transition to submenu during overflow cases",
+ "props": [
+ {
+ "name": "anchor",
+ "type": "React.ReactElement",
+ "required": true,
+ "description": "This is the anchor element to be used as menu trigger. Ideally ActionBar.IconButton"
+ },
+ {"name": "children", "type": "React.ReactElement", "required": true}
+ ]
}
]
}
diff --git a/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx b/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx
index 350085304af..f74b15a6daf 100644
--- a/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx
+++ b/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx
@@ -120,6 +120,13 @@ export const CommentBox = () => {
icon={ReplyIcon}
aria-label="Saved Replies"
>
+ }>
+
+ First Item
+ Second Item
+ Third Item
+
+
diff --git a/packages/react/src/drafts/ActionBar/ActionBar.tsx b/packages/react/src/drafts/ActionBar/ActionBar.tsx
index d2ecea1b100..8e51b163bb0 100644
--- a/packages/react/src/drafts/ActionBar/ActionBar.tsx
+++ b/packages/react/src/drafts/ActionBar/ActionBar.tsx
@@ -13,7 +13,8 @@ import {useOnOutsideClick} from '../../hooks/useOnOutsideClick'
import type {IconButtonProps} from '../../Button'
import {IconButton} from '../../Button'
import Box from '../../Box'
-import {ActionMenu} from '../..'
+import {ActionMenu} from '../../ActionMenu'
+import {Action} from 'history'
type ChildSize = {
text: string
@@ -43,6 +44,31 @@ export type ActionBarProps = {
export type ActionBarIconButtonProps = IconButtonProps
+export const ActionBarIconButton = forwardRef((props: ActionBarIconButtonProps, forwardedRef) => {
+ const backupRef = useRef(null)
+ const ref = (forwardedRef ?? backupRef) as RefObject
+ const {size, setChildrenWidth} = React.useContext(ActionBarContext)
+ useIsomorphicLayoutEffect(() => {
+ const text = props['aria-label'] ? props['aria-label'] : ''
+ const domRect = (ref as MutableRefObject).current.getBoundingClientRect()
+ setChildrenWidth({text, width: domRect.width})
+ }, [ref, setChildrenWidth])
+ return
+})
+
+export type ActionBarSubMenuProps = {anchor: React.ReactElement; children: React.ReactElement[] | React.ReactElement}
+
+export const ActionBarSubMenu = (props: ActionBarSubMenuProps) => {
+ const {anchor, children} = props
+
+ return (
+
+ {anchor}
+ {children}
+
+ )
+}
+
const NavigationList = styled.div`
${sx};
`
@@ -239,6 +265,24 @@ export const ActionBar: React.FC> = prop
{menuItems.map((menuItem, index) => {
if (menuItem.type === ActionList.Divider) {
return
+ } else if (menuItem.type === ActionBarSubMenu) {
+ const {children: menuItemChildren, anchor} = menuItem.props
+ const {icon: Icon, 'aria-label': ariaLabel} = anchor.props
+ return (
+
+
+
+ {Icon ? (
+
+
+
+ ) : null}
+ {ariaLabel}
+
+
+ {menuItemChildren}
+
+ )
} else {
const {
children: menuItemChildren,
@@ -279,18 +323,6 @@ export const ActionBar: React.FC> = prop
)
}
-export const ActionBarIconButton = forwardRef((props: ActionBarIconButtonProps, forwardedRef) => {
- const backupRef = useRef(null)
- const ref = (forwardedRef ?? backupRef) as RefObject
- const {size, setChildrenWidth} = React.useContext(ActionBarContext)
- useIsomorphicLayoutEffect(() => {
- const text = props['aria-label'] ? props['aria-label'] : ''
- const domRect = (ref as MutableRefObject).current.getBoundingClientRect()
- setChildrenWidth({text, width: domRect.width})
- }, [ref, setChildrenWidth])
- return
-})
-
const sizeToHeight = {
small: '24px',
medium: '28px',
diff --git a/packages/react/src/drafts/ActionBar/index.ts b/packages/react/src/drafts/ActionBar/index.ts
index ae3069a0ae3..d01713da516 100644
--- a/packages/react/src/drafts/ActionBar/index.ts
+++ b/packages/react/src/drafts/ActionBar/index.ts
@@ -1,8 +1,9 @@
-import {ActionBar as Bar, ActionBarIconButton, VerticalDivider} from './ActionBar'
+import {ActionBar as Bar, ActionBarIconButton, ActionBarSubMenu, VerticalDivider} from './ActionBar'
export type {ActionBarProps} from './ActionBar'
const ActionBar = Object.assign(Bar, {
IconButton: ActionBarIconButton,
+ SubMenu: ActionBarSubMenu,
Divider: VerticalDivider,
})