diff --git a/code/ui/components/src/tabs/tabs.tsx b/code/ui/components/src/tabs/tabs.tsx index a9218b82e9b4..683e8456478f 100644 --- a/code/ui/components/src/tabs/tabs.tsx +++ b/code/ui/components/src/tabs/tabs.tsx @@ -51,10 +51,23 @@ const WrapperChildren = styled.div<{ backgroundColor: string }>(({ theme, backgr export const TabBar = styled.div({ overflow: 'hidden', + + '&:first-of-type': { + marginLeft: -3, + }, + whiteSpace: 'nowrap', flexGrow: 1, }); +const TabBarSide = styled(Side)({ + flexGrow: 1, + flexShrink: 1, + maxWidth: '100%', +}); + +TabBar.displayName = 'TabBar'; + export interface ContentProps { absolute?: boolean; bordered?: boolean; @@ -147,31 +160,33 @@ export const Tabs: FC = memo( return list.length ? ( - - {visibleList.map(({ title, id, active, color }) => { - return ( - { - tabRefs.current.set(id, ref); - }} - className={`tabbutton ${active ? 'tabbutton-active' : ''}`} - type="button" - key={id} - active={active} - textColor={color} - onClick={(e: MouseEvent) => { - e.preventDefault(); - actions.onSelect(id); - }} - role="tab" - > - {title} - - ); - })} - - + + + {visibleList.map(({ title, id, active, color }) => { + return ( + { + tabRefs.current.set(id, ref); + }} + className={`tabbutton ${active ? 'tabbutton-active' : ''}`} + type="button" + key={id} + active={active} + textColor={color} + onClick={(e: MouseEvent) => { + e.preventDefault(); + actions.onSelect(id); + }} + role="tab" + > + {title} + + ); + })} + + + {tools ? {tools} : null} diff --git a/code/ui/manager/src/components/hooks/useMedia.tsx b/code/ui/manager/src/components/hooks/useMedia.tsx new file mode 100644 index 000000000000..240629e79cfe --- /dev/null +++ b/code/ui/manager/src/components/hooks/useMedia.tsx @@ -0,0 +1,19 @@ +import { useState, useEffect } from 'react'; + +const useMediaQuery = (query: string) => { + const [matches, setMatches] = useState(false); + + useEffect(() => { + const media = window.matchMedia(query); + if (media.matches !== matches) { + setMatches(media.matches); + } + const listener = () => setMatches(media.matches); + window.addEventListener('resize', listener); + return () => window.removeEventListener('resize', listener); + }, [matches, query]); + + return matches; +}; + +export default useMediaQuery; diff --git a/code/ui/manager/src/components/panel/panel.tsx b/code/ui/manager/src/components/panel/panel.tsx index 020ad08c4761..6519ee9d9219 100644 --- a/code/ui/manager/src/components/panel/panel.tsx +++ b/code/ui/manager/src/components/panel/panel.tsx @@ -1,16 +1,9 @@ import type { ReactElement } from 'react'; import React, { Component, Fragment } from 'react'; -import { styled } from '@storybook/theming'; import { Tabs, Icons, IconButton } from '@storybook/components'; import type { State } from '@storybook/manager-api'; import { shortcutToHumanString } from '@storybook/manager-api'; - -const DesktopOnlyIconButton = styled(IconButton)({ - // Hides full screen icon at mobile breakpoint defined in app.js - '@media (max-width: 599px)': { - display: 'none', - }, -}); +import useMediaQuery from '../hooks/useMedia'; export interface SafeTabProps { title: (() => string) | string; @@ -63,39 +56,46 @@ const AddonPanel = React.memo<{ selectedPanel = null, panelPosition = 'right', absolute = true, - }) => ( - - - - - - - - - } - id="storybook-panel-root" - > - {Object.entries(panels).map(([k, v]) => ( - - {v.render} - - ))} - - ) + }) => { + const isTablet = useMediaQuery('(min-width: 599px)'); + return ( + + + + + + + + + ) : undefined + } + id="storybook-panel-root" + > + {Object.entries(panels).map(([k, v]) => ( + + {v.render} + + ))} + + ); + } ); AddonPanel.displayName = 'AddonPanel';