diff --git a/.changeset/sweet-icons-stare.md b/.changeset/sweet-icons-stare.md new file mode 100644 index 00000000000..246b7dfab7d --- /dev/null +++ b/.changeset/sweet-icons-stare.md @@ -0,0 +1,5 @@ +--- +"@primer/react": patch +--- + +ActionBar: The overflow menu was earlier bootlegged with heavily customised ActionList. This is being replaced with ActionMenu which is cleaner and more robust. diff --git a/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx b/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx index 01a8dfc9e2c..350085304af 100644 --- a/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx +++ b/packages/react/src/drafts/ActionBar/ActionBar.stories.tsx @@ -1,7 +1,9 @@ import React from 'react' import type {Meta} from '@storybook/react' import ActionBar from '.' +import Text from '../../Text' import { + PencilIcon, BoldIcon, CodeIcon, ItalicIcon, @@ -14,12 +16,14 @@ import { ListOrderedIcon, TasklistIcon, ReplyIcon, + ThreeBarsIcon, } from '@primer/octicons-react' import {MarkdownInput} from '../MarkdownEditor/_MarkdownInput' import {ViewSwitch} from '../MarkdownEditor/_ViewSwitch' import type {MarkdownViewMode} from '../MarkdownEditor/_ViewSwitch' -import {Box, Dialog, Button} from '../..' +import {Box, Dialog, Button, Avatar, ActionMenu, IconButton, ActionList} from '../..' import {Divider} from '../../deprecated/ActionList/Divider' +import mockData from '../SelectPanel2/mock-story-data' export default { title: 'Drafts/Components/ActionBar', @@ -169,3 +173,147 @@ export const ActionBarWithMenuTrigger = () => { ) } + +export const ActionbarToggle = () => { + const descriptionStyles = { + borderWidth: 1, + borderStyle: 'solid', + borderColor: 'border.default', + p: 3, + } + const topSectionStyles = { + bg: 'canvas.subtle', + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + borderBottomWidth: 1, + borderStyle: 'solid', + borderColor: 'border.default', + p: 3, + } + const bottomSectionStyles = { + p: 3, + } + const loginName = mockData.collaborators[1].login + const [showEditView, setEditView] = React.useState(false) + const [description /*, setDescription*/] = React.useState('') + const anchorRef = React.useRef(null) + return ( + + + + + + {loginName} + + opened this issue 2 hours ago + + + + + + + + + + + + + Copy Link + + + + + + Quote reply + + + setEditView(true)}> + + + + Edit + + + + + + + + {showEditView ? ( + + + + + + + + ) : ( + {description ? description : 'No description Provided'} + )} + + + ) +} + +export const MultipleActionBars = () => { + const [showFirstCommentBox, setShowFirstCommentBox] = React.useState(false) + const [showSecondCommentBox, setShowSecondCommentBox] = React.useState(false) + return ( + + + {showFirstCommentBox ? ( + + + + + + + + ) : ( + + )} + + + {showSecondCommentBox ? ( + + + + + + + + ) : ( + + )} + + + ) +} diff --git a/packages/react/src/drafts/ActionBar/ActionBar.tsx b/packages/react/src/drafts/ActionBar/ActionBar.tsx index 817aaa08420..d2ecea1b100 100644 --- a/packages/react/src/drafts/ActionBar/ActionBar.tsx +++ b/packages/react/src/drafts/ActionBar/ActionBar.tsx @@ -13,6 +13,7 @@ import {useOnOutsideClick} from '../../hooks/useOnOutsideClick' import type {IconButtonProps} from '../../Button' import {IconButton} from '../../Button' import Box from '../../Box' +import {ActionMenu} from '../..' type ChildSize = { text: string @@ -46,13 +47,7 @@ const NavigationList = styled.div` ${sx}; ` -const MORE_BTN_HEIGHT = 45 const GAP = 8 -const MoreMenuListItem = styled.li` - display: flex; - align-items: center; - height: ${MORE_BTN_HEIGHT}px; -` const listStyles = { display: 'flex', @@ -67,29 +62,15 @@ const listStyles = { position: 'relative', } -const menuStyles = { - position: 'absolute', - zIndex: 1, - top: '90%', - right: '0', - boxShadow: '0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24)', - borderRadius: '12px', - backgroundColor: 'canvas.overlay', - listStyle: 'none', - // Values are from ActionMenu - minWidth: '192px', - maxWidth: '640px', -} - const MORE_BTN_WIDTH = 86 -const getNavStyles = () => ({ +const navStyles = { display: 'flex', paddingX: 3, justifyContent: 'flex-end', align: 'row', alignItems: 'center', maxHeight: '32px', -}) +} const menuItemStyles = { textDecoration: 'none', @@ -192,7 +173,6 @@ export const ActionBar: React.FC> = prop const moreMenuRef = useRef(null) const moreMenuBtnRef = useRef(null) const containerRef = React.useRef(null) - const disclosureWidgetId = React.useId() const validChildren = getValidChildren(children) // Responsive props object manages which items are in the list and which items are in the menu. @@ -231,13 +211,6 @@ export const ActionBar: React.FC> = prop moreMenuBtnRef.current?.focus() }, []) - const onAnchorClick = useCallback((event: React.MouseEvent) => { - if (event.defaultPrevented || event.button !== 0) { - return - } - setIsWidgetOpen(isWidgetOpen => !isWidgetOpen) - }, []) - useOnEscapePress( (event: KeyboardEvent) => { if (isWidgetOpen) { @@ -253,61 +226,52 @@ export const ActionBar: React.FC> = prop return ( - + {listItems} {menuItems.length > 0 && ( - - - - {menuItems.map((menuItem, index) => { - if (menuItem.type === ActionList.Divider) { - return - } else { - const { - children: menuItemChildren, - //'aria-current': ariaCurrent, - onClick, - icon: Icon, - 'aria-label': ariaLabel, - } = menuItem.props - return ( - | React.KeyboardEvent, - ) => { - closeOverlay() - focusOnMoreMenuBtn() - typeof onClick === 'function' && onClick(event) - }} - > - {Icon ? ( - - - - ) : null} - {ariaLabel} - - ) - } - })} - - + + + + + + + {menuItems.map((menuItem, index) => { + if (menuItem.type === ActionList.Divider) { + return + } else { + const { + children: menuItemChildren, + //'aria-current': ariaCurrent, + onClick, + icon: Icon, + 'aria-label': ariaLabel, + } = menuItem.props + return ( + | React.KeyboardEvent, + ) => { + closeOverlay() + focusOnMoreMenuBtn() + typeof onClick === 'function' && onClick(event) + }} + > + {Icon ? ( + + + + ) : null} + {ariaLabel} + + ) + } + })} + + + )}