diff --git a/code/core/src/manager/components/sidebar/SearchResults.tsx b/code/core/src/manager/components/sidebar/SearchResults.tsx index 0259bd2a92e9..9c20f9fe2090 100644 --- a/code/core/src/manager/components/sidebar/SearchResults.tsx +++ b/code/core/src/manager/components/sidebar/SearchResults.tsx @@ -16,6 +16,7 @@ import { matchesKeyCode, matchesModifiers } from '../../keybinding'; import { statusMapping } from '../../utils/status'; import { UseSymbol } from './IconSymbols'; +import { StatusLabel } from './StatusButton'; const { document } = global; @@ -31,6 +32,7 @@ const ResultRow = styled.li<{ isHighlighted: boolean }>(({ theme, isHighlighted cursor: 'pointer', display: 'flex', alignItems: 'start', + justifyContent: 'space-between', textAlign: 'left', color: 'inherit', fontSize: `${theme.typography.size.s2}px`, @@ -54,6 +56,7 @@ const IconWrapper = styled.div({ }); const ResultRowContent = styled.div({ + flex: 1, display: 'flex', flexDirection: 'column', }); @@ -181,7 +184,7 @@ const Result: FC< const nameMatch = matches.find((match: Match) => match.key === 'name'); const pathMatches = matches.filter((match: Match) => match.key === 'path'); - const [i] = item.status ? statusMapping[item.status] : []; + const [icon] = item.status ? statusMapping[item.status] : []; return ( @@ -216,7 +219,7 @@ const Result: FC< ))} - {item.status ? i : null} + {item.status ? {icon} : null} ); }); diff --git a/code/core/src/manager/components/sidebar/StatusButton.tsx b/code/core/src/manager/components/sidebar/StatusButton.tsx new file mode 100644 index 000000000000..7c5008757b11 --- /dev/null +++ b/code/core/src/manager/components/sidebar/StatusButton.tsx @@ -0,0 +1,63 @@ +import type { Theme } from '@emotion/react'; +import { IconButton } from '@storybook/core/components'; +import { styled } from '@storybook/core/theming'; +import type { API_StatusValue } from '@storybook/types'; +import { transparentize } from 'polished'; + +const withStatusColor = ({ theme, status }: { theme: Theme; status: API_StatusValue }) => { + const defaultColor = + theme.base === 'light' + ? transparentize(0.3, theme.color.defaultText) + : transparentize(0.6, theme.color.defaultText); + + return { + color: { + pending: defaultColor, + success: theme.color.positive, + error: theme.color.negative, + warn: theme.color.warning, + unknown: defaultColor, + }[status], + }; +}; + +export const StatusLabel = styled.div<{ status: API_StatusValue }>(withStatusColor, { + margin: 3, +}); + +export const StatusButton = styled(IconButton)<{ + height?: number; + width?: number; + status: API_StatusValue; + selectedItem?: boolean; +}>( + withStatusColor, + ({ theme, height, width }) => ({ + transition: 'none', + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + width: width || 28, + height: height || 28, + + '&:hover': { + color: theme.color.secondary, + }, + + '&:focus': { + color: theme.color.secondary, + borderColor: theme.color.secondary, + + '&:not(:focus-visible)': { + borderColor: 'transparent', + }, + }, + }), + ({ theme, selectedItem }) => + selectedItem && { + '&:hover': { + boxShadow: `inset 0 0 0 2px ${theme.color.secondary}`, + background: 'rgba(255, 255, 255, 0.2)', + }, + } +); diff --git a/code/core/src/manager/components/sidebar/Tree.tsx b/code/core/src/manager/components/sidebar/Tree.tsx index 232205941ba7..2f26407f847b 100644 --- a/code/core/src/manager/components/sidebar/Tree.tsx +++ b/code/core/src/manager/components/sidebar/Tree.tsx @@ -43,62 +43,13 @@ import { useLayout } from '../layout/LayoutProvider'; import { IconSymbols, UseSymbol } from './IconSymbols'; import { CollapseIcon } from './components/CollapseIcon'; import { StatusContext, useStatusSummary } from './StatusContext'; +import { StatusButton } from './StatusButton'; const Container = styled.div<{ hasOrphans: boolean }>((props) => ({ marginTop: props.hasOrphans ? 20 : 0, marginBottom: 20, })); -export const Action = styled(IconButton)<{ - height?: number; - width?: number; - status: API_StatusValue; - selectedItem?: boolean; -}>( - ({ theme, height, width, status }) => { - const defaultColor = - theme.base === 'light' - ? transparentize(0.3, theme.color.defaultText) - : transparentize(0.6, theme.color.defaultText); - - return { - transition: 'none', - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - width: width || 28, - height: height || 28, - color: { - pending: defaultColor, - success: theme.color.positive, - error: theme.color.negative, - warn: theme.color.warning, - unknown: defaultColor, - }[status], - - '&:hover': { - color: theme.color.secondary, - }, - - '&:focus': { - color: theme.color.secondary, - borderColor: theme.color.secondary, - - '&:not(:focus-visible)': { - borderColor: 'transparent', - }, - }, - }; - }, - ({ theme, selectedItem }) => - selectedItem && { - '&:hover': { - boxShadow: `inset 0 0 0 2px ${theme.color.secondary}`, - background: 'rgba(255, 255, 255, 0.2)', - }, - } -); - const CollapseButton = styled.button(({ theme }) => ({ all: 'unset', display: 'flex', @@ -126,6 +77,11 @@ export const LeafNodeStyleWrapper = styled.div(({ theme }) => ({ minHeight: 28, borderRadius: 4, + '&:hover, &:focus': { + background: transparentize(0.93, theme.color.secondary), + outline: 'none', + }, + '&[data-selected="true"]': { color: theme.color.lightest, background: theme.color.secondary, @@ -249,7 +205,6 @@ const Node = React.memo(function Node({ closeOnOutsideClick onClick={(event) => event.stopPropagation()} placement="bottom" - style={{ position: 'absolute', right: 0, top: 0 }} tooltip={() => ( (function Node({ /> )} > - + {icon} - + ) : null} @@ -406,14 +361,13 @@ const Node = React.memo(function Node({ closeOnOutsideClick onClick={(event) => event.stopPropagation()} placement="bottom" - style={{ position: 'absolute', right: 0, top: 0 }} tooltip={({ onHide }) => } > - + - + )} diff --git a/code/core/src/manager/components/sidebar/TreeNode.tsx b/code/core/src/manager/components/sidebar/TreeNode.tsx index e3e9c8854cf7..57c8c7197735 100644 --- a/code/core/src/manager/components/sidebar/TreeNode.tsx +++ b/code/core/src/manager/components/sidebar/TreeNode.tsx @@ -43,11 +43,6 @@ const BranchNode = styled.button<{ gap: 6, paddingTop: 5, paddingBottom: 4, - - '&:hover, &:focus': { - background: transparentize(0.93, theme.color.secondary), - outline: 'none', - }, })); const LeafNode = styled.a<{ depth?: number }>(({ theme, depth = 0 }) => ({ @@ -61,17 +56,11 @@ const LeafNode = styled.a<{ depth?: number }>(({ theme, depth = 0 }) => ({ paddingLeft: `${22 + depth * 18}px`, paddingTop: 5, paddingBottom: 4, - paddingRight: 28, fontSize: `${theme.typography.size.s2}px`, textDecoration: 'none', overflowWrap: 'break-word', wordWrap: 'break-word', wordBreak: 'break-word', - - '&:hover, &:focus': { - background: transparentize(0.93, theme.color.secondary), - outline: 'none', - }, })); export const RootNode = styled.div(({ theme }) => ({