Skip to content

Commit 7f25f1b

Browse files
JanHamaraJán Hamaramartimalek
authored
feature: Add Divider component to Wave (#221)
* feat: add Divider component to Wave * feat(divider): add default offset to the divider add additional tests to check the default offset * fix(divider): allow usage of 1px in .stylelintrc Needed to change stylelintrc config to allow usage of px unit for divider * Update src/components/Divider/Divider.spec.tsx Co-authored-by: martimalek <[email protected]> * Update src/components/Divider/Divider.spec.tsx Co-authored-by: martimalek <[email protected]> * Update src/components/Divider/docs/Divider.mdx Co-authored-by: martimalek <[email protected]> * Update src/components/Divider/docs/Divider.mdx Co-authored-by: martimalek <[email protected]> * Update src/components/Divider/docs/Divider.mdx Co-authored-by: martimalek <[email protected]> Co-authored-by: Ján Hamara <[email protected]> Co-authored-by: martimalek <[email protected]>
1 parent 517c136 commit 7f25f1b

File tree

6 files changed

+240
-7
lines changed

6 files changed

+240
-7
lines changed

.stylelintrc

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99
],
1010
"rules": {
1111
"declaration-empty-line-before": null,
12-
"unit-whitelist": [
13-
"rem",
14-
"deg",
15-
"fr",
16-
"ms",
17-
"%"
18-
],
12+
"declaration-property-unit-whitelist": {
13+
"/.*/": ["rem", "deg", "fr", "ms", "%", "px"]
14+
},
15+
"declaration-property-value-blacklist": {
16+
"/.*/": ["(\\d+[1]+px|[^1]+px)"]
17+
},
1918
"value-keyword-case": ["lower", { "ignoreKeywords": ["dummyValue"] }]
2019
}
2120
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { render, screen } from '@testing-library/react';
2+
import * as React from 'react';
3+
import { Divider } from './Divider';
4+
5+
describe('Divider', () => {
6+
it('renders a horizontal divider by default when not passing any props', () => {
7+
render(<Divider />);
8+
expect(screen.getByTestId('horizontal-divider')).toBeInTheDocument();
9+
expect(screen.queryByTestId('vertical-divider')).not.toBeInTheDocument();
10+
});
11+
12+
it('renders a vertical divider when passing vertical prop', () => {
13+
render(<Divider vertical />);
14+
expect(screen.getByTestId('vertical-divider')).toBeInTheDocument();
15+
expect(screen.queryByTestId('horizontal-divider')).not.toBeInTheDocument();
16+
});
17+
18+
it('renders horizontal divider with 1rem top and bottom offset by default', () => {
19+
render(<Divider />);
20+
const dividerInstance = screen.getByTestId('horizontal-divider');
21+
const dividerStyle = window.getComputedStyle(dividerInstance);
22+
23+
expect(dividerStyle.marginTop).toBe('1rem');
24+
expect(dividerStyle.marginBottom).toBe('1rem');
25+
});
26+
27+
it('renders vertical divider with 1rem left and right offset by default', () => {
28+
render(<Divider vertical />);
29+
const dividerInstance = screen.getByTestId('vertical-divider');
30+
const dividerStyle = window.getComputedStyle(dividerInstance);
31+
32+
expect(dividerStyle.marginLeft).toBe('1rem');
33+
expect(dividerStyle.marginRight).toBe('1rem');
34+
});
35+
});

src/components/Divider/Divider.tsx

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import React from 'react';
2+
import styled, { StyledComponent } from 'styled-components';
3+
import { compose, space, SpaceProps } from 'styled-system';
4+
import { theme } from '../../essentials/theme';
5+
import { get } from '../../utils/themeGet';
6+
7+
type DividerOffset = number | string;
8+
9+
interface DividerProps extends SpaceProps {
10+
/**
11+
* Set the direction of the divider to vertical
12+
*/
13+
vertical?: boolean;
14+
/**
15+
* Set offset / margin of the divider from the surrounding content
16+
*/
17+
offset?: DividerOffset;
18+
}
19+
20+
const HorizontalLine: StyledComponent<'div', typeof theme, DividerProps, 'theme'> = styled.div.attrs({ theme })<
21+
Pick<SpaceProps, 'my'>
22+
>`
23+
width: 100%;
24+
margin-left: auto;
25+
margin-right: auto;
26+
border: 0;
27+
border-top: 1px solid ${get('semanticColors.border.primary')};
28+
29+
${compose(space)}
30+
`;
31+
32+
const VerticalLine: StyledComponent<'div', typeof theme, DividerProps, 'theme'> = styled.div.attrs({ theme })<
33+
Pick<SpaceProps, 'mx'>
34+
>`
35+
display: inline-block;
36+
width: 0.06rem;
37+
margin-top: 0;
38+
margin-bottom: 0;
39+
border: 0;
40+
border-left: 1px solid ${get('semanticColors.border.primary')};
41+
42+
${compose(space)}
43+
`;
44+
45+
const Divider: React.FC<DividerProps> = ({ vertical = false, offset = '1rem' }: DividerProps) =>
46+
vertical ? (
47+
<VerticalLine mx={offset} data-testid="vertical-divider" />
48+
) : (
49+
<HorizontalLine my={offset} data-testid="horizontal-divider" />
50+
);
51+
52+
export { Divider, DividerProps, DividerOffset };
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
name: Divider
3+
menu: Components
4+
route: /components/divider
5+
---
6+
7+
import { Playground } from 'docz';
8+
import { ItemWrapper } from '../../../../docs/components/ItemWrapper.ts';
9+
import { Divider } from '../Divider.tsx';
10+
import { WrappedHorizontalDivider, WrappedVerticalDivider, SectionPlaceholder } from './WrappedDivider.tsx';
11+
12+
# Divider
13+
14+
**Primary UI element for visually separating content**
15+
16+
Renders a divider UI component: horizontal or vertical line that visually separates two pieces of data, content or UI.
17+
<br/>
18+
19+
### Default Behaviour
20+
The horizontal divider takes up the full available width and the vertical divider takes up the full available height.
21+
22+
The horizontal divider is rendered by default. Set **vertical** prop to `true` to change the divider orientation.
23+
<br/>
24+
25+
### Divider vs Border
26+
The default color of Divider is **$border.primary** (#C6CDD4), however...
27+
28+
**Divider is NOT a border, and should not be used as such. Please do not use this component as a border for elements.**
29+
30+
Divider is naturally expected to have a certain offset from the elements it is 'dividing' or separating.
31+
<br/>
32+
33+
### Style Props
34+
The Divider has the following design props:
35+
- **offset** - set the divider offset from the content it is separating (uses _mx_, _my_ styled system props)
36+
<br/>
37+
<br/>
38+
39+
## Usage
40+
41+
### Horizontal (with default offset)
42+
43+
<ItemWrapper>
44+
<WrappedHorizontalDivider offset='1rem' />
45+
</ItemWrapper>
46+
47+
```jsx
48+
<Divider />
49+
```
50+
<br/>
51+
52+
### Horizontal (without offset)
53+
54+
<ItemWrapper>
55+
<WrappedHorizontalDivider offset={0} />
56+
</ItemWrapper>
57+
58+
```jsx
59+
<Divider offset={0} />
60+
```
61+
<br/>
62+
63+
### Vertical (with default offset)
64+
65+
<ItemWrapper>
66+
<WrappedVerticalDivider offset='1rem' />
67+
</ItemWrapper>
68+
69+
```jsx
70+
<Divider vertical />
71+
```
72+
<br/>
73+
74+
### Vertical (without offset)
75+
76+
<ItemWrapper>
77+
<WrappedVerticalDivider offset={0} />
78+
</ItemWrapper>
79+
80+
```jsx
81+
<Divider vertical />
82+
```
83+
<br/>
84+
85+
# Playground
86+
87+
<Playground>
88+
<section>Section 1</section>
89+
<Divider />
90+
<section>Section 2</section>
91+
</Playground>
92+
93+
<Playground>
94+
{/* We need the row flow to see vertical divider */}
95+
<div style={{ display: 'flex' }}>
96+
<SectionPlaceholder>Section 1</SectionPlaceholder>
97+
<Divider vertical />
98+
<SectionPlaceholder>Section 2</SectionPlaceholder>
99+
</div>
100+
</Playground>
101+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import { Divider } from '../Divider';
4+
import type DividerOffset from '../Divider';
5+
6+
const DividerWrapper = styled.div`
7+
height: auto;
8+
display: flex;
9+
width: 100%;
10+
`;
11+
12+
const DividerColumnWrapper = styled(DividerWrapper)`
13+
flex-direction: column;
14+
`;
15+
16+
const DividerSideElement = styled.div`
17+
height: auto;
18+
padding: 4;
19+
`;
20+
21+
const SectionPlaceholder = styled.div`
22+
flex: 1;
23+
height: '200px';
24+
border: 1px black solid;
25+
text-align: center;
26+
padding: 20px;
27+
`;
28+
29+
const WrappedHorizontalDivider = (offset: DividerOffset): React.ReactElement => (
30+
<DividerColumnWrapper>
31+
<DividerSideElement>Element 1</DividerSideElement>
32+
<Divider offset={offset} />
33+
<DividerSideElement>Element 2</DividerSideElement>
34+
</DividerColumnWrapper>
35+
);
36+
37+
const WrappedVerticalDivider = (offset: DividerOffset): React.ReactElement => (
38+
<DividerWrapper>
39+
<DividerSideElement>Element 1</DividerSideElement>
40+
<Divider vertical offset={offset} />
41+
<DividerSideElement>Element 2</DividerSideElement>
42+
</DividerWrapper>
43+
);
44+
45+
export { WrappedHorizontalDivider, WrappedVerticalDivider, SectionPlaceholder };

src/components/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export { Tag, TagProps } from './Tag/Tag';
2121
export { InlineSpinner, InlineSpinnerProps } from './InlineSpinner/InlineSpinner';
2222
export { TabBar, TabBarWithLink as TabBarProps } from './TabBar/TabBar';
2323
export { DatePicker, DateRangePicker, DateRangePickerProps, DatePickerProps } from './Datepicker';
24+
export { Divider, DividerProps } from './Divider/Divider';
2425
export { Tooltip, TooltipProps } from './Tooltip/Tooltip';
2526
export { Toggle, ToggleProps } from './Toggle/Toggle';
2627
export { Box, BoxProps } from './Box/Box';

0 commit comments

Comments
 (0)