Skip to content

Commit

Permalink
feat(Card): add style for nested cards (#4244)
Browse files Browse the repository at this point in the history
The same style as we have in the Edit- and ViewContainer's:
https://eufemia.dnb.no/uilib/extensions/forms/Iterate/ViewContainer/demos/

We will get an additional approval from Hens tomorrow.

👁️ [PR
Example](https://eufemia-git-feat-card-nested-eufemia.vercel.app/uilib/components/card/demos/#nested-cards).
  • Loading branch information
tujoworker authored Nov 8, 2024
1 parent 45687ea commit f45aa4a
Show file tree
Hide file tree
Showing 21 changed files with 104 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ export const Default = () => {
)
}

export const NestedCards = () => {
return (
<ComponentBox data-visual-test="layout-card-nested">
<Card>
<P>First Card</P>
<Card top>
<P>Second Card</P>
<Card top>
<P>Third Card (for edge cases only)</P>
</Card>
</Card>
</Card>
</ComponentBox>
)
}

export const WithTable = () => {
return (
<ComponentBox data-visual-test="layout-card-table">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ For [form components](uilib/extensions/forms/), you should use `stack={true}` to

<Examples.Stack />

### Nested Cards

Nested cards have `responsive={false}` by default and will not behave responsive.

<Examples.NestedCards />

### Without padding

<Examples.WithoutPadding />
Expand Down
43 changes: 24 additions & 19 deletions packages/dnb-eufemia/src/components/card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import React from 'react'
import React, { useContext } from 'react'
import classnames from 'classnames'
import Flex from '../flex/Flex'
import { SectionParams, SectionProps } from '../section/Section'
import { combineLabelledBy } from '../../shared/component-helper'
import CardContext from './CardContext'
import Space from '../Space'
import useId from '../../shared/helpers/useId'

import type { BasicProps as FlexContainerProps } from '../flex/Container'
import type { BasicProps as FlexItemProps } from '../flex/Item'
import type { SpaceTypeMedia } from '../../shared/types'
import type { SpaceProps } from '../Space'
import Space from '../Space'

export type Props = {
/**
Expand All @@ -33,6 +34,8 @@ export type Props = {
Omit<React.HTMLProps<HTMLElement>, 'ref' | 'wrap' | 'size' | 'title'>

function Card(props: Props) {
const nestedContext = useContext(CardContext)

const {
className,
stack,
Expand All @@ -44,7 +47,7 @@ function Card(props: Props) {
align,
divider = 'space',
rowGap,
responsive = true,
responsive = !nestedContext?.isNested,
filled,
title,
children,
Expand Down Expand Up @@ -91,22 +94,24 @@ function Card(props: Props) {

return (
<Flex.Item alignSelf={alignSelf} element="section" {...params}>
<Flex.Container
direction={direction ?? 'vertical'}
divider={divider}
alignSelf={alignSelf}
align={stack ? 'stretch' : align}
wrap={!stack}
gap={stack ? 'medium' : (gap ?? spacing) || false}
rowGap={rowGap || false}
>
{title && (
<Space id={titleId} className="dnb-card__title">
{title}
</Space>
)}
{children}
</Flex.Container>
<CardContext.Provider value={{ isNested: true }}>
<Flex.Container
direction={direction ?? 'vertical'}
divider={divider}
alignSelf={alignSelf}
align={stack ? 'stretch' : align}
wrap={!stack}
gap={stack ? 'medium' : (gap ?? spacing) || false}
rowGap={rowGap || false}
>
{title && (
<Space id={titleId} className="dnb-card__title">
{title}
</Space>
)}
{children}
</Flex.Container>
</CardContext.Provider>
</Flex.Item>
)
}
Expand Down
11 changes: 11 additions & 0 deletions packages/dnb-eufemia/src/components/card/CardContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react'

export interface CardContextState {
isNested?: boolean
}

const CardContext = React.createContext<CardContextState | undefined>(
undefined
)

export default CardContext
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ describe.each(['ui', 'sbanken'])('Card for %s', (themeName) => {
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match nested cards', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="layout-card-nested"]',
})
expect(screenshot).toMatchImageSnapshot()
})
})

describe.each(['ui', 'sbanken'])(
Expand All @@ -69,6 +76,7 @@ describe.each(['ui', 'sbanken'])(
},
url: '/uilib/components/card/demos',
}

it('have to match border', async () => {
const screenshot = await makeScreenshot({
...params,
Expand Down Expand Up @@ -103,5 +111,12 @@ describe.each(['ui', 'sbanken'])(
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match nested cards', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="layout-card-nested"]',
})
expect(screenshot).toMatchImageSnapshot()
})
}
)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@
--card-outline-color: var(--border-color, var(--sb-color-gray-light));
--card-outline-width: 0.0625rem;
--card-background-color: var(--sb-color-white);

// Nested Cards
& .dnb-card {
--rounded-corner: 0.375rem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@
--card-outline-color: var(--border-color, var(--color-lavender));
--card-outline-width: 0.25rem;
--card-background-color: var(--color-white);

// Nested Cards
& .dnb-card {
--outline-width: 0.125rem;
--rounded-corner: 0.375rem;
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import React, {
useRef,
} from 'react'
import classnames from 'classnames'
import { Flex, HeightAnimation } from '../../../../../components'
import { Card, HeightAnimation } from '../../../../../components'
import SectionContainerContext, {
SectionContainerContextState,
} from './SectionContainerContext'
Expand Down Expand Up @@ -123,16 +123,17 @@ function SectionContainer(props: Props & FlexContainerProps) {
duration={450}
keepInDOM // Ensure fields get mounted so they will sync with the data context
>
<Flex.Stack
<Card
stack
innerSpace={variant === 'basic' ? false : 'small'}
className="dnb-forms-section-block__inner"
{...restProps}
element="section"
aria-label={ariaLabel}
innerRef={containerRef}
tabIndex={-1}
>
{children}
</Flex.Stack>
</Card>
</HeightAnimation>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,23 @@
flex-direction: column;
}

&--variant-basic {
--border-color: transparent;
}

&__inner {
flex: 1;
outline: none; // for JavaSCript focus

margin-bottom: var(--space);
padding: var(--padding, 1rem);

.dnb-forms-section-block--variant-basic &,
&:not([class*='dnb-flex-container--spacing']) {
--padding: 0;
&:has(.dnb-flex-container--spacing-small) {
--space: var(--spacing-small);
}

&[class*='dnb-flex-container--spacing'] {
&.dnb-flex-container--spacing {
&-small {
--space: var(--spacing-small);
}
&-medium {
--space: var(--spacing-medium);
}
&-large {
--space: var(--spacing-large);
}
}

border-radius: 0.375rem;

.dnb-forms-section-block--variant-outline & {
box-shadow: inset 0 0 0 2px var(--block-outline-color);
}
&:has(.dnb-flex-container--spacing-medium) {
--space: var(--spacing-medium);
}
&:has(.dnb-flex-container--spacing-large) {
--space: var(--spacing-large);
}

transition:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useContext, useReducer, useRef } from 'react'
import classnames from 'classnames'
import { Flex, HeightAnimation } from '../../../../components'
import { Card, HeightAnimation } from '../../../../components'
import IterateItemContext, {
IterateItemContextState,
} from '../IterateItemContext'
Expand Down Expand Up @@ -182,14 +182,15 @@ function ArrayItemArea(props: Props & FlexContainerProps) {
duration={450}
keepInDOM // Ensure fields get mounted so they will sync with the data context
>
<Flex.Stack
<Card
stack
innerSpace="small"
className="dnb-forms-section-block__inner"
{...restProps}
element="section"
aria-label={ariaLabel}
>
{children}
</Flex.Stack>
</Card>
</HeightAnimation>
</ArrayItemAreaContext.Provider>
)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f45aa4a

Please sign in to comment.