Skip to content

Commit

Permalink
feat(Card, Section): add outset property for moderate layout breakout
Browse files Browse the repository at this point in the history
  • Loading branch information
tujoworker committed Nov 21, 2024
1 parent 4a8880f commit f893f2d
Show file tree
Hide file tree
Showing 27 changed files with 229 additions and 35 deletions.
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] {
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
3 changes: 3 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,7 @@ function Card(props: Props) {
filled && 'dnb-card--filled'
),
breakout: responsive ? trueWhenSmall : false,
outset: typeof outset === 'boolean' ? 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()
})
}
)
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>
)
}
20 changes: 11 additions & 9 deletions packages/dnb-eufemia/src/components/card/style/dnb-card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -113,26 +113,28 @@
& > .dnb-flex-container--align-stretch > .dnb-button {
align-self: flex-start;
}

// Nested Cards
& .dnb-card {
--outline-width: 0.125rem;
}
}

.dnb-card--auto-indent:has(
+ .dnb-card,
+ * + .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] {
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
10 changes: 9 additions & 1 deletion packages/dnb-eufemia/src/components/section/Section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ export type SectionProps = {
*/
breakout?: boolean | ResponsiveProp<boolean>

/**
* Define if the Card should break out negatively on larger screens. You can not use `breakout` and `outset` together.
* Defaults to `false`
*/
outset?: boolean | ResponsiveProp<boolean>

/**
* Define if the section should have rounded corners. Defaults to `false`.
*/
Expand Down Expand Up @@ -152,7 +158,8 @@ export function SectionParams(

const {
variant,
breakout = true,
breakout = !props.outset,
outset,
roundedCorner,
textColor,
backgroundColor,
Expand Down Expand Up @@ -188,6 +195,7 @@ export function SectionParams(
'breakout',
(value) => `var(--breakout--${value ? 'on' : 'off'})`
),
...computeStyle(outset, 'outset', (value) => (value ? '1' : '0')),
...computeStyle(
roundedCorner,
'rounded-corner',
Expand Down
59 changes: 59 additions & 0 deletions packages/dnb-eufemia/src/components/section/SectionDocs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { PropertiesTableProps } from '../../shared/types'

export const SectionProperties: PropertiesTableProps = {
variant: {
doc: 'Defines the semantic purpose and subsequently the style of the visual helper. Will take precedence over the style_type property.',
type: 'string',
status: 'optional',
},
breakout: {
doc: 'Use `true` to enable a fullscreen breakout look. Supports also media query breakpoints like `{ small: boolean }`. Defaults to `true`.',
type: 'boolean',
status: 'optional',
},
outset: {
doc: 'Define if the Card should break out negatively on larger screens. You can not use `breakout` and `outset` together. Defaults to `false`.',
type: 'boolean',
status: 'optional',
},
outline: {
doc: "Define a custom border color. If `true` is given, `color-black-8` is used. Use a Eufemia color. Supports also media query breakpoints like `{ small: 'black-8' }`.",
type: 'string',
status: 'optional',
},
roundedCorner: {
doc: 'Use `true` to enable rounded corners (border-radius). Supports also media query breakpoints like `{ small: boolean }`. Defaults to `false`.',
type: 'boolean',
status: 'optional',
},
backgroundColor: {
doc: "Define a custom background color, instead of a variant. Use a Eufemia color. Supports also media query breakpoints like `{ small: 'white' }`.",
type: 'string',
status: 'optional',
},
dropShadow: {
doc: 'Use `true` to show the default Eufemia DropShadow. Supports also media query breakpoints like `{ small: true }`.',
type: 'boolean',
status: 'optional',
},
textColor: {
doc: "Define a custom text color to compliment the backgroundColor. Use a Eufemia color. Supports also media query breakpoints like `{ small: 'black-80' }`.",
type: 'string',
status: 'optional',
},
innerSpace: {
doc: "Will add a padding around the content. Supports also media query breakpoints like `{small: { top: 'medium' }}`.",
type: 'string',
status: 'optional',
},
innerRef: {
doc: '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()`.',
type: 'React.Ref',
status: 'optional',
},
'[Space](/uilib/layout/space/properties)': {
doc: 'Spacing properties like `top` or `bottom` are supported.',
type: ['string', 'object'],
status: 'optional',
},
}
Loading

0 comments on commit f893f2d

Please sign in to comment.