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

feat(Card, Section): add outset property for moderate layout breakout #4317

Merged
merged 1 commit into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,12 @@ import { Field, Form } from '@dnb/eufemia/src/extensions/forms'

export const Default = () => {
return (
<ComponentBox>
<Card data-visual-test="layout-card-border">
<ComponentBox data-visual-test="layout-card-border">
<Card>
<P>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi
cursus pharetra elit in bibendum.
</P>
<P>
Praesent nunc ipsum, convallis eget convallis gravida, vehicula
vitae metus.
</P>
</Card>
</ComponentBox>
)
Expand All @@ -35,11 +31,11 @@ export const Default = () => {
export const NestedCards = () => {
return (
<ComponentBox data-visual-test="layout-card-nested">
<Card>
<Card stack>
<P>First Card</P>
<Card top>
<Card stack>
<P>Second Card</P>
<Card top>
<Card stack>
<P>Third Card (for edge cases only)</P>
</Card>
</Card>
Expand Down Expand Up @@ -274,3 +270,20 @@ export const WithNestedSection = () => {
</ComponentBox>
)
}

export const WithOutset = () => {
return (
<ComponentBox data-visual-test="layout-card-outset">
<Flex.Vertical>
<Form.MainHeading>Main heading</Form.MainHeading>
<Card stack outset>
<P>Card content</P>
<Card>
<P>Nested card</P>
</Card>
</Card>
<Form.SubmitButton />
</Flex.Vertical>
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ Nested cards have `responsive={false}` by default and will not behave responsive

<Examples.NestedCards />

## With `outset`

On small screens (mobile) the outset is removed.

<Examples.WithOutset />

### Without padding

<Examples.WithoutPadding />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,12 @@
showTabs: true
---

import PropertiesTable from 'dnb-design-system-portal/src/shared/parts/PropertiesTable'
import { SectionProperties } from '@dnb/eufemia/src/components/section/SectionDocs'

## Properties

| Properties | Description |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `variant` | _(optional)_ defines the semantic purpose and subsequently the style of the visual helper. Will take precedence over the style_type property |
| `element` | _(optional)_ define what HTML element should be used. Defaults to `<section>`. |
| `breakout` | _(optional)_ use `true` to enable a fullscreen breakout look. Supports also media query breakpoints like `{ small: boolean }`. Defaults to `true`. |
| `outline` | _(optional)_ define a custom border color. If `true` is given, `color-black-8` is used. Use a Eufemia [color](/uilib/usage/customisation/colors/). Supports also media query breakpoints like `{ small: 'black-8' }` |
| `roundedCorner` | _(optional)_ use `true` to enable rounded corners (border-radius). Supports also media query breakpoints like `{ small: boolean }`. Defaults to `false`. |
| `backgroundColor` | _(optional)_ define a custom background color, instead of a variant. Use a Eufemia [color](/uilib/usage/customisation/colors/). Supports also media query breakpoints like `{ small: 'white' }`. |
| `dropShadow` | _(optional)_ use `true` to show the default Eufemia DropShadow. Supports also media query breakpoints like `{ small: true }`. |
| `textColor` | _(optional)_ define a custom text color to compliment the backgroundColor. Use a Eufemia [color](/uilib/usage/customisation/colors/). Supports also media query breakpoints like `{ small: 'black-80' }`. |
| `innerSpace` | _(optional)_ will add a padding around the content. Supports also media query breakpoints like `{small: { top: 'medium' }}`. |
| `innerRef` | _(optional)_ by providing a React Ref we can get the internally used element (DOM). E.g. `inner_ref={myRef}` by using `React.createRef()` or `React.useRef()`. |
| [Space](/uilib/layout/space/properties) | _(optional)_ spacing properties like `top` or `bottom` are supported. |
<PropertiesTable props={SectionProperties} />

## Variants

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,9 +624,19 @@ button.dnb-button::-moz-focus-inner {
.dnb-section:not([style*="--breakout"]) {
--breakout: var(--breakout--on);
}
.dnb-section[style*="--outset"].dnb-space[style]:not(.dnb-card) {
padding-left: calc(var(--padding-left) * (1 - var(--outset)));
padding-right: calc(var(--padding-right) * (1 - var(--outset)));
}
.dnb-section[style*="--outset"]::before {
margin-left: calc(var(--padding-left, var(--spacing-medium)) * -1 * var(--outset));
margin-right: calc(var(--padding-right, var(--spacing-medium)) * -1 * var(--outset));
background-color: inherit;
}
@media screen and (max-width: 60em) {
.dnb-section {
--breakout: var(--breakout--small, var(--breakout--fallback));
--outset: var(--outset--small, var(--outset--fallback));
--background-color--value: var(--background-color--small);
--text-color--value: var(--text-color--small);
--outline-color: var(--outline-color--small);
Expand All @@ -640,6 +650,7 @@ button.dnb-button::-moz-focus-inner {
@media screen and (max-width: 60em) and (min-width: 40.00625em) {
.dnb-section {
--breakout: var(--breakout--medium, var(--breakout--fallback));
--outset: var(--outset--medium, var(--outset--fallback));
--background-color--value: var(--background-color--medium);
--text-color--value: var(--text-color--medium);
--outline-color: var(--outline-color--medium);
Expand All @@ -653,6 +664,7 @@ button.dnb-button::-moz-focus-inner {
@media screen and (min-width: 60.00625em) {
.dnb-section {
--breakout: var(--breakout--large, var(--breakout--fallback));
--outset: var(--outset--large, var(--outset--fallback));
--background-color--value: var(--background-color--large);
--text-color--value: var(--text-color--large);
--outline-color: var(--outline-color--large);
Expand Down
7 changes: 7 additions & 0 deletions packages/dnb-eufemia/src/components/card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export type Props = {
*/
filled?: boolean
} & FlexContainerProps &
Pick<SectionProps, 'outset'> &
FlexItemProps & {
stack?: boolean
} & SpaceProps &
Expand All @@ -49,6 +50,7 @@ function Card(props: Props) {
rowGap,
responsive = !nestedContext?.isNested,
filled,
outset,
title,
children,
...rest
Expand Down Expand Up @@ -79,6 +81,11 @@ function Card(props: Props) {
filled && 'dnb-card--filled'
),
breakout: responsive ? trueWhenSmall : false,
outset: nestedContext?.isNested
? false
: outset === true
? falseWhenSmall
: outset,
roundedCorner: responsive ? falseWhenSmall : true,
outline: '--outline-card-color',
innerSpace:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ describe.each(['ui', 'sbanken'])('Card for %s', (themeName) => {
})
expect(screenshot).toMatchImageSnapshot()
})

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

describe.each(['ui', 'sbanken'])(
Expand Down Expand Up @@ -118,5 +125,12 @@ describe.each(['ui', 'sbanken'])(
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match outset', async () => {
const screenshot = await makeScreenshot({
selector: '[data-visual-test="layout-card-outset"]',
})
expect(screenshot).toMatchImageSnapshot()
})
}
)
50 changes: 50 additions & 0 deletions packages/dnb-eufemia/src/components/card/__tests__/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ describe('Card', () => {
expect(element).toHaveClass('dnb-flex-item--align-self-stretch')
expect(container).toHaveClass('dnb-flex-container--align-stretch')
expect(container).toHaveClass('dnb-flex-container--align-self-stretch')
expect(container).toHaveClass('dnb-flex-container--spacing-medium')
})

it('should set align="stretch" classes', () => {
Expand Down Expand Up @@ -331,6 +332,55 @@ describe('Card', () => {
expect(element.getAttribute('style')).not.toContain('--space-')
})

it('should support "outset"', () => {
const { rerender } = render(<Card outset />)

const element = document.querySelector('.dnb-card')

expect(element).toHaveStyle('--outset--small: 0')
expect(element).toHaveStyle('--outset--medium: 1')
expect(element).toHaveStyle('--outset--large: 1')

rerender(
<Card
outset={{
small: true,
medium: false,
large: false,
}}
/>
)

expect(element).toHaveStyle('--outset--small: 1')
expect(element).toHaveStyle('--outset--medium: 0')
expect(element).toHaveStyle('--outset--large: 0')

rerender(<Card outset={false} />)

expect(element).toHaveStyle('--outset--small: 0')
expect(element).toHaveStyle('--outset--medium: 0')
expect(element).toHaveStyle('--outset--large: 0')
})

it('should not allow "outset" on nested cards', () => {
render(
<Card outset>
<Card outset />
</Card>
)

const firstCard = document.querySelector('.dnb-card')
const secondCard = firstCard.querySelector('.dnb-card')

expect(firstCard).toHaveStyle('--outset--small: 0')
expect(firstCard).toHaveStyle('--outset--medium: 1')
expect(firstCard).toHaveStyle('--outset--large: 1')

expect(secondCard).toHaveStyle('--outset--small: 0')
expect(secondCard).toHaveStyle('--outset--medium: 0')
expect(secondCard).toHaveStyle('--outset--large: 0')
})

it('should support "responsive" of false', () => {
const { rerender } = render(
<Card>
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.
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.
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.
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 from 'react'

import { Field, Form } from '../../../extensions/forms'
import { Card, Flex, Grid } from '../../'
import { Card, Flex, Grid, Section, Space } from '../../'
import { Wrapper, Box } from 'storybook-utils/helpers'
import { H2, P } from '../../../elements'

Expand Down Expand Up @@ -190,3 +190,31 @@ export const WithGrid = () => {
</div>
)
}

export const WithOutset = () => {
return (
<Space space="large">
<Flex.Vertical>
<Form.MainHeading>Main heading</Form.MainHeading>
<Card stack outset>
<P>Card content</P>
<Card>
<P>Nested card</P>
</Card>
</Card>
<Form.SubmitButton />
</Flex.Vertical>

<Section
top
roundedCorner
outline
outset={{ small: false, medium: true, large: true }}
innerSpace="medium"
backgroundColor="transparent"
>
<P>Nested card</P>
</Section>
</Space>
)
}
31 changes: 24 additions & 7 deletions packages/dnb-eufemia/src/components/card/style/dnb-card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,19 @@
align-self: flex-start;
}

// Nested Cards
& .dnb-card {
--outline-width: 0.125rem;
&[style*='--outset'] {
&.dnb-space[style]:not(.dnb-card) {
padding-left: calc(var(--padding-left) * calc(1 - var(--outset)));
padding-right: calc(var(--padding-right) * calc(1 - var(--outset)));
}
&.dnb-card > .dnb-flex-container {
margin-left: calc(
var(--padding-left, var(--spacing-medium)) * -1 * var(--outset)
);
margin-right: calc(
var(--padding-right, var(--spacing-medium)) * -1 * var(--outset)
);
}
}
}

Expand All @@ -125,14 +135,21 @@
+ * + .dnb-card,/* e.g. one paragraph */
+ * + * + .dnb-card,/* e.g. two paragraphs */
+ .dnb-help-button__content + .dnb-section + .dnb-card
) {
&:not([class*='space__bottom']) {
margin-bottom: var(--spacing-small);
}
}

.dnb-card--auto-indent:has(
+ .dnb-card:not([style*='--outset']),
+ * + .dnb-card:not([style*='--outset']),/* e.g. one paragraph */
+ * + * + .dnb-card:not([style*='--outset']),/* e.g. two paragraphs */
+ .dnb-help-button__content + .dnb-section + .dnb-card:not([style*='--outset'])
) {
&:not([class*='space__left']) {
@include allAbove(small) {
margin-left: var(--spacing-medium);
}
}

&:not([class*='space__bottom']) {
margin-bottom: var(--spacing-small);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -624,9 +624,19 @@ button.dnb-button::-moz-focus-inner {
.dnb-section:not([style*="--breakout"]) {
--breakout: var(--breakout--on);
}
.dnb-section[style*="--outset"].dnb-space[style]:not(.dnb-card) {
padding-left: calc(var(--padding-left) * (1 - var(--outset)));
padding-right: calc(var(--padding-right) * (1 - var(--outset)));
}
.dnb-section[style*="--outset"]::before {
margin-left: calc(var(--padding-left, var(--spacing-medium)) * -1 * var(--outset));
margin-right: calc(var(--padding-right, var(--spacing-medium)) * -1 * var(--outset));
background-color: inherit;
}
@media screen and (max-width: 60em) {
.dnb-section {
--breakout: var(--breakout--small, var(--breakout--fallback));
--outset: var(--outset--small, var(--outset--fallback));
--background-color--value: var(--background-color--small);
--text-color--value: var(--text-color--small);
--outline-color: var(--outline-color--small);
Expand All @@ -640,6 +650,7 @@ button.dnb-button::-moz-focus-inner {
@media screen and (max-width: 60em) and (min-width: 40.00625em) {
.dnb-section {
--breakout: var(--breakout--medium, var(--breakout--fallback));
--outset: var(--outset--medium, var(--outset--fallback));
--background-color--value: var(--background-color--medium);
--text-color--value: var(--text-color--medium);
--outline-color: var(--outline-color--medium);
Expand All @@ -653,6 +664,7 @@ button.dnb-button::-moz-focus-inner {
@media screen and (min-width: 60.00625em) {
.dnb-section {
--breakout: var(--breakout--large, var(--breakout--fallback));
--outset: var(--outset--large, var(--outset--fallback));
--background-color--value: var(--background-color--large);
--text-color--value: var(--text-color--large);
--outline-color: var(--outline-color--large);
Expand Down
Loading
Loading