Skip to content

Commit

Permalink
Merge branch 'padms/2736' into staging
Browse files Browse the repository at this point in the history
  • Loading branch information
padms committed Jan 21, 2025
2 parents 435b624 + 89cc1aa commit d4194a0
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 79 deletions.
5 changes: 5 additions & 0 deletions sanityv3/schemas/documents/page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ export default {
description: 'You can override the hero image as the SoMe image by uploading another image here.',
fieldset: 'metadata',
},
{
name: 'stickyMenu',
title: 'Sticky Menu',
type: 'stickyMenu',
},
...sharedHeroFields,
{
title: 'Is Campain',
Expand Down
2 changes: 2 additions & 0 deletions sanityv3/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import transcript from './objects/transcript'
import anchorLinkList from './objects/anchorLinkList/anchorLinkList'
import anchorLinkReference from './objects/anchorLinkList/anchorLinkReference'
import imageForText from './objects/imageForText'
import stickyMenu from './objects/stickyMenu'

const {
pageNotFound,
Expand Down Expand Up @@ -210,6 +211,7 @@ const RemainingSchemas = [
anchorLinkList,
anchorLinkReference,
imageForText,
stickyMenu,
]

// Then we give our schema to the builder and provide the result to Sanity
Expand Down
47 changes: 47 additions & 0 deletions sanityv3/schemas/objects/stickyMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Rule } from 'sanity'
import { defaultColors } from '../defaultColors'
import { description } from './iframe/sharedIframeFields'

const chosenColors = ['White', 'Moss Green Light']
const backgroundColors = defaultColors.filter((color) => chosenColors.includes(color.title))

export default {
name: 'stickyMenu',
title: 'Sticky Menu',
type: 'object',
fields: [
{
title: 'Title',
name: 'title',
type: 'string',
},
{
title: 'Links',
name: 'links',
type: 'array',
of: [
{
type: 'anchorLinkReference',
title: 'Anchor reference',
},
{ type: 'downloadableFile', title: 'Downloadable file' },
],
validation: (Rule: Rule) =>
Rule.unique()
.max(2)
.custom((value: any) => {
if (value.length == 2 && value[0]._type == value[1]._type) return 'Cannot have two links of same type'
return true
}),
},
{
title: 'Color',
description: 'Default is white.',
name: 'backgroundColor',
type: 'colorlist',
options: {
colors: backgroundColors,
},
},
],
}
8 changes: 6 additions & 2 deletions web/core/Link/LogoLink.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { AnchorHTMLAttributes } from 'react'
import { LogoSecondary } from '@components'
import NextLink from 'next/link'
import { twMerge } from 'tailwind-merge'
import { useIntl } from 'react-intl'

export type LogoLinkProps = AnchorHTMLAttributes<HTMLAnchorElement>

export const LogoLink = ({ ...rest }: LogoLinkProps) => {
export const LogoLink = ({ className, ...rest }: LogoLinkProps) => {
const intl = useIntl()
return (
<NextLink
href="/"
aria-label={intl.formatMessage({ id: 'logolink_title', defaultMessage: 'Equinor homepage' })}
{...rest}
className="fill-energy-red-100 dark:fill-white-100 flex items-center justify-self-start h-full focus:outline-none focus-visible:envis-outline dark:focus-visible:envis-outline-invert"
className={twMerge(
'fill-energy-red-100 dark:fill-white-100 flex items-center justify-self-start h-full focus:outline-none focus-visible:envis-outline dark:focus-visible:envis-outline-invert',
className,
)}
prefetch={false}
>
<LogoSecondary className="-mt-[12%]" />
Expand Down
57 changes: 57 additions & 0 deletions web/core/Link/StickyMenuLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { forwardRef } from 'react'
import { twMerge } from 'tailwind-merge'
import { BaseLink, BaseLinkProps } from './BaseLink'
import { TransformableIcon } from '../../icons/TransformableIcon'
import { arrow_down, library_pdf } from '@equinor/eds-icons'

export type StickMenuLinkProps = {
isDownloadable?: boolean
} & BaseLinkProps

/** Sticky menu link style */
export const StickyMenuLink = forwardRef<HTMLAnchorElement, StickMenuLinkProps>(function StickyMenuLink(
{ children, type = 'internalUrl', className = '', href = '', isDownloadable = false, ...rest },
ref,
) {
const classNames = twMerge(
`
group
inline-flex
align-baseline
w-fit
text-slate-80
leading-0
`,
className,
)
const contentClassNames = `
relative
w-fit
hover:underline
no-underline
`

return (
<BaseLink className={classNames} ref={ref} href={href} {...rest}>
{isDownloadable && <TransformableIcon iconData={library_pdf} className="mr-1" />}
<span className={contentClassNames}>{children}</span>
{isDownloadable && (
<TransformableIcon
iconData={arrow_down}
className="text-energy-red-100
dark:text-white-100 h-[22px] border-energy-red-100 border-b-[2px]
ml-2"
/>
)}
{!isDownloadable && (
<TransformableIcon
iconData={arrow_down}
className="text-energy-red-100
dark:text-white-100
ml-2"
/>
)}
</BaseLink>
)
})
export default StickyMenuLink
1 change: 1 addition & 0 deletions web/core/Link/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export { default as Link, type LinkProps } from './Link'
export { default as ResourceLink, type ResourceLinkProps } from './ResourceLink'
export { default as ButtonLink, type ButtonLinkProps } from './ButtonLink'
export { default as BaseLink, type BaseLinkProps } from './BaseLink'
export { default as StickyMenuLink, type StickMenuLinkProps } from './StickyMenuLink'
export { default as LogoLink, type LogoLinkProps } from './LogoLink'
7 changes: 7 additions & 0 deletions web/lib/queries/common/anchorLinkReferenceFields.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const anchorLinkReferenceFields = /* groq */ `
_type == "anchorLinkReference" =>{
"type": _type,
"id": _key,
title,
anchorReference,
}`
6 changes: 2 additions & 4 deletions web/lib/queries/common/pageContentFields.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { keyNumbersFields } from './keyNumbersFields'
import { noDrafts, sameLang } from './langAndDrafts'
import promoteMagazine from './promotions/promoteMagazine'
import { lastUpdatedTimeQuery, publishDateTimeQuery } from './publishDateTime'
import { anchorLinkReferenceFields } from './anchorLinkReferenceFields'

const pageContentFields = /* groq */ `
_type == "keyNumbers" =>{
Expand Down Expand Up @@ -593,10 +594,7 @@ _type == "keyNumbers" =>{
title,
columns,
"anchorList":anchorList[]{
"type": _type,
"id": _key,
title,
anchorReference,
${anchorLinkReferenceFields}
}
},
_type == "imageForText" => {
Expand Down
13 changes: 13 additions & 0 deletions web/lib/queries/common/stickyMenu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import downloadableFileFields from './actions/downloadableFileFields'
import { anchorLinkReferenceFields } from './anchorLinkReferenceFields'

export const stickyMenu = /* groq */ `"stickyMenu":
content->stickyMenu{
title,
"type": _type,
"links": links[]{
${downloadableFileFields},
${anchorLinkReferenceFields}
}
}
`
2 changes: 2 additions & 0 deletions web/lib/queries/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { eventContentFields } from './common/eventContentFields'
import { heroFields } from './common/heroFields'
import { seoAndSomeFields } from './common/seoAndSomeFields'
import { breadcrumbsQuery } from './common/breadcrumbs'
import { stickyMenu } from './common/stickyMenu'

const allSlugsQuery = /* groq */ `
"currentSlug": {
Expand All @@ -22,6 +23,7 @@ export const routeQuery = /* groq */ `
${allSlugsQuery},
"title": content->title,
"seoAndSome": content->${seoAndSomeFields},
${stickyMenu},
"hero": content->${heroFields},
"template": content->_type,
content->_type == "page" => {
Expand Down
105 changes: 39 additions & 66 deletions web/pageComponents/shared/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import styled, { createGlobalStyle } from 'styled-components'
import { CSSProperties } from 'react'
import { createGlobalStyle } from 'styled-components'
import { useRouter } from 'next/router'
import { default as NextLink } from 'next/link'
import { Topbar, BackgroundContainer } from '@components'
import { AllSlugsType, LocalizationSwitch } from './LocalizationSwitch'
import type { MenuData, SimpleMenuData } from '../../types/index'
import type { MenuData, SimpleMenuData, StickyMenuData } from '../../types/index'
import { Flags } from '../../common/helpers/datasetHelpers'
import { languages, defaultLanguage } from '../../languages'
import { FormattedMessage, useIntl } from 'react-intl'
Expand All @@ -15,59 +14,18 @@ import Head from 'next/head'
import getConfig from 'next/config'
import { getAllSitesLink } from '../../common/helpers/getAllSitesLink'
import { Icon } from '@equinor/eds-core-react'
import { ButtonLink, LogoLink } from '@core/Link'
import { ButtonLink, LogoLink, StickyMenuLink } from '@core/Link'
import SiteMenu from '@sections/SiteMenu/SiteMenu'

const TopbarOffset = createGlobalStyle`
body {
padding-top: var(--topbar-height);
}
`

const HeaderRelative = styled.header`
position: relative;
`

const TopbarContainer = styled(Topbar.InnerContainer)`
display: grid;
grid-template-areas: 'logo menu';
grid-template-rows: 1fr;
align-items: center;
grid-column-gap: var(--space-large);
column-gap: var(--space-large);
`

/* This div is needed because of the grid layout to wrap focus lock panes.
We might look into to improve this at some point. */
const ControlChild = styled.div``

const ControlsContainer = styled.div`
grid-area: menu;
justify-self: right;
display: grid;
grid-template-columns: repeat(var(--columns), auto);
grid-column-gap: var(--space-small);
column-gap: var(--space-small);
align-items: center;
@media (min-width: 600px) {
grid-column-gap: var(--space-medium);
column-gap: var(--space-medium);
}
`

const StyledAllSites = styled(NextLink)`
cursor: pointer;
font-size: var(--typeScale-1);
text-decoration: none;
&:hover {
text-decoration: underline;
}
`

export type HeaderProps = {
menuData?: MenuData | SimpleMenuData
slugs: AllSlugsType
stickyMenuData?: StickyMenuData
}

const HeadTags = ({ slugs }: { slugs: AllSlugsType }) => {
Expand Down Expand Up @@ -121,13 +79,13 @@ const HeadTags = ({ slugs }: { slugs: AllSlugsType }) => {
const AllSites = () => {
const allSitesURL = getAllSitesLink('external')
return (
<StyledAllSites href={allSitesURL} prefetch={false}>
<NextLink className="cursor-pointer text-base no-underline hover:underline" href={allSitesURL} prefetch={false}>
<FormattedMessage id="all_sites" defaultMessage="All Sites" />
</StyledAllSites>
</NextLink>
)
}

const Header = ({ slugs, menuData }: HeaderProps) => {
const Header = ({ slugs, menuData, stickyMenuData }: HeaderProps) => {
const router = useRouter()
const localization = {
activeLocale: router.locale || defaultLanguage.locale,
Expand All @@ -148,23 +106,24 @@ const Header = ({ slugs, menuData }: HeaderProps) => {
const intl = useIntl()
const searchLabel = intl.formatMessage({ id: 'search', defaultMessage: 'Search' })

const anchorReference = stickyMenuData?.links.find((it) => it.type == 'anchorLinkReference')
const resourceLink = stickyMenuData?.links.find((it) => it.type == 'downloadableFile')

return (
<HeaderRelative>
<div className="sticky top-0 z-10">
<HeadTags slugs={slugs} />
<TopbarOffset />
<BackgroundContainer>
<Topbar>
<TopbarContainer>
<Topbar.InnerContainer className="grid [grid-template-areas:'logo_menu'] grid-rows-1 items-center gap-x-8">
<LogoLink className="[grid-area:logo]" />
<ControlsContainer
style={
{
'--columns': columns,
} as CSSProperties
}
<div
className={`grid [grid-area:menu] justify-self-end ${
columns == 3 ? 'grid-cols-auto-3' : columns == 2 ? 'grid-cols-auto-2' : 'grid-cols-1'
} gap-x-4 items-center sm:gap-x-61`}
>
{hasSearch && (
<ControlChild>
<div>
<ButtonLink
variant="ghost"
aria-expanded="true"
Expand All @@ -175,27 +134,41 @@ const Header = ({ slugs, menuData }: HeaderProps) => {
<Icon size={24} data={search} />
<FormattedMessage id="search" />
</ButtonLink>
</ControlChild>
</div>
)}
{hasMoreThanOneLanguage && (
<LocalizationSwitch activeLocale={localization.activeLocale} allSlugs={validSlugs} />
)}
{shouldDisplayAllSites ? (
<AllSites />
) : menuData && Flags.HAS_FANCY_MENU ? (
<ControlChild>
<div>
<SiteMenu data={menuData as MenuData} />
</ControlChild>
</div>
) : (
<ControlChild>
<div>
<SiteMenu variant="simple" data={menuData as SimpleMenuData} />
</ControlChild>
</div>
)}
</ControlsContainer>
</TopbarContainer>
</div>
</Topbar.InnerContainer>
</Topbar>
{stickyMenuData && (
<div className="w-full items-center bg-moss-green-50 p-4 grid grid-cols-2 lg:grid-cols-5 gap-2 lg:px-16 lg:gap-16 shadow-top-bar z-40">
<div className="text-center font-bold lg:col-span-3 text-md col-span-2"> {stickyMenuData?.title}</div>
<StickyMenuLink className="mr-4 place-self-end self-center" href={`#${anchorReference?.anchorReference}`}>
{anchorReference?.title}
</StickyMenuLink>
{resourceLink && (
<StickyMenuLink href={resourceLink.href} isDownloadable>
{' '}
{resourceLink.label}
</StickyMenuLink>
)}
</div>
)}
</BackgroundContainer>
</HeaderRelative>
</div>
)
}

Expand Down
Loading

0 comments on commit d4194a0

Please sign in to comment.