Skip to content

Commit

Permalink
feat(Flex): add line-framed to divider (#3244)
Browse files Browse the repository at this point in the history
Relies on PR #3242
Also, I think, a white background for [this
example](https://eufemia-git-feat-flex-container-bookend-line-eufemia.vercel.app/uilib/layout/flex/container/#framed-line-dividers),
would be better. Therefor, we may get in this PR #3245 for that.


![image](https://github.com/dnbexperience/eufemia/assets/1501870/8136979f-b374-46fa-a70d-fc9cdf0be7b6)


I think, `line-framed` describes the use-case good. But maybe something
different is better?

- outlined
- grooved
- bordered
- enclosed
  • Loading branch information
tujoworker authored Jan 20, 2024
1 parent e3e1c42 commit 1aa3338
Show file tree
Hide file tree
Showing 10 changed files with 198 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,30 @@ export const WrappedWithChildren = () => {
</ComponentBox>
)
}

export const FramedLineDividers = () => {
return (
<ComponentBox
scope={{ TestElement }}
data-visual-test="flex-container-line-framed"
background="white" // will be enabled in related PR
>
{() => {
const Item = () => (
<Flex.Stack divider="line-framed" spacing="x-small">
<TestElement>FlexItem</TestElement>
<TestElement>FlexItem</TestElement>
</Flex.Stack>
)

return (
<Flex.Horizontal rowGap={false}>
<Item />
<Item />
<Item />
</Flex.Horizontal>
)
}}
</ComponentBox>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ Will wrap on small screens.

<Examples.VerticalWithFieldString />

### Framed line dividers

This example shows how to use the `Flex.Container` component to create a framed line divider (`line-framed`), which includes a line before the first item and above the last item.

<Examples.FramedLineDividers />

### Flex.withChildren

<Examples.WrappedWithChildren />
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ showTabs: true
| `wrap` | `boolean` | _(optional)_ True to wrap contents if there is not enough space. Defaults to `true`. |
| `justify` | `string` | _(optional)_ How to place sub components if there is space available in the container. Can be: `flex-start`, `flex-end`, `center`, `space-between`, `space-around` or `space-evenly`. |
| `align` | `string` | _(optional)_ How to align sub components. Can be: `flex-start`, `flex-end`, `center`, `stretch` or `baseline`. |
| `divider` | `string` | _(optional)_ How to separate sub components. Can be: `space` or `line`. |
| `divider` | `string` | _(optional)_ How to separate sub components. Can be: `space`, `line`, or `line-framed`. |
| `sizeCount` | `number` | _(optional)_ Define how many parts your layout should be divided in. Should be used in combination with a [Flex.Item](/uilib/layout/flex/item). Defaults to `12`. |
| `rowGap` | `string` or `boolean` | _(optional)_ Defines how much the gap between rows should be. Can be `large`, `medium`, `small` or `false` for no gap. Use `true` for `small`. It will inherit the `spacing` prop, if Flex.Item has a `size` prop. |
| `spacing` | `string` or `boolean` | _(optional)_ How much space between sub components. Can be `medium`, `small` or `false` for no spacing. |
Expand Down
71 changes: 29 additions & 42 deletions packages/dnb-eufemia/src/components/card/__tests__/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,17 @@ describe('Card', () => {
const element = document.querySelector('.dnb-card')
const children = element.children

expect(element.className).toContain(
'dnb-flex-container--divider-space'
)
expect(element).toHaveClass('dnb-flex-container--divider-space')

expect(children.length).toBe(2)

expect(children[0].tagName).toBe('P')
expect(children[0].className).toEqual(
expect(children[0]).toHaveClass(
'dnb-p dnb-space__top--zero dnb-space__bottom--zero'
)

expect(children[1].tagName).toBe('P')
expect(children[1].className).toContain('dnb-space__top--small')
expect(children[1]).toHaveClass('dnb-space__top--small')
})

it('should stack children divided by lines', () => {
Expand All @@ -127,24 +125,21 @@ describe('Card', () => {
const element = document.querySelector('.dnb-card')
const children = element.children

expect(element.className).toContain('dnb-flex-container--divider-line')

expect(children.length).toBe(4)

expect(children[1].tagName).toBe('DIV')
expect(children[1].className).toContain('dnb-space__top--small')
expect(element).toHaveClass('dnb-flex-container--divider-line')

expect(children[2].tagName).toBe('HR')
expect(children[2].className).toContain(
'dnb-space__left--zero dnb-space__bottom--zero dnb-space__right--zero dnb-space__top--zero dnb-hr'
)
expect(children.length).toBe(3)

expect(children[0].tagName).toBe('P')
expect(children[0].className).toEqual(
expect(children[0]).toHaveClass(
'dnb-p dnb-space__top--zero dnb-space__bottom--zero'
)
expect(children[3].tagName).toBe('P')
expect(children[3].className).toEqual(
expect(children[1].tagName).toBe('HR')
expect(children[1]).toHaveClass(
'dnb-flex-container__hr dnb-space__top--small dnb-space__left--zero dnb-space__bottom--zero dnb-space__right--zero dnb-hr'
)

expect(children[2].tagName).toBe('P')
expect(children[2]).toHaveClass(
'dnb-p dnb-space__top--small dnb-space__bottom--zero'
)
})
Expand All @@ -158,19 +153,15 @@ describe('Card', () => {

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

expect(element.className).toContain(
'dnb-flex-container--direction-vertical'
)
expect(element).toHaveClass('dnb-flex-container--direction-vertical')

rerender(
<Card direction="horizontal">
<P>Paragraph</P>
</Card>
)

expect(element.className).toContain(
'dnb-flex-container--direction-horizontal'
)
expect(element).toHaveClass('dnb-flex-container--direction-horizontal')
})

it('should use section as default element', () => {
Expand Down Expand Up @@ -209,20 +200,18 @@ describe('Card', () => {
const element = document.querySelector('.dnb-card')
const children = element.children

expect(element.className).toContain(
'dnb-flex-container--spacing-small'
)
expect(element).toHaveClass('dnb-flex-container--spacing-small')

expect(children.length).toBe(3)

expect(children[0].className).toContain('dnb-space__top--zero')
expect(children[0].className).toContain('dnb-space__bottom--zero')
expect(children[0]).toHaveClass('dnb-space__top--zero')
expect(children[0]).toHaveClass('dnb-space__bottom--zero')

expect(children[1].className).toContain('dnb-space__top--small')
expect(children[1].className).toContain('dnb-space__bottom--zero')
expect(children[1]).toHaveClass('dnb-space__top--small')
expect(children[1]).toHaveClass('dnb-space__bottom--zero')

expect(children[2].className).toContain('dnb-space__top--small')
expect(children[2].className).toContain('dnb-space__bottom--zero')
expect(children[2]).toHaveClass('dnb-space__top--small')
expect(children[2]).toHaveClass('dnb-space__bottom--zero')

rerender(
<Card spacing="large">
Expand All @@ -232,18 +221,16 @@ describe('Card', () => {
</Card>
)

expect(element.className).toContain(
'dnb-flex-container--spacing-large'
)
expect(element).toHaveClass('dnb-flex-container--spacing-large')

expect(children[0].className).toContain('dnb-space__top--zero')
expect(children[0].className).toContain('dnb-space__bottom--zero')
expect(children[0]).toHaveClass('dnb-space__top--zero')
expect(children[0]).toHaveClass('dnb-space__bottom--zero')

expect(children[1].className).toContain('dnb-space__top--large')
expect(children[1].className).toContain('dnb-space__bottom--zero')
expect(children[1]).toHaveClass('dnb-space__top--large')
expect(children[1]).toHaveClass('dnb-space__bottom--zero')

expect(children[2].className).toContain('dnb-space__top--large')
expect(children[2].className).toContain('dnb-space__bottom--zero')
expect(children[2]).toHaveClass('dnb-space__top--large')
expect(children[2]).toHaveClass('dnb-space__bottom--zero')
})

it('gets valid ref element', () => {
Expand Down
30 changes: 21 additions & 9 deletions packages/dnb-eufemia/src/components/flex/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ export type BasicProps = {
| 'space-around'
| 'space-evenly'
align?: 'flex-start' | 'flex-end' | 'center' | 'stretch' | 'baseline'
// For when used as a flex item in an outer container in addition to being a container:
/** For when used as a flex item in an outer container in addition to being a container: */
alignSelf?: 'flex-start' | 'flex-end' | 'center' | 'baseline' | 'stretch'
divider?: 'space' | 'line'
/** When "line-framed" is used, a line will be shown between items and above the first and below the last item */
divider?: 'space' | 'line' | 'line-framed'
/** Spacing between items inside */
spacing?:
| false
Expand Down Expand Up @@ -117,7 +118,9 @@ function FlexContainer(props: Props) {
// is the spacing-props that controls space between children. Then override with props sent to the children, including both top
// and bottom when th
const isFirst = i === 0
const isLast = i >= childrenArray.length - 1
const previousChild = childrenArray?.[i - 1]
const isHeading = hasHeading && isHeadingElement(previousChild)

// Always set spacing between elements in the vertical layout on the top props, and 0 on bottom, to avoid
// having to divide spacing between both with smaller values.
Expand All @@ -128,24 +131,33 @@ function FlexContainer(props: Props) {
const endSpacing = 0
let startSpacing = null

const isHeading = hasHeading && isHeadingElement(previousChild)
if (
divider === 'line' &&
// No line above first element
!isFirst &&
// No line above heading
!isHeading
!isHeading &&
((divider === 'line' && !isFirst) || divider === 'line-framed')
) {
const spaceAboveLine = getSpaceValue(end, previousChild) ?? spacing
startSpacing = (getSpaceValue(start, child) ?? spacing) as SpaceType

return (
<React.Fragment key={`element-${i}`}>
<Space top={spaceAboveLine} />
<Hr space={0} className="dnb-flex-container__hr" />
<Hr
top={!isFirst ? spaceAboveLine : 0}
space={0}
className="dnb-flex-container__hr"
/>

{renderWithSpacing(child, {
space: { [start]: startSpacing, [end]: endSpacing },
})}

{divider === 'line-framed' && isLast && (
<Hr
top={spaceAboveLine}
space={0}
className="dnb-flex-container__hr"
/>
)}
</React.Fragment>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ describe('Flex.Container', () => {
expect(screenshot).toMatchImageSnapshot()
})

it('have to match bookend line', async () => {
const screenshot = await makeScreenshot({
url: '/uilib/layout/flex/container/demos',
selector:
'[data-visual-test="flex-container-line-framed"] .dnb-flex-container',
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match wrapped bookend line', async () => {
const screenshot = await makeScreenshot({
url: '/uilib/layout/flex/container/demos',
pageViewport: {
width: 240,
},
selector:
'[data-visual-test="flex-container-line-framed"] .dnb-flex-container',
})
expect(screenshot).toMatchImageSnapshot()
})

it('have to match field on large viewport', async () => {
const screenshot = await makeScreenshot({
url: '/uilib/layout/flex/container/demos',
Expand Down
Loading

0 comments on commit 1aa3338

Please sign in to comment.