Skip to content

Commit

Permalink
feat(Breadcrumb): add animation when in collapse mode
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Sep 14, 2022
1 parent 65dbbfb commit f7a64c4
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const BreadcrumbMultipleData = () => (
];
return (
<Breadcrumb data={pages} spacing/>
<Breadcrumb data={pages} spacing />
)
}
`
Expand Down Expand Up @@ -89,7 +89,7 @@ export const BreadcrumbVariants = () => (
return (
// Try changing variant here
<Breadcrumb variant="collapse" data={pages} spacing/>
<Breadcrumb variant="collapse" data={pages} spacing />
)
}
`
Expand Down
56 changes: 28 additions & 28 deletions packages/dnb-eufemia/src/components/breadcrumb/Breadcrumb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
convertJsxToString,
validateDOMAttributes,
} from '../../shared/component-helper'
import { BreadcrumbMultiple } from './BreadcrumbMultiple'

export interface BreadcrumbProps {
/**
Expand Down Expand Up @@ -111,6 +112,12 @@ export interface BreadcrumbProps {
* Default: false
*/
spacing?: boolean

/**
* Will disable the height animation
* Default: false
*/
noAnimation?: boolean
}

export const defaultProps = {
Expand All @@ -128,6 +135,7 @@ export const defaultProps = {
const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {
// Every component should have a context
const context = React.useContext(Context)

// Extract additional props from global context
const allProps = usePropsWithContext(
localProps,
Expand All @@ -136,10 +144,11 @@ const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {
context?.Breadcrumb,
{ skeleton: context?.skeleton }
)

const {
className,
skeleton,
children: childrenItems,
children: items,
variant,
onClick,
navText, // has a translation in context
Expand All @@ -150,6 +159,7 @@ const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {
collapsedStyleType,
isCollapsed: overrideIsCollapsed,
spacing,
noAnimation,
data,
href,
...props
Expand All @@ -165,7 +175,7 @@ const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {

let currentVariant = variant
if (!variant) {
if (childrenItems || data) {
if (items || data) {
currentVariant = isSmallScreen ? 'collapse' : 'multiple'
} else {
currentVariant = 'single'
Expand All @@ -176,24 +186,6 @@ const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {
setCollapse(overrideIsCollapsed)
}, [overrideIsCollapsed])

const MultipleCrumbs = () => (
<ol className="dnb-breadcrumb__list">
{data?.map((breadcrumbItem, i) => (
<BreadcrumbItem
key={`${breadcrumbItem.text}`}
variant={
(i == 0 && 'home') ||
(i == data.length - 1 && 'current') ||
null
}
{...breadcrumbItem}
/>
))}

{childrenItems}
</ol>
)

validateDOMAttributes(allProps, props)

return (
Expand Down Expand Up @@ -237,16 +229,24 @@ const Breadcrumb = (localProps: BreadcrumbProps & ISpacingProps) => {
/>
)}

{currentVariant === 'multiple' && <MultipleCrumbs />}
{currentVariant === 'multiple' && (
<BreadcrumbMultiple
open={true}
items={items}
data={data}
noAnimation={noAnimation}
/>
)}
</Section>

{currentVariant === 'collapse' && !isCollapsed && (
<Section
style_type={collapsedStyleType}
className="dnb-breadcrumb__collapse"
data-testid="breadcrumb-collapse"
>
<MultipleCrumbs />
{currentVariant === 'collapse' && (
<Section style_type={collapsedStyleType}>
<BreadcrumbMultiple
open={!isCollapsed}
items={items}
data={data}
noAnimation={noAnimation}
/>
</Section>
)}
</nav>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export interface BreadcrumbItemProps {
* Default: null
*/
skeleton?: SkeletonShow

style?: React.CSSProperties
}

const defaultProps = {
Expand All @@ -72,7 +74,7 @@ const BreadcrumbItem = (localProps: BreadcrumbItemProps) => {
} = context

// Extract additional props from global context
const { text, href, icon, onClick, variant, skeleton, ...props } =
const { text, href, icon, onClick, variant, skeleton, style, ...props } =
usePropsWithContext(localProps, defaultProps, context?.BreadcrumbItem)

const currentIcon: IconPrimaryIcon =
Expand All @@ -85,6 +87,7 @@ const BreadcrumbItem = (localProps: BreadcrumbItemProps) => {
className="dnb-breadcrumb__item"
data-testid="breadcrumb-item"
aria-current={variant === 'current' ? 'page' : undefined}
style={style}
>
{isInteractive ? (
<Button
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import classnames from 'classnames'
import React from 'react'
import { useHeightAnimation } from '../../shared/useHeightAnimation'
import BreadcrumbItem, { BreadcrumbItemProps } from './BreadcrumbItem'

type BreadcrumbMultipleProps = {
open?: boolean
noAnimation?: boolean
data: Array<BreadcrumbItemProps>
items?: React.ReactNode
}

export const BreadcrumbMultiple = ({
open = null,
items = null,
noAnimation = null,
data,
}: BreadcrumbMultipleProps) => {
const collapseRef = React.useRef()
const { isInDOM, inInParallax } = useHeightAnimation(collapseRef, {
open,
animate: !noAnimation,
})

if (!isInDOM) {
return null
}

return (
<div
className={classnames(
'dnb-breadcrumb__collapse',
inInParallax && 'dnb-breadcrumb__collapse--parallax'
)}
data-testid="breadcrumb-collapse"
ref={collapseRef}
>
<ol className={classnames('dnb-breadcrumb__list')}>
{data?.map((breadcrumbItem, i) => {
const style = { '--delay': String(i) } as React.CSSProperties
return (
<BreadcrumbItem
key={`${breadcrumbItem.text}`}
variant={
(i == 0 && 'home') ||
(i == data.length - 1 && 'current') ||
null
}
style={style}
{...breadcrumbItem}
/>
)
})}

{items}
</ol>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,18 @@ exports[`Breadcrumb scss have to match snapshot 1`] = `
.dnb-breadcrumb__collapse {
display: flex;
flex-direction: column;
padding: 0 var(--spacing-large); }
padding: 0 var(--spacing-large);
overflow: hidden;
transition: height 400ms cubic-bezier(0.42, 0, 0, 1); }
.dnb-breadcrumb__collapse .dnb-breadcrumb__list {
flex-direction: column;
align-items: flex-start; }
.dnb-breadcrumb--spacing .dnb-breadcrumb__collapse {
padding: var(--spacing-x-small) var(--spacing-large); }
.dnb-breadcrumb__collapse .dnb-breadcrumb__item {
transition: transform 400ms cubic-bezier(0.42, 0, 0, 1) calc(var(--delay) * 50ms);
transform: translateX(-1rem); }
.dnb-breadcrumb__collapse--parallax .dnb-breadcrumb__item {
transform: translateX(0); }
.dnb-breadcrumb--spacing .dnb-breadcrumb__collapse .dnb-breadcrumb__list {
padding: var(--spacing-x-small) 0; }
"
`;
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,24 @@
&__collapse {
display: flex;
flex-direction: column;

padding: 0 var(--spacing-large);

overflow: hidden;
transition: height 400ms #{$defaultEasing};
}
&__collapse &__list {
flex-direction: column;
align-items: flex-start;
}
&--spacing &__collapse {
padding: var(--spacing-x-small) var(--spacing-large);
&__collapse &__item {
transition: transform 400ms #{$defaultEasing} calc(var(--delay) * 50ms);
transform: translateX(-1rem);
}
&__collapse--parallax &__item {
transform: translateX(0);
}
&--spacing &__collapse &__list {
padding: var(--spacing-x-small) 0;
}
}

0 comments on commit f7a64c4

Please sign in to comment.