Skip to content

Commit

Permalink
chore(Portal): add View Transition
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Sep 22, 2023
1 parent 06573a2 commit 9e5f840
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 61 deletions.
17 changes: 7 additions & 10 deletions packages/dnb-design-system-portal/gatsby-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,8 @@ export const replaceHydrateFunction = () => {
export const wrapRootElement = rootElement('browser')
export const wrapPageElement = pageElement()

// This was used before during visual testing
// but it looks like they do not safe us any time
// export const disableCorePrefetching = () => {
// return window.IS_TEST
// }
// export const registerServiceWorker = () => {
// return !window.IS_TEST
// }

// scroll to top on route change
export const shouldUpdateScroll = () => true
export const shouldUpdateScroll = () => false

export const onRouteUpdate = ({ location, prevLocation }) => {
try {
Expand All @@ -64,3 +55,9 @@ export const onRouteUpdate = ({ location, prevLocation }) => {
applyPageFocus('content')
}
}

declare global {
interface Document {
startViewTransition(): void
}
}
31 changes: 25 additions & 6 deletions packages/dnb-design-system-portal/src/core/PortalLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import React from 'react'
import { MDXProvider } from '@mdx-js/react'
import { graphql, useStaticQuery } from 'gatsby'
import { graphql, navigate, useStaticQuery } from 'gatsby'
import Layout from '../shared/parts/Layout'
import Tabbar from '../shared/tags/Tabbar'
import tags from '../shared/tags'
import { resetLevels } from '@dnb/eufemia/src/components/Heading'
import { setPortalHeadData, usePortalHead } from './PortalHead'
import { Breadcrumb } from '@dnb/eufemia/src'
import { startPageTransition } from '../shared/tags/Transition'

const ContentWrapper = Tabbar.ContentWrapper

Expand Down Expand Up @@ -136,11 +137,29 @@ export default function PortalLayout(props: PortalLayoutProps) {
return (
<Layout key="layout" location={location} fullscreen={fullscreen}>
{fmData.breadcrumb && (
<Breadcrumb
key="breadcrumb"
top="large"
data={fmData.breadcrumb}
/>
<Breadcrumb key="breadcrumb" top="large">
{fmData.breadcrumb.map((item, i, a) => {
return (
<Breadcrumb.Item
key={item.text}
variant={
(i == 0 && 'home') ||
(i == a.length - 1 && 'current') ||
null
}
text={item.text}
href={item.href}
onClick={clickHandler}
/>
)

function clickHandler(e) {
e.event.preventDefault()
startPageTransition()
navigate(item.href)
}
})}
</Breadcrumb>
)}

{currentFm.showTabs && (
Expand Down
2 changes: 2 additions & 0 deletions packages/dnb-design-system-portal/src/shared/menu/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
linkInnerStyle,
boxStyle,
} from './Card.module.scss'
import { startPageTransition } from '../tags/Transition'

export default class Card extends React.PureComponent {
static propTypes = {
Expand Down Expand Up @@ -49,6 +50,7 @@ export default class Card extends React.PureComponent {
this.isSelected() && 'current-card',
)}
to={url}
onClick={startPageTransition}
aria-current={this.isSelected()}
>
<Span className={linkInnerStyle}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import React, { useContext, useEffect, useRef } from 'react'
import classnames from 'classnames'
import Link from '../parts/Link'
import Anchor from '../tags/Anchor'
import { useStaticQuery, graphql } from 'gatsby'
import Context from '@dnb/eufemia/src/shared/Context'
import { SidebarMenuContext } from './SidebarMenuContext'
Expand Down Expand Up @@ -318,8 +318,8 @@ function ListItem({
} as React.CSSProperties /* Casting to allow css variable in JSX inline styling */
}
>
<Link
to={path}
<Anchor
href={path}
onClick={closeMenu}
className={classnames(
'dnb-anchor',
Expand All @@ -344,7 +344,7 @@ function ListItem({
{status && (
<Badge space={{ right: 'xx-small' }} content={statusTitle} />
)}
</Link>
</Anchor>
</li>
{/* Currently not nesting list items with an <ul/> inside <li/> as it breaks the styling for the time being */}
{subheadings &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { useStaticQuery, graphql } from 'gatsby'
import { navigate, useStaticQuery, graphql } from 'gatsby'
import { hamburger as hamburgerIcon } from '@dnb/eufemia/src/icons'
import { close as closeIcon } from '@dnb/eufemia/src/icons/primary_icons'
import PortalLogo from './graphics/logo'
Expand All @@ -25,6 +25,7 @@ import {
portalHeaderWrapperStyle,
hideSidebarToggleButtonStyle,
} from './StickyMenuBar.module.scss'
import { startPageTransition } from '../tags/Transition'

export default function StickyMenuBar({
hideSidebarToggleButton,
Expand Down Expand Up @@ -66,6 +67,11 @@ export default function StickyMenuBar({
text="Home"
title="Eufemia main sections"
href="/"
on_click={({ event }) => {
event.preventDefault()
startPageTransition()
navigate('/')
}}
icon="chevron_left"
icon_position="left"
/>
Expand Down
28 changes: 25 additions & 3 deletions packages/dnb-design-system-portal/src/shared/parts/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
setPageFocusElement,
scrollToLocationHashId,
} from '@dnb/eufemia/src/shared/helpers'
import { P, Logo, GlobalStatus } from '@dnb/eufemia/src'
import { P, Logo, GlobalStatus, Button } from '@dnb/eufemia/src'
import './PortalStyle.scss'
import {
portalStyle,
Expand Down Expand Up @@ -115,6 +115,7 @@ function Layout(props: LayoutProps) {
</div>
</MainContent>

<ScrollToTop />
<Footer />
</Content>

Expand All @@ -131,6 +132,29 @@ type ContentProps = {
fullscreen: boolean
} & React.HTMLProps<HTMLDivElement>

const ScrollToTop = () => {
return (
<Button space="large" on_click={clickHandler} variant="tertiary">
Scroll to top
</Button>
)
function clickHandler() {
document.documentElement.style.scrollBehavior = 'auto'
const element = document.querySelector('main')
element.style.transform = 'translate3d(0, -50px, 0)'
window.scrollTo({ top: 0, behavior: 'auto' })
window.requestAnimationFrame(() => {
element.style.transition = 'transform 800ms var(--easing-default)'
element.style.transform = 'translate3d(0, 0, 0)'
setTimeout(() => {
element.style.transition = ''
element.style.transform = ''
document.documentElement.style.scrollBehavior = ''
}, 800)
})
}
}

const Content = ({
fullscreen = false,
className = null,
Expand Down Expand Up @@ -181,8 +205,6 @@ const Footer = () => {

<Logo height="40" color="white" />

{/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */}
{/* @ts-ignore */}
<Link
to="/license"
className="dnb-anchor dnb-anchor--contrast dnb-anchor--no-underline"
Expand Down
27 changes: 0 additions & 27 deletions packages/dnb-design-system-portal/src/shared/parts/Link.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { Anchor, Ul, Li } from '@dnb/eufemia/src'
import { Ul, Li } from '@dnb/eufemia/src'
import AutoLinkHeader from '../tags/AutoLinkHeader'
import Anchor from '../tags/Anchor'
import { resetLevels } from '@dnb/eufemia/src/components/Heading'
import ReactMarkdown from 'react-markdown'
import { basicComponents } from '../../shared/tags'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,11 @@ html[show-dev-grid] .dev-grid {
.lh-32 {
line-height: calc(var(--line-height-basis) + 0.5rem); /* 2rem */
}

// Make the home => pages animation
.home-background ul {
view-transition-name: home;
}
#portal-sidebar-menu {
view-transition-name: home;
}
43 changes: 34 additions & 9 deletions packages/dnb-design-system-portal/src/shared/tags/Anchor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,21 @@
import React from 'react'
import { Link } from '@dnb/eufemia/src'
import { scrollToHashHandler } from '@dnb/eufemia/src/components/Anchor'
import { GatsbyLinkProps, Link as GatsbyLink } from 'gatsby'
import isAbsoluteUrl from 'is-absolute-url'
import { ElementIsType } from '@dnb/eufemia/src/elements/Element'
import { startPageTransition } from './Transition'

export default function Anchor<TState>({
children,
href,
onClick = null,
...rest
}) {
if (!/^\//.test(href)) {
href = `/${href}`
}

const Anchor = ({ children, href, onClick = null, ...rest }) => {
if (/^http/.test(href) || href[0] === '!') {
rest.target = '_blank'
rest.rel = 'noreferrer'
Expand All @@ -16,18 +29,30 @@ const Anchor = ({ children, href, onClick = null, ...rest }) => {
}
}

const element = (isAbsoluteUrl(href) ? 'a' : GatsbyLink) as ElementIsType
const props = rest as Omit<
GatsbyLinkProps<TState>,
'ref' | 'innerRef' | 'children'
>

return (
<Link
lang="en-GB"
to={href}
element={element}
{...props}
onClick={clickHandler}
>
{children}
</Link>
)

function clickHandler(event: React.MouseEvent<HTMLAnchorElement>) {
startPageTransition()

if (onClick) {
onClick()
}
scrollToHashHandler(event)
}

return (
<Link lang="en-GB" href={href} {...rest} onClick={clickHandler}>
{children}
</Link>
)
}

export default Anchor
4 changes: 4 additions & 0 deletions packages/dnb-design-system-portal/src/shared/tags/Tabbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Button, Tabs } from '@dnb/eufemia/src/components'
import { fullscreen as fullscreenIcon } from '@dnb/eufemia/src/icons'
import AutoLinkHeader from './AutoLinkHeader'
import { tabsWrapperStyle } from './Tabbar.module.scss'
import { startPageTransition } from './Transition'

export const defaultTabs = [
{ title: 'Info', key: '/info' },
Expand Down Expand Up @@ -42,6 +43,7 @@ export default function Tabbar({
)

const openFullscreen = () => {
startPageTransition()
setFullscreen(true)

const path = [
Expand All @@ -58,6 +60,7 @@ export default function Tabbar({
s.replace(/\?fullscreen$|&fullscreen|fullscreen|\?$/, '')

const quitFullscreen = () => {
startPageTransition()
setFullscreen(false)

const path = [
Expand Down Expand Up @@ -118,6 +121,7 @@ export default function Tabbar({
data={preparedTabs}
selected_key={selectedKey}
on_change={({ selected_key }) => {
startPageTransition()
navigate(selected_key)
}}
render={({ Wrapper, Content, TabsList, Tabs }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export function startPageTransition() {
if (
!globalThis.IS_TEST &&
typeof document.startViewTransition !== 'undefined'
) {
document.startViewTransition()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export default class ContentWrapper extends React.PureComponent {
createSpacingClasses(rest)
)}
{...params}
animate={false}
>
{content}
</HeightAnimation>
Expand Down

0 comments on commit 9e5f840

Please sign in to comment.