From 8ee6e7118d26763f461461cbb43eef7987595f23 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Wed, 12 Oct 2022 11:41:23 +1000 Subject: [PATCH 1/6] remove preventDefault --- src/UnderlineNav2/UnderlineNavItem.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/UnderlineNav2/UnderlineNavItem.tsx b/src/UnderlineNav2/UnderlineNavItem.tsx index 4aa9624cfd5..973c8c9a286 100644 --- a/src/UnderlineNav2/UnderlineNavItem.tsx +++ b/src/UnderlineNav2/UnderlineNavItem.tsx @@ -127,7 +127,6 @@ export const UnderlineNavItem = forwardRef( if (typeof afterSelect === 'function') afterSelect(event) } setSelectedLink(ref as RefObject) - event.preventDefault() }, [onSelect, afterSelect, ref, setSelectedLink] ) @@ -138,7 +137,6 @@ export const UnderlineNavItem = forwardRef( if (typeof afterSelect === 'function') afterSelect(event) } setSelectedLink(ref as RefObject) - event.preventDefault() }, [onSelect, afterSelect, ref, setSelectedLink] ) From 7a88918c3b236d6f6f7380ecca5c2ff838b33ca3 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Thu, 13 Oct 2022 11:09:50 +1000 Subject: [PATCH 2/6] docs improvement --- docs/content/drafts/UnderlineNav2.mdx | 180 +++++++++++------- .../gatsby-theme-doctocat/live-code-scope.js | 2 + src/UnderlineNav2/UnderlineNav.tsx | 145 +++++++------- 3 files changed, 187 insertions(+), 140 deletions(-) diff --git a/docs/content/drafts/UnderlineNav2.mdx b/docs/content/drafts/UnderlineNav2.mdx index 25298112592..2e0526acc05 100644 --- a/docs/content/drafts/UnderlineNav2.mdx +++ b/docs/content/drafts/UnderlineNav2.mdx @@ -17,9 +17,9 @@ import {UnderlineNav} from '@primer/react/drafts' ```jsx live drafts - Item 1 - Item 2 - Item 3 + Code + Issues + Pull Requests ``` @@ -48,79 +48,129 @@ import {UnderlineNav} from '@primer/react/drafts' ### Overflow Behaviour -When overflow occurs, the component first hides icons if present to optimize for space and show as many items as possible. (Only for fine pointer devices) - -#### Items Without Icons - -```jsx live drafts - - - Code - - - Issues - - - Pull Requests - - Discussions - - Actions - - - Projects - - Security - Insights - - Settings - - +Component behaves depending on the pointer type in case of an overflow. + +#### Fine Pointer Devices + +Component first hides icons if they present to optimize for space and show as many items as possible. If there is still an overflow, it will display the items that don't fit in the `More` menu. + +```javascript noinline live drafts +const Navigation = () => { + const items = [ + {navigation: 'Code', icon: CodeIcon}, + {navigation: 'Issues', icon: IssueOpenedIcon, counter: 120}, + {navigation: 'Pull Requests', icon: GitPullRequestIcon, counter: 13}, + {navigation: 'Discussions', icon: CommentDiscussionIcon, counter: 5}, + {navigation: 'Actions', icon: PlayIcon, counter: 4}, + {navigation: 'Projects', icon: ProjectIcon, counter: 9}, + {navigation: 'Insights', icon: GraphIcon}, + {navigation: 'Settings', icon: GearIcon, counter: 10}, + {navigation: 'Security', icon: ShieldLockIcon} + ] + const [selectedIndex, setSelectedIndex] = React.useState(0) + return ( + + + + {items.map((item, index) => ( + { + setSelectedIndex(index) + e.preventDefault() + }} + counter={item.counter} + > + {item.navigation} + + ))} + + + + ) +} + +render() ``` -#### Display `More` Menu +#### Coarse Pointer Devices + +```javascript noinline live drafts +const items = [ + {navigation: 'Code', icon: CodeIcon}, + {navigation: 'Issues', icon: IssueOpenedIcon, counter: 120}, + {navigation: 'Pull Requests', icon: GitPullRequestIcon, counter: 13}, + {navigation: 'Discussions', icon: CommentDiscussionIcon, counter: 5}, + {navigation: 'Actions', icon: PlayIcon, counter: 4}, + {navigation: 'Projects', icon: ProjectIcon, counter: 9}, + {navigation: 'Insights', icon: GraphIcon}, + {navigation: 'Settings', icon: GearIcon, counter: 10}, + {navigation: 'Security', icon: ShieldLockIcon} +] +const Navigation = () => { + const [selectedIndex, setSelectedIndex] = React.useState(0) + return ( + + + + {items.map((item, index) => ( + { + setSelectedIndex(index) + e.preventDefault() + }} + counter={item.counter} + > + {item.navigation} + + ))} + + + + ) +} + +render() +``` -If there is still overflow, the component will behave depending on the pointer. +### Loading State For Counters ```jsx live drafts - - + + Code - - Issues - - - Pull Requests - - Discussions - - Actions - - - Projects - - Security - - Insights - - - Settings - - Wiki + Issues + Pull Requests ``` -### Loading state for counters +### With React Router -```jsx live drafts - - - Item 1 - - Item 2 - Item 3 - +```jsx +import {Link} from 'react-router-dom' +import {UnderlineNav} from '@primer/react/drafts' + +const Navigation = () => { + return ( + + + Code + + + Issues + + + Pull Requests + + + ) +} ``` ## Props diff --git a/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js b/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js index 991f401f1fd..b5c891a12f8 100644 --- a/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js +++ b/docs/src/@primer/gatsby-theme-doctocat/live-code-scope.js @@ -4,6 +4,7 @@ import * as primerComponents from '@primer/react' import * as drafts from '@primer/react/drafts' import * as deprecated from '@primer/react/deprecated' import {Placeholder} from '@primer/react/Placeholder' +import {MatchMedia} from '@primer/react/hooks/useMedia' import React from 'react' import State from '../../../components/State' @@ -24,6 +25,7 @@ export default function resolveScope(metastring) { ...(metastring.includes('deprecated') ? deprecated : {}), ReactRouterLink, State, + MatchMedia, Placeholder } } diff --git a/src/UnderlineNav2/UnderlineNav.tsx b/src/UnderlineNav2/UnderlineNav.tsx index 5b60b502900..cfbcaa4bc06 100644 --- a/src/UnderlineNav2/UnderlineNav.tsx +++ b/src/UnderlineNav2/UnderlineNav.tsx @@ -12,15 +12,7 @@ import CounterLabel from '../CounterLabel' import {useTheme} from '../ThemeProvider' import {ChildWidthArray, ResponsiveProps, OnScrollWithButtonEventType} from './types' -import { - moreBtnStyles, - getDividerStyle, - getNavStyles, - ulStyles, - scrollStyles, - moreMenuStyles, - menuItemStyles -} from './styles' +import {moreBtnStyles, getDividerStyle, getNavStyles, ulStyles, scrollStyles, moreMenuStyles} from './styles' import {ArrowButton} from './UnderlineNavArrowButton' import styled from 'styled-components' import {LoadingCounter} from './LoadingCounter' @@ -354,74 +346,77 @@ export const UnderlineNav = forwardRef( iconsVisible }} > - (getNavStyles(theme, {align}), sxProp)} - aria-label={ariaLabel} - ref={navRef} - > - {isCoarsePointer && ( - 0} - onScrollWithButton={onScrollWithButton} - aria-label={ariaLabel} - /> - )} - - (responsiveProps.overflowStyles, ulStyles)} ref={listRef}> - {responsiveProps.items} - {actions.length > 0 && ( - - - - More - - - {actions.map((action, index) => { - const {children: actionElementChildren, ...actionElementProps} = action.props - return ( - | React.KeyboardEvent) => { - swapMenuItemWithListItem(action, index, event, updateListAndMenu) - setSelectEvent(event) - }} - > - + (getNavStyles(theme, {align}), sxProp)} + aria-label={ariaLabel} + ref={navRef} + > + {isCoarsePointer && ( + 0} + onScrollWithButton={onScrollWithButton} + aria-label={ariaLabel} + /> + )} + + (responsiveProps.overflowStyles, ulStyles)} ref={listRef}> + {responsiveProps.items} + {actions.length > 0 && ( + + + + More + + + {actions.map((action, index) => { + const {children: actionElementChildren, ...actionElementProps} = action.props + return ( + | React.KeyboardEvent + ) => { + swapMenuItemWithListItem(action, index, event, updateListAndMenu) + setSelectEvent(event) + }} > - {actionElementChildren} - - {loadingCounters ? ( - - ) : ( - {actionElementProps.counter} - )} - - - ) - })} - - - - + + {actionElementChildren} + + {loadingCounters ? ( + + ) : ( + {actionElementProps.counter} + )} + + + ) + })} + + + + + )} + + + {isCoarsePointer && ( + 0} + onScrollWithButton={onScrollWithButton} + aria-label={ariaLabel} + /> )} - - - {isCoarsePointer && ( - 0} - onScrollWithButton={onScrollWithButton} - aria-label={ariaLabel} - /> - )} + ) From f6921be20ec2d618c61d0d460207d0a54ed57c3a Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Thu, 13 Oct 2022 11:34:24 +1000 Subject: [PATCH 3/6] render ActionList.Item as NavItem and wrap with li --- src/UnderlineNav2/UnderlineNav.tsx | 60 ++++++++++++------- src/UnderlineNav2/UnderlineNavArrowButton.tsx | 2 +- src/UnderlineNav2/UnderlineNavContext.tsx | 2 + src/UnderlineNav2/UnderlineNavItem.tsx | 7 ++- src/UnderlineNav2/styles.ts | 38 ++++++------ 5 files changed, 65 insertions(+), 44 deletions(-) diff --git a/src/UnderlineNav2/UnderlineNav.tsx b/src/UnderlineNav2/UnderlineNav.tsx index cfbcaa4bc06..7c709a453e1 100644 --- a/src/UnderlineNav2/UnderlineNav.tsx +++ b/src/UnderlineNav2/UnderlineNav.tsx @@ -12,7 +12,15 @@ import CounterLabel from '../CounterLabel' import {useTheme} from '../ThemeProvider' import {ChildWidthArray, ResponsiveProps, OnScrollWithButtonEventType} from './types' -import {moreBtnStyles, getDividerStyle, getNavStyles, ulStyles, scrollStyles, moreMenuStyles} from './styles' +import { + moreBtnStyles, + getDividerStyle, + getNavStyles, + ulStyles, + scrollStyles, + moreMenuStyles, + menuItemStyles +} from './styles' import {ArrowButton} from './UnderlineNavArrowButton' import styled from 'styled-components' import {LoadingCounter} from './LoadingCounter' @@ -216,6 +224,8 @@ export const UnderlineNav = forwardRef( const isCoarsePointer = useMedia('(pointer: coarse)') + const [asNavItem, setAsNavItem] = useState('a') + const [selectedLink, setSelectedLink] = useState | undefined>(undefined) const [focusedLink, setFocusedLink] = useState | null>(null) @@ -339,6 +349,7 @@ export const UnderlineNav = forwardRef( selectedLinkText, setSelectedLinkText, setFocusedLink, + setAsNavItem, selectEvent, afterSelect: afterSelectHandler, variant, @@ -375,29 +386,32 @@ export const UnderlineNav = forwardRef( {actions.map((action, index) => { const {children: actionElementChildren, ...actionElementProps} = action.props return ( - | React.KeyboardEvent - ) => { - swapMenuItemWithListItem(action, index, event, updateListAndMenu) - setSelectEvent(event) - }} - > - + | React.KeyboardEvent + ) => { + swapMenuItemWithListItem(action, index, event, updateListAndMenu) + setSelectEvent(event) + }} > - {actionElementChildren} - - {loadingCounters ? ( - - ) : ( - {actionElementProps.counter} - )} - - + + {actionElementChildren} + + {loadingCounters ? ( + + ) : ( + {actionElementProps.counter} + )} + + + ) })} diff --git a/src/UnderlineNav2/UnderlineNavArrowButton.tsx b/src/UnderlineNav2/UnderlineNavArrowButton.tsx index 81d5822d592..8ac51ab1bef 100644 --- a/src/UnderlineNav2/UnderlineNavArrowButton.tsx +++ b/src/UnderlineNav2/UnderlineNavArrowButton.tsx @@ -56,7 +56,7 @@ const ArrowButton = ({ aria-label={`Scroll ${ariaLabel} navigation ${type}`} onClick={(e: React.MouseEvent) => onScrollWithButton(e, direction)} icon={type === 'left' ? ChevronLeftIcon : ChevronRightIcon} - sx={getArrowBtnStyles(theme, type)} + sx={getArrowBtnStyles(theme)} aria-disabled={!show} /> diff --git a/src/UnderlineNav2/UnderlineNavContext.tsx b/src/UnderlineNav2/UnderlineNavContext.tsx index 285810ba36f..2175eb06834 100644 --- a/src/UnderlineNav2/UnderlineNavContext.tsx +++ b/src/UnderlineNav2/UnderlineNavContext.tsx @@ -10,6 +10,7 @@ export const UnderlineNavContext = createContext<{ selectedLinkText: string setSelectedLinkText: React.Dispatch> setFocusedLink: React.Dispatch | null>> + setAsNavItem: React.Dispatch> selectEvent: React.MouseEvent | React.KeyboardEvent | null afterSelect?: (event: React.MouseEvent | React.KeyboardEvent) => void variant: 'default' | 'small' @@ -24,6 +25,7 @@ export const UnderlineNavContext = createContext<{ selectedLinkText: '', setSelectedLinkText: () => null, setFocusedLink: () => null, + setAsNavItem: () => null, selectEvent: null, variant: 'default', loadingCounters: false, diff --git a/src/UnderlineNav2/UnderlineNavItem.tsx b/src/UnderlineNav2/UnderlineNavItem.tsx index 973c8c9a286..00185b6a794 100644 --- a/src/UnderlineNav2/UnderlineNavItem.tsx +++ b/src/UnderlineNav2/UnderlineNavItem.tsx @@ -72,6 +72,7 @@ export const UnderlineNavItem = forwardRef( selectedLinkText, setSelectedLinkText, setFocusedLink, + setAsNavItem, selectEvent, afterSelect, variant, @@ -107,6 +108,8 @@ export const UnderlineNavItem = forwardRef( if (typeof onSelect === 'function' && selectEvent !== null) onSelect(selectEvent) setSelectedLinkText('') } + + setAsNavItem(Component) }, [ ref, preSelected, @@ -117,7 +120,9 @@ export const UnderlineNavItem = forwardRef( setChildrenWidth, setNoIconChildrenWidth, onSelect, - selectEvent + selectEvent, + Component, + setAsNavItem ]) const keyPressHandler = React.useCallback( diff --git a/src/UnderlineNav2/styles.ts b/src/UnderlineNav2/styles.ts index 6f3510a24f0..0f35ebd6f53 100644 --- a/src/UnderlineNav2/styles.ts +++ b/src/UnderlineNav2/styles.ts @@ -32,19 +32,20 @@ export const counterStyles = { export const getNavStyles = (theme?: Theme, props?: Partial>) => ({ display: 'flex', - paddingX: 2, justifyContent: props?.align === 'right' ? 'flex-end' : 'flex-start', borderBottom: '1px solid', borderBottomColor: `${theme?.colors.border.muted}`, align: 'row', alignItems: 'center', - position: 'relative' + position: 'relative', + paddingX: 3 }) export const ulStyles = { display: 'flex', listStyle: 'none', - padding: '0', + paddingY: 0, + paddingX: 0, margin: '0', marginBottom: '-1px', alignItems: 'center' @@ -82,6 +83,8 @@ export const btnWrapperStyles = ( bottom: 0, left: direction === 'left' ? 0 : 'auto', right: direction === 'right' ? 0 : 'auto', + // Min touch target size + width: '44px', alignItems: 'center', background: show ? `linear-gradient(to ${direction} ,#fff0, ${theme?.colors.canvas.default} 14px, ${theme?.colors.canvas.default} 100%)` @@ -90,33 +93,28 @@ export const btnWrapperStyles = ( display: `${display}` }) -export const getArrowBtnStyles = (theme?: Theme, direction = 'left') => ({ - fontWeight: 'normal', +export const getArrowBtnStyles = (theme?: Theme) => ({ boxShadow: 'none', - margin: 0, border: 0, - borderRadius: 2, - paddingX: '14px', - paddingY: 0, background: 'transparent', - height: '60%', - + width: '100%', + height: '100%', + // to reset the hover styles of the button '&:hover:not([disabled]), &:focus-visible': { - background: theme?.colors.canvas.default + background: 'transparent' }, + // To reset global focus styles because it doesn't support safari right now. '&:focus:not(:disabled)': { outline: 0, - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}`, - background: `linear-gradient(to ${direction} ,#fff0, ${theme?.colors.canvas.default} 14px, ${theme?.colors.canvas.default} 100%)` + boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` }, // where focus-visible is supported, remove the focus box-shadow '&:not(:focus-visible)': { - boxShadow: 'none', - background: `linear-gradient(to ${direction} ,#fff0, ${theme?.colors.canvas.default} 14px, ${theme?.colors.canvas.default} 100%)` + boxShadow: 'none' }, '&:focus-visible:not(:disabled)': { - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}`, - background: `linear-gradient(to ${direction} ,#fff0, ${theme?.colors.canvas.default} 14px, ${theme?.colors.canvas.default} 100%)` + outline: 0, + boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` } }) @@ -200,5 +198,7 @@ export const menuItemStyles = { // This is needed to hide the selected check icon on the menu item. https://github.com/primer/react/blob/main/src/ActionList/Selection.tsx#L32 '& > span': { display: 'none' - } + }, + // To reset the style when the menu items are rendered as react router links + textDecoration: 'none' } From fff761d0a0271c73c2bd5ea2894ec72dc9fbd92c Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Fri, 14 Oct 2022 16:21:43 +1000 Subject: [PATCH 4/6] loadingCounters and counter issue fix --- src/UnderlineNav2/UnderlineNav.tsx | 4 +++- src/UnderlineNav2/UnderlineNavItem.tsx | 10 ++++------ src/UnderlineNav2/examples.stories.tsx | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/UnderlineNav2/UnderlineNav.tsx b/src/UnderlineNav2/UnderlineNav.tsx index 7c709a453e1..5b44d2c8279 100644 --- a/src/UnderlineNav2/UnderlineNav.tsx +++ b/src/UnderlineNav2/UnderlineNav.tsx @@ -407,7 +407,9 @@ export const UnderlineNav = forwardRef( {loadingCounters ? ( ) : ( - {actionElementProps.counter} + actionElementProps.counter !== undefined && ( + {actionElementProps.counter} + ) )} diff --git a/src/UnderlineNav2/UnderlineNavItem.tsx b/src/UnderlineNav2/UnderlineNavItem.tsx index 00185b6a794..92ca1815253 100644 --- a/src/UnderlineNav2/UnderlineNavItem.tsx +++ b/src/UnderlineNav2/UnderlineNavItem.tsx @@ -42,7 +42,7 @@ export type UnderlineNavItemProps = { /** * Counter */ - counter?: number + counter?: number | string } & SxProp & LinkProps @@ -175,11 +175,9 @@ export const UnderlineNavItem = forwardRef( {children} )} - {counter && ( - - {loadingCounters ? : {counter}} - - )} + + {loadingCounters ? : counter !== undefined && {counter}} + diff --git a/src/UnderlineNav2/examples.stories.tsx b/src/UnderlineNav2/examples.stories.tsx index 04daa680922..5fe1c48e458 100644 --- a/src/UnderlineNav2/examples.stories.tsx +++ b/src/UnderlineNav2/examples.stories.tsx @@ -72,10 +72,10 @@ export const withCounterLabels = () => { ) } -const items: {navigation: string; icon: React.FC; counter?: number}[] = [ +const items: {navigation: string; icon: React.FC; counter?: number | string}[] = [ {navigation: 'Code', icon: CodeIcon}, - {navigation: 'Issues', icon: IssueOpenedIcon, counter: 120}, - {navigation: 'Pull Requests', icon: GitPullRequestIcon, counter: 13}, + {navigation: 'Issues', icon: IssueOpenedIcon, counter: 0}, + {navigation: 'Pull Requests', icon: GitPullRequestIcon, counter: '12K'}, {navigation: 'Discussions', icon: CommentDiscussionIcon, counter: 5}, {navigation: 'Actions', icon: PlayIcon, counter: 4}, {navigation: 'Projects', icon: ProjectIcon, counter: 9}, From 7a97ca749f5c138df346b89af9089686df39c27c Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Fri, 14 Oct 2022 19:42:53 +1000 Subject: [PATCH 5/6] documentation improvement --- docs/content/drafts/UnderlineNav2.mdx | 33 ++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/content/drafts/UnderlineNav2.mdx b/docs/content/drafts/UnderlineNav2.mdx index 2e0526acc05..50ec7349073 100644 --- a/docs/content/drafts/UnderlineNav2.mdx +++ b/docs/content/drafts/UnderlineNav2.mdx @@ -153,16 +153,23 @@ render() ### With React Router ```jsx -import {Link} from 'react-router-dom' +import {Link, useNavigate} from 'react-router-dom' import {UnderlineNav} from '@primer/react/drafts' const Navigation = () => { + const navigate = useNavigate() return ( Code - + { + navigate('issues') + }} + > Issues @@ -173,15 +180,24 @@ const Navigation = () => { } ``` + + You can bind the routing with both 'to' and 'onSelect' prop here. However; please note that if an 'href' prop is + passed, it will be ignored here. + + ## Props ### UnderlineNav + { ### UnderlineNav.Item + From e59e2129c37279fd1e9fb569d690a3ae90273fd3 Mon Sep 17 00:00:00 2001 From: Armagan Ersoz Date: Mon, 17 Oct 2022 14:45:54 +1000 Subject: [PATCH 6/6] introduce gap between items and remove 4px padding around --- src/UnderlineNav2/UnderlineNav.tsx | 6 ++++-- src/UnderlineNav2/UnderlineNavItem.tsx | 15 ++++++++++++--- src/UnderlineNav2/styles.ts | 22 ++++++++++++++-------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/UnderlineNav2/UnderlineNav.tsx b/src/UnderlineNav2/UnderlineNav.tsx index 5b44d2c8279..6155db5f6a0 100644 --- a/src/UnderlineNav2/UnderlineNav.tsx +++ b/src/UnderlineNav2/UnderlineNav.tsx @@ -19,7 +19,8 @@ import { ulStyles, scrollStyles, moreMenuStyles, - menuItemStyles + menuItemStyles, + GAP } from './styles' import {ArrowButton} from './UnderlineNavArrowButton' import styled from 'styled-components' @@ -146,7 +147,8 @@ const calculatePossibleItems = (childWidthArray: ChildWidthArray, navWidth: numb breakpoint = index - 1 break } else { - sumsOfChildWidth = sumsOfChildWidth + childWidth.width + // The the gap between items into account when calculating the number of items possible + sumsOfChildWidth = sumsOfChildWidth + childWidth.width + GAP } } diff --git a/src/UnderlineNav2/UnderlineNavItem.tsx b/src/UnderlineNav2/UnderlineNavItem.tsx index 92ca1815253..9572fbf3b15 100644 --- a/src/UnderlineNav2/UnderlineNavItem.tsx +++ b/src/UnderlineNav2/UnderlineNavItem.tsx @@ -175,9 +175,18 @@ export const UnderlineNavItem = forwardRef( {children} )} - - {loadingCounters ? : counter !== undefined && {counter}} - + + {loadingCounters ? ( + + + + ) : ( + counter !== undefined && ( + + {counter} + + ) + )} diff --git a/src/UnderlineNav2/styles.ts b/src/UnderlineNav2/styles.ts index 0f35ebd6f53..8369626804b 100644 --- a/src/UnderlineNav2/styles.ts +++ b/src/UnderlineNav2/styles.ts @@ -2,6 +2,13 @@ import {Theme} from '../ThemeProvider' import {BetterSystemStyleObject} from '../sx' import {UnderlineNavProps} from './UnderlineNav' +// The gap between the list items. It is a constant because the gap is used to calculate the possible number of items that can fit in the container. +export const GAP = 8 + +const focusRing = (theme?: Theme): BetterSystemStyleObject => ({ + boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` +}) + export const iconWrapStyles = { alignItems: 'center', display: 'inline-flex', @@ -48,7 +55,8 @@ export const ulStyles = { paddingX: 0, margin: '0', marginBottom: '-1px', - alignItems: 'center' + alignItems: 'center', + gap: `${GAP}px` } export const getDividerStyle = (theme?: Theme) => ({ @@ -106,15 +114,14 @@ export const getArrowBtnStyles = (theme?: Theme) => ({ // To reset global focus styles because it doesn't support safari right now. '&:focus:not(:disabled)': { outline: 0, - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` + ...focusRing(theme) }, // where focus-visible is supported, remove the focus box-shadow '&:not(:focus-visible)': { boxShadow: 'none' }, '&:focus-visible:not(:disabled)': { - outline: 0, - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` + ...focusRing(theme) } }) @@ -129,7 +136,6 @@ export const getLinkStyles = ( color: 'fg.default', textAlign: 'center', textDecoration: 'none', - paddingX: 1, ...(props?.variant === 'small' ? smallVariantLinkStyles : defaultVariantLinkStyles), '@media (hover:hover)': { '&:hover > div[data-component="wrapper"] ': { @@ -140,7 +146,7 @@ export const getLinkStyles = ( '&:focus': { outline: 0, '& > div[data-component="wrapper"]': { - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` + ...focusRing(theme) }, // where focus-visible is supported, remove the focus box-shadow '&:not(:focus-visible) > div[data-component="wrapper"]': { @@ -148,7 +154,7 @@ export const getLinkStyles = ( } }, '&:focus-visible > div[data-component="wrapper"]': { - boxShadow: `inset 0 0 0 2px ${theme?.colors.accent.fg}` + ...focusRing(theme) }, // renders a visibly hidden "copy" of the label in bold, reserving box space for when label becomes bold on selected '& span[data-content]::before': { @@ -164,7 +170,7 @@ export const getLinkStyles = ( position: 'absolute', right: '50%', bottom: 0, - width: `calc(100% - 8px)`, + width: '100%', height: 2, content: '""', bg: selectedLink === ref ? theme?.colors.primer.border.active : 'transparent',