Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mobile nav updates #93

Merged
merged 15 commits into from
Jul 10, 2024
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@markdoc/markdoc": "0.4.0",
"@markdoc/next.js": "0.2.2",
"@open-draft/until": "2.1.0",
"@pluralsh/design-system": "3.49.0",
"@pluralsh/design-system": "3.52.1",
"@react-types/shared": "3.22.0",
"@tanstack/react-table": "8.10.7",
"@tanstack/react-virtual": "3.0.1",
Expand Down
57 changes: 57 additions & 0 deletions src/components/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,63 @@ export const ProductLink = forwardRef(
}
)

export const SolutionLink = forwardRef(
(props: ComponentProps<typeof MainLinkBase>, ref) => {
const { Link } = useNavigationContext()

return (
<MainLinkBase
ref={ref}
as={Link}
{...props}
>
<ResponsiveText
as="p"
textStyles={{ '': 'mBody2Bold' }}
>
{props.children}
</ResponsiveText>
<ArrowRightIcon
className="hover-arrow"
size="16px"
style={{ marginLeft: 'auto' }}
/>
</MainLinkBase>
)
}
)
export const ProductMobileLink = forwardRef(
(props: ComponentProps<typeof MainLinkBase>, ref) => {
const { Link } = useNavigationContext()

const itemConfig = getProductsConfigs()[props.id || '']

return (
<MainLinkBase
ref={ref}
as={Link}
{...props}
>
<div className="h-[25px] w-[25px] min-w-[25px] rounded-medium border border-grey-750 bg-fill-two p-xxsmall">
{itemConfig?.navIcon}
</div>
<ResponsiveText
as="p"
textStyles={{ '': 'aBody2' }}
>
{itemConfig?.title}
</ResponsiveText>

<ArrowRightIcon
className="hover-arrow"
size="16px"
style={{ marginLeft: 'auto' }}
/>
</MainLinkBase>
)
}
)

export const MainLinkBase = styled.a.withConfig({
shouldForwardProp: (prop) => !['isDisabled', 'isSelected'].includes(prop),
})<{ isDisabled?: boolean; isSelected?: boolean }>(({ theme, isSelected }) => ({
Expand Down
9 changes: 9 additions & 0 deletions src/components/NavigationDesktop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { type NavData, useNavData } from '@src/contexts/NavDataContext'
import { mqs } from '../breakpoints'

import { ProductTopNavMenu } from './menu/ProductNav'
import { SolutionTopNavMenu } from './menu/SolutionNav'
import { TopNavMenu } from './menu/TopNavMenu'
import { MainLink } from './Navigation'

Expand Down Expand Up @@ -53,6 +54,14 @@ export const NavigationDesktop = styled(
/>
)
}
if (i === 1) {
return (
<SolutionTopNavMenu
key={navItem.id}
navItem={navItem}
/>
)
}

return (
<TopNavMenu
Expand Down
134 changes: 94 additions & 40 deletions src/components/NavigationMobile.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import { DiscordIcon } from '@pluralsh/design-system'
import {
Accordion,
ArrowRightIcon,
Button,
Divider,
} from '@pluralsh/design-system'

import { isEmpty } from 'lodash-es'
import styled from 'styled-components'
import styled, { useTheme } from 'styled-components'
import { useIsomorphicLayoutEffect } from 'usehooks-ts'

import { DISCORD_LINK } from '@src/consts'
import { useNavData } from '@src/contexts/NavDataContext'
import { type NavListFragment } from '@src/generated/graphqlDirectus'

import GithubStars from './GithubStars'
import useScrollLock from './hooks/useScrollLock'
import { MainLink } from './Navigation'
import { MainLink, ProductMobileLink } from './Navigation'
import { type NavContextValue, NavigationFull } from './NavigationFull'
import { SocialLink } from './PageHeaderButtons'

const MobileMainLink = styled(MainLink)(({ theme }) => ({
paddingLeft: 0,
paddingRight: 0,
paddingTop: theme.spacing.xsmall,
paddingBottom: theme.spacing.xsmall,
marginBottom: theme.spacing.xsmall,
const MobileMainLink = styled(MainLink)(() => ({
width: '100%',
marginTop: 1,
}))

export const MenuHeading = styled.h6(({ theme }) => ({
Expand All @@ -34,12 +32,6 @@ type MobileMenuProps = NavContextValue & {
className?: string
}

const SocialIcons = styled.div(({ theme }) => ({
display: 'flex',
marginTop: theme.spacing.xlarge,
gap: theme.spacing.medium,
}))

type NavData = (
| (NavListFragment & {
subnav?: NavData | null
Expand All @@ -48,40 +40,79 @@ type NavData = (
)[]

function NavList({ navData }: { navData?: NavData | null }) {
const theme = useTheme()

if (!navData) {
return null
}

return (
<>
<div className="flex flex-col gap-medium">
{navData.map((navItem) => {
if (!navItem) {
return null
}
if (isEmpty(navItem?.subnav)) {
return (
<MobileMainLink
<Button
key={navItem?.id}
{...(navItem?.link?.url ? { href: navItem?.link.url } : {})}
as="a"
secondary
endIcon={<ArrowRightIcon />}
style={{
justifyContent: 'space-between',
padding: theme.spacing.medium,
borderColor: theme.colors.border,
}}
>
{navItem?.link?.title}
</MobileMainLink>
</Button>
)
}

return (
<section
<Accordion
label={navItem?.link?.title}
key={navItem.id}
className="mb-medium"
// @ts-ignore
style={{ backgroundColor: theme.colors['fill-two'] }}
>
{navItem?.link?.title ? (
<MenuHeading>{navItem?.link?.title}</MenuHeading>
) : null}
<NavList navData={navItem?.subnav} />
</section>
{navItem.subnav?.map((subnavItem) => {
if (!subnavItem) {
return null
}

if (navItem.link?.title === 'Product') {
return (
<ProductMobileLink
key={subnavItem.id}
id={subnavItem.id}
{...(subnavItem?.link?.url
? { href: subnavItem?.link.url }
: {})}
>
{subnavItem?.link?.title}
</ProductMobileLink>
)
}

return (
<MobileMainLink
key={subnavItem.id}
{...(subnavItem?.link?.url
? { href: subnavItem?.link.url }
: {})}
style={{ padding: theme.spacing.medium }}
>
{subnavItem?.link?.title}
</MobileMainLink>
)
})}
</Accordion>
)
})}
</>
</div>
)
}

Expand All @@ -93,21 +124,44 @@ function PluralMenuContent({
className?: string
}) {
const navData = useNavData()
const theme = useTheme()

return (
<div {...props}>
<NavList navData={navData} />
<SocialIcons>
<SocialLink
href={DISCORD_LINK}
target="_blank"
rel="noopener noreferrer"
tabIndex={0}
<div className="flex flex-col gap-small">
<Button
as="a"
href="/contact-sales"
primary
fontFamily={theme.fontFamilies.sans}
endIcon={<ArrowRightIcon />}
style={{
justifyContent: 'space-between',
padding: theme.spacing.medium,
}}
>
<DiscordIcon size={16} />
</SocialLink>
<GithubStars />
</SocialIcons>
Book a demo
</Button>
<Button
as="a"
href="https://app.plural.sh/login"
secondary
fontFamily={theme.fontFamilies.sans}
endIcon={<ArrowRightIcon />}
style={{
justifyContent: 'space-between',
padding: theme.spacing.medium,
borderColor: theme.colors.border,
}}
>
Log in
</Button>
</div>
<Divider
className="my-medium"
backgroundColor={theme.colors.border}
/>
<NavList navData={navData} />
</div>
)
}
Expand Down
Loading
Loading