From e5668ffc8e433c363c96d3a1b0038ed01fb365d4 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 2 Feb 2023 18:10:05 +0100 Subject: [PATCH 1/2] Menu design upgrades 1. Icons are always on the left. If there is one icon in a menu item, every other menu item will have an indent to match the space of the icon as seen in the Storybook menu. 2. If there are no icons, the item label is not indented. 3. There is a node on the right of each menu item that can be populated with keyboard shortcuts, illustrations, etc. 4. Active items (denoted with a checkmark) will be both bold and blue. 5. There will be an optional `description` text node that will be below the item label. 6. Keyboard shortcuts will list all commands in one container. 7. The decorative menu tooltip arrows are no longer shown. --- .../src/components/ToolbarMenuListItem.tsx | 39 +--- code/ui/components/src/index.ts | 4 +- code/ui/components/src/tabs/tabs.hooks.tsx | 1 - code/ui/components/src/tooltip/ListItem.tsx | 111 ++++++----- code/ui/components/src/tooltip/Tooltip.tsx | 2 +- .../src/tooltip/TooltipLinkList.stories.tsx | 178 +++++++++++++++--- .../src/tooltip/TooltipLinkList.tsx | 29 ++- .../components/src/tooltip/assets/ellipse.png | Bin 0 -> 1489 bytes code/ui/components/src/typings.d.ts | 1 + .../src/components/sidebar/Menu.stories.tsx | 26 +-- .../manager/src/components/sidebar/Menu.tsx | 8 +- .../src/components/sidebar/RefIndicator.tsx | 8 +- .../manager/src/containers/Menu.stories.tsx | 93 +++++++++ code/ui/manager/src/containers/menu.tsx | 73 +++---- code/ui/manager/src/globals/exports.ts | 2 + 15 files changed, 392 insertions(+), 183 deletions(-) create mode 100644 code/ui/components/src/tooltip/assets/ellipse.png create mode 100644 code/ui/manager/src/containers/Menu.stories.tsx diff --git a/code/addons/toolbars/src/components/ToolbarMenuListItem.tsx b/code/addons/toolbars/src/components/ToolbarMenuListItem.tsx index 35979e0b05dd..c07a885562dc 100644 --- a/code/addons/toolbars/src/components/ToolbarMenuListItem.tsx +++ b/code/addons/toolbars/src/components/ToolbarMenuListItem.tsx @@ -1,18 +1,9 @@ -import type { ReactNode } from 'react'; import React from 'react'; +import type { TooltipLinkListLink } from '@storybook/components'; import { Icons } from '@storybook/components'; import type { ToolbarItem } from '../types'; -interface ListItem { - id: string; - left?: ReactNode; - title?: ReactNode; - right?: ReactNode; - active?: boolean; - onClick?: () => void; -} - -type ToolbarMenuListItemProps = { +export type ToolbarMenuListItemProps = { currentValue: string; onClick: () => void; } & ToolbarItem; @@ -28,34 +19,18 @@ export const ToolbarMenuListItem = ({ currentValue, }: ToolbarMenuListItemProps) => { const Icon = icon && ; - const hasContent = left || right || title; - const Item: ListItem = { + const Item: TooltipLinkListLink = { id: value || currentValue, active: currentValue === value, + right, + title, + left, onClick, }; - if (left) { - Item.left = left; - } - - if (right) { - Item.right = right; - } - - if (title) { - Item.title = title; - } - if (icon && !hideIcon) { - if (hasContent && !right) { - Item.right = Icon; - } else if (hasContent && !left) { - Item.left = Icon; - } else if (!hasContent) { - Item.right = Icon; - } + Item.left = Icon; } return Item; diff --git a/code/ui/components/src/index.ts b/code/ui/components/src/index.ts index e2b6ef984165..6f8a9ab78ca0 100644 --- a/code/ui/components/src/index.ts +++ b/code/ui/components/src/index.ts @@ -56,7 +56,8 @@ export { Form } from './form/index'; export { WithTooltip, WithTooltipPure } from './tooltip/lazy-WithTooltip'; export { TooltipMessage } from './tooltip/TooltipMessage'; export { TooltipNote } from './tooltip/TooltipNote'; -export { TooltipLinkList } from './tooltip/TooltipLinkList'; +export { TooltipLinkList, type Link as TooltipLinkListLink } from './tooltip/TooltipLinkList'; +export { default as ListItem } from './tooltip/ListItem'; // Toolbar and subcomponents export { Tabs, TabsState, TabBar, TabWrapper } from './tabs/tabs'; @@ -68,6 +69,7 @@ export { AddonPanel } from './addon-panel/addon-panel'; // Graphics export type { IconsProps } from './icon/icon'; export { Icons, Symbols } from './icon/icon'; +export { icons } from './icon/icons'; export { StorybookLogo } from './brand/StorybookLogo'; export { StorybookIcon } from './brand/StorybookIcon'; diff --git a/code/ui/components/src/tabs/tabs.hooks.tsx b/code/ui/components/src/tabs/tabs.hooks.tsx index d6aeb270a672..a3d506137937 100644 --- a/code/ui/components/src/tabs/tabs.hooks.tsx +++ b/code/ui/components/src/tabs/tabs.hooks.tsx @@ -60,7 +60,6 @@ export function useList(list: ChildrenList) { <> ( - { - '& svg': { - transition: 'all 200ms ease-out', - opacity: 0, - height: 12, - width: 12, - margin: '3px 0', - verticalAlign: 'top', - }, - '& path': { - fill: 'inherit', - }, +const Right = styled.span({ + display: 'flex', + '& svg': { + height: 12, + width: 12, + margin: '3px 0', + verticalAlign: 'top', }, - ({ active, theme }) => - active - ? { - '& svg': { - opacity: 1, - }, - '& path': { - fill: theme.color.secondary, - }, - } - : {} -); - -const Center = styled.span({ - flex: 1, - textAlign: 'left', - display: 'inline-flex', - - '& > * + *': { - paddingLeft: 10, + '& path': { + fill: 'inherit', }, }); +const Center = styled.span<{ isIndented: boolean }>( + { + flex: 1, + textAlign: 'left', + display: 'flex', + flexDirection: 'column', + }, + ({ isIndented }) => (isIndented ? { marginLeft: 24 } : {}) +); + export interface CenterTextProps { active?: boolean; disabled?: boolean; } const CenterText = styled.span( - { - flex: 1, - textAlign: 'center', - }, + ({ theme }) => ({ + fontSize: '11px', + lineHeight: '14px', + }), ({ active, theme }) => active ? { @@ -112,17 +100,22 @@ export interface LeftProps { active?: boolean; } -const Left = styled.span(({ active, theme }) => - active - ? { - '& svg': { - opacity: 1, - }, - '& path': { - fill: theme.color.primary, - }, - } - : {} +const Left = styled.span( + ({ active, theme }) => + active + ? { + '& svg': { + opacity: 1, + }, + '& svg path': { + fill: theme.color.secondary, + }, + } + : {}, + () => ({ + display: 'flex', + maxWidth: 14, + }) ); export interface ItemProps { @@ -139,7 +132,7 @@ const Item = styled.a( justifyContent: 'space-between', lineHeight: '18px', - padding: '7px 15px', + padding: '7px 10px', display: 'flex', alignItems: 'center', @@ -188,14 +181,20 @@ export type LinkWrapperType = FC; export interface ListItemProps extends Omit, 'href' | 'title'> { loading?: boolean; + /** + * @deprecated This property will be removed in SB 8.0 + * Use `icon` property instead. + */ left?: ReactNode; title?: ReactNode; center?: ReactNode; right?: ReactNode; + icon?: keyof typeof icons | ReactElement; active?: boolean; disabled?: boolean; href?: string; LinkWrapper?: LinkWrapperType; + isIndented?: boolean; } const ListItem: FC = ({ @@ -204,8 +203,10 @@ const ListItem: FC = ({ title, center, right, + icon, active, disabled, + isIndented, href, onClick, LinkWrapper, @@ -214,11 +215,17 @@ const ListItem: FC = ({ const itemProps = getItemProps(onClick, href, LinkWrapper); const commonProps = { active, disabled }; + const isStorybookIcon = typeof icon === 'string' && icons[icon]; + return ( - {left && {left}} + {icon ? ( + {isStorybookIcon ? : icon} + ) : ( + left && {left} + )} {title || center ? ( -
+
{title && ( {title} diff --git a/code/ui/components/src/tooltip/Tooltip.tsx b/code/ui/components/src/tooltip/Tooltip.tsx index 98e8dce76a20..7c748773b6ea 100644 --- a/code/ui/components/src/tooltip/Tooltip.tsx +++ b/code/ui/components/src/tooltip/Tooltip.tsx @@ -126,7 +126,7 @@ export interface TooltipProps { export const Tooltip = React.forwardRef<HTMLDivElement, TooltipProps>( ( - { placement, hasChrome, children, arrowProps, tooltipRef, color, withArrows = true, ...props }, + { placement, hasChrome, children, arrowProps, tooltipRef, color, withArrows, ...props }, ref ) => { return ( diff --git a/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx b/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx index 6aed9627a331..e3006e96766b 100644 --- a/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx +++ b/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx @@ -1,9 +1,11 @@ import type { FunctionComponent, MouseEvent, ReactElement } from 'react'; import React, { Children, cloneElement } from 'react'; import { action } from '@storybook/addon-actions'; -import type { Meta } from '@storybook/react'; +import type { Meta, StoryObj } from '@storybook/react'; import { WithTooltip } from './WithTooltip'; import { TooltipLinkList } from './TooltipLinkList'; +import { Icons } from '../icon/icon'; +import ellipseUrl from './assets/ellipse.png'; const onLinkClick = action('onLinkClick'); @@ -27,24 +29,6 @@ const StoryLinkWrapper: FunctionComponent<StoryLinkWrapperProps> = ({ }); }; -export const links = [ - { - id: '1', - title: 'Link', - href: 'http://google.com', - }, - { - id: '2', - title: 'Link', - href: 'http://google.com', - }, - { - id: '3', - title: 'callback', - onClick: action('onClick'), - }, -]; - export default { component: TooltipLinkList, decorators: [ @@ -61,18 +45,160 @@ export default { ), ], excludeStories: ['links'], -} as Meta; +} satisfies Meta<typeof TooltipLinkList>; -export const Links = { +type Story = StoryObj<typeof TooltipLinkList>; + +export const WithoutIcons = { args: { - links: links.slice(0, 2), + links: [ + { + id: '1', + title: 'Link 1', + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + href: 'http://google.com', + }, + ], LinkWrapper: StoryLinkWrapper, }, -}; +} satisfies Story; -export const LinksAndCallback = { +export const WithOneIcon = { args: { - links, + links: [ + { + id: '1', + title: 'Link 1', + center: 'This is an addition description', + icon: 'link', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + href: 'http://google.com', + }, + ], LinkWrapper: StoryLinkWrapper, }, -}; +} satisfies Story; + +export const ActiveWithoutAnyIcons = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + active: true, + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; + +export const ActiveWithSeparateIcon = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + icon: 'link', + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + active: true, + center: 'This is an addition description', + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; + +export const ActiveAndIcon = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + active: true, + icon: 'link', + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; + +export const WithIllustration = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + active: true, + icon: 'link', + right: <img src={ellipseUrl} width="16" height="16" alt="ellipse" />, + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + right: <img src={ellipseUrl} width="16" height="16" alt="ellipse" />, + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; + +export const WithCustomIcon = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + active: true, + icon: <Icons icon="linux" />, + right: <img src={ellipseUrl} width="16" height="16" alt="ellipse" />, + center: 'This is an addition description', + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + right: <img src={ellipseUrl} width="16" height="16" alt="ellipse" />, + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; diff --git a/code/ui/components/src/tooltip/TooltipLinkList.tsx b/code/ui/components/src/tooltip/TooltipLinkList.tsx index b3bc5e697409..2311ca458a5c 100644 --- a/code/ui/components/src/tooltip/TooltipLinkList.tsx +++ b/code/ui/components/src/tooltip/TooltipLinkList.tsx @@ -13,7 +13,7 @@ const List = styled.div( maxHeight: 15.5 * 32, // 11.5 items }, ({ theme }) => ({ - borderRadius: theme.appBorderRadius * 2, + borderRadius: theme.appBorderRadius, }) ); @@ -28,8 +28,8 @@ export interface TooltipLinkListProps { LinkWrapper?: LinkWrapperType; } -const Item: FC<TooltipLinkListProps['links'][number]> = (props) => { - const { LinkWrapper, onClick: onClickFromProps, id, ...rest } = props; +const Item: FC<Link & { isIndented?: boolean }> = (props) => { + const { LinkWrapper, onClick: onClickFromProps, id, isIndented, ...rest } = props; const { title, href, active } = rest; const onClick = useCallback( (event: SyntheticEvent) => { @@ -47,19 +47,28 @@ const Item: FC<TooltipLinkListProps['links'][number]> = (props) => { href={href} id={`list-item-${id}`} LinkWrapper={LinkWrapper} + isIndented={isIndented} {...rest} {...(hasOnClick ? { onClick } : {})} /> ); }; -export const TooltipLinkList: FC<TooltipLinkListProps> = ({ links, LinkWrapper }) => ( - <List> - {links.map(({ isGatsby, ...p }) => ( - <Item key={p.id} LinkWrapper={isGatsby ? LinkWrapper : null} {...p} /> - ))} - </List> -); +export const TooltipLinkList: FC<TooltipLinkListProps> = ({ links, LinkWrapper }) => { + const hasOneLeftElement = links.some((link) => link.left || link.icon); + return ( + <List> + {links.map(({ isGatsby, ...p }) => ( + <Item + key={p.id} + LinkWrapper={isGatsby ? LinkWrapper : null} + isIndented={hasOneLeftElement} + {...p} + /> + ))} + </List> + ); +}; TooltipLinkList.defaultProps = { LinkWrapper: ListItem.defaultProps.LinkWrapper, diff --git a/code/ui/components/src/tooltip/assets/ellipse.png b/code/ui/components/src/tooltip/assets/ellipse.png new file mode 100644 index 0000000000000000000000000000000000000000..b17235199494c80bc530b2e71d11eb1ec9e43d38 GIT binary patch literal 1489 zcmV;?1upuDP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F800009a7bBm000&x z000&x0ZCFM@Bjb+0drDELIAGL9O(c600d`2O+f$vv5yP<VFdsH1!hS^K~#7Fl~=J+ z97hoCo;wgH3V9W{N-kVxoyn1pz%h_n8B{s2v!lv6kh$yt6xijA(-$B`R;J6O3=uhS zl|hk}v1E#LYg`D}W4Ap!-90mVAcO|)_GWf=`t_UF-LnWcY;@R7pft<n%+$j1MZ239 znC7EaGAs<_Ba^=^TG{caeUP7jy7%Al7lZ!FR(_Lp@q>n+-%DY7at&rWJ-Bl_p_vX@ z!)T4xhN%WHJg@sL7#3~&`!oBQg@23L$8XPOAHMkEL3Z8x=Dmh@l7ya4Z$o);XuE3` zYhvM&{qs}Y7a{sC>KH&-L9Ze_{ATCXc6aA6`6vLiJ(WUnybl$vN4D$*k)SqM+qA!J zA7c(37@dKFrM33%{LbI^w}<JC02IF_T`FPMt`j|gyq+`3AFAD~jmZ}%BmPQ457oSU z*(pZ5i$5QBuLW@W)4jA+;4=!w1LY(PRG^+S=fuRj4&RA!Q}pcIM2XM7U;ih)5&*5I zN$VVUt${g^^&p5;_rUQRY>@lYO#udj?mvE7TSY0H&~C4{pIibkI)zQ9y<WwU93CY0 z4#Z`anK-FKyhn`H65+fjl_l_YuterM@2brPfYaXnw7S4`Q4qV%k5b@3{6tm0_uF&9 zM7d!?5;O>nIrXhpS*~w=`)3*$C}5LqFn848jcA-o6h{#Q6&O9H?h6|JA$rj58C9b- z2Vl7DGF-2AynZSYG%rAEPR1R>BuoH{5f#IjWI)~GEsza!{Io~Z+g{vF%tQ&x`Upjw zlHbtCK@`PBMp%~0L@+$AzYt8q2+$|h$=R~O$}G6G$w8ExsEGs{FeK4LL{r!ecb7sY zh*1WKB5$-K+f=Y%HGo~6Lz=!K#v?u&i`U!lQc^TS#L21Wl5jlB3ZG0xU1Qft8%iae zD@IjIQ54jzqDX^204Ts4bHY*YHO8wO8<KStB#O{YK-GPeWHp+d0j3>A4~UUrk|1@< zp!ZxJ#ReVhZDKs79Hf#1bZ2AtK<bP~gG3Q*pE!}l5l4a)5H!%lWqb9|P`1<aOJ4Cn zo(bt|==n@ZS_2%*9P1S|1c1W49T&$XhXW3c)#H&w5@`NK2%6?a1w<%9*wmP3LwY<U zyCwVY(sO;`$g#c3KxXXFfr=?6U2tk5@>>yADT*tG14e9B4Tj1nwL#es_!XL0h79ca z%s-wzph;w-$;rTX2{2AKObRH4gdxp<I#U_iGxjJqu($FcO#Q+T0ghnu1ZgTpjfkKv z@Wt8#;$sv^dEiWrZUHlWHZXSw2RXFp2}XIG^%&Qgu?^R=pBSU2<^eTI6$6GaRP|gK z^LXRsO75y5R@B#><JAd#XfY$GY$Ak6h*?&;oKC2j^`hG5mbSvfa-w`#k2nCGr>`?; z<0Fcql!zkdH4}Pn*=s)*?ol*TTn_Oe$-c0*et)r)c>s00)v31ZC4=}Vq`?vDfIAga zWHgo)gwhNlVMSTdNfEQod235ecmUYX@{(xD&OPGgLs)AqA8&d>j%%$KTAas;Beb$P z=j=8v^#}9$B>;8n^xtIFEm*O0vuHRt?G1|vxn^LTDNrOVVaRe|u8zv~#LA%mRlN4) z_kzh^@&jyvWx|3$?-d_P8-`t`QLRZhDhz;daCEn_(_0fuFMs>|VBFr7Z$`Lrmce8- zZ{^w#Jh1MgcvDE6C3pzpt>UqZelc}C|9azYc9pF*yr<!+O-^vKLC<F%L90HrQqLbb zgc;PMI>z2RdU9LqpBOyt|Ft@w!8NT7A87dCO=d5vw4ZK3HN9+Kj25klukBcB;Uwa> r1&f(6a9}%olLZa_`0mFWy`KLMIWH<k6{wmd00000NkvXXu0mjflh(3K literal 0 HcmV?d00001 diff --git a/code/ui/components/src/typings.d.ts b/code/ui/components/src/typings.d.ts index b7d6bd46cf5b..388e1a012e23 100644 --- a/code/ui/components/src/typings.d.ts +++ b/code/ui/components/src/typings.d.ts @@ -1,2 +1,3 @@ declare module '*.md'; declare module '*.mdx'; +declare module '*.png'; diff --git a/code/ui/manager/src/components/sidebar/Menu.stories.tsx b/code/ui/manager/src/components/sidebar/Menu.stories.tsx index cb57d6d6e003..8d22f6aecd8d 100644 --- a/code/ui/manager/src/components/sidebar/Menu.stories.tsx +++ b/code/ui/manager/src/components/sidebar/Menu.stories.tsx @@ -1,33 +1,21 @@ import { expect } from '@storybook/jest'; -import type { FunctionComponent } from 'react'; -import React, { Fragment } from 'react'; +import type { ComponentProps } from 'react'; +import React from 'react'; import { TooltipLinkList } from '@storybook/components'; import { styled } from '@storybook/theming'; import { within, userEvent, screen } from '@storybook/testing-library'; -import { MenuItemIcon, SidebarMenu, ToolbarMenu } from './Menu'; +import { SidebarMenu, ToolbarMenu } from './Menu'; import { useMenu } from '../../containers/menu'; export default { - component: MenuItemIcon, + component: SidebarMenu, title: 'Sidebar/Menu', - decorators: [ - (StoryFn: FunctionComponent) => ( - <Fragment> - <StoryFn /> - </Fragment> - ), - ], }; -const fakemenu = [ - { title: 'has icon', left: <MenuItemIcon icon="check" />, id: 'icon' }, - { - title: 'has imgSrc', - left: <MenuItemIcon imgSrc="https://storybook.js.org/images/placeholders/20x20.png" />, - id: 'img', - }, - { title: 'has neither', left: <MenuItemIcon />, id: 'non' }, +const fakemenu: ComponentProps<typeof TooltipLinkList>['links'] = [ + { title: 'has icon', icon: 'link', id: 'icon' }, + { title: 'has no icon', id: 'non' }, ]; export const Items = () => <TooltipLinkList links={fakemenu} />; diff --git a/code/ui/manager/src/components/sidebar/Menu.tsx b/code/ui/manager/src/components/sidebar/Menu.tsx index 64c0508e4c67..209d4c3e3fe1 100644 --- a/code/ui/manager/src/components/sidebar/Menu.tsx +++ b/code/ui/manager/src/components/sidebar/Menu.tsx @@ -3,7 +3,7 @@ import React, { useMemo } from 'react'; import { styled } from '@storybook/theming'; import { transparentize } from 'polished'; -import type { Button } from '@storybook/components'; +import type { Button, TooltipLinkListLink } from '@storybook/components'; import { WithTooltip, TooltipLinkList, Icons, IconButton } from '@storybook/components'; export type MenuList = ComponentProps<typeof TooltipLinkList>['links']; @@ -66,6 +66,10 @@ export interface ListItemIconProps { imgSrc?: string; } +/** + * @deprecated Please use `Icons` from `@storybook/components` instead + * Component will be removed in SB 8.0 + */ export const MenuItemIcon = ({ icon, imgSrc }: ListItemIconProps) => { if (icon) { return <Icon icon={icon} />; @@ -76,7 +80,7 @@ export const MenuItemIcon = ({ icon, imgSrc }: ListItemIconProps) => { return <Placeholder />; }; -type ClickHandler = ComponentProps<typeof TooltipLinkList>['links'][number]['onClick']; +type ClickHandler = TooltipLinkListLink['onClick']; const SidebarMenuList: FC<{ menu: MenuList; diff --git a/code/ui/manager/src/components/sidebar/RefIndicator.tsx b/code/ui/manager/src/components/sidebar/RefIndicator.tsx index 0d116a63f5c0..9c469e741026 100644 --- a/code/ui/manager/src/components/sidebar/RefIndicator.tsx +++ b/code/ui/manager/src/components/sidebar/RefIndicator.tsx @@ -1,20 +1,20 @@ import { global } from '@storybook/global'; -import type { FC, ComponentProps } from 'react'; +import type { FC } from 'react'; import React, { useMemo, useCallback, forwardRef } from 'react'; +import type { TooltipLinkListLink } from '@storybook/components'; import { Icons, WithTooltip, Spaced, TooltipLinkList } from '@storybook/components'; import { styled } from '@storybook/theming'; import { transparentize } from 'polished'; import { useStorybookApi } from '@storybook/manager-api'; -import { MenuItemIcon } from './Menu'; import type { RefType } from './types'; import type { getStateType } from './utils'; const { document, window: globalWindow } = global; -export type ClickHandler = ComponentProps<typeof TooltipLinkList>['links'][number]['onClick']; +export type ClickHandler = TooltipLinkListLink['onClick']; export interface IndicatorIconProps { type: ReturnType<typeof getStateType>; } @@ -222,7 +222,7 @@ export const RefIndicator = React.memo( tooltip={ <TooltipLinkList links={Object.entries(ref.versions).map(([id, href]) => ({ - left: href === ref.url ? <MenuItemIcon icon="check" /> : <span />, + icon: href === ref.url ? 'check' : undefined, id, title: id, href, diff --git a/code/ui/manager/src/containers/Menu.stories.tsx b/code/ui/manager/src/containers/Menu.stories.tsx new file mode 100644 index 000000000000..0865f8709748 --- /dev/null +++ b/code/ui/manager/src/containers/Menu.stories.tsx @@ -0,0 +1,93 @@ +import type { FunctionComponent, MouseEvent, ReactElement } from 'react'; +import React, { Children, cloneElement } from 'react'; +import { action } from '@storybook/addon-actions'; +import type { Meta, StoryObj } from '@storybook/react'; +import { TooltipLinkList, WithTooltip } from '@storybook/components'; +import { Shortcut } from './menu'; + +const onLinkClick = action('onLinkClick'); + +interface StoryLinkWrapperProps { + href: string; + passHref?: boolean; +} + +const StoryLinkWrapper: FunctionComponent<StoryLinkWrapperProps> = ({ + href, + passHref = false, + children, +}) => { + const child = Children.only(children) as ReactElement; + return cloneElement(child, { + href: passHref && href, + onClick: (e: MouseEvent) => { + e.preventDefault(); + onLinkClick(href); + }, + }); +}; + +export default { + component: TooltipLinkList, + decorators: [ + (storyFn) => ( + <div + style={{ + height: '300px', + }} + > + <WithTooltip placement="top" trigger="click" startOpen tooltip={storyFn()}> + <div>Tooltip</div> + </WithTooltip> + </div> + ), + ], + excludeStories: ['links'], +} satisfies Meta<typeof TooltipLinkList>; + +type Story = StoryObj<typeof TooltipLinkList>; + +export const WithShortcuts = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + center: 'This is an addition description', + right: <Shortcut keys={['⌘']} />, + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + right: <Shortcut keys={['⌘', 'K']} />, + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; + +export const WithShortcutsActive = { + args: { + links: [ + { + id: '1', + title: 'Link 1', + center: 'This is an addition description', + active: true, + right: <Shortcut keys={['⌘']} />, + href: 'http://google.com', + }, + { + id: '2', + title: 'Link 2', + center: 'This is an addition description', + right: <Shortcut keys={['⌘', 'K']} />, + href: 'http://google.com', + }, + ], + LinkWrapper: StoryLinkWrapper, + }, +} satisfies Story; diff --git a/code/ui/manager/src/containers/menu.tsx b/code/ui/manager/src/containers/menu.tsx index 9e7bc34e04ef..23408c86f77a 100644 --- a/code/ui/manager/src/containers/menu.tsx +++ b/code/ui/manager/src/containers/menu.tsx @@ -1,12 +1,11 @@ import type { FC } from 'react'; -import React, { useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; -import { Badge } from '@storybook/components'; +import { Badge, Icons } from '@storybook/components'; import type { API } from '@storybook/manager-api'; import { styled, useTheme } from '@storybook/theming'; import { shortcutToHumanString } from '@storybook/manager-api'; -import { MenuItemIcon } from '../components/sidebar/Menu'; const focusableUIElements = { storySearchField: 'storybook-explorer-searchfield', @@ -14,8 +13,8 @@ const focusableUIElements = { storyPanelRoot: 'storybook-panel-root', }; -const Key = styled.code(({ theme }) => ({ - width: 16, +const Key = styled.span(({ theme }) => ({ + display: 'inline-block', height: 16, lineHeight: '16px', textAlign: 'center', @@ -25,17 +24,26 @@ const Key = styled.code(({ theme }) => ({ borderRadius: 2, userSelect: 'none', pointerEvents: 'none', - '& + &': { - marginLeft: 2, - }, + padding: '0 6px', })); -const Shortcut: FC<{ keys: string[] }> = ({ keys }) => ( +const KeyChild = styled.code( + ({ theme }) => ` + padding: 0; + + & + & { + margin-left: 6px; + } +` +); + +export const Shortcut: FC<{ keys: string[] }> = ({ keys }) => ( <> - {keys.map((key, index) => ( - // eslint-disable-next-line react/no-array-index-key - <Key key={index}>{shortcutToHumanString([key])}</Key> - ))} + <Key> + {keys.map((key, index) => ( + <KeyChild key={key}>{shortcutToHumanString([key])}</KeyChild> + ))} + </Key> </> ); @@ -56,9 +64,8 @@ export const useMenu = ( title: 'About your Storybook', onClick: () => api.navigateToSettingsPage('/settings/about'), right: api.versionUpdateAvailable() && <Badge status="positive">Update</Badge>, - left: <MenuItemIcon />, }), - [api, enableShortcuts, shortcutKeys] + [api] ); const releaseNotes = useMemo( @@ -66,9 +73,8 @@ export const useMenu = ( id: 'release-notes', title: 'Release notes', onClick: () => api.navigateToSettingsPage('/settings/release-notes'), - left: <MenuItemIcon />, }), - [api, enableShortcuts, shortcutKeys] + [api] ); const shortcuts = useMemo( @@ -77,12 +83,11 @@ export const useMenu = ( title: 'Keyboard shortcuts', onClick: () => api.navigateToSettingsPage('/settings/shortcuts'), right: enableShortcuts ? <Shortcut keys={shortcutKeys.shortcutsPage} /> : null, - left: <MenuItemIcon />, style: { borderBottom: `4px solid ${theme.appBorderColor}`, }, }), - [api, enableShortcuts, shortcutKeys] + [api, enableShortcuts, shortcutKeys.shortcutsPage, theme.appBorderColor] ); const sidebarToggle = useMemo( @@ -90,8 +95,9 @@ export const useMenu = ( id: 'S', title: 'Show sidebar', onClick: () => api.toggleNav(), + active: showNav, right: enableShortcuts ? <Shortcut keys={shortcutKeys.toggleNav} /> : null, - left: showNav ? <MenuItemIcon icon="check" /> : <MenuItemIcon />, + left: showNav ? <Icons icon="check" /> : null, }), [api, enableShortcuts, shortcutKeys, showNav] ); @@ -101,8 +107,9 @@ export const useMenu = ( id: 'T', title: 'Show toolbar', onClick: () => api.toggleToolbar(), + active: showToolbar, right: enableShortcuts ? <Shortcut keys={shortcutKeys.toolbar} /> : null, - left: showToolbar ? <MenuItemIcon icon="check" /> : <MenuItemIcon />, + left: showToolbar ? <Icons icon="check" /> : null, }), [api, enableShortcuts, shortcutKeys, showToolbar] ); @@ -112,8 +119,9 @@ export const useMenu = ( id: 'A', title: 'Show addons', onClick: () => api.togglePanel(), + active: showPanel, right: enableShortcuts ? <Shortcut keys={shortcutKeys.togglePanel} /> : null, - left: showPanel ? <MenuItemIcon icon="check" /> : <MenuItemIcon />, + left: showPanel ? <Icons icon="check" /> : null, }), [api, enableShortcuts, shortcutKeys, showPanel] ); @@ -124,7 +132,6 @@ export const useMenu = ( title: 'Change addons orientation', onClick: () => api.togglePanelPosition(), right: enableShortcuts ? <Shortcut keys={shortcutKeys.panelPosition} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -134,8 +141,9 @@ export const useMenu = ( id: 'F', title: 'Go full screen', onClick: () => api.toggleFullscreen(), + active: isFullscreen, right: enableShortcuts ? <Shortcut keys={shortcutKeys.fullScreen} /> : null, - left: isFullscreen ? 'check' : <MenuItemIcon />, + left: isFullscreen ? <Icons icon="check" /> : null, }), [api, enableShortcuts, shortcutKeys, isFullscreen] ); @@ -146,7 +154,6 @@ export const useMenu = ( title: 'Search', onClick: () => api.focusOnUIElement(focusableUIElements.storySearchField), right: enableShortcuts ? <Shortcut keys={shortcutKeys.search} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -157,7 +164,6 @@ export const useMenu = ( title: 'Previous component', onClick: () => api.jumpToComponent(-1), right: enableShortcuts ? <Shortcut keys={shortcutKeys.prevComponent} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -168,7 +174,6 @@ export const useMenu = ( title: 'Next component', onClick: () => api.jumpToComponent(1), right: enableShortcuts ? <Shortcut keys={shortcutKeys.nextComponent} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -179,7 +184,6 @@ export const useMenu = ( title: 'Previous story', onClick: () => api.jumpToStory(-1), right: enableShortcuts ? <Shortcut keys={shortcutKeys.prevStory} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -190,7 +194,6 @@ export const useMenu = ( title: 'Next story', onClick: () => api.jumpToStory(1), right: enableShortcuts ? <Shortcut keys={shortcutKeys.nextStory} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); @@ -201,24 +204,22 @@ export const useMenu = ( title: 'Collapse all', onClick: () => api.collapseAll(), right: enableShortcuts ? <Shortcut keys={shortcutKeys.collapseAll} /> : null, - left: <MenuItemIcon />, }), [api, enableShortcuts, shortcutKeys] ); - const getAddonsShortcuts = (): any[] => { + const getAddonsShortcuts = useCallback(() => { const addonsShortcuts = api.getAddonsShortcuts(); const keys = shortcutKeys as any; return Object.entries(addonsShortcuts) - .filter(([actionName, { showInMenu }]) => showInMenu) + .filter(([_, { showInMenu }]) => showInMenu) .map(([actionName, { label, action }]) => ({ id: actionName, title: label, onClick: () => action(), right: enableShortcuts ? <Shortcut keys={keys[actionName]} /> : null, - left: <MenuItemIcon />, })); - }; + }, [api, enableShortcuts, shortcutKeys]); return useMemo( () => [ @@ -240,7 +241,8 @@ export const useMenu = ( ], [ about, - ...(api.releaseNotesVersion() ? [releaseNotes] : []), + api, + releaseNotes, shortcuts, sidebarToggle, toolbarToogle, @@ -253,6 +255,7 @@ export const useMenu = ( prev, next, collapse, + getAddonsShortcuts, ] ); }; diff --git a/code/ui/manager/src/globals/exports.ts b/code/ui/manager/src/globals/exports.ts index bcc126d07c7d..ca4dfa361bfb 100644 --- a/code/ui/manager/src/globals/exports.ts +++ b/code/ui/manager/src/globals/exports.ts @@ -73,6 +73,7 @@ export default { 'Img', 'LI', 'Link', + 'ListItem', 'Loader', 'OL', 'P', @@ -105,6 +106,7 @@ export default { 'components', 'createCopyToClipboardFunction', 'getStoryHref', + 'icons', 'interleaveSeparators', 'nameSpaceClassNames', 'resetComponents', From 882330a42498c53f05579fe3d39e5dd83597cf43 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic <valentin@chromatic.com> Date: Mon, 6 Feb 2023 16:36:39 +0100 Subject: [PATCH 2/2] Change default behaviour of Tooltip trigger to 'click' --- .../a11y/src/components/VisionSimulator.tsx | 1 - .../src/containers/BackgroundSelector.tsx | 1 - .../src/components/ToolbarMenuList.tsx | 1 - code/addons/viewport/src/Tool.tsx | 1 - .../src/components/ArgsTable/ArgValue.tsx | 1 - code/ui/blocks/src/controls/Color.tsx | 1 - code/ui/components/src/tabs/tabs.stories.tsx | 23 +++++++++++++++---- code/ui/components/src/tooltip/Tooltip.tsx | 2 +- .../src/tooltip/TooltipLinkList.stories.tsx | 2 +- .../src/tooltip/TooltipMessage.stories.tsx | 2 +- .../src/tooltip/TooltipNote.stories.tsx | 8 +------ .../src/tooltip/WithTooltip.stories.tsx | 4 ---- .../ui/components/src/tooltip/WithTooltip.tsx | 2 +- .../manager/src/components/sidebar/Menu.tsx | 2 -- .../src/components/sidebar/RefBlocks.tsx | 1 - .../src/components/sidebar/RefIndicator.tsx | 2 -- .../manager/src/containers/Menu.stories.tsx | 2 +- code/ui/manager/src/containers/menu.tsx | 1 + 18 files changed, 26 insertions(+), 31 deletions(-) diff --git a/code/addons/a11y/src/components/VisionSimulator.tsx b/code/addons/a11y/src/components/VisionSimulator.tsx index 4b528802dd76..b66f8eef297d 100644 --- a/code/addons/a11y/src/components/VisionSimulator.tsx +++ b/code/addons/a11y/src/components/VisionSimulator.tsx @@ -133,7 +133,6 @@ export const VisionSimulator = () => { )} <WithTooltip placement="top" - trigger="click" tooltip={({ onHide }) => { const colorList = getColorList(filter, (i) => { setFilter(i); diff --git a/code/addons/backgrounds/src/containers/BackgroundSelector.tsx b/code/addons/backgrounds/src/containers/BackgroundSelector.tsx index 71b33e7821f4..2d531964812d 100644 --- a/code/addons/backgrounds/src/containers/BackgroundSelector.tsx +++ b/code/addons/backgrounds/src/containers/BackgroundSelector.tsx @@ -116,7 +116,6 @@ export const BackgroundSelector: FC = memo(function BackgroundSelector() { <Fragment> <WithTooltip placement="top" - trigger="click" closeOnOutsideClick tooltip={({ onHide }) => { return ( diff --git a/code/addons/toolbars/src/components/ToolbarMenuList.tsx b/code/addons/toolbars/src/components/ToolbarMenuList.tsx index b3db9112af82..3b7056a217c0 100644 --- a/code/addons/toolbars/src/components/ToolbarMenuList.tsx +++ b/code/addons/toolbars/src/components/ToolbarMenuList.tsx @@ -57,7 +57,6 @@ export const ToolbarMenuList: FC<ToolbarMenuListProps> = withKeyboardCycle( return ( <WithTooltip placement="top" - trigger="click" tooltip={({ onHide }) => { const links = items // Special case handling for various "type" variants diff --git a/code/addons/viewport/src/Tool.tsx b/code/addons/viewport/src/Tool.tsx index 75eec71d656e..dd321b637cf9 100644 --- a/code/addons/viewport/src/Tool.tsx +++ b/code/addons/viewport/src/Tool.tsx @@ -180,7 +180,6 @@ export const ViewportTool: FC = memo( <Fragment> <WithTooltip placement="top" - trigger="click" tooltip={({ onHide }) => ( <TooltipLinkList links={toLinks(list, item, setState, state, onHide)} /> )} diff --git a/code/ui/blocks/src/components/ArgsTable/ArgValue.tsx b/code/ui/blocks/src/components/ArgsTable/ArgValue.tsx index e2961973c9fa..131aab285a1b 100644 --- a/code/ui/blocks/src/components/ArgsTable/ArgValue.tsx +++ b/code/ui/blocks/src/components/ArgsTable/ArgValue.tsx @@ -161,7 +161,6 @@ const ArgSummary: FC<ArgSummaryProps> = ({ value, initialExpandedArgs }) => { return ( <WithTooltipPure closeOnOutsideClick - trigger="click" placement="bottom" visible={isOpen} onVisibleChange={(isVisible) => { diff --git a/code/ui/blocks/src/controls/Color.tsx b/code/ui/blocks/src/controls/Color.tsx index 0ced85cb271e..b126c80e3b2d 100644 --- a/code/ui/blocks/src/controls/Color.tsx +++ b/code/ui/blocks/src/controls/Color.tsx @@ -320,7 +320,6 @@ export const ColorControl: FC<ColorControlProps> = ({ return ( <Wrapper> <PickerTooltip - trigger="click" startOpen={startOpen} closeOnOutsideClick onVisibleChange={() => addPreset(color)} diff --git a/code/ui/components/src/tabs/tabs.stories.tsx b/code/ui/components/src/tabs/tabs.stories.tsx index 02a2927d5373..7a9abdb24130 100644 --- a/code/ui/components/src/tabs/tabs.stories.tsx +++ b/code/ui/components/src/tabs/tabs.stories.tsx @@ -4,7 +4,14 @@ import React, { Fragment } from 'react'; import { action } from '@storybook/addon-actions'; import { logger } from '@storybook/client-logger'; import type { Meta, StoryObj } from '@storybook/react'; -import { within, fireEvent, waitFor, screen, getByText } from '@storybook/testing-library'; +import { + within, + fireEvent, + waitFor, + screen, + getByText, + userEvent, +} from '@storybook/testing-library'; import { Tabs, TabsState, TabWrapper } from './tabs'; const colours = Array.from(new Array(15), (val, index) => index).map((i) => @@ -220,10 +227,18 @@ export const StatefulDynamicWithOpenTooltip = { const addonsTab = await canvas.findByRole('tab', { name: /Addons/ }); await waitFor(async () => { - await fireEvent(addonsTab, new MouseEvent('mouseenter', { bubbles: true })); - const tooltip = await screen.getByTestId('tooltip'); - await expect(tooltip).toBeInTheDocument(); + const tooltip = await screen.queryByTestId('tooltip'); + + if (!tooltip) { + await userEvent.click(addonsTab); + } + + if (!tooltip) { + throw new Error('Tooltip not found'); + } }); + + expect(screen.queryByTestId('tooltip')).toBeInTheDocument(); }, render: (args) => ( <TabsState initial="test1" {...args}> diff --git a/code/ui/components/src/tooltip/Tooltip.tsx b/code/ui/components/src/tooltip/Tooltip.tsx index 7c748773b6ea..d4ccde5e41df 100644 --- a/code/ui/components/src/tooltip/Tooltip.tsx +++ b/code/ui/components/src/tooltip/Tooltip.tsx @@ -108,7 +108,7 @@ const Wrapper = styled.div<WrapperProps>( drop-shadow(0px 5px 5px rgba(0,0,0,0.05)) drop-shadow(0 1px 3px rgba(0,0,0,0.1)) `, - borderRadius: theme.appBorderRadius * 2, + borderRadius: theme.appBorderRadius, fontSize: theme.typography.size.s1, } : {} diff --git a/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx b/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx index e3006e96766b..3691e91239af 100644 --- a/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx +++ b/code/ui/components/src/tooltip/TooltipLinkList.stories.tsx @@ -38,7 +38,7 @@ export default { height: '300px', }} > - <WithTooltip placement="top" trigger="click" startOpen tooltip={storyFn()}> + <WithTooltip placement="top" startOpen tooltip={storyFn()}> <div>Tooltip</div> </WithTooltip> </div> diff --git a/code/ui/components/src/tooltip/TooltipMessage.stories.tsx b/code/ui/components/src/tooltip/TooltipMessage.stories.tsx index 4b5a4714c5c3..9c210eb90bab 100644 --- a/code/ui/components/src/tooltip/TooltipMessage.stories.tsx +++ b/code/ui/components/src/tooltip/TooltipMessage.stories.tsx @@ -12,7 +12,7 @@ export default { height: '300px', }} > - <WithTooltip placement="top" trigger="click" startOpen tooltip={storyFn()}> + <WithTooltip placement="top" startOpen tooltip={storyFn()}> <div>Tooltip</div> </WithTooltip> </div> diff --git a/code/ui/components/src/tooltip/TooltipNote.stories.tsx b/code/ui/components/src/tooltip/TooltipNote.stories.tsx index f21030c62b75..6c1e533edc77 100644 --- a/code/ui/components/src/tooltip/TooltipNote.stories.tsx +++ b/code/ui/components/src/tooltip/TooltipNote.stories.tsx @@ -11,13 +11,7 @@ export default { height: '300px', }} > - <WithTooltip - hasChrome={false} - placement="top" - trigger="click" - startOpen - tooltip={storyFn()} - > + <WithTooltip hasChrome={false} placement="top" startOpen tooltip={storyFn()}> <div>Tooltip</div> </WithTooltip> </div> diff --git a/code/ui/components/src/tooltip/WithTooltip.stories.tsx b/code/ui/components/src/tooltip/WithTooltip.stories.tsx index f2f7c9e0f6da..76eab8d7c113 100644 --- a/code/ui/components/src/tooltip/WithTooltip.stories.tsx +++ b/code/ui/components/src/tooltip/WithTooltip.stories.tsx @@ -86,7 +86,6 @@ export const SimpleHoverFunctional: StoryObj<ComponentProps<typeof WithTooltip>> export const SimpleClick: StoryObj<ComponentProps<typeof WithTooltip>> = { args: { placement: 'top', - trigger: 'click', }, render: (args) => ( <WithTooltip tooltip={<Tooltip />} {...args}> @@ -98,7 +97,6 @@ export const SimpleClick: StoryObj<ComponentProps<typeof WithTooltip>> = { export const SimpleClickStartOpen: StoryObj<ComponentProps<typeof WithTooltip>> = { args: { placement: 'top', - trigger: 'click', startOpen: true, }, render: (args) => ( @@ -111,7 +109,6 @@ export const SimpleClickStartOpen: StoryObj<ComponentProps<typeof WithTooltip>> export const SimpleClickCloseOnClick: StoryObj<ComponentProps<typeof WithTooltip>> = { args: { placement: 'top', - trigger: 'click', closeOnOutsideClick: true, }, render: (args) => ( @@ -124,7 +121,6 @@ export const SimpleClickCloseOnClick: StoryObj<ComponentProps<typeof WithTooltip export const WithoutChrome: StoryObj<ComponentProps<typeof WithTooltip>> = { args: { placement: 'top', - trigger: 'click', hasChrome: false, }, render: (args) => ( diff --git a/code/ui/components/src/tooltip/WithTooltip.tsx b/code/ui/components/src/tooltip/WithTooltip.tsx index b60443a76124..70dadd67dc16 100644 --- a/code/ui/components/src/tooltip/WithTooltip.tsx +++ b/code/ui/components/src/tooltip/WithTooltip.tsx @@ -139,7 +139,7 @@ const WithTooltipPure: FC<WithTooltipPureProps> = ({ WithTooltipPure.defaultProps = { svg: false, - trigger: 'hover', + trigger: 'click', closeOnOutsideClick: false, placement: 'top', modifiers: [ diff --git a/code/ui/manager/src/components/sidebar/Menu.tsx b/code/ui/manager/src/components/sidebar/Menu.tsx index 209d4c3e3fe1..fb553512efd8 100644 --- a/code/ui/manager/src/components/sidebar/Menu.tsx +++ b/code/ui/manager/src/components/sidebar/Menu.tsx @@ -107,7 +107,6 @@ export const SidebarMenu: FC<{ return ( <WithTooltip placement="top" - trigger="click" closeOnOutsideClick tooltip={({ onHide }) => <SidebarMenuList onHide={onHide} menu={menu} />} > @@ -124,7 +123,6 @@ export const ToolbarMenu: FC<{ return ( <WithTooltip placement="bottom" - trigger="click" closeOnOutsideClick modifiers={[ { diff --git a/code/ui/manager/src/components/sidebar/RefBlocks.tsx b/code/ui/manager/src/components/sidebar/RefBlocks.tsx index d92d6f26dacc..ddc0c64886d4 100644 --- a/code/ui/manager/src/components/sidebar/RefBlocks.tsx +++ b/code/ui/manager/src/components/sidebar/RefBlocks.tsx @@ -169,7 +169,6 @@ export const ErrorBlock: FC<{ error: Error }> = ({ error }) => ( Oh no! Something went wrong loading this Storybook. <br /> <WithTooltip - trigger="click" tooltip={ <ErrorDisplay> <ErrorFormatter error={error} /> diff --git a/code/ui/manager/src/components/sidebar/RefIndicator.tsx b/code/ui/manager/src/components/sidebar/RefIndicator.tsx index 9c469e741026..6dd822de9ec2 100644 --- a/code/ui/manager/src/components/sidebar/RefIndicator.tsx +++ b/code/ui/manager/src/components/sidebar/RefIndicator.tsx @@ -190,7 +190,6 @@ export const RefIndicator = React.memo( <IndicatorPlacement ref={forwardedRef}> <WithTooltip placement="bottom-start" - trigger="click" tooltip={ <MessageWrapper> <Spaced row={0}> @@ -218,7 +217,6 @@ export const RefIndicator = React.memo( {ref.versions && Object.keys(ref.versions).length ? ( <WithTooltip placement="bottom-start" - trigger="click" tooltip={ <TooltipLinkList links={Object.entries(ref.versions).map(([id, href]) => ({ diff --git a/code/ui/manager/src/containers/Menu.stories.tsx b/code/ui/manager/src/containers/Menu.stories.tsx index 0865f8709748..5db85f26f163 100644 --- a/code/ui/manager/src/containers/Menu.stories.tsx +++ b/code/ui/manager/src/containers/Menu.stories.tsx @@ -36,7 +36,7 @@ export default { height: '300px', }} > - <WithTooltip placement="top" trigger="click" startOpen tooltip={storyFn()}> + <WithTooltip placement="top" startOpen tooltip={storyFn()}> <div>Tooltip</div> </WithTooltip> </div> diff --git a/code/ui/manager/src/containers/menu.tsx b/code/ui/manager/src/containers/menu.tsx index 23408c86f77a..dba70ddb950c 100644 --- a/code/ui/manager/src/containers/menu.tsx +++ b/code/ui/manager/src/containers/menu.tsx @@ -30,6 +30,7 @@ const Key = styled.span(({ theme }) => ({ const KeyChild = styled.code( ({ theme }) => ` padding: 0; + vertical-align: middle; & + & { margin-left: 6px;