diff --git a/.changeset/plenty-planes-fix.md b/.changeset/plenty-planes-fix.md new file mode 100644 index 00000000000..726d22fb001 --- /dev/null +++ b/.changeset/plenty-planes-fix.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Convert SideNav component to CSS Modules behind team feature flag diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-colorblind-linux.png new file mode 100644 index 00000000000..f3d7905d565 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-dimmed-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-dimmed-linux.png new file mode 100644 index 00000000000..b80a00be1ea Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-high-contrast-linux.png new file mode 100644 index 00000000000..2aaa19fd9fb Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-linux.png new file mode 100644 index 00000000000..f3d7905d565 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-tritanopia-linux.png new file mode 100644 index 00000000000..f3d7905d565 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-colorblind-linux.png new file mode 100644 index 00000000000..d57cb657f7f Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-high-contrast-linux.png new file mode 100644 index 00000000000..e6be6bfc182 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-linux.png new file mode 100644 index 00000000000..d57cb657f7f Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-tritanopia-linux.png new file mode 100644 index 00000000000..d57cb657f7f Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Default-light-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-colorblind-linux.png new file mode 100644 index 00000000000..4c608fb019c Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-dimmed-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-dimmed-linux.png new file mode 100644 index 00000000000..016d1815637 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-high-contrast-linux.png new file mode 100644 index 00000000000..6cb1757ea75 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-linux.png new file mode 100644 index 00000000000..7890b396da3 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-tritanopia-linux.png new file mode 100644 index 00000000000..4c608fb019c Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-colorblind-linux.png new file mode 100644 index 00000000000..865fa5f03ed Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-high-contrast-linux.png new file mode 100644 index 00000000000..bf54b235514 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-linux.png new file mode 100644 index 00000000000..0e2db7713d0 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-tritanopia-linux.png new file mode 100644 index 00000000000..865fa5f03ed Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Full-Variant-light-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-colorblind-linux.png new file mode 100644 index 00000000000..0f9c72a1437 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-dimmed-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-dimmed-linux.png new file mode 100644 index 00000000000..6078a43654c Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-high-contrast-linux.png new file mode 100644 index 00000000000..e48547b6c1a Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-linux.png new file mode 100644 index 00000000000..0f9c72a1437 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-tritanopia-linux.png new file mode 100644 index 00000000000..0f9c72a1437 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-colorblind-linux.png new file mode 100644 index 00000000000..db98c6b4dc5 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-high-contrast-linux.png new file mode 100644 index 00000000000..0ff06c0b1cb Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-linux.png new file mode 100644 index 00000000000..db98c6b4dc5 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-tritanopia-linux.png new file mode 100644 index 00000000000..db98c6b4dc5 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Nested-Variant-light-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-colorblind-linux.png new file mode 100644 index 00000000000..a819b943a7b Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-dimmed-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-dimmed-linux.png new file mode 100644 index 00000000000..d2ac17dbe9d Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-dimmed-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-high-contrast-linux.png new file mode 100644 index 00000000000..b124525401e Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-linux.png new file mode 100644 index 00000000000..a819b943a7b Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-tritanopia-linux.png new file mode 100644 index 00000000000..a819b943a7b Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-dark-tritanopia-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-colorblind-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-colorblind-linux.png new file mode 100644 index 00000000000..8dc8fd8746d Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-colorblind-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-high-contrast-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-high-contrast-linux.png new file mode 100644 index 00000000000..ff4b810bcd3 Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-high-contrast-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-linux.png new file mode 100644 index 00000000000..8dc8fd8746d Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-linux.png differ diff --git a/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-tritanopia-linux.png b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-tritanopia-linux.png new file mode 100644 index 00000000000..8dc8fd8746d Binary files /dev/null and b/.playwright/snapshots/components/SideNav.test.ts-snapshots/SideNav-Lightweight-Variant-light-tritanopia-linux.png differ diff --git a/e2e/components/SideNav.test.ts b/e2e/components/SideNav.test.ts new file mode 100644 index 00000000000..7f63bafaeff --- /dev/null +++ b/e2e/components/SideNav.test.ts @@ -0,0 +1,56 @@ +import {test, expect} from '@playwright/test' +import {visit} from '../test-helpers/storybook' +import {themes} from '../test-helpers/themes' + +const stories = [ + { + title: 'Default', + id: 'deprecated-components-sidenav-dev--default', + }, + { + title: 'Full Variant', + id: 'deprecated-components-sidenav-dev--full-variant', + }, + { + title: 'Lightweight Variant', + id: 'deprecated-components-sidenav-dev--lightweight-variant', + }, + { + title: 'Lightweight Nested Variant', + id: 'deprecated-components-sidenav-dev--lightweight-nested-variant', + }, +] as const + +test.describe('SideNav', () => { + for (const story of stories) { + test.describe(story.title, () => { + for (const theme of themes) { + test.describe(theme, () => { + test('default @vrt', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + }, + }) + + // Default state + expect(await page.screenshot({animations: 'disabled'})).toMatchSnapshot( + `SideNav.${story.title}.${theme}.png`, + ) + }) + + test('axe @aat', async ({page}) => { + await visit(page, { + id: story.id, + globals: { + colorScheme: theme, + }, + }) + await expect(page).toHaveNoViolations() + }) + }) + } + }) + } +}) diff --git a/packages/react/src/SideNav.module.css b/packages/react/src/SideNav.module.css new file mode 100644 index 00000000000..04746116dc5 --- /dev/null +++ b/packages/react/src/SideNav.module.css @@ -0,0 +1,114 @@ +.SideNav { + background-color: var(--bgColor-muted); +} + +.SideNavBordered { + border-color: var(--borderColor-default); + border-style: solid; + border-width: var(--borderWidth-thin); + border-radius: var(--borderRadius-medium); + + /* Remove duplicate borders from nested SideNavs */ + & > & { + border-right: 0; + border-bottom: 0; + border-left: 0; + } +} + +.SideNavLink { + position: relative; + display: block; + width: 100%; + /* stylelint-disable-next-line primer/typography */ + font-size: 14px; + text-align: left; + text-decoration: none; + + & > .SideNav { + border-bottom: none; + } + + .SideNav.SideNavVariant-normal > & { + padding: var(--base-size-16); + color: var(--fgColor-default); + border: 0; + border-top: var(--borderWidth-thin) solid var(--borderColor-muted); + + &:first-child { + border-top: 0; + border-top-left-radius: var(--borderRadius-medium); + border-top-right-radius: var(--borderRadius-medium); + } + + &:last-child { + border-bottom-right-radius: var(--borderRadius-medium); + border-bottom-left-radius: var(--borderRadius-medium); + } + + /* Bar on the left */ + &::before { + position: absolute; + top: 0; + bottom: 0; + left: 0; + z-index: 1; + width: 3px; + pointer-events: none; + content: ''; + } + + &:hover { + text-decoration: none; + background-color: var(--bgColor-neutral-muted); + } + + &:focus { + z-index: 1; + text-decoration: none; + background-color: var(--bgColor-neutral-muted); + outline: solid 2px var(--fgColor-accent); + } + + &[aria-current='page'], + &[aria-selected='true'] { + background-color: var(--bgColor-default); + + /* Bar on the left */ + /* stylelint-disable-next-line selector-max-specificity */ + &::before { + /* stylelint-disable-next-line primer/colors */ + background-color: var(--underlineNav-borderColor-active, var(--color-primer-border-active, #fd8c73)); + } + } + } + + .SideNav.SideNavVariant-lightweight > & { + padding: var(--base-size-4) 0; + color: var(--fgColor-accent); + + &:hover { + color: var(--fgColor-default); + text-decoration: none; + } + + &:focus { + z-index: 1; + color: var(--fgColor-default); + text-decoration: none; + outline: solid 1px var(--fgColor-accent); + } + + &[aria-current='page'], + &[aria-selected='true'] { + font-weight: var(--base-text-weight-medium); + color: var(--fgColor-default); + } + } +} + +.SideNavLinkFull { + display: flex; + align-items: center; + justify-content: space-between; +} diff --git a/packages/react/src/SideNav.tsx b/packages/react/src/SideNav.tsx index 3d290fb3604..cdd1fe047a0 100644 --- a/packages/react/src/SideNav.tsx +++ b/packages/react/src/SideNav.tsx @@ -1,177 +1,225 @@ import type {To} from 'history' - -import {get} from './constants' import styled, {css} from 'styled-components' import Box from './Box' import type {ComponentProps} from './utils/types' -import Link from './Link' -import React from 'react' +import Link, {type LinkProps} from './Link' +import React, {type PropsWithChildren} from 'react' import {clsx} from 'clsx' import type {SxProp} from './sx' import sx from './sx' +import {toggleStyledComponent} from './internal/utils/toggleStyledComponent' +import classes from './SideNav.module.css' +import {useFeatureFlag} from './FeatureFlags' + +const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team' type SideNavBaseProps = { + as?: React.ElementType variant?: 'lightweight' | 'normal' bordered?: boolean className?: string children?: React.ReactNode 'aria-label'?: string -} - -function SideNavBase({variant = 'normal', className, bordered, children, 'aria-label': ariaLabel}: SideNavBaseProps) { +} & SxProp + +const StyledNav = toggleStyledComponent( + CSS_MODULES_FEATURE_FLAG, + 'nav', + styled(Box)` + background-color: var(--bgColor-muted); + + ${props => + props.bordered && + css` + border-color: var(--borderColor-default); + border-style: solid; + border-width: var(--borderWidth-thin); + border-radius: var(--borderRadius-medium); + + // Remove duplicate borders from nested SideNavs + & > & { + border-left: 0; + border-right: 0; + border-bottom: 0; + } + `} + + ${sx}; + `, +) + +function SideNav({ + as = 'nav', + variant = 'normal', + className, + bordered, + children, + 'aria-label': ariaLabel, + sx: sxProp, +}: SideNavBaseProps) { + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) const variantClassName = variant === 'lightweight' ? 'lightweight' : 'normal' - const newClassName = clsx(className, `variant-${variantClassName}`) - + const newClassName = clsx( + { + [classes.SideNav]: enabled, + [classes.SideNavBordered]: enabled && bordered, + [classes[`SideNavVariant-${variantClassName}`]]: enabled, + sidenav: !enabled, + [`variant-${variantClassName}`]: !enabled, + }, + className, + ) return ( - {children} - + ) } -const SideNav = styled(SideNavBase)` - background-color: ${get('colors.canvas.subtle')}; - - ${props => - props.bordered && - css` - // Remove duplicate borders from nested SideNavs - & > & { - border-left: 0; - border-right: 0; - border-bottom: 0; - } - `} - - ${sx}; -` -type StyledSideNavLinkProps = { +type StyledSideNavLinkProps = PropsWithChildren<{ to?: To selected?: boolean variant?: 'full' | 'normal' -} +}> & + LinkProps // used for variant normal hover, focus pseudo selectors const CommonAccessibilityVariantNormalStyles = css` - background-color: ${get('colors.neutral.subtle')}; + background-color: var(--bgColor-neutral-muted); text-decoration: none; ` // used for light weight hover, focus pseudo selectors const CommonAccessibilityVariantLightWeightStyles = css` - color: ${get('colors.fg.default')}; + color: var(--fgColor-default); text-decoration: none; ` -const SideNavLink = styled(Link).attrs(props => { - const isReactRouter = typeof props.to === 'string' - if (isReactRouter || props.selected) { - // according to their docs, NavLink supports aria-current: - // https://reacttraining.com/react-router/web/api/NavLink/aria-current-string - return {'aria-current': 'page'} - } else { - return {} - } -})` - position: relative; - display: block; - ${props => - props.variant === 'full' && - css` - display: flex; - align-items: center; - justify-content: space-between; - `} - width: 100%; - text-align: left; - font-size: ${get('fontSizes.1')}; - - & > ${SideNav} { - border-bottom: none; - } - - ${SideNav}.variant-normal > & { - color: ${get('colors.fg.default')}; - padding: ${get('space.3')}; - border: 0; - border-top: ${get('borderWidths.1')} solid ${get('colors.border.muted')}; - - &:first-child { - border-top: 0; - border-top-right-radius: ${get('radii.2')}; - border-top-left-radius: ${get('radii.2')}; +const StyledSideNavLink = toggleStyledComponent( + CSS_MODULES_FEATURE_FLAG, + Link, + styled(Link)` + position: relative; + display: block; + width: 100%; + font-size: 14px; + text-align: left; + text-decoration: none; + ${props => + props.variant === 'full' && + css` + display: flex; + align-items: center; + justify-content: space-between; + `} + + & > .sidenav { + border-bottom: none; } - &:last-child { - border-bottom-right-radius: ${get('radii.2')}; - border-bottom-left-radius: ${get('radii.2')}; - } - - // Bar on the left - &::before { - position: absolute; - top: 0; - bottom: 0; - left: 0; - z-index: 1; - width: 3px; - pointer-events: none; - content: ''; - } - - &:hover { - ${CommonAccessibilityVariantNormalStyles} - } + .sidenav.variant-normal > & { + color: var(--fgColor-default); + padding: var(--base-size-16); + border: 0; + border-top: var(--borderWidth-thin) solid var(--borderColor-muted); - &:focus { - ${CommonAccessibilityVariantNormalStyles} - outline: solid 2px ${get('colors.accent.fg')}; - z-index: 1; - } + &:first-child { + border-top: 0; + border-top-right-radius: var(--borderRadius-medium); + border-top-left-radius: var(--borderRadius-medium); + } - &[aria-current='page'], - &[aria-selected='true'] { - background-color: ${get('colors.sidenav.selectedBg')}; + &:last-child { + border-bottom-right-radius: var(--borderRadius-medium); + border-bottom-left-radius: var(--borderRadius-medium); + } // Bar on the left &::before { - background-color: ${get('colors.primer.border.active')}; + position: absolute; + top: 0; + bottom: 0; + left: 0; + z-index: 1; + width: 3px; + pointer-events: none; + content: ''; + } + + &:hover { + ${CommonAccessibilityVariantNormalStyles} } - } - } - ${SideNav}.variant-lightweight > & { - padding: ${get('space.1')} 0; - color: ${get('colors.accent.fg')}; + &:focus { + ${CommonAccessibilityVariantNormalStyles} + outline: solid 2px var(--fgColor-accent); + z-index: 1; + } - &:hover { - ${CommonAccessibilityVariantLightWeightStyles} - } + &[aria-current='page'], + &[aria-selected='true'] { + background-color: var(--bgColor-default); - &:focus { - ${CommonAccessibilityVariantLightWeightStyles} - outline: solid 1px ${get('colors.accent.fg')}; - z-index: 1; + // Bar on the left + &::before { + background-color: var(--underlineNav-borderColor-active, var(--color-primer-border-active, #fd8c73)); + } + } } - &[aria-current='page'], - &[aria-selected='true'] { - color: ${get('colors.fg.default')}; - font-weight: ${get('fontWeights.semibold')}; + .sidenav.variant-lightweight > & { + padding: var(--base-size-4) 0; + color: var(--fgColor-accent); + + &:hover { + ${CommonAccessibilityVariantLightWeightStyles} + } + + &:focus { + ${CommonAccessibilityVariantLightWeightStyles} + outline: solid 1px var(--fgColor-accent); + z-index: 1; + } + + &[aria-current='page'], + &[aria-selected='true'] { + color: var(--fgColor-default); + font-weight: var(--base-text-weight-medium); + } } - } - ${sx}; -` + ${sx}; + `, +) + +const SideNavLink = ({selected, to, variant, className, children, ...rest}: StyledSideNavLinkProps) => { + const isReactRouter = typeof to === 'string' + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + const newClassName = clsx( + {[classes.SideNavLink]: true, [classes.SideNavLinkFull]: enabled && variant === 'full'}, + className, + ) + + // according to their docs, NavLink supports aria-current: + // https://reacttraining.com/react-router/web/api/NavLink/aria-current-string + return ( + + {children} + + ) +} SideNavLink.displayName = 'SideNav.Link' diff --git a/packages/react/src/stories/deprecated/SideNav.dev.stories.tsx b/packages/react/src/stories/deprecated/SideNav.dev.stories.tsx new file mode 100644 index 00000000000..12e8e170641 --- /dev/null +++ b/packages/react/src/stories/deprecated/SideNav.dev.stories.tsx @@ -0,0 +1,130 @@ +import {Avatar, Box, CounterLabel, Heading, Label, SideNav, Text} from '../..' +import type {Meta} from '@storybook/react' +import React from 'react' +import type {ComponentProps} from '../../utils/types' +import Octicon from '../../Octicon' +import {DotIcon, MailIcon, PersonIcon, SmileyIcon, ZapIcon} from '@primer/octicons-react' + +export default { + title: 'Deprecated/Components/SideNav/Dev', + component: SideNav, +} as Meta> + +export const Default = () => ( + + + Account + + + Profile + + + Emails + + + Notifications + + +) + +export const FullVariant = () => ( + + + Text Only + + + + With an avatar + + + + With an Octicon + + + With a status icon + + + + With a label + + + + With a counter + 16 + + + A heading + and some more content + + +) + +export const LightweightVariant = () => ( + + + + Menu + + + + + Account + + + Profile + + + Emails + + + Notifications + + + +) + +export const LightweightNestedVariant = () => ( + + + + Account + + + + Profile + + + + + Sub item 1 + + + Sub item 2 + + + Sub item 3 + + + + + + Emails + + +)